当前位置:文档之家› 编译原理-- 语法分析——规约

编译原理-- 语法分析——规约

课程名称编译原理设计题目语法分析——规约目录一.问题描述 (2)二.文法及属性文法的描述 (2)2.1文法描述 (2)2.2 while-do循环语句的文法 (2)2.3属性文法描述 (2)3语法分析方法及中间代码形式的描述 (3)3.1 语法分析方法 (3)3.2 中间代码形式描述 (3)4简要的分析与概要设计 (4)4.1词法分析 (4)4.2递归下降翻译器的设计 (4)4.3语法制导翻译 (5)5 详细的算法描述 (5)5.1 文法 (6)5.2 查错 (6)三.测试方法和测试结果 (9)3.1测试方法 (9)3.2测试结果 (9)四.设计心得 (10)一、问题描述1.1 能够写出一个while-do语句,此语句符合LL(1)的文法。

1.2 构造词法分析程序对while-do语句进行词法分析。

1.3构造语法分析程序对while-do语句进行语法分析,判断语法正确性。

1.4 运行程序,要求有正确的语义输出(4地址码)。

二、文法及属性文法的描述:2.1 文法描述:基本概念:文法是对语言结构的定义与描述。

即从形式上用于描述和规定语言构的称为“文法”。

定义:文法G=(V N,V T,P,Z)V N:非终结符号集V T:终结符号集P:产生式或规则的集合Z:开始符号(识别符号) Z∈V N其中:2.2 while-do循环语句的文法文法G(s)如下:S-->WEDG (意思是while E do G)G-->c=RR-->dTe|dT-->+|-|*|/E-->aFbF--> >|==|< (id1,id2代表标识符)2.3 属性文法的描述:2.3.1属性文法的定义形式:每个文法符号有一组属性,每个文法产生式A->α有一组产生式b:=f(c1,c2,……,ck)的语义规则,其中f式函数,b和c1,c2,……,ck式该产生式文法符号的属性。

3.语法分析方法及中间代码形式的描述;3.1 语法分析方法:3.1.1本次设计采用LL(1)分析:预测分析方法概述:分析钜阵的元素M[A,a]中的下标A为非终结符,a为终结符或句子的结束标记“#”,钜阵元素M[A,a]的内容为一条关于A的产生式。

它表明当用非终结符A向下推而当输入符a时,所应该采用的后选式。

当钜阵元素为空时,则表示用A往下推导时遇到了不应该出现的符号,即A与a不能匹配,因此应该出错处理。

在构造预测分析表时,对每个终结符或“#”号用a表示,则若a∈SELECT (A->a)。

令M[A,a]= A->a(一般为了简化,取M[A,a]= a)把所有的无定义的M[A,a]标上ERROR(一般在表中用空白表示)。

3.1.2 此程序预测分析方法:此设计为非左递归while-do文法,应采用自上而下的预测分析方法。

在此设计中,产生式只到E->id1>id2| id1=id2| id1<id2,F-> id1= id2(E->aFb F->>|==|<)对F只有一种产生式而在输入串中的终结符a,b……等在程序中用id代替了,正好做到了输入串和符号栈的匹配抵消,因此简化了预测分析表的构造,对于E 来说有3个侯选式,在本程序中通过函数firstset()来判断应该选哪个产生式,但是firstset()是依赖Token2数组来判断的,没有完全摆脱掉数组的限制,因此也是本程序的不足之处。

3.2 中间代码的描述:3.2.1中间代码概述:中间代码采用四元式输出,一个四元式是一个带有四个域的记录结构,这四个域分别称为op﹑arg1﹑arg2及result。

域op包含一个代表运算符的内部码。

语句while a<b do a=a+b的四元式输出形式如下:100( <, a , b , 102 )101 ( j , _ , _ , 105 )102 ( + , a , b , n )103 ( = , n , _ , a )104 ( j , _ , _ , 100)3.2.1本次设计的中间代码:本次程序的中间代码是根据一定的语义规则写出的:F代码结构:S.begin :E.ture :to E.false :4.简4.1词法分析词法分析程序的任务是:从左至右逐个字符地对源程序进行扫描,产生一个个的单词符号,把作为字符串的源程序改造成为单词符号的中间程序。

词法分析检查的错误主要是挑出源程序中出现的非法符号。

所谓非法符号是指不是程序设计语言中允许出现的符号,就像自然语句中的错字。

