Upload
maeve
View
55
Download
0
Embed Size (px)
DESCRIPTION
第七章 中间代码生成. 中间语言 语法制导方法 简单表达式的中间代码生成 原子语句的中间代码生成 结构语句的中间代码生成 声明的中间代码. 中间语言. 后缀式----逆波兰式 图结构中间代码(语法树、 DAG) 三地址中间代码(三元式、四元式). 三地址中间代码. 三元式: i:( ,op1,op2) 四元式 : ( ,op1,op2,result). 如: a:= b×c+b×d. 语法制导方法. - PowerPoint PPT Presentation
Citation preview
第七章 中间代码生成第七章 中间代码生成
中间语言 语法制导方法 简单表达式的中间代码生成 原子语句的中间代码生成 结构语句的中间代码生成 声明的中间代码
中间语言中间语言
后缀式 ---- 逆波兰式 图结构中间代码(语法树、 DAG) 三地址中间代码(三元式、四元式)
三地址中间代码三地址中间代码 三元式: 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, - )
语法制导方法语法制导方法
语法制导方法 基于文法结构,在每个产生式的右部增加语义动作,在语法分析过程中,如遇语义动作,就完成对应的语义处理。
类型检查和类型转换类型检查和类型转换各种条件表达式的类型是否是布尔类型?运算符的运算分量是否相容?赋值语句的左、右部类型是否相容?实参与形参的类型是否相容?下标表达式的类型是否为所允许的类型?函数说明中的函数类型与返回值的类型是否
一致?
类型表达式等价类型表达式等价结构等价 基本类型等价且类型构造子相。名字等价 两个类型表达式形式完全相同。
中间代码生成中的几个问题中间代码生成中的几个问题
语义信息的获取与保存语义栈及其操作常用的语义子程序
简单表达式的简单表达式的 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)
下标变量中间代码生成下标变量中间代码生成(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) 把累加后的地址结果压入语义栈;
表达式中间代码生成的例子表达式中间代码生成的例子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)
赋值语句的形式为: Left := Right 赋值语句的四元式结构 :
Left 的中间代码 Right 的中间代码
(FLOAT , right , —, t )(ASSIG , Right ( t ) , n , Left )
语法制导: S L:=R #ASSIGN#ASSIGN :
•从语义栈中取出赋值号左右分量的语义信息;•比较类型是否相同,如果不同,则生成类型转换中间代码;•生成赋值四元式 (ASSIG , Right ( t ) , n , Left ) 。
赋值语句中间代码
过函调用的中间代码 f(E1 , E2 …, , En): E1.tuple
…
En.tuple
(ACT,E1.Arg)
…
(ACT,En.Arg)
(CALL,<f>,— , result)
或 (CALL,<f> ,— )
传给形参
形参实参结合中间代码 :(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) 动态转向地址
例: 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 )
过过 // 函调用中间代码的生成函调用中间代码的生成 遇到过 / 函名: 在符号表中的地址压栈,实参计数器为 0 ; 遇到实参 Ei : 产生计算表达式 Ei 的中间代码,实参的语义 信息压栈,计数器加 1 。 实参结束: 根据过 / 函的语义信息,检查形参与实参个数 一致?类型相容?种类符合?过 / 函?, 产生参数传送的中间代码。产生调用的中间代码 删除语义栈中过 / 函名及实参的内容, 如果是函数 将返回值的语义信息压入栈中。
CallHead
ActParam
CallTail
过过 // 函调用的语法制导函调用的语法制导ProcFunCall→ id #CallHead
( ParamList ) #CallTailParamList→ | ExpListExpList→ E #ActParam NextListNextList→ | , ExpList
GOTOGOTO 语句和标号语句的中间代语句和标号语句的中间代码码
LABEL L1,L2,...,Ln 空
SGOTO Li ( JUMP, ARG(Li) )
SLi:S ( LABEL,ARG(Li) )
S.tuple
条件语句的中间代码条件语句的中间代码条件语句的文法:
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, _, _, _)
条件语句的语法制导S→ if E then #ThenIf S ElsePart #EndIf
ElsePart → else #ElseIf S
ElsePart → #ThenIf
根据 Sem [ top ] 的值,检查它的类型是否为 boolean类型,如果是则产生中间代码 (THEN, Sem[top], _, _) 。
#ElseIf
产生中间代码 (ELSE, _, _, _) #EndIf
产生中间代码 (ENDIF, _, _, _)
WhileWhile 语句的中间代码语句的中间代码
while 语句的文法:S→ while E do S
while 语句的中间代码形式(WHILE, _, _, _)
E 的中间代码
(DO, E.FORM, _, _)
S 的中间代码
(ENDWHILE, _, _, _)
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, _, _, _)
过程过程 // 函数声明的中间代码函数声明的中间代码过程 / 函数的文法定义:
ProcFunDec→ProcDec | FunDec
ProcDec→Procedure id (ParamList)
Declaration ProgramBody
FunDec→Function id (ParamList):Type
Declaration ProgramBody
过过 // 函声明的中间代码形式函声明的中间代码形式形式:Procedure
P(FormDecList) LabelDec ConstDec TypeDec VarDec ProDec1
…… ProDecn
Body
中间代码结构:(Entry,Label,Size,Lev
el)
ProDec1.tuple …… ProDecn.tuple Body.Tuple(EndProc/
EndFunc,-,-,-)
过程声明的例子过程声明的例子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, ……)
过程过程 // 函数声明的语法制导函数声明的语法制导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, _, _, _)