⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wordanalyst.cpp

📁 词法分析程序。通过分析文件的各个单词得到一个Token序列。课程作业:-)
💻 CPP
字号:
#include<iostream.h>
#include<fstream.h>
#include<stdlib.h>
#include<string.h>
#include<iomanip.h>
#define Lenth  32
//变量类型
#define INTEGER  1
#define CHAR	 2
#define BOOL     3 
#define MAX      50

char* wordTable[61];
//--------------------------标识符链表:save token
struct Id{
	char *value;	//记录标识符的名字	
	int num;		//记录常量的数值
	int line;		//line the token in
	short sym;
	short seq;		//变量和常量的序列
	Id *next;
};

Id *IdListHead=NULL;	//链头
Id *IdListTail=NULL;	//链尾
int TailNum=1;    //记录自定义字符的序号
//重载加入链表的函数
//关键字或字符
void addIdList(Id*s){
	if(IdListHead==NULL){
		IdListHead=s;
		IdListTail=s;
	}
	else{
		IdListTail->next=s;
		IdListTail=s;
	}
}
//自定义变量
void addIdList(Id* s,int &seq){
	if(IdListHead==NULL){
		seq=TailNum;
		s->seq=TailNum++;
		IdListHead=s;
		IdListTail=s;
		
	}
	else{
		seq=TailNum++;
		s->seq=seq;
		IdListTail->next=s;
		IdListTail=s;
		
	}
}
//查找自定义变量是否已存在
short searchIdList(Id **s,int &seq,char *A){
	if(IdListHead==NULL){
		return 0;
	}
	else{
		Id *p=new Id;
		p=IdListHead;
		for(seq=1;p&&strcmp(p->value,A)!=0;p=p->next,seq++);
		if(p==NULL) return 0;
		else{
			*s=p;
			return 1;
		}
	}
}

//--------------------------------------初始变量
void iniWordTable(){
	int i=0;
	for(;i<61;i++){
		wordTable[i]=new char[10];
		wordTable[i]="   ";
	}
	wordTable[1]="and";
	wordTable[2]="array";
	wordTable[3]="begin";
	wordTable[4]="bool";
	wordTable[5]="call";
	wordTable[6]="case";
	wordTable[7]="char";
	wordTable[8]="constant";
	wordTable[9]="dim";
	wordTable[10]="do";
	wordTable[11]="else";
	wordTable[12]="end";
	wordTable[13]="false";
	wordTable[14]="for";
	wordTable[15]="if";
	wordTable[16]="input";
	wordTable[17]="integer";
	wordTable[18]="not";
	wordTable[19]="of";
	wordTable[20]="or";
	wordTable[21]="output";
	wordTable[22]="procedure";
	wordTable[23]="program";
	wordTable[24]="read";
	wordTable[25]="real";
	wordTable[26]="repeat";
	wordTable[27]="set";
	wordTable[28]="stop";
	wordTable[29]="then";
	wordTable[30]="to";
	wordTable[31]="true";
	wordTable[32]="until";
	wordTable[33]="var";
	wordTable[34]="while";
	wordTable[35]="write";

	wordTable[39]="(";
	wordTable[40]=")";
	wordTable[41]="*";
	wordTable[42]="*/";
	wordTable[43]="+";
	wordTable[44]=",";
	wordTable[45]="-";
	wordTable[46]=".";
	wordTable[47]="..";
	wordTable[48]="/";
	wordTable[49]="/*";
	wordTable[50]=":";
	wordTable[51]=":=";
	wordTable[52]=";";
	wordTable[53]="<";
	wordTable[54]="<=";
	wordTable[55]="<>";
	wordTable[56]="=";
	wordTable[57]=">";
	wordTable[58]=">=";
	wordTable[59]="[";
	wordTable[60]="]";
}

