语法制导翻译:使用上下文无关文法来引导对语言的翻译,是一种面向文法的翻译技术。
notion image

5.1 语法制导定义(SDD)

SDD是对上下文无关文法(CFG)的推广,将每个文法符和一个语义属性集合相关联。
将每个产生式和一组语义规则相关联,这些规则用于产生该产生式中各文法符号的属性值。
如果X是一个文法符号,a是X的一个属性,则用X.a表示属性a在某个标号为$X 的分析树结点上的值。
简单计算器的语法制导定义(SDD)
简单计算器的语法制导定义(SDD)
简单计算器的语法制导翻译(SDT)
简单计算器的语法制导翻译(SDT)
 
SDT是对SDD的补充
  • 在产生式右部嵌入了程序片段的CFG,这些程序片段称为语义动作。按照惯例,语义动作放在花括号内
  • 一个语义动作在产生式中的位置决定了这个动作的执行时间
 
SDD:
是关于语言翻译的高层次规格说明
隐蔽了许多具体实现细节,使用户不必显式地说明翻译发生的顺序
SDT:
可以看作是对SDD的一种补充,是SDD的具体实施方案
显式地指明了语义规则的计算顺序,以便说明某些实现细节
 

5.1.1 综合属性和继承属性

综合属性 synthesized attribute

在分析树上结点N的综合属性通过N的子节点和N本身的属性值来定义。
例如对于产生式E→E1+T,综合属性对应的语义规则可以是E.val=E1.val+T.val。
终结符可以具有综合属性。终结符的综合属性值是由词法分析器提供的词法值,因此在SDD中没有计算终结符属性值的语义规则。
notion image
notion image

继承属性 inherited attribute

在分析树上N结点的继承属性只能通过N的父节点、兄弟节点或者N本身的属性值来定义。
终结符没有继承属性,终结符从词法分析器处获得的属性值被归为综合属性值。
notion image
notion image
在上面这个SDD就是一个带有继承属性的SDD。首先根据产生式(1)对应的语义规则,得到了最上面的L.inh=T.type=real,然后根据产生式(4)对应的语义规则,得到Lbellow.inh=Lup.inh,然后同样的道理依据产生式(4)得到Lbellow.inh=Lup.inh
 

属性文法

在SDD中,副作用是指在语法规则的语义动作中对属性进行修改或操作的行为。一个没有副作用的SDD也称为属性文法(在属性文法的语义规则中,仅仅通过其它属性值和常量来定义一个属性值)。
副作用可以改变属性的值,更新符号表、计算表达式的结果等。副作用的一个常见示例是在语义动作中更新符号表,当遇到变量声明时,可以通过语义动作将变量添加到符号表中,并分配内存空间。
其实这与纯函数编程中对副作用的定义应该是相似的,有待考证。
例如:
notion image

5.1.2 SDD的求值顺序

SDD为CFG中的文法符号设置语义属性。对于给定的输入串x,我们将应用语义规则,计算分析树中各结点对应的属性值。SDD声明了语法分析树上属性之间的依赖关系,按照这种依赖关系的拓扑排序可以确定他们的求值顺序。
依赖图是一个描述了分析树中结点属性间依赖关系的有向图
分析树中每个标号为X的结点的每个属性a都对应着依赖图中的一个结点
如果属性X.a的值依赖于属性Y.b的值,则依赖图中有一条从Y.b的结点指向X.a的结点的有向边
notion image
 

5.1.3 S-属性定义和L-属性定义

S-SDD

定义:仅仅使用综合属性的SDD
如果一个SDD是S属性的,可以按照语法分析树节点的任何自底向上顺序来计算它的各个属性值
S-属性定义可以在自底向上的语法分析过程中实现
仅仅使用综合属性的SDD称为S属性的SDD,也叫S-属性定义,S-SDD。
 

L-SDD

