语法制导翻译技术和中间代码生成.ppt

上传人:牧羊曲112 文档编号:5841064 上传时间:2023-08-26 格式:PPT 页数:80 大小:440KB
返回 下载 相关 举报
语法制导翻译技术和中间代码生成.ppt_第1页
第1页 / 共80页
语法制导翻译技术和中间代码生成.ppt_第2页
第2页 / 共80页
语法制导翻译技术和中间代码生成.ppt_第3页
第3页 / 共80页
语法制导翻译技术和中间代码生成.ppt_第4页
第4页 / 共80页
语法制导翻译技术和中间代码生成.ppt_第5页
第5页 / 共80页
点击查看更多>>
资源描述

《语法制导翻译技术和中间代码生成.ppt》由会员分享,可在线阅读,更多相关《语法制导翻译技术和中间代码生成.ppt(80页珍藏版)》请在三一办公上搜索。

1、S.P,O.P,第5章语法制导翻译技术和中间代码生成,要求明确语义分析的任务明确属性文法和语法制导翻译的含义明确自底向上和自顶向下语法制导翻译的区别和特点明确生成中间代码的目的,中间代码的几种形式,教学目标,属性文法语法制导翻译法的基本思想常见的中间代码各种不同语法结构的语法制导翻译技术,教学内容,词法分析,语法分析:解决单词和语言成分的识别及词法和语法结构的检查。语法结构可形式化地用一组产生式来描述。给定一组产生式,我们能够很容易地将其分析器构造出来。本章要介绍的是语义分析和中间代码生成技术。程序语言中间代码目标代码,翻译,翻译,根据语义规则对识别出的各种语法成分析其含义,进行初步翻译,生成

2、相应的中间代码或直接生成目标代码。,第一,审查每个语法结构的静态语义,即检查语法结构合法的程序是否真正有意义。也称静态语义检查。(类型检查、控制流的检查、一致性检查、相关名字的检查)第二,如果静态语义正确,语义处理则要执行真正的翻译,要么生成中间代码,要么生成实际的目标代码。(说明性语句:填符号表;可执行性语句:生成中间代码),语义分析的任务,类型检查。控制流检查,确保控制语句有合法的转向点。例如,C语言中的break语句使控制跳离包括该语句的最小的switch,while或for语句。如果不存在包括它的这样的语句,则应报错。,静态语义检查,静态语义检查,一致性检查。很多情况下要求对象只能被定

3、义一次。例如,语言中规定一个标识符在同一作用域中只能被说明一次,同一case语句的标号不能相同,枚举类型的元素不能重复出现等。相关名字检查。有的语言中有时规定,同一名字必须出现两次或多次。例如,Ada语言中,循环或程序块可以有一个名字,它出现在这些结构的开头和结尾,如同语句括号一般,编译程序必须检查它们的配对情况。,附加了一组属性和运算(语义)规则的文法,5.2 属性文法,文法符号X的属性t常用X.t来表示,语义规则是根据产生式所蕴涵的语义操作建立起来的,并与语义分析的目标有关不同的产生式对应不同的语义规则不同的分析目标也对应不同的语义规则,静态语义检查、符号表操作、代码生成及打印各种错误信息

4、,属性文法,属性文法的形式定义:AG:AG=(G,V,E)G:上下文无关文法;V:属性的有穷集合;每一个属性与某一个文法符号相关联;用文法符号属性表示E:表示属性的断言或谓词的有穷集合(语义规则);每一个断言与文法的某个产生式相关联)属性:综合属性(自下而上传递信息)、继承属性(自上而下传递信息),非终结符E、T及F都有一个综合属性val,符号i有一个综合属性。某些非终结符加下标是为了区分一个产生式中同一非终结符多次出现,例5.1,语法制导翻译的过程,语法制导翻译:将语义规则与语法规则相结合,在语法分析的过程中通过执行语义动作,计算语义属性值,从而完成预定的翻译工作。,语法制导翻译分为两种处理

