《编译原理中间代码生成7》由会员分享,可在线阅读,更多相关《编译原理中间代码生成7(85页珍藏版)》请在金锄头文库上搜索。
1、第七章第七章 中间代码生成中间代码生成本章内容本章内容介绍几种常用的中间表示介绍几种常用的中间表示:后缀表示、图形后缀表示、图形表示和三地址代码表示和三地址代码用语法制导定义和翻译方案的方法来说明源用语法制导定义和翻译方案的方法来说明源语言的各种构造怎样被翻译成中间形式语言的各种构造怎样被翻译成中间形式 分析分析器器静态静态检查检查器器中间中间代码代码生成生成器器中间中间代码代码记记号号流流代码代码生成生成器器7.1 中中 间间 语语 言言7.1.1 后缀表示后缀表示表达式表达式E的的后缀表示后缀表示可以如下归纳定义可以如下归纳定义如果如果E是变量或常数,那么是变量或常数,那么E的后缀表示就是
2、的后缀表示就是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的后缀表示就是
3、的后缀表示就是E本身本身如果如果E是形式为是形式为E1 opE2的表达式,那么的表达式,那么E的后的后缀表示是缀表示是E1 E2 op,其中其中E1 和和E2 分别是分别是E1和和E2的后缀表示的后缀表示如果如果E是形式为是形式为(E1)的表达式,那么的表达式,那么E1的后缀的后缀表示也是表示也是E的后缀表示的后缀表示7.1 中中 间间 语语 言言后缀表示不需要括号后缀表示不需要括号(8 4) + 2 的后缀表示是的后缀表示是8 4 2 + 7.1 中中 间间 语语 言言后缀表示不需要括号后缀表示不需要括号(8 4) + 2 的后缀表示是的后缀表示是8 4 2 + 后缀表示的最大优点是便于计算
4、机处理表达后缀表示的最大优点是便于计算机处理表达式式7.1 中中 间间 语语 言言后缀表示不需要括号后缀表示不需要括号(8 4) + 2 的后缀表示是的后缀表示是8 4 2 + 后缀表示的最大优点是便于计算机处理表达后缀表示的最大优点是便于计算机处理表达式式后缀表示很容易拓广到含一元算符的表达式后缀表示很容易拓广到含一元算符的表达式 7.1 中中 间间 语语 言言后缀表示不需要括号后缀表示不需要括号(8 4) + 2 的后缀表示是的后缀表示是8 4 2 + 后缀表示的最大优点是便于计算机处理表达后缀表示的最大优点是便于计算机处理表达式式后缀表示很容易拓广到含一元算符的表达式后缀表示很容易拓广到
5、含一元算符的表达式 后缀表示也可以拓广到表示赋值语句和控制后缀表示也可以拓广到表示赋值语句和控制语句,但很难用栈来描述它的计算语句,但很难用栈来描述它的计算7.1 中中 间间 语语 言言7.1.2 图形表示图形表示语法树是一种图形化的中间表示语法树是一种图形化的中间表示 assigna+ bcdcduminus(a) 语法树语法树 a = ( b + c d) + c d的图形的图形表示表示7.1 中中 间间 语语 言言7.1.2 图形表示图形表示语法树是一种图形化的中间表示语法树是一种图形化的中间表示有向无环图有向无环图也是一种中间表示也是一种中间表示 assigna+ bcdcduminu
6、sassigna+ bcduminus(a) 语法树语法树(b) dag 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 E2E.nptr = mkNode( , E1.nptr, E2.nptr) E E1E.nptr
7、= mkUNode( uminus, E1.nptr) E (E1) E.nptr = E1.nptr F id E.nptr = mkLeaf (id, id.entry) 7.1 中中 间间 语语 言言7.1.3 三地址代码三地址代码一般形式:一般形式:x = y op z表达式表达式x + y z翻译成的三地址语句序列是翻译成的三地址语句序列是t1 = y z t2 = x + t1 7.1 中中 间间 语语 言言三地址代码是语法树或三地址代码是语法树或dag的一种线性表示的一种线性表示a = ( b + c d ) + c d语法树的代码语法树的代码t1 = bt2 = c dt3 =
8、 t1 + t2t4 = c dt5 = t3 + t4a = t5assigna+ bcdcduminus7.1 中中 间间 语语 言言三地址代码是语法树或三地址代码是语法树或dag的一种线性表示的一种线性表示a = ( b + c d ) + c d语法树的代码语法树的代码dag的代码的代码t1 = bt1 = bt2 = c dt2 = c dt3 = t1 + t2t3 = t1 + t2t4 = c dt4 = t3 + t2t5 = t3 + t4 a = t4a = t5assigna+ bcduminus7.1 中中 间间 语语 言言本书常用的三地址语句本书常用的三地址语句赋值
9、语句赋值语句x = y op z, x = op y, x = y无条件转移无条件转移goto L条件转移条件转移if x relop y goto L过程调用过程调用param x 和和call p , n过程返回过程返回 return y索引赋值索引赋值x = yi和和 xi = y地址和指针赋值地址和指针赋值x = &y,x = y和和 x = y7.1 中中 间间 语语 言言7.1.4 静态单赋值形式静态单赋值形式一种便于某些代码优化的中间表示一种便于某些代码优化的中间表示和三地址代码的主要区别和三地址代码的主要区别 所有赋值指令都是对不同名字的变量的赋值所有赋值指令都是对不同名字的变
10、量的赋值三地址代码三地址代码静态单赋值形式静态单赋值形式p = a +bp1 = a +b q = p cq1 = p1 c p = q dp2 = q1 d p = e pp3 = e p2 q = p + q q2 = p3 + q17.1 中中 间间 语语 言言7.1.4 静态单赋值形式静态单赋值形式一种便于某些代码优化的中间表示一种便于某些代码优化的中间表示和三地址代码的主要区别和三地址代码的主要区别 所有赋值指令都是对不同名字的变量的赋值所有赋值指令都是对不同名字的变量的赋值一个变量在不同路径上都定值的解决办法一个变量在不同路径上都定值的解决办法if (flag) x = 1; el
11、se x = 1;y = x a;的条件语句改成的条件语句改成if (flag) x1 = 1; else x2 = 1;x3 = (x1, x2);/由由flag的值决定用的值决定用x1还是还是x27.2 声声 明明 语语 句句为局部名字建立符号表条目为局部名字建立符号表条目为它分配存储单元为它分配存储单元符号表中包含名字的类型和分配给它的存储符号表中包含名字的类型和分配给它的存储单元的相对地址等信息单元的相对地址等信息7.2 声声 明明 语语 句句7.2.1 过程中的声明过程中的声明7.2 声声 明明 语语 句句计算被声明名字的类型和相对地址计算被声明名字的类型和相对地址P offset
12、= 0 D; SD D ; D D id : T enter ( id.lexeme, T.type, offset);offset = offset + T.width T integer T.type = integer; T.width = 4 T real T.type = real; T.width = 8 T array num of T1T.type = array (num.val, T1.type);T.width = num.val T1.widthT T1 T.type = pointer (T1.type); T.width = 4 7.2 声声 明明 语语 句句7.2
13、.2 作用域信息的保存作用域信息的保存所讨论语言的文法所讨论语言的文法P D; SD D ; D | id : T | proc id ; D ; S 语义动作用到的函数语义动作用到的函数mkTable(previous)enter(table, name, type, offset) addWidth(table, width)enterProc(table, name, newtable)7.2 声声 明明 语语 句句P M D; S addWidth (top (tblptr), top (offset) ); pop(tblptr); pop (offset) M t = mkTabl
14、e (nil);push(t, tblprt); push (0, offset) D D1 ; D2D proc id ; N D1; S t = top(tblptr);addWidth(t, top(offset) ); pop(tblptr); pop(offset);enterProc(top(tblptr), id.lexeme, t) Did :T enter(top(tblptr), id.lexeme, T.type, top(offset); top(offset) = top(offset) + T.width N t = mkTable(top(tblptr) ); p
15、ush(t, tblptr); push(0, offset) 7.2 声声 明明 语语 句句exchangereadarrayxa表表 头头空空sortquicksort指向指向readarraypartitionvk表表 头头quicksortreadarrayi表表 头头exchange表表 头头指向指向exchangepartition7.2 声声 明明 语语 句句7.2.3 记录的域名记录的域名T record D endT record L D endT.type = record (top(tblptr) );T.width = top(offset);pop(tblptr);
16、pop(offset) L t = mkTable(nil);push(t, tblprt); push(0, offset) 7.3 赋赋 值值 语语 句句7.3.1 符号表的中名字符号表的中名字S id := E p = lookup(id.lexeme);if p != nil thenemit ( p, =, E.place)else error E E1 + E2E.place = newTemp(); emit (E.place, =, E1.place, +, E2.place) 7.3 赋赋 值值 语语 句句7.3.1 符号表的中名字符号表的中名字E E1 E.place =
17、newTemp(); emit (E.place, =, uminus, E1.place) E (E1) E.place = E1.place E id p = lookup(id.lexeme);if p != nil then E.place = p else error 7.3 赋赋 值值 语语 句句7.3.2 数组元素的地址计算数组元素的地址计算一维数组一维数组A的第的第i个元素的地址计算个元素的地址计算base + ( i low ) w7.3 赋赋 值值 语语 句句7.3.2 数组元素的地址计算数组元素的地址计算一维数组一维数组A的第的第i个元素的地址计算个元素的地址计算base
18、 + ( i low ) w 重写成重写成i w + (base low w)减少了运行时的计算减少了运行时的计算7.3 赋赋 值值 语语 句句二维数组二维数组A: array1.2, 1.3 of T列为主列为主A1, 1, A2, 1, A1, 2, A2, 2, A1, 3, A2, 37.3 赋赋 值值 语语 句句二维数组二维数组A: array1.2, 1.3 of T列为主列为主A1, 1, A2, 1, A1, 2, A2, 2, A1, 3, A2, 3行为主行为主A1, 1, A1, 2, A1, 3, A2, 1, A2, 2, A2, 3 7.3 赋赋 值值 语语 句句二
19、维数组二维数组A: array1.2, 1.3 of T列为主列为主A1, 1, A2, 1, A1, 2, A2, 2, A1, 3, A2, 3行为主行为主A1, 1, A1, 2, A1, 3, A2, 1, A2, 2, A2, 3base + ( (i1 low1) n2 + (i2 low2 ) ) w(其中其中n2 = high2 low2 + 1)7.3 赋赋 值值 语语 句句二维数组二维数组A: array1.2, 1.3 of T列为主列为主A1, 1, A2, 1, A1, 2, A2, 2, A1, 3, A2, 3行为主行为主A1, 1, A1, 2, A1, 3,
20、A2, 1, A2, 2, A2, 3base + ( (i1 low1) n2 + (i2 low2 ) ) w(其中其中n2 = high2 low2 + 1)( (i1 n2 ) + i2 ) w + (base ( (low1 n2 ) + low2 ) w)7.3 赋赋 值值 语语 句句多维数组下标变量多维数组下标变量Ai1, i2, ., ik 的地址表达式的地址表达式( ( ( (i1 n2 + i2 ) n3 + i3 ) ) nk + ik) w + base ( ( ( (low1 n2 + low2) n3 + low3) ) nk + lowk ) w7.3 赋赋 值值
21、 语语 句句7.3.3 数组元素地址计算的翻译方案数组元素地址计算的翻译方案下标变量访问的产生式下标变量访问的产生式L id Elist | idElist Elist, E | E改成改成L Elist | idElist Elist, E | id E7.3 赋赋 值值 语语 句句所有产生式所有产生式S L := EE E + EE (E )E LL Elist L idElist Elist, EElist id E7.3 赋赋 值值 语语 句句L id L.place = id.place; L.offset = null 7.3 赋赋 值值 语语 句句L id L.place = i
22、d.place; L.offset = null Elist id E Elist.place = E.place; Elist.ndim = 1; Elist.array = id.place 7.3 赋赋 值值 语语 句句L id L.place = id.place; L.offset = null Elist id E Elist.place = E.place; Elist.ndim = 1; Elist.array = id.place Elist Elist1, E t = newTemp(); m = Elist1.ndim + 1; emit (t, =, Elist1.pl
23、ace, , limit(Elist1.array, m) ); emit (t, =, t, +, E.place); Elist.array = Elist1.array; Elist.place = t; Elist.ndim = m7.3 赋赋 值值 语语 句句L id L.place = id.place; L.offset = null Elist id E Elist.place = E.place; Elist.ndim = 1; Elist.array = id.place Elist Elist1, E t = newTemp(); m = Elist1.ndim + 1;
24、 emit (t, =, Elist1.place, , limit(Elist1.array, m) ); emit (t, =, t, +, E.place); Elist.array = Elist1.array; Elist.place = t; Elist.ndim = mL Elist L.place = newTemp(); emit (L.place, =, base(Elist.array), ,invariant (Elist.array) ); L.offset = newTemp(); emit (L.offset, =, Elist.place, ,width(Eli
25、st.array)7.3 赋赋 值值 语语 句句E Lif L.offset = null then / L是简单变量是简单变量 / E.place = L.place else begin E.place = newTemp(); emit (E.place, =, L.place, , L.offset, ) end 7.3 赋赋 值值 语语 句句E Lif L.offset = null then / L是简单变量是简单变量 / E.place = L.place else begin E.place = newTemp(); emit (E.place, =, L.place, , L
26、.offset, ) end E E1 + E2E.place = newTemp();emit (E.place, =, E1.place , +, E2.place) 7.3 赋赋 值值 语语 句句E Lif L.offset = null then / L是简单变量是简单变量 / E.place = L.place else begin E.place = newTemp(); emit (E.place, =, L.place, , L.offset, ) end E E1 + E2E.place = newTemp();emit (E.place, =, E1.place , +,
27、E2.place) E (E1 )E.place = E1.place 7.3 赋赋 值值 语语 句句E Lif L.offset = null then / L是简单变量是简单变量 / E.place = L.place else begin E.place = newTemp(); emit (E.place, =, L.place, , L.offset, ) end E E1 + E2E.place = newTemp();emit (E.place, =, E1.place , +, E2.place) E (E1 )E.place = E1.place S L = E if L.o
28、ffset = null then / L是是简简单单变变量量 /emit (L.place, = , E.place)else emit (L.place , , L.offset, , =, E.place) 7.3 赋赋 值值 语语 句句S:=L.place = xL.offset = nullxE.place = t4L.place = t2L.offset = t3Elist.place = t1Elist.ndim = 2Elist.array = A,Elist.place = yElist.ndim = 1Elist.array = AE.place = zL.place =
29、zL.offset = nullE.place = yL.place = yL.offset = nullAzy x := A y, z 的注释分析树的注释分析树7.3 赋赋 值值 语语 句句S:=L.place = xL.offset = nullxE.place = t4L.place = t2L.offset = t3Elist.place = t1Elist.ndim = 2Elist.array = A,Elist.place = yElist.ndim = 1Elist.array = AE.place = zL.place = zL.offset = nullE.place =
30、yL.place = yL.offset = nullAzy x := A y, z 的注释分析树的注释分析树t1 = y 20 t1 = t1 + z 7.3 赋赋 值值 语语 句句S:=L.place = xL.offset = nullxE.place = t4L.place = t2L.offset = t3Elist.place = t1Elist.ndim = 2Elist.array = A,Elist.place = yElist.ndim = 1Elist.array = AE.place = zL.place = zL.offset = nullE.place = yL.p
31、lace = yL.offset = nullAzy x := A y, z 的注释分析树的注释分析树t1 = y 20 t1 = t1 + z t2 =A 84 t3 = 4 t1 7.3 赋赋 值值 语语 句句S:=L.place = xL.offset = nullxE.place = t4L.place = t2L.offset = t3Elist.place = t1Elist.ndim = 2Elist.array = A,Elist.place = yElist.ndim = 1Elist.array = AE.place = zL.place = zL.offset = nul
32、lE.place = yL.place = yL.offset = nullAzy x := A y, z 的注释分析树的注释分析树t1 = y 20 t1 = t1 + z t2 =A 84 t3 = 4 t1 t4 = t2 t3 7.3 赋赋 值值 语语 句句S:=L.place = xL.offset = nullxE.place = t4L.place = t2L.offset = t3Elist.place = t1Elist.ndim = 2Elist.array = A,Elist.place = yElist.ndim = 1Elist.array = AE.place =
33、zL.place = zL.offset = nullE.place = yL.place = yL.offset = nullAzy x := A y, z 的注释分析树的注释分析树t1 = y 20 t1 = t1 + z t2 =A 84 t3 = 4 t1 t4 = t2 t3 x = t4 7.3 赋赋 值值 语语 句句7.3.4 类型转换类型转换x = y + i j(x和和y的类型是的类型是real,i和和j的类型是的类型是integer)中间代码中间代码t1 = i int jt2 = inttoreal t1 t3 = y real+ t2 x = t37.3 赋赋 值值 语
34、语 句句E E1 + E2E.place = newTemp();if E1.type = integer & E2.type = integer then begin emit (E.place, =, E1.place, int+, E2.place);E.type = integerendelse if E1.type = integer & E2.type = real then beginu = newTemp();emit (u, =, inttoreal, E1.place);emit (E.place, =, u, real+, E2.place);E.type = reale
35、nd . . .7.4 布尔表达式和控制流语句布尔表达式和控制流语句7.4.1 布尔表达式布尔表达式布尔表达式有两个基本目的布尔表达式有两个基本目的计算逻辑值计算逻辑值在控制流语句中用作条件表达式在控制流语句中用作条件表达式本节所用的布尔表达式文法本节所用的布尔表达式文法B B or B | B and B | not B | ( B ) | E relop E | true | false7.4 布尔表达式和控制流语句布尔表达式和控制流语句7.4.1 布尔表达式布尔表达式布尔表达式有两个基本目的布尔表达式有两个基本目的计算逻辑值计算逻辑值在控制流语句中用作条件表达式在控制流语句中用作条件表达
36、式布尔表达式的完全计算布尔表达式的完全计算值值的的表表示示数数值值化化,其其计计算算类类似似于于算算术术表表达达式式的的计计算算7.4 布尔表达式和控制流语句布尔表达式和控制流语句7.4.1 布尔表达式布尔表达式布尔表达式有两个基本目的布尔表达式有两个基本目的计算逻辑值计算逻辑值在控制流语句中用作条件表达式在控制流语句中用作条件表达式布尔表达式的完全计算布尔表达式的完全计算值值的的表表示示数数值值化化,其其计计算算类类似似于于算算术术表表达达式式的的计计算算布尔表达式的布尔表达式的“短路短路”计算计算 B1 or B2 定义成定义成 if B1 then true else B2 B1 and
37、 B2 定义成定义成 if B1 then B2 else false用控制流来实现,即用程序中的位置来表示值用控制流来实现,即用程序中的位置来表示值7.4 布尔表达式和控制流语句布尔表达式和控制流语句7.4.2 控制流语句的翻译控制流语句的翻译S if B then S1| if B then S1 else S2| while B do S1| S1; S2 7.4 布尔表达式和控制流语句布尔表达式和控制流语句B.codeS1.codeB.true:. . .指向指向B.true指向指向B.false(a) if-thenB.codeS1.codeB.true:. . .指向指向B.tru
38、e指向指向B.falseB.false: goto S.nextS2.code(b) if-then-elseB.codeS1.codeB.true:. . .指向指向B.true指向指向B.falsegoto S.beginS.begin:(c) while-doS1.codeS2.codeS1.next:. . .(d) S1; S27.4 布尔表达式和控制流语句布尔表达式和控制流语句S if B then S1B.true = newLabel(); B.false = S.next; S1.next = S.next; S.code = B.code | gen(B.true, :)
39、| S1.code B.codeS1.codeB.true:. . .指向指向B.true指向指向B.false(a) if-then7.4 布尔表达式和控制流语句布尔表达式和控制流语句S if B then S1 else S2B.true = newLabel(); B.false = newLabel(); S1.next = S.next; S2.next = S.next; S.code = B.code | gen(B.true, :) | S1.code | gen(goto, S.next) | gen(B.false, :) | S2.code B.codeS1.codeB.
40、true:. . .指向指向B.true指向指向B.falseB.false: goto S.nextS2.code(b) if-then-else7.4 布尔表达式和控制流语句布尔表达式和控制流语句S while B do S1 S.begin = newLabel(); B.true = newLabel(); B.false = S.next; S1.next = S.begin; S.code = gen(S.begin, :) | B.code | gen(B.true, :) | S1.code | gen(goto, S.begin) B.codeS1.codeB.true:.
41、. .指向指向B.true指向指向B.falsegoto S.beginS.begin:(c) while-do7.4 布尔表达式和控制流语句布尔表达式和控制流语句S S1; S2S1.next = newLabel(); S2.next = S.next; S.code = S1.code | gen(S1.next, :) | S2.code S1.codeS2.codeS1.next:. . .(d) S1; S27.4 布尔表达式和控制流语句布尔表达式和控制流语句7.4.3 布尔表达式的控制流翻译布尔表达式的控制流翻译如果如果B是是a b的形式,的形式,那么代码是:那么代码是:if a
42、 b goto B.truegoto B.false7.4 布尔表达式和控制流语句布尔表达式和控制流语句表达式表达式a b or c d and e f的代码是:的代码是:if a b goto Ltruegoto L1L1:if c d goto L2goto LfalseL2:if e f goto Ltruegoto Lfalse7.4 布尔表达式和控制流语句布尔表达式和控制流语句B B1 or B2B1.true = B.true; B1.false = newLabel(); B2.true = B.true; B2.false = B.false; B.code = B1.code
43、 | gen(B1.false, :) | B2.code 7.4 布尔表达式和控制流语句布尔表达式和控制流语句B B1 or B2B1.true = B.true; B1.false = newLabel(); B2.true = B.true; B2.false = B.false; B.code = B1.code | gen(B1.false, :) | B2.code B not B1B1.true = B.false; B1.false = B.true; B.code = B1.code 7.4 布尔表达式和控制流语句布尔表达式和控制流语句B B1 and B2B1.true =
44、 newLabel(); B1.false = B.false; B2.true = B.true; B2.false = B.false; B.code = B1.code | gen(B1.true, :) | B2.code 7.4 布尔表达式和控制流语句布尔表达式和控制流语句B B1 and B2B1.true = newLabel(); B1.false = B.false; B2.true = B.true; B2.false = B.false; B.code = B1.code | gen(B1.true, :) | B2.code B (B1 ) B1.true = B.tr
45、ue; B1.false = B.false; B.code = B1.code 7.4 布尔表达式和控制流语句布尔表达式和控制流语句B E1 relop E2B.code = E1.code | E2.code |gen(if, E1.place, relop.op, E2.place, goto, B.true) | gen(goto, B.false) 7.4 布尔表达式和控制流语句布尔表达式和控制流语句B E1 relop E2B.code = E1.code | E2.code |gen(if, E1.place, relop.op, E2.place, goto, B.true)
46、| gen(goto, B.false) B trueB.code = gen(goto, B.true)B falseB.code = gen(goto, B.false)7.4 布尔表达式和控制流语句布尔表达式和控制流语句7.4.4 开关语句的翻译开关语句的翻译switch Ebegincase V1: S1case V2: S2. . .case Vn - 1: Sn 1default: Snend7.4 布尔表达式和控制流语句布尔表达式和控制流语句分支数较少时分支数较少时t = E的代码的代码 | Ln-2: if t != Vn-1 goto Ln-1 if t != V1 goto
47、 L1 | Sn -1的代码的代码 S1的代码的代码 | goto nextgoto next | Ln-1: Sn的代码的代码 L1:if t != V2 goto L2 | next: S2的代码的代码goto nextL2:. . . . . 7.4 布尔表达式和控制流语句布尔表达式和控制流语句分支较多时,将分支测试的代码集中在一起,分支较多时,将分支测试的代码集中在一起,便于生成较好的分支测试代码。便于生成较好的分支测试代码。t = E的代码的代码| Ln: Sn的代码的代码goto test | goto nextL1:S1的代码的代码 |test: if t = V1 goto L
48、1 goto next| if t = V2 goto L2 L2:S2的代码的代码 | . . .goto next|if t = Vn-1 goto Ln-1. . . |goto LnLn-1: Sn -1的代码的代码| next:goto next7.4 布尔表达式和控制流语句布尔表达式和控制流语句中间代码增加一种中间代码增加一种case语句,便于代码生成器语句,便于代码生成器对它进行特别处理对它进行特别处理 test: case V1 L1case V2 L2. . .case Vn-1 Ln-1case t Ln next: 7.4 布尔表达式和控制流语句布尔表达式和控制流语句7.
49、4.5 过程调用的翻译过程调用的翻译S call id (Elist)Elist Elist, EElist E7.4 布尔表达式和控制流语句布尔表达式和控制流语句过程调用过程调用id(E1, E2, , En)的中间代码结构的中间代码结构E1.place = E1的代码的代码E2.place = E2的代码的代码. . .En.place = En的代码的代码param E1.placeparam E2.place. . .param En.placecall id.place, n7.4 布尔表达式和控制流语句布尔表达式和控制流语句S call id (Elist)为长度为为长度为n的队列
50、中的每个的队列中的每个E.place,emit(param, E.place); emit(call, id.plase, n) Elist Elist, E把把E.place放入队列末尾放入队列末尾Elist E将队列初始化,并让它仅含将队列初始化,并让它仅含E.place 本本 章章 要要 点点中间代码的几种形式,它们之间的相互转换中间代码的几种形式,它们之间的相互转换符号表的组织和作用域信息的保存符号表的组织和作用域信息的保存数数组组元元素素定定址址的的翻翻译译方方案案,布布尔尔表表达达式式的的两两种不同实现方式种不同实现方式赋赋值值语语句句和和各各种种控控制制流流语语句句的的中中间间代
51、代码码格格式式和生成中间代码的翻译方案和生成中间代码的翻译方案过过程程调调用用的的中中间间代代码码格格式式和和生生成成中中间间代代码码的的翻译方案翻译方案例例 题题 1Pascal语言的标准将语言的标准将for语句语句for v := initial to final do stmt定义成和下面的代码序列有同样的含义:定义成和下面的代码序列有同样的含义:begint1 := initial; t2 := final;if t1= t2 then beginv := t1; stmt;while v t2 do beginv := succ(v); stmtendendend例例 题题 1Pas
52、cal语言的标准将语言的标准将for语句语句for v := initial to final do stmt能否定义成和下面的代码序列有同样的含义?能否定义成和下面的代码序列有同样的含义?begint1 := initial; t2 := final;v := t1;while v t2 goto L1v = t1 L2: stmtif v = t2 goto L1v = v + 1goto L2 L1: 例例 题题 2C语言的语言的for语句有下列形式语句有下列形式for (e1;e2;e3) stmt它和它和e1;while (e2)do beginstmt;e3;end例例 题题 2C
53、语言的语言的for语句语句for (e1;e2;e3) stmt的中间代码的中间代码结构如下结构如下 e1的代码的代码L1: e2的代码的代码L2: e3的代码的代码 goto L1 stmt的代码的代码 goto L2真转真转假转,由外层语句决定假转,由外层语句决定例例 题题 3Pascal语言语言var a,b : array1.100 of integer;a:=b允许数组之间赋值允许数组之间赋值若若a和和b是同一类型记录,也允许是同一类型记录,也允许C语言语言数组类型不行,结构类型可以数组类型不行,结构类型可以为为这这种种赋赋值值选选用用或或设设计计一一种种三三地地址址语语句句,它它要
54、便于生成目标代码要便于生成目标代码例例 题题 3Pascal语言语言var a,b : array1.100 of integer;a:=b允许数组之间赋值允许数组之间赋值若若a和和b是同一类型记录,也允许是同一类型记录,也允许仍仍然然用用中中间间代代码码复复写写语语句句 x = y,在在生生成成目目标标代代码码时时,必必须须根根据据它它们们类类型型的的size,产产生生一一连连串的值传送指令串的值传送指令例例 题题 4 下下面面的的翻翻译译方方案案使使用用了了变变量量offset,请请重重写写该该翻翻译译方方案案,它它完完成成同同样样的的事事情情,但但只只使使用用文文法符号的属性,而不使用变
55、量法符号的属性,而不使用变量offsetP offset = 0 DD D ; D D id : T enter(id.lexeme, T.type, offset); offset = offset + T.width T integer T.type = integer; T.width = 4 T realT.type = real; T.width = 8 例例 题题 4P D.offset1 = 0 D P.offset = D.offset2 D D1.offset1 = D.offset1 D1 ; D2.offset1 = D1.offset2 D2 D.offset2 = D2.offset2 D id :Tenter ( id.lexeme, T.type, D.offset1); D.offset2 = D.offset1 + T.width T integer T.type = integer; T.width = 4 T realT.type = real; T.width = 8 习习 题题第一次:第一次:7.1第二次:第二次:7.4, 7.8, 7.10