第六章 属性文法和语法制导翻译

Post on 04-Jan-2016

77 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

第六章 属性文法和语法制导翻译. 从本章开始,我们介绍有关语义分析及翻译的问题。其处理的方法主要是属性文法和语法制导翻译方法。 本章中,我们将首先介绍属性文法的基本概念,然后介绍基于属性文法的处理方法,讨论如何自上而下分析和自下而上分析中实现属性计算。 本章重点掌握前四节 6.1 属性文法, 6.2 基于属性文法的处理方法, 6.3 S — 属性文法的自下而上计算, 6.4 L — 属 性文法和自顶向下翻译。. 6 。 1 属性文法 - PowerPoint PPT Presentation

TRANSCRIPT

第六章 属性文法和语法制导翻译

第六章 属性文法和语法制导翻第六章 属性文法和语法制导翻译译

从本章开始,我们介绍有关语从本章开始,我们介绍有关语义分析及翻译的问题。其处理的方法义分析及翻译的问题。其处理的方法主要是属性文法和语法制导翻译方法。主要是属性文法和语法制导翻译方法。

本章中,我们将首先介绍属性本章中,我们将首先介绍属性文法的基本概念,然后介绍基于属性文法的基本概念,然后介绍基于属性文法的处理方法,讨论如何自上而下文法的处理方法,讨论如何自上而下分析和自下而上分析中实现属性计算。分析和自下而上分析中实现属性计算。

本章重点掌握前四节本章重点掌握前四节 6.16.1 属性属性文法,文法, 6.26.2 基于属性文法的处理方法,基于属性文法的处理方法,6.3 S—6.3 S— 属性文法的自下而上计算,属性文法的自下而上计算,6.4 L—6.4 L— 属性文法和自顶向下翻译。属性文法和自顶向下翻译。

第六章 属性文法和语法制导翻译

66 。。 11 属性文法属性文法 属性文法是在上下文无关文法的基础上为每个文法符号属性文法是在上下文无关文法的基础上为每个文法符号

(终结符或非终结符)配备若干个相关的“值”(称为(终结符或非终结符)配备若干个相关的“值”(称为属性属性)。这些属性代表与文法符号相关的信息,例如它)。这些属性代表与文法符号相关的信息,例如它的类型、值、代码序列的类型、值、代码序列、符号表内容等等。属性和变量、符号表内容等等。属性和变量一样,可以进行计算和传递。一样,可以进行计算和传递。

属性一般分为两类:属性一般分为两类:综合属性综合属性和和继承属性。继承属性。简单的说,简单的说,综合属性用于“自下而上”传递信息,而继承属性用于综合属性用于“自下而上”传递信息,而继承属性用于“自上而下”传递信息。“自上而下”传递信息。

属性加工加工的过程即是语义处理的过程,对于文法属性加工加工的过程即是语义处理的过程,对于文法的每一个产生式都配备了一组属性的计算规则,则称为的每一个产生式都配备了一组属性的计算规则,则称为语义规则。语义规则。

在一个属性文法中,对应于每个产生式在一个属性文法中,对应于每个产生式 AA 都有一套都有一套与之相关联的语义规则,每条语义规则的形式为:与之相关联的语义规则,每条语义规则的形式为:

第六章 属性文法和语法制导翻译

b:=f(c1,c2,…,ck) b:=f(c1,c2,…,ck) 这里这里 ff 是一个函数,而且或者是一个函数,而且或者 ( ( 11 )) bb 是是 AA 的一个综合属性并且的一个综合属性并且 c1,c2,…ckc1,c2,…ck 是产生式右是产生式右边文法符号的属性;或者边文法符号的属性;或者 ( ( 22 )) bb 是产生式右边某个文法符号的一个继承属性并且是产生式右边某个文法符号的一个继承属性并且 cc1,c2,…ck1,c2,…ck 是是 AA 或产生式右边任何文法符号的属性或产生式右边任何文法符号的属性 在这两种情况下,我们都说属性 在这两种情况下,我们都说属性 bb 依赖于属性依赖于属性 c1,c2…,ck.c1,c2…,ck.

