第七章 中间代码生成

本章内容
– 介绍几种常用的中间表示:后缀表示、
图形表示和三地址代码
– 用语法制导定义和翻译方案的方法来说
明程序设计语言的结构怎样被翻译成中
间形式



分析

静态
检查

中间

代码

生成


代码
生成

7.1 中 间 语 言
7.1.1 后缀表示
表达式 E 的后缀表示可以如下递归定义
• 如果 E 是变量或常数,那么 E 的后 缀 表
示就是 E 本身。

7.1 中 间 语 言
7.1.1 后缀表示
表达式 E 的后缀表示可以如下递归定义
• 如果 E 是变量或常数,那么 E 的后 缀 表
示就是 E 本身。
• 如果 E 是形式为 E1 opE2 的表达式,那么 E
的后 缀 表示是 E1′ E2′ op ,其中 E1′ 和
E2′ 分 别 是 E1 和 E2 的后 缀 表示。

7.1 中 间 语 言
7.1.1 后缀表示
表达式 E 的后缀表示可以如下递归定义
• 如果 E 是变量或常数,那么 E 的后 缀 表
示就是 E 本身。
• 如果 E 是形式为 E1 opE2 的表达式,那么 E
的后 缀 表示是 E1′ E2′ op ,其中 E1′ 和
E2′ 分 别 是 E1 和 E2 的后 缀 表示。
• 如果 E 是形式为 (E1) 的表达式,那么 E1
的后 缀 表示也是 E 的后 缀 表示 。

7.1 中 间 语 言 • 后缀表示不需要括号 (8 − 4) + 2 的后 缀 表示是 8 4 −2 + .

1 中 间 语 言 • 后缀表示不需要括号 (8 − 4) + 2 的后 缀 表示是 8 4 −2 + • 后缀表示的最大优点是便于计算机处理 表达式 .7.

1 中 间 语 言 • 后缀表示不需要括号 (8 − 4) + 2 的后 缀 表示是 8 4 −2 + • 后缀表示的最大优点是便于计算机处理 表达式 • 后缀表示很容易拓广到含一元算符的表 达式 .7.

7.1 中 间 语 言
• 后缀表示不需要括号
(8 − 4) + 2 的后 缀 表示是 8 4 −2 +
• 后缀表示的最大优点是便于计算机处理
表达式
• 后缀表示很容易拓广到含一元算符的表
达式
• 后缀表示也可以拓广到表示赋值语句和
控制语句,但很语用语来描述它的语算

7.1 中 间 语 言
7.1.2 图形表示
• 语法树是一种图形化的中间表示
assign
a

+

+


c
uminus
d
c
d
b
(a) 语法树
a := (−b + c∗d ) + c∗d 的图形表

7.1 中 间 语 言
7.1.2 图形表示
• 语法树是一种图形化的中间表示
• 有向无环图 也是一种中间表示
assign

a

assign

+

a

+

+
+



c
uminus
d
uminus
c
c
d
d
b
b
(b) dag
(a) 语法树
a := (−b + c∗d ) + c∗d 的图形表

7.1 中 间 语 言
构造赋值语句语法树的语法制导定义
产 生 式
语 义 规 则
S → id :=E S.nptr := mknode(‘assign’, mkleaf (id,
id.entry), E.nptr)
E → E1 +E2 E.nptr := mknode( ‘+’, E1.nptr, E2.nptr)
E → E1 ∗E2 E.nptr := mknode( ‘∗’, E1.nptr, E2.nptr)
E → −E1

E.nptr := mkunode( ‘uminus’, E1.nptr)

E → (E1)

E.nptr := E1.nptr

F → id

E.nptr := mkleaf (id, id.entry)

3 三地址代码 一般形式: x := y op z 表达式 x + y ∗ z 翻译成的三地址语句序列是 t1 := y ∗ z t2 := x + t1 .1 中 间 语 言 7.1.7.

1 中 间 语 言 三地址代码是语法树或 dag 的一 种线 性表 示 a := (−b + c∗d ) + c∗d 语法树的代码 dag 的代码 t1 := −b t1 := −b t2 := c ∗ d t2 := c ∗ d t3 := t1 + t2 t3 := t1 + t2 t4 := c ∗ d t4 := t3 + t2 t5 := t3 + t4 a := t4 .7.

