集美大学计算机工程学院实验报告课程名称编译原理实验名称LL(1)分析文法实验类型设计型姓名学号日期地点成绩教师评语:一、实验目的根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对预测分析LL(1)分析法的理解。二、实验环境MicrosoftVisualC++6.0三、实验设计思想模块结构:(1)定义部分:定义常量、变量、数据结构。(2)初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);(3)控制部分:从键盘输入一个表达式符号串;(4)利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。表2-1文法的分析表非终结符输入符号i+-*/()$EE-TGE-TGGG-+TGG--TGG-εG-εTT-FST-FSSS-εS-εS-*FSS-/FSS-εS-εFF-iF-(E)四、实验内容程序输入/输出示例:对下列文法,用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输出的格式如下:(1)LL(1)分析程序,编制人:姓名,学号,班级(2)输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串(3)输出过程如下:步骤分析栈剩余输入串所用产生式1Ei+i*i#E-TG(4)输入符号串为非法符号串(或者为合法符号串)备注:(1)在“所用产生式”一列中如果对应有推导则写出所用产生式;如果为匹配终结符则写明匹配的终结符;如分析异常出错则写为“分析出错”;若成功结束则写为“分析成功”。(2)在此位置输入符号串为用户自行输入的符号串。(3)上述描述的输出过程只是其中一部分的。实验结果:测试:i+i#实验结果:测试:i-i#实验结果:测试:i*i#实验结果:测试:i/i#实验结果:测试:i+(i*i)#实验结果:测试:i-(i/i)#实验结果:测试非法输入字符串:i-i实验结果:测试非法输入字符串:i-i#实验结果:测试非法输入字符串:i+i)#实验结果:测试非法输入字符串:i-i-#实验结果:测试非法输入字符串:i-i-#实验结果:测试非法输入字符串:(i+i#五、实验小结【1】通过本实验,对于LL(1)分析文法有了一定程度的掌握,加深了语法分析的原理和LL(1)语法分析方法的理解,但是程序一开始仍旧有不完善的地方,本来应该出错的地方并未显示错误,比如以下测试,然后通过修改程序段是的程序得以正确执行。还有在推导LL(1)分析表的时候漏填了一部分的follow集,慢慢得出LL(1)分析表的数据结构,程序得以正常运行。六、实验源程序#includestdio.h#includestdlib.h#includestring.h#includedos.hcharA[20];/*分析栈*/charB[20];/*剩余串*/charv1[20]={'i','+','-','/','*','(',')','#'};/*终结符*/charv2[20]={'E','G','T','S','F'};/*非终结符*/intj=0,b=0,top=0,l;/*L为输入串长度*/typedefstructtype/*产生式类型定义*/{charorigin;/*大写字符*/chararray[5];/*产生式右边字符*/intlength;/*字符个数*/}type;typee,t,g,g0,g1,s,s0,s1,f,f1;/*结构体变量*/typeC[10][10];/*预测分析表*/voidprint()/*输出分析栈*/{inta;/*指针*/for(a=0;a=top+1;a++)printf(%c,A[a]);printf(\t\t);}/*print*/voidprint1()/*输出剩余串*/{intj;for(j=0;jb;j++)/*输出对齐符*/printf();for(j=b;j=l;j++)printf(%c,B[j]);printf(\t\t\t);}/*print1*/voidmain(){intm,n,k=0,flag=0,finish=0;charch,x;typecha;/*用来接受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;g0.origin='G';strcpy(g0.array,-TG);g0.length=3;g1.origin='G';g1.array[0]='^';g1.length=1;s.origin='S';strcpy(s.array,*FS);s.length=3;s0.origin='S';strcpy(s0.array,/FS);s0.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][5]=e;C[1][1]=g;C[1][2]=g0;C[1][6]=g1;C[1][7]=g1;C[2][0]=t;C[2][5]=t;C[3][1]=s1;C[3][2]=s1;C[3][3]=s0;C[3][4]=s;C[3][6]=s1;C[3][7]=s1;C[4][0]=f1;C[4][5]=f;printf(提示:本程序只能对由'i','+','-','*','/','(',')'构成的以'#'结束的字符串进行分析,\n\n);printf(请输入要分析的字符串:);do/*读入分析串*/{scanf(%c,&ch);if((ch!='i')&&(ch!='+')&&(ch!='-')&&(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;jcha.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*/