要特别强掉的是:要特别强掉的是: ( ( 11 )终结符只有综合属性,它由词法分析器提供;)终结符只有综合属性,它由词法分析器提供; ( ( 22 )非终结符既可以有综合属性也可以有继承属性,文法)非终结符既可以有综合属性也可以有继承属性,文法开始符号的所有继承属性作为属性计算前的初始值。开始符号的所有继承属性作为属性计算前的初始值。 一般来讲,对出现在产生式右边的继承属性和出现在产生式 一般来讲,对出现在产生式右边的继承属性和出现在产生式左边的综合属性都必须提供一个计算规则,属性计算规则中左边的综合属性都必须提供一个计算规则,属性计算规则中只能使用相应产生式的文法符号的属性,这有利于产生式范只能使用相应产生式的文法符号的属性,这有利于产生式范围内“封装”属性的依赖性。然而,出现在产生式左边的继围内“封装”属性的依赖性。然而,出现在产生式左边的继承属性和出现在产生式右边的综合属性不由所给的产生式的承属性和出现在产生式右边的综合属性不由所给的产生式的属性计算规则进行计算,它们由其它产生式的属性规则计算属性计算规则进行计算,它们由其它产生式的属性规则计算 ,,由属性计算器的参数提供由属性计算器的参数提供

第六章 属性文法和语法制导翻译

语义规则所描述的工作可以包括属性计算、静态语义规则所描述的工作可以包括属性计算、静态语义检查、符号表操作、代码生成等。语义规则可能语义检查、符号表操作、代码生成等。语义规则可能产生副作用(如产生代码),也可能不是变元的严格产生副作用(如产生代码),也可能不是变元的严格函数(如某个规则给出可用的下一个数据单元的地函数(如某个规则给出可用的下一个数据单元的地址)。这样的语义规则通常写成过程调用,或过程段。址)。这样的语义规则通常写成过程调用,或过程段。

综合属性综合属性:: 在语法树中,一个结点的综合属性的值由其子结点在语法树中,一个结点的综合属性的值由其子结点

的属性值确定。因此,通常使用自底向上的方法在每的属性值确定。因此,通常使用自底向上的方法在每一个结点处使用语义规则计算综合属性的值。仅仅使一个结点处使用语义规则计算综合属性的值。仅仅使用综合属性的属性文法称用综合属性的属性文法称 S—S— 属性文法。属性文法。

继承属性继承属性:: 在语法树中,一个结点的继承属性由此结点的父结在语法树中,一个结点的继承属性由此结点的父结

点和点和 // 或兄弟结点的某些属性确定。用继承属性来表或兄弟结点的某些属性确定。用继承属性来表示程序语言结构中的上下文依赖关系很方便。示程序语言结构中的上下文依赖关系很方便。

第六章 属性文法和语法制导翻译

66 。。 2 2 基于属性文法的处理方法 基于属性文法的处理方法 从概念上讲,基于属性文法的处理过程通常是这样的:对单词符从概念上讲,基于属性文法的处理过程通常是这样的:对单词符

号串进行语法分析,构造语法分析树,然后根据需要遍历语法树,号串进行语法分析,构造语法分析树,然后根据需要遍历语法树,并在语法树的各结点处按语义规则进行计算。并在语法树的各结点处按语义规则进行计算。

输入串输入串语法树语法树依赖图依赖图语义规则计算次序语义规则计算次序 这种由源程序的语法结构所驱动的处理办法就是这种由源程序的语法结构所驱动的处理办法就是语法制导翻译法语法制导翻译法。。

语义规则的计算可能产生代码、在符号表中存放信息、给出错误语义规则的计算可能产生代码、在符号表中存放信息、给出错误信息或执行任何其它动作。对输入串的翻译也就是根据语义规则信息或执行任何其它动作。对输入串的翻译也就是根据语义规则进行计算得出结果。进行计算得出结果。

66 。。 22 。。 11 依赖图依赖图 如果在一棵语法树中一个结点的属性如果在一棵语法树中一个结点的属性 bb 依赖于属性依赖于属性 cc ,那么这,那么这

个结点处计算个结点处计算 bb 的属性规则必须在确定的属性规则必须在确定 cc 的语义规则之后使用。的语义规则之后使用。在一颗语法树中的结点的继承属性和综合属性之间的相互依赖关在一颗语法树中的结点的继承属性和综合属性之间的相互依赖关系可以用称作依赖图的一个有向图来描述。 系可以用称作依赖图的一个有向图来描述。

