当前位置:文档之家› 编译原理作业集-第七章

编译原理作业集-第七章

编译原理作业集-第七章
编译原理作业集-第七章

第七章语义分析和中间代码产生

本章要点

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. 一个类型表达式或者是基本类型,或者由类型构造符施于其他类型表达式组成。基本类型和类型构造符都因具体语言的不同而不同。

Ⅰ. 一个基本类型是一个类型表达式。

Ⅱ. 类型名是一个类型表达式

Ⅲ. 类型构造符作用于类型表达式,其结果仍然是类型表达式

Ⅳ. 类型表达式中可出现类型变量,即变量值是类型表达式。

4. 所谓类型系统就是把类型表达式赋给语言各相关成分的规则的集合。同一种语言的编译程序,在不同的实现系统里,可能使用不同的类型系统。

5. 静态语义检查就是编译过程中进行的语义检查。主要工作有:类型检查、控制流检查、一致性检查、相关名字检查,还有名字的作用域分析等。

五、简答题:

1. 四元式和三元式有什么不同?

2. 为什么要使用中间代码的表示形式?

3. 现在有四种程序设计语言:PASCAL、FORTRAN、C和BASIC。要求在A、B、C和D 四种机器上都能编译这四种语言,而编译程序需要在中间语言级别上进行优化处理。问:需要编制多少个编译程序的前后端接口?

4. 为什么三元式没有存放计算结果的单元?

5. 过程调用语句在翻译的时候,如何处理参数传递的问题(只考虑传递实在参数地址的情况)?P200.

五.答案:1. 一个四元式是一个带有四个域的记录结构,分别为op,arg1,arg2,result。四元式之间的联系是通过临时变量来实现的,更改一个四元式表很容易,因此对中间代码进行优化处理时比较方便。

一个三元式是一个带有三个域的记录结构,分别为op,arg1,arg2。三元式之间的联系是通过指针来实现的,更改一个三元式表没有四元式表那样容易,但是,对中间代码进行优化处理时,四元式和间接三元式同样方便。

2. 使用中间代码有如下好处:

(1)中间形式与具体机器无关,把与机器特性紧密相关的内容尽可能放到后端,有利于目标重定位,一种中间形式可以为生成多种不同型号目标机上的目标代码服务。

(2)可以对中间代码进行与机器无关的优化,有利于提高目标代码的质量。

(3)使各阶段的开发复杂性降低,有利于编译程序的开发。

3. 由于各种不同的程序设计语言都有很多不同的特点,所以,若有m种不同的程序设计语言,就会有m个前端。这时,如果有n种不同的机器,也就会有n个后端。从理论上讲,如果要移植一个现有的编译程序到另外一台新机器上,只需要重新编写它的后端即可。

现在有四种程序设计语言:PASCAL、FORTRAN、C和BASIC,那么可以得到四个前端:有A、B、C和D四种机器,要求在每种机器上都能编译上述四种语言,只需要根据四种不同机器的特点为每种语言构造四个后端就行了。所以要在A、B、C和D四种机器上都能编译上述四种语言,总共需要编制16个前后端的接口即可。

4. 由于中间语言(包括三元式)是用来辅助生成目标代码的,并不会真正进行计算,也就

不需要一个临时单元存放结果,那么在编制后面的三元式时如果要用到这些运算结果,可以用这些三元式的编号来代替。

六、应用题:

1. 已知产生布尔表达式的语法定义如下:

E→E1 or E2

E→E1 and E2

E→not E1

E→(E

)

1

E→id1 relop id2

E→id

1

a写出翻译模式;

b画出语法树(语义动作也表示在其中);

c通过对语法树的遍历,写出对布尔表达式a

1. 答案:见教材P187,图7.14。

E→E1 or E2{E.place:=newtemp;

emit(E.place ':=' E1.place 'or' E2.place)}

E→E1 and E2{E.place:=newtemp;

emit(E.place ':=' E1.place 'and' E2.place)}

E→not E1 {E.place:=newtemp;

emit(E.place ':=' 'not' E1.place)}

E→(E1){E.place:= E1.place}

E→id1 relop id2{E.place:=newtemp;

emit('if' id1.place relop.op id2.place 'goto' nextstat+3);

emit(E.place ':=' '0');

emit('goto' nextstat+2);

emit(E.place ':=' '1')}

E→id1{E.place:=id.place}

100: if a

101: T1:=0

102: goto 104

103: T1:=1

104: if c

105: T2:=0

106: goto 108

107: T2:=1

108: if e

109: T3:=0

110: goto 112

111: T3:=1

112: T4:=T2 and T3

113: T5:=T1 or T4

2. 画出赋值语句a:=b*-c+b*-c的抽象语法树和DAG图,并写出它的后缀式表示法。

3. 翻译算术表达式a*- (b+c)为

a):一棵语法树

b):后缀式

c):三地址代码

3. 答案:(1)

(2)后缀式:a b c + uminus *

(3)三地址代码序列为:

t1:= b + c

t2 := - t1

t3 := a* t2

4. 翻译算术表达式–(a+b)*(c+d) +(a+b+c) 为

a):四元式

b):三元式

c):间接三元式

4. 答案:(1)四元式序列为:

op arg1 arg2 result

(1) + a b t1

(2) + c d t2

(3) * t1 t2 t3

(4) uminus t3 t4

(5) + a b t5

(6) + t5 c t6

(7) + t4 t6 t7

(2

op arg1 arg2

(1) + a b

(2) + c d

(3) * (1) (2)

(4) uminus (3)

(5) + a b

(3)间接三元式表示:

5. 已知数组翻译模式如下:

(1) S → L := E

{ if L.offset = null then // 简单变量

emit(L.place ‘:=’ E.place)

else //数组元素

emit(L.place ‘[’ L.offset ‘]’ ‘:=’ E.place) }

(2) E → E1 + E2

{ E.place := newtemp;

emit(E.place ‘:=’ E1.place ‘+’ E2.place) }

(4) E → L

{ if L.offset = null then

E.place := L.place

else begin

E.place := newtemp;

emit(E.place ‘:=’ L.place‘[’ L.offset ‘]’)

end }

(5) L → Elist ]

{ L.place := newtemp;

emit(L.place ‘:=’ Elist.array ‘-’, ck);

L.offset := newtemp;

emit(L.offset ‘:=’ w ‘*’ Elist.place) }

(6) L → id

{ L.place := id.place;

L.offset := null }

(7) Elist → Elist1, E

{ t := newtemp;

m:= Elist1.ndim + 1;

emit(t ‘:=’ Elist1.ndim ‘*’

limit(Elist1.array, m));

emit(t ‘:=’ t ‘+’ E.place);

Elist.array := Elist1.array;

Elist.place := t;

Elist.ndim := m }