4.2递归下降翻译器的设计1.:对每个非终结符F构造一个函数过程,对F的每个继承属性设置一个形式参数,函数的返回值为F的综合属性,F对应的函数过程中,为出现在F的产生式中的每一个文法符号的每一个属性都设置一个局部变量。

非终结符F对应的函数过程中,根据当前的输入符号决定使用哪个产生式候选。

2:每个产生式对应的程序代码中,按照从左到右的次序,对于单词符号,非3:终结符和语义动作分别做以下工作。

(1)对于带有综合属性x的终结符X,把x的值存入为X,x设置的变量中。

然后产生一个匹配X的调用,并继续读入一个输入符号。

(2)对于每个非终结符号R,产生一个右边带有函数调用的赋值语句c=R(r1,r2,…,rk)(3)对于语义动作,把动作的代码抄进分析器中,用代表属性的变量来代替对应属性的每一次引用。

4.3语法制导翻译在语法分析过程中,随着分析的步步进展,根据每个产生式所对应的语义子程序(或语义规则描述的语义动作)进行翻译。

属性文法的每个符号有属性,所以每个符号入栈时,必须连属性一起入栈,这样,栈符号就由文法符号及存放该符号属性的域所组成。

由于属性类型不同,属性域存放的内容就要根据属性的类型来定。

有的可能直接存放属性值,也有的存放的是指向属性值的指针。

对于综合属性,其属性域不存放其属性值,而是存放一个指针,指向存贮该属性值的单元。

对于继承属性,其属性域直接保存其属性值。

继承属性的属性域刚入栈时为空,但是在该栈符号变成栈顶符号之前的某一时刻,它们必须接受相应的属性值,即在成为栈顶时,继承属性的属性域必须有值。

5.详细算法描述5.1 文法/*文法G(s)s-->WEDGG-->c=RR-->dTe|dT -> +|-|*|/|%E-->aFbF--> >|==|<*/5.2 查错:按照递归下降法求Wa<bDa=a+b,程序的执行顺序是S()→W()→E→F()→D()→G()→R()→T()1)S()void S(){printf("%d\tS-->WEDG\n",total);total++;W();E();}2)W()void W(){if(ch!='W'){printf("有非法字符%c请按回车返回!!",ch);getchar();getchar();exit(1);}}3)E()void E(){ch=a[++i1];if(ch!='a'){printf("有非法字符%c %c请按回车返回!!",ch);getchar();getchar();exit(1);}printf("%d\tE-->aFb\n",total);total++;F();}4)F()void F(){int i;ch=a[++i1];i=i1+1;if(a[i]!='b'){printf("有非法字符%c请按回车返回!!",a[i]);getchar();getchar();exit(1);}switch(ch){case '>':printf("%d\tF-->>\n",total);total++;break;case '==':printf("%d\tF-->==\n",total);total++;break;default:printf("%d\tF--><\n",total);total++;break;}D();G();}5)D()void D(){++i1;ch=a[++i1];if(ch!='D'){printf("有非法字符%c请按回车返回!!",ch);getchar();getchar();exit(1);}ch=a[++i1];}6)G()void G(){int i=i1+1;if(ch!='c'&&a[i]!='='){printf("有非法字符%c %c请按回车返回!!",ch,a[i]);getchar();getchar();exit(1);}printf("%d\tG-->c=R\n",total);total++;R();}7)R()void R(){int i;i=i1+1;i1=i1+2;ch=a[i1];if(a[i]!='='&&ch!='d'){printf("有非法字符%c %c请按回车返回!!",a[i],ch);getchar();getchar();exit(1);}else{if((a[i1+1]=='+')||(a[i1+1]=='-')||(a[i1+1]=='*')||(a[i1+1]=='/')){printf("%d\tR-->dTe\n",total);total++;T();}else{printf("%d\tR-->d\n",total);total++;W();E();}}}8)T()void T(){ch=a[++i1];switch(ch){case '+':printf("%d\tT-->+\n",total);total++;break;case '-':printf("%d\tT-->-\n",total);total++;break;case '*':printf("%d\tT-->*\n",total);total++;break;default:printf("%d\tT-->/\n",total);total++;break;}ch='#';}三、测试方法和测试结果3.1测试方法在C++环境下,设计几个有代表的用例,进行测试,例如:输入语句W(while)a<bD(do)a=a+b#(其中d表示do ,w表示while)。

相关主题