190 likes | 409 Views
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 V ptr :=V 1 ptr f:=E V str :=V 1 str 赋值语句的中间代码形式: ( ASSIG,Arg1,Arg2,n)
E N D
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:= RL.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 空 SGOTO Li(JUMP, ARG(Li) ) SLi:S ( LABEL,ARG(Li) ) S.tuple
结构语句的中间代码 • 条件语句的中间代码 • While语句的中间代码 • Repeat语句的中间代码 • For语句的中间代码 • Case语句的中间代码
S IFETHEN S1 E.Tuple (JUMP0,E.Arg,S.OutL) S1.Tuple (LABEL,S.OutL) 条件语句的中间代码 IFETHENS1ELSES2 E.Tuple (JUMP0,E.Arg,S.ElseL) S1.Tuple (JUMP,S.OutL) (LABEL,S.ElseL) S2.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 WHILEEDOS1 (LABEL,S.StartL) E.Tuple (JUMP0,E.Arg,S.OutL) S1.Tuple (JUMP,S.StartL) (LABEL,S.OutL)
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 repeatS1untilE (LABEL, S.StartL) S1.Tuple E.Tuple (JUMP0, E.Arg,S.StartL)
Repeat语句代码生成的LL文法 S →repeat#StartRepeat S1do E #FinishRepeat #StartRepeat :PUSH(S.StartL) Generate(LABEL, Sem[top].Arg ) #FinishRepeat: Generate(JUMP0,Sem[top].Arg, Sem[top-1].Arg) POP(2)
For语句的中间代码 forV:=E1toE2doS1 forV:=E1downtoE2doS1 E1.Tuple E2.Tuple E1.Tuple E2.Tuple (GT,E1.Arg, E2.Arg,t1) (JUMP1, t1, S.OutL) (ASSIG, E1.Arg, V.Arg) (LT,E1.Arg, E2.Arg,t1) (JUMP1, t1, S.OutL) (ASSIG, E1.Arg, V.Arg) (LABEL, S.LoopL) (LABEL, S.LoopL) S1.Tuple S1.Tuple (ADDI, V.Arg, 1, t2) (ASSIG, t2, V.Arg) (GT,V.Arg, E2.Arg, t3) (JUMP0, t3, S.LoopL) (SUBI, V.Arg, 1, t2) (ASSIG, t2, V.Arg) (LT,V.Arg, E2.Arg, t3) (JUMP0, t3, S.LoopL) (LABEL, S.OutL) (LABEL, S.OutL)
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) caseEof 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
过/函声明的中间代码 中间代码结构: (Entry,Label,Size,Level) ProDec1.tuple …… ProDecn.tuple Body.Tuple (EndProc/EndFunc,-,-,-) 形式: Procedure P(FormDecList) LabelDec ConstDec TypeDec VarDec ProDec1 …… ProDecn Body
过程声明的例子 (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, ……) procedure Q( x: real ); var u : real ; function f( k: real ); begin f := k +k end; begin u := f(50); y:= u * x end;