(8) Elist id [ E

{ Elist.place := E.place;

E.ndim := 1;

Elist.array := id.place }

利用该翻译模式对下面赋值语句:A[i,j] :=B[i,j] + C[A[k,l]] + D[i+j]。

(1)画出并注释语法分析树;

(2)翻译成三地址代码;

5. 答案:对于C语言的数组,每维的下界约定为0。例如,对A[10,20]来说,A[0,0]是第一元素,A[i,j]的相对地址为:base + ( i * n2 + j ) * w

三地址序列如下:

t11 := i * 20

t12 := t11+j

t13 := A-84;

t14 := 4*t12

t15 := t13[t14] //A[i,j]

t21 := i*20

t22 := t21+j

t23 := B-84;

t24 := 4*t22

t25 := t23[t24] //B[i,j]

t31 := k*20

t32 := t31+l

t33 := A-84

t34 := 4*t32

t35 := t33[t34] //A[k,l]

t36 := 4*t35

t37 := C-4

t38 := t37[t36] //C[A[k,l]]

t41 := i+j

t42 := 4*t41

t43 := D-4

t44 := t43[t42] //D[i+j]

t1 := t25 +t38

t2 := t1 + t44

t23[t24] := t2

注:A,B,C,D分别表示数组A,B,C,D的基地址。

6. 试把下列C语言程序的可执行语句

main(){

int i;

int a[10];

while (i<=10)

a[i]=0;

}

翻译为:(1)一棵语法树,(2)后缀式,(3)三地址代码。

6.答案:(1)

(2)后缀式为:i 10 <= a i [] 0 = while

从理论上可以说while ( i <= 10 ) a[i] = 0; 的后缀式如上面表示。但若这样表示,在执行while 操作时,赋值语句已经执行,这显然与语义不符,因此改为:

i 10 <= <下一个语句开始地址> BM a i [] 0 = <本语句始址>BRL

其中BM操作为当表达式为假时转向<下一个语句开始地址>,BRL是一个一目运算,无条件转向<本语句始址>。

(3)三地址代码序列为:

100 if i <= 10 goto 102

101 goto 106

102 t1 := 4 * i

103 t2 := a

104 t2[t1] := 0

105 goto 100

106

7. 已知布尔表达式翻译成三地址代码的翻译模式如下:

E→E1 or E2 { E.place:=newtemp;

emit(E.place ':=' E1.place 'or' E2.place) }

E→E1 and E2 { E.place:=newtemp;

emit(E.place ':=' E1.place 'and' E2.place) }

E→not E1 { E.place:=newtemp;

emit(E.place ':=' 'not' E1.place) }

E→(E1) { E.place:= E1.place }

E→id1 relop id2 { E.place:=newtemp;

emit('if' id1.place relop.op id2.place 'goto' nextstat+3);

emit(E.place ':=' '0');

emit('goto' nextstat+2);

emit(E.place ':=' '1') }

E→id1 { E.place:=id.place }

试编写一个递归下降程序,用来该属性文法。

7. 答案:

首先消除该翻译模式的左递归:

(注:'{','}'为元语言符号。)

递归预测翻译程序如下:

TYPE

link = 表类型;

PROCEDURE E ;

V AR

E.truelist, E.falselist, T.truelist, T.falselist: link;

BEGIN

{ E.truelist, E,falselist } := T;

WHILE ( lookahead == 'or ' ) DO

BEGIN

match(or);

M.quad := nextquad;

{ T.truelist, T.falselist } := T;

backpatch(E.falselist, M.quad);

E.truelist := merge(E.truelist, T.truelist);

E.falselsit := T.falselist

END;

return({E.truelist, E.falselist})

END;

PROCEDURE T;

V AR

T.truelist, T.falselist, F.truelsit, F.falselist: link;

BEGIN

{ T.truelist, T,falselist } := F;

WHILE ( lookahead == 'and ' ) DO

BEGIN

match(and);

M.quad := nextquad;

{ F.truelist, F.falselist } := F;

backpatch(T.truelist, F.truelist);

T.truelist := F.truelist;

T.falselist := merge(T.falselist, F.falselist)

END;

return({T.truelist, T.falselist})

END;

PROCEDURE F;

V AR

F.truelist, F.falselist, E.truelsit, E.falselist: link;

BEGIN

CASE ( lookahead ) OF

'not' :BEGIN

match(not);

{ E.truelist, E.falselist } := F;

F.truelist := E.falselist;

F.falselist := E.truelist

END;

'( ' : BEGIN

match(();

{ E.truelist, E.falselist ) := E;

match());

F.truelist := E.truelist;

F.falselist := E.falselist

END;

'id' : BEGIN

match(id);

match(relop);

match(id);

F.truelist := makelist(nextquad);

F.falselist := makelist(nextquad+1);

emit('if' id1.place relop id2.place 'goto-');

emit('goto-')

END;

'true': BEGIN

match(true);

F.truelist := makelist(nextquad);

F.falselist := null;

emit('goto-')

END;

'false':BEGIN

match(false);

F.truelist := makelist(nextquad);

F.falselist := null;

emit('goto-')

END

otherwise : error

END of CASE

return({F.truelist, F.falselist})

END;

8. 试编写翻译模式,用来实现do-while语句的回填算法。

8.答案:

do-while语句的三地址代码结构如下:

从do-while语句的三地址代码结构可以知道,开始,要记录下L.code的开始地址,以填写E.truelist。生成E.code之前,要记录下E.code的开始地址,用它填写L.nextlist。为此,在规则相应处添加标记非终结符,以完成相应的语义动作。翻译模式如下:

9. Pascal语言中,语句

for v:=initial to final do stmt

与下列代码序列有相同含义

begin

t1:=initial; t2:=final;

if t1<=t2 then begin

v:=t1;

stmt

while v<>t2 do begin

v:=succ(v);

stmt

end

end

end

(1)试考虑下述Pascal程序

program forloop(input, output);

var i,initial,final: integer;

begin

read(initial, final);

for i:= initial to final do

write(i)

end

对于initial=MAXINT-5和final= MAXINT,问此程序将做些什么?其中MAXINT为目标机器允许的最大整数。

(2)试构造一个翻译pascal的for语句为三地址代码的语法制导定义。

9.

(1)显示如下六个整数:

MAXINT -5

MAXINT -4

MAXINT -3

MAXINT -2

MAXINT -1

MAXINT

(2)为简单起见,for语句的三地址代码如下:

t1 := initial

t2 := final

if t1 > t2 goto S.next

v := t1

stmt.code

S.begin:

if v > t2 goto S.next

v := succ(v)

stmt.code

goto S.begin

语法制导定义如下:

10. 假如有下面的Pascal说明

TYPE atype=ARRAY [0..9,-10..10] OF integer;

cell=RECORD

a,b:integer

END;

pcell=↑cell;

foo=ARRAY [1..100] OF cell;

FUNCTION bar(r:integer;y:cell):pcell;

BEGIN……END;

写出atype,cell,pcell,foo和bar的类型表达式。

10.答案:

atype: ARRAY(0..9, ARRAY(-10..10, integer));

cell: RECORD((a× integer)× (b×integer));

pcell: POINTER(cell);

或: POINTER(RECORD((a ×integer)× (b× integer)));

foo: ARRAY(1..100, cell);

或: ARRAY(1..100, RECORD((a ×integer)× (b× integer)));

bar: integer× cell→pcell;

或: integer× cell→POINTER(RECORD((a×integer) ×(b×integer)));

11. 已知语句序列的类型检查翻译方案:

S→id:=E { if id.type=E.type

then S.type:=void

else S.type:=type_error }

S→if E then S1 { if E.type=boolean

then S.type:=S1.type

else S.type:=type_error }

S→while E do S1 { if E.type=boolean

then S.type:=S1.type

else S.type:=type_error }

S→S1:S2 { if S1.type=void and S2.type=void

then S.type:=void

else S.type:=type_error }

修改该翻译方案,使之能够处理:

(1)语句有值。赋值语句的值是赋值号右边的表达式的值。条件语句或当语句的值是语句体的值,语句表的值是表中最后一个语句的值。

(2)布尔表达式。加上逻辑算符and,or和not,还有关系算符的产生式,然后给出适当的翻译规则,计算出这些表达式的类型。

11. 答案:(1)

S -> id:=E { S.type:= IF id.type=E.type

THEN E.type

ELSE type_error;

S.val:= IF id.type=E.type

THEN E.val

ELSE val_error }

S -> IF E THEN S1 {S.type:= IF E.type=boolean

THEN S1.type

ELSE type_error

S.val:= IF E.type=boolean

THEN S1.val

ELSE val_error}

S -> WHILE E DO S1 {S.type:= IF E.type=boolean

THEN S1.type

ELSE type_error

S.val:= IF E.type=boolean

THEN S1.val

ELSE val_error}

S -> S1;S2 {S.type:=S2.type;

S.val:=S2.val}

(2)

E -> E1 AND E2 {E.type:= IF(E1.type=boolean)AND(E2.type=boolean)

THEN boolean

ELSE type_error}

E -> E1 OR E2 {E.type:= IF(E1.type=boolean)AND(E2.type=boolean)

THEN boolean

ELSE type_error}

E -> NOT E1 {E.type:= IF(E1.type=boolean)

THEN boolean

ELSE type_error}

E -> E1 op E2 {E.type:= IF(E1.type=E2.type)

THEN boolean

ELSE type_error}

注:op为关系运算符,包括=, <>, <, >, <=, >=

12. 文法G[P]及其产生式如下:

P→D;E

D→D;D|id:T

T→list of T|char|integer

E→(L)|Literal|num|id

L→E,L|E

这个文法产生由字面常量组成的表。符号的解释和文法(7.11)相同,增加类型List,它表示类型为T的元素构成的表。写一个翻译模式,以确定表达式(E)和表(L)的类型(注:表中每个元素的类型是一样的)。

12.答案:

D -> id:T {addtype(id.entry,T.type))}

T -> char {T.type:=char}

T -> integer {T.type:=integer}

T -> list of T1 {T.type:=list(T1.type)}

E -> num {E.type:=integer}

E -> id {E.type:=lookup(id.entry)}

E -> Literal {E.type:=char}

E -> (L) {E.type:=list(L.type)}

L -> E,L1 {L.type:=IF (E.type=L1.type)

THEN E.type

ELSE type_error}

L -> E {L.type:=E.type}

编译原理作业集第七章

第七章语义分析和中间代码产生 本章要点 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、给出下面语言的相应文法。L1={a n b n c i|n≥1,i≥0} 答案: S→ AB|B A→ a|aA B→ bBc|bc 2.给出下面语言的相应文法 L1={a n b n c m d m| m,n≥1,n为奇数,m为偶数}。 答案:文法G(S):S→AC A→aaAbb/ab C→ccCcc/cc 3、构造一个DFA,它接受={a,b}上所有包含ab的字符串。 (要求:先将正规式转化为NFA,再将NFA确定化,最小化) (一)相应的正规式为(a|b)*ab(a|b)* (二)①与此正规式对应的NFA为 答案;在自己写的纸上 4、对下面的文法G: E→TE’ E’→+E|ε T→FT’ T’→T|ε F→PF’ F’→*F’|ε P→(E)|a|b|∧(1)证明这个文法是LL(1)的。 考虑下列产生式: E’->E|ε T’->T|ε F’->*F’ |ε P->(E) |∧a|b FIRST(+E)∩FIRST(ε)={+}∩{ε}=φ FIRST(+E)∩FOLLOW(E')={+}∩{#,)}=φ FIRST(T)∩FIRST(ε)={(,a,b,^}∩{ε}=φ

FIRST(T)∩FOLLOW(T')={(,a,b,^}∩{+,),#}=φ FIRST(*F')∩FIRST(ε)={*}∩{ε}=φ FIRST(*F')∩FOLLOW(F')={*}∩{(,a,b,^,+,),#}=φ FIRST((E))∩FIRST(a) ∩FIRST(b) ∩FIRST(^)=φ 所以,该文法式LL(1)文法. 计算这个文法的每个非终结符的FIRST和FOLLOW。(8分) 答案:FIRST(E)={(,a,b,^} FIRST(E')={+,ε} FIRST(T)={(,a,b,^} FIRST(T')={(,a,b,^,ε} FIRST(F)={(,a,b,^} FIRST(F')={*,ε} FIRST(P)={(,a,b,^} FOLLOW(E)={#,)} FOLLOW(E')={#,)} FOLLOW(T)={+,),#} FOLLOW(T')={+,),#} FOLLOW(F)={(,a,b,^,+,),#} FOLLOW(F')={(,a,b,^,+,),#} FOLLOW(P)={*,(,a,b,^,+,),#} (3)构造它的预测分析表。(6分) 答案;在手机上 写出表达式a+b*(c-d)对应的逆波兰式和三元式序列。 答案:逆波兰式:(abcd-*+) 三元式序列: OP ARG1 ARG2 (1) - c d (2) * b (1) (3) + a (2)

编译原理期末考试习题及答案

一、填空题|(每题4分,共20分) 1. 乔母斯基定义的3型文法(线性文法)产生式形式 A→Ba|a,或A→aB|a,A,B∈Vn, a,b∈Vt 。 2.语法分析程序的输入是单词符号,其输出是语法单位。 3 型为 B → .aB 的LR(0)项目被称为移进项目,型为 B → a.B 的LR(0) 项目被称为待约项目, 4.在属性文法中文法符号的两种属性分别为继承属性和综合属性。 5、运行时存贮管理方案有静态存储分配、动态存储分配和堆式存储分配和方案。 二.已知文法 G(S) (1) E → T | E+T (2) T → F | F*F (3) F →(E)| i (1)写出句型(T*F+i)的最右推到并画出语法树。(4分) (2)写出上述句型的短语,直接短语和句柄。(4分) 答:(1)最右推到(2分) E ==> T ==> F ==> (E) ==> (E+T) ==> (E+F) ==> (E+i) ==> (T+i) ==> (T*F+i) (2) 语法树(2分) (3)(4分) 短语:(T*F+i),T*F+i ,T*F , i 直接短语:T*F , i 句柄:T*F 三. 证明文法G(S) :S → SaS |ε是二义的。(6分) 答:句子aaa对应的两颗语法树为:

因此,文法是二义文法 四.给定正规文法G(S): (1) S → Sa | Ab |b (2) A → Sa 请构造与之等价的DFA。(6分) 答:对应的NFA为:(6分) 状态转换表: a b {F} Φ{S} {S} {S,A} Φ {S,A} {S,A} {S} 五. 构造识别正规语言b*a(bb*a)*b* 最小的DFA(要求写出求解过程)。(15分)答:(1)对应的NFA(5分) a b {0} {1,3} {0} {1,3} Φ{2,3} {2,3} {1,3} {2,3} (5分) 六. 已知文法G(S) : (1) S → ^ | a | (T) (2) T → T,S | S 试:(1)消除文法的左递归;(4分) (2)构造相应的first 和 follow 集合。(6分) 答:(1)消除文法的左递归后文法 G’(S)为: (1) S → ^ | a | (T)

王汝传编译原理习题答案

《编译原理》习题答案: 第一次: P14 2、何谓源程序、目标程序、翻译程序、汇编程序、编译程序和解释程序?它们之间可能有何种关系? 答:被翻译的程序称为源程序; 翻译出来的程序称为目标程序或目标代码; 将汇编语言和高级语言编写的程序翻译成等价的机器语言,实现此功能的程序称为翻译程序; 把汇编语言写的源程序翻译成机器语言的目标程序称为汇编程序; 解释程序不是直接将高级语言的源程序翻译成目标程序后再执行,而是一个个语句读入源程序,即边解释边执行; 编译程序是将高级语言写的源程序翻译成目标语言的程序。 关系:汇编程序、解释程序和编译程序都是翻译程序,具体见P4 图 1.3。 P14 3、编译程序是由哪些部分组成?试述各部分的功能? 答:编译程序主要由8个部分组成:(1)词法分析程序;(2)语法分析程序;(3)语义分析程序;(4)中间代码生成;(5)代码优化程序;(6)目标代码生成程序;(7)错误检查和处理程序;(8)信息表管理程序。具体功能见P7-9。 P14 4、语法分析和语义分析有什么不同?试举例说明。 答:语法分析是将单词流分析如何组成句子而句子又如何组成程序,看句子乃至程序是否符合语法规则,例如:对变量x:= y 符合语法规则就通过。语义分析是对语句意义进行检查,如赋值语句中x与y类型要一致,否则语法分析正确,语义分析则错误。 P15 5、编译程序分遍由哪些因素决定? 答:计算机存储容量大小;编译程序功能强弱;源语言繁简;目标程序优化程度;设计和实现编译程序时使用工具的先进程度以及参加人员多少和素质等等。 补充: 1、为什么要对单词进行内部编码?其原则是什么?对标识符是如何进行内部编码的? 答:内部编码从“源字符串”中识别单词并确定单词的类型和值;原则:长度统一,即刻画了单词本身,也刻画了它所具有的属性,以供其它部分分析使用。对于标识符编码,先判断出该单词是标识符,然后在类别编码中写入相关信息,以表示为标识符,再根据具体标识符的含义编码该单词的值。 补充: 2、赋值语句:A:= 5 * C的语法和语义指的是什么? 答:语法分析将检查该语句是否符合赋值语句规则,语义是指将 5 * C 的结果赋值为 A 。第二次作业: P38 1、设T1={11,010},T2={0,01,1001},计算:T2T1,T1*,T2+。 T2T1={011,0010,0111,01010,100111,1001010} T1*={ε,11,010,1111,11010,01011,010010……} T2+={0,01,1001,00,001,01001,010,0101……}

编译原理教程课后习题答案——第七章

第七章目标代码生成 7.1 对下列四元式序列生成目标代码: T=A-B S=C+D W=E-F U=W/T V=U*S 其中,V是基本块出口的活跃变量,R0和R1是可用寄存器。 【解答】简单代码生成算法依次对四元式进行翻译。我们以四元式T=a+b为例来说明其翻译过程。 汇编语言的加法指令代码形式为 ADD R, X 其中,ADD为加法指令;R为第一操作数,第一操作数必须为寄存器类型;X为第二操作数,它可以是寄存器类型,也可以是内存型的变量。ADD R,X指令的含意是:将第一操作数R与第二操作数相加后,再将累加结果存放到第一操作数所在的寄存器中。要完整地翻译出四元式T=a+b,则可能需要下面三条汇编指令: MOV R, a ADD R, b MOV T, R 第一条指令是将第一操作数a由内存取到寄存器R中;第二条指令完成加法运算;第三条指令将累加后的结果送回内存中的变量T。是否在翻译成目标代码时都必须生成这三条汇编指令呢?从目标代码生成的优化角度考虑,即为了使生成的目标代码更短以及充分利用寄存器,上面的三条指令中,第一条和第三条指令在某些情况下是不必要的。这是因为,如果下一个四元式紧接着需要引用操作数T,则第三条指令就不急于生成,可以推迟到以后适当的时机再生成。 此外,如果必须使用第一条指令,即第一操作数不在寄存器而是在内存中,且此时所有可用寄存器都已分配完毕,这时就要根据寄存器中所有变量的待用信息(也即引用点)来决定淘汰哪一个寄存器留给当前的四元式使用。寄存器的淘汰策略如下: (1) 如果某寄存器中的变量已无后续引用点且该变量是非活跃的,则可直接将该寄存器作为空闲寄存器使用。 (2) 如果所有寄存器中的变量在基本块内仍有引用点且都是活跃的,则将引用点最远的变量所占用寄存器中的值存放到内存与该变量对应的单元中,然后再将此寄存器分配给当前的指令使用。 因此,本题所给四元式序列生成的目标代码如下: MOV R0, A SUB R0, C /*R0=T*/ MOV R1, C ADD R1, D /*R1=S*/ MOV S, R1 /*S引用点较T引用点远,故将R1的值送内存单元S*/ MOV R1, E SUB R1, F /*R1=W*/ SUB R1, R0 /*R1=U*/ MUL R1, S /*R1=V*/ 7.2 假设可用的寄存器为R0和R1,且所有临时单元都是非活跃的,试将以下四元式基本

(精选)编译原理期末考试题目及答案

一、填空题(每空2分,共20分) 1.编译程序首先要识别出源程序中每个单词,然后再分析每个句子并翻译其意义。 2.编译器常用的语法分析方法有自底向上和自顶向下两种。 3.通常把编译过程分为分析前端与综合后端两大阶段。词法、语法和语义分析是对源程序的分析,中间代码生成、代码优化与目标代码的生成则是对源程序的综合。 4.程序设计语言的发展带来了日渐多变的运行时存储管理方案,主要分为两大类,即静态存储分配方案和动态存储分配方案。 5.对编译程序而言,输入数据是源程序,输出结果是目标程序。 1.计算机执行用高级语言编写的程序主要有两种途径:解释和编译。 2.扫描器是词法分析器,它接受输入的源程序,对源程序进行词法分析并识别出一个个单词符号,其输出结果是单词符号,供语法分析器使用。 3.自下而上分析法采用移进、归约、错误处理、接受等四种操作。 4.一个LL(1)分析程序需要用到一张分析表和符号栈。 5.后缀式abc-/所代表的表达式是a/(b-c)。 二、单项选择题(每小题2分,共20分) 1.词法分析器的输出结果是__C。 A.单词的种别编码B.单词在符号表中的位置 C.单词的种别编码和自身值D.单词自身值 2.正规式 M 1 和 M 2 等价是指__C_。 A. M1和M2的状态数相等B. M1和M2的有向边条数相等 C. M1和M2所识别的语言集相等 D. M1和M2状态数和有向边条数相等 3.文法G:S→xSx|y所识别的语言是_C____。 A. xyx B. (xyx)* C.xnyxn(n≥0) D. x*yx* 4.如果文法G是无二义的,则它的任何句子α_A____。 A.最左推导和最右推导对应的语法树必定相同B.最左推导和最右推导对应的语法树可能不同 C.最左推导和最右推导必定相同D.可能存在两个不同的最左推导,但它们对应的语法树相同5.构造编译程序应掌握____D__。 A.源程序B.目标语言 C.编译方法 D.以上三项都是 6.四元式之间的联系是通过__B___实现的。 A.指示器B.临时变量C.符号表 D.程序变量 7.表达式(┐A∨B)∧(C∨D)的逆波兰表示为__B___。 A.┐AB∨∧CD∨B.A┐B∨CD∨∧C. AB∨┐CD∨∧ D.A┐B∨∧CD∨8. 优化可生成__D___的目标代码。 A.运行时间较短B.占用存储空间较小 C.运行时间短但占用内存空间大 D.运行时间短且占用存储空间小 9.下列___C___优化方法不是针对循环优化进行的。 A. 强度削弱 B.删除归纳变量C.删除多余运算 D.代码外提 10.编译程序使用_B_区别标识符的作用域。 A. 说明标识符的过程或函数名B.说明标识符的过程或函数的静态层次 C.说明标识符的过程或函数的动态层次 D. 标识符的行号 三、判断题(对的打√,错的打×,每小题1分,共10分) 2.一个有限状态自动机中,有且仅有一个唯一的终态。x

编译原理 第一章 习题解答

第一章习题解答 2.编译程序有哪些主要构成成分?各自的主要功能是什么? 编译程序的主要构成成分有:词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、代码优化程序、目标代码生成程序、表格管理程序及出错处理程序。 (1)词法分析程序:从左到右扫描源程序,识别单词及其有关属性; (2)语法分析程序:分析源程序的结构, 判别它是否为相应程序设计语言中的一个合法程序; (3)语义分析程序:审查源程序有无语义错误,为代码生成阶段收集类型信息; (4)中间代码生成程序:将源程序变成一种内部表示形式; (5)代码优化程序:对前阶段产生的中间代码进行变换或进行改造,使生成的目标代码更为高效; (6)目标代码生成程序:把中间代码变换成特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码; (7)表格管理程序:保存编译过程中的各种信息; (8)出错处理程序:若编译过程中发现源程序存在错误,则报告错误的性质和错误发生的地点,有些还可以自动校正错误。 3.什么是解释程序?它与编译程序的主要不同是什么? 解释程序接受某个语言的程序并立即运行这个源程序。它的工作模式是一个个的获取、分析并执行源程序语句,一旦第一个语句分析结束,源程序便开始运行并且生成结果,它特别适合程序员交互方式的工作情况。 而编译程序是一个语言处理程序,它把一个高级语言程序翻译成某个机器的汇编或二进制代码程序,这个二进制代码程序再机器上运行以生成结果。 它们的主要不同在于:解释程序是边解释边执行,解释程序运行结束即可得到该程序的运行结果,而编译程序只是把源程序翻译成汇编或者二进制程序,这个程序再执行才能得到程序的运行结果。(当然还有其他不同,比如存储组织方式不同)

编译原理试题及答案3

编译原理复习题 一、填空题: 1、编译方式与解释方式的根本区别在于(是否生成目标代码)。 2、对编译程序而言,输入数据是(源程序),输出结果是(目标程序)。 3、如果编译程序生成的目标程序是机器代码程序,则源程序的执行分为两大阶段:(编译阶段)和(运行阶段)。 4、如果编译程序生成的目标程序是汇编语言程序,则源程序的执行分成三个阶段:(编译阶段)、(汇编阶段)和(运行阶段)。 5、自顶向下语法分析方法会遇到的主要问题有(回溯)和((左递归带来的)无限循环)。 6、LL(k)分析法中,第一个L的含义是(从左到右进行分析),第二个L的含义是(每次进行最左推导),“k”的含义是(向输入串中查看K个输入符号)。 7、LL(1)分析法中,第一个L的含义是(从左到右进行分析),第二个L的含义是(每次进行最左推导),“1”的含义是(向输入串中查看1个输入符号)。 8、自顶向下语法分析方法的基本思想是:从(识别符号)出发,不断建立(直接推导),试图构造一个推导序列,最终由它推导出与输入符号相同的(符号串)。 9、自底向上语法分析方法的基本思想是:从待输入的符号串开始,利用文法的规则步步向上进行(直接归约),试图(归约)到文法的(识别符号|开始符号)。 10、LR(0)分析法的名字中,“L”的含义是(从左到右进行分析),“R”的含义是(采用最右推导的逆过程---最左归约),“0”的含义是(向貌似句柄的符号串后查看0个输入符号)。 11、LR(1)分析法的名字中,“L”的含义是(从左到右进行分析),“R”的含义是(采用最右推导的逆过程---最左归约),“1”的含义是(向貌似句柄的符号串后查看1个输入符号)。 12、SLR(1)分析法的名字中,“S”的含义是(简单的),“L”的含义是(从左到右进行分析),“R”的含义是(采用最右推导的逆过程---最左归约),“1”的含义是(向貌似句柄的符号串后查看1个输入符号)。 13、在编译过程中,常见的中间语言形式有(逆波兰表示)、(三元式)、(四元式)和(树形表示)。 14、在编译程序中安排中间代码生成的目的是(便于代码优化)和(便于目标程序的移植)。 15、表达式-a+b*(-c+d)的逆波兰表示为(a-bc-d+*+ )。 16、表达式a+b*(c+d/e)的逆波兰表示为(abcde/+*+ )。 17、表达式a:=a+b*c↑(d/e)/f的逆波兰表示为(aabcde/↑*f/+:= )。 18、文法符号的属性有(继承属性)和(综合属性)两种。 19、一个文法符号的继承属性是通过语法树中它的(兄弟结点与父)结点的相应文法符号的属性来计算的。 20、一个文法符号的综合属性是通过语法树中它的(子)结点的属性来计算的。

编译原理复习题及答案

编译原理复习题及答案一、选择题 1.一个正规语言只能对应( B ) A 一个正规文法 B 一个最小有限状态自动机 2.文法G[A]:A→εA→aB B→Ab B→a是( A ) A 正规文法 B 二型文法 3.下面说法正确的是( A ) A 一个SLR(1)文法一定也是LALR(1)文法 B 一个LR(1)文法一定也是LALR(1)文法 4.一个上下文无关文法消除了左递归,提取了左公共因子后是满足LL(1)文法的( A ) A 必要条件 B 充分必要条件 5.下面说法正确的是( B ) A 一个正规式只能对应一个确定的有限状态自动机 B 一个正规语言可能对应多个正规文法 6.算符优先分析与规范归约相比的优点是( A ) A 归约速度快 B 对文法限制少 7.一个LR(1)文法合并同心集后若不是LALR(1)文法( B ) A 则可能存在移进/归约冲突 B 则可能存在归约/归约冲突 C 则可能存在移进/归约冲突和归约/归约冲突 8.下面说法正确的是( A ) A Lex是一个词法分析器的生成器 B Yacc是一个语法分析器 9.下面说法正确的是( A ) A 一个正规文法也一定是二型文法 B 一个二型文法也一定能有一个等价的正规文法 10.编译原理是对(C)。 A、机器语言的执行 B、汇编语言的翻译 C、高级语言的翻译 D、高级语言程序的解释执行

11.(A)是一种典型的解释型语言。 A.BASIC B.C C.FORTRAN D.PASCAL 12.把汇编语言程序翻译成机器可执行的目标程序的工作是由(B)完成的。 A. 编译器 B. 汇编器 C. 解释器 D. 预处理器 13.用高级语言编写的程序经编译后产生的程序叫(B) A.源程序?B.目标程序C.连接程序D.解释程序14.(C)不是编译程序的组成部分。 A.词法分析程序 B.代码生成程序? C.设备管理程序 D.语法分析程序 15.通常一个编译程序中,不仅包含词法分析,语法分析,语义分析,中间代码生成,代码优化,目标代码生成等六个部分,还应包括(C)。 A.模拟执行器B.解释器?C.表格处理和出错处理 ??? D.符号执行器16.编译程序绝大多数时间花在(D)上。 A.出错处理B.词法分析C.目标代码生成D.表格管理 17.源程序是句子的集合,(B)可以较好地反映句子的结构。 A. 线性表 B. 树 C. 完全图 D. 堆栈 18.词法分析器的输出结果是(D)。 A、单词自身值 B、单词在符号表中的位置 C、单词的种别编码 D、单词的种别编码和自身值 19.词法分析器不能(D) A. 识别出数值常量 B. 过滤源程序中的注释 C. 扫描源程序并识别记号 D. 发现括号不匹配 20.文法:G:S→xSx | y所识别的语言是(D)。 A、xyx B、(xyx)* C、x*yx* D、x n yx n(n≥0) 21.如果文法G是无二义的,则它的任何句子α(A) A.最左推导和最右推导对应的语法树必定相同 B.最左推导和最右推导对应的语法树可能不同 C.最左推导和最右推导必定相同 D.可能存在两个不同的最左推导,但它们对应的语法树相同 22.正则文法(A)二义性的。 A. 可以是 B. 一定不是 C. 一定是 23.(B)这样一些语言,它们能被确定的有穷自动机识别,但不能用正则表达式表示。 A. 存在 B. 不存在 C. 无法判定是否存在 24.给定文法A→bA | ca,为该文法句子的是(C)

编译原理课后习题答案+清华大学出版社第二版

第 1 章引论 第1 题 解释下列术语: (1)编译程序 (2)源程序 (3)目标程序 (4)编译程序的前端 (5)后端 (6)遍 答案: (1)编译程序:如果源语言为高级语言,目标语言为某台计算机上的汇编语言或机器语言,则此翻译程序称为编译程序。 (2)源程序:源语言编写的程序称为源程序。 (3)目标程序:目标语言书写的程序称为目标程序。 (4)编译程序的前端:它由这样一些阶段组成:这些阶段的工作主要依赖于源语言而与目标机无关。通常前端包括词法分析、语法分析、语义分析和中间代码生成这些阶 段,某些优化工作也可在前端做,也包括与前端每个阶段相关的出错处理工作和符 号表管理等工作。 (5)后端:指那些依赖于目标机而一般不依赖源语言,只与中间代码有关的那些阶段,即目标代码生成,以及相关出错处理和符号表操作。 (6)遍:是对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。 第2 题 一个典型的编译程序通常由哪些部分组成?各部分的主要功能是什么?并画出编译程序的总体结构图。 答案: 一个典型的编译程序通常包含8个组成部分,它们是词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、中间代码优化程序、目标代码生成程序、表格管理程序和错误处理程序。其各部分的主要功能简述如下。 词法分析程序:输人源程序,拼单词、检查单词和分析单词,输出单词的机内表达形式。 语法分析程序:检查源程序中存在的形式语法错误,输出错误处理信息。 语义分析程序:进行语义检查和分析语义信息,并把分析的结果保存到各类语义信息表中。 中间代码生成程序:按照语义规则,将语法分析程序分析出的语法单位转换成一定形式的中间语言代码,如三元式或四元式。 中间代码优化程序:为了产生高质量的目标代码,对中间代码进行等价变换处理。目标代码生成程序:将优化后的中间代码程序转换成目标代码程序。

编译原理第七章例题

1.写出下列表达式的三地址形式的中间表示。 (1)5+6 ? (a + b); (2)?A∨( B ∧ (C ∨ D)); (3)for j:=1 to 10 do a[j + j]:=0; (4)if x > y then x:=10 else x:= x + y; 答:⑴100: t1:=a+b 101: t2:=6*t1 102: t3:=5+t2 ⑵100: if A goto 102 101: goto T 102: if B goto 104 103: goto F 104: if C goto T 105: goto 106 106: if D goto T 107: goto F ⑶100: j:=1 101: if j>10 goto NEXT 102: i:=j+j 103: a[i]:=0 104: goto 101 ⑷100: if x>y goto 102 101: goto 104 102: x:=10 103: goto 105 104: x:=x+y 105: 2.将语句if A V B>0 then while C>0 do C:=C+D翻译成四元式。答:

100 (jnz,A,-,104) 101 (j,-,-,102) 102 (j>,B,0,104) 103 (j,-,-,109) 104 (j>,C,0,106) 105 (j,-,-,109) 106 (+,C,D,T1) 107 (:=,T1,-,C) 108 (j,-,-,104) 109 3.试将下述程序段翻译成三地址形式的中间代码表示。 while ( a+b

编译原理试题及答案

参考答案 一、单项选择题(共10小题,每小题2分,共20分) 1.语言是 A .句子的集合 B .产生式的集合 C .符号串的集合 D .句型的集合 2.编译程序前三个阶段完成的工作是 A .词法分析、语法分析和代码优化 B .代码生成、代码优化和词法分析 C .词法分析、语法分析、语义分析和中间代码生成 D .词法分析、语法分析和代码优化 3.一个句型中称为句柄的是该句型的最左 A .非终结符号 B .短语 C .句子 D .直接短语 4.下推自动机识别的语言是 A .0型语言 B .1型语言 C .2型语言 D .3型语言 5.扫描器所完成的任务是从字符串形式的源程序中识别出一个个具有独立含义的最小语法单位即 A . 字符 B .单词 C .句子 D .句型 6.对应Chomsky 四种文法的四种语言之间的关系是 A .L 0?L 1?L 2?L 3 B .L 3?L 2?L 1?L 0 C .L 3=L 2?L 1?L 0 D .L 0?L 1?L 2=L 3 7.词法分析的任务是 A .识别单词 B .分析句子的含义 C .识别句子 D .生成目标代码 8.常用的中间代码形式不含 A .三元式 B .四元式 C .逆波兰式 D .语法树 9. 代码优化的目的是 A .节省时间 B .节省空间 C .节省时间和空间 D .把编译程序进行等价交换 10.代码生成阶段的主要任务是 A .把高级语言翻译成汇编语言 B .把高级语言翻译成机器语言 C .把中间代码变换成依赖具体机器的目标代码 装 订 线

D.把汇编语言翻译成机器语言 二、填空题(本大题共5小题,每小题2分,共10分) 1.编译程序首先要识别出源程序中每个(单词),然后再分析每个(句子)并翻译其意义。2.编译器常用的语法分析方法有(自底向上)和(自顶向下)两种。 3.通常把编译过程分为分析前端与综合后端两大阶段。词法、语法和语义分析是对源程序的(分析),中间代码生成、代码优化与目标代码的生成则是对源程序的(综合)。 4.程序设计语言的发展带来了日渐多变的运行时存储管理方案,主要分为两大类,即(静态存储分配)方案和(动态存储分配)方案。 5.对编译程序而言,输入数据是(源程序),输出结果是(目标程序)。 三、名词解释题(共5小题,每小题4分,共20分) 1.词法分析 词法分析的主要任务是从左向右扫描每行源程序的符号,按照词法规则 从构成源程序的字符串中识别出一个个具有独立意义的最小语法单位, 并转换成统一的内部表示(token),送给语法分析程序。 2.LL(1)文法 若文法的任何两个产生式A →α | β都满足下面两个条件: (1)FIRST(α) ? FIRST(β ) = φ; (2)若β?* ε,那么FIRST(α) ? FOLLOW( A ) = φ。 我们把满足这两个条件的文法叫做LL(1)文法,其中的第一个L代表从左 向右扫描输入,第二个L表示产生最左推导,1代表在决定分析器的每步 动作时向前看一个输入符号。除了没有公共左因子外,LL(1)文法还有一 些明显的性质,它不是二义的,也不含左递归。 3.语法树 句子的树结构表示法称为语法树(语法分析树或语法推导树)。 给定文法G=(V N,V T,P,S),对于G的任何句型都能构造与之关联的 语法树。这棵树具有下列特征: (1)根节点的标记是开始符号S。 (2)每个节点的标记都是V中的一个符号。 (3)若一棵子树的根节点为A,且其所有直接子孙的标记从左向右的排列 次序为A1A2…A R,那么A→A1A2…A R一定是P中的一条产生式。

编译原理试题答案

编译原理期末测试题 专业班级:_________学号:_________姓名:__________总分 一、单项选择题(共10小题,每小题2分) (题分 20分) 1.语言是 A .句子的集合 B .产生式的集合 C .符号串的集合 D .句型的集合 2.编译程序前三个阶段完成的工作是 A .词法分析、语法分析和代码优化 B .代码生成、代码优化和词法分析 C .词法分析、语法分析、语义分析和中间代码生成 D .词法分析、语法分析和代码优化 3.一个句型中称为句柄的是该句型的最左 A .非终结符号 B .短语 C .句子 D .直接短语 4.下推自动机识别的语言是 A .0型语言 B .1型语言 C .2型语言 D .3型语言 5.扫描器所完成的任务是从字符串形式的源程序中识别出一个个具有独立含义的最小语法单位即 A . 字符 B .单词 C .句子 D .句型 6.对应Chomsky 四种文法的四种语言之间的关系是 A .L 0?L 1?L 2?L 3 B .L 3?L 2?L 1?L 0 C .L 3=L 2?L 1?L 0 D .L 0?L 1?L 2=L 3 7.词法分析的任务是 A .识别单词 B .分析句子的含义 C .识别句子 D .生成目标代码 8.常用的中间代码形式不含 A .三元式 B .四元式 C .逆波兰式 D .语法树 9. 代码优化的目的是 A .节省时间 B .节省空间 C .节省时间和空间 D .把编译程序进行等价交换 装 订 线

10.代码生成阶段的主要任务是 A .把高级语言翻译成汇编语言 B .把高级语言翻译成机器语言 C .把中间代码变换成依赖具体机器的目标代码 D .把汇编语言翻译成机器语言 二、填空题(本大题共5小题,每小题2分)(题分 10分) 1.编译程序首先要识别出源程序中每个( ),然后再分析每个( )并翻译 其意义。 2.编译器常用的语法分析方法有( )和( )两种。 3.通常把编译过程分为分析前端与综合后端两大阶段。词法、语法和语义分析是对源程序的( ),中间代码生成、代码优化与目标代码的生成则是对源程序的( )。 4.程序设计语言的发展带来了日渐多变的运行时存储管理方案,主要分为两大类,即: ( )方案和( )方案。 5.对编译程序而言,输入数据是( ),输出结果是( )。 三、名词解释题(共5小题,每小题4分) (题分 20分) 1.词法分析 2.LL(1)文法 3.语法树 4.LR(0)分析器 5.语言和文法 四、简答题(共4小题,每小题5分) (题分 20分) 1.编译程序和高级语言有什么区别? 2.编译程序的工作分为那几个阶段? 3.简述自下而上的分析方法。 4.简述代码优化的目的和意义。

编译原理考试试题与答案(汇总)

《编译原理》考试试题及答案(汇总) 一、是非题(请在括号,正确的划√,错误的划×)(每个2分,共20分) 1.编译程序是对高级语言程序的解释执行。(× ) 2.一个有限状态自动机中,有且仅有一个唯一的终态。(×) 3.一个算符优先文法可能不存在算符优先函数与之对应。(√ ) 4.语法分析时必须先消除文法中的左递归。(×) 5.LR分析法在自左至右扫描输入串时就能发现错误,但不能准确地指出出错地点。(√) 6.逆波兰表示法表示表达式时无须使用括号。(√ ) 7.静态数组的存储空间可以在编译时确定。(×) 8.进行代码优化时应着重考虑循环的代码优化,这对提高目标代码的效率将起更大作用。(×) 9.两个正规集相等的必要条件是他们对应的正规式等价。(× ) 10.一个语义子程序描述了一个文法所对应的翻译工作。(×) 二、选择题(请在前括号选择最确切的一项作为答案划一个勾,多划按错论)(每个4分,共40分) 1.词法分析器的输出结果是_____。 A.( ) 单词的种别编码B.( ) 单词在符号表中的位置 C.( ) 单词的种别编码和自身值D.( ) 单词自身值 2.正规式 M 1 和 M 2 等价是指_____。 A.( ) M1和M2的状态数相等 B.( ) M1和M2的有向边条数相等C.( ) M1和M2所识别的语言集相等D.( ) M1和M2状态数和有向边条数相等

3.文法G:S→xSx|y所识别的语言是_____。 A.( ) xyx B.( ) (xyx)* C.( ) xnyxn(n≥0) D.( ) x*yx* 4.如果文法G是无二义的,则它的任何句子α_____。 A.( )最左推导和最右推导对应的语法树必定相同 B.( ) 最左推导和最右推导对应的语法树可能不同 C.( ) 最左推导和最右推导必定相同 D.( )可能存在两个不同的最左推导,但它们对应的语法树相同 5.构造编译程序应掌握______。 A.( )源程序B.( ) 目标语言 C.( ) 编译方法 D.( ) 以上三项都是 6.四元式之间的联系是通过_____实现的。 A.( ) 指示器B.( ) 临时变量 C.( ) 符号表 D.( ) 程序变量 7.表达式(┐A∨B)∧(C∨D)的逆波兰表示为_____。 A. ( ) ┐AB∨∧CD∨B.( ) A┐B∨CD∨∧ C.( ) AB∨┐CD∨∧ D.( ) A┐B∨∧CD∨ 8. 优化可生成_____的目标代码。 A.( ) 运行时间较短B.( ) 占用存储空间较小C.( ) 运行时间短但占用存空间大D.( ) 运行时间短且占用存储空间小 9.下列______优化方法不是针对循环优化进行的。 A. ( ) 强度削弱 B.( ) 删除归纳变量 C.( ) 删除多余运算 D.( ) 代码外提

编译原理第二版课后习答案

《编译原理》课后习题答案第一章 第 1 章引论 第 1 题 解释下列术语: (1)编译程序 (2)源程序 (3)目标程序 (4)编译程序的前端 (5)后端 (6)遍 答案: (1)编译程序:如果源语言为高级语言,目标语言为某台计算机上的汇编语言或机器语言,则此翻译程序称为编译程序。 (2)源程序:源语言编写的程序称为源程序。 (3)目标程序:目标语言书写的程序称为目标程序。 (4)编译程序的前端:它由这样一些阶段组成:这些阶段的工作主要依赖于源语言而与目标机无关。通常前端包括词法分析、语法分析、语义分析和中间代码生成这些阶 段,某些优化工作也可在前端做,也包括与前端每个阶段相关的出错处理工作和符 号表管理等工作。 (5)后端:指那些依赖于目标机而一般不依赖源语言,只与中间代码有关的那些阶段,即目标代码生成,以及相关出错处理和符号表操作。 (6)遍:是对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。 第 2 题 一个典型的编译程序通常由哪些部分组成?各部分的主要功能是什么?并画出编译程 序的总体结构图。 答案: 一个典型的编译程序通常包含 8 个组成部分,它们是词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、中间代码优化程序、目标代码生成程序、表格管理程序和错误处理程序。其各部分的主要功能简述如下。 词法分析程序:输人源程序,拼单词、检查单词和分析单词,输出单词的机表达形式。 语法分析程序:检查源程序中存在的形式语法错误,输出错误处理信息。 语义分析程序:进行语义检查和分析语义信息,并把分析的结果保存到各类语义信息表中。 中间代码生成程序:按照语义规则,将语法分析程序分析出的语法单位转换成一定形式 的中间语言代码,如三元式或四元式。 中间代码优化程序:为了产生高质量的目标代码,对中间代码进行等价变换处理。 目标代码生成程序:将优化后的中间代码程序转换成目标代码程序。 表格管理程序:负责建立、填写和查找等一系列表格工作。表格的作用是记录源程序的 各类信息和编译各阶段的进展情况,编译的每个阶段所需信息多数都从表格中读取,产生的中间结果都记录在相应的表格中。可以说整个编译过程就是造表、查表的工作过程。需要指出的是,这里的“表格管理程序”并不意味着它就是一个独立的表格管理模块,而是指编译程序具有的表格管理功能。 错误处理程序:处理和校正源程序中存在的词法、语法和语义错误。当编译程序发现源

编译原理试题及答案——加强版

编译原理试题及答案 <高级版> 一、对于文法 G[S] : S → 1A | 0B | ε A → 0S | 1AA B → 1S | 0BB ⑴ (3 分 ) 请写出三个关于 G[S] 的句子; ⑵ (4 分 ) 符号串 11A0S 是否为 G [S] 的句型?试证明你的结论。 ⑶ (3 分 ) 试画出 001B 关于 G [S] 的语法树。 二、请构造一个文法,使其产生这样的表达式 E :表达式中只含有双目运算符 + 、 * ,且 + 的优先级高于 * , + 采用右结合, * 采用左结合,运算对象只有标识符 i ,可以用括号改变运算符优先级。要求给出该文法的形式化描述。 三、设有语言 L={ α | α∈ {0,1} + ,且α不以 0 开头,但以 00 结尾 } 。 ⑴试写出描述 L 的正规表达式; ⑵构造识别 L 的 DFA (要求给出详细过程,并画出构造过程中的 NDFA 、 DFA 的状态转换图,以及 DFA 的形式化描述 ) 。 四、给定文法 G[S] : S → AB A → a B | bS | c B → AS | d ⑴ (6 分 ) 请给出每一个产生式右部的 First 集;

⑵ (3 分 ) 请给出每一个非终结符号的 Follow 集; ⑶ (8 分 ) 请构造该文法的 LL(1) 分析表; ⑷ (8 分 ) 什么是 LL(1) 文法?该文法是 LL(1) 文法吗?为什么? 五、给定文法 G[S] : S → SaA|a A → AbS|b ⑴请构造该文法的以 LR(0) 项目集为状态的识别规范句型活前缀的 DFA 。 ⑵请构造该文法的 LR(0) 分析表。 ⑶什么是 LR(0) 文法?该文法是 LR(0) 文法吗?为什么? ⑷什么是 SLR(1) 文法?该文法是 SLR(1) 文法吗?为什么? 六、给定下列语句: if a+b>c then x := a*(b-c) + (b*c-d)/e ⑴写出其等价的逆波兰表示; ⑵写出其等价的四元式序列。 七、已知下列 C 语言程序: int * f() { int a = 100; return &a; } main()

相关主题
文本预览
相关文档 最新文档