在为一棵语法树构造依赖图以前,我们为每一个包含过程调用在为一棵语法树构造依赖图以前,我们为每一个包含过程调用的语义规则引入一个虚综合属性的语义规则引入一个虚综合属性 bb ,这样把每一个语义规则都写,这样把每一个语义规则都写成 成

b:= f(cb:= f(c11,c,c22, …c, …ckk) ) 的形式。依赖图中为每一个属性设置一个的形式。依赖图中为每一个属性设置一个结点,如果属性结点,如果属性 bb 依赖属性依赖属性 cc ,则从属性,则从属性 cc 的结点有一条有向边的结点有一条有向边连到属性连到属性 bb 的结点。的结点。

第六章 属性文法和语法制导翻译

这里要掌握这里要掌握依赖图依赖图的画法。的画法。 例如,属性例如,属性 A.a:=f( X.x, Y.y )A.a:=f( X.x, Y.y ) 对应于产生式 对应于产生式 AAXYXY的语义规则的语义规则 ,, 这条语义这条语义

规则确定了依赖于属性规则确定了依赖于属性 X.xX.x 和和 Y.yY.y 的综合属的综合属性性 A.aA.a 。 如果在语法树中应用这个产生式,。 如果在语法树中应用这个产生式,那么在依赖图中会有三个结点那么在依赖图中会有三个结点 A.a,X.x,A.a,X.x, 和和 Y.Y.yy。由于。由于 A.aA.a 依赖依赖 X.xX.x ,所以有一条有向边,所以有一条有向边从从 X.xX.x 到到 A.a.A.a. 由于由于 A.aA.a 也依赖于也依赖于 Y.yY.y ,所以,所以还有一条有向边从还有一条有向边从 Y.yY.y 连到连到 A.a.A.a.

如果与产生式如果与产生式 AAXYXY对应的语义规则还有:对应的语义规则还有: X.i:=g(A.a,Y.y)X.i:=g(A.a,Y.y) 那么,图中还应有两条有向边,一条从那么,图中还应有两条有向边,一条从 A.aA.a 连连到到 X.iX.i ,另一条从,另一条从 Y.yY.y 连到连到 X.iX.i

,, 因为因为 X.iX.i 依赖于依赖于 A.aA.a 和和 Y.y.Y.y.

第六章 属性文法和语法制导翻译

[[ 例例 6.3]6.3]当下面的产生式应用于语法树时,我们就像图当下面的产生式应用于语法树时,我们就像图 6.6.44 所示的那样把有向边加到依赖图中。所示的那样把有向边加到依赖图中。

产生式 语义规则产生式 语义规则 EEE1+E2 E.val:=E1.val+E2.valE1+E2 E.val:=E1.val+E2.val

[[例例 6.4]6.4]下页的图是书中图下页的图是书中图 6.2 6.2 (( P139P139)带注释语法)带注释语法树的依赖图。依赖图中的结点由数字来标识,这些数树的依赖图。依赖图中的结点由数字来标识,这些数字将在讨论属性的计算次序时用到。从代表字将在讨论属性的计算次序时用到。从代表 T.typeT.type的的结点结点 44 有一条边连到代表有一条边连到代表 L.inL.in的结点的结点 55,因为根据产,因为根据产生式生式 DDTLTL 的语义规则的语义规则 L1.in=L.in,L1.in=L.in, 可知可知 L1.inL1.in依赖依赖于于 L.in,L.in,

第六章 属性文法和语法制导翻译

所以有两条向下的边分别进入结点所以有两条向下的边分别进入结点 7 7 和和 99 。每一。每一个于个于 LL 产生式有关的语义规则产生式有关的语义规则 addtype(id.entry,L.in)addtype(id.entry,L.in) 都都产生一个虚属性,结点产生一个虚属性,结点 66 、、 88 和和 1010 都为这些虚属性构都为这些虚属性构造的。造的。

如果一属性文法不存在属性之间的循环依赖关系,如果一属性文法不存在属性之间的循环依赖关系,那么该文法为那么该文法为良定义的。良定义的。为了设计编译程序,我们只处为了设计编译程序,我们只处理良定义的属性文法。理良定义的属性文法。

第六章 属性文法和语法制导翻译

属性的计算次序属性的计算次序 一个有向非循环图的拓扑序是图中结点的任何顺序一个有向非循环图的拓扑序是图中结点的任何顺序

