编译原理ch6 属性文法和语法制导翻译_第1页
编译原理ch6 属性文法和语法制导翻译_第2页
编译原理ch6 属性文法和语法制导翻译_第3页
编译原理ch6 属性文法和语法制导翻译_第4页
编译原理ch6 属性文法和语法制导翻译_第5页
已阅读5页,还剩65页未读, 继续免费阅读

下载本文档

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

文档简介

1、1962年美国斯坦福大学麦克阿瑟(Mcarthur)教授在国际信息加工联合会年会上作了著名的报告“通往计算机的数学科学”,系统地论述了程序设计语言语义形式化的重要性,以及和程序正确性、语言的正确实施等的关系,并提出在形式语言研究中使用抽象语法和状态向量等基本方法形式语义学 。根据形式化的侧重面和所使用的数学工具的不同,形式语义学可分成: 操作语义学着重模拟数据加工过程中计算机系统的操作。 指称语义学主要描述数据加工的结果而不是加工过程的细节。 公理语义学用公理化的方法描述程序对数据的加工。 代数语义学把程序设计语言看作是刻划数据和加工数据的一种抽象数据类型,使用研究抽象数据类型的代数方法,来描

2、述程序设计语言的形式语义。丹麦的科学家曾经运用指称语义学理论成功地实现了Ada语言的编译系统 。形式语义学方法缺点:符号系统比较复杂,其描述文本不易读,不能借助这些形式系统自动完成语义处理任务。目前实际应用中比较流行的语义描述和语义处理方法是属性文法和语法制导翻译的方法属性文法基于属性文法的处理方法 语法制导翻译 Knuth在1968年提出在上下文无关文法的基础上,在描述语义动作时,为每个文法符号(终结符和非终结符)配备若干相关的“值”,如“类型”,“地址”等,称为属性。对文法的每个产生式配备一组属性计算规则称为语义规则,它的描述形式为b:=f(c1,c2,ck),其中b,c1,c2ck为文法

3、符号的属性,f是一个函数。每个文法符号联系于一组属性,且对每个产生式都给出其语义规则的文法称为属性文法。属性代表与文法符号相关信息,如类型、值、代码序列、符号表内容等;属性可以进行计算和传递;在一个属性文法中,对应于每个产生式A都有一组与之相关联的语义规则,每条规则的形式为:b:=f(c1,c2,ck)这里,f是一个函数 (1)b是A的一个属性,并且c1,c2,ck是产生式右边文法符号的属性,则b是A的综合属性; (2)b是产生式右边某个文法符号X的一个属性,并且c1,c2,ck 是A或产生式右边任何文法符号的属性, 则b是X的继承属性;属性b依赖于属性c1,c2,ck。 产 生 式 LEn

4、EE1+T ETTT1*FTFF (E)Fdigit语语 义义 规规 则则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 :=digit.lexval对于某个文法符号XVT VN,用 X . type(X的类型),X . cat(X的种别),X .val(X的值或地址)等表示它的属性。用下标(上角标)区分同一产生式中相同符号的多次出现。在语法树中,一个结点的综合属性的值由其子结点的属性值确定。使用自底向上的方法在每一个结点处使用语义规

5、则计算综合属性的值仅仅使用综合属性的属性文法称S属性文法 产 生 式 语 义 规 则LEn print(E.val) EE1+T E.val := E1.val+T.val ET E.val :=T.val TT1*F T.val :=T1.val* F.val TF T.val :=F.val F (E) F.val :=E.val Fdigit F.val :=digit.lexvaldigit.lexval=3F.val=3T.val=3*digit.lexval=5F.val=5T.val=15E.val=15+digit.lexval=4F.val=4T.val=4E.val=19n

6、L在语法树中,一个结点的继承属性由此结点的父结点和/或兄弟结点的某些属性确定用继承属性来表示程序设计语言结构中的上下文依赖关系很方便产 生 式 语 义 规 则 DTLL.in := T.type TintT.type := integer TrealT.type := real LL1, idL1.in :=L.in addtype(id.entry, L.in) Lid addtype(id.entry, L.in)产 生 式 语 义 规 则 DTL L.in := T.type Tint T.type := integer Treal T.type := real LL1, id L1.i

