#include<stdlib.h> #include<stdio.h> #include<string.h> #include<iostream> #define SIZE 128 char priority[6][6]; //算符优先关系表数组 char input[SIZE]; //存放输入的要进行分析的句子 char remain[SIZE]; //存放剩余串 char AnalyseStack[SIZE]; //分析栈 void analyse(); int testchar(char x); //判断字符X在算符优先关系表中的位置 void remainString(); //移进时处理剩余字符串,即去掉剩余字符串第一个字符 int k; void init()//构造算符优先关系表,并将其存入数组中 { priority[1][0]='>'; priority[1][1]='>'; priority[1][2]='<'; priority[1][3]='<'; priority[1][4]='>'; priority[1][5]='>'; priority[2][0]='>'; priority[2][1]='>'; priority[2][2]='$';//无优先关系的用$表示 priority[2][3]='$'; priority[2][4]='>'; priority[2][5]='>'; priority[3][0]='<'; priority[3][1]='<'; priority[3][2]='<'; priority[3][3]='<'; priority[3][4]='='; priority[3][5]='$'; priority[4][0]='>'; priority[4][1]='>'; priority[4][2]='$'; priority[4][3]='$'; priority[4][4]='>'; priority[4][5]='>'; priority[5][0]='<'; priority[5][1]='<'; priority[5][2]='<'; priority[5][3]='<'; priority[5][4]='$'; priority[5][5]='='; } void analyse()//对所输入的句子进行算符优先分析过程的函数 { int i,j,f,z,z1,n,n1,z2,n2; int count=0;//操作的步骤数 char a; //用于存放正在分析的字符 char p,Q,p1,p2; f=strlen(input); //测出数组的长度 for(i=0;i<=f;i++) { a=input[i]; if(i==0) remainString(); if(AnalyseStack[k]=='+'||AnalyseStack[k]=='*'||AnalyseStack[k]=='i' ||AnalyseStack[k]=='('||AnalyseStack[k]==')'||AnalyseStack[k]=='#') j=k; else j=k-1; z=testchar(AnalyseStack[j]);//从优先关系表中查出s[j]和a的优先关系 if(a=='+'||a=='*'||a=='i'||a=='('||a==')'||a=='#') n=testchar(a); else //如果句子含有不是终结符集合里的其它字符,不合法 { printf("错误!该句子不是该文法的合法句子!\n"); break; } p=priority[z][n]; if(p=='$') { printf("错误!该句子不是该文法的合法句子!\n"); return; } if(p=='>') { for( ; ; ) { Q=AnalyseStack[j]; if(AnalyseStack[j-1]=='+'||AnalyseStack[j-1]=='*'||AnalyseStack[j-1]=='i' ||AnalyseStack[j-1]=='('||AnalyseStack[j-1]==')'||AnalyseStack[j-1]=='#') j=j-1; else j=j-2; z1=testchar(AnalyseStack[j]); n1=testchar(Q); p1=priority[z1][n1]; if(p1=='<') //把AnalyseStack[j+1]~AnalyseStack[k]归约为N { count++; printf("(%d) %s\t%10c\t%5c%17s\t 归约\n",count,AnalyseStack,p,a,remain); k=j+1; i--; AnalyseStack[k]='N'; int r,r1; r=strlen(AnalyseStack); for(r1=k+1;r1<r;r1++) AnalyseStack[r1]='\0'; break; } else continue; } } else { if(p=='<') //表示移进 { count++; printf("(%d) %s\t%10c\t%5c%17s\t 移进\n",count,AnalyseStack,p,a,remain); k=k+1; AnalyseStack[k]=a; remainString(); } else { if(p=='=') { z2=testchar(AnalyseStack[j]); n2=testchar('#'); p2=priority[z2][n2]; if(p2=='=') { count++; printf("(%d) %s\t%10c\t%5c%17s\t 接受\n",count,AnalyseStack,p,a,remain); printf("该句子是该文法的合法句子。\n"); break; } else { count++; printf("(%d) %s\t%10c\t%5c%17s\t 移进\n",count,AnalyseStack,p,a,remain); k=k+1; AnalyseStack[k]=a; remainString(); } } else { printf("错误!该句子不是该文法的合法句子!\n"); break; } } } } } int testchar(char x) { int m; if(x=='+') m=0; if(x=='*') m=1; if(x=='i') m=2; if(x=='(') m=3; if(x==')') m=4; if(x=='#') m=5; return m; } void remainString() { int i,j; i=strlen(remain); for(j=0;j<i;j++) remain[j]=remain[j+1]; remain[i-1]='\0'; } int main() { init(); printf("请输入要进行分析的句子(以#号结束输入):\n"); gets(input);//将输入的字符串存到数组中 printf("步骤 栈 优先关系 当前符号 剩余输入串 移进或归约\n"); k=0; AnalyseStack[k]='#'; AnalyseStack[k+1]='\0'; int length,i; //初始化剩余字符串数组为输入串 length=strlen(input);// for(i=0;i<length;i++) remain[i]=input[i]; remain[i]='\0'; analyse();//对所输入的句子进行算符优先分析过程的函数 return 0; }