m1,m2, …mk,m1,m2, …mk, 使得边必须是从序列中前面的结点指向使得边必须是从序列中前面的结点指向后面的结点。也就是说,如果后面的结点。也就是说,如果 mimimjmj 是是 mimi 到到 mjmj 的一的一条边,那么在序列中条边,那么在序列中 mimi 必须出现在必须出现在 mjmj 之前。之前。

一个依赖图的任何拓扑排序都给出一个语法树中结一个依赖图的任何拓扑排序都给出一个语法树中结点的语义规则计算的有效顺序。这就是说,在拓扑排序点的语义规则计算的有效顺序。这就是说,在拓扑排序中,在一个结点上,语义规则中,在一个结点上,语义规则 b:=fb:=f (( c1,c2,…ck)c1,c2,…ck) 中的中的属性属性 c1,c2…ckc1,c2…ck 在计算在计算 bb 以前都是可用的。以前都是可用的。

66 。。 22 。。 22 树遍历的属性计算方法树遍历的属性计算方法 通过树遍历计算属性值得方法很多种。这些方法都通过树遍历计算属性值得方法很多种。这些方法都假设语法树已经建立起了,并且树中已带有开始符号的假设语法树已经建立起了,并且树中已带有开始符号的继承属性和终结符的综合属性。然后以某种次序遍历语继承属性和终结符的综合属性。然后以某种次序遍历语法树,直至计算出所有的属性。最常用的遍历方法是深法树,直至计算出所有的属性。最常用的遍历方法是深度优先,从左到右的遍历方法。度优先,从左到右的遍历方法。

第六章 属性文法和语法制导翻译

66 。。 22 。。 33 一遍扫描的处理方法一遍扫描的处理方法 与树遍历的属性计算方法不同,一遍扫描的方法是在语法与树遍历的属性计算方法不同,一遍扫描的方法是在语法

分析的同时计算属性值。分析的同时计算属性值。 如果按这种一遍扫描的编译程序模型来理解语法制导翻译如果按这种一遍扫描的编译程序模型来理解语法制导翻译

方法的话,所谓语法制导翻译法,直观上说是为文法中每个方法的话,所谓语法制导翻译法,直观上说是为文法中每个产生式配上一组语义规则,并且在语法分析的同时执行这些产生式配上一组语义规则,并且在语法分析的同时执行这些语义规则语义规则 .. 在自上而下的语义分析中在自上而下的语义分析中 ,, 若一个产生式匹配输若一个产生式匹配输入串成功入串成功 ,, 或者在自下而上分析中或者在自下而上分析中 ,,当一个产生式被用于进当一个产生式被用于进行归约时行归约时 ,, 此产生式相应的语义规则就被计算此产生式相应的语义规则就被计算 ,,完成有关语完成有关语义分析和代码生成的工作义分析和代码生成的工作 ..

6.2.4 6.2.4 抽象语法树抽象语法树 建立表达式的抽象语法树建立表达式的抽象语法树 ,, 我们通过为每个运算分量或运算我们通过为每个运算分量或运算

符号都建立一个结点来为子表达式建立子树符号都建立一个结点来为子表达式建立子树 . . 运算符号结点运算符号结点的各子结点分别是表示该运算符号的各个运算分量的子表达的各子结点分别是表示该运算符号的各个运算分量的子表达式组成的子树的根式组成的子树的根 ..

第六章 属性文法和语法制导翻译

抽象语法树中的每一个结点可以由包含几个抽象语法树中的每一个结点可以由包含几个域的记录来实现的域的记录来实现的 . . 在一个运算符号对应的在一个运算符号对应的结点中结点中 ,, 一个域标识运算符号,其它域包含一个域标识运算符号,其它域包含指向运算分量的结点的指针。运算符号通常指向运算分量的结点的指针。运算符号通常叫做这个结点的标号。当我们进行翻译时,叫做这个结点的标号。当我们进行翻译时,抽象语法树中的结点可能会用附加域来存放抽象语法树中的结点可能会用附加域来存放结点的属性值结点的属性值 (( 或指向属性的指针)。或指向属性的指针)。

66 。。 3 S—3 S— 属性文法的自下而上计算属性文法的自下而上计算 这一节我们考虑这样一类属性文法:这一节我们考虑这样一类属性文法: S—S—

