对于给定的文法G[E] :
E→E+T|E-T|T
T→T*F| T/F|F
F→(E)|i
消除左递归后的文法是:
E→TE'
E'→+TE'|-TE'|∑
T→FT'
T'→*FT'|/FT'|∑
F→(E)|i
是否是LL(1)文法?
select(E→TE')=first(TE')={(,i}
select(E'→+TE')=first(+TE')={+}
select(E'→-TE')=first(-TE')={-}
select(E'→∑)=follow(E')={),#}
select(T→FT')=first(FT')={(,i}
select(T'→*FT')=first(*FT')={*}
select(T'→/FT')=first(/FT')={/}
select(T'→∑)=follow(T')={+,-,),#)
select(F→(E))=first((E))={(}
select(F→i)=first(i)={i}
由上分析,得知此文法满足LL(1)文法.
C语言代码如下:
#include<stdio.h> #include <string.h> void scaner(); void E(); void E1(); void T(); void T1(); void F(); void error(); char proce[100],ch,token[20]; int syn,i,j,m,sum=0; char *keyword[6]= {"begin","if","then","while","do","end"}; main() {i=0;//记录输入多少个字符printf("\n 请输入词法分析程序:");do{ch=getchar();proce[i]=ch;i++;}while (ch!='#');i=0;do{scaner();switch(syn){case 11: printf("\n(%d,%d)",syn,sum);break;case -1: printf("\n(%s,#)",token);break;default: printf("\n(%d,%s)",syn, token);}}while (syn!=0);printf("\n");i=0;scaner();E();if (syn==0)printf("\n 语法正确. \n");else printf("\n 语法失败. \n");} void scaner() {for (j=0;j<20;j++)token[j]=NULL;//将token赋值为空m=0;sum=0;ch=proce[i];i++;while (ch==' '){ch=proce[i++];}if (ch>='a'&& ch<='z'){while (ch>='a'&& ch<='z'||ch>='0' && ch<='9'){token[m++]=ch;ch=proce[i++];//继续看后面的 }syn=10;i--;//判断为变量for (j=0;j<6;j++)if(strcmp(token,keyword[j])==0){syn=j+1;break;}//如果有可以匹配的就为关键字 }elseif(ch>='0' && ch<='9'){while (ch>='0' && ch<='9'){sum=sum*10+(ch-'0');ch=proce[i];i++;}syn=11;i--;}elseswitch(ch){case '<': token[m]=ch;m++;ch=proce[i];i++;if (ch=='>'){syn=21;token[m]=ch;m++;}else if (ch=='='){syn=22;token[m]=ch;m++;}else{syn=20;i--;}break;case '>': m=0;token[m]=ch;m++;ch=proce[i];i++;if (ch=='='){syn=24;token[m]=ch;m++;}else{syn=23;i--;}break;case ':': m=0;token[m++]=ch;ch=proce[i++];if (ch=='='){syn=18;token[m++]=ch;}else{syn=17;i--;}break;case '+':syn=13;token[0]=ch;break;case '-':syn=14;token[0]=ch;break;case '*':syn=15;token[0]=ch;break;case '/':syn=16;token[0]=ch;break;case '=':syn=25;token[0]=ch;break;case ';':syn=26;token[0]=ch;break;case '(':syn=27;token[0]=ch;break;case ')':syn=28;token[0]=ch;break;case '#':syn=0;token[0]=ch;break;default:syn=-1;token[0]=ch;} }
void E() {printf("E ");T();E1();} void E1() {printf("E1 ");if (syn==13){scaner();T();E1();}else {if (syn!=28 && syn!=0)error();} } void T() {printf("T ");F();T1(); } void T1() {printf("T1 ");if (syn==15) {scaner();F();T1();}else {if (syn!=28 && syn!=0 && syn!=13) error();} }void F() {printf("F ");if (syn==27){scaner();E();if(syn==28) scaner();else error();}else if (syn==11 || syn==10)scaner(); }void error() {printf("\n (%d,%s)语法错误! \n",syn, token); }