一.实验目的1.掌握LL(1分析法的基本原理2.掌握LL(1分析表的构造方法3.掌握LL(1驱动程序的构造方法二.实验内容及要求根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对预测分析LL(1)分析法的理解。例:对下列文法,用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输出的格式如下:(1LL(1)分析程序,编制人:姓名,学号,班级(2输入一以#结束的符号串(包括+—*/()i#:在此位置输入符号串(3输出过程如下:步骤分析栈剩余输入串所用产生式1Ei+i*i#E-TG(4输入符号串为非法符号串(或者为合法符号串备注:(1在“所用产生式”一列中如果对应有推导则写出所用产生式;如果为匹配终结符则写明匹配的终结符;如分析异常出错则写为“分析出错”;若成功结束则写为“分析成功”。(2在此位置输入符号串为用户自行输入的符号串。(3上述描述的输出过程只是其中一部分的。注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#;2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);3.对学有余力的同学,测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;4.可采用的其它的文法。三.实验过程LL(1分析法的实验源程序代码如下:#include#include#include#includecharA[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,g1,s,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;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;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;jprintf(%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*/程序的运行结果如下:四.实验心得经过这个实验的练习,通过对程序的分析,让我进一步了解LL(1)算法的思想以及它的进一步程序实现,让我对它的了解从简单的理论上升到程序实现的级别,有理论上升到实际,让我更清楚它的用途。五.实验体会及思考在对实验的分析的时候,也遇到很多的问题,刚开始根本想不到用程序怎么实现这么繁杂的LL(1)文法,后来看了程序才知道,才转过来弯,通过对这个程序的分析与揣摩,让自己对这方面文法的实现有了一定的头绪,对以后的的一些文法的程序实现会有很大的帮助,通过练习我也感到理论仅留在理论是远远不行的,用通过一定方式实现才有实用价值。