第七章 中间代码生成

25
第第第 第第第第第第 第第第 第第第第第第 第第第第 第第第第第第 第第第第第第第第第第第第 第第第第第第第第第第第 第第第第第第第第第第第 第第第第第第第

description

第七章 中间代码生成. 中间语言 语法制导方法 简单表达式的中间代码生成 原子语句的中间代码生成 结构语句的中间代码生成 声明的中间代码. 中间语言. 后缀式----逆波兰式 图结构中间代码(语法树、 DAG) 三地址中间代码(三元式、四元式). 三地址中间代码. 三元式: i:(  ,op1,op2) 四元式 : (  ,op1,op2,result). 如: a:= b×c+b×d. 语法制导方法. - PowerPoint PPT Presentation

Transcript of 第七章 中间代码生成

Page 1: 第七章 中间代码生成

第七章 中间代码生成第七章 中间代码生成

中间语言 语法制导方法 简单表达式的中间代码生成 原子语句的中间代码生成 结构语句的中间代码生成 声明的中间代码

Page 2: 第七章 中间代码生成

中间语言中间语言

后缀式 ---- 逆波兰式 图结构中间代码(语法树、 DAG) 三地址中间代码(三元式、四元式)

Page 3: 第七章 中间代码生成

三地址中间代码三地址中间代码 三元式: i:(,op1,op2) 四元式:( ,op1,op2 , result)

如: a:= b×c+b×d

三元式 四元式(1) (×, b, c) (1) (×, b, c, t1)

(2) (×, b, d) (2) (×, b, d, t2)

(3) (+, (1), (2)) (3) (+, t1, t2, t3)

(4) (:=, (3), a) (4) (:=, t3, a, - )

Page 4: 第七章 中间代码生成

语法制导方法语法制导方法

语法制导方法 基于文法结构,在每个产生式的右部增加语义动作,在语法分析过程中,如遇语义动作,就完成对应的语义处理。

Page 5: 第七章 中间代码生成

类型检查和类型转换类型检查和类型转换各种条件表达式的类型是否是布尔类型?运算符的运算分量是否相容?赋值语句的左、右部类型是否相容?实参与形参的类型是否相容?下标表达式的类型是否为所允许的类型?函数说明中的函数类型与返回值的类型是否

一致?

Page 6: 第七章 中间代码生成

类型表达式等价类型表达式等价结构等价 基本类型等价且类型构造子相。名字等价 两个类型表达式形式完全相同。

Page 7: 第七章 中间代码生成

中间代码生成中的几个问题中间代码生成中的几个问题

语义信息的获取与保存语义栈及其操作常用的语义子程序

Page 8: 第七章 中间代码生成

简单表达式的简单表达式的 LLLL 语法制导语法制导E T Es

Es +T #GenCode(+) Es

Es

T PTs

Ts *P #GenCode(×) Ts

Ts

P id #Push(id)P C #Push(C)P (E)

Page 9: 第七章 中间代码生成

下标变量中间代码生成下标变量中间代码生成(1) V → #Init id #PUSH(Addr(id)) A (2) A → [ E ] #AddNext B(3) B → (4) B → [ E ] #AddNext B #Init :用来初始化下标计数器 n = 0 ;#Push :把 id 首地址压入栈中;#AddNext :

1) 下标计数器加 1 , n := n+1 ;2) 从语义栈中取出下标表达式计算结果 result ;3) 生成计算第 n 维下标需要累加的地址偏移的四元式组:( SUBI, result, Ln, tn+1) ( MULTI , tn+1 , Sk , tn+2 )( MULT, tn+2 , size, tn+3)

 4) 从语义栈中取出地址累加结果 ad ;5) 生成地址累加四元式 ( ADDI , ad , tn+3 , tn+4)

6) 把累加后的地址结果压入语义栈;

Page 10: 第七章 中间代码生成

表达式中间代码生成的例子表达式中间代码生成的例子a[5+i].x + m * z 其中, i,m:integer; z:real;a:array[1..100] of rt; rt = record y:int;x:real end

1. (ADDI, 5, i, t1)

2. (SUBI, t1 ,1, t2)

3. (MULTI, t2, 2,t3)

4. (AADD, a , t3, t4)

5. (AADD , t4, 1, t5)

6. (FLOAT , m, t6)

7. (MULTF , t6, z, t7)

8. (ADDF , t5, t7,t8)

Page 11: 第七章 中间代码生成

赋值语句的形式为: Left := Right 赋值语句的四元式结构 :

Left 的中间代码 Right 的中间代码

(FLOAT , right , —, t )(ASSIG , Right ( t ) , n , Left )

语法制导: S L:=R #ASSIGN#ASSIGN :

•从语义栈中取出赋值号左右分量的语义信息;•比较类型是否相同,如果不同,则生成类型转换中间代码;•生成赋值四元式 (ASSIG , Right ( t ) , n , Left ) 。

赋值语句中间代码

Page 12: 第七章 中间代码生成

过函调用的中间代码 f(E1 , E2 …, , En): E1.tuple

En.tuple

(ACT,E1.Arg)

(ACT,En.Arg)

(CALL,<f>,— , result)

或 (CALL,<f> ,— )

传给形参

Page 13: 第七章 中间代码生成

形参实参结合中间代码 :(VALACT, Ei.Arg, offseti, sizei)…… 值参

(VARACT, Ei.Arg, offseti, sizei)…… 变参

(FUNCACT, Ei.Arg, offseti, sizei)…… 函数参数

(PROACT, Ei.Arg, offseti, sizei)…… 过程参数过 / 函调用代码:(call ,<f>, true, result) 静态转向地址

(call ,<f>, false, result) 动态转向地址

