7.4 布尔表达式和控制流语句 布尔表达式有两个基本目的 计算逻辑值 c = (a > b) && a > 1 在控制流语句中用作条件表达式 if (a > b && a > 1) then … 1/25
7.4 布尔表达式和控制流语句 布尔表达式有两种计算方式: if ( 1 or i++ > 3) then 布尔表达式的完全计算 E1 or E2 布尔表达式的“短路”计算 E1 or E2 定义成 if E1 then true else E2 E1 and E2 定义成 if E1 then E2 else false
7.4 布尔表达式和控制流语句 7.4.1 布尔表达式的翻译 E E or E | E and E | not E | ( E ) | id relop id | true | false a < b的翻译 100: if a < b goto 103 101: t := 0 102: goto 104 103: t := 1 104: >, >=, <, <=, <>, == 对于a<b的翻译而言,由于三地址代码中不包括形如t=a<b的格式,故此使用if x relop y goto L 来实现。
7.4 布尔表达式和控制流语句 E E1 or E2 {E.place := newtemp; emit (E.place, ‘:=’, E1.place, ‘or’ E2.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’ ) } a < b的翻译 100: if a < b goto 103 101: t := 0 102: goto 104 103: t := 1 104:
7.4 布尔表达式和控制流语句 7.4.2 控制流语句的翻译 S if E then S1 | if E then S1 else S2 | while E do S1 | S1; S2 5/25
7.4 布尔表达式和控制流语句 指向E.true 指向E.true E.code 指向E.false E.code 指向E.false S1.code S1.code . . . S1.next: goto S.next (S1.next) E.false: S2.code E s1 (a) if--then . . . E s1 s2 (b) if-then-else E.code S1.code E.true: . . . 指向E.true 指向E.false goto S.begin S.begin: (c) while-do S1.code S2.code S1.next: . . . (d) S1; S2 E s1
7.4 布尔表达式和控制流语句 S if E then S1 {E.true := newlabel; E.code S1.code E.true: . . . 指向E.true 指向E.false (a) if-then S if E then S1 {E.true := newlabel; E.false := S.next; S1.next := S.next; S.code := E.code || gen(E.true, ‘:’) || S1.code }
7.4 布尔表达式和控制流语句 S if E then S1 else S2 {E.true := newlabel; E.code S1.code E.true: . . . 指向E.true 指向E.false E.false: goto S.next S2.code (b) if-then-else S if E then S1 else S2 {E.true := newlabel; E.false := newlabel; S1.next := S.next; S2.next := S.next; S.code := E.code || gen(E.true, ‘:’) || S1.code || gen(‘goto’, S.next) || gen(E.false, ‘:’) || S2.code}
7.4 布尔表达式和控制流语句 S while E do S1 {S.begin:= newlabel; E.true := newlabel; E.false := S.next; S1.next := S.begin; S.code := gen(S.begin, ‘:’) || E.code || gen(E.true, ‘:’) || S1.code || gen(‘goto’, S.begin) } E.code S1.code E.true: . . . 指向E.true 指向E.false goto S.begin S.begin: (c) while-do
7.4 布尔表达式和控制流语句 S S1; S2 {S.code := S1.code || gen(S1.next, ‘:’) || S2.code } S1.code S2.code S1.next: . . . (d) S1; S2 10/25
7.4 布尔表达式和控制流语句 7.4.3 布尔表达式的控制流翻译 如果E是a < b的形式, 那么代码是: if a < b goto E.true goto E.false
7.4 布尔表达式和控制流语句 表达式 a < b or c < d and e < f 的代码是: if a < b goto Ltrue goto L1 L1: if c < d goto L2 goto Lfalse L2: if e < f goto Ltrue
7.4 布尔表达式和控制流语句 E E1 and E2 {E1.true := newlabel; E1.code 指向E1.false E1.true: E E1 and E2 {E1.true := newlabel; E1.false := E.false; E2.true := E.true; E2.false := E.false; E.code := E1.code || gen(E1.true, ‘:’) || E2.code } E2.code . . . E1 and E2
7.4 布尔表达式和控制流语句 E E1 and E2 {E1.true := newlabel; E1.false := E.false; E2.true := E.true; E2.false := E.false; E.code := E1.code || gen(E1.true, ‘:’) || E2.code } E (E1 ) {E1.true := E.true; E.code := E1.code }
7.4 布尔表达式和控制流语句 E E1 or E2 {E1.true := E.true; E1.false := newlabel; E2.false := E.false; E.code := E1.code || gen(E1.false, ‘:’) || E2.code } 15/25
7.4 布尔表达式和控制流语句 E E1 or E2 {E1.true := E.true; E1.false := newlabel; E2.false := E.false; E.code := E1.code || gen(E1.false, ‘:’) || E2.code } E not E1 {E1.true := E.false; E1.false := E.true; E.code := E1.code }
7.4 布尔表达式和控制流语句 E id1 relop id2 如果E是a < b的形式, 那么代码是: if a < b goto E.true goto E.false E id1 relop id2 {E.code := gen(‘if’, id1.place, relop.op, id2.place, ‘goto’, E.true) || gen(‘goto’, E.false) } E true {E.code := gen(‘goto’, E.true)} E false {E.code := gen(‘goto’, E.false)}
7.4 布尔表达式和控制流语句 7.4.4 开关语句的翻译 switch E begin case V1: S1 case V2: S2 . . . case Vn - 1: Sn – 1 default: Sn end
7.4 布尔表达式和控制流语句 分支数较少时 t := E的代码 if t V1 goto L1 S1的代码 goto next L1: if t V2 goto L2 S2的代码 L2: . . . . . . Ln-2: if t Vn-1 goto Ln-1 Sn -1的代码 | goto next Ln-1: Sn的代码 next:
7.4 布尔表达式和控制流语句 分支较多时,将分支测试的代码集中在一起, 便于生成较好的分支测试代码。 t := E的代码 | Ln: Sn的代码 goto test | goto next L1: S1的代码 |test: if t = V1 goto L1 goto next | if t = V2 goto L2 L2: S2的代码 | . . . goto next | if t = Vn-1 goto Ln-1 . . . | goto Ln Ln-1: Sn -1的代码 | next: goto next 20/25
7.4 布尔表达式和控制流语句 中间代码增加一种case语句,便于代码生成器 对它进行特别处理 test: case V1 L1 . . . case Vn-1 Ln-1 case t Ln next:
7.4 布尔表达式和控制流语句 7.4.5 过程调用的翻译 S call id (Elist) Elist Elist, E
7.4 布尔表达式和控制流语句 过程调用id(E1, E2, …, En)的中间代码结构 E1.place := E1的代码 . . . En.place := En的代码 param E1.place param E2.place param En.place call id.place, n
7.4 布尔表达式和控制流语句 S call id (Elist) {为长度为n的队列中的每个E.place, emit(‘param’, E.place); emit(‘call’, id.plase, n) } Elist Elist, E {把E.place放入队列末尾} Elist E {将队列初始化,并让它仅含E.place} E1.place | E2.place | E3.place | E4.place …..
本 章 要 点 中间代码的几种形式,它们之间的相互转换 符号表的组织和作用域信息的保存 布尔表达式的两种不同实现方式 本 章 要 点 中间代码的几种形式,它们之间的相互转换 符号表的组织和作用域信息的保存 布尔表达式的两种不同实现方式 赋值语句和各种控制流语句的中间代码格式和生成中间代码的翻译方案 过程调用的中间代码格式和生成中间代码的翻译方案 25/25