《编译原理-龙书》练习第6章

本文详细介绍了《编译原理》第六章的内容,涵盖语法树的变体,包括DAG的构造;三地址代码的表示形式;类型和声明的处理,如类型检查和计算相对地址;表达式的翻译方法;控制流的实现,如while、for循环和条件语句的转换;以及switch语句的编译处理。

f

6.1 语法树的变体

6.1.1 xy+-*/的表达式在纸上构造DAG是比较容易的,如果用LL或LR文法构造,则如第4章,需要先建表,然后分析。

6.1.2 类似6.1.1

6.2 三地址代码

6.2.1 a + -(b+c)

三地址代码

t1 = b + c

t2 = minus t1

t3 = a + b2

四元式

oparg1arg2result
+bct1
minust1 t2
+at2t3

三元式

oparg1arg2
+bc
minus(0) 
+a(1)

间接三元式

35(0)  0+bc
36(1)  1minus(0) 
37(2)  2+a(1)
     oparg1arg2

6.2.3

6.3 类型和声明

6.3.1 计算相对地址参考图6-17

float x; 类型float,偏移0

record { float x; float y; } p;

x 类型float,偏移0;y类型float,偏移4;p类型record,偏移0


6.4 表达式的翻译

6.4.1

E -> E1*E2E.addr=new Temp()
E.code = E1.code E2.code gen(E.adr '=' E1.addr '+' E2.addr
E -> +E2E.addr = E1.addr
E.code = E2.code

6.4.2

E -> E1*E2E.addr = new Temp()
gen(E.addr '=' E1.addr '+' E2.addr)
E -> +E2E.addr = E1.addr

6.4.3 类似例6.12,略

6.4.4-6.4.9 按列存储跟行差距不大,略去;计算位置很容易,略去

6.5 类型检查

6.5.1 仿照图6-27即可

x(float) = s(short) + c(char)

t.type = max(short, char) = float
a1 = widen(s.addr, short, float);

a2 = widen(c.addr, char, float);

x.addr = new Temp()

gen(x.addr '=' a1 '+' a2)

6.5.2


6.6 控制流

6.6.1 

1) repeat S while B                S -> do S1 while B

B.true = newlabel();

B.false = S.next

S1.next = newlabel();

S.code = label(B.true) S.code label(S1.next) B.code

2) for(S1; B; S2) S3                S -> for(S1; B; S2) S3

相当于  S1 while(B) S3;S2

begin = newlabel()

B.true = newlabel

B.false = S.next

S.code = S1.code label(begin) B.code label(B.true) S2.code S3.code gen('goto' begin)

6.6.2 if(B) { repeat S until !(B) } S -> if(B1) { repeat S1 while(B2) }

start = B1.true = B2.true = newlabel()

B1.false = B2.false = S.next

S1.next = newlabel();

S.code = B1.code label(start) S1.code label(S1.next) B2.code

6.6.3 B -> B1 ^ B2

B.code = B1.code B2.code  gen('if' B1 '==' B2 'goto' B.false) gen('goto' B.true)

6.6.4 1) if (a==b && c==d || e==f) x==1;

       iffalse a==b goto L3

       if c==d goto L2

L3: iffalse e==f goto L1

L2: x==1;

L1: 

6.6.5 不会

6.6.6 这道题的意思不知道是不是避免冗余的共同,如果是,对于B->B1&&B2有

B1.true = fall

B1.false = if B.false!=fall then B.false else newlabel()

B2.true = B.true

B2.false = B.false

B.code = if B.false!=fall then B1.code B2.code

else B1.code B2.code label(B1.false)

6.6.7 


6.7 回填

6.7.1 1) a==b && (c==d || e==f)

100: if(a==b) goto _102

101: goto _false

102: if(c==d) goto _true

103: goto 104

104: if(e==f) goto _true

105: goto _false

6.7.2 

E3.false = E4

S2.next = S3

E4.false = S3

S1.next = E3

E2.true = E3

6.7.3

S4.next = E1

S5.next = S3

S6.next = E1

S7.next = E1

S8.next = S.next

6.8 switch语句

6.8.1

switch ( E ) {

case V1: S1      gen S1.code         addPair(V1, L1)

case V2: S2      gen S2.code         addPair(V2, L2)

...

case Vn-1: Sn-1      gen Sn-1.code         addPair(Vn-1, Ln-1)

default: Sn gen Sn.code default Ln


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值