编译原理实验3-算符优先分析法
#include<stdlib.h>#include<stdio.h>#include<string.h>#include<iostream>#define SIZE 128char 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;elsej=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;}