版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第七章第七章 语法制导翻译技术及中间语法制导翻译技术及中间代码的生成代码的生成 主主 要要 内内 容容1.语义翻译的方法:采用语法制导翻译技术的方法。语义翻译的方法:采用语法制导翻译技术的方法。 依据的文法依据的文法(描述文法的语义描述文法的语义):属性文法。:属性文法。(一般掌握一般掌握) 语法制导翻译过程:根据已有的属性文法,生成句子的语法制导翻译过程:根据已有的属性文法,生成句子的 中间代码过程。中间代码过程。(重点掌握重点掌握)2.语义翻译结果的表示:中间代码语义翻译结果的表示:中间代码 。(重点掌握重点掌握) 常见:常见: 逆波兰表示逆波兰表示四元式表示和三地址代码四元式表示和三地址
2、代码 三元式和树形表示三元式和树形表示1. 语义分析概述语义分析概述一、语义分析的任务一、语义分析的任务任务有:1.审查每一个语法结构的静态语义,即验证语法正确的结构是否有意义。如:赋值语句:x:=x+y,左边变量类型与右边变量类型是否一致。2.在语义正确的基础上生成一种中间代码或目标代码。二、语义分析的范围二、语义分析的范围1o.确定类型:确定标识符所关联的数据类型。2o.类型检查:按语言的类型规则,检查运算的合法性与运算分量类型的一致性,必要时作类型转换。3o.识别含义:根据语言的语义定义(形式或非形式),识别程序中各构造成分组合到一起的含义。,并作相应的语义处理(生成中间代码或目标代码)
3、4o.控制流检查:控制流语句必须转移到合法的地方。如:c中,break语句规定跳出最内层的循环或switch语句.5o.一致性检查:在很多场合要求对象只能被说明一次,如:pascal语言规定同一个标识符在一个分程序中只能被说明一次等。6o.相关名字检查:如:ada,循环或块可以有一个名字,它出现在这些结构的开头或结尾。编译程序必须检查这两个地方用的名字是否相同。 其它:如名字的作用域分析等也是语义分析的工作。三、语义描述工具和语义分析方法三、语义描述工具和语义分析方法1.语义描述工具 目前流行:用属性文法作为描述语义的工具。2.语义分析方法根据描述属性文法的语义规则的方式不同,语义分析方法分为
4、:语法制导定义方法翻译方案2. 属属 性性 文文 法法一、属性一、属性属性常用来描述事物或人的特征。如:人的姓名,性别等,商品的颜色、重量、单位等。v属性:属性:在编译中,对文法的每一个符号,引进一些属性,用这些属性描述文法符号相关的信息,如:类型、值或存储位置等。如:a:=x ,在语法推导或归约时,有时结合x的类型,位置,值,考虑语法分析的正确性,即语法分析中有语义检查。如:x的属性:xtype,xplace,xval分别表示x的类型,位置,值等语义。v属性值:可以在语法分析过程中计算和传递。v属性的加工过程就是语义的处理过程。二、属性文法二、属性文法1.语义规则语义规则在对文法符号属性处理
5、过程中,必须遵守一定义的规则语义规则。为文法的每一产生式定义一组属性的计算规则,称为语义规则。2.属性文法属性文法形式定义:一个属性文法是一个三元组a,a=(g,v,f)其中:g为一个上下文无关文法; v 表示属性的有穷集合; f表示属性的断言或谓词的有穷集。v在属性文法中:每个属性与文法中某个符号相关联,用“符号属性”表示。如:xtype,xint,xbool等。每个断言与文法的某产生式相关联。断言就是产生式上定义的一组语义规则。例:一个简单表达式方法:e:=t1+t2|t1ort2t:=num|true|falsev根据程序语言中有关类型的检验原则,可以得到关于类型检验的属性文法:1.e:
6、=t1+t2 t1.type=int and t1.type=int2.e:=t1ort2 t1.type=bool and t1.type=bool3.t:=num t.type=int4.t:=true t.type=bool5.t:=false t.type=boolv属性分类:综合属性 继承属性综合属性:从语法分析角度看,如果一个结点的某一属性,其值由子结点的属性的值来计算,称该属性为综合属性。例:已知上例属性文法的输入串3+4语法树。其中:e中语义规则中的t1.type和t2.type中的type属性的值分别由子结点t1.type=int和t2.type=int中的int值来计算,使
7、得e中的语义规则(断言)为真。因此:type是综合属性。综合属性用于“自下向上”传递信息。 e t t 4 3 + t1type=int t2type=int t1 type=int,t2 type=int 继承属性:在语法分析树中,结点的某个属性值由该结点的兄弟结点和(或)父结点的属性值来计算,此结点的属性称为继承属性。继承属性用于“自上而下”传递信息。v注意:注意:终结符号只有综合属性,他由词法分析器提供。非终结符号既有综合属性,也可有继承属性。文法识别符号(开始符号)的所有继承属性作为属性计算前的初始值。根据处理不同的要求,属性和断言可以多种形式出现,如:语义规则或者程序段等。例:简单表
8、达式求值的属性文法。产生式:1.l:=eprint(e.val)2.e:=e1+te.val:=e1.val+t.val3.e:=te.val:=t.val4.t:=t1*fe.val:=t1.val*f.val5.t:=ft.val:=f.val6.f:=(e)f.val:=e.val7.f:=digitf.val:= digit.lexval例:描述说明语句中简单变量类型信息的属性文法产生式语义规则1.d:=tll.in:=t.type2.t:=intt.type :=integer3.t:=realt.type :=real 4.l:=l1,id l1.in:=l.inaddtype(i
9、d.entry,l.in)5.l:=idaddtype(id.entry,l.in)文法定义了一种说明语句,该说明语句的形式是由关键字int或real开头,后跟一个标识符表,每一个标识符间用逗号隔开:real id1,id2,idn或 int id1,id2,idn属性文法中,非终结符t有综合属性type,其值由关键字int和real决定。v语义规则l.in:=t.type将l的属性值置为该说明语句指定的类型。 l.in将被沿着语法树传递到下边的结点使用,与l产生式相联的规则里使用了它。如:句子int id1,id2语法树:图2 d t l l int , id2 id1 一、基本思想对文法中
10、的每个产生式都附加上一个语义动作或语义子程序,伴随着语法分析,每当使用一条产生式进行推导或归约时,就执行相应产生式的语义动作(包括:查填表格,改变变量的求值,打印信息和生成中间代码等),从而完成预定的翻译工作。即在语法翻译过程中伴随部分语义的检查工作。3. 语法制导翻译概述语法制导翻译概述v语法制导翻译方法:自底向上的语法制导翻译方法自顶向下的语法制导翻译方法二、语法制导翻译的步骤1、为所给文法每个产生式设计相应的语义规则。例:为一个简单表达式计值的文法:e = e+e|e*e|(e)|digit设计计值的语义规则如下:1. e =e(1)+e(2)eval:=e(1)val+e(2)val
11、2. e =e(1)*e(2)eval:=e(1)val*e(2)val 3. e =(e(1)eval:=e(1)val4. e =digiteval:=lexdigit为文法产生式写语义规则或语义子程序是本章的难点.2.采用lr分析方法,则构造lr分析表状态actiongoto+digit*()#e0s3s211s4s5acc2s3s263r4r4r4r44s3s275s3s286s4s5s97r1s5r1r18r2r2r2r29r3r3r3r33. 将原lr语法分析栈扩充,增加语义值栈。4. 根据语义分析栈的工作过程设计总控程序,使语法分析与语义分析工作同时完成。例:计算表达式7+8*5
12、的语法树,以及用lr语法制导翻译法得到该表达式的计值过程:snxnxnvals1x1s0#x1val状态栈文法符号栈语义值栈步骤状态栈语义栈符号栈输入符号栈主要动作10_#7+8*5#s3203_#7+8*5#r4301_7#e+8*5#s44014_7_#e+8*5#s350143_7_#e+8*5#r460147_7_8#e+e*5#s5701475_7_8#e+e*5#s38014753_7_8_#e+e*5#r49014758_7_8_5#e+e*e#r2100147_7_40#e+e#r11101_47#e#acc 7 + eval=47 eval=7 eval=40 + eval=
13、8 eval=5 8 5 注:自底向上语法制导翻译的特点:当栈顶形成句柄执行归约时,调用相应的语义动作。语法分析与语义分析同步操作。*v说明:若把计值的动作改为产生某种中间代码的子程序,那么,就能在伴随着语法分析的制导下,随着分析的进展逐步生成中间代码。v问题:1.什么是中间代码?它有哪几种形式表示源程序语言的句子? 4.4.中间语言中间语言 2.在语义规则语义规则中,怎么样定义生成中间代码(主要是四元式或三地址式)的一些语义规则? 5. 表达式及语句的语义翻译 3.根据具有生成中间代码的属性文法,生成中间代码的过程是怎样的?一、中间语言概述1 中间语言v中间语言:它介于源程序到目标语言程序中
14、间程序的语言v中间语言程序:用中间语言表示的程序。v作用:用于编译程序,将源程序翻译成等价的中间语言程序,再将中间语言程序转化成目标程序(即将语义分析和目标代码生成分开处理)v源程序中间语言程序目标程序v中间语言是表示语法制导翻译的结果。等价变换转化4. 4. 中中 间间 语语 言言好处:v中间语言与机器无关,使采用中间语言进行翻译的编译程序系统易于移植。v易于优化翻译后的代码。v使编译程序的结构在逻辑上更简单明确。2 中间语言的表示常见:逆波兰表示 四元式表示和三地址代码 三元式和树形表示二、逆波兰表示由波兰逻辑学家j.lukasiewicz(卢卡西维兹)首先提出用来表示表达式的方法,后来推
15、广到表示程序设计语言中的其它语法成分。1.表达式的逆波兰表示表达式的表示:v中缀表示:运算符居中,运算对象在左右两边:a+bv波兰表示:前缀表示:运算符在前,运算对象在后:+ab后缀表示:运算对象在前,运算符在后:ab+(逆波兰表示)v例:逆波兰表示的例子(1)表达式逆波兰表示的定义: 设e是一般表达式,则: 一般表达式一般表达式逆波兰表达式逆波兰表达式v若e为变量或常量ev(e)e的逆波兰式ve(1)ope(2)(二目运算) e(1)的逆波兰式e(2)的逆波兰式opvope(单目运算) e的逆波兰式op中缀表示(一般表示)逆波兰表示a+b*cabc*+a*(b+c/d)abcd/+*a*b+
16、cab*c+a*b+(c-d)/eab*cd-e/+ 在编译过程中,在编译过程中,生成逆波兰表示的语义规则描述生成逆波兰表示的语义规则描述: 产生式 语义规则 e:=e(1)ope(2) e.code=e(1).code|e(2).code|op e:=(e(1) ) e.code=e(1).code e:=i e.code=i 其中:e.code表示e的逆波兰式;|表示逆波兰式的连接。(2)逆波兰表示的特点逆波兰表示的特点a.标识符标识符(运算对象运算对象)出现的顺序(从左到右)和原有顺序相同。出现的顺序(从左到右)和原有顺序相同。b. 运算符是按实际计算顺序(从左到右)出现的。运算符是按实
17、际计算顺序(从左到右)出现的。c. 运算符紧跟在运算对象的后面出现,并且没有括号。运算符紧跟在运算对象的后面出现,并且没有括号。(3) 好处:易于对表达式的计算处理v对于中缀表达式的计算,系统需要用两个工作栈分别处理运算对象和运算符。v对于逆波兰表示的表达式计算处理只用一个工作栈。例:逆波兰式ab+c*的计算处理过程遇运算对象a,b入栈扫描ab+c*ba栈遇运算符+取出a,b,运算结果t入栈tctc*遇运算对象c入栈*遇运算法*取出c,t作运算,设结果t1t12. 形成逆波兰表示怎样将一般表达式转换成逆波兰表示?基本思想:从左到右扫描表达式,每遇到:1o 表达式中的运算对象则往左去。2o 表达
18、式中的运算符,则与运算符栈顶元素比较优先数:逆波兰表示表达式运算对象运算符进栈出栈运算符栈如果运算符栈顶元素的优先数大于或等于表达式中当前的运算符优先数,则栈顶元素退栈向左去。然后当然运算符继续与栈顶的新元素比较优先数。直到栈顶元素的优先数小于表达式中当前运算符为止。此时,才将表达式中当前运算符进栈。例:画出形成表达式a*(b+c/d)的逆波兰表示过程a*(b+c/d)#a(b+c/d)#*#ab+c/d)#(*#ab+c/d)#(*#abc/d)#+(*#abc/d)#+(*#步骤步骤步骤步骤步骤步骤abcd)#abcd)#/+(*#/+(*#/+(*#abcd/)#+(*#abcd/+)#
19、*#abcd/+*#步骤步骤步骤步骤 步骤形成逆波兰表示的过程,实质上是表达式的翻译过程。(算法不难写出)例:a/b/c+d = ab/c/d+(a+b)*(c-d/e) = ab+cde/-*3. 扩充的逆波兰表示逆波兰不仅仅用来表示计算表达式,而且可以推广到其它语法成分的表示。v赋值语句:a := e (其中e是表达式)逆波兰表示:ae:=(其中e应该为逆波兰表示)例:a:=3*(b+c)的逆波兰表示:a3bc+*:=v条件语句:if u then s1 else s2逆波兰表示:u l1 jumpf s1 l2 jump s2其中:u为布尔表达式的逆波兰表示s1,s2均为相应语句的逆波兰
20、表示。jumpf 表示一个双目运算符:当u为假(0)时,它引向标号 l1的分支, l1表示语句s2的开始位置。jump表示单目运算符:它无条件的引向标号为l2的分支, l2表示语句s2后的符号位置。逆波兰式表示的语义:当u=0(假)转去执行s2,否则转向执行s1,然后跳到s2之后的语句。有下列源程序段:k := 0;if ij then k := k+6*ai-jelse begini:=i+1;j:=j-1;end;逆波兰表示:k0:=ijl1 jumpf kk6ij-asubs*+:=l2 jump l1: ii1+:=jj1-:= l2:含义:当ij为假便转向l1处执行s2;否则执行s1
21、后无条件转到l2处即语句s2的后继部分。三、三元式和树形表示1。三元式一个三元式由三个主要部分和一个序号组成:(i)(op,arg1,arg2)其中:op是运算符,arg1和arg2是运算对象。当op为一目运算符时,只有一个运算对象。(i)表示三元式的序号,三元式的运算结果由每个三元式前序号(i)指示。序号(i)指向三元式所处的表格位置,因此引用一个三元式的计算结果是通过引用该三元式的序号实现的。三元式出现的先后顺序与表达式的计值顺序一致。例:a:=-b*c+b*d三元式:(1)(,b,_)(2)(*,(1),c)(3)(*,b,d)(4)(+,(2),(3)(5)(:=,(4),a)2. 间
22、接三元式由于三元式的先后顺序决定了值的顺序,因此在产生三元式形式的中间代码后,对其进行代码的优化时难免涉及到改变三元式的顺序(即三元式表示的中间代码不利用代码优化),这就要修改三元式表。为了最少改动三元式表,可以另设一张间接码表来表示有关三元式在三元式表的计值顺序,用这种办法处理的中间代码称为间接三元式。例:表达式x=a+b*c y=d-b*c其间接三元式表示如下:三元式表间接码表(1)(*,b,c)(1)(2)(+,a,)(1)(2)(3)(=,x,(2)(3)(4)(-,d,(1)(1)(5)(=,y,(4)(4)(5)由于间接码表的作用,编译程序每产生一个三元式时,先查看三元式表中是否存
23、在当前三元式,若存在就不需要重复填写三元式表,如上例中的三元式(1) (*,b,c)在间接码表中出现了两次,但三元式表中实际只有一个三元式。注:三元式表示的中间代码不利于中间代码的优化。间接三元式表示的中间代码有利于中间代码的优化。3.树形表示v树形结构是三元式的另一种表示形式例如:上例a:=-b*c+b*d的树形表示(由三元式的下至上画出) := + a b * * c - d b 树形表示法很容易表示一个表达式或语句。v一个表达式中简单变量或常数的树形表示就是它们的本身。v如果表达式e1和e2的树分别为t1和t2,则: e1和e2, e1* e2, -e1的树分别:注:二目运算对应二叉树三
24、目运算对应三叉树:如条件语句if u then s1 else s2 可看作三目运算。其三目运算符定义为:if then else 则:树表示 + t2 t1 e1+e2 * t2 t1 e1*e2 - t1 -e1 s2 u s1 注:多叉树不便于存储,可以化为二叉树: s1 s2 u new 四、四元式和三地址代码四元式是一种比较普遍采用的中间代码形式。v四元式由四个部分组成:(i)(op,arg1,arg2,result)其中:op为运算符;arg1,arg2为运算对象。result存放结果的变量。四元式之间的联系通过变量来联系(而不用三元式中的序号联系)例:a:=b*c+b*d四元式表
25、示: (1) (*,b,c,t1) (2) (*,b,d,t2) (3) (+, t1, t2, t3) (4) (:=, t3,_,a)注:四元式和三元式的主要不同在于:四元式之间的联系通过中间引用的变量名实现,而三元式之间的联系通过三元式序号实现。这说明要更改一张三元式表比较困难,它需要改变一序列的三元式的序号。四元式表的修改比较容易,调整四元式之间位置,不改变其中的参数。因此:四元式和三地址代码表示的中间代码便于中间代码的优化。而三元式和树不便于优化。有时将四元式表示成更直观的形式三地址代码v三地址代码形式:x:=a op b (赋值形式)与赋值语句的区别:其右边最多只能有一个运算符。
26、例:上例的四元式写成三地址代码: (1) t1:=b*c (2) t2:=b*d (3) t3:= t1+ t2 (4) a:= t3 v三地址代码表示的好处:表示中间代码更直观,有利于中间代码的优化和目标代码的生成。v四元式的生成算法与逆波兰式生成算法基本相同。v扩充四元式可表示程序语言的其它语法成分。例:将表达式: a+b*(c-d)-e/f g写成逆波兰表示、三元式和四元式逆波兰表示:abcd-*+efg /-三元式: (1) (-,c,d) (2) (*,b,(1) (3) (+,a,(2) (4) ( ,f ,g) (5) (/,e,(4) (6) (-,(3),(5)四元式:(1)
27、(-,c,d,t1) (2)(*,b, t1, t2) (3)(+,a, t2, t3) (4)( ,f,g, t4) (5)(/,e, t4, t5) (6)(-, t3, t5, t6)三地址代码: t1:=c-d t2:=b*t1 t3:=a+ t2 t4:=f g t5:=e/ t4 t6:= t3- t5例:将语句:if avbd then i:=i+1 else i:=i-1 写成四元式。 (1) (,b,d, t1) (2) (v,a, t1, t2) (3) (bmz, t2, ,(7) (t2为假) (4) (+,i,1, t3) (5) (:=, t3, ,i) (6) (
28、jmp,(9) (7) (-,i,1, t4) (8) (:=, t4, , i) (9)三地址代码:(1) t1:=b, , );i为逻辑变量或逻辑常量;i rop i为关系表达式。1. 布尔表达式的翻译v布尔表达式的计值方法:(1)通过逐步计算出各部分的值来计算整个表达式的值.例:假定用1表示true,0表示false,则布尔表达式: 1(0 0) 1 =1 (0 1) 1 =1 0 =1(2)利用逻辑运算符的性质计值如:当a=1,则ab的值(不管b为何值)一定为1。v布尔表达式计值方法不同,则采用的翻译方法也不同。例:按第(1)种方法,布尔表达式a=bcd将被翻译成如下的四元式序列: (
29、1) if a=b goto (4) (a=b为真转(4)) (2) t1=0 (3) goto (5) (4)t1=1 (5) t2=c d (6) t3=t1 t2例:按布尔表达式第(1)种计值法,将文法:e =ee|ee|e|(e)|i rop i|i表示的布尔表达式翻译成四元式的翻译方案。e =e(1) e(2)e place=newtemp();emit(e place=e(1) place e(2) place);e =e(1) e(2)e place=newtemp();emit(e place=e(1) place e(2) place);e = e(1) e place=ne
30、wtemp();emit(e place=e(1) place);e = (e(1) e place= e(1) place;e = i(1)rop i(2) e place=newtemp();emit(if i(1) place rop i(2) place goto nextq+3);emit(e place=0);emit(goto nextq+2);emit(e place=1)e = ie place= i place2.控制语句中布尔表达式的翻译v布尔表达式不仅可以计值,而且其值还决定了程序控制流的转向(如if和while中).v现讨论布尔表达式e在if-then,if-then
31、-else和while-do中翻译。三种语句的语法和代码结构为:s =if e then s(1)|if e then s(1)else s(2)|while e do s(1) s(1)的代码e的代码真假s(1)的代码e的代码真假s(1)的代码e的代码真假s(2)的代码if e then s(1) 代码结构if e then s(1) else s(2)代码结构while e do s(1) 代码结构为了将作为条件控制的布尔表达式e正确翻译成四元式,且e翻译的代码是一串条件转移和无条件转移的四元式代码,则定义下面的一组控制转移的四元式:(1)if e goto li 当e为真,转向li ,称
32、li 为e的真出口,记为e true。(2)if e(1) rop e(2) goto li 当e(1) rop e(2)为真,转向li ,li 为关系运算符rop的真出口。(3)goto lj 无条件转向标号lj,称lj为假出口,记为: e false。例:e的布尔表达式为:abcf,翻译为如下四元式序列:(1)if ab goto e true (2)goto (3)(3)if cf goto e true(6)goto e false注:布尔表达式计值是采用第二种方式进行。 描述布尔表达式控制功能的语义的四元式序列都是由一串条件转移和无条件转移四元式代码组成。现把e布尔式放在条件语句中考
33、察条件语句转移的出口问题例:有条件语句:if abcf then s(1) else s(2)其四元式序列为:(1)if ab goto (7)(2)goto (3)(3)if cf goto (7)(6)goto (p+1)(7)(关于s(1)的四元式序列)(p)goto (q)(p+1)(关于s(2)的四元式序列) (q)后继四元式v四元式中的地址回填问题上述if四元式序列中的(1)和(5)四元式的转移地址(7)不能在产生式(1)和(5)四元式时立即得知,至少要等到if语句的then时才能回填(7)表示的产生s(1)的第一个四元式的地址。同理(4)和(6)四元式中的转移地址(p+1)也需要
34、s(2)的第一个四元式的地址回填。v采用拉链技术解决四元式序列中的地址回填为了记录需回填地址的四元式,把需回填e true 的四元式拉成一个链(为真值的链简称真链);把需要回填e false 的四元式拉成另一个链(为假值的链简称假链)拉链的方法:若有四元式序列:(10).goto e true(20).goto e true(30). goto e true则链成:(10).goto (0)(20).goto (10)(30). goto (20)其中,地址(30)为链头,0为链尾标志,地址(10)为链尾。v最后,讨论用于if 语句和while语句中的布尔表达式的语义翻译问题。为了回填四元式中
35、地址信息,要用到公共变量,过程和函数:四元式(标号或地址)指针nextqnextq的值表示下一个即将要产生的四元式标号,初值为1,每生成一个四元式,其值自动加1。 设置非终结符e的语义变量e bcodee bcode表示非终结符e的第一个四元式标号。 回填过程backpatch(p,t) 功能:把p所链接的每个四元式的第四区段都回填为t。若原第四区段已有信息,应保存后再回填为t。 链接函数merge(p1,p2)将p1和p2为链首的两个链合并为一条,返回合并后的链首值。根据布尔运算特性,采用自下而上的语法制导翻译方法,给出布尔表达式文法中每个产生式相应的语义子程序:(1) e =i e tru
36、e=nextq;e fale=nextq+1;e bcode=nextq;emit(if i place goto 0);emit(goto 0);(2)e =i(1) rop i(2) e true=nextq;e bcode=nextq;e fale=nextq+1;emit(if i(1)place rop i(2) place goto 0);emit(goto 0);(3) e =(e(1) etrue = e(1)true ; efalse = e(1)false; ebcode = e(1)bcode;(4) e = e(1) etrue = e(1)false; e false
37、 = e(1)true; e bcode = e(1) bcode (5) e =e(1)e(2) backpatch(e(1) false, e(2) bcode); ebcode=e(1) bcode; etrue=merge(e(1) true, e(2) true); efalse=e(2) false;(6) e =e(1) e(2) backpatch(e(1) true, e(2) bcode); ebcode=e(1) bcode; e true =e(2) true; e false =merge(e(1) false, e(2) false); 产生式(1)(同理(2),(
38、3),(4)式一样)语义子程序中,可见用e =i归约后,e的真假链都有了具体值。这样,在用产生式(5)归约时,e(1)与e(2)的真假链分别也有了具体值。根据布尔运算的特性可知:(1)当e(1)为假时,计算e(2),所以e(2)的第一个四元式地址(这是已记录在e(2) bcode中) e(2) bcode这时回填为e(1)的假值链,因此有backpatch(e(1) false, e(2) bcode)。(2)若e(1)为真时,无须计算e(2)而去执行s(1)的第一个四元式,但此时尚未扫描到“then”,因此,保留e(1)已形成的值链首e(1) true;若e(2)为真时,其转移地址用e(1)
39、,所以将e(1),e(2)两个真链e(1) true, e(2) true合并为e的一个链。(3)若e(1)为假,在计算e(2), e(2)也为假,这时整个布尔式e(1) e(2)为假,可见e(2)的假出口与整个布尔式的假出口一致,此时e(2)的假出口e(2) false业已形成。因此,有e false= e(2) false。(4)尽管有e(1),e(2)参与运算,但按扫描顺序,首先生成e(1)的四元式。因此,e(1)的第一个四元式也就是整个布尔式的第一个四元式,所以有ebcode=e(1) bcode.同理不难分析(6)产生式的语义子程序。 下面以表达式abd为例,按上面的翻译方案,说明将
40、它生成四元式的过程。(1)首先指示器nextq赋初值为1,当扫描到a时,用e =i归约,根据产生式(1)的语义子程序,有:e(1) true=nextq=(1), e(1) false=nextq+1=(2),ebcode=1,生成四元式: (1)if a goto 0 (2)goto 0此时nextq=3(2)继续扫描,由自底向上的语法制导翻译可知,这时应归约bd,用产生式e =e(1) rop e(2) ,有:e(2) true=nextq=(3), e(2) false=nextq+1=(4), e(2) bcode=nextq=(3),生成四元式: (3)if bd goto 0(4)
41、goto 0此时nextq=5 (3)继续向上归约,用e=e(1) e(2)归约,有:回填backpatch(e(1) false, e(2) bcode)ebcode= e(1) bcode;etrue=merge(e(1) true, e(2) true);efalse=e(2) false;因为e(1) ture=(1), e(2) ture=(3)所以合并后etrue(3),将e(1) true放到e(2)的链尾。回填得:e(2) bcode=(3),将(3)填入e(1) false中,即goto(3)。合并e(1),e(2)的真链将e(2) true填到以e(1) 为真链头的一个四元
42、式区段中。最后e(2)的假链就是e的假链:efalse=e(2) false; 得到一组四元式: (1)if a goto 0(2)goto (3)(3) if bd goto(1)(4)goto 0这时,etrue=(3),efalse=(4)三、控制语句的翻译v在程序设计语言中,控制语句的一般形式:if-then, if-then-else, while-do这些语句由下列文法定义:gs: (1)s(1)s =if e then s(1)(2)s =if e then s(1) else s(2)(3)s=while e do s(1)(4)s=a(5)s=l(6)l=l(1);s(7)l
43、=s其中:非终结符l表示语句串,a表示赋值语句,s为语句,e为布尔表达式。下面着重介绍控制语句翻译过程中涉及的回填和拉链技术。1.if语句的翻译如:s =if e then s(1) else s(2)翻译此语句应明确以下几点:(1)布尔表达式e的作用仅在于控制对s(1)或s(2)的选择。因此,作为转移条件的布尔式e,使用e true和e false分别指出尚待回填“真”,“假”出口的四元式串;(2)e的“真”出口只有在扫描到then时才能知道,而它的“假”出口则需要s(1)并且到达else之后才能明确。这就是说,必须把efalse的值传下去,以便在到达相应的else时才能进行回填。(3)另外
44、,当s(1) 执行完之后意味着整个if语句也已经执行完毕,因此在s(1) 的编码之后产生一条无条件转移指令(goto 0),但在完成s(2) 的翻译之前,该无条件转移的转移目标无法知道。对于语句嵌套的情况,如:if e(1) then if e(2) then s(1) else s(2) else s(3),在翻译s(2)后,s(1) 后的无条件转移目标仍无法确定,因为它不仅跨越s(2),还要跨越s(3)。可见,转移目标的确定与if所处的环境有关。因此,对非终结符s(或l)设置一个语义变量s chain(或l chain),记忆所有待填信息的四元式链,知道翻译完整个语句后再回填转移目标地址。
45、 为了扫描控制语句的每一时刻不失时机地处理和回填有关信息,将文法改写,并写出if 语句各产生式相应语义子程序。(1)s =cs(1)(2)c=if e then(3)s=tps(2)(4)tp= cs(1) else根据程序设计语言的处理顺序,首先用产生式(2)c=if e then 归约,这时在then后可产生e的真出口地址。因此将then后的第一个四元式回填至e的真出口地址。e的假出口地址作为待填信息放在c的语义变量c chain中,即c=if e then backpatch(etrue,nextq);cchain=efalse;接着用产生式(1) s =cs(1)继续向上归约。此时已经
46、处理到c=if e then s(1),注意到归约时e的真出口已经处理,由于e不成立时注意地址v与s(1)语句的待填转移地址相同,e的假出口地址已放在cchain中,但此时转移地址仍未确定,s(1)的待填转移地址的链放在s(1) chain中,所以应将cchain与s(1) chain一并作为s的待填信息链,用函数merge链起来,链头保留在s chain中,即有:s=cs(1) schain=merge(cchain, s(1) chain如果if语句没有后继部分,在产生式(1)(2)归约为s后,随即可产生后续第一个四元式地址,以此回填s的语义值schain。即为if e then s(1)
47、语句的语义子程序。如果if 语句为if-then-else 形式,用产生式tp= cs(1) else继续归约。归约时首先产生s(1)语句序列的最后一个无条件转移四元式,它的标号保留在q中。(i) s(1)第一个四元式/*e的真出口*/。(q)goto 0/*q的第四区段有待回填*/nextq/*else后的第一个四元式,即e的假出口*/q就是整个语句s的语义值schain.因为有待回填q第四区段的值,它与schain一样,链在以链头为tpchain的链中,用merge函数实现。过程emit产生(q)四元式后,nextq自动加1,这时nextq是else后的第一个四元式地址,也是e的假出口地址
48、,回填该值时efalse即cchain中,因此有 tp= cs(1) else q=nextq;emit(goto 0);backpatch(cchain,nextq);tpchain=merge(schain,q);最后用产生式(3) s=tps(2)归约。当s(2)语句序列处理完后,产生if的后继语句。这时就有了后继语句四元式的地址,该地址是整个if语句的出口地址,它与s(2)语句序列的出口一致。s(2)的出口待填信息在s(2) chain中,因此将tpchain和s(2) chain链接,并以schain为链头。s=tps(2)schain=merge(tpchain,s(2)chain
49、);2.while语句的翻译将产生式:s=while e do s(1) 分解如下:(1)s=wds(1)(2) wd=wedo(3)w=while写出文法各产生式的语义子程序如下:观察while语句的代码结构如图,执行到while时,首先记下e的第一条四元式地址,以便归约到do s(1)后能准确地转到该入口。其次,语义值w chain仍是待填信息链。根据while语句的语义,s(1)语句序列的最后一条语句要由能转移到e的第一个四元式的功能,以便判断e是否成立。e成立再执行s(1),e不成立则离开while语句,执行后继语句。因此e的假出口efalse为待填信息存放在wchain与schain
50、中。由while语句执行的顺序,首先用产生式(3)w =while归约,这时nextq记下e的第一个四元式地址,并保留在wbcode中,即有:(1)w=while wbcode=nextq;s(1)的代码e的代码真假继续扫描,用产生式wd=wedo归约。如前所述,扫描完e后,应该会产生etrue和efalse。扫描完do后,可回填etrue值,用backpatch(etrue,nextq),而efalse要等到s(1)语句序列全部产生后才能回填,因此作为待填信息,由wdchain传下去,wdchainefalse继续传下去。即有:(2) wd=wedo backpatch(etrue,next
51、q);wdchain=efalse;wdbcode=wbcode;用产生式(1)s=wd s(1)归约时, s(1)语句序列的全部四元式已产生。应无条件返回e的第一个四元式,因此产生四元式(goto wdbcode),同时回填e的入口地址到s(1)语句序列中所有需要该信息的四元式中,用backpatch(s(1) chain, wdbcode)。即有:(3)s=wds(1) backpatch(s(1) chain, wdbcode);emit(goto wdbcode);schain=wdchain;goto wdbcode是while的后继语句。后继语句的第一个四元式地址是e的假出口,已在
52、wdchain中,将该信息作为整个while语句的假出口保留schain中,以便回填。例:将下列语句翻译成一组四元式,while awhile abd dob6) then x=x-1if (x6) then x=x-1else y=x+1else y=x+1根据while,if语句的文法中产生式语义动作和布尔表达式以及赋值语句的翻译方案,翻译该语句的一组四元式如下: 100 if a goto 104100 if a goto 104 / /* *w wbcodebcode=100=100* */ / 101 goto 101 goto 102 102 102 if bd goto 102
53、if b6 goto 104 if x6 goto 106 106 105 goto 105 goto 109 109 106 t 106 t1 1=x-1=x-1 107 x= t 107 x= t1 1108 goto 111109 t t2 2=x+1=x+1110 y= t110 y= t2 2111 goto111 goto 100 100112112最后,schain112回填在e的假出口中。 a代码 b6代码x=x-1代码y=x+1代码tfttff代码结构图 小结及举例一.小结1.主要内容:语义分析采用语法制导翻译方法以及中间代码的生成。(1)语义描述的工具属性文法。 属性文法定
54、义为三元组ag(g,v,e),它将文法g.属性v和属性的断言e有机的结合在一起,准确的描述了处理(归约或推导)每个产生式时的语义分析工作。 属性描述了处理对象的特征。属性的断言说明了文法符号之间的语义规则和语义动作。(2)语法制导翻译方法。两类翻译方法:自底向上和自顶向下语法制导翻译方法翻译对象:简单算术表达式和赋值语句.布尔表达式.条件语句和while语句等。(重点掌握部分)(3)翻译结果的形成中间代码。中间代码形式:逆波兰式.三元式.间接三元式.树形表示.四元式和三地址代码等。2.主要解决的问题(1)设计属性文法设计文法产生式的语义规则或语义动作子程序。(难点)*根据所给的条件,设计文法符
55、号的属性。*根据文法符号属性的语义关系设计语义规则或语义动作。(2)掌握自底向上翻译方法中,算术表达式.布尔表达式.赋值语句.条件语句和while语句的翻译过程和生成四元式的结果。(3)掌握给定表达式的各种中间代码形式的描述方法。二.举例例:给出adva+be表达式的逆波兰表示根据运算符的优先级,逆波兰表示:运算符的优先级,逆波兰表示:abc+adab+ev例:写出条件表达式:例:写出条件表达式: if (x+y)*z=5 then x:=(a+b)c else y:=abcc else y:=abc(1)(1)四元式序列四元式序列 (2)(2)逆波兰表示逆波兰表示解:解:(1)(1)四元式序
56、列四元式序列(1)(+,x,y,t(1)(+,x,y,t1 1) )(2)(2)(* *,t,t1 1,z,t,z,t2 2) )(3)(=,t(3)(=,t2 2,5,t,5,t3 3) )(4)(jumpf,t(4)(jumpf,t3 3,(9),(9)(5)(+,a,b,t(5)(+,a,b,t4 4) )(6)(,t(6)(,t4 4,c,t,c,t5 5) )(7)(:=,t(7)(:=,t5 5,x),x)(8)(jump,(12)(8)(jump,(12)(9)(,a,b,t(9)(,a,b,t6 6) )(10)(,t(10)(,t6 6,c,t,c,t7 7) )(11)(:=,t(11)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 教育机器人在小学科学教育中的应用前景
- 现代学校图书馆借阅模式创新与实践
- 2025年度特色民宿经营许可及产权转让协议4篇
- 二零二五版股权收购托管与财务报表编制服务协议3篇
- 2025年租车代驾服务客户满意度调查合同4篇
- 二零二五年度农业科技成果转化出样合作框架4篇
- 2024运营总监综合运营管理提升合同3篇
- 旅店2025年度绿化维护服务合同2篇
- 2025年度商业广场大理石表面处理及翻新服务协议4篇
- 2025版卫生院与药品供应商合作协议书3篇
- 割接方案的要点、难点及采取的相应措施
- 2025年副护士长竞聘演讲稿(3篇)
- DB11∕T 1028-2021 民用建筑节能门窗工程技术标准
- (初级)航空油料计量统计员技能鉴定理论考试题库(含答案)
- 执业药师劳动合同范本
- 2024年高考英语复习(新高考专用)完形填空之词汇复现
- 【京东物流配送模式探析及发展对策探究开题报告文献综述4100字】
- 施工现场工程令
- 药物经济学评价模型构建
- Daniel-Defoe-Robinson-Crusoe-笛福和鲁滨逊漂流记全英文PPT
- 第一章威尔逊公共行政管理理论
评论
0/150
提交评论