Page 14: 第七章 中间代码生成

例: x + f (H(10), g(Y)) 其中 x 是整型变量, H 为形参函数名, H 的形参

为 值参, f 、 g 为实在函数名, f 的参数均为值参, g 的参数为变参。 ( VALACT,10,1,1 ) ( CALL, H, false, t1 ) ( VARACT, Y,1,1 ) ( CALL, g, true, t2 ) ( VALACT, t1, 1,size1 ) ( VALACT, t2, 2,size2 ) ( CALL, f, true, t3 ) ( ADDI, x, t3, t4 )

Page 15: 第七章 中间代码生成

过过 // 函调用中间代码的生成函调用中间代码的生成 遇到过 / 函名: 在符号表中的地址压栈,实参计数器为 0 ; 遇到实参 Ei : 产生计算表达式 Ei 的中间代码,实参的语义 信息压栈,计数器加 1 。 实参结束: 根据过 / 函的语义信息,检查形参与实参个数 一致?类型相容?种类符合?过 / 函?, 产生参数传送的中间代码。产生调用的中间代码 删除语义栈中过 / 函名及实参的内容, 如果是函数 将返回值的语义信息压入栈中。

CallHead

ActParam

CallTail

Page 16: 第七章 中间代码生成

过过 // 函调用的语法制导函调用的语法制导ProcFunCall→ id #CallHead

( ParamList ) #CallTailParamList→ | ExpListExpList→ E #ActParam NextListNextList→ | , ExpList

Page 17: 第七章 中间代码生成

GOTOGOTO 语句和标号语句的中间代语句和标号语句的中间代码码

LABEL L1,L2,...,Ln 空

SGOTO Li ( JUMP, ARG(Li) )

SLi:S ( LABEL,ARG(Li) )

S.tuple

Page 18: 第七章 中间代码生成

条件语句的中间代码条件语句的中间代码条件语句的文法:

S→ if E then S ElsePart

ElsePart→ else S

ElsePart → 条件语句的中间代码形式

if E then S1 else S2 if E then S

E 的中间代码(THEN, E.FORM, _)S1 的中间代码(ELSE, _, _, _)S2 的中间代码(ENDIF, _, _, _)

E 的中间代码(THEN, E.FORM, _)S 的中间代码(ENDIF, _, _, _)

Page 19: 第七章 中间代码生成

条件语句的语法制导S→ if E then #ThenIf S ElsePart #EndIf

ElsePart → else #ElseIf S

ElsePart → #ThenIf

根据 Sem [ top ] 的值,检查它的类型是否为 boolean类型,如果是则产生中间代码 (THEN, Sem[top], _, _) 。

#ElseIf

产生中间代码 (ELSE, _, _, _) #EndIf

产生中间代码 (ENDIF, _, _, _)

Page 20: 第七章 中间代码生成

WhileWhile 语句的中间代码语句的中间代码

while 语句的文法:S→ while E do S

while 语句的中间代码形式(WHILE, _, _, _)

E 的中间代码

(DO, E.FORM, _, _)

S 的中间代码

(ENDWHILE, _, _, _)

Page 21: 第七章 中间代码生成

while 语句的语法制导S→ while #StartWhile E do #DoWhile S #EndWhile

#StartWhile

产生中间代码 (WHILE, _, _, _) #DoWhile

遇 do 时(表达式 E 处理完,其值在 Sem[top] ): ⑴ 类型检查:检查 E 是否为 boolean 类型; ⑵ 产生中间代码 (DO, E.FORM , _, _) ; ⑶ E 弹栈: pop(1) ;

#EndWhile

产生中间代码 (ENDWHILE, _, _, _)

Page 22: 第七章 中间代码生成

过程过程 // 函数声明的中间代码函数声明的中间代码过程 / 函数的文法定义:

ProcFunDec→ProcDec | FunDec

ProcDec→Procedure id (ParamList)

Declaration ProgramBody

FunDec→Function id (ParamList):Type

Declaration ProgramBody

Page 23: 第七章 中间代码生成

过过 // 函声明的中间代码形式函声明的中间代码形式形式:Procedure

P(FormDecList) LabelDec ConstDec TypeDec VarDec ProDec1

…… ProDecn

Body

中间代码结构:(Entry,Label,Size,Lev

el)

ProDec1.tuple …… ProDecn.tuple Body.Tuple(EndProc/

EndFunc,-,-,-)

Page 24: 第七章 中间代码生成

过程声明的例子过程声明的例子procedure Q( x: real );

var u : real ;function f(k:real):real;

begin f := k +k end;begin u := f(50); y:= u * x end ;

(EntryQ,LabelQ,SizeQ,LQ)

(Entryf,Labelf,Sizef,Lf)

(ADDF, k, k, t0)

(ASSIG, t0,f)

(ENDFUNC,……)

(VALACT, 50,1,1)

(CALL, Labelf,true,t1)

(ASSIG, t1, u)

(MULTF, u,x, t2)

(ASSIG, t2, y)

(ENDPROC, ……)

Page 25: 第七章 中间代码生成

过程过程 // 函数声明的语法制导函数声明的语法制导ProcFunDec → ProcDec | FunDecProcDec → Procedure id (ParamList)

Declaration #Entry ProgramBody #EndProcFunDec → Function id (ParamList): Type

Declaration #Entry ProgramBody #EndFunc #Entry

(1) 给子程序 Q 分配新标号 LevelQ ,并将它填到 Q 的符号表项中(2) 产生入口中间代码

(ENTRY, LabelQ, SizeQ, LevelQ) #EndProc 和 #EndFunc

在遇到 end 时产生出口中间代码(ENDPROC, _, _, _)

或 (ENDFUNC, _, _, _)