5、方法:(1)自底向上语法制导翻译:对每个产生式编制一个语义子程序,在进行语法分析的过程中,当一个产生式获得匹配时,就调用相应的语义子程序实现语义检查与翻译。这种实现方案隐藏了其中语义规则的计算次序等实现细节,不必规定翻译顺序。(2)自顶向下语法制导翻译:在产生式右部的适当位置,插入相应的语义动作,按照分析的进程,执行遇到的语义动作。这是一种动作与分析交错的实现方案。,语法制导定义,对每个产生式编制一个语义子程序在进行语法分析的过程中,当一个产生式获得匹配时,就调用相应的语义子程序实现语义检查与翻译,自底向上传递信息,自顶向下(自左向右)传递信息,属性翻译文法的应用,综合属性与自下而上定值 每个

6、非终结符的属性值都是根据位于其下面那些符号的属性值来确定的,即按一种自下而上的方式来确定的。继承属性和自上而下定值 非终结符的属性值或者根据其上层非终结符的属性来确定或者根据产生式右部其它符号的属性来确定。这种属性值是根据自上而下方式确定的。,print(E.val)打印由E产生的算术表达式的值,可认为这条规则定义了L的一个虚属性。,L E,E E1+T,E T,T T1*F,T F,F(E),F i,print(E.val),E.val=E1.val+T.val,E.val=T.val,T.val=T1.val F.val,T.val=F.val,F.val=E.val,F.val=i.le

7、xval,例5.综合属性,语 义 规 则,产生式,一个结点的综合属性值是其子结点的某些属性来决定的,+3*4的注释分析树,通常使用自底向上的分析方法在每个结点处使用语义规则来计算综合属性值当一个产生式获得匹配时,就调用相应的语义子程序从叶结点到根结点进行计算,只含有综合属性的语法制导定义称为S属性定义,S属性定义与自底向上翻译,LR分析器可以改造为一个翻译器,在对输入串进行语法分析的同时对属性进行计算LR分析器增加属性值(语义)栈,1)为文法的每条规则设计相应的语义子程序;2)增加一个语义信息栈;3)在语法分析的同时做语义处理:即在用某一个产生式进行规约的同时,调用相应的语义子程序完成所用规则

8、的语义动作,并将每次动作后的值保存在语义栈中,翻译步骤,计算表达式2+3*5,GE:1 EE+T2 ET3 TT*F4 TF5 F(E)6 Fi,i+i*i,表达式2+3*5的归约过程,注意,句柄归约在先,语义动作调用在后归约时,栈内句柄各符号的语义信息与句柄及同时出栈,整个句柄所表示的语义信息则赋给相应产生式左部非终结符号的语义变量,并让该非终结符号及语义信息同时入栈,生成中间代码的目的(1)便于优化(2)便于移植(3)逻辑结构清晰,常见的中间代码形式:后缀式三地址代码(四元式、三元式和间接三元式)图形(抽象语法树、有向无环图),中间代码:一种介于源语言和目标语言之间的中间语言形式,5.中间

9、代码,中缀表示后缀表示a+b ab+a+b*c abc*+(a+b)*c ab+c*a:=b*c+b*d abc*bd*+:=,特点,1、运算对象出现的顺序和原有顺序(从左到右)相同2、运算符按实际计算顺序(从左到右)出现3、运算符紧跟在运算对象的后面出现,且没有括号,优点:简明、便于计值,后缀式,分别给出下列表达式的后缀表示,1.-a+b*(-c+d)2.X:=-(a+b)/(c-d)-(a+b*c)3.a=c b=d4.ab+c ada+be,逆波兰表示法(后缀式),特点:运算符直接写在其运算对象之后。不再有括号运算对象出现的次序未变求值过程简单,宜于用栈实现,后缀式的计算用一个栈实现。一

10、般的计算过程是:自左至右扫描后缀式,每碰到运算量就把它推进栈。每碰到k目运算符就把它作用于栈顶的k个项,并用运算结果代替这k个项。,三地址代码,种类,(1)x=y op z形式的赋值语句,其中op是二元运算符。(2)x=op y形式的赋值语句,其中op是一元运算符。(3)x=y形式的赋值语句。(4)无条件转移语句goto L,表示下一个要执行的语句是标号为L的语句。(5)条件转移语句if x rop y goto L中,rop为关系运算符,如果x和y满足关系rop,就转而执行标号为L的语句,否则顺序执行下一个语句。,(6)过程调用语句param x 和call p,n。源程序中的过程调用语句p

11、(x1,x2,xn)可以产生如下的三地址代码:param x1param x2 param xncall p,n其中n为实参个数。过程返回语句形如return y,其中y为过程返回的一个值。,(7)变址赋值:x=yi,把从y开始的第i个存储单元的值赋给x。xi=y,把y的值赋给x开始的第i个存储单元。其中,x,y和i都代表数据对象。(8)地址和指针赋值:x=&y,把y的地址赋给x。x=y,把y指示的地址单元中的内容赋给x。x=y,把x指向的存储单元的值置为y。,2具体实现,四元式,结果:通常是由编译引进的临时变量,例:X=(A+B)*(C+D)-E,T1,T2,T3,T4为临时变量,由四元式优

12、化比较方便,表达式的三元式:,第三个三元式中的操作数(1)(2)表示第(1)和第(2)条三元式的计算结果。,三元式,不便于代码优化:删除某些三元式后可能需作一系列的修改,图形表示法,无循环有向图(Directed Acyclic Graph,简称DAG)对表达式中的每个子表达式,DAG中都有一个结点一个内部结点代表一个操作符,它的孩子代表操作数在一个DAG中代表公共子表达式的结点具有多个父结点,例:x=y+yz+yz,抽象语法树,图形表示,有向无环图,练习:1.表达式a+(-b)*c的三元式,(1)(,b,_);单目运算,运算对象2为空(2)(*,(1),c)(3)(+,a,(2),三元式,X

13、=a+b*c Y=d-b*c,三元式表(1)(*,b,c)(2)(+,a,(1)(3)(=,x,(2)(4)(_,d,(1)(5)(=,y,(4),2.四元式(三地址代码),X=a*b+c*d的四元式序列 三地址代码(1)(*,a,b,T1)(1)T1=a*b(2)(*,c,d,T2)(2)T2=c*d(3)(+,T1,T2,T3)(3)T3=T1+T2(4)(=,T3,_,X)(4)X=T3,2023年8月26日,编 译 原 理,3.a:=b*(-c)+b*(-c)的图表示法,2023年8月26日,编 译 原 理,抽象语法树对应的代码:T1:=-c T2:=b*T1T3:=-c T4:=b*

14、T3 T5:=T2+T4 a:=T5,a:=b*(-c)+b*(-c)的图表示法,2023年8月26日,编 译 原 理,DAG对应的代码:T1:=-cT2:=b*T1T5:=T2+T2a:=T5,抽象语法树对应的代码:T1:=-c T2:=b*T1T3:=-c T4:=b*T3 T5:=T2+T4 a:=T5,自底向上的语法制导翻译,自底向上的语法制导翻译方法是在自底向上的语法分析过程中逐步实现语义规则的翻译方法。在实现时注意以下几点:(1)自底向上的翻译的特点,栈的操作,对产生式的要求等(2)各种程序语句的目标结构(3)从源结构到目标结构的变换方法(包括对产生式的改造等),算术表达式和赋值语

15、句的翻译,翻译步骤:(1)分析文法的特点;(2)设计一系列的语义变量、定义语义过程、语义函数;(3)设计每一条规则的语义子程序;(4)增加一个语义信息栈,构造LR分析表;(5)语法分析同时语义处理.,例:有文法GA:1.Ai:=E2.E E+TT3.T T*FF4.F P5.P i(E)简单算术表达式的计值顺序与四元式出现的顺序相同,因此目标代码的顺序(结构)为:(1)先生成E的代码(一系列顺序执行的四元式)(2)把E的值赋给变量i(表达式的结果赋给赋值语句的左变量),引入语义变量,语义过程和语义函数(1)语义变量E.place:表示存放E值的变量名在符号表中的入口地址或临时变量的整数码.(2

16、)语义函数newtemp():申请一个临时单元,存放中间结果;(3)语义过程emit(T=arg1 op arg2):产生一条四元式,并添入四元式表中;(4)语义过程lookup(i.name):审查i.name是否出现在符号表中,在:返回地址,不在:返回NULL;(5)语义函数entry(i):回送标识符i在符号表中的入口地址.,表达式的语义动作设计,1.Ai:=E emit(entry(i)=E.place2.E E1+T E.place=newtemp(),emit(E.place)=E1.place+T.place3.E T E.place=newtemp(),emit(E.place

17、=T.place)4.T T1*F T.place=newtemp(),emit(T.place)=T1.place*F.place5.T F T.place=newtemp(),emit(T.place=F.place),6.F _P F.place=newtemp(),emit(F.place)=P.place7.P(E)P.place=newtemp(),emit(P.place=E.place)8.P I P.place=newtemp(),emit(P.place=Entry(i),例如:表达式X:=a+b*(c-d)的翻译,K+1:T1:=c-dK+2:T2=b*T1K+3:T3:

18、=a+T2K+4:X:=T3,(-,c,d,T1)(*,b,T1,T2)(+,a,T2,T3)(:=,T3,_,X),布尔表达式的翻译,布尔表达式 是由布尔运算符(and,or,not)作用于布尔变量(或常数)或关系表达式而形成的。布尔表达式的作用:用作控制语句中的条件:if-then、while、repeat等逻辑赋值句中的逻辑运算,布尔表达式到四元式的翻译,文法:EEEEEE(E)idE rop E 其中,(and)、(or)、(not)为布尔(逻辑)运算符;rop为关系运算符(,=,);id为布尔(逻辑)变量或布尔(逻辑)常数;E rop E为关系表达式。布尔表达式的求值方法:通过逐步计

19、算出各部分的值来计算整个表达式。利用布尔运算符的性质计算其值,布尔表达式作为控制语句中的条件式,作用是用于选择下一个执行点 while E do S1E的作用是选择S1执行,还是跳过S1语句,执行S1后面的语句E有两个出口:真:S1语句假:S1后面的语句,While语句的目标结构,布尔初等量(布尔变量和关系表达式)的目标结构,由两个转移四元式构成,一个表示真出口Li,另一个表示假出口Lj,设E是一布尔变量,它的目标结构为:(1)if E goto Li(jumpt,_,_,Li)(jnz,E,_,Li)(2)if E1 rop E2 goto Li(jump,E1,E2,Li)(jrop,E1

20、,E2,Li)例:(j,a,b,p)(3)goto Lj(jump Lj)(j,_,_,Lj),举例:if ab then A:=x+y的四元式序列,if ab goto Li(真出口)goto Lj(假出口)Li:S的第一个四元式S的最后一个四元式Lj:S 后面的语句,(1)if ab goto(3)(2)goto(5)(3)T1:=x+y(4)A:=T1(5),多因子组成的布尔表达式的翻译,例:if ab c then S1 else S2分析结果如下:当ab为真,执行S1,不需要计算c的值当ab为假,计算c的值,c为真:执行S1,为假:执行S2当ab与c分别为真时,程序转向一致,真出口相

21、同(S1)当ab与c分别为假时,程序转向一致,假出口相同(S2),if ab c then S1 elseS2的四元式序列,(1)if ab goto S1的第一条语句(5)(2)goto(3)(3)if c goto S1的第一条语句(5)(4)goto S2的第一条语句(p+1(5)关于S1的四元式序列(p)Goto q(p+1)关于S2的四元式序列(q)后继四元式,目标结构,E的代码 TF,S1的代码,JUMP S,S2的代码,S(后继语句),2023年8月26日,编 译 原 理,if E then S1 else S2的四元式序列,(1)if E goto(3)(2)goto(S2的第

22、一个四元式)(p+1)(3)关于S1的四元式序列(p)goto r(执行完S1后转出)(p+1)关于S2的四元式序列(r)后继四元式,2023年8月26日,编 译 原 理,while E do S1的四元式序列,(1)if E goto(3)(2)goto(S1后面的语句)(p+1)(3)关于S1的四元式序列(p)goto(1)(p+1)后继四元式,2023年8月26日,编 译 原 理,真出口链、假出口链、回填(Backparch),在多个因子组成的布尔表达式中,可能有多个因子的真出口或假出口的转移去向相同,但又不能立刻知道具体转向位置。把转移方向相同的四元式链在一起,一旦发现具体转移目标,就

23、回填。真出口用Etrue来表示。假出口用Efalse来表示。回填Backparch(g,t)将t填入由g所指向的四元式的结果部分,2023年8月26日,编 译 原 理,if ab c then S1 elseS2的真假出口回填描述,(1)if ab goto 0/*E的真出口Etrue有待回填(2)goto(3)/*回填E的第一个假出口(3)if c goto(1)/*(3)是E的真出口链(4)goto 0/*E的假出口Efalse有待回填(5)关于S1的四元式序列/*此时回填真出口Etrue(p)goto 0/*有待回填q的位置(p+1)关于S2的四元式序列/*此时回填假出口Efalse(q

24、)后继四元式/*此时回填q,2023年8月26日,编 译 原 理,语法制导翻译中使用的公共变量、过程和函数,guad:四元式指针(表示四元式的编号或地址)GEN(X):生成一条四元式,把它放到四元式表的尾部,(和前面介绍的emit功能相同)Nextguad:指向下一个即将形成的四元式的编号,其初值为1,执行一次GEN(X),Nextguad自动加1;merg(p1,p2)函数将以 p1,p2为链首的两个四元式合并为一,返回合并后的链首,条件语句的翻译,基本思路:先对定义它的文法进行改造,以便能在相应处添加上语义子程序;根据它的语义,设计出相应语义子程序的动作。,2023年8月26日,编 译 原

25、 理,if语句的文法,S if E then S1S if E then S1 else S2(E是转移条件)对if E then S1 else S2,其Etrue直到扫描到then,产生S1的第一个四元式序号时,才能将该标号作为E的真链填入到Etrue,而Efalse 直到扫描到else,产生S2的第一个四元式序号时,才得到Efalse的值。,2023年8月26日,编 译 原 理,if语句文法的改造,(1)C if E then(2)T C S1 else(3)S T S2(4)S C S1 目标结构如右图,2023年8月26日,编 译 原 理,(1)C if E then backpat

26、ch(Etrue,Nextguad),C.chain=Efalse 当用产生式if E then 进行归约时,生成了条件E的代码,E的假出口不能回填,通过非终结符C向后传递,所以引入C.chain链.,if语句的语义动作,2023年8月26日,编 译 原 理,(2)T C S1 else q:=Nextguad,emit(goto 0)Backpatch(C.chain,Nextguad),T.chain=merg(S1.chain,q)当用产生式T C S1 else 归约时,S1的代码已经形成,回填E的 假出口即C.chain。此时S2 的代码尚未形成,S1的转出链和JMP转向相同,合并为

27、一,通过T向后传递.,if语句的语义动作,2023年8月26日,编 译 原 理,if语句的语义动作,(3)S T S2S.chain:=merg(T.chain,S2.chain)(4)S C S1 S.chain:=merg(C.chain,S1.chain),2023年8月26日,编 译 原 理,If AB CD then if AB then F:=1 else F:=0 else G:=G+1,采用then 与else的最近匹配原则(三地址指令)(1)if A goto(3)(2)goto 0(13)(3)if B goto(5)(4)goto(2)(13)(5)if CD goto(

28、7)(6)goto(4)(13)(7)if AB goto(9)(8)goto 0(11),(9)F:=1(10)goto 0(15)(11)F:=0(12)goto(10)(15)(13)T:=G+1(14)G:=T(15),2023年8月26日,编 译 原 理,If AB CD then if AB then F:=1 else F:=0 else G:=G+1,四元式形式代码(1)(jnz,A,_,(3)(2)(j,_,_,0)(13)(3)(jnz,B,_,(5)(4)(j,_,_,(2)(13)(5)(j,C,D,(7)(6)(j,_,_,(4)(13)(7)(j,A,B,(9)(8

29、)(j,_,_,0)(11),(9)(:=,1,_,F)(10)(j,_,_,0)(15)(11)(:=,0,_,F)(12)(j,_,_,(10)(15)(13)(+,G,1,T)(14)(:=,T,_,G)(15),2023年8月26日,编 译 原 理,While 语句的翻译,文法:GSS while E do S 文法改造为:S CS1C W E do W while,2023年8月26日,编 译 原 理,(1)W while W.head:=Nextguad;当用W while 归约时,Nextguad记下E的第一个四元式的位置,保留在Wguad中。(2)C W E do backpa

30、tch(Etrue,Nextguad,C.chain=Efalse,C.head=W.head当使用C W E do 进行归约时,E的代码已经生成有两个出口Etrue和Efalse,扫描完do后,可以回填Etrue,而Efalse要到S1语句全部生成后才能回填,因此为待填信息,由C向后传递。,While 语句的语义动作,2023年8月26日,编 译 原 理,While 语句的语义动作,(3)SC S1Backpatch(S1chain,C.head);S.chain:=C.chain;GEN(goto,W.head);当用上式进行归约时,S1语句全部产生,while 语句结束应返回,因此产生四

31、元式(goto w.head),同时回填Efalse,2023年8月26日,编 译 原 理,while a0b0 do if xy then b:=b-1 else a:=a-1,假设四元式序列从100开始编号100(j,a,0,102)101(j,_,_,0)(112)102(j,b,0,104)103(j,_,_,101)(112)104(j,x,y,106)105(j,_,_,0)(109)106(-,b,1,T1),107(:=,T1,_,b)108(j,_,_,100)109(j,a,1,T2)110(:=,T2,_.a)111(j,_,_,100)112,2023年8月26日,编

32、译 原 理,文法GS:SSaAA AAbBB BcSde(1)证明AacAbcBaAdbed是文法的一个句型.(2)请写出该句型的所有短语、素短语及句柄。(3)为文法GS 的产生式构造相应的翻译子程序,使句型AacAbcBaAdbed经该翻译方案翻译后,输出为。,2023年8月26日,编 译 原 理,文法及相应的翻译方案如下:,SbTc print”1”Sa print”2”TR print”3”RR/S print”4”RS print”5”对于输入符号串bR/bTc/bSc/ac,该符号串的输出是什么?输出为1453142431,归约的次序为:(1)SbTc(1)(2)RR/S(4)(3)

33、RS(5)(4)TR(3)(5)SbTc(1)(6)RR/S(4)(7)Sa(2)(8)RR/S(4)(9)TR(3)(10)SbTc(1),2023年8月26日,编 译 原 理,数组赋值语句的翻译,数组:相同类型数据的N维复合结构.数组中每一个元素在计算机中占有相同的存储空间数组分为静态数组和动态数组数组的一般定义:Al1:u1,l2:u2,lk:uk,ln:un其中:A 是数组名lk是数组下标的下限,uk是上限 k是数组的维数数组在内存中是用一片连续的存储单元来表示.,数组的定义和存储,2023年8月26日,编 译 原 理,一维数组:al1:u1(l1iu1)每个元素的宽度为w,地址为:b

34、1+(i-l1)*w是数组a的第一个元素的相对地址,称为起始地址可以表示为:i*w+(b1-l1*w)令C=b1-l1*w(可以计算出来)故:ai=i*w+c,数组元素的地址表示,2023年8月26日,编 译 原 理,数组元素的地址表示,二维数组Al1:u1,l2:u2:事先约定存储顺序按行存储、按列存储数组元素ai1,i2地址可表示为:D=bap+vapbap:固定部分,在编译时可以计算出来,a是数组元素首地址,d2是第二维的维长,c=l1d2+l2 Bap=a-cvap:可变部分Vap=i1d2+i2,2023年8月26日,编 译 原 理,数组元素的四元式:bapvap,临时单元T=bap

35、 T1=vap(1)数组元素的引用 X:=TT1四元式为:(=,TT1,-,X)(2)数组元素的赋值 TT1:=X四元式为:(=,X,-,TT1),2023年8月26日,编 译 原 理,数组元素翻译举例设一数组为A:array1.10,1.20 of reald1=10,d2=20 c=l1d2+l2=21赋值句AI,J+2:=10.0+AI+1,J+1的四元式序列为:,K+0:(+,J,2,T1)K+1:(*,I,20,T2)/*计算vap=i1d2+i2K+2:(+,T2,T1,T1)K+3:(-,a,21,T3)/*计算bap=a-c c=21K+4:(+,I,1,T4)/*计算AI+1,J+1的地址K+5:(+,J,1,T5),2023年8月26日,编 译 原 理,K+6:(*,T4,20,T6)K+7:(+,T6,T5,T5)/*T5为vapK+8:(,a,21,T7)/*T7为bapK+9:(=,T7T5,-,T8)/T8为AI+1,J+1的值K+10:(+,10.0,T8,T9)K+11:(=,T9,-,T3T2),

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号