//-----------------------------------------词法分析程序
int wordAnalyst(){
	int work=1;		//工作变量,当发生错误时work=0;
	ifstream rwfile;
//	while(cin){
//		cout<<"------------------------------"<<endl;
		cout<<"请输入你要进行词法分析的文件。退出请输入:exit。"<<endl;
		char* src=new char[20];			//指定文件
		cin>>src;
		if(strcmp(src,"exit")==0){
			rwfile.close();
			return 0;
		}
		if(IdListHead!=NULL||IdListTail!=NULL){
			delete IdListHead;
			IdListHead=NULL; 
			IdListTail=NULL;
			TailNum=1;
		}
		work=1;
		
		cout<<"File opening..."<<endl;	
		rwfile.open(src);
		if(!rwfile){
			cout<<"File open error!"<<endl;
			exit(0);
		}
		else {	cout<<"File has been open."<<endl;}	

		for(int l=1; !rwfile.eof();l++){		//l存储行数
			char *line=new char[50];
			rwfile.getline(line,50);	
			int chars=0,zsCount=0,dyCount=0;	//字符数与注释对齐数,单引号对齐数
			//处理该行
			while(line[chars]!=0){
				for(;line[chars]==' '||line[chars]==9;chars++) ; 		//滤掉空格或tab
				//----------------------------------------------------------------数字
				while(line[chars]>='0'&&line[chars]<='9'&&line[chars]!=0){				
					char *A=new char[Lenth];		//记录错误的单词
					int num=0;						//记录常量的数值
					for(int k=0;line[chars]!=' '&&line[chars]>='0'&&line[chars]<='9'&&line[chars]!=0;k++,chars++){
						A[k]=line[chars];		//记录值
						num=num*10+line[chars]-'0';
					}
					if(line[chars]!=' '&&line[chars]!=0){
						//如果数字后面跟的不是单界符,则是非法单词
						if(line[chars]<39||line[chars]>47&&line[chars]<58||line[chars]>62&&line[chars]<91||line[chars]>93){
							for(;line[chars]!=' '&&line[chars]!=0&&line[chars]<39||line[chars]>47&&line[chars]<58||line[chars]>62&&line[chars]<91||line[chars]>93;k++,chars++){
								A[k]=line[chars];
							}
							A[k]='\0';
							cout<<"第"<<l<<"行: 非法单词:"<<A<<endl;
							work=0;
						}
					}
					if(line[chars]>=0){
						A[k]='\0';			
						Id *s=new Id;
						int seq;			//用于重载addIdList函数
						if(searchIdList(&s,seq,A)){		//寻找是否已存在该标识符或整数或字符常数
							delete A;		//删除临时量
							Id *p=new Id;	//添加新节点
							p->next=NULL;
							p->value=s->value;
							p->num=num;
							p->sym=s->sym;
							p->seq=s->seq;
							p->line=l;		//save line the token in
							addIdList(p);
						}
						else{
							s->next=NULL;
							s->sym=37;
							s->num=num;
							s->value=new char[Lenth];
							strcpy(s->value,A);
							delete A;
							s->line=l;
							addIdList(s,seq);
						}
						if(line[chars]==0)break;
					}
					
					for(;line[chars]==' '||line[chars]==9;chars++);		//滤掉空格或tab
				}
						
				//------------------------------------------------------------------字母
				while((line[chars]>='A'&&line[chars]<='Z')||(line[chars]>='a'&&line[chars]<='z')){
					char *A=new char[Lenth];
					//字母和数字
					for(int k=0; line[chars]!=0 && line[chars]!=' '&& ((line[chars]>='A'&&line[chars]<='Z')||(line[chars]>='a'&&line[chars]<='z')||line[chars]>='0'&&line[chars]<='9');k++,chars++){
						A[k]=line[chars];		//记录值
					}
					if(line[chars]>=0){
						A[k]='\0';
						Id *s=new Id;				
						int seq;	
						//搜索链表
						if(searchIdList(&s,seq,A)){
							delete A;		//删除临时量
							Id *p=new Id;
							p->next=NULL;
							p->value=s->value;
							p->sym=s->sym;
							p->seq=s->seq;
							p->line=l;
							addIdList(p);
								
						}
						//搜索字符表
						else{
							for(int i=1;i<=60&&strcmp(A,wordTable[i]);i++);
							if(i<=60){			
								s->next=NULL;
								s->sym=i;
								s->value=new char[Lenth];
								strcpy(s->value,A);
								s->line=l;
								addIdList(s);
								delete A;		//删除临时量
							}
							else{
								//加入链表
								s->next=NULL;
								s->sym=36;
								s->value=new char[Lenth];
								strcpy(s->value,A);
								delete A;		//删除临时量
								s->line=l;
								addIdList(s,seq);
							}
						}
						if(line[chars]==0)  break;	
					}
					for(;line[chars]==' '||line[chars]==9;chars++);		
					//滤掉空格或tab
				}
				//modify:运算符可连续
				//----------------------------------------------------------分界符
				if(line[chars]!=0&&!((line[chars]>='0'&&line[chars]<='9')||(line[chars]>='A'
					&&line[chars]<='Z')||(line[chars]>='a'&&line[chars]<='z'))){
					//
					//单引号------------------------------------------------------字符常数
					if(line[chars]==39){
						dyCount++;		//单引号计数
						char *A=new char[Lenth];
						for(int k=0;line[chars]!=0&&line[++chars]!=39;k++){
							A[k]=line[chars];
						}
						A[k]='\0';
						if(line[chars]==39){
							dyCount--;
							chars++;
							Id *s=new Id;
							s->next=NULL;
							s->sym=38;
							s->line=l;
							s->value=new char[Lenth];
							strcpy(s->value,A);
							delete A;		//删除临时量
							int seq;
							addIdList(s,seq);			
						}
						else{	delete A; break;}
						for(;line[chars]==' '||line[chars]==9;chars++);		//滤掉空格或tab
					}
					//-----------------------------------------------记录单界符
					else{
						char *A=new char[Lenth];
						int w=1;		//用来回填'/0'
						A[0]=line[chars++];
						if(A[0]==':'&&line[chars]=='=')	{A[1]=line[chars++];w=0;}
						if(A[0]=='/'&&line[chars]=='*')	{A[1]=line[chars++];w=0;}
						if(A[0]=='.'&&line[chars]=='.') {A[1]=line[chars++];w=0;}
						if(A[0]=='<'&&line[chars]=='=') {A[1]=line[chars++];w=0;}
						if(A[0]=='>'&&line[chars]=='=') {A[1]=line[chars++];w=0;}
						if(A[0]=='<'&&line[chars]=='>') {A[1]=line[chars++];w=0;}
						if(w)	A[1]='\0';
						else	A[2]='\0';
						if(line[chars]>=0){
							for(int i=39;i<61&&strcmp(A,wordTable[i])!=0;i++);
							if(i<61){
								if(i==49){
									//注释符计数,且过滤掉“/*” 符号和后面的所有信息
									for(zsCount++;line[chars]!=0&&!(line[chars++]=='*'&&line[chars++]=='/'););
									if(line[chars-2]=='*'&&line[chars-1]=='/') zsCount--;
								}
								else{
									Id*p=new Id;
									p->next=NULL;
									p->sym=i;
									p->value=new char[Lenth];
									p->line=l;
									strcpy(p->value,A);
									addIdList(p);
								}
							}
							else{
								cout<<"第"<<l<<"行:非字符集定义的字符:"<<line[chars]<<endl;
								if(line[chars]!=0)	chars++;
								work=0;
							}
							//end if
							delete A;
							if(line[chars]==0) break;
						}
					}
					//end if
				}

				for(;line[chars]==' '||line[chars]==9;chars++);		//滤掉空格或tab
				
		}
		if(zsCount!=0){	 cout<<"第"<<l<<"行: 注释符匹配出错!"<<endl;work=0;}
		if(dyCount!=0){  cout<<"第"<<l<<"行: 单引号匹配出错!"<<endl;work=0;}
		delete line;
	}
	cout<<endl;
	
	if(work){
		//输出分析结果
		Id *p=new Id;
		p=IdListHead;
		for(int i=0;p;i++,p=p->next){
			if(i%5==0)	cout<<endl;
			if(p->sym!=36&&p->sym!=37&&p->sym!=38) 
				cout<<"("<<p->sym<<",-)"<<'\t';
			else
				cout<<"("<<p->sym<<","<<p->seq<<")"<<'\t';		
		}
//	}
	//end while
	cout<<endl;
	rwfile.close();
    }
	return work;
}



void main(int argc,char *argv[]){
	cout<<"孙振华"<<'\t'<<"05级网络工程4班"<<'\t'<<"200530491317"<<endl;
		iniWordTable();  //初始字符表
	while(1){
	    wordAnalyst();	//词法分析正确则返回1,否则为0
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -