北京大学 编译原理 期中考试

北京大学  编译原理  期中考试
北京大学  编译原理  期中考试

2011年《编译技术》第三次小测验

(2011年6月1日)

姓名:_______________ 学号:________________

(本次小测验闭卷。时间:50分钟)

1.[45pt] 简答

a)[10pt] (类型表达式)假设类型名link和cell的定义如下(PASCAL):

TYPE link = ^cell;

cell = record

info: integer;

next: link

end;

FUNCTION foo (x:integer, y:cell) : link;

请写出foo的类型表达式。

foo的类型表达式:

integer × cell → POINTER (cell)

其中,cell的类型表达式: RECORD((info×integer)×(next×POINTER(cell))

a)[15pt] (语义检查)在C语言中,3++ 和(id+id)++这样的表达式

在编译时会报告如下的错误: invalid lvalue in increment。

现有如下简化的C语言表达式文法:

E → E +E | (E) | E++ | id | num

设计一个语法制导的翻译模式,使其能够检查 “++” 运算符的运算对象

是否合法。(如果不合法,输出上述的错误消息)。

E’→E { }

E → E1 + E2{ E.val := rvalue }

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

if

(E1.val = rvalue) then

E → E1++ {

print(“invalid lvalue in increment”)

E.val := rvalue }

E → id { E.val := lvalue }

E → num { E.val := rvalue }

b)[12pt] (参数传递方式)给定Pascal的程序:

program main(input, output);

var a,b : integer;

procedure p(x,y,z: integer);

begin

y:= y+1; z:= z+x;

end;

begin

a:= 3; b:= 4;

p(a+b, a, a);

print a;

end.

假定采用如下的过程参数传递方式,上述程序的输出结果分别是什么?

(i) 传值调用:__________3_________________

(ii) 引用调用:__________11__________________

(iii) “复制-恢复”调用:________10_________________

(iv) 换名调用:_____________12___________________

c)[8pt] (运行时存储分配)一个PASCAL程序(采用栈式存储分配,用

存取链实现对非局部名字的访问)由主程序M和过程P、Q、R、S、T 构成,它们之间的全部包含关系是:M直接包含P和Q;P直接包含R 和S;Q直接包含T。这里用X→Y表示X调用Y。

当调用为M→P→P→R→Q→T→S时,画出此时栈中活动记录示意图。

活动记录只需给出控制链、存取链及相应的过程名字。

2.[30pt] (翻译模式)【注意:只允许使用继承和综合属性,不许使用全局变量】

设有文法:

S → (L) | a

L →L, S | S

a)设计一个适合自底向上分析的语法制导翻译模式,输出括号的对数。例

如,对于句子 (a, (a, a)),输出的结果是 2 (共包含两对括号)。【提示:添加S’ →S对文法进行拓广。】

S’ →S { print (S.count) }

S →(L) { S.count := L.count + 1}

S → a { S.count := 0 }

L →L1, S { L.count := L1.count + S.count }

L →S { L.count := S.count }

b)设计一个适合自顶向下分析的语法制导翻译模式,输出每个a的嵌套深

度。例如,对于句子 (a, (a,a)),输出的结果是 1 2 2。【提示:添加S’ →S

对文法进行拓广。】

S’ →{ S.depth := 0 } S

S →( { L.depth := S.depth +1 } L )

S → a { print(S.depth) }

L → { S.depth :=L.depth } S, { L1.depth := L.depth } L1

L →{ S.depth := L.depth } S

3.[25pt] 中间代码生成

设有说明(假设real占8个字节,integer占4个字节。):

var a: array[‐10..1, ‐1..10] of real;

rv: record i:integer

rec: record j:integer; k:integer end;

end;

x, y, z : integer;

给出下列语句的中间代码和相应的S.nextlist。

switch (x) {

case 10: if (y

case 20: while(y

default: x:=0

}

(1)goto (24)

(2)if y

(3)goto ( )

(4)t1:= x+5

(5)t2:= ‐2*12

(6)t2:= t2+t1

(7)t3:= a+968

(8)t4:= 8*t2

(9)t5:= rv+8 (10)t6:= *t5

(11)t7:= t6+1

(12)t8:= inttoreal t7

(13)t3[t4]:=t8

(14)goto ( )

(15)if y

(16)goto (20 )

(17)t9:= y+1

(18)y:= t9

(19)goto (15)

(20)z:= 1

(21)goto ( )

(22)x:= 0

(23)goto ( )

(24)if (x=10) goto (2)

(25)if (x=20) goto (15)

(26)goto (22)

S.nextlist = {3, 14, 21, 23}

相关文档
最新文档