原子语句的中间代码
输入输出语句:
S ?Write(E) E.tuple
(WRITE,E.Arg);
S ? Read(V) V.tuple
( READ,V.Arg)
语法制导:
S ? Read(V) #READ
S ? Write(E) #WRITE
赋值语句:
赋值语句形式:
V:=E Vptr:=V1ptr f:=E Vstr:=V1str
赋值语句的中间代码形式,(ASSIG,Arg1,Arg2,n)
或 (FLOAT,Arg1,Arg2)
S ? L:= R L.tuple
R.tuple
(ASSIG,R.Arg,L.Arg,size)
或 (FLOAT,R.Arg,L.Arg)
语法制导,S ?L:=R #ASSIGN
过函调用
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) 动态转向地址
GOTO语句和标号语句的中间代码
LABEL L1,L2,...,Ln 空
S?GOTO Li ( JUMP,ARG(Li) )
S?Li:S ( LABEL,ARG(Li) )
S.tuple
结构语句的中间代码
? 条件语句的中间代码
? While语句的中间代码
? Repeat语句的中间代码
? For语句的中间代码
? Case语句的中间代码
条件语句的中间代码
IF E THEN S1 ELSE S2
E.Tuple
(JUMP0,E.Arg,S.ElseL)
S1.Tuple
(JUMP,S.OutL)
(LABEL,S.ElseL)
S2.Tuple
(LABEL,S.OutL)
S ? IF E THEN S1
E.Tuple
(JUMP0,E.Arg,S.OutL)
S1.Tuple
(LABEL,S.OutL)
条件语句代码生成的 LL文法
S→ if #StartIF E then #TestIF S1 ElsePart #EndIF
ElsePart → else #GenJump #GenElseL S2 #GenOutL
ElsePart → ? #GenOutL
#StartIF:PUSH(S.ElseL);PUSH(S.OutL);
#TestIF:Generate(JUMP0,Sem[top].Arg,Sem[top-2]);POP(1)
#GenJump:Generate(JUMP,Sem[top].Arg )
#GenElseL,Generate(LABEL,Sem[top-1].Arg)
#GenOutL,Generate(LABEL,Sem[top].Arg)
#EndIF,POP(2)
While语句的中间代码
S ? WHILE E DO S1
E.Tuple
(JUMP0,E.Arg,S.OutL)
S1.Tuple
(JUMP,S.StartL)
(LABEL,S.OutL)
(LABEL,S.StartL)
While语句代码生成的 LL文法
S → while #StartWhile E do #WhileTest
S1 #FinishWhile
#StartWhile,PUSH(S.StartL);PUSH(S.OutL);
Generate(LABEL,Sem[top-1].Arg)
#WhileTest,Generate(JUMP0,Sem[top].Arg,Sem[top-1].Arg)
POP(1);
# FinishWhile,Generate(JUMP,S.StartL)
Generate(LABEL,S.OutL)
POP(2)
Repeat语句的中间代码
S ? repeat S1 until E
S1.Tuple
(JUMP0,E.Arg,S.StartL)
E.Tuple
(LABEL,S.StartL)
Repeat语句代码生成的 LL文法
S → repeat #StartRepeat S1 do E #FinishRepeat
#StartRepeat,PUSH(S.StartL)
Generate(LABEL,Sem[top].Arg )
#FinishRepeat:
Generate(JUMP0,Sem[top].Arg,Sem[top-1].Arg)
POP(2)
For语句的中间代码
for V:=E1 to E2 do S1
E1.Tuple
E2.Tuple
(GT,E1.Arg,E2.Arg,t1)
(JUMP1,t1,S.OutL)
(ASSIG,E1.Arg,V.Arg)
S1.Tuple
(ADDI,V.Arg,1,t2)
(ASSIG,t2,V.Arg)
(GT,V.Arg,E2.Arg,t3)
(JUMP0,t3,S.LoopL)
(LABEL,S.OutL)
(LABEL,S.LoopL)
for V:=E1 downto E2 do S1
E1.Tuple
E2.Tuple
(LT,E1.Arg,E2.Arg,t1)
(JUMP1,t1,S.OutL)
(ASSIG,E1.Arg,V.Arg)
S1.Tuple
(SUBI,V.Arg,1,t2)
(ASSIG,t2,V.Arg)
(LT,V.Arg,E2.Arg,t3)
(JUMP0,t3,S.LoopL)
(LABEL,S.OutL)
(LABEL,S.LoopL)
For语句代码的 LL动作文法
S→ for #StartFOR V:=E FORKIND E do #ForDO
S #FinishFOR
FORKIND → to #ToKind
FORKIND → downto #DownKind
StarFOR,产生新标号 S.LoopL和 S.OutL;
ToKind/DownKind,标记循环种类;
ForDO:
FinishFOR:
Case语句的中间代码
E.tuple
(JUMP,Search)
L1:S1的中间代码
(JUMP,OutL)
.,.....
OtherL:S*的中间代码
(JUMP,OutL)
Table:
Search:
(LABEL,OutL)
case E of
C1,S1;
… …
Cn,Sn;
Other,S*
end
搜索表方法:
Table,(C1,L1) (C2,L2) … (Cn,Ln)(-,OtherL)
Search,用 E.Arg查 Table表并转向相应 Sj
转向表方法,
最小, 最大分支常数, MinC,MaxC;
Table,(JUMP,Li) 或 ( JUMP,OtherL)
Search,(LT,E.Arg,MinC,t1) (JUMP1,t1,OtherL)
(GT,E.Arg,MaxC,t2) (JUMP1,t2,OtherL)
(JUMPX,E.Arg,Table,MinC)
语法制导:
S ? case #StartCase E of #StartOptionList
OptionList
OtherOption
end #FinishCase
OptionList ? C #Choice:S;#FinishOption
OptionList
OptionList ?
OtherOption ?other:#StartOther S
#FinishOtherOption
过 /函声明的中间代码
形式:
Procedure P(FormDecList)
LabelDec
ConstDec
TypeDec
VarDec
ProDec1
……
ProDecn
Body
中间代码结构:
(Entry,Label,Size,Level)
ProDec1.tuple
……
ProDecn.tuple
Body.Tuple
(EndProc/EndFunc,-,-,-)
过程声明的例子
procedure Q( x,real );
var u, real ;
function f( k,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,0,1)
(CALL,Labelf,true,t1)
(ASSIG,t1,u)
(MULTR,u,x,t2)
(ASSIG,t2,y)
(ENDPROC,…… )