属性文法,它只含有综合属性。属性文法,它只含有综合属性。 下面我们讨论分析栈中的综合属性。下面我们讨论分析栈中的综合属性。 在自底向上的分析法中。我们使用一个栈来在自底向上的分析法中。我们使用一个栈来存放已经分析过的子树的信息。现在我们可存放已经分析过的子树的信息。现在我们可以在分析栈中使用一个附域来存放综合属性以在分析栈中使用一个附域来存放综合属性值。图值。图 6.96.9 表示的是一个带有一个属性值空间表示的是一个带有一个属性值空间的分析栈的例子。的分析栈的例子。

State valState val… …… …X X.xX X.xY Y.yY Y.yZ Z.zZ Z.z… …… …

图图 6.96.9

toptop

第六章 属性文法和语法制导翻译

我们假设图中的栈是由一对数组我们假设图中的栈是由一对数组 statestate 和和 valval 来实来实现的。每一个现的。每一个 statestate 元素都是一个指向元素都是一个指向 LR(1)LR(1) 分析表的分析表的指针(或索引)。(注意,文法符号隐含在指针(或索引)。(注意,文法符号隐含在 statestate 中而中而不需要存储在栈中)。然而,如果像第五章中的那样不需要存储在栈中)。然而,如果像第五章中的那样把文法符号存入栈中时,那么当第把文法符号存入栈中时,那么当第 ii 个个 statestate 对应的符对应的符号为号为 AA时,时, val[i]val[i] 中就存放语法树中与结点中就存放语法树中与结点 AA 对应的对应的属性值。属性值。

设当栈顶由指针设当栈顶由指针 toptop指示。我们假设综合属性是指示。我们假设综合属性是刚好在每次归约前计算的。假设语义规则刚好在每次归约前计算的。假设语义规则 A.a:=f(X.x,Y.A.a:=f(X.x,Y.y,Z.z)y,Z.z) 是对应于产生式是对应于产生式 AAXYZXYZ 的。在把的。在把 XYZXYZ归约成归约成AA 以前,属性以前,属性 Z.zZ.z 的值放在的值放在 val[top]val[top] 中,中, Y.yY.y 的值放在的值放在val[top-1]val[top-1] 中,中, X.xX.x 的值放在的值放在 val[top-2]val[top-2] 中。如果一个中。如果一个符号没有综合属性,那么数组符号没有综合属性,那么数组 valval 中相应的元素就不定中相应的元素就不定义。归约后,义。归约后, toptop 值减值减 22 ,, AA 的状态存放在的状态存放在 state[top]state[top]中(也就是中(也就是 XX 的位置)综合属性的位置)综合属性 A.aA.a 的值存放在的值存放在 val[tval[top]op] 中。中。

第六章 属性文法和语法制导翻译

66 。。 4 L—4 L— 属性文法和自顶向下翻译属性文法和自顶向下翻译 一个属性文法称为一个属性文法称为 L—L— 属性文法属性文法:如果对于每个产生式:如果对于每个产生式

AAX1X2…XnX1X2…Xn 其每个语义规则中的每个属性或者是综合属性,其每个语义规则中的每个属性或者是综合属性,或者是或者是 Xj(1<=j<=n)Xj(1<=j<=n) 的一个继承属性且这个继承属性仅依赖的一个继承属性且这个继承属性仅依赖于:于:

(( 11 )产生式)产生式 XjXj 的左边符号的左边符号 X1,X2,…Xj-1X1,X2,…Xj-1 的属性的属性 (( 22 )) AA 的继承属性。的继承属性。66 。。 44 。。 1 1 翻译模式翻译模式 属性文法可以看成是关于语言翻译的高级规范说明,其属性文法可以看成是关于语言翻译的高级规范说明,其

中隐去实现细节,使用户从明确说明翻译顺序的工作中解脱中隐去实现细节,使用户从明确说明翻译顺序的工作中解脱出来。下面我们讨论一种适合语法制导翻译的另一种描述形出来。下面我们讨论一种适合语法制导翻译的另一种描述形式,称为式,称为翻译模式翻译模式。翻译模式给出了使用语义规则进行计算。翻译模式给出了使用语义规则进行计算的次序,这样就可以把某些实现细节表示出来。在翻译模式的次序,这样就可以把某些实现细节表示出来。在翻译模式中,和文法符号相关的属性和语义规则(这里我们也称语义中,和文法符号相关的属性和语义规则(这里我们也称语义动作),用花括号动作),用花括号 { }{ } 括起来,插入到产生式右部的合适位置括起来,插入到产生式右部的合适位置上。这样翻译模式给出了使用语义规则进行计算的顺序。上。这样翻译模式给出了使用语义规则进行计算的顺序。