7、n :=L.in addtype(id.entry, L.in) Lid addtype(id.entry, L.in) id1L,id2L,id3LrealTDT.type=realL.in=realL.in=realL.in=real终结符只有综合属性,由词法分析器提供非终结符既可有综合属性也可有继承属性,文法开始符号的所有继承属性作为属性计算前的初始值对出现在产生式右边的继承属性和出现在产生式左边的综合属性都必须提供一个计算规则。属性计算规则中只能使用相应产生式中的文法符号的属性出现在产生式左边的继承属性和出现在产生式右边的综合属性不由所给的产生式的属性计算规则进行计算,它们由其它产生式

8、的属性规则计算或者由属性计算器的参数提供语义规则所描述的工作可以包括属性计算、静态语义检查、符号表操作、代码生成等等。例. 考虑非终结符A,B和C,其中, A有一个继承属性a和一个综合属性b; B有综合属性c; C有继承属性d。 产生式ABC可能有语义规则 C.d:=B.c+1 A.b:=A.a+B.c 而属性A.a和B.c在其它地方计算 属性文法基于属性文法的处理方法 语法制导翻译 由源程序的语法结构所驱动的处理办法就是语法制导翻译法 (1) 依赖图 (2) 树遍历 (3) 一遍扫描输入串输入串语法树语法树依赖图依赖图语义规则计算次序语义规则计算次序n基于属性文法的处理过程基于属性文法的处理

9、过程在一棵语法树中的结点的继承属性和综合属性之间的相互依赖关系可以由称作依赖图的一个有向图来描述为每一个包含过程调用的语义规则引入一个虚综合属性b,这样把每一个语义规则都写成b:=f(c1,c2,ck)的形式依赖图中为每一个属性设置一个结点,如果属性b依赖于属性c,则从属性c的结点有一条有向边连到属性b的结点(即需先有c才能计算b)。for 语法树中每一结点n do for 结点n的文法符号的每一个属性a do 为a在依赖图中建立一个结点;for 语法树中每一个结点n do for 结点n所用产生式对应的每一个语义规则b:=f(c1,c2,ck ) dofor i:=1 to k do 从ci

10、结点到b结点构造一条有向边; EE1E2 E.val:=E1.val+E2.val E1+E2Evalvalval产 生 式 语 义 规 则 DTL L.in := T.type Tint T.type := integer Treal T.type := real LL1, id L1.in :=L.in addtype(id.entry, L.in) Lid addtype(id.entry, L.in) id1L,id2L,id3LrealTD4type5in6 - addtype(id.entry, L.in)7in8 addtype9in10 addtype1entry2entry3

11、entry一条求值规则只有在其各变元值均已求得的情况下才可以使用;如果一属性文法不存在属性之间的循环依赖关系,那么称该文法为良定义的 通过树遍历的方法计算属性的值 假设语法树已建立,且树中已带有开始符号的继承属性和终结符的综合属性 以某种次序遍历语法树,直至计算出所有属性 深度优先,从左到右的遍历 While 还有未被计算的属性 doVisitNode(S) /*S是开始符号*/procedure VisitNode (N:Node) ;begin if N是一个非终结符 then /*假设它的产生式为NX1Xm*/ for i :=1 to m do if XiVN then /*即Xi是非

12、终结符*/ begin 计算Xi的所有能够计算的继承属性; VisitNode (Xi) end; 计算N的所有能够计算的综合属性end产 生 式语 义 规 则 SXYZ Z.h := S.a X.c := Z.g S.b := X.d -2 Y.e := S.bXx X.d :=2*X.cYy Y.f := Y.e*3Zz Z.g :=Z.h+1 例:考虑属性文法例:考虑属性文法G。其中,。其中,S有继承属性有继承属性a、综合属性、综合属性b;X有有继承属性继承属性c、综合属性、综合属性d;Y有继承属性有继承属性e、综合属性、综合属性f;Z有继承有继承属性属性h、综合属性、综合属性gS:a=

13、0XYZxyzZ:h=0 g=1X:c=1 d=2S:a=0, b=0Y:e=0 f=0产 生 式 语义规则 SXYZ Z.h := S.a X.c := Z.g S.b := X.d -2 Y.e := S.bXx X.d :=2*X.cYy Y.f := Y.e*3Zz Z.g :=Z.h+1 第一次遍历结束第二次遍历结束第三次遍历结束一遍扫描的处理方法是在语法分析的同时计算属性值 所采用的语法分析方法 属性的计算次序L属性文法适合于一遍扫描的自上而下分析S属性文法适合于一遍扫描的自下而上分析属性文法基于属性文法的处理方法 语法制导翻译 直观上说就是为每个产生式配上一个翻译子程序(称语义动

14、作或语义子程序),并且在语法分析的同时执行它。语义动作一方面规定了产生式产生的符号串的意义,另一方面又按照这种意义规定了生成中间代码应做的基本动作。定义:在语法分析过程中,当一个产生式获得匹配(自上而下分析)和用于归约(自下而上分析)时,此产生式对应的语义子程序进入工作,完成既定翻译任务,产生中间代码。例. 定义算术表达式E的“值”的语义动作:1. EE(1)+E(2) E.VAL := E(1).VAL+E(2).VAL2. E0E.VAL := 03. E1 E.VAL := 1 上述语义动作虽然不产生中间代码,但产生式1、2、3所产生的句子有了具体意义,而且,能按照其语义动作,在分析句子

