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

📄 word.cpp

📁 一个语法分析
💻 CPP
字号:
#include<iostream.h>
#include<string.h>
#include<stdio.h>
#define len 200
#define readpath "sourse.txt"
#define savepath "result.txt"
char getch(FILE *);
bool isNum(char);
bool isLet(char);
bool isOther(char);
void writeFile();
void clearStr();
void makeOp();
void makeId(char *);
void makeNum();
typedef FILE *stream;
char gchar[len];
int cxf=0;
int cxn=0;
char strToken[10];
int str=0;
char chF;
char chLater;
struct table{
	char id[10];
	char type;
}tab[len];
int tabN=0;
//两个的块变量分割
int iStack[100];
char cStack[100];
int tx=0;
int ix=1;
int cx=1;
char ch,ch1;                //当前取得的字符
/*struct table{
	char id[20];
	char mn;
}tab[]={{"void",'w'},{" ",' '},{"main",'m'},{"(",'('},{")",')'},{"{",'{'},{"int",'t'},{" ",' '},{"a",'i'},{";",';'},{"a",'i'},{"=",'='},{"3",'u'},{";",';'},{"if",'f'},{"(",'('},{"a",'i'},{"*",'o'},{"3",'u'},{")",')'},{"{",'{'},{"a",'i'},{"=",'='},{"a",'i'},{"+",'o'},{"3",'u'},{";",';'},{"}",'}'},{"return",'n'},{";",';'},{"}",'}'},{"#",'#'}};
//tab[]={{"void",'w'},{" ",' '},{"main",'m'},{"(",'('},{")",')'},{"{",'{'},{"int",'t'},{" ",' '},{"a",'i'},{";",';'},{"while",'y'},{"(",'('},{"a",'i'},{"*",'*'},{"3",'u'},{")",')'},{"{",'{'},{"a",'i'},{"=",'='},{"a",'i'},{"+",'+'},{"3",'u'},{";",';'},{"}",'}'},{"return",'n'},{";",';'},{"}",'}'},{"#",'#'}};*/
struct analyseTab{
	char c;
	int i;
	char gen[3];
};
char col[]={"wm(){}t i;fy=oun#PFHBDSRTE"};
char row[]={"PFHBDSRTE"};
struct analyseTab anal[63][26];
void initAnalyseTab()
{
	
	int i=0,j=0;
	for(i=0;i<63;i++)
		for(j=0;j<26;j++)
		{
			anal[i][j].c=col[j];
			anal[i][j].i=i;
		}
    for(j=0;j<16;j++)
	{
		strcpy(anal[2][j].gen,"r1");
		strcpy(anal[5][j].gen,"r2");
		strcpy(anal[12][j].gen,"r7");
		strcpy(anal[21][j].gen,"r10");
		strcpy(anal[29][j].gen,"r3");
		strcpy(anal[30][j].gen,"r4");
		strcpy(anal[31][j].gen,"r17");
		strcpy(anal[35][j].gen,"r15");
		strcpy(anal[36][j].gen,"r16");
		strcpy(anal[40][j].gen,"r6");
		strcpy(anal[46][j].gen,"r13");
		strcpy(anal[47][j].gen,"r5");
		strcpy(anal[51][j].gen,"r14");
		strcpy(anal[59][j].gen,"r8");
		strcpy(anal[60][j].gen,"r9");
		strcpy(anal[61][j].gen,"r11");
		strcpy(anal[62][j].gen,"r12");
	}
	strcpy(anal[0][0].gen,"s4");
	strcpy(anal[3][4].gen,"s6");
	strcpy(anal[4][7].gen,"s7");
	strcpy(anal[6][6].gen,"s9");
	strcpy(anal[7][1].gen,"s10");
	strcpy(anal[8][6].gen,"s16");
	strcpy(anal[8][8].gen,"s15");
	strcpy(anal[8][10].gen,"s13");
	strcpy(anal[8][11].gen,"s14");
	strcpy(anal[9][7].gen,"s17");
	strcpy(anal[10][2].gen,"s18");
	strcpy(anal[11][8].gen,"s15");
	strcpy(anal[11][10].gen,"s22");
	strcpy(anal[11][11].gen,"s23");
	strcpy(anal[11][15].gen,"s20");
	strcpy(anal[13][2].gen,"s24");
	strcpy(anal[14][2].gen,"s25");
	strcpy(anal[15][12].gen,"s26");
	strcpy(anal[16][7].gen,"s27");
	strcpy(anal[17][8].gen,"s28");
	strcpy(anal[18][3].gen,"s29");
	strcpy(anal[19][5].gen,"s30");
	strcpy(anal[20][9].gen,"s31");
	strcpy(anal[22][2].gen,"s32");
	strcpy(anal[23][2].gen,"s33");
	strcpy(anal[24][8].gen,"s36");
	strcpy(anal[24][14].gen,"s35");
	strcpy(anal[25][8].gen,"s36");
	strcpy(anal[25][14].gen,"s35");
	strcpy(anal[26][8].gen,"s36");
	strcpy(anal[26][14].gen,"s35");
	strcpy(anal[27][8].gen,"s39");
	strcpy(anal[28][9].gen,"s40");
	strcpy(anal[32][8].gen,"s36");
	strcpy(anal[32][14].gen,"s35");
	strcpy(anal[33][8].gen,"s36");
	strcpy(anal[33][14].gen,"s35");
	strcpy(anal[34][3].gen,"s43");
	strcpy(anal[34][13].gen,"s44");
	strcpy(anal[37][3].gen,"s45");
	strcpy(anal[37][13].gen,"s44");
	strcpy(anal[38][9].gen,"s46");
	strcpy(anal[38][13].gen,"s44");
	strcpy(anal[39][9].gen,"s47");
	strcpy(anal[41][3].gen,"s48");
	strcpy(anal[41][13].gen,"s44");
	strcpy(anal[42][3].gen,"s49");
	strcpy(anal[42][13].gen,"s44");
	strcpy(anal[43][4].gen,"s50");
	strcpy(anal[44][8].gen,"s36");
	strcpy(anal[44][14].gen,"s35");
	strcpy(anal[45][4].gen,"s52");
	strcpy(anal[48][4].gen,"s53");
	strcpy(anal[49][4].gen,"s54");
	strcpy(anal[50][8].gen,"s15");
	strcpy(anal[50][10].gen,"s13");
	strcpy(anal[50][11].gen,"s14");
	strcpy(anal[52][8].gen,"s15");
	strcpy(anal[52][10].gen,"s13");
	strcpy(anal[52][11].gen,"s14");
	strcpy(anal[53][8].gen,"s15");
	strcpy(anal[53][10].gen,"s13");
	strcpy(anal[53][11].gen,"s14");
	strcpy(anal[54][8].gen,"s15");
	strcpy(anal[54][10].gen,"s13");
	strcpy(anal[54][11].gen,"s14");
	strcpy(anal[55][5].gen,"s59");
	strcpy(anal[55][8].gen,"s15");
	strcpy(anal[55][10].gen,"s22");
	strcpy(anal[55][11].gen,"s23");
	strcpy(anal[56][5].gen,"s60");
	strcpy(anal[56][8].gen,"s15");
	strcpy(anal[56][10].gen,"s22");
	strcpy(anal[56][11].gen,"s23");
	strcpy(anal[57][5].gen,"s61");
	strcpy(anal[57][8].gen,"s15");
	strcpy(anal[57][10].gen,"s22");
	strcpy(anal[57][11].gen,"s23");
	strcpy(anal[58][5].gen,"s62");
	strcpy(anal[58][8].gen,"s15");
	strcpy(anal[58][10].gen,"s22");
	strcpy(anal[58][11].gen,"s23");
	strcpy(anal[0][17].gen,"1");
	strcpy(anal[0][18].gen,"2");
	strcpy(anal[0][19].gen,"3");
	strcpy(anal[3][20].gen,"5");
	strcpy(anal[6][21].gen,"8");
	strcpy(anal[8][22].gen,"11");
	strcpy(anal[8][25].gen,"12");
	strcpy(anal[11][23].gen,"19");
	strcpy(anal[11][25].gen,"21");
	strcpy(anal[24][24].gen,"34");
	strcpy(anal[25][24].gen,"37");
	strcpy(anal[26][24].gen,"38");
	strcpy(anal[32][24].gen,"41");
	strcpy(anal[33][24].gen,"42");
	strcpy(anal[44][24].gen,"51");
	strcpy(anal[50][22].gen,"55");
	strcpy(anal[50][25].gen,"12");
	strcpy(anal[52][22].gen,"56");
	strcpy(anal[52][25].gen,"12");
	strcpy(anal[53][22].gen,"57");
	strcpy(anal[53][25].gen,"12");
	strcpy(anal[54][22].gen,"58");
	strcpy(anal[54][25].gen,"12");
	strcpy(anal[55][25].gen,"21");
	strcpy(anal[56][25].gen,"21");
	strcpy(anal[57][25].gen,"21");
	strcpy(anal[58][25].gen,"21");
}
char *r[]={"","P->F","F->HB","H->w m()","B->{DSR}","D->Dt i;","D->t i;","S->E","S->f(T){S}","S->y(T){S}","S->SE","S->Sf(T){S}","S->Sy(T){S}","E->i=T;","T->ToT","T->u","T->i","R->n;"};
void push(int i,char c)
{
	iStack[ix++]=i;
	cStack[cx++]=c;
}
void show()
{
	cout<<"可能有错误语句为:"<<"'"<<tab[tx-1].id<<"'"<<endl;
	cout<<"错误位置:在语句'"<<tab[tx-2].id<<"'和'"<<tab[tx].id<<"'之间!"<<endl;
}
void pop(int i)
{
	ix-=i;
	cx-=i;
}
void errorMessage(int num,char loc)
{
	show();
	//cout << "错误位置:" << loc << endl;
	cout << "错误原因:(" << num << ")";
	switch(num)
	{
	case 0:cout << "函数头定义有错!" << endl;break;
	//case 1:
	//case 2:
	case 43:
	case 45:
	case 46:
	case 47:
	case 3:cout << "函数体必须从'{'开始!" << endl;break;
	case 4:cout << "函数头定义错误!" << endl;break;
	//case 5:
	case 6:cout << "函数体必须从'{'开始!" << endl;break;
	case 7:cout << "必须以main为函数入口!" << endl;break;//必须以main为函数入口
	case 8:cout << "未申明变量或者while,if语法错误!" << endl;break;//未申明变量
	case 16:
	case 9:cout << "缺少空格!" << endl;break;//缺少空格*
	case 13:
	case 14:
	case 10:cout << "缺少左括号!" << endl;break;//缺少左括号
	case 11:cout <<"语句顺序不符合语法规定(if or while)或应为return语句!"<< endl;break;//嵌套语句有错误???
	case 15:cout << "表达式错误!" << endl;break;
	case 27:
	case 17:cout << "变量声明错误!" << endl;break;
	case 18:cout << "缺少右括号!" << endl;break;
	case 19:cout << "函数体,语句体必须从'}'结束!" << endl;break;
	case 20:cout << "语句必须以';'结束!(return)" << endl;break;//信息有错误
//	case 21:
	case 22:
	case 23:cout << "缺少左括号!" << endl;break;//缺少左括号
	case 24:
	case 25:
	case 32:
	case 33:
	case 44:
//	case 25:cout << "语句必须以';'结束!" << endl;break;
	case 26:cout << "赋值语句错误!" << endl;break;
//	case 27:cout << "(47)函数体,语句体必须从'}'结束" << endl;break;
	case 39:
	case 28:cout << "语句必须以';'结束!" << endl;break;
	case 41:
	case 37:
	case 34:cout << "表达式或者条件表达式错误!" << endl;break;//运算符号出错
	case 38:cout << "变量定义或赋值有误!" << endl;break;
	case 50:
	case 52:
	case 53:
	case 54:cout <<"语句体内部语句顺序有误!"<< endl;break;//id if while
	case 55:
	case 56:
	case 57:
	case 58:cout <<"语句顺序不符合语法规定!"<< endl;break;//id if while
	}
}
void  gramany()         /// w void, t int, i id ,f if, y while,n return ; 
{                   //// m main
	int s=0;
	int ri=0;
	int gt=0;
	char temp[3];
	ch=tab[tx++].type;
	ch1=ch;
    for(int i=0;tab[i].type!='#';i++)
		cout << tab[i].id;
	cout << endl;
	initAnalyseTab();
	iStack[0]=0;
	cStack[0]='#';
	while(1)
	{
		    strcpy(temp,anal[s][0].gen);
			if(s==1)
			{
			cout << "语法无错误!"<< endl;
			return ;
			}
			if(temp[0]=='r')                       //规约
			{
				if(strlen(temp)>2)
			    ri=(temp[1]-48)*10+temp[2]-48;
				else 
			    ri=temp[1]-48;
				pop(strlen(r[ri])-3);
				ch=r[ri][0];
				s=iStack[ix-1];
			}
			else    
			{
			 for(int j=0;j<26;j++)
			 {
				  strcpy(temp,anal[s][j].gen);
			   if(anal[s][j].c==ch&&strcmp(temp,""))
			   {
			    if(anal[s][j].c<'Z'&&anal[s][j].c>'A')         //非终结符
				{					
				    if(strlen(temp)>1)
					s=(temp[0]-48)*10+temp[1]-48;
					else 
					s=temp[0]-48;
					push(s,anal[s][j].c);
					ch=ch1;
					break;
				}
				else               //终结符
				{
				 if(strlen(temp)>2)
				  s=(temp[1]-48)*10+temp[2]-48;
				 else 
				  s=temp[1]-48;
			     push(s,ch);		 
				 ch=tab[tx++].type;
				 ch1=ch;
				 break;
				}				
			   }
			 } //end for
			 if(j==26)
			   {
				   errorMessage(s,ch);
				   return;
			   }
			}             //end else
	}                 //end while
}
void main()
{
	stream f_out;
	f_out=fopen(readpath,"r");
	if(NULL==f_out){printf("read file error!");return;}
	printf("一下为输入的源程序:\n");
	chF=fgetc(f_out);
	putchar(chF);
	while(chF!=EOF)
	{
		gchar[cxf++]=chF;
		chF=getch(f_out);
	}
	cxn=cxf;
	cxf=0;
	while(true)
	{	
		while(' '==gchar[cxf])
		{
			gchar[++cxf];//只有系统保留字或者变量申明后的空格有效
		}
		if(0==cxn--){printf("\n源程序分割执行完毕!");break;}
		if(isLet(gchar[cxf]))
		{
			while(true)
			{
				strToken[str++]=gchar[cxf++];
				if(isNum(gchar[cxf])||isLet(gchar[cxf]))continue;//是数字或者字母可以继续
				if(' '==gchar[cxf])
				{
					makeId(strToken);
					strToken[str++]=gchar[cxf++];
					strcpy(tab[tabN].id,strToken);
					tab[tabN].type=' ';
					clearStr();
					break;
				}
				if(isOther(gchar[cxf]))//第一个肯定是letter
				{
					makeId(strToken);
					strToken[str++]=gchar[cxf++];
					if('('==gchar[cxf]||')'==gchar[cxf]||'{'==gchar[cxf]||'}'==gchar[cxf]||('='==gchar[cxf-1]&&'='!=gchar[cxf]))
					{
						makeOp();
						break;
					}
					if(isOther(gchar[cxf]))
					{
						strToken[str++]=gchar[cxf++];
						makeOp();
						break;
					}
					else
					{
						makeOp();
						break;
					}
				}
			}
		}
		else if(isNum(gchar[cxf]))
		{
			while(true)
			{
				strToken[str++]=gchar[cxf++];
				if(isNum(gchar[cxf]))continue;
				else if(isLet(gchar[cxf]))
				{
					printf("变量申明或数值有误!");
					break;
				}
				while(' '==gchar[cxf])
				{
					gchar[++cxf];//只有系统保留字或者变量申明后的空格有效
				}
				if(isOther(gchar[cxf]))
				{
					makeNum();
					strToken[str++]=gchar[cxf++];
					if('('==gchar[cxf]||')'==gchar[cxf]||'{'==gchar[cxf]||'}'==gchar[cxf]||('='==gchar[cxf-1]&&'='!=gchar[cxf]))
					{
						makeOp();
						break;
					}
					if(isOther(gchar[cxf]))
					{
						strToken[str++]=gchar[cxf++];
						makeOp();
						break;
					}
					else
					{
						makeOp();
						break;
					}
				}	
			}
		}
		else if(isOther(gchar[cxf]))
		{
		 	strToken[str++]=gchar[cxf++];
			if('('==gchar[cxf]||')'==gchar[cxf]||'{'==gchar[cxf]||'}'==gchar[cxf]||('='==gchar[cxf-1]&&'='!=gchar[cxf]))
			{
				makeOp();
			}
			if(isOther(gchar[cxf]))
			{
				strToken[str++]=gchar[cxf++];
				makeOp();
			}
			else
			{
				makeOp();
			}
		}
	}
	strcpy(tab[tabN].id,"#");
	tab[tabN].type='#';
	printf("\n共分割了:%d 字符!",tabN);
	for(int i=0;i<tabN+1;i++)
	{
		printf("\n%s ",tab[i].id);
		putchar(tab[i].type);
	}
	char more1=' ';		
	printf("\n需要将以上分析结果保存吗?(Y/N)");	
	cin>>more1;
	if('y'==more1||'Y'==more1){writeFile();printf("\n保存的文件名为result.txt\n");}
	gramany();
	return;
}
char getch(stream f_in)
{
	char t_ch=' ';
	if(t_ch!=EOF)
	{
		t_ch=fgetc(f_in);
		putchar(t_ch);
		while('\n'==t_ch||'\t'==t_ch)
		{
			t_ch=fgetc(f_in);
			putchar(t_ch);
		}
		return t_ch;
	}
	else fclose(f_in); 
	return '@';
}
bool isNum(char t)
{
	if(t>='0'&&t<='9')
		return true;
	else return false;
}
bool isLet(char t)
{
	if(t>='a'&&t<='z')
		return true;
	else return false;
}
bool isOther(char t)
{
	switch(t)
	{
		case ';':
		case '{':
		case '}':
		case '(':
		case ')':
		case '=':
		case '+':
		case '-':
		case '*':
		case '/':
		case '>':
		case '<':
		case '!':
		case '&':
		case '|':return true;
		default:return false;
	}
}
void writeFile()
{
	stream f_in;
	f_in=fopen(savepath,"w");
	if(NULL==f_in){printf("Creat or Read file error!");return;}
	for(int i=0;i<tabN;i++)
	{
		fprintf(f_in,"%s\t%c\n",tab[i].id,tab[i].type);
	}
	printf("Write file OK!");
	fclose(f_in);
}
void clearStr()
{
	for(int i=0;i<10;i++)
	{
		strToken[i]=NULL;
	}
	str=0;
	tabN++;
}
void makeOp()
{
	strcpy(tab[tabN].id,strToken);
	if(!strcmp(strToken,"("))tab[tabN].type='(';//return;
	else if(!strcmp(strToken,")"))tab[tabN].type=')';//return;
	else if(!strcmp(strToken,"{"))tab[tabN].type='{';//return;
	else if(!strcmp(strToken,"}"))tab[tabN].type='}';//return;
	else if(!strcmp(strToken,";"))tab[tabN].type=';';//return;
	else if(!strcmp(strToken,"="))tab[tabN].type='=';//return;
	else tab[tabN].type='o';
	clearStr();
}
void makeId(char *strtemp)
{
	strcpy(tab[tabN].id,strToken);
	if(!strcmp(strToken,"void"))tab[tabN].type='w';//return;
	else if(!strcmp(strToken,"while"))tab[tabN].type='y';//return;
	else if(!strcmp(strToken,"int"))tab[tabN].type='t';//return;
	else if(!strcmp(strToken,"return"))tab[tabN].type='n';//return;
	else if(!strcmp(strToken,"if"))tab[tabN].type='f';//return;
	else if(!strcmp(strToken,"main"))tab[tabN].type='m';//return;
	else tab[tabN].type='i';
	clearStr();
}
void makeNum()
{
	strcpy(tab[tabN].id,strToken);
	tab[tabN].type='u';
	clearStr();
}

⌨️ 快捷键说明

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