第六章 属性文法和语法制导翻译

如果既有综合属性又有继承属性,在建立翻译模如果既有综合属性又有继承属性,在建立翻译模式时就必须特别小心:式时就必须特别小心:

(( 11 )产生式右边的符号的继承属性必须在这个符)产生式右边的符号的继承属性必须在这个符号以前的动作中计算出来。号以前的动作中计算出来。

(( 22 )一个动作不能引用这个动作右边符号的综合)一个动作不能引用这个动作右边符号的综合属性。属性。

(( 33 )产生式左边非终结符的综合属性只有在它所)产生式左边非终结符的综合属性只有在它所引用的所有属性都计算出来后才能计算。计算这种属引用的所有属性都计算出来后才能计算。计算这种属性的动作通常可放在产生式右端的末尾。性的动作通常可放在产生式右端的末尾。

66 。。 44 。。 2 2 自顶向下翻译自顶向下翻译 在第四章我们知道,为了构造不带回溯的自顶向下在第四章我们知道,为了构造不带回溯的自顶向下

语法分析,必须消除文法中的左递归。现在我们把前语法分析,必须消除文法中的左递归。现在我们把前面消除左递归的方法加以扩充面消除左递归的方法加以扩充 ,,当消除一个翻译模式的当消除一个翻译模式的基本语法的左递归时同时考虑属性。这种方法适合带基本语法的左递归时同时考虑属性。这种方法适合带综合属性的翻译模式。这样许多文法可以使用自顶向综合属性的翻译模式。这样许多文法可以使用自顶向下分析来实现。下分析来实现。

第六章 属性文法和语法制导翻译

对于自顶向下的分析,我们假设动作是在处于相对于自顶向下的分析,我们假设动作是在处于相同位置上的符号被展开(匹配成功)时执行的。一个符同位置上的符号被展开(匹配成功)时执行的。一个符号的继承属性必须由出现这个符号之前的动作来计算,号的继承属性必须由出现这个符号之前的动作来计算,产生式左边非终结符的综合属性必须在它的所依赖的所产生式左边非终结符的综合属性必须在它的所依赖的所有属性都计算出来之后才能被计算。有属性都计算出来之后才能被计算。

下面我们把转换左递规翻译模式的方法推广到一般,下面我们把转换左递规翻译模式的方法推广到一般,以便进行自顶向下分析:以便进行自顶向下分析:

假设我们有下面的翻译模式:假设我们有下面的翻译模式: AAAA11Y {A.a:=g(AY {A.a:=g(A11.a,Y.y) }.a,Y.y) }

AAX { A.a:=f(X.x) }X { A.a:=f(X.x) }

其每个文法符号都有一个综合属性,用小写字母表示,其每个文法符号都有一个综合属性,用小写字母表示,gg 和和 ff 是任意函数。是任意函数。

利用第四章消除左递归的算法,可将其转换成下面利用第四章消除左递归的算法,可将其转换成下面文法: 文法: AAXRXR

R R YR|εYR|ε

第六章 属性文法和语法制导翻译

再考虑语义动作,翻译模式变为:再考虑语义动作,翻译模式变为: A→X {R. i:=f(X.x) }A→X {R. i:=f(X.x) }

R { A.a:=R.s }R { A.a:=R.s }

R→Y { R1.i:=g((R.i), Y.y) }R→Y { R1.i:=g((R.i), Y.y) }

RR11 {R.s:= R {R.s:= R11.s }.s }

R→ε {R.s:= R.i }R→ε {R.s:= R.i }

经过转换的翻译模式,使用了经过转换的翻译模式,使用了 RR 的继承属性的继承属性 i i 和和综合属性综合属性 s.s.

66 。。 44 。。 3 3 递归下降翻译器的设计递归下降翻译器的设计 66 。。 5 5 自下而上计算继承属性自下而上计算继承属性

第六章 属性文法和语法制导翻译

例题与习题解答例题与习题解答[[ 例例 66 。。 1] 1] 某程序设计语言说明部分的语法制导定义如下:某程序设计语言说明部分的语法制导定义如下: D→TLD→TL         T→intT→int T→realT→real

L→LL→L11, id, id