n • 过程返回 return y • 索引赋值 x := y[i] 和 x[i] := y • 地址和指针赋值 x := &y , x := ∗y 和 x := y .1 中 间 语 言 本 书 常用的三地址 语 句 • 赋值语句 x := y op z , x := op y , x := y • 无条件转移 goto L • 条件转移 if x relop y goto L • 过程调用 param x 和 call p .7.

7.2 声 明 语 句 • 为局部名字建立符号表条目 • 为它分配存储单元 • 符号表中包含名字的类型和分配给它的 存储单元的相对地址等信息 .

2.2 声 明 语 句 7.7.1 过程中的声明 .

width := num.type := real.width} T→ ↑T1 {T. T.width := 4 } T→ real {T. D D → id : T {enter ( id.2 声 明 语 句 计算被声明名字的类型和相对地址 P → {offset := 0} D S D →D .type.7.width := 8 } T→ array [ num ] of T1 {T.name. T.type := pointer (T1.type).type := array (num. T1. T.type).width } T → integer {T.val.width := 4 } . T.type := integer.val × T1. T. offset). offset := offset + T.

7.2 声 明 语 句 7. D . type. name.2. width) enterproc(table. name.2 作用域信息的保存 • 所讨论语言的文法 P →D S D → D . D | id : T | proc id . offset) addwidth(table. newtable) . S • 语义动作用到的函数 mktable(previous) enter(table.

id. S {t := top(tblptr).7. tblptr).width } N →ε {t := mktable(top(tblptr) ).type.name. offset) } D → D1 . t) } D→id : T {enter(top(tblptr). enterproc(top(tblptr). offset) } . T. pop(offset).name. pop (offset) } M →ε {t := mktable (nil). addwidth(t. pop(tblptr). push(t. pop(tblptr). id. D2 D → proc id . top(offset) := top(offset) + T. N D1. push(0. top(offset) ).2 声 明 语 句 P → M D S {addwidth (top (tblptr). tblprt). top(offset)). push (0. top (offset) ). push(t.

7.2 声 明 语 句 空 sort 表 头 a x readarray exchange quicksort i readarrary 表 头 exchange 表 头 指向 readarray 指向 exchange quicksort 表 头 k v partition partition .

pop(tblptr).2. pop(offset) } L →ε {t := mktable (nil). tblprt).type := record (top(tblptr) ).7.width := top(offset). push(0.3 记录的域名 T → record D end T → record L D end {T. push(t.2 声 明 语 句 7. T. offset) } .

emit (E.place.place := newtemp.1 符号表的中名字 S → id := E {p := lookup(id. E. E1.place) } . ‘+’. E2.name).place) else error } E → E1 + E2 {E. ‘:=’.3 赋 值 语 句 7. ‘:=’.7.3. if p ≠ nil then emit ( p.place.

‘:=’.1 符号表的中名字 E → −E1 {E. E1.3 赋 值 语 句 7. emit (E.7.place := E1.place := newtemp.place.name).place) } E → (E1) {E.3. ‘uminus’. if p ≠ nil then E.place := p else error } .place } E → id {p := lookup(id.

7.3 赋 值 语 句 7.3.2 临时名字的重新使用 • 大量临时变量的使用对优化有利 • 大量临时变量会增加符号表管理的负担 • 也会增加运行时临时数据占的空间 .

3.7.3 赋 值 语 句 7.2 临时名字的重新使用 • 大量临时变量的使用对优化有利 • 大量临时变量会增加符号表管理的负担 • 也会增加运行时临时数据占的空间 E → E1 + E2 的 动 作 产 生的代 码 的一般形式 为 语 算 E1 到 t1 语 算 E 2 到 t2 t3 := t1 + t2 (( ))((()())()) .

3 赋 值 语 句 基于临时变量生成期特征的三地址代码 x := a ∗ b + c ∗ d − e ∗ f 语 句 $0 := a ∗ b $1 := c ∗ d $0 := $0 + $1 $1 := e ∗ f $0 := $0 − $1 x := $0 c 的值 0 1 2 1 2 1 0 .7.

7.3.3 赋 值 语 句 7.3 数组元素的地址计算 一维数组 A 的第 i 个 元 素 的 地 址 语 算 base + ( i − low ) × w .

3 赋 值 语 句 7.3.3 数组元素的地址计算 一维数组 A 的第 i 个元素的地址计算 base + ( i − low ) × w 重写成 i × w + (base − low × w) 减少了运行语的语算 .7.

3] . 1]. A[2. 2]. A[1. 1]. A[2. 2]. 3].3 赋 值 语 句 二维数组 • 列为主 A[1. A[2. A[1.7.

A[2. A[1. 2]. 3]. A[1. 2]. 3]. 1]. A[2. 2]. A[1. 1]. 1]. 1]. 3] . 3] • 行为主 A[1.3 赋 值 语 句 二维数组 • 列为主 A[1. A[2. A[1. A[2. 2]. A[2. A[2.7.

A[2. 3] base + ( (i1 − low1) × n2 + (i2 − low2 ) ) × w (其中 n2 = high2 − low2 + 1 ) . A[1. 3]. 2]. A[2. 2]. 3]. 1]. A[2. A[2. A[2. 2].3 赋 值 语 句 二维数组 • 列为主 A[1. 1].7. 1]. A[1. 3] • 行为主 A[1. 1]. 2]. A[1. A[1. A[2.

3]. 3]. A[1. 1]. 2]. A[2.7. 2].3 赋 值 语 句 二维数组 • 列为主 A[1. 3] base + ( (i1 − low1) × n2 + (i2 − low2 ) ) × w (其中 n2 = high2 − low2 + 1 ) ( (i1 × n2 ) + i2 ) × w + . 2]. A[2. 1]. A[2. 1]. A[1. A[2. A[1. A[2. 3] • 行为主 A[1. 2]. 1]. A[1. A[2.

. i2.7. . ik ] 的地址表达式 ( (… ( (i1 × n2 + i2 ) × n3 + i3 ) … ) × nk + ik) × w + base − ( ( … ( (low1 × n2 + low2) × n3 + low3) … ) × nk + lowk ) × w ...3 赋 值 语 句 多维数组 A[i1.

3.7. E | E 改成 L → Elist ] | id Elist → Elist. E | id [E .3 赋 值 语 句 7.4 数组元素地址计算的翻译方案 下标变量访问的产生式 L → id [ Elist ] | id Elist → Elist.

3 赋 值 语 句 所有产生式 S → L := E E →E + E E → (E ) E →L L → Elist ] L → id Elist → Elist. E Elist → id [ E .7.

3 赋 值 语 句 L → id {L.offset := null } .7.place. L.place := id.

place := id.7.3 赋 值 语 句 L → id {L.place := E. Elist.offset := null } Elist → id [ E {Elist. L.place.ndim := 1. Elist.place.array := id.place } .

emit (t.place } Elist → Elist1. m) ). Elist.array := id.place.array := Elist1. ‘+’. emit (t. Elist.7.offset := null } Elist → id [ E {Elist. Elist.array. ‘:=’.3 赋 值 语 句 L → id {L.ndim + 1.ndim := 1.place := E. Elist. Elist.array.ndim := m} .place := t. ‘∗’.place. t. ‘:=’. Elist1.place := id. L. limit(Elist1.place. E { t := newtemp. E. m := Elist1.place).

array) ).place := t.place } Elist → Elist1.ndim := m} L → Elist ] { L.ndim + 1.offset := null } Elist → id [ E {Elist. Elist1. Elist.place. E. L. Elist. ‘:=’.array. m) ). ‘+’. ‘:=’. invariant (Elist.place.place := newtemp.array).place).place.offset. ‘∗’.offset := newtemp.place := E. w) } .3 赋 值 语 句 L → id {L.ndim := 1. Elist. L. ‘:=’.place := id.7. Elist. emit (L. m := Elist1.array := Elist1. base(Elist. ‘∗’.array. Elist. limit(Elist1. emit (t.place. ‘−’. E { t := newtemp. emit (L.place. t. Elist.array := id. ‘:=’. emit (t.

L.7.offset.place := newtemp.place else begin E.3 赋 值 语 句 E → L{if L.place.place.offset = null then /∗ L 是简单变量  / E. emit (E. ‘:=’.place := L. ‘[’. L. ‘]’) end } .

place. ‘[’. ‘:=’. E1.place) } . L.place := newtemp. emit (E.place := L. ‘]’) end } E → E1 + E2{E. emit (E. E2.offset.place. L. ‘:=’.offset = null then /∗ L 是简单变量  / E.3 赋 值 语 句 E → L{if L. ‘+’.place .place else begin E.place := newtemp.place.7.

place } .place . E2.place.place else begin E. ‘:=’. ‘[’.place.3 赋 值 语 句 E → L{if L. L.offset = null then /∗ L 是简单变量  / E.place := E1.7. E1. ‘:=’. L. emit (E.offset.place := L. emit (E.place := newtemp.place. ‘]’) end } E → E1 + E2{E. ‘+’.place := newtemp.place) } E → (E1 ){E.

7. ‘+’.offset = null then /∗ L 是简单变量  / emit (L. L.place := L. ‘:=’.place .place } S → L := E {if L. E.place := E1. ‘]’.offset.place . E.3 赋 值 语 句 E → L{if L. ‘[’.place. ‘:=’. ‘]’) end } E → E1 + E2{E. E2. emit (E.offset = null then /∗ L 是简单变量  / E. L. ‘[’.place) } .place. L. E1. emit (E.place) } E → (E1 ){E.place := newtemp. ‘:= ’.place.place else begin E.place := newtemp. ‘:=’.place) else emit (L.place.offset.

place := x L.place := y L.offset := null z y x := A[ y.place := t1 Elist.place := y .place := t2 L.ndim := 1 Elist.offset := null E.place := t4 L.place := y L.offset := t3 ] E.array := A Elist.place := z L.place := z L.array := A A [ E.ndim := 2 Elist.7.3 赋 值 语 句 S L. Elist.offset := null := x Elist. z ] 的注释分析树 .

offset := null := x t1 := y × 20 Elist.7.ndim := 2 Elist.offset := null z y x := A[ y.place := x L.3 赋 值 语 句 S L. z ] 的注释分析树 .place := y L.place := y L.array := A A [ E.offset := null E.place := z L.place := t2 L.offset := t3 ] E.place := z L.place := y .array := A Elist. Elist.ndim := 1 Elist.place := t1 t1 := t1 + z Elist.place := t4 L.

place := x L.offset := null [ E.place := y z L.ndim := 2 Elist.array := A Elist.3 赋 值 语 句 S L.place := t4 t2 :=A − 84 L. Elist.offset := null A E.array := A L.offset := t3 x t1 := y × 20 Elist.place := z Elist. z ] 的注释分析树 ] .place := t1 t1 := t1 + z Elist.place := t2 t3 := 4 × t1 L.7.ndim := 1 L.place := y E.place := y L.offset := null := y x := A[ y.place := z .

array := A L.offset := null [ E.place := y E.place := z Elist.place := y L. Elist. z ] 的注释分析树 ] .place := t2 t3 := 4 × t1 L.offset := null y x := A[ y.7.offset := null A := t4 := t2 [t3 ] E.3 赋 值 语 句 S L.ndim := 1 L.place := t4 t2 :=A − 84 L.place := y z L.place := t1 t1 := t1 + z Elist.offset := t3 x t1 := y × 20 Elist.ndim := 2 Elist.place := z .place := x L.array := A Elist.

place := t2 t3 := 4 × t1 L.place := t4 t2 :=A − 84 L.place := z Elist.offset := null A := t4 := t2 [t3 ] E.place := y L.ndim := 2 Elist.3 赋 值 语 句 x := t4 S L.place := t1 t1 := t1 + z Elist.place := x L.place := y E.7.ndim := 1 L.array := A L. z ] 的注释分析树 ] .place := z .offset := t3 x t1 := y × 20 Elist.offset := null y x := A[ y.array := A Elist.place := y z L. Elist.offset := null [ E.

3.5 类型转换 x := y + i ∗ j ( x 和 y 的 类 型是 real , i 和 j 的 类 型是 integer ) 中间代码 t1 := i int× j t2 := inttoreal t1 t3 := y real+ t2 x := t .3 赋 值 语 句 7.7.

E.place.7.type = integer then begin emit (E.type = integer end else if E1. emit (E.place := newtemp if E1.place).place).type := real end . E2. ‘int+’. u. ‘:=’. E1. ‘inttoreal’. E2. E1.type = integer and E2.place.3 赋 值 语 句 E → E1 + E2 E. ‘:=’. ‘:=’. emit (u. E. ‘real+’.place).place.type = integer and E2.type = real then begin u := newtemp.

7.4 布尔表达式和控制流语 句 布语表达式有两个基本目的 • 计 算 逻辑值 • 在控制流语句中用作条件表达式 .

4 布尔表达式和控制流语 句 布尔表达式有两个基本目的 • 计 算 逻辑值 • 在控制流语句中用作条件表达式 布尔表达式的完全计算 布尔表达式的 “短路 ”计算 E1 or E2 定义成 if E1 then true else E2 E1 and E2 定义成 if E1 then E2 else false .7.

4.7.4 布尔表达式和控制流语 句 7.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: .

place := newtemp. E1.place := newtemp. nextstat + 2 ). nextstat+3 ). id2. ‘0’ ). relop.place.place.7. ‘:=’.4 布尔表达式和控制流语 句 E → E1 or E2 {E.place. . ‘:=’.op. emit (‘if’.place. emit (E.place) } E → id1 relop id2 {E.place. emit (E. ‘goto’. emit (‘goto’. id1. ‘or’ E2.

2 控制流语句的翻译 S → if E then S1 | if E then S1 else S2 | while E do S1 | S1.7. S2 .4.4 布尔表达式和控制流语 句 7.

.true: E.code S1.false (a) if-then S. ..code .next E.code S2..true: E.trueE. (c) while-do E....begin .code S1.false .code goto S.false 指向 S1.true: E. S2 指向 E.code 指向 E.false: S2.code .7.code .true 指向 E. (d) S1.code goto S..true 指向 E. (b) if-then-else S1. 指向 E.4 布尔表达式和控制流语 句 E.begin: E.next: S1.

true: E.true := newlabel. ‘:’) || S1.7. {E.code S → if E then S1 .next := S. S.next.4 布尔表达式和控制流语 句 E.true 指向 E.code } .code 指向 E.code := E.false := S.false S1.. (a) if-then S1.next. E..true.code || gen(E.

next. (b) if-then-else S2.7.code S → if E then S1 else S2 goto S.next {E. . S. E. S1..next := S..code E.false.code || gen(E.true 指向 E.true. S.code := E.code || gen(‘goto’. ‘:’) || S1.next := S. ‘:’) || .false: S2.false S1.true: E.code 指向 E.4 布尔表达式和控制流语 句 E.next) || gen(E.true := newlabel.false := newlabel.next.

code 指向 E.begin. S1. S. ‘:’) || S1.code || gen(E..next.true := newlabel..7.begin:= newlabel.next := S.true: S1.true.begin) } .false := S.false 指向 S → while E do S1 E.code || gen(‘goto’.code {S.code := gen(S. goto S.4 布尔表达式和控制流语 句 S. E.begin: E. ‘:’) || E.trueE. S.begin .begin. (c) while-do E.

S2 {S1.next := newlabel. ‘:’) || S2.next..code || gen(S1.next: S1.code := S1.code S2.. S2. S. S2 .code .7.code } S1.next := S.4 布尔表达式和控制流语 句 S → S1. (d) S1.next.

4 布尔表达式和控制流语 句 7.false .4.3 布尔表达式的控制流翻译 如果 E 是 a < b 的形式, 那么代码是: if a < b goto E.7.true goto E.

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 goto Lfalse .7.

false.false := newlabel.7. ‘:’) || E2. E2. E.true.code } .4 布尔表达式和控制流语 句 E → E1 or E2 {E1.false := E.true := E. E2.false.true := E.code := E1. E1.code || gen(E1.true.

true := E.false. E1.false := newlabel.code } E → not E1 {E1.true := E.false. ‘:’) || E2. E.true.7.true.false := E.code := E1. E2. .4 布尔表达式和控制流语 句 E → E1 or E2 {E1.true := E. E1.true.code || gen(E1. E2.false.false := E.

false := E.false.true.7.false.code := E1.true := E.true. E2.4 布尔表达式和控制流语 句 E → E1 and E2 {E1. E1. E2. E.false := E.true := newlabel.code } .code || gen(E1. ‘:’) || E2.

true.true.false := E.false := E.false.false.code } E → (E1 ) {E1.false := E.7.true := E. E1. E2. E1.false.true := E. .code || gen(E1.true.true := newlabel.code := E1. E2. ‘:’) || E2. E.4 布尔表达式和控制流语 句 E → E1 and E2 {E1.

false) } .place. E. relop.place. id2. id1.op.7. E.true) || gen(‘goto’.code := gen(‘if’. ‘goto’.4 布尔表达式和控制流语 句 E → id1 relop id2 {E.

E. id2. E. id1. E.true) || gen(‘goto’.code := gen(‘goto’. E.code := gen(‘if’.place. ‘goto’.false)} .place.7.op.true)} E → false {E.false) } E → true {E. relop.code := gen(‘goto’.4 布尔表达式和控制流语 句 E → id1 relop id2 {E.

4 布尔表达式和控制流语 句 7.7.1: Sn – 1 default: Sn end . case Vn ..4 开关语句的翻译 switch E begin case V1: S1 case V2: S2 ..4.

4 布尔表达式和控制流语 句 分支数 较 少 时 t := E 的代码 1 | Ln-2: if t ≠ Vn-1 goto Ln- if t ≠ V1 goto L1 | Sn -1 的代码 S1 的代码 | goto next goto next | Ln-1: Sn 的代码 L1: if t ≠ V2 goto L2 | next: S2 的代码 goto 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 的代码 | ...7... | goto L . goto next | if t = Vn-1 goto Ln-1 .

7..4 布尔表达式和控制流语 句 中间代码增加一种 case 语句,便于代码生 成器 对 它 进 行特 别处 理 test: case V1 case V2 . case Vn-1 case t L1 L2 Ln-1 Ln ..

5 过程调用的翻译 S → call id (Elist) Elist → Elist.4 布尔表达式和控制流语 句 7.7. E Elist → E .4.

place := E2 的代码 .place := En 的代码 param E1. En) 的中 间 代 码结 构 E1... E2.. En.7..place := E1 的代码 E2. param En.place param E2.4 布尔表达式和控制流语 句 过程调用 id(E1.place . ….place .

plase.place , emit(‘param’. E. n) } Elist → Elist. E { 把 E.place} .4 布尔表达式和控制流语 句 S → call id (Elist) { 为长度为 n 的 队 列中的 每 个 E.place 放入队列末尾 } Elist → E { 将队列初始化,并让它仅含 E. id.place).7. emit(‘call’.

本 章 要 点 • 中间代码的几种形式,它们之间的相互 转换 • 符号表的组织和作用域信息的保存 • 数组元素定址的翻译方案,布尔表达式 的两 种 不同 实现 方式 • 赋值语句和各种控制流语句的中间代码 格式和生成中间代码的翻译方案 • 过程调用的中间代码格式和生成中间代 码的翻译方案 .

stmt end end . if t1<= t2 then begin v := t1. t2 := final.例 题 1 Pascal 语言的标准将 for 语句 for v := initial to final do stmt 定义成和下面的代码序列有同样的含义: begin t1 := initial. stmt. while v <> t2 do begin v := succ(v).

t2 := final. v := succ(v) end end . v := t1. while v <= t2 do begin stmt.例 题 1 Pascal 语言的标准将 for 语句 for v := initial to final do stmt 能否定义成和下面的代码序列有同样的含 义? begin t1 := initial.

例 题 1 Pascal 语言 for 语句 for v := initial to final do stmt 的中 间 代 码结 构如下 : t1 := initial t2 := final if t1 > t2 goto L1 v := t1 L2: stmt if v = t2 goto L1 v := v + 1 goto L2 .

例 题 2 C 语言的 for 语句有下列形式 for (e1. e3. end .e3) stmt 它和 e1.e2. while (e2)do begin stmt.

e2.例 题 2 C 语言的 for 语句 for (e1.e3) stmt 的中 间 代 码 结构如下 e1 的代码 L1: e2 的代码 L2: e3 的代码 goto L1 stmt 的代码 假转,由外层语句决 定 真转 .

1 • 第二次: 7.习 • 第一次: 7. 7.4.8 题 .

Sign up to vote on this title
UsefulNot useful