编译原理作业集-第七章
- 格式:doc
- 大小:274.50 KB
- 文档页数:18
第七章习题解答7.1 给定文法:S→(A)A→ABBA→BB→bB→c①构造它的基本LR(0)项目集;②构造它的LR(0)项目集规范族;③构造识别该文法活前缀的DFA;④该文法是SLR文法吗?若是,构造它的SLR分析表。
7.2 给定文法:E→EE+E→EE*E→a①构造它的LR(0)项目集规范族;②它是SLR(1)文法吗?若是,构造它的SLR(1)分析表;③它是LR(1)文法吗?若是,构造它的LR(1)分析表;④它是LALR(1)文法吗?若是,构造它的LALR分析表。
7.3 给出一个非LR(0)文法。
7.4 给出一个SLR(1)文法,但它不是LR(0)文法,构造它的SLR分析表。
7.5 给出一个LR(1)文法,但它不是LALR(1)文法,构造它的规范LR(1)分析表。
7.6 给定二义性文法:① E→E+E② E→E*E③ E→(E)④ E→id用所述的无二义性规则和(或)另加一些无二义性规则,例如,给算符*、+施加某种结合规则。
①构造它的LR(0)项目集规范族及识别活前缀的DFA;②构造它的LR分析表。
习题参考答案7.1 解:文法的基本LR(0)项目集为S→.(A) S→(.A) S→(A.) S→(A).A→.ABB A→A.BB A→AB.B A→ABB.A→.B A→B. B→.b B→b.B→.c B→c.构造该文法的识别活前缀的DFSA如下图所示:I文法的识别活前缀的DFSA该文法的LR(0)项目集规范族={I0,I1,I2,I3,I4,I5,I6,I7,I8}因为在构造出来的识别活前缀的DFA中,每一个状态对应的项目集都不含有移进-归约、归约-归约冲突,所以该文法是LR(0)文法,当然也是SLR文法。
因为 FOLLOW(S)={#}FOLLOW(A)=FIRST{)}∪FIRST(BB)={),b,c}FOLLOW(B)=FIRST(B)∪FOLLOW(A)={b,c,)}其对应的SLR(1)分析表如下表所示。
第七章LR分析法1.已知文法A→aAd|aAb|ε判断该文法是否是SLR(1)文法,若是构造相应分析表,并对输入串ab#给出分析过程。
解:增加一个非终结符S/后,产生原文法的增广文法有:S/→AA→aAd|aAb|ε下面构造它的LR(0)项目集规范族为:02对于I0来说有FOLLOW(A)∩{a}={b,d,#}∩{a}=Φ所以在I0状态下面临输入符号为a时移进,为b,d,#时归约,为其他时报错。
对于I2来说有也有与I0完全相同的结论。
这就是说,以上的移进-归约冲突是可以解决的,因此该文法是SLR(1)文法。
其他SLR(1)分析表为:下面构造它的SLR(1)项目集规范族为:15S→a|^|(T)T→T,S|S(1)构造它的LR(0),LALR(1),LR(1)分析表。
(2)给出对输入符号串(a#和(a,a#的分析过程。
(3)说明(1)中三种分析表发现错误的时刻和输入串的出错位置有何区别。
解:(1)加入非终结符S/,方法的增广文法为:S/→SS→aS→^S→(T)T→T,ST→S下面构造它的LR(0)项目集规范族为:表7.15.1 文法的LR(0)分析表17.若包含条件语句的语句文法可缩写为:S→iSeS|iS|S;S|a其中:i代表if,e代表else,a代表某一语句。
若规定:(1)else与其左边最近的if结合(2);服从左结合试给出文法中i,e,; 的优先关系,然后构造出无二义性的LR分析表,并对输入串iiaea#给出分析过程。
解:加入S/→S产生式构造出增广文法如下:[0] S/→S[1] S→iSeS[2] S→iS[3] S→S;S[4] S→a由习惯可知,定义文法中i,e,;,a4个算符的优先关系为:a>e>i>;。
并且i与;的结合方向均为自左至右。
由上述状态项目集可见:a.状态I1存在移进-归约冲突,由于FOLLOW(S/)∩{;}={#}∩{;}=Φ,所以面临#号时应acc,面临;号时应移进。
编译原理作业集-第七章(精选.)第七章语义分析和中间代码产⽣本章要点1. 中间语⾔,各种常见中间语⾔形式;2. 说明语句、赋值语句、布尔表达式、控制语句等的翻译;3. 过程调⽤的处理;4. 类型检查;本章⽬标掌握和理解中间语⾔,各种常见中间语⾔形式;各种语句到中间语⾔的翻译;以及类型检查等内容。
本章重点1.中间代码的⼏种形式,它们之间的相互转换:四元式、三元式、逆波兰表⽰;3.赋值语句、算术表达式、布尔表达式的翻译及其中间代码格式;4.各种控制流语句的翻译及其中间代码格式;5.过程调⽤的中间代码格式;6.类型检查;本章难点1. 各种语句的翻译;2. 类型系统和类型检查;作业题⼀、单项选择题:1. 布尔表达式计算时可以采⽤某种优化措施,⽐如A and B⽤if-then-else可解释为_______。
a. if A then true else B;b. if A then B else false;c. if A then false else true;d. if A then true else false;2. 为了便于优化处理,三地址代码可以表⽰成________。
a. 三元式b. 四元式c. 后缀式d. 间接三元式3. 使⽤三元式是为了________:a. 便于代码优化处理b. 避免把临时变量填⼊符号表c. 节省存储代码的空间d. 提⾼访问代码的速度4. 表达式-a+b*(-c+d)的逆波兰式是________。
a. ab+-cd+-*;b. a-b+c-d+*;c. a-b+c-d+*;d. a-bc-d+*+;5. 赋值语句x:=-(a+b)/(c-d)-(a+b*c)的逆波兰式表⽰是_______。
a. xab+cd-/-bc*a+-:=;a. xab+/cd-bc*a+--:=;a. xab+-cd-/abc*+-:=;a. xab+cd-/abc*+--:=;6. 在⼀棵语法树中结点的继承属性和综合属性之间的相互依赖关系可以由________来描述。
编译原理模拟试卷一、选择题(每题1分,共5分)1.在编译过程中,词法分析的主要任务是什么?A.构建语法树B.将源程序分解为单词序列C.语义分析D.代码2.下列哪个不属于编译器的组成部分?A.词法分析器B.语法分析器C.代码器D.数据库管理系统3.在编译器中,中间代码的作用是什么?A.提高编译速度B.方便目标代码C.提高程序的可读性4.下列哪种语言通常被用作编译器的实现语言?A.PythonB.JavaC.C++5.在编译原理中,形式语言的主要作用是什么?A.描述程序设计语言的语法B.描述程序的语义C.描述程序的数据结构D.描述程序的算法二、判断题(每题1分,共5分)1.编译器的主要任务是将源程序转换为目标代码。
(正确/错误)2.语法分析器负责检查源程序中的语法错误。
(正确/错误)3.语义分析是在语法分析之后进行的。
(正确/错误)4.中间代码是一种与机器无关的代码。
(正确/错误)5.代码优化不会影响程序的正确性。
(正确/错误)三、填空题(每题1分,共5分)1.编译器包括____、____、____、____等组成部分。
2.在编译过程中,____负责将源程序分解为单词序列。
3.语法分析器的主要任务是构建____。
4.语义分析器负责检查____。
5.代码器负责____。
四、简答题(每题2分,共10分)1.简述编译器的工作流程。
2.解释什么是词法分析。
3.什么是语法分析?它的主要任务是什么?4.什么是语义分析?它的主要作用是什么?5.简述中间代码的作用。
五、应用题(每题2分,共10分)1.给出一个简单的C语言程序,请描述它通过编译器的过程。
2.什么是编译器的优化?请给出一个例子。
3.解释什么是编译器的错误处理。
4.什么是编译器的调试信息?它的作用是什么?5.请解释编译器的前端和后端。
六、分析题(每题5分,共10分)1.分析并解释编译器中的词法分析、语法分析和语义分析之间的关系。
2.分析并解释编译器中的中间代码和目标代码之间的关系。
第7章习题7-1 设有如下的三地址码(四元式)序列:read NI:=NJ:=2L1 : if I≤J goto L3L2 : I:=I-Jif I>J goto L2if I=0 goto L4J:=J+1I:=Ngoto L1L3 : Print ′YES′haltL4 : Print ′NO′halt试将它划分为基本块,并作控制流程图。
7-2 考虑如下的基本块:D:=B*CE:=A+BB:= B*CA:=E+D(1) 构造相应的DAG;(2) 对于所得的DAG,重建基本块,以得到更有效的四元式序列。
7-3 对于如下的两个基本块:(1) A:=B*CD:=B/CE:=A+DF:=2*EG:=B*CH:=G*GF:=H*GL:=FM:=L(2) B:=3D:=A+CE:=A*CF:=E+DG:=B*FH:=A+CI:=A*CJ:=H+IK:=B*5L:=K+JM:=L分别构造相应的DAG,并根据所得的DAG,重建经优化后的四元式序列。
在进行优化时,须分别考虑如下两种情况:(ⅰ)变量G、L、M在基本块出口之后被引用;(ⅱ)仅变量L在基本块出口之后被引用。
7-4 对于题图7-4所示的控制流程图:(1) 分别求出它们各个结点的必经结点集;(2) 分别求出它们的各个回边;(3) 找出各流程图的全部循环。
7-5 对于如下的程序:I:=1read J,KL: A:=K*IB:=J*IC:=A*Bwrite CI:=I+1if A<100 goto Lhalt试对其中的循环进行可能的优化。
第8章习题答案7-1 解:划分情况及控制流程如答案图7-1所示:答案图7-1 将四元式序列划分为基本块7-2 解:(1) 相应的DAG如答案图7-2所示。
答案图7-2 DAG(2) 优化后的代码为:D:=B*CE:=A+BB:=DA:=E+D7-3 解:(1) 相应的DAG如答案图7-3-(1)所示。
若只有G、L、M在出口之后被引用,则优化后的代码为:G:=B*CH:=G*GL:=H*GM:=L若只有L在出口之后被引用,则代码为:G:=B*CH:=G*GL:=H*G(2) 相应的DAG如答案图7-3-(2)所示。
第七章习题答案1.拓广该文法:(0) S→A (1)A→aAd (2)A→aAb (3)A→ε构造LR(0)项目集规范族如下:由图可知,在项目集I0、I2中存在移进-归约冲突,该文法不是LR(0)文法。
在I0中,移进符号为a,而归约符号为Follow(A)={b,d,#},交集为空,可以解决冲突;在I2中,移进符号为a,而归约符号为Follow(A)={b,d,#},交集为空,可以解决冲突。
因此,该文法是SLR(1)文法。
输入串ab#的分析过程7.拓广该文法:(0) S’→S (1) S→A (2)A→Ab (3)A→bBa(4)B→aAc (5)B→a (6)B→aAb构造LR(0)项目集规范族如下:由图可知,在项目集I2、I6中存在移进-归约冲突,该文法不是LR(0)文法。
Follow(S’)={#}Follow(S)=Follow(S’)={#}Follow(A)=Follow(S)∪{b,c}={b,c,#}Follow(B)={a}在I2中,移进符号为b,归约符号为Follow(S)={#},交集为空,可以解决冲突;在I6中,移进符号为b,归约符号为Follow(B)={a},交集为空,可以解决冲突。
因此,该文法为SLR(1)文法。
8.拓广该文法:(0) S’→S (1) S→A$ (2)A→BaBb(3)A→DbDa (4)B→ε(5)D→ε构造LR(0)项目集规范族如下:由图可知,在项目集I0中存在归约-归约冲突,该文法不是LR(0)文法。
Follow(S’)={#}Follow(S)=Follow(S’)={#}Follow(A)= {$}Follow(B)={a,b}Follow(D)={a,b}在I 0中,归约项目B→·的归约符号集为Follow(B)={a,b},归约项目D→·的归约符号集为{a,b},交集不为空,因此,该文法不是SLR(1)文法。
构造LR(1)项目集规范族如下:由图可知,不存在任何冲突,该文法是LR(1)文法。
第七章语义分析和中间代码产生本章要点1. 中间语言,各种常见中间语言形式;2. 说明语句、赋值语句、布尔表达式、控制语句等的翻译;3. 过程调用的处理;4. 类型检查;本章目标掌握和理解中间语言,各种常见中间语言形式;各种语句到中间语言的翻译;以及类型检查等内容。
本章重点1.中间代码的几种形式,它们之间的相互转换:四元式、三元式、逆波兰表示;3.赋值语句、算术表达式、布尔表达式的翻译及其中间代码格式;4.各种控制流语句的翻译及其中间代码格式;5.过程调用的中间代码格式;6.类型检查;本章难点1. 各种语句的翻译;2. 类型系统和类型检查;作业题一、单项选择题:1. 布尔表达式计算时可以采用某种优化措施,比如A and B用if-then-else可解释为_______。
a. if A then true else B;b. if A then B else false;c. if A then false else true;d. if A then true else false;2. 为了便于优化处理,三地址代码可以表示成________。
a. 三元式b. 四元式c. 后缀式d. 间接三元式3. 使用三元式是为了________:a. 便于代码优化处理b. 避免把临时变量填入符号表c. 节省存储代码的空间d. 提高访问代码的速度4. 表达式-a+b*(-c+d)的逆波兰式是________。
a. ab+-cd+-*;b. a-b+c-d+*;c. a-b+c-d+*;d. a-bc-d+*+;5. 赋值语句x:=-(a+b)/(c-d)-(a+b*c)的逆波兰式表示是_______。
a. xab+cd-/-bc*a+-:=;a. xab+/cd-bc*a+--:=;a. xab+-cd-/abc*+-:=;a. xab+cd-/abc*+--:=;6. 在一棵语法树中结点的继承属性和综合属性之间的相互依赖关系可以由________来描述。
a. 抽象语法树;b. 语法规则;c. 依赖图;d. 三地址代码;7. 按照教材中的约定,三地址语句if x relop y then L表示成四元式为。
a. (relop,x,y,L);b. (relop,L,x,y);c. (relop,x,L,y);d. (L,x,y,relop);8. 在编译程序中,不是常见的中间语言形式。
a.波兰式;b. 三元式;c. 四元式;d. 抽象语法树;9. 在编译程序中安排中间代码生成的目的是________。
a. 便于提高编译效率;b. 便于提高分析的正确性;c. 便于代码优化和目标程序的移植;d.便于提高编译速度;10. 按照教材中的约定,下面不是类型表达式:a. boolean;b. type-error;c. real;d. DAG;11. 一个Pascal函数function f ( a, b:char ) :↑integer;……其作用域类型是:a. char×integer;b. char×char;c. char×pointer(integer);d. integer×integer;12. 因为标识符可用于多种情况,比如常量标识符、变量标识符、过程标识符等等。
因此,在符号表中为了给出各个符号的标志,常给标识符引入一个属性kind,然后在相应产生式的语义动作中添加给kind属性赋值的语句。
比如,在在产生式D id:T的语义动作中添加赋值语句id.kind= 。
a. V AR;b. CONSTANT;c. PROC;d. FUNC;13. 下面情况下,编译器需要创建一张新的符号表。
a. 过程调用语句;b. 标号说明语句;c. 数组说明语句;d.记录说明语句;14. 函数function f(a,b:char):↑integer;…所以f函数的类型表达式为:a. char×char→pointer(integer);b. char×char→pointer;c. char×char→integer;d. char×char→integer (pointer)15. 如果一个语言的编译器能保证编译通过的程序,在运行时不会出现类型错误,则称该语言是。
a. 静态的;b. 强类型的;c. 动态的;d. 良类型的;一.答案:1. b;2. d;3. b;4. d;5. c;6. c.;7. a;8. a;9. c;10. d;11. b;12. a;13. d;14. a;15. b;二、填空题:1. 语法分析是依据语言的语法规则进行的,中间代码产生是依据语言的________规则进行的。
2. 多目运算x:=y[i]的三元式表示为两部分:________________和________________。
3.生成三地址代码时,临时变量的名字对应抽象语法树的____________。
4. 一个类型表达式或者是基本类型,或者由____________施加于其它类型表达式组成。
5. 在程序设计语言中,布尔表达式有两个基本的作用:一个是;另一个是。
6. 允许嵌套过程的语言,其过程说明语句的翻译用两个栈tblptr和offset分别保存尚未处理完的过程的和它们的offset,这两个栈顶的元素分别是正在处理的过程的的符号表指针和。
7. 在一些pascal的实现中,如果说明中出现了没有名字的类型表达式,编译器这样处理:建立一个来和每个声明的变量标识符相联系。
8. 赋值语句a:=b*-c+b*-c的后缀式为。
9. 多目运算X[i]:=y的三元式表示为两部分:________________和________________。
10. 编译器遇到常量说明时,要把常量值登录入并回送序号;在中为等号左边的标识符建立新条目,在该条目中填入常量标志、相应类型和常量表序号。
11. 典型的转移条件语句:if E then S1 else S2中,作为转移条件的布尔表达式E,赋予它两种“出口”:一是;二是。
12. 类型表达式或者是,或者是作用在其它类型表达式上得到的新的类型表达式。
13. pascal变量说明:var A:array[1..10] of integer与A相关的类型表达式为:。
14. 若T是类型表达式,则pointer(T)是类型表达式,它表示类型。
15. 通过一遍扫描来产生布尔表达式和控制流语句的代码存在一个问题,就是当生成某些转移语句时可能还不知道该语句将要转移到的语句的地址是什么。
采用的办法来解决这个问题。
二.1. 语义;2. (0): ( [ ]=, y, i ),(1): ( assign, x, (0) );3. 内部结点;4. 类型构造符;5. 计算逻辑值;作控制流语句中的条件表达式;6. 符号表指针,相对地址;7. 隐含的类型名;8. a b c uminus * b c uminus * + assign;9. (0):(=[ ],x,i);(1):(assign,(0),y);10. 常量表;符号表;11. “真”出口,转向S1;“假”出口,转向S2;12. 基本类型;类型构造符;13. array(1..10, integer) ;14. “指向T类型对象的指针”;15. “拉链-回填”三、判断题:1. 中间代码是独立于机器的,复杂性介于源语言和机器语言之间,便于进行与机器无关调换代码优化工作。
()2. 在程序设计语言中,一般来说,布尔表达式仅仅用于条件、循环等控制流语句中的条件表达式计算。
()3. “回填”技术用于对过程中的说明语句进行处理时把计算出的有关符号的属性填入符号表。
( )4. 如果E是一个常量或变量,则E的逆波兰式是E自身。
( )5. 对于任何一个编译程序来说,中间代码的产生是不一定必要的。
()6. 由于三元式中的三个域中,仅有两个域与地址有关,所以,三元式不是严格意义上的三地址代码。
()7. 两个类型表达式要么是同样的基本类型,要么是同样的类型构造符作用于结构等价的类型,我们就说,这两个类型系统等价。
()8. 对于Pascal这样允许嵌套过程的语言,每当遇到过程说明D→proc id ; D1; S时,便创建一张新的符号表,也就是说,让每个过程说明都有自己一张独立的符号表。
()9. 记录类型的各个域变量分配存储区域的地址的确定是相对于为记录类型变量所分配存储区域的首地址的,所以记录类型不应该建立自己的符号表。
()10. 类型表达式中不可出现类型变量,即类型变量值不是类型表达式。
()11. 所谓类型系统就是把类型表达式赋给语言各相关结构成分的规则的集合。
同一种语言(比如C++语言)的编译程序,在不同的实现系统里(比如微软的Visual C++和Linux下的开源编译器TCC),可能使用不同的类型系统。
12. 四元式表示的是四地址代码,三元式表示的是三地址代码。
()13. 生成三地址代码时,临时变量的名字对应抽象语法树的内部结点。
()14. 后缀式是抽象语法树的线性表示形式,后缀式是树结点的一个序列,其中每个结点都是在所有子结点之后立即出现的。
()15. 后缀表示形式只是用于表达式的,其他的语法结构比如条件语句、循环语句等不能使用后缀式。
()三.答案:1. √;2. ×;3. ×;4. √;5. √;6. ×;7. √;8. √;9. ×;10. ×;11. √;12. ×;13. √;14. √;15. ×;四、名词解释:1. 三地址代码;2. 回填;3. 类型表达式;4. 类型系统;5. 静态语义检查四.答案:1. 三地址代码是由下面一般形式的语句构成的序列:x:= y op z。
其中x、y、z为名字、常数或编译时产生的临时变量;op代表运算符号如定点运算符、浮点运算符、逻辑运算符等等,每个语句的右边只能有一个运算符。
2. 通过一遍扫描来产生布尔表达式和控制流语句的代码的主要问题在于,当生成某些转移语句时我们可能还不知道该语句将要转移到的标号是什么。
为了解决这个问题,可以在生成形成分支的跳转指令时,暂时不确定跳转目标,而建立一个链表,把转向这个目标的跳转指令的标号键入这个链表,一旦目标确定之后再把它填入有关的跳转指令中。
这种技术称为回填。
3. 一个类型表达式或者是基本类型,或者由类型构造符施于其他类型表达式组成。
基本类型和类型构造符都因具体语言的不同而不同。
Ⅰ. 一个基本类型是一个类型表达式。
Ⅱ. 类型名是一个类型表达式Ⅲ. 类型构造符作用于类型表达式,其结果仍然是类型表达式Ⅳ. 类型表达式中可出现类型变量,即变量值是类型表达式。