第八章中间代码生成2015(1)_第1页
第八章中间代码生成2015(1)_第2页
第八章中间代码生成2015(1)_第3页
第八章中间代码生成2015(1)_第4页
第八章中间代码生成2015(1)_第5页
已阅读5页,还剩64页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第八章第八章 中间代码生成中间代码生成中间代码的优点:便于移植,便于修改,便于优化,便于中间代码的优点:便于移植,便于修改,便于优化,便于目标代码生成。目标代码生成。中间代码生成阶段:在语义分析时产生中间代码。中间代码生成阶段:在语义分析时产生中间代码。语义分析的主要功能:语义分析的主要功能:(1)进行语义检查;)进行语义检查;(2)构造符号表(扫描声明部分时);(遇定义性标识)构造符号表(扫描声明部分时);(遇定义性标识符构造符号表;遇使用性标识符查符号表,取其属性)符构造符号表;遇使用性标识符查符号表,取其属性)(3)在扫描)在扫描语句语句部分时产生中间代码。部分时产生中间代码。18.1

2、中间代码中间代码8.1.1 中间代码的种类中间代码的种类按其结构分为下面几大类:按其结构分为下面几大类:(1)后缀式()后缀式(suffix)(2)三地址:三元式()三地址:三元式(Triple)、四元式()、四元式(Quadruple)(3)抽象语法树()抽象语法树(AST)Abstract Semantic Tree(4)无环有向图()无环有向图(DAG)8.1.2 后缀式中间代码后缀式中间代码适合于栈式机的一种中间代码,又称栈式中间代码适合于栈式机的一种中间代码,又称栈式中间代码前缀式前缀式12e ,ef2中缀中缀式式 a+b 后缀式的结构:后缀式的结构:ab+,Suffix(E)表达式

3、表达式 E 的后缀的后缀式,式,Suffix(a+b)=ab+ 后缀式定义:设后缀式定义:设 E 的后缀式记为的后缀式记为suffix(E),则,则() Suffix(E1 E2) = Suffix(E1) suffix(E2) () Suffix(E) = Suffix(E)() Suffix(x:=E) = Suffix(E) x :=() Suffix(x) = x, Suffix(c) = c, x为变量,为变量, c为常量。为常量。(v) Suffix(f(E1,E2,En) = Suffix(E1), Suffix(En) f例:例: (a+b*c)suffix(a+b*c)=ab

4、c*+3 suffix a:f a,h b,cdesuffix(a) suffix f a,h b,c*d+e:=a suffix f a,h b,cd e:a suffix f a,h b,cde:a suffix a suffix h b,cf de:a a b c h f de: 后缀式的优点后缀式的优点:(1)运算对象顺序不变,运算符按其优先级顺序排序)运算对象顺序不变,运算符按其优先级顺序排序(高在前)(高在前);(2)操作符紧跟在运算对象之后)操作符紧跟在运算对象之后;(3)无括号)无括号.suffix abc dabcd 4便于产生栈式机上的目标代码便于产生栈式机上的目标代码用栈

5、实现的算法:遇变量或常量压栈,用栈实现的算法:遇变量或常量压栈,遇运算符栈顶元素运算,出栈,并将结果压入栈。遇运算符栈顶元素运算,出栈,并将结果压入栈。abc dab d 计算:计算: 后缀式:后缀式:abcdabd c*d栈式机栈式机代码代码代码含义代码含义PUSH #ntoptop+1; S(top) n n:常数常数PUSH xtoptop+1; S(top) (x) x:变量变量ADDS(top 1)S(top 1)+S(top); top top 1SUBS(top 1)S(top 1) S(top); top top 1MULS(top 1)S(top 1)*S(top); top

6、 top 1MINUS(top) S(top)abcdabd 目标代码(机械生成)目标代码(机械生成):push a; push b; push c; push d; MUL; ADD; push a; SUB; MUL; push b; push d; MUL; ADD68.1.3 三地址中间代码三地址中间代码特点:两个操作数,一个操作码,一个结果值。特点:两个操作数,一个操作码,一个结果值。优点:便于目标代码生成。优点:便于目标代码生成。抽象形式:抽象形式:result:=Operand1 Op Operand2三地址代码实现:三元式,四元式,间接三元式。三地址代码实现:三元式,四元式,间

7、接三元式。(1)三元式)三元式一般形式:一般形式: (p) (op,arg1,arg2) p为三元式标号为三元式标号 相当于相当于 (p):=arg1 op arg2 结果存放在标号中结果存放在标号中 7设设tri(E)表示表示E的三元式序列,的三元式序列,last(E)表示表示E的最后一个三元式的最后一个三元式代号。代号。则则(i) tri(E1 E2)= tri(E1) tri(E2)(i)()( ,last(E1), last(E2)) (ii) tri(E)= tri(E) (iii) tri(a)=空空, last(a)=a, a为常量或变量。为常量或变量。三元式定义:三元式定义:2

8、tri abdd(1),b,d ,( ) ,a,(3) ,d(2)四元式)四元式一般形式一般形式 (+,a,b,T) T为临时变量。为临时变量。结果存在标号结果存在标号3中中8四元式定义:四元式定义:设Qua(E)为E的四元式序列,res(E)为E的结果变量。则 (i) (ii) (iii)T,Eres,Eres,EQuaEQuaEEQua21212111EQuaEQua 为常量或变量aaares空,aQua Qua ab,a,b,TTres ab ,: 11223Qua ab c/d,b,c,T , /,T ,d,T ,a,T ,Ta+b*c/d的结果变量是?的结果变量是?98.1.4 抽象

9、语法树(表达式) 树定义的树分别定义为则,为表达式的树,和分别为和设12121212121e,ee,eee,eeeTT表示RTLT,Etree2121T,T,Etree,T,T,Etree2e1e1e2e*1eLTRTXX:根;LT:左子树;RT:右子树10树结构一般形式定义:设树结构一般形式定义:设etree(E)为为E的树结构,的树结构,E为表达式为表达式 则则() () ()2121Eetree,Eetree,EtreeEEetree etreeEetree E 为常量或变量aa,aetree的树例baba:c etree c:a ba b:,etree c ,etree a ba be

10、tree cc, etree ababEtree,etree ab ,etree abetree abEtree,a,b 11为了实现为了实现 三地址代码,允许有不同个数的分量。三地址代码,允许有不同个数的分量。例:例: T1:=a*c T2:=float(b) a:=T5中间代码按其功能分为以下几类:中间代码按其功能分为以下几类:l算术运算,逻辑运算,关系运算代码;算术运算,逻辑运算,关系运算代码;l输入输入/输出;输出;l类型转换;类型转换;l变量地址代码;变量地址代码;l赋值代码;赋值代码;1(*, , ,)a c T2(, ,)float b T5(: , ) T a(READI ,

11、READF)(WRITEI , WRITEF)(FLOAT)(INDEX , FIELD , POINTER)(MOVE , MOVEA)8.1.5 多元式中间代码多元式中间代码12l标号标号 (LABEL)l转向代码;转向代码; (JUMP0-有条件转移有条件转移 JUMP无条件条件转移无条件条件转移)l返回返回代码代码 (RETURN)l函数起始和结尾代码;函数起始和结尾代码; (FUNCBEGIN,FUNCEND)l调用代码调用代码; (CALL)l实参代码实参代码( ADDRPARAM,VALUEPARAM,FUNCPARAM,PROCPARAM)1314例:例: read(A);re