L→id L→id 给出语法制导定义及自底向上的翻译模式,并给出语法制导定义及自底向上的翻译模式,并比较两者的不同。比较两者的不同。

解:语法制导定义为:解:语法制导定义为: D→TLD→TL        {L.in := T.type }{L.in := T.type }

   T→int { T.type := integer }T→int { T.type := integer } T→real { T.type := real }T→real { T.type := real }

L→LL→L11, id { L1.in := L.in, addtype(id.entry , L.in ) }, id { L1.in := L.in, addtype(id.entry , L.in ) }

L→id { addtype (id.entry, L.in) }L→id { addtype (id.entry, L.in) }

第六章 属性文法和语法制导翻译

自底向上分析的翻译模式为:自底向上分析的翻译模式为: D→T {L.in := T.type }D→T {L.in := T.type }

LL         T→int { T.type := integer }T→int { T.type := integer }

T→real { T.type := real }T→real { T.type := real }

L→ { LL→ { L11.in := L.in }.in := L.in }

LL11, id { addtype(id.entry , L.in ) }, id { addtype(id.entry , L.in ) }

L→id { addtype (id.entry, L.in) }L→id { addtype (id.entry, L.in) }

从上述定义看两者的区别仅在于在翻译模式中把语义动作插入在规则右部的任从上述定义看两者的区别仅在于在翻译模式中把语义动作插入在规则右部的任意位置。而语法制导中把语义动作都放在产生式的最后。意位置。而语法制导中把语义动作都放在产生式的最后。

[[ 例例 66 。。 2] 2] 在一个移入——归约的分析中采用以下的语法制导的翻译模式,在在一个移入——归约的分析中采用以下的语法制导的翻译模式,在某产生式归约时,立即执行括号中的动作。某产生式归约时,立即执行括号中的动作。

A→aB {print “0” }A→aB {print “0” }

A→c {print “1” }A→c {print “1” }

B→Ab { print “2” } B→Ab { print “2” } 当分析器输入为当分析器输入为 aacbbaacbb 时,打印的字符串是什么时,打印的字符串是什么 ??

第六章 属性文法和语法制导翻译

解: 分析器的分析过程如右图:解: 分析器的分析过程如右图:由于分析器采用移入归约的方式进行分析,由于分析器采用移入归约的方式进行分析,

符号串符号串 aacbbaacbb 的分析过程将按标号进行,的分析过程将按标号进行,而按一产生式归约时立即执行括号中的而按一产生式归约时立即执行括号中的动作所以分析器打印的字符为:动作所以分析器打印的字符为:

1202012020

[[ 例例 66 。。 3] 3] 已知表达式抽象语法树的属性已知表达式抽象语法树的属性文法的翻译模式为:文法的翻译模式为:

产生式产生式 E→EE→E11 + T + T

E→EE→E11 * T * T

E→TE→T

T→(E)T→(E)

T→numT→num

语义动作语义动作E.nptr:=mknode(‘+’ ,E1.nptr, T.nptr )E.nptr:=mknode(‘+’ ,E1.nptr, T.nptr )E.nptr:=mknode(‘*’, E1.nptr, T.nptr )E.nptr:=mknode(‘*’, E1.nptr, T.nptr )E.nptr:=T.nptrE.nptr:=T.nptrT.nptr:=E.nptrT.nptr:=E.nptrT.npter:= mknode(num, num.val )T.npter:= mknode(num, num.val )

第六章 属性文法和语法制导翻译

求其消除左递归后的翻译模式:求其消除左递归后的翻译模式:解:解: E→ T { R.i := T.type }E→ T { R.i := T.type }

R { E.nptr := R.s }R { E.nptr := R.s }

R→ +R→ +

T { RT { R11.i :=mknode(‘+’, R.i , T.nptr ) }.i :=mknode(‘+’, R.i , T.nptr ) }

R1 { R.s := R1.s }R1 { R.s := R1.s }

R→ *R→ *

T { RT { R11.i := mknode(‘*’, R.i, T.nptr) }.i := mknode(‘*’, R.i, T.nptr) }

R1 { R.s := R1.s }R1 { R.s := R1.s }

R→ε { R.s := R.i }R→ε { R.s := R.i }

T→(T→(

E E

) {T.nptr := E.nptr }) {T.nptr := E.nptr }

T→num { T.nptr := mknode(num , num.val ) }T→num { T.nptr := mknode(num , num.val ) }

top related