LL1语法分析实验报告
LL1语法分析设计原理与实现技术实验报告
LL(1)语法分析设计原理与实现技术实验报告变更说明、实验目的:本实验的目的在于在教师的引导下以问题回朔与思维启发的方式, 使学生在不断的探究过程中掌握编译程序设计与构造的基本原理与实现技术, 启迪学生的抽象思维、激发学生的学习兴趣、培养学生的探究精神与专业素养, 从而提高学生发现问题、分析问题与解决问题的能力。
、实验内容[ 实验项目]实现LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的LL(1)文法的LL(1)分析程序。
G[E]: E —TEE'—ATE | &T—F「T'—MFT | &F—(E)|iA—+|-M—*|/[ 实验说明]终结符号i 为用户定义的简单变量, 即标识符的定义。
[ 设计要求](1) 输入串应就是词法分析的输出二元式序列,即某算术表达式“实验项目一”的输出结果。
输出为输入串就是否为该文法定义的算术表达式的判断结果(2) LL(1) 分析过程应能发现输入串出错;(3) 设计两个测试用例(尽可能完备,正确与出错), 并给出测试结果。
三、实验环境操作系统:Windows 7 软件: VC++6、0四、程序功能描述提供了文件输入方式, 且输入的内容为二元式序列; 能够对输入的字符串做出正确的LL(1) 分析判断,并给出判断结果,判断结果输出到文件, 并显示在屏幕;能发现输入串中的错误,包含非法字符, 输入不匹配等; 能够处理一些可预见性的错误,如文件不存在, 输入非法等。
五、数据结构设计全局:MAX 50ch^r dn^lvseSt^cl<[MAX]; 丿/勺〜析丰戋char toRen[HAJ<]|; "匾人車typedef= struct CSS "严主式结构体<char loft;char Klgtlt[5];int rightlength;}CSS; _CSS E,G9G1,T9H,H1,F.F1P A,A1P M JI1 ;|CSS anali)5elable[7][8];局部(mai n()中):int nain()<C1 h 3 厂 a "int i=0,j = 0f ni,u=6(u=n;"i指示栈顶位貳j扌繇剩余串扫描位置Int num un,num ut;bool Flag=true;char tokenl[MAK];char t oken2[HAX];FILE *fpin,*fpout;六、程序结构描述设计方法:本程序采用从文件读取的输入方式,输入的内容需为二元式序列,然后按照LL(1)分析的方法对输入的字符串进行分析判断,并输出判断结果,程序通过对输入串的检查能够发现输入串中的错误。
编译原理实验报告《ll(1)语法分析器构造》
规则右部首符号是终结
符
.
.
{ first[r].append(1,a); break;// 添加并结束
}
if(U.find(P[i][j])!=string::npos)// 规则右部首符号是非终结符 ,形如 X:: =Y1Y2...Yk
{
s=U.find(P[i][ j]);
//cout<<P[i][ j]<<":\n";
arfa=beta=""; for( j=0;j<100&&P[j][0]!=' ';j++) {
if(P[ j][0]==U[i]) {
if(P[ j][4]==U[i])// 产生式 j 有左递归 {
flagg=1;
.
.
for(temp=5;P[j][temp]!=' ';temp++) arfa.append(1,P[
{
int i,j,r,s,tmp;
string* first=new string[n];
char a;
int step=100;// 最大推导步数
while(step--){
// cout<<"step"<<100-step<<endl;
for(i=0;i<k;i++)
{
//cout<<P[i]<<endl;
j][temp]);
if(P[ j+1][4]==U[i]) arfa.append("|");//
LL1语法分析
北华航天工业学院《编译原理》课程实验报告课程实验题目:LL(1)语法分析实验作者所在系部:计算机科学与工程系作者所在专业:计算机科学与技术作者所在班级:xxx作者学号:xxxxx _ 作者姓名:xxxx指导教师姓名:xxxx完成时间:2011年4月28日一、实验目的理解预测分析表方法的实现原理。
二、实验内容及要求编写一通用的预测法分析程序,要求有一定的错误处理能力,出错后能够使程序继续运行下去,直到分析过程结束。
可通过不同的文法(通过数据表现)进行测试。
给定算术表达式文法,编写程序。
测试数据:1.算术表达式文法E→TE’E’→ +TE’|- TE’|εT→FT’T’→*FT’ |/ FT’ |%FT’|εF→(E) |id|num2.作业3.10 文法三、实验程序设计说明1.实验方案设计主要函数之间的调用关系如下图所示:2.程序源代码源代码如下:#include <iostream>#include <cstdio>#include <stack>using namespace std;struct Node1{ char vn;char vt;char s[10];}MAP[20];//存储分析预测表每个位置对应的终结符,非终结符,产生式int k;//用R代表E',W代表T',e代表空char start='E';int len=8;charG[10][10]={"E->TR","R->+TR","R->e","T->FW","W->*FW","W->e","F->(E)","F->i "};//存储文法中的产生式char VN[6]={'E','R','T','W','F'};//存储非终结符char VT[6]={'i','+','*','(',')','#'};//存储终结符char SELECT[10][10]={"(,i","+","),#","(,i","*","+,),#","(","i"};//存储文法中每个产生式对应的SELECT集char Right[10][8]={"->TR","->+TR","->e","->FW","->*FW","->e","->(E)","->i"}; //用R代表A',W代表B',e代表空/*char start='A';int len=6;char G[10][10]={"A->aR","R->ABl","R->e","B->dW","W->bW","W->e"};char VN[6]={'A','R','B','W'};char VT[6]={'a','d','b','#','l'};char SELECT[10][10]={"a","a","d,#","d","b","l"};char Right[10][6]={"->aR","->ABl","->e","->dW","->bW","->e"};*/stack <char> stak;bool compare(char *a,char *b){ int i,la=strlen(a),j,lb=strlen(b);for(i=0;i<la;i++)for(j=0;j<lb;j++){ if(a[i]==b[j])return 1; }return 0;}char *Find(char vn,char vt){ int i;for(i=0;i<k;i++){ if(MAP[i].vn==vn && MAP[i].vt==vt)return MAP[i].s;}return "error";}char * Analyse(char * word){ char p,action[10],output[10];int i=1,j,l=strlen(word),k=0,l_act,m;while(!stak.empty())stak.pop();stak.push('#');stak.push(start);printf("___________________________________________________________\n");printf("\n 对符号串%s的分析过程\n",word);printf(" -----------------------------------------------------------------------\n");printf("\n");printf(" 步骤栈顶元素剩余输入串动作\n");printf(" -----------------------------------------------------------------------\n");p=stak.top();while(p!='#'){ printf("%7d ",i++);p=stak.top();stak.pop();printf("%6c ",p);for(j=k,m=0;j<l;j++)output[m++]=word[j];output[m]='\0';printf("%10s",output);if(p==word[k]){ if(p=='#'){ printf(" 分析成功\n");return "SUCCESS";}printf(" 匹配终结符“%c”\n",p);k++;}else{ strcpy(action,Find(p,word[k]));if(strcmp(action,"error")==0){ printf(" 没有可用的产生式\n");return "ERROR"; }printf(" 展开非终结符%c%s\n",p,action);int l_act=strlen(action);if(action[l_act-1]=='e')continue;for(j=l_act-1;j>1;j--)stak.push(action[j]);}} if(strcmp(output,"#")!=0)return "ERROR";}int main (){ freopen("in1.txt","r",stdin);//freopen("in2.txt","r",stdin);char source[100];int i,j,flag,l,m;//printf("\n***为了方便编写程序,用R代表E',W代表T',e代表空*****\n\n");printf("\n****为了方便编写程序,用R代表A',W代表B',e代表空*****\n\n");printf("该文法的产生式如下:\n");for(i=0;i<len;i++)printf(" %s\n",G[i]);printf("___________________________________________________________\n");printf("\n该文法的SELECT集如下:\n");for(i=0;i<len;i++){ printf(" SELECT(%s) = { %s }\n",G[i],SELECT[i]); }printf("___________________________________________________________\n");//判断是否是LL(1)文法flag=1;for(i=0;i<8;i++){ for(j=i+1;j<8;j++){if(G[i][0]==G[j][0]){ if(compare(SELECT[i],SELECT[j])){flag=0;break;}}} if(j!=8)break; }if(flag)printf("\n有相同左部产生式的SELECT集合的交集为空,所以文法是LL(1)文法。
LL1语法分析程序实验报告
LL1语法分析程序实验报告实验目的:通过编写LL(1)语法分析程序,加深对语法分析原理的理解,掌握语法分析方法的实现过程,并验证所编写的程序的正确性。
实验准备:1.了解LL(1)语法分析的原理和步骤;2.根据语法规则,构建一个简单的文法;3.准备一组测试用例,包括符合语法规则的输入和不符合语法规则的输入。
实验步骤:1.根据文法规则,构建预测分析表;2.实现LL(1)语法分析程序;3.编写测试用例进行测试;4.分析测试结果。
实验结果:我根据上述步骤,编写了一个LL(1)语法分析程序,并进行了测试。
以下是我的测试结果:测试用例1:输入:9+7*(8-5)分析结果:成功测试用例2:输入:3+*5分析结果:失败测试用例3:输入:(3+5)*分析结果:失败测试用例4:输入:(3+5)*2+4分析结果:成功分析结果符合预期,说明我编写的LL(1)语法分析程序是正确的。
在测试用例1和测试用例4中,分析结果是成功的,而在测试用例2和测试用例3中,分析结果是失败的,这是因为输入不符合文法规则。
实验总结:通过本次实验,我进一步理解了LL(1)语法分析的原理和步骤。
编写LL(1)语法分析程序不仅要根据文法规则构建预测分析表,还要将预测分析表与输入串进行比对,根据匹配规则进行预测分析,最终得到分析结果。
在实验过程中,我发现在构建预测分析表和编写LL(1)语法分析程序时需要仔细思考和调试才能保证正确性。
通过本次实验,我对语法分析方法的实现过程有了更深入的认识,对于将来在编译原理方面的学习和工作有了更好的准备。
LL(1)实验报告(附代码)
实验二LL(1)分析法实验学时:4实验类型:综合实验要求:必修一、实验目的通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。
使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。
有利于提高学生的专业素质,为培养适应社会多方面需要的能力。
二、实验内容◆根据某一文法编制调试LL (1 )分析程序,以便对任意输入的符号串进行分析。
◆构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分析程序。
◆分析法的功能是利用LL(1)控制程序根据显示栈栈顶内容、向前看符号以及LL(1)分析表,对输入符号串自上而下的分析过程。
三、LL(1)分析法实验设计思想及算法◆模块结构:(1)定义部分:定义常量、变量、数据结构。
(2)初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);(3)控制部分:从键盘输入一个表达式符号串;(4)利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。
四、实验要求1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。
2、如果遇到错误的表达式,应输出错误提示信息。
3、对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG(2)G->+TG|—TG(3)G->ε(4)T->FS(5)S->*FS|/FS(6)S->ε(7)F->(E)(8)F->i输出的格式如下:实验报告正文的内容:LL(1)分析法的思想及LL(1)分析法的文法:LL(1)分析法是一种无回溯的自上而下分析算法,其本质即为求句柄,将输入串逐字的压入栈中,一旦发现栈中存在句柄,即对其进行归约算法,在实际操作中,通过求解算法的First()及Follow()集,构造文法的分析表,在分析过程中,通过查表得到要进行的动作,以此实现文法的分析。
LL(1)语法分析设计原理与实现技术实验 实验报告及源代码 北京交通大学
LL(1)语法分析设计原理与实现技术实验计科100X班 10284XXX程序设计功能实现LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的LL(1)文法的LL(1)分析程序。
G[E]: E→TE′E′→ATE′|εT→FT′T′→MFT′|εF→(E)|iA→+|-M→*|/说明:终结符号i 为用户定义的简单变量,即标识符的定义。
主要数据结构描述由文法可得:对于E:FIRST( E )= {(, i }对于E’: FIRST( E’ ) ={+,−,ε}对于T: FIRST( T )= ={(, i }对于T’: FIRST( T’)= ={*,∕,ε}对于F: FIRST( F )= ={(, i }对于A: FIRST( A )= ={+, - }对于M: FIRST(M)= ={*, / }由此我们容易得出各非终结符的FOLLOW集合如下:FOLLOW( E )= { ),#}FOLLOW(E’) ={ ),#}FOLLOW( T ) ={+,−,),#}FOLLOW( T’ ) = FOLLOW( T ) ={+,−,),#}FOLLOW( F )=FIRST(T’)\ε∪FOLLOW(T’)={*,∕,+,−,),#}FOLLOW( A )= { (, i }FOLLOW( M )= { (, i}文法LL(1)的预测分析表(表1):表1. LL(1)预测分析表注:为编程方便,在程序中,将E’、T’改为G、S程序结构描述1.设计方法:程序通过从文本文档读入数据,将所读数据以空格、回车或者退格为标示符,分为字符串,对字符串进行词法分析,最后将所有字符串按序输出到结果文档中,并在结果文档中标明每个字符串的类别序号。
2、程序中主要函数定义和调用关系如下:函数:void print()作用:输出分析栈void print1();作用:输出剩余串int main();作用:主要逻辑功能程序执行图如下:实验结果测试用例1:i+i*i#测试用例2:i-i++#实验总结相对于递归下降分析法,LL(1)分析法更为有效.采用此种方法的分析器由一张预测分析表(LL(1)分析表)、一个控制程序(表驱动程序)和一个分析栈组成,预测分析表中个元素的含义是:或者指出当前推到所应使用过的产生式,或者指出输入符号串中存在语法错误.LL(1)分析法的局限在于:只能分析LL(1)文法或者某些非LL(1)文法,但需先将其改造成LL(1)文法。
LL(1)语法分析
注:整个实验报告内容,仅第九点是任课教师填写,其他各项都必须有实验小组人员填写。
一、实验目的(1) 识别LL1文法(2) 求first集合(3) 求follow集合(4) 求select集合(5) 求预测分析表(6) 输入串进行LL1分析二、实验内容识别LL1文法求first集合求follow集合求select集合求预测分析表输入串进行LL1分析程序的流程图如下所:三、实验需求(需要实现哪些功能)1判断文法是否符合LL(1)文法要能进行LL(1)分析,那么这个文法应该满足:无二义性,无左递归,无左公因子2求出first集合3求出follow集合4求出select集合5构造预测分析表6对串进行LL(1)分析四、主要数据结构介绍public List<String> Vn = new ArrayList<>();//存放所有的非终结符public ArrayList<String> Vt = new ArrayList<String>();//存放终结符public String biaoshifu = null;public String inputSB = "E->TB\r\n" +"B->+TB|ε\r\n" +"T->FP\r\n" +"P->*FP|ε\r\n" +"F->(E)|i\r\n";//存放输入的文法产生式public ArrayList<String[]> in = new ArrayList<String[]>();//这数据结构真是逼人绝路才去想到绝处逢生,哈哈,关键实现了可变长度文法接收,在这存放的是拆分后最简单的文法,也是由用户输入public ArrayList<String[]> inPlus = new ArrayList<>();public ArrayList<String[]> first = new ArrayList<String[]>();//包括左推导符和其First集public ArrayList<String[]> follow = new ArrayList<String[]>();public ArrayList<String[]> select = new ArrayList<>();public ArrayList<String[]> track = new ArrayList<String[]>();//track有一条一条的非终结符串组成的路径数组public String[][] table = null;//绘制的预测表格五、主要模块算法介绍1,getFirst()求出输入字符的first集合存贮到ArrayList中2,getmyfirst()从ArrayList中获取求出的first集合3,getFellow()求出输入字符的Fellow集合存贮到ArrayList中4,getmyFellow()从ArrayList中获取求出的Fellow集合5,getmyselect()是通过前面求的first集合和fellow集合求出select集合6,drawTable()是绘制预测表格六、程序实现环境及使用说明Eclipse七、实验测试用例设计说明1,LL(1)文法E->TBB->+TB|εT->FPP->*FP|εF->(E)|i2,First集算法:First(E) = First(T) = First(F) = First(() + First(i)First(B) = First(+) + First(ε)First(T) = First(F) = First(() + First(i)First(P) = First(*) + First(ε)First(F) = First(() + First(i)3,First集:First(E)={(,i}First(B)={+,ε}First(T)={(,i}First(P)={*,ε}First(F)={(,i}4,Follow集算法:Follow集算法:Follow(E): E→E E→(E)Follow(B): E→TB E→(E)→(B)Follow(T): E→TB→T+ E→TB→Tε E→(E)→(T)Follow(P): E→TB→FPB→.P+ E→TB→FPB→.PεE→FP E→(E)→(P)Follow(F): E→FP→F* E→FP→FεE→TB→F+ E→(E)→(F)5,Follow集:Follow(E)={#,)}Follow(B)={#,)}Follow(T)={+,ε,)}Follow(P)={+,ε,#,)}Follow(F)={*,ε,+,)}6,select集E->TB ( iB->+TB +B->ε# )T->FP ( iP->*FP *P->ε+ # )F->(E) (F->i i7,预测分析表+ * ( ) iE E->TB E->TB B B->+TB B->εT T->FP T->FP P P->εP->*FP P->εF F->(E) F->i八、实验结果测试情况(以截图形式)1文法:2first集合3fellow集合4select集合5预测分析表九、小组对实验结果的自我评价通过这次实验,我对LL1文法,first集合,fellow集合,select集合有了一定的了解,进一步的巩固了这部分的知识。
语法分析实验报告
语法分析实验报告一: 实验内容:编写语法分析程序, 实现对算术表达式的语法分析, 要求所分析的算术表达式由如下的文法产生。
E->E+T|E-T|TT->T*F|T/F|FF->id|(E)|num二: 实验要求:在对表达式进行分析的同时, 输出所采用的产生式。
1.编写LL(1)语法分析程序, 要求:编程实现算法4.2, 为给定的文法自动构造预测分析表编程实现算法4.1, 构造LL(1)预测分析程序,2.编写语法分析程序, 实现自底向上的分析, 要求:构造识别所有活前缀的DFA构造LR分析表编程实现算法4.3, 构造LR分析程序1.三: 实验分析:2.方法二(编写LL(1)语法分析程序)1.步骤:(1)根据题目所给出的文法构造相应的无左递归文法, 并求出该文法各非终结符的FIRST、FOLLOW集合;(2)构造文法的LL(1)分析表;(3)由此构造LL分析程序。
2.实现方法:1.输入缓冲区为一个字符型数组, 读入输入的算术表达式并保存在此, 以’$’结束;2.为构造文法的LL(1)分析表, 构建一个相对应的字符串数组;3.在实际程序中P代表E', Q代表T', e代表ε,i代表id, n代表num;4.处理输入表达式中代表id和num的子串, 分别将它们转化为'i'和'n'进行分析;5.LL(1)预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前的输入符号a做哪种过程的。
对于任何(X,a),总控程序每次都执行下述三种可能的动作之一:(1)若X = a =‘$’, 则宣布分析成功, 停止分析过程。
(2)若X = a!=‘$’, 则把X从STACK栈顶弹出, 让a指向下一个输入符号。
①如果是终结符合, 则栈不加入新符号②如果是非终结符合, 则把表达式右边入栈(3)若M[A, a]中存放着“出错标志”, 则调用出错诊断程序ERROR。
LL(1)语法分析实验报告
编译原理实验报告
(1)设计思路
输入文法规则、非终结符和终结符先求出first集合,然后根据first集合和文法规则再求出follow集合,最后求出LL(1)预测分析表,最后通过分析表识别字符串是否符合文法规则。
(2)流程图
(3)具体过程:
(a)first和follow集合的计算:
对G中每个文法符号X∈VT∪VN,构造FIRST(X)。
连续使用下述规则,直至每个FIRST集合不再增大:
a、若X∈ VT,则FIRST(X)={X};
b、若X∈ VN,且有产生式X→a…,则把a加入FIRST(X) ;若X→ε也是一条产生式,则把ε也加入
c、若X→Y…是一个产生式且Y∈ VN,则把FIRST(Y)中的所有非ε元素都加入FIRST(X)中;若X→Y1Y2…Yk是一个产生式,Y1,Y2,…,Yi-1都是非终结符,而且,对任意j(1≤j≤i-1),FIRST(Yj)都含有ε,则把FIRST(Yi)
(2)产生各个符合的FIRST集合及FOLLOW集合:
(3)构造M[A,a]
(4)输入字符串:i*(i+i)进行分析:
该字符串是文法的句型
(5)输入另一个字符串:i+i(i*i)进行分析:
该字符串不是文法的句型。
编译原理LL(1)分析实验报告
青岛科技大学LL(1)分析编译原理实验报告学生班级__________________________学生学号__________________________学生姓名________________________________年 ___月 ___日一、实验目的LL(1)分析法的基本思想是:自项向下分析时从左向右扫描输入串,分析过程中将采用最左推导,并且只需向右看一个符号就可决定如何推导。
通过对给定的文法构造预测分析表和实现某个符号串的分析,掌握LL(1)分析法的基本思想和实现过程。
二、实验要求设计一个给定的LL(1)分析表,输入一个句子,能根据LL(1)分析表输出与句子相应的语法数。
能对语法数生成过程进行模拟。
三、实验内容(1)给定表达式文法为:G(E’): E’→#E# E→E+T | T T→T*F |F F→(E)|i(2)分析的句子为:(i+i)*i四、模块流程五、程序代码#include<iostream>#include<stdio.h>#include <string>#include <stack>using namespace std;char Vt[]={'i','+','*','(',')','#'}; /*终结符*/char Vn[]={'E','e','T','t','F'}; /*非终结符*/ int LENVt=sizeof(Vt);void showstack(stack <char> st) //从栈底开始显示栈中的内容{int i,j;char ch[100];j=st.size();for(i=0;i<j;i++){ch[i]=st.top();st.pop();}for(i=j-1;i>=0;i--){cout<<ch[i];st.push(ch[i]);}}int find(char c,char array[],int n) //查找函数,返回布尔值{int i;int flag=0;for(i=0;i<n;i++){if(c==array[i])flag=1;}return flag;}int location(char c,char array[]) //定位函数,指出字符所在位置,即将字母转换为数组下标值{int i;for(i=0;c!=array[i];i++);return i;}void error(){cout<<" 出错!"<<endl;}void analyse(char Vn[],char Vt[],string M[5][6],string str){int i,j,p,q,h,flag=1;char a,X;stack <char> st; //定义堆栈st.push('#');st.push(Vn[0]); //#与识别符号入栈j=0; //j指向输入串的指针h=1;a=str[j];cout<<"步骤"<<"分析栈"<<"剩余输入串"<<" 所用产生式"<<endl;while(flag==1){cout<<h<<" "; //显示步骤h++;showstack(st); //显示分析栈中内容cout<<" ";for(i=j;i<str.size();i++) cout<<str[i]; //显示剩余字符串X=st.top(); //取栈顶符号放入X if(find(X,Vt,LENVt)==1) //X是终结符if(X==a) //分析栈的栈顶元素和剩余输入串的第一个元素相比较if (X!='#'){cout<<" "<<X<<"匹配"<<endl;st.pop();a=str[++j]; //读入输入串的下一字符}else{ cout<<" "<<"acc!"<<endl<<endl; flag=0;}else{error();break;}else{p=location(X,Vn); //实现下标的转换(非终结符转换为行下标)q=location(a,Vt); //实现下标的转换(终结符转换为列下标)string S1("NULL"),S2("null");if(M[p][q]==S1 || M[p][q]==S2) //查找二维数组中的产生式{error();break;} //对应项为空,则出错else{string str0=M[p][q];cout<<" "<<X<<"-->"<<str0<<endl; //显示对应的产生式st.pop();if(str0!="$") //$代表"空"字符for(i=str0.size()-1;i>=0;i--) st.push(str0[i]);//产生式右端逆序进栈}}}}main(){string M[5][6]={"Te" ,"NULL","NULL","Te", "NULL","NULL","NULL","+Te" ,"NULL","NULL","$", "$","Ft", "NULL","NULL","Ft", "NULL","NULL","NULL","$", "*Ft", "NULL","$", "$","i", "NULL","NULL","(E)", "NULL","NULL"}; //预测分析表j string str;int errflag,i;cout<<"文法:E->E+T|T T->T*F|F F->(E)|i"<<endl;cout<<"请输入分析串(以#结束):"<<endl;do{ errflag=0;cin>>str;for(i=0;i<str.size();i++)if(!find(str[i],Vt,LENVt)){ cout<<"输入串中包含有非终结符"<<str[i]<<"(输入错误)!"<<endl;errflag=1;}} while(errflag==1); //判断输入串的合法性analyse(Vn, Vt, M,str);return 0;}六、实验结果七、实验总结。
LL(1)语法分析实验报告
LL(1)语法分析实验报告一、实验目的通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,检查语法错误,进一步掌握常用的语法分析方法。
二、实验内容构造LL(1)语法分析程序,任意输入一个文法符号串,并判断它是否为文法的一个句子。
程序要求为该文法构造预测分析表,并按照预测分析算法对输入串进行语法分析,判别程序是否符合已知的语法规则,如果不符合则输出错误信息。
消除递归前的文法消除递归后的等价文法E→E+T E→TE’E→T E’→+TE’|εT→T*F T→FT’T→F T’→*FT’|εF→(E)|i F→(E)|i根据已建立的分析表,对下列输入串:i+i*i进行语法分析,判断其是否符合文法。
三、实验要求1.根据已由的文法规则建立LL(1)分析表;2.输出分析过程。
请输入待分析的字符串: i+i*i符号栈输入串所用产生式#E i+i*i# E→TE’#E’T i+i*i# T→FT’#E’T’F i+i*i# F→i#E’T’i i+i*i##E’T’ +i*i# T’→ε#E’ +i*i# E’→+TE’#E’T+ +i*i##E’T i*i# T→FT’#E’T’F i*i# F→i#E’T’i i*i##E’T’ *i# T’→*FT’#E’T’F* *i##E’T’F i# F→i#E’T’i i##E’T’ # T’→ε#E’ # E’→ε# #四、程序思路模块结构:1、定义部分:定义常量、变量、数据结构。
2、初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体等);3、运行程序:让程序分析一个text文件,判断输入的字符串是否符合文法定义的规则;4、利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示简单的错误提示。
五、程序流程图输入要分析的串判断输入串是否正确判断分析句型是否完全匹配?成功失败否是是否八、程序调试与测试结果运行后结果如下:九、实验心得递归下降分析法是确定的自上而下分析法,这种分析法要求文法是LL(1)文法。
LL(1)语法分析程序实验报告
LL(1)语法分析程序实验报告——糖拌咸鱼/coser 实验目的与要求:通过设计、编写和调试构造First集合、Follow集合和LL(1)预测分析表,利用LL(1)预测分析表来分析给定的符号串的程序,了解构造LL(1)分析表的构造步骤、分析方法、对文法的要求。
能够从文法G出发,自动生成对应的分析表,并分析给定的符号串,并通过表格和图形的方式实现。
实验环境:开发语言:C#开发平台:Visual Studio 2010运行平台:windows平台,并装有.net 3.5以上输入:一个文法以及一个待分析的给定符号串输出:该文法的中所有非终结符的First和Follow集合该文法的LL(1)预测分析表根据LL(1)预测分析表分析符号串的过程和分析树实验的测试语法:E->TAA->+TA|εT->FBB->*FB|εF->(E)|i实验的测试符号串:合法:i*i+i非法:i*i+i-i实验设计:1.LL(1)语法分析程序的详细数据流图设计2.数据结构设计a)类设计b)数据成员设计3.函数子模块设计4.算法设计a)求各个文法符号X的First集合算法1.如果X是一个终结符号,那么First(X)=X。
2.如果X是一个非终结符号,且X->Y1Y2…..YK是一个产生式,其中k>=1,那么如果对于某个i,a在First(Yi)中且ε在所有的First(Y1), First(Y2)…….First(Yi-1)中,就把a加入到First(X)中。
3.如果X->ε是一个产生式,那么将ε加入到First(X)中。
4.不断应用上述规则,直到再没有新的终结符号或ε可以被加入任何First集合中为止。
算法实现:b)计算所有非终结符A的Follow(A) 集合算法1.将#放入到Follow(S)中,其中S是开始符号,而#是输入右端的结束标记。
2.如果存在一个表达式A->XBY,那么First(Y)中除了ε之外的所有符号都在Follow(B)中3.如果存在一个产生式A->XB,或存在产生式A->XBY,且First(Y)包含ε,那么Follow(A)中的所有符号都在Follow(B)中。
LL(1)语法分析 任意输入一个文法符号串,并判断它是否为文法的一个句子
电子信息工程学系实验报告课程名称:编译原理成绩:实验项目名称:LL(1)语法分析实验时间:2009.04.02指导教师(签名):班级:计算机061 姓名:林世宁学号:610704120实验目的:根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析,加深对预测分析LL(1)分析法的理解。
实验环境:PC机,软件开发工具如TC,visualc++实验内容及过程:构造LL(1)语法分析程序,任意输入一个文法符号串,并判断它是否为文法的一个句子。
程序要求为该文法构造预测分析表,并按照预测分析算法对输入串进行语法分析,判别程序是否符合已知的语法规则,如果不符合(编译出错),则输出错误信息。
实验步骤:1.定义目标语言的语法规则;2.求解预测分析方法需要的符号集和分析表;3.依次读入给定文法符号串,根据预测分析的方法进行语法分析,直到源程序结束;4.对遇到的语法错误做出错误处理;5.算法流程图参考:实验结果及分析:该LL(1)语法分析程序,能对输入的文法符号串,进行分析并判断它是否为文法的一个句子。
实验心得:通过本次实验加深对预测分析LL(1)分析法的理解,能撑握编写LL(1)分析程序对任意输入的符号串进行分析。
附录:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<dos.h>char A[20];char B[20];char v1[20]={'i','+','*','(',')','#'};char v2[20]={'E','G','T','S','F'};int j=0,b=0,top=0,l;typedef struct type{char origin;char array[5];int length;}type;type e,t,g,g1,s,s1,f,f1;type C[10][10];void print(){ int a;for(a=0;a<=top+1;a++)printf("%c",A[a]);printf("\t\t");}void print1(){ int j;for(j=0;j<b;j++)printf(" ");for(j=b;j<=l;j++)printf("%c",B[j]);printf("\t\t\t");}void main(){ int m,n,k=0,flag=0,finish=0;char ch,x;type cha;e.origin='E';strcpy(e.array,"TG");e.length=2;t.origin='T';strcpy(t.array,"FS");t.length=2;g.origin='G';strcpy(g.array,"+TG");g.length=3;g1.origin='G';g1.array[0]='^';g1.length=1;s.origin='S';strcpy(s.array,"*FS");s.length=3;s1.origin='S';s1.array[0]='^';s1.length=1;f.origin='F';strcpy(f.array,"(E)");f.length=3;f1.origin='F';f1.array[0]='i';f1.length=1;for(m=0;m<=4;m++)for(n=0;n<=5;n++)C[m][n].origin='N'; C[0][0]=e;C[0][3]=e;C[1][1]=g;C[1][4]=g1;C[1][5]=g1;C[2][0]=t;C[2][3]=t;C[3][1]=s1;C[3][2]=s;C[3][4]=C[3][5]=s1;C[4][0]=f1;C[4][3]=f;printf("提示:本程序只能对由'i','+','*','(',')'构成的以'#'结束的字符串进行分析,\n"); printf("请输入要分析的字符串:");do{scanf("%c",&ch);if ((ch!='i') &&(ch!='+') &&(ch!='*')&&(ch!='(')&&(ch!=')')&&(ch!='#')){printf("输入串中有非法字符\n");exit(1);}B[j]=ch;j++;}while(ch!='#');l=j;ch=B[0];A[top]='#'; A[++top]='E';printf("步骤\t\t分析栈 \t\t剩余字符 \t\t所用产生式 \n");do{x=A[top--];printf("%d",k++);printf("\t\t");for(j=0;j<=5;j++)if(x==v1[j]){flag=1;break;}if(flag==1){if(x=='#'){finish=1;printf("acc!\n");getchar();getchar();exit(1);}if(x==ch){print();print1();printf("%c匹配\n",ch);ch=B[++b];flag=0;}else{print();print1();printf("%c出错\n",ch);exit(1);}}else{for(j=0;j<=4;j++)if(x==v2[j]){ m=j;break;}for(j=0;j<=5;j++)if(ch==v1[j]){ n=j;break;}cha=C[m][n];if(cha.origin!='N'){print();print1();printf("%c->",cha.origin);for(j=0;j<cha.length;j++)printf("%c",cha.array[j]);printf("\n");for(j=(cha.length-1);j>=0;j--) A[++top]=cha.array[j]; if(A[top]=='^')top--;}else{ print();print1();printf("%c出错\n",x);exit(1);}}}while(finish==0);}备注:以上各项空白处若填写不够,可自行扩展。
ll 1 语法分析实验报告
ll 1 语法分析实验报告语法分析实验报告一、引言语法分析是编译器中的重要步骤之一,它负责将输入的源代码转化为语法树或抽象语法树,以便后续的语义分析和代码生成。
本实验旨在通过实现一个简单的LL(1)语法分析器,加深对语法分析原理和算法的理解。
二、实验目的1. 理解LL(1)语法分析的原理和算法;2. 掌握使用LL(1)文法描述语言的方法;3. 实现一个简单的LL(1)语法分析器。
三、实验环境本实验使用C++编程语言,开发环境为Visual Studio。
四、实验步骤1. 设计LL(1)文法在开始实现LL(1)语法分析器之前,我们需要先设计一个LL(1)文法。
LL(1)文法是一种满足LL(1)分析表构造要求的文法,它能够保证在语法分析过程中不会出现二义性或回溯。
通过仔细分析待分析的语言的语法规则,我们可以设计出相应的LL(1)文法。
2. 构造LL(1)分析表根据设计的LL(1)文法,我们可以构造出对应的LL(1)分析表。
LL(1)分析表是一个二维表格,其中的行表示文法的非终结符,列表示文法的终结符。
表格中的每个元素表示在某个非终结符和终结符的组合下,应该进行的语法分析动作。
3. 实现LL(1)语法分析器基于构造的LL(1)分析表,我们可以开始实现LL(1)语法分析器。
分析器的主要工作是根据输入的源代码和LL(1)分析表进行分析,并输出语法树或抽象语法树。
五、实验结果与分析经过实验,我们成功实现了一个简单的LL(1)语法分析器,并对一些简单的语言进行了分析。
实验结果表明,我们设计的LL(1)文法和LL(1)分析表能够正确地进行语法分析,没有出现二义性或回溯。
六、实验总结通过本次实验,我们深入学习了LL(1)语法分析的原理和算法,并通过实现一个简单的LL(1)语法分析器加深了对其的理解。
实验过程中,我们发现LL(1)文法的设计和LL(1)分析表的构造是实现LL(1)语法分析器的关键。
同时,我们也意识到LL(1)语法分析器在处理复杂的语言时可能会面临一些困难,需要进一步的研究和优化。
LL(1) 语法分析实验 (4学时)——学实验报告
大学实验报告
No. 2
课程编译原理成绩教师签章
实验名称:LL(1) 语法分析实验(4学时)
一、实验目的:
1. 了解LL(1)语法分析是如何根据语法规则逐一分析词法分析所得到的单词,检查语法错误,即掌握语法分析过程。
2. 掌握LL(1)语法分析器的设计与调试
二、实验内容:
文法:E→TE’,E’→+TE’|ε,T→FT’,T’→*FT’|ε,F→(E) | i
针对上述文法,编写一个LL(1)语法分析程序:
1. 输入:诸如i+i*i 的字符串,以#结束。
2. 处理:基于分析表进行LL(1)语法分析,判断其是否符合文法。
3. 输出:串是否合法。
三、实验要求:
1. 在编程前,根据上述文法建立对应的、正确的预测分析表。
2. 设计恰当的数据结构存储预测分析表。
3. 任选C/C++/Java中的一种作为编程语言,要求所编程序结构清晰。
四、实验环境:
系统要求:WindowsXP系统
内存:256M以上
软件支持:Microsoft Visual C++6.0
开发语言:C++
五、实验分析:
1.通过文法:E→TE’,E’→+TE’|ε,T→FT’,T’→*FT’|ε,F→(E) | i 产生
六、实验过程:
七、实验结论:。
LL(1)语法分析实验报告
实验报告姓名:***学号:**********班级:惠普开发142学校:青岛科技大学Mail:****************电话:178****6475教师:宮生文实验报告:实验名称:LL(1)语法分析实验目的和要求编制一个能识别由词法分析给出的单词符号序列是否是给定文法的正确句子(程序),输出对输入符号串的分析过程。
实验内容和步骤:一、实验内容对于这个实验,总共用了三个函数,即主函数、输出分析栈函数、输出剩余串函数。
在主函数中,还要构造预测分析表。
二、实验步骤1、基于实验的内容,构造程序所需的模块2、根据已建构的模块,写出各个模块的相应程序代码3、在主函数中调用模块来完成所要得到的效果在本程序中,首先使用了结构体类型定义来定义产生式,用字符串数组存放分析栈、剩余串、终结符和非终结符,用二维数组存放预测分析表,利用指针对栈中数据进行读取。
在本程序中,总共用了三个函数,即主函数、输出分析栈函数、输出剩余串函数。
在主函数中,还要构造预测分析表,对输入的字符串进行分析,调用另外两个函数。
实验代码如下:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<dos.h>char A[20];/*分析栈*/char B[20];/*剩余串*/char v1[20]={'i','+','*','(',')','#'};/*终结符*/char v2[20]={'E','G','T','S','F'};/*非终结符*/int j=0,b=0,top=0,l;/*L为输入串长度*/typedef struct type/*产生式类型定义*/{char origin;/*大写字符*/char array[5];/*产生式右边字符*/int length;/*字符个数*/}type;type e,t,g,g1,s,s1,f,f1;/*结构体变量*/type C[10][10];/*预测分析表*/void print()/*输出分析栈*/{int a;/*指针*/for(a=0;a<=top+1;a++)printf("%c",A[a]);printf("\t\t");}/*print*/void print1()/*输出剩余串*/{int j;for(j=0;j<b;j++)/*输出对齐符*/printf(" ");for(j=b;j<=l;j++)printf("%c",B[j]);printf("\t\t\t");}/*print1*/void main(){int m,n,k=0,flag=0,finish=0;char ch,x;type cha;/*用来接受C[m][n]*//*把文法产生式赋值结构体*/e.origin='E';strcpy(e.array,"TG");e.length=2;t.origin='T';strcpy(t.array,"FS");t.length=2;g.origin='G';strcpy(g.array,"+TG");g.length=3;g1.origin='G';g1.array[0]='^';g1.length=1;s.origin='S';strcpy(s.array,"*FS");s.length=3;s1.origin='S';s1.array[0]='^';s1.length=1;f.origin='F';strcpy(f.array,"(E)");f.length=3;f1.origin='F';f1.array[0]='i';f1.length=1;for(m=0;m<=4;m++)/*初始化分析表*/for(n=0;n<=5;n++)C[m][n].origin='N';/*全部赋为空*//*填充分析表*/C[0][0]=e;C[0][3]=e;C[1][1]=g;C[1][4]=g1;C[1][5]=g1;C[2][0]=t;C[2][3]=t;C[3][1]=s1;C[3][2]=s;C[3][4]=C[3][5]=s1;C[4][0]=f1;C[4][3]=f;printf("提示:本程序只能对由'i','+','*','(',')'构成的以'#'结束的字符串进行分析,\n"); printf("请输入要分析的字符串:");do/*读入分析串*/{scanf("%c",&ch);if ((ch!='i') &&(ch!='+') &&(ch!='*')&&(ch!='(')&&(ch!=')')&&(ch!='#')){printf("输入串中有非法字符\n");exit(1);}B[j]=ch;j++;}while(ch!='#');l=j;/*分析串长度*/ch=B[0];/*当前分析字符*/A[top]='#'; A[++top]='E';/*'#','E'进栈*/printf("步骤\t\t分析栈\t\t剩余字符\t\t所用产生式\n");do{x=A[top--];/*x为当前栈顶字符*/printf("%d",k++);printf("\t\t");for(j=0;j<=5;j++)/*判断是否为终结符*/if(x==v1[j]){flag=1;break;}if(flag==1)/*如果是终结符*/{if(x=='#'){finish=1;/*结束标记*/printf("acc!\n");/*接受*/getchar();getchar();exit(1);}/*if*/if(x==ch){print();print1();printf("%c匹配\n",ch);ch=B[++b];/*下一个输入字符*/flag=0;/*恢复标记*/}/*if*/else/*出错处理*/{print();print1();printf("%c出错\n",ch);/*输出出错终结符*/exit(1);}/*else*/}/*if*/else/*非终结符处理*/{for(j=0;j<=4;j++)if(x==v2[j]){m=j;/*行号*/break;}for(j=0;j<=5;j++)if(ch==v1[j]){n=j;/*列号*/break;}cha=C[m][n];if(cha.origin!='N')/*判断是否为空*/{print();print1();printf("%c-",cha.origin);/*输出产生式*/for(j=0;j<cha.length;j++)printf("%c",cha.array[j]);printf("\n");for(j=(cha.length-1);j>=0;j--)/*产生式逆序入栈*/A[++top]=cha.array[j];if(A[top]=='^')/*为空则不进栈*/top--;}/*if*/else/*出错处理*/{print();print1();printf("%c出错\n",x);/*输出出错非终结符*/exit(1);}/*else*/}/*else*/}while(finish==0);}/*main*/三、实验过程记录:实验截图:当输入内容不匹配或输入内容非法时要退出程序,此时若不关闭已经打开的文件可能导致文件内容受到破坏;解决方法是给error()函数设置一个文件指针变量参数FILE* fp,在退出程序之前通过fp关闭文件四、实验总结:通过本次实验我锻炼了自己的上机操作能力及编程能力,并对理论知识有了进一步的了解。
编译原理实验二LL(1)语法分析实验报告
专题3_LL(1)语法分析设计原理与实现李若森 13281132 计科1301一、理论传授语法分析的设计方法和实现原理;LL(1) 分析表的构造;LL(1)分析过程;LL(1)分析器的构造。
二、目标任务实验项目实现LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的 LL(1)文法的LL(1)分析程序。
G[E]:E→TE’E’→ATE’|εT→FT’T’→MFT’|εF→(E)|iA→+|-M→*|/设计说明终结符号i为用户定义的简单变量,即标识符的定义。
加减乘除即运算符。
设计要求(1)输入串应是词法分析的输出二元式序列,即某算术表达式“专题 1”的输出结果,输出为输入串是否为该文法定义的算术表达式的判断结果;(2)LL(1)分析程序应能发现输入串出错;(3)设计两个测试用例(尽可能完备,正确和出错),并给出测试结果。
任务分析重点解决LL(1)表的构造和LL(1)分析器的实现。
三、实现过程实现LL(1)分析器a)将#号放在输入串S的尾部b)S中字符顺序入栈c)反复执行c),任何时候按栈顶Xm和输入ai依据分析表,执行下述三个动作之一。
构造LL(1)分析表构造LL(1)分析表需要得到文法G[E]的FIRST集和FOLLOW集。
构造FIRST(α)构造FOLLOW(A)构造LL(1)分析表算法根据上述算法可得G[E]的LL(1)分析表,如表3-1所示:表3-1 LL(1)分析表主要数据结构pair<int, string>:用pair<int, string>来存储单个二元组。
该对照表由专题1定义。
map<string, int>:存储离散化后的终结符和非终结符。
vector<string>[][]:存储LL(1)分析表函数定义init:void init();功能:初始化LL(1)分析表,关键字及识别码对照表,离散化(非)终结符传入参数:(无)传出参数:(无)返回值:(无)Parse:bool Parse( const vector<PIS> &vec, int &ncol );功能:进行该行的语法分析传入参数:vec:该行二元式序列传出参数:emsg:出错信息epos:出错标识符首字符所在位置返回值:是否成功解析。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
LL(1)语法分析
一,实验名称:
实现LL分析。
二,实验要求:
➢输入任意文法
➢消除左递归
➢消除左因子
➢测试任意输入语句是否合法
➢数据结构描述
➢算法说明
➢输出first集合
➢输出follow集合
➢输出LL(1)表
三.设计原理及算法描述
所谓LL(1)分析法,就是指从左到右扫描输入串(源程序),同时采用最左推导,且对每次直接推导只需向前看一个输入符
号,便可确定当前所应当选择的规则。
实现LL(1)分析的程
序又称为LL(1)分析程序或LL1(1)分析器。
一个文法要能进行LL(1)分析,那么这个文法应该满足:无
二义性,无左递归,无左公因子。
当文法满足条件后,再分别
构造文法每个非终结符的FIRST和FOLLOW集合,然后根据FIRST和FOLLOW集合构造LL(1)分析表,最后利用分析表,根据LL(1)语法分析构造一个分析器。
LL(1)的语法分析程序包含了三个部分,总控程序,预测分析表函数,先进先出的语法分析栈,本程序也是采用了同样的方法进行语法分析,该程序是采用了C语言来编写,其逻辑结构图如下:
LL(1)预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前的输入符号a做哪种过程的。
对于任何(X,a),
总控程序每次都执行下述三种可能的动作之一:
(1)若X = a =‘#’,则宣布分析成功,停止分析过程。
(2)若X = a ‘#’,则把X从STACK栈顶弹出,让a指向下一个输入符号。
(3)若X是一个非终结符,则查看预测分析表M。
若M[A,a]中存放着关于X的一个产生式,那么,首先把X弹出STACK 栈顶,然后,把产生式的右部符号串按反序一一弹出STACK 栈(若右部符号为ε,则不推什么东西进STACK栈)。
若M[A,a]中存放着“出错标志”,则调用出错诊断程序ERROR。
事实上,LL(1)的分析是根据文法构造的,它反映了相应文法所定义的语言的固定特征,因此在LL(1)分析器中,实际上是以LL(1)分析表代替相应方法来进行分析的。
2.构造LL(1)分析表
考查文法G[E]:
E→E+T | T
T→T*F | F
F→( E ) | i | x | y
我们容易看出此文法没有左公因子也没有二义性,但却存在两个直接左递归,这里我们利用引入新非终结符的方法来消除它使方法满足要求,即:
对形如:U→Ux|y的产生式(其中x,y V+ ,y不以U开头),引入一个新的非终结符U’后,可以等价地改写成为:
U→yU’
U’→x U’|ε
显然改写后,U和U’都不是左递归的非终结符。
因此文法G [E]按上述方法消去左递归后可等价地写成:
E→TP
P→+TP | ε
T→FQ
Q→*FQ | ε
F→( E ) | i | x | y
在构造LL(1)预测分析表之前,首先要构造该文法的每个非终结符的FIRST和FOLLOW集合,按照下面描述的算法来构造这两个集合。
①FIRST集合的构造算法:
(1)若X∈VT,则FIRST(X)={X}。
(2)若X∈VN,且有产生式X→a……,则把a加入到FIRST(X)中;若X→ε也是一条产生式,则把ε也加到FIRST(X)中。
(3)若X→Y……是一个产生式且Y∈VN,则把FIRST(Y)中的所有非ε-元素都加到FIRST(X)中;若X→Y1Y2…Yk是一个产生式,Y1,…,Yi-1都是非终结符,而且,对于任何j,1≤j≤i-1,FIRST(Yj)都含有ε(即Y1…Yi-1* ε),则把FIRST(Yj)中的所有非ε-元素都加到FIRST(X)中;特别是,若所有的FIRST(Yj)均含有ε,j=1,2,…,k,则把ε加到FIRST(X)中。
连续使用上面的规则,直至每个集合FIRST不再增大为止。
②FOLLOW集合的构造算法:
(1)对于文法的开始符号S,置#于FOLLOW(S)中;(2)若A→αBβ是一个产生式,则把FIRST(β)| {ε}加至FOLLOW(B)中;
(3)若A→αB是一个产生式,或A→αBβ是一个产生式而βε(即ε∈FIRST(β)),则把FOLLOW(A)加至FOLLOW(B)中。
连续使用上面的规则,直至每个集合FOLLOW不再增大为止。
现在来构造G[E]的LL(1)预测分析表。
预测分析表M[A, a]是如下形式的一个矩阵。
A为非终结符,a是终结符或‘#’。
矩阵元素M[A, a]中存放这一条关于A的产生式,指出当A面临输入符号a是所应采用的规则。
M[A, a]也可能存放一条“出错标志”,指出当A根本不该面临输入符号a。
4.利用分析表进行预测分析
带预测分析的PDA
1)总程序的算法描述如下:
BEGIN
首先把‘#’然后把文法开始符号推进STACK栈;
把第一个输入符号读进a;
FLAG:=TRUE;
WHILE FLAG DO
BEGIN
把栈顶符号出栈到X中;
IF XÎVT THEN
IF X =a THEN 把下一输入符号读进a
ELSE ERROR
ELSE IF X= ‘#’ THEN
IF X=a THEN FLAG:=FALSE
ELSE ERROR
ELSE IF M[A, a]={X®x1x2…xk} THEN
把xk, xk–1,…, x1依次进栈
/*若x1, x2 …xk=e,则不进栈*/
ELSE ERROR
END OF WHILE;
STOP /*分析成功,过程结束*/
END
四.主要数据结构描述
1. char termin[50]; /*终结符号*/
char non_ter[50]; /*非终结符号*/
char v[50]; /*所有符号*/
char left[50]; /*左部*/
char right[50][50]; /*右部*/
char first[50][50],follow[50][50]; /*各产生式右部的FIRST 和左部的FOLLOW集合*/
int M[20][20]; /*二维数组存储分析表*/
栈T用来存放产生式的右边
Str数组存放要分析的句子串
五.运行结果:
ERTWF#
+*()i#
测试文法G[E]:
1 E -> TR
2 R -> +TR|^
3 T -> FW
4 W -> * FW|^
5 F -> (E)|i
分析例句:i*(i)# , i+i#
六.结果分析
以上两个试验从较大呈度上说明了程序运行的正确性及稳定性,当然,对程序本身还有待进行更进一步的严格测试。