12、ad(B);If AB then C:=A+5 else C:=B+5 ;write(2*(C-1);中间代码的抽象结构序列:中间代码的抽象结构序列:(READI , A)(READI , B) (GT,A, B,t1)(JUMP0,t1,L1)(ADDI,A,5,t2)(MOVE,t2,C)1.(JUMP,L2)(LABEL,L1)(ADDI,B,5,t3) (MOVE,t3,C)(LABEL, L2)(SUBI, C,1 ,t4)(MULI 2 t4,t5)8.(WRITEI,t5) (ADDI,a , b , t1) 操作域操作域ARG,不能是变量。,不能是变量。解决方案:解决方案: 1

13、.采用变量在符号表中的地址(采用变量在符号表中的地址(符号表地址法符号表地址法);); 2.把生成地址时所需要的信息封装后直接存把生成地址时所需要的信息封装后直接存 储在一个储在一个ARG中(中(逻辑地址法逻辑地址法)。)。主要讨论逻辑地址法(通过变量名和符号表生成主要讨论逻辑地址法(通过变量名和符号表生成ARG)。)。ARG结构:结构: 变量:变量: 函数函数/过程(形参):过程(形参): 函数函数/过程(实在):过程(实在):leveloffModeFormallevelOffActualLabel入口地址入口地址8.1.6 中间代码分量中间代码分量ARG结构结构15整数:整数:实数:实数

14、:标号:标号:变量的左值和右值。变量的左值和右值。左值:变量的单元地址;左值:变量的单元地址; 右值:变量单元的内容。右值:变量单元的内容。 (l , off) *(l , off) 间接变量:用来存放其它变量地址的变量称为间接变量。间接变量:用来存放其它变量地址的变量称为间接变量。引址形参变量引址形参变量存放实参变量地址;存放实参变量地址;间接临时变量间接临时变量存放复杂变量地址的临时变量(下标变量,域存放复杂变量地址的临时变量(下标变量,域名变量和指针变量)名变量和指针变量)表示:表示:Y (V)-存放变量存放变量V的地址,的地址,Y为间接变量。为间接变量。NRL16ARG的访问模式的访问

15、模式(Mode):确定是直接引用还是间接引用(确定是直接引用还是间接引用(dir/indir)。)。作用:作用: 目标代码生成期间,在目标代码生成变量的目标代码地址目标代码生成期间,在目标代码生成变量的目标代码地址时,时,用来确定产生直接地址还是间接地址。用来确定产生直接地址还是间接地址。ARG的数据结构的数据结构Struct ARGenum kind ARGkind; union int LabelARG int IntARG; float RealArg; struct LogicAddr VarARG; struct RoutInform FuncARG; struct RoutInFo

16、rm ProcARG;ARGBoby; 17Enum kind LabelKind, IntKind , RealKind , VarKind , FuncKind , ProcKind LabelARG , IntARG , RealArg, VarARG , FuncARG, ProcARG ARGkindARGBobyARG的数据结构的数据结构:18例:形参x和y, x:引值形参, y:引址形参。ARG(x)=varkind( Levelx , offsetx ,dir) VARG(x)=(VarKind, Levelx, offsetx, dir) /宏表示ARG(Y)=varkind

17、( Levely , offsety , indir) VARG(y) =(VarKind , Levely , offsety , indir) /宏表示遇到(ADD , ARG(x) , ARG(y) ,TARG(T)时根据offset和 Mode生成如下间接地址的目标代码。 LOAD sp, R -offsetx xR ADD *sp, R -offsety (*y)+RR19ARG宏表示:(为方便书写,遇到标号,变量,常量时宏表示:(为方便书写,遇到标号,变量,常量时,在中间代在中间代码的相应码的相应ARG位置上生成其逻辑地址。)位置上生成其逻辑地址。)LARG(L)=(LabelKi

18、nd , L)IARG(N)=(IntKind , N)RARG(R)=(RealKind , R)VARG(x)=(VarKind , levelx , offx, Modex)TARG(T, mode)= (VarKind , 1, T, mode)FARG(f)=(FuncKind , Actual , Lf , size)FARG(F)=(FuncKind, Formal, levelF, OffF)临时变量临时变量208.2 表达式的中间代码生成表达式的中间代码生成E.Type:表达式:表达式 E 的类型;的类型;E. Code: 表达式表达式 E 的中间代码;的中间代码;E.Arg

19、:表达式:表达式 E 结果的结果的ARG。假设假设a,b,c整型;整型;E.Type=integer;E. Code=(*,b,c, T1) (+,a, T1 ,T2)E.Arg=TARG(T2,dir) =(varkind, 1, T2 ,dir)8.2.1 表达式的语义信息表达式的语义信息E=a+b*cT1:=b*c;T2:=a+T121表达式的类型表达式的类型E.Type EN ; E.type=integer; E R ; E.type=real; EV ; E.type=V.type; E f() ; E.type=type_of(f); E E1E2; E.type=Type of

20、 sult(E1E2 )E.arg E N ; E.arg=IARG(N) E R ; E.arg=RARG(N) E V ; E.arg=V.arg E F(); E.arg=TARG(T1,dir) E E1E2; E.arg=TARG(T2)228.2.2 表达式中间代码 E.codeE E1E2; E.type=type_of(, E1.arg,E2.arg) E.code=E1.code|E2.code|(, E1.arg,E2.arg,E.arg) E.arg=TARG(newtemp,dir)E (E1) E.type=E1.type E.code=E1.code E.arg=E

21、1.arg23E N E.type=int E.code=空 E.arg=IARG(N)E V ; E.type=V.type E.code=V.code E.arg=V.argE f(EL); E.type=type_of(f) E.arg=TARG(T,dir)24E.code?例:a*b+c*d的中间代码E=a*b+c*dE.code=(a*b).code | (c*d).code | (+,(a*b).arg,(c*d).arg,T3.arg)=(*,VARG(a),VARG(b),TARG(T1,dir) (*,VARG(c),VARG(d),TARG(T2,dir) (+,TARG

22、(T1,dir),TARG(T2,dir),TARG(T3,dir)E.Type=T3.type;E.Arg= TARG(T3,dir)25类型转换类型转换 (FLOAT,VARG(J),TAGR(T1,dir) float(J)T1例:例:E A*(3.5+J*B) A,B:实型实型 J:整型:整型E.code= (FLOAT,VARG(J),TAGR(T1,dir) (MULTF,TAGR(T1,dir),VARG(B),TARG(T2,dir) (ADDF,RAGR(3.5),TARG(T2,dir),TARG(T3,dir) (MULTF,VAGR(A),TARG(T3,dir),TA

23、RG(T4,dir)E.type=realE.arg=TARG(T4,dir)8.2.3 表达式的中间代码生成表达式的中间代码生成26原理分析:只有遇到运算符时才生成中间代码。原理分析:只有遇到运算符时才生成中间代码。语义栈:存储常量、变量的信息。语义栈:存储常量、变量的信息。SemStack :当遇到常量当遇到常量N时,将时,将 压栈压栈 常量常量R时,将时,将 压栈压栈 变量变量x时,将时,将 压栈压栈 E+T时,时, top top-1 top(ADD,E.arg,T.arg,TARG(T ) E.typeE.argrealPtrRARG(R)intPtrIARG(N)T.typeT.a

24、rgtype(x) VARG(x)type(x) VARG(x)T.typeT.arg27代码生成算法代码生成算法(6) PV空(1) ET空(2)GenCode( )EET(3) TP空(5) (,(.)Pnpush intType NARG token seman(4)*GenCode(*)TTP(7)() PE(8)()Pid EL28语义子程序语义子程序例:例:x+y*z+10中间代码生成过程。中间代码生成过程。vx+y*z+10 的语法树 v语法分析过程: EE TE TT* PTPVVPPnV移进*z+10#E+T归约*z+10#E+P(V)(int,arg(y)归约归约*z+10

25、#E+y移进y*z+10#E+移进+y*z+10#E归约+y*z+10#T归约+y*z+10#P(V)(int,arg(x)归约归约+y*z+10#x移进x+y*z+10#中间代码中间代码语义栈语义栈动作动作输入流输入流符号栈符号栈29xyzok#E(ADDI,arg(T2),arg(n),Targ(T3)归约归约#E+T归约#E+P归约归约#E+10移进10#E+移进+10#E(ADDI,arg(x),arg(T1),Targ(T2)归约归约+10#E+T(MULI,arg(y),arg(z),Targ(T1)(int,arg(z)归约归约+10#E+T*P(V)归约归约+10#E+T*z中

26、间代码语义栈动作输入流符号栈移进*z+10#E+T移进z+10#E+T*P*T+E(int,arg(x)(int,arg(y)(int,arg(z)(int,arg(n)30EE TE TT* PPnVz(int,Targ(T1)(int,Targ(T2)(int,arg(x)(int,arg(y)(int,Targ(T3)8.2.4 变量的中间代码变量的中间代码文法:文法:主要任务:计算变量的地址。主要任务:计算变量的地址。l变量的目标代码是计算出的变量空间的首地址,并赋给一变量的目标代码是计算出的变量空间的首地址,并赋给一个临时变量(个临时变量(间接临时变量间接临时变量)。)。Addr(V

27、):表示表示V的首地址。假设首地址可计算。的首地址。假设首地址可计算。off(V ,u):表示):表示u域关于域关于V 记录空间的偏移量;记录空间的偏移量;low表示数组变量表示数组变量V 的下标的下界;的下标的下界;CSize表示数组变量表示数组变量V 的的元素元素的空间大小。的空间大小。|.|*Vid V EV idV不同变量地址的计算:不同变量地址的计算: Vx addr(V)=addr(x)VV.id addr(V)=addr(V)+off(V,id)VVi addr(V)=addr(V)+(i-low)*CSize1.V *V addr(V)=content(addr(V)31变量的

28、中间代码变量的中间代码(1) Vid V.code=空空 V.arg=id /VARG(id)=(varkind,l,off,dir) V.type=type_of(id) (2) VVE V.type=elemtype_of(V) V.arg=TARG(newtemp,indir) V.code=(INDEX,V.arg,TARG(T2),V.arg)(*, TARG(T1), CSize,TARG(T2)( ,E.arg,low,TARG(T1)E.codeV.codeTARG(T3, indir)32(3) VV.u V.type=fieldtype_of(V,u) V.arg=TARG

29、(newtemp,indir) V.code=(4) V=*V V.type=basetype_of(V) V.arg=TARG(newtemp,indir) V.code= V.code(FIELD,V.arg,off(u),V.arg)V.code(POINT,V.arg,V.arg)变量的中间代码变量的中间代码33例:中间代码示例1计算aij的地址 说明 (1)省略了ARG; (2) 间接访问, 直接访问。a:array1.5 of array1.10of integer;(SUBI , i , 1 ,T1 )(MULTI,T1,10,T2) (INDEX,a, T2, T3*)(SUB

30、I , j , 1 , T4)(MULTI,T4,1,T5)(INDEX, T3*, T5, T6*) *iT中间代码示例2Var a:array1.10 of record i:integer; b:boolean enda2.b的中间代码如下:(SUBI , 2 , 1 ,T1 )(MULTI,T1,2,T2) (INDEX,a, T2, T3*)(FIELD, T3*, 1, T4*)iT34一维数组元素的长度存放变量存放变量ai 和和aij的地的地址是那几个变量址是那几个变量?存放变量存放变量ai的地址的地址存放变量存放变量aij的地址的地址文法:文法:标准变量情形:标准变量情形: F

31、indEntry(token.Seman,Entry,isdef) (tp,L,off,mode)=(SymbTableEntry.type/level/off/mode) PUSH(tp,(Varkind,L,off,mode) /VARG(id) (type,arg)=SemStacktop; (type1,off)=FieldOffset(type,token.seman) T=newtemp(); SendCode(FIELD,arg(V),IARG(off),TARG(T,indir) /中间代码中间代码 POP(1); PUSH(type1,TARG(T, indir); /结果压

32、入语义栈结果压入语义栈 Top 语义栈语义栈SemStack8.2.5 变量的中间代码生成(语法制导生成)变量的中间代码生成(语法制导生成)|.|*Vid V E V idVVid.VV idtype(V)arg(V)id35 Top 语义栈SemStack下标变量:下标变量: (type1,arg1)=SemStacktop 1; (type2,arg2)=SemStacktop; low:=*type1.low; SIZE:=*type1. ElemType.Size; /元素的长度元素的长度ResultType=*type1.ElemType;T1:=newTemp(); T2:=new

33、Temp();SendCode(SUBI,arg2,IARG(low),TARG(T1, dir)SendCode(MULI,TARG(T1,dir),IARG(SIZE),TARG(T2, dir)T3=newtemp();SendCode(INDEX,arg1,TARG(T2,dir),TARG(T3, indir)Pop(2);PUSH(ResultType,TARG(T3,indir) 注:注:PUSH,POP对语义栈的操作;对语义栈的操作;SendCode():生成中间代码。():生成中间代码。VVETop-1Type(V) Arg(V) TopType(E)Arg(E)存放存放E的

34、结果的结果存放存放V的地址的地址TopType(VE)VE地址地址36语义栈语义栈 TopType(VE)Arg(VE)v例:例: Type string=array1.10 of char; Var a:record name:string; tele: string; age:integer endBegin a.age:=20; end.扫描说明部分建立符号表和类型表。扫描说明部分建立符号表和类型表。类型表类型表:类型定义参见TYPEIR(P159) strPtr10arrayTy110charPtr recPtr21recordTyelemPtr elemPtr namestrPtr0

35、telestrPtr10ageintPtr20string strPtrtypekind10a recPtrvarkinddirlevelaoffa符号表:符号表:37a.age 的中间代码生成过程的中间代码生成过程v语义栈(SemStack)内容(type,arg)=SemStacktop; /(type,arg)=(recPtr,(varkind,levela,offa,dir)(type1,off)=FieldOffset(type,token.seman); /(type1,off)=(intPtr,20)T=newtemp(); SendCode(FIELD,arg,IARG(off

36、),TARG(T,indir)/中间代码中间代码 (FIELD,arg,20, TARG(T,indir )POP(1); PUSH(type1,TARG(T,indir);topvarkindlevelaoffadirargtopintPtrvarkind1Tindirage注:注:PUSH,POP对语义栈的操作;对语义栈的操作;SendCode( ):生成中间代码。生成中间代码。385 的中间代码生成过程v语义栈(SemStack)内容(type,arg)=SemStacktop; /(type,arg)=(recPtr,(varkind,levela,offa,dir)(ty

37、pe1,off)=FieldOffset(type,token.seman); /(type1,off)=(stPtr,0)T=newtemp(); SendCode(FIELD,arg,IARG(off),TARG(T,indir)/中间代码中间代码 (FIELD,arg,0, TARG(T,indir )POP(1); PUSH(type1,TARG(T,indir);topvarkindlevelaoffadirargtopstPtrvarkind1Tindirname注:注:PUSH,POP对语义栈的操作;对语义栈的操作;SendCode():生成中间代码。生成中间代码。的

38、中间代码生成过程39Varg(a)的地址的地址下标变量:下标变量: (type1,arg1)=SemStacktop 1=(stPtr,varKind, 1,T,indir); (type2,arg2)=SemStacktop=(intPtr,intKind,5); low:=*type1.low=1; SIZE:=*type1.ElemType.Size=1; /Size为数组元素长度为数组元素长度ResultType=*type1.ElemType=charP5 的中间代码生成过程v语义栈(SemStack)内容TopintPtrintKind5Top-1 st

39、Ptrvarkind1Tindirargname40下标变量:下标变量:T1:=newTemp(); T2:=newTemp();SendCode(SUBI,arg2,IARG(low),TARG(T1, dir)/(SUBI,5,1,TARG(T1, dir)SendCode(MULI,TARG(T1),IARG(SIZE),TARG(T2, dir)/(MULI,TARG(T1),1,TARG(T2, dir)T3=newtemp();SendCode(INDEX,arg1,TARG(T2),TARG(T3, indir)/(INDEX,arg1,TARG(T2),TARG(T3, ind

40、ir)Pop(2);PUSH(ResultType,TARG(T3,indir) 注:注:PUSH,POP对语义栈的操作;对语义栈的操作;SendCode():生成中间代码。:生成中间代码。topcharPtrvarkind1T3 indir41chara.age 的中间代码的中间代码(FIELD, a , 20, TARG(T, indir)5的中间代码的中间代码(FIELD,a,0,TARG(T,indir) /T中存放中存放的地址的地址(SUBI,5,1,TARG(T1, dir)(MULI,TARG(T1),1,TARG(T2, dir)(INDEX,TARG(

41、T,indir),TARG(T2,dir),TARG(T3, indir)428.3 原子语句的中间代码生成原子语句的中间代码生成8.3.1 输入输入/ 输出语句的中间代码生成输出语句的中间代码生成8.3.2 goto语句的中间代码生成语句的中间代码生成8.3.3 return语句的中间代码生成语句的中间代码生成8.3.4 赋值语句中间代码生成赋值语句中间代码生成8.3.5 函数(过程)调用的中间代码生成函数(过程)调用的中间代码生成主要讲:主要讲: 8.3.4 赋值语句中间代码生成赋值语句中间代码生成 8.3.5 函数(过程)调用的中间代码生成函数(过程)调用的中间代码生成43如 c:=a+

42、b 将:=看成运算符,其优先级最低Suffix(c:=a+b)=c a b+:=多元式: 1. (ADDI,a,b,T1) 2. (:=, T1,c)三元式: 1. (ADDI,a,b) 2. (:=, ,c)V:=E(当V是简单变量x时) E.arg:=value(E); x:= E.arg; (当V是复合变量x时) V.arg:=addr(V);E.arg:=value(E);V.arg:=E.arg;说明:当V为简单变量时。V.code=空; V.arg=x;8.3.4 赋值语句中间代码生成赋值语句中间代码生成 44中间代码生成算法:SV:=E(typeL,argL)=SemStackt

43、op1; (typeR,argR)=SemStacktop;If(typeL!=typeR & typeL=realType)SendCode(FLOAT,argR,T1); SendCode(MOVE,T1,argL);else SendCode(MOVE, argR, argL);pop(2) TopType(E)Arg(E)Top1Type(V)Arg(V)45语义栈语义栈例:例: 赋值语句中间代码生成赋值语句中间代码生成Type string=array1.10 of char; Var a:record name:string; tele: string; age:integ

44、er endBegin a.age:=20; end.(FIELD, a , 20, TARG(T, indir)(MOV,IARG(20),TARG(T,indir)468.3.5 函数(过程)调用的中间代码函数(过程)调用的中间代码生成生成函数调用结构 id(E1,E2,En)1 id是函数名?2 实参Ei和形参Xi是否匹配?3 实参个数和形参个数是否相同?1 id的种类和类型kind,type。2 形参信息表的开始地址FirstParam。3 形参个数Num4 函数声明中间代码的启动标号:StartLabel(处理声明时填写标号)5 函数的活动记录大小:Size。6 函数的层数:Leve

45、l。从符号表获得的信息语义错误检查47形式调用与实在调用若函数调用f(E1,E2,En)中的f为实在函数名,则称为实在调用实在调用;若f为形参函数名,则称其为形式调用形式调用。形式调用与实在调用的区别形式调用形式调用实在调用实在调用函数体无有形实结合动态静态实参种类不知道知道48假设有如下函数声明:function f(G:func): int return(G(1)+G(2); /G(1),G(2)为形式调用function g(y:int): int return(y+20);function u(z:int): int return(z+30);function h(x:int): in

46、t return(f(g)+f(u)+x);调用语句:h(10) 结果:11649函数调用的三个阶段:1计算实参;2 传递实参;3 转向函数体代码。函数调用 f(E1, E2): X1,X2为F的形参计算E1.codeE2.codeT1:=a+bT2:=c+d传递X1 E1.argX2E2.argX1:=T1X2:=T2转移Tcall(f)t:=call(f)函数调用代码分解图50例: z:=f(u(E1,E2), h(E3, E4)调用顺序:uhf1t1:=E1; 6t3:=E3; 11Xf:=Ru2 t2:=E2 7t4:=E4; 12Yf:=Rh3 Xu:=t1 8Xh:=t3 13Rf

47、:=CALL(f)4 Yu:=t2 9Yh:=t4 14z:=Rf5 Ru:=CALL(u) 10Rh:=CALL(h)计算和调用顺序:1计算实参从左到右进行;2 函数体的调用从里向外。51Xu,Yu为函数u的形参, Xh,Yh为函数h的形参, Xf,Yf为函数f的形参,8.4 8.4 结构语句中间代码结构语句中间代码生成生成8.4.1 条件语句的中间代码生成条件语句的中间代码生成 Sif E then S1 else S2 Sif E then S1v条件语句中间代码结构条件语句中间代码结构 (JUMP0,E.arg,ElseL) (JUMP,OutL) (LABEL,ElseL) (LAB

48、EL,OutL)E.CodeS1.CodeS2.Code (JUMP0,E.arg,OutL)(LABEL,OutL)E.CodeS1.Code52例:例: if x0 then if y0 then if y0 then if yif E then M S sendCode(LABEL,LSq.outL);POPLS(1);S-if E then M1 S else M2 S sendCode(LABEL,LSq.outL);POPLS(1)M- PUSHLS(-,NewLabel),LS); /OutL压栈SendCode(JUMP0,SemStacktop.arg,LSq.outL);P

49、OP(1);M1- PUSHLS(NewLabel,NewLabel),LS); /ElseL,OutL压栈 SendCode(JUMP0,SemStacktop.arg,LSq.ElseL); POP(1);M2- SendCode(JUMP, LSq.OutL); SendCode(LABEL, LSq.ElseL); 5711SIfthen SSIfelse SIfthenif E thenIfelseIfthen S elseIfthenif E ThenThenthen条件语句中间代码生成算法 SIfthen SSendCode(LABEL,LSq.OutL) ;popLs(1)SI

50、felse SSendCode(LABEL,LSq.OutL);popLs(2);Ifthen if E thenpushLS(_,NewLabel),LS);SendCode(JUMP0,SemStacktop.arg.LSq.OUTL);pop(1) Ifthen1 if E Then /空空 Then thenPushLS(newLabel1,NewLabel),LS);/ElseL和和OutL 压栈压栈SendCode(JUMP0, SemStacktop.arg, LSq.ElseL);pop(1)/表达式信息退栈表达式信息退栈SwmStack.5859IfelseIfthen1 S

51、 elseSendCode(JUMP, LSq.OutL);SendCode(LABEL, LSq.ElseL);标号栈标号栈 LS(LabelStack). 二元组分别是二元组分别是ElseL 和和OutL 标号标号.LSq.ElseL LSq.OutL 栈顶栈顶NewLabel:每调用一次产生一个新的标号。:每调用一次产生一个新的标号。例:例: if E then M1 S else M2 S2M1:-生成标号(一对),生成一个生成标号(一对),生成一个JUMP0中间代码。中间代码。M2:-生成生成JUMP中间代码,生成标号中间代码,生成标号ElseL。本章使用本章使用LR(1)分析方法。分析方法。 LR(1)是移进是移进归约方法(自底向上的归约方法(自底向上的方法)。方法)。60注意:采用语法分析方法LR方法 采用目标结构多元式 语义栈 SEMS 文法变换方法 例: SA将其分成两部分 SA12 1,2 产生相应动作。变换的方法(两种) (i) SAS1 S2 先执行动作2,后执行动作1 (ii) SS 2 SA1 先执行动作1,后执行动作261SendCode LABEL,LSq.OUTL ; POPLS(1)SendCode JUMP,lsq.OutL ;SendCode LABEL,lsq.ElseL ;PUSHLS(NewLabel,NewLab

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论