15、的同时一步一步地算出每个句子的“值”。如果语义动作不是简单的计值程序,而是某种中间代码的产生程序,那么随着语法分析的进展,这种代码也逐步生成。语法制导翻译的作用 产生中间代码 产生目标指令 对输入串进行解释执行 根据输入语言的文法(输入文法),根据输入语言的文法(输入文法),分析各产生式的语义,即分析要求计算分析各产生式的语义,即分析要求计算机完成的操作,分别编写出完成这些操机完成的操作,分别编写出完成这些操作的子程序和程序段(称语义子程序),作的子程序和程序段(称语义子程序),并把它们的名字作为动作符号插入到输并把它们的名字作为动作符号插入到输入文法各产生式右部的适当位置上,从入文法各产生式

16、右部的适当位置上,从而形成翻译文法。而形成翻译文法。 在语法分析过程中,就能在分析符号在语法分析过程中,就能在分析符号串的同时,执行由翻译文法所确定的,串的同时,执行由翻译文法所确定的,与该符号串相对应的动作序列,即按动与该符号串相对应的动作序列,即按动作符号的顺序调用相应的子程序完成翻作符号的顺序调用相应的子程序完成翻译任务。译任务。与语法制导翻译方法相对的是非语法制导翻译,即翻译程序将不受输入语言的文法的控制,如形式语义学的翻译方法。ET1 + T2 if T1.type = int and T2.type = int then E.type := int else error E T1

17、or T2 if T1.type = bool and T2.type = bool then E.type := bool else error T n T.type := int T b T.type := bool 语法制导的一个具体实现#-S0XX.VALSm-1YY.VALSmLR分析器的栈加入分析器的栈加入语义值语义值。状态状态值值符号符号TOP输入串:输入串: n + n5+-ET1 + T2 if T1.type = int and T2.type= int E.type :=int else error E T1 or T2 if T1.type = bool and T2.

18、type=bool E.type :=bool else error T n T.type := intT b T.type := bool 2Tint0#-4nint6Tint1Eint4nint输入串输入串n + b4nint0#-2Tint0#-5+-2Tint0#-3bbool5+-2Tint0#-6Tbool5+-2Tint0#-1Eerror0#-ET1 + T2 if T1.type = int and T2.type= int E.type :=int else error E T1 or T2 if T1.type = bool and T2.type=bool E.type

19、 :=bool else error T n T.type := intT b T.type := bool 构造翻译器的基本思想 综合属性可以在分析输入串的语法结构同时,由自下而上的分析器来计算。 在分析器中,保存与栈中文法符号有关的综合属性值,每当归约时,新的文法符号的综合属性值就由栈中正在归约的产生式的右部符号的属性值来计算。 Z Z.z Y Y.y X X.x #top state val当用 A AXYZXYZ 归约时: A A.a #top其中: A.a = f (X.x , Y.y , Z.z ) state val 输入串 动作动作 # _ 3*5+4n #3 _3 *5+4n

20、 进栈 #F _3 *5+4n 归约 #T _3 *5+4n 归约 #T* _3_ 5+4n 进栈 #T*5 _3_5 +4n 进栈 #T*F _3_5 +4n 归约 #T _15 +4n 归约 #E _15 +4n 归约 state val 输入串 动作动作 #E+ _15_ 4n 进栈 #E+4 _15_4 n 进栈 #E+F _15_4 n 归约 #E+T _15_4 n 归约 #E _19 n 归约 #En _19 进栈 #L “19 ” 归约 LEn EE1+T ET TT1*F TF F(E) Fdigit print ( val top ) valntop = val top-2

