第八章 中间代码生成
? 中间语言
? 简单表达式的中间代码生成
? 原子语句的中间代码生成
? 结构语句的中间代码生成
? 声明的中间代码
中间语言
? 后缀式 ----逆波兰式
? 三地址中间代码(三元式、四元式)
? 图结构中间代码(语法树,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,- )
简单表达式的中间代码形式
? E ? C Tuple(E)=空,ARG(E)= C.val
? E ? x Tuple(E)=空,ARG(E)= x.val
? E ? E1 ? E2 Tuple(E)= Tuple(E1)|| Tuple(E2)
|| (?,ARG(E1),ARG(E2),t)
ARG(E)= t,t是临时变量
表达式的语义信息:
表达式种类,E.kind
表达式的类型,E.type
表达式的结果值 ARG,E.Arg 或 ARG(E)
标号 L,ARG(L)= LabelForm’(L)
整数 C,ARG(C)= ValueForm’(C)
源程序变量 X,ARG(X)= AddrForm’(L,Off,Mode)
临时变量 T,ARG(T)= AddrForm’(-1,off,Mode)
表达式的中间代码,E.tuple
产生一条中间代码的子程序 GenCode(?):
运算分量 (栈顶和次栈顶 )类型检查;
如需类型转换:生成类型转换中间代码;
生成 ?操作的 中间代码 ;
从栈中删除运算分量的语义信息;
表达式结果的语义信息压栈
简单表达式中间代码
的 LR语法制导
E ? T
E ? E+T #GenCode(+)
T ? P
T ? T× P #GenCode(× )
P ? C {Push((C.type,C.Arg))}
P ? id {Push(VarType(entry),VarArg(entry))}
P ? (E)
简单表达式的 LL语法制导
E ? T Es
Es ? +T #GenAdd Es
Es ? ?
T ? PTs
Ts ? *P #GenMul Ts
Ts ? ?
P ? id #VPrimary
P ? C #CPrimary
P ?(E)
GenAdd, GenCode(+) ; GenMul,GenCode(× )
Vprimary,Cprimary,同上。
变量中间代码结构
V.tuple=空
? V ? V1.id V1.tuple
(AADD,V1.Arg,offset(id),V.Arg)
? V ? V1[E] V1.tuple
E.tuple
(SUBI,E.Arg,low,t1)
(MULTI,t1,size,t2)
(AADD,V1.Arg,t2,V.Arg)
? V ? V1 ? V1.tuple
(ASSIGN,V1.Arg,V.Arg)
? V ? id
变量中间代码的 LR语法制导
? V ? id
{Push((VarType(entry),VarArg(entry)))}
? V ? V1.id #FieldVar
FieldVar,L:= Sem[top-1]; R:= Sem[top];
ResultArg:= NewTemp(indir);
Generate(AADD,L.Arg,R.arg,ResultArg)
Pop(2),Push((R.type,ResultArg))
? V ? V1[E] #IndexVar
IndexVar,L:= Sem[top-1]; R:= Sem[top];
ResultArg:=NewTemp(indir);
ResultType:= L.Type.ElemType;
Low:=L.Type.Low;Size:= L.Type.ElemSize;
Generate(SUBI,R.Arg,Low,t1);
Generate(MULI,t1,Size,t2);
Generate(AADD,L.Arg,t2,ResultArg);
POP(2); Push((ResultType,ResultArg));
? V ? V1? #DenoVar
DenoVar,ResultArg:=NewTemp(indir);
ResultType:= Sem[top].Type.BaseType;
Generate(ASSIG,Sem[top].Arg,ResultArg)
POP(1); Push((ResultType,ResultArg))
表达式中间代码生成的例子
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)