1、2016.5.26一、 实验目的和要求实验目的:设计、编制、调试一个LL(1)语法分析器,利用语法分析器对符号串的识别,加深对语法分析原理的理解。实验要求:1、检测左递归,如果有则进行消除;2、求解FIRST集和FOLLOW集;3、构建LL(1)分析表;4、构建LL分析程序,对于用户输入的句子,能够利用所构造的分析程序进行分析,并显示出分析过程。以上实验要求可分两个同学完成。例如构建分析表一个同学完成、构建分析程序并分析符号串另一个同学完成。二、实验环境(实验设备) 硬件:计算机 软件:Visual C +6.0二、 实验原理及内容实验内容:设计并实现一个LL(1)语法分析器,实现对算术文法G
2、E:E-E+T|T T-T*F|F F-(E)|i所定义的符号串进行识别,例如符号串abc+age+80为文法所定义的句子,符号串(abc-80(*s5)不是文法所定义的句子。实验代码:#includestringiostreamusing namespace std;void input_grammer(string *G)/输入文法G,n个非终结符 int i=0;/计数 char ch=y; while(ch=) cinGi+; cout继续输入?(y/n)nch; void preprocess(string *G,string *P,string &U,string &u,int &
3、n,int &t,int &k)/将文法G预处理产生式集合P,非终结符、终结符集合U、u, int i,j,r,temp; char C;/记录规则中()后的符号 int flag;/检测到() n=t=k=0; for( i=0;i50;i+) Pi= /字符串如果不初始化,在使用Pij=a时将不能改变,可以用Pi.append(1,a) U=u= /字符串如果不初始化,无法使用Ui=a赋值,可以用U.append(1,a) for(n=0;!Gn.empty();n+) Un=Gn0; /非终结符集合,n为非终结符个数 for(i=0;n;i+) for(j=4;jGi.length();
4、j+) if(U.find(Gij)=string:npos&u.find(Gij)=string:npos) if(Gij!=|Gij!) /if(Gij!() ut+=Gij; /终结符集合,t为终结符个数 flag=0;r=4; Pk0=Ui;Pk1=Pk2=Pk3= /* if(Gij= j+;flag=1; for(temp=j;Gitemp!temp+); C=Gitemp+1; /C记录()后跟的字符,将C添加到()中所有字符串后面 if(Gij=) j+;flag=0; */ /if(flag=1) Pkr+=C; k+;j+; Pk0=Ui; r=4; Pkr+=Gij; e
5、lse Pkr+=Gij; k+; /获得产生式集合P,k为产生式个数int eliminate_1(string *G,string *P,string U,string *GG)/消除文法G1中所有直接左递归得到文法G2,要能够消除含有多个左递归的情况)string arfa,beta;/所有形如A:=A|中的、连接起来形成的字符串arfa、betaint i,j,temp,m=0;int flag=0;/flag=1表示文法有左递归int flagg=0;/flagg=1表示某条规则有左递归char C=A/由于消除左递归新增的非终结符,从A开始增加,只要不在原来问法的非终结符中即可加入
6、for(i=0;20&Ui! flagg=0; arfa=beta= for(j=0;100&Pj0! if(Pj0=Ui) if(Pj4=Ui)/产生式j有左递归 flagg=1; for(temp=5;Pjtemp!temp+) arfa.append(1,Pjtemp); if(Pj+14=Ui) arfa.append(|);/不止一个产生式含有左递归 else for(temp=4;temp+) beta.append(1,Pjtemp); if(Pj+10=Ui&Pj+14!=Ui) beta.append( if(flagg=0)/对于不含左递归的文法规则不重写 GGm=Gi;
7、m+; else flag=1;/文法存在左递归 GGm.append(1,Ui);GGm.append(= if(beta.find()!=string:npos) GGm.append(+beta+) else GGm.append(beta); while(U.find(C)!npos)C+; GGm.append(1,C); m+; if(arfa.find(+arfa+ else GGm.append(arfa);| C+; /A:=A|改写成A:=A,A=A|,return flag;int* ifempty(string* P,string U,int k,int n) int*
8、 empty=new int n;/指示非终结符能否推导到空串 int i,j,r; for(r=0;rr+) emptyr=0;/默认所有非终结符都不能推导到空 int flag=1;/1表示empty数组有修改 int step=100;/假设一条规则最大推导步数为步 while(step-) for(i=0;k; r=U.find(Pi0); if(Pi4=) emptyr=1;/直接推导到空 else for(j=4;Pij! if(U.find(Pij)! if(emptyU.find(Pij)=0) break; else break; if(Pij=/多步推导到空 else flag=0; return empty;string* FIRST_X(string* P,string U,string u,int* empty,int k,int n) int i,j,r,s,tmp; string* first=new stringn; char a; int step=100;/最大推导步数 while(step-) / coutstep100-stependl;i
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1