21、 +val top valntop = val top-2 * *val top val ntop = valtop-1 L-属性文法 如果每个产生式AX1X2Xn ,其对应的语义规则中的每个属性,或者是综合属性,或者是Xj的一个继承属性且这个继承属性仅依赖于: (1)产生式中Xj的左边符号X1,X2, Xj-1的属性 (2)A的继承属性(注:A也在Xj的左侧)以下文法是否为以下文法是否为L-L-属性文法?属性文法?不是。因为文法符号Q的继承属性Q.i依赖于它右边的文法符号R的属性R.sS-属性文法一定是L-属性文法,为什么? 属性文法可以看成是关于语言翻译的高级规格说明,它隐去了实现的细节,

22、从而使用户从明确说明翻译顺序的工作中解脱出来。 翻译模式是适合语法制导翻译的另一种描述形式,它给出了使用语义规则进行计算的次序,这样就把实现的细节表示了出来。 在翻译模式中, 通过把语义规则插入产生式右部的合适位置上,来给出属性的计算次序。 ETR R+TR R-TR R Tnum 分析一下输入串分析一下输入串9 - 5: E T R 9 - T R 5 95- E T R 9 - T R 5 + T R 2 后缀后缀:9 5 2 +95-2+ ETR R+TR print (+) R-TR print (-) R Tnum print( num.val ) ETR R+T print (+)

23、 R R-T print (-) R R Tnum print( num.val ) L-属性文法能确保每个动作都能计算出来。 如何设计一个合理的翻译模式? 1)当一个属性文法只有综合属性时,则语义动作放在产生式的后面即可; 2)当属性文法既有综合属性,又有继承属性时,一般要求建立的翻译模式满足下面三个条件: 1) 产生式右边的继承属性必须在这个符号以前计算出来; 2) 一个动作不能引用这个动作右边符号的综合属性; 3)产生式左边符号的综合属性,只有在它引用的所有属性都计算出来之后才计算。这种动作放在产生式的末尾。例:将以下属性文法改写为翻译模式。 BB1B2 B1.ps=B.ps B2.ps

24、=B.ps B.ht=max(B1.ht , B2.ht) 改写为: B B1.ps=B.ps B1 B2.ps=B.ps B2 B.ht=max(B1.ht , B2.ht) L-属性文法是如何在自上而下的分析中的实现? 为了便于说明动作的顺序和属性计算的顺序,用翻译模式来进行描述属性文法。 为了构造不带回溯的自上而下的语法分析,必须消除左递归。那么,当消除一个翻译模式中产生式的左递归时,如何修改属性呢? 先考虑仅含综合属性的翻译模式。 EE1+T E.val =E1.val+T.val EE1-T E.val =E1.val-T.val ET E.val=T.val T(E) T.val=

25、E.val Tnum T.val=num.val 考虑输入串:9-5+2 E E + T E - T 4 T 5 9 T.val=9 E.val=9 T.val=5 E.val=4 T.val=4 E.val=8 ETR R-TR | +TR | T(E) | num再考虑输入串:9-5+2先画出语法树,再考虑自上而下的翻译过程 E T R 9 - T R1 5 + T R2 2 T.val=9 R.i=9T.val=5R1.i=4T.val=2R2.i=6E.val=6 ?T num T.val=num.val ET R R.i=T.val R- T R1 R1.i=R.i-T.val ET

26、 R.i=T.val R E.val=R.s R-T R1.i=R.i-T.val R1 R.s=R1.s R+T R1.i=R.i+T.val R1 R.s=R1.s R R.s=R.i T(E) T.val=E.val T num T.val=num.val 假设:每个文法符号只有一个综合属性 AA1Y A.a= g (A1.a , Y.y) AX A.a=f (X.x) 消除左递归后的翻译模式为: AX R.i= f(X.x) R A.a=R.s RY R1.i=g(R.i , Y.y ) R1 R.s=R1.s R R.s=R.i A A Y2 A Y1X A X R Y1 R Y2

27、R A2.a=f(X.x)A1.a=g( A2.a , Y1.y )A.a=g( A1.a , Y2.y )R.i=f(X.x)R1.i=g( R.i, Y1.y )R2.i=g( R1.i ,Y2.y )自下而上翻译自上而下翻译 EE1+T E.nptr =mknode(+, E1.nptr ,T.nptr EE1-T E.nptr =mknode(-, E1.nptr ,T.nptr ET E.nptr=T.nptr ET R R-T R1 R R.i = T.nptr E.nptr = R.s R1.i = mknode(-, R.nptr ,T.nptr ) R.s = R1.s R.s = R.i 消除左递归后在自下而上的分析过程中如何实现L-属性文法? 下面方法可以实现基于LL(1)文法的属性文法,也可以实现许多基于LR(1)文法的

温馨提示

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

评论

0/150

提交评论