思想:在一个产生式所关联的各属性之间,依赖图的边可以从左到右,但不能从右到左
注意:若同时有综合属性和继承属性,不一定有可行的属性求值顺序。但是L-属性定义一定有可行顺序
一个SDD是L-属性定义,当且仅当它的每个属性要么是一个综合属性,要么是满足如下条件的继承属性:假设存在一个产生式A→X1X2...Xn,其右部符号Xi(1≤i≤n)的继承属性仅依赖于下列属性:
  • A的继承属性
  • 产生式中Xi​左边的符号 X1​,X2​,…,Xi−1​ 的属性
  • Xi本身的属性,但Xi 的全部属性不能在依赖图中形成环路
所以对于L-SDD,所有的分析树属性都依赖于左边或者下边的节点。所以不会存在环路。
每个S-属性定义都是L-属性定义
L-SSD的例子
L-SSD的例子
 

5.2 语法制导翻译方案SDT

5.2.1 将S-SDD转换为SDT

转换规则:
将每个语义动作都放在产生式的最后
因为S-SSD只有综合属性
notion image
 
在LR语法分析中实现SDT
实现方法:
SDT可以在LR语法分析过程中实现
当归约发生时执行相应的语义动作
 
扩展栈使其存放综合属性
notion image
 
将语义规则改写成栈操作
notion image

5.2.2 将L-SDD转换为SDT

转换规则:
将计算某个非终结符号A的继承属性的动作插入到产生式右部中紧靠在A的本次出现之前的位置上
将计算一个产生式左部符号的综合属性的动作放置在这个产生式右部的最右端
notion image
 
在语法分析过程中实现SDT
如果一个L-SDD的基本文法可以使用LL分析技术,那么它的SDT可以在LL或LR语法分析过程中实现
  • 非递归的预测分析过程中进行语义翻译
  • 递归的预测分析过程中进行语义翻译
  • LR分析过程中进行语义翻译
 

递归下降语法分析中的翻译

构造递归下降的翻译器
构造算法:
函数A的参数是非终结符号A的继承属性。
函数A的返回值是非终结符号A的综合属性集合。
函数A的函数体中需要:
  • 选择一个产生式
  • 对产生式的每个文法符号的每个属性设置局部变量
  • 为产生式体中的非终结符号传递继承属性
  • 计算A的综合属性
 
与每个产生式有关的代码执行如下动作:从左到右考虑产生式右部的词法单元、非终结符及语义动作
对于带有综合属性x的词法单元X,把x的值保存在局部变量X. x中;然后产生一个匹配X的调用,并继续输入
对于非终结符B,产生一个右部带有函数调用的赋值语句c := B(b1 , b2 , …, bk),其中, b1 , b2 , …, bk是代表B的继承属性的变量,c是代表B的综合属性的变量
对于每个动作,将其代码复制到语法分析器,并把对属性的引用改为对相应变量的引用
notion image
 

LL语法分析中的翻译

语法分析栈扩展为
符号栈
动作记录:即将被执行的语义动作的指针
综合记录:非终结符号的综合属性值
继承记录:非终结符号的继承属性,也可以和符号栈合并
notion image
notion image
分析栈中的每一个记录都对应着一段执行代码
综合记录出栈时,要将综合属性值复制给后面特定的语义动作
变量展开时(即变量本身的记录出栈时),如果其含有继承属性,则要将继承属性值复制给后面特定的语义动作
 

LR语法分析中的翻译

如何修改文法来利用LR语法分析进行翻译?
首先构造SDT,在各个非终结符之前放置语义动作来计算它的继承属性,并在产生式后端放置语义动作计算综合属性
对每个内嵌的语义动作,向文法中引入一个标记非终结符来替换它。每个这样的位置都有一个不同的标记,并且对于任意一个标记M都有一个产生式M→ε。
如果标记非终结符M在某个产生式A→α{a}β中替换了语义动作a,对a进行修改得到a',并且将a'关联到M→ε上。动作a'
(a) 将动作a需要的A或α中符号的任何属性作为M的继承属性进行复制
(b) 按照a中的方法计算各个属性,但是将计算得到的这些属性作为M的综合属性
notion image
 
Loading...