Sdd Sdt
语法制导翻译_1
- 文法G[S]及其语法制导翻译定义如下:
产生式 | 语义动作 |
---|---|
$S’\rightarrow S$ | print(S.num) |
$S\rightarrow (L)$ | $S.num = L.num + 1$ |
$S\rightarrow a$ | $S.num = 0$ |
$L\rightarrow L(1), S$ | $L.num = L(1).num + S.num$ |
$L\rightarrow S$ | $L.num = S.num$ |
若输入为$(a,(a))$,且采用自底向上分析方法,则输出为2
- 有文法G及其语法制导翻译如下所示( 语义规则中的*和+分别是常规意义下的算术运算符)
. | . |
---|---|
$E\rightarrow E(1)\wedge T$ | ${E.val = E(1).val * T.val}$ |
$E\rightarrow T$ | ${E.val = T.val}$ |
$T\rightarrow T(1)# n$ | ${T.val = T(1).val + n.val}$ |
$T\rightarrow n$ | ${T.val = n.val}$ |
则分析句子$3\wedge 3# 4$其值为21
- 有一语法制导定义如下:
. | . |
---|---|
$S\rightarrow bAb$ | print “1” |
$A\rightarrow (B$ | print “2” |
$A\rightarrow a$ | print “3” |
$B\rightarrow aA)$ | print “4” |
若输入序列为$b(a(a(aa)))b$,且采用自底向上的分析方法,则输出序列为34242421
- 有一语法指导定义如下,其中+表示符号连接运算:
. | . |
---|---|
$S\rightarrow B$ | print B.vers |
$B\rightarrow a$ | $B.vers=a$ |
$B\rightarrow b$ | $B.vers=b$ |
$B\rightarrow Ba$ | $B.vers=a+B.vers$ |
$B\rightarrow Bb$ | $B.vers=b+B.vers$ |
输入序列abab,采用自底向上的分析方法,则输出序列为baba
- 使用语义规则可以定义一个程序的意义
- 语义规则中的属性有两种:综合属性与继承属性
- 终结符具有综合属性
S-SDD, L-SDD, SDT
- S-SDD:S属性的SDD、S-属性定义。仅仅使用综合属性的SDD成为S-SDD。S-SDD可以自底向上顺序来计算属性值。S-SDD可以在自底向上的语法分析过程中实现
- L-SDD:L-属性定义、L属性的SDD。依赖图的边可以从左到右,但不能从右到左(L是Left的首字母)
- L-SDD,属性要么是一个综合属性,要么满足
假如存在一个产生式A,其右部符号$X_i$的继承属性仅依赖于下列属性
- A的继承属性。
- $X_i$左边的符号的属性
- $X_i$本身的属性
- 每个S-SDD都是L-SDD
- 将一个S-SDD转换为SDT的方法是:将每个语义动作都放在产生式的最后
- SDT(语法制导翻译方案): 产生式右部中嵌入程序片段(语义动作)的CFG
- SDT可以看作是SDD的具体实施方案
- 基本文法可以使用 LR分析技术,且SDD是 S属性的
- 基本文法可以使用 LL分析技术,且SDD是 L属性的
- 将L-SDD转换为SDT的规则 (重要)
- 将计算某个非终结符号A的 继承属性的动作插入到产生式右部中 紧靠在A的本次出现之前的位置上
- 将计算一个产生式左部符号的 综合属性的动作放置在这个产生式右部的最右端
- 如果一个L-SDD的基本文法可以使用LL分析技术,那么它的SDT可以在LL或LR语法分析过程中实现
- 如果一个S-SDD的基本文法可以使用LR分析技术,那么它的SDT可以在LR语法分析过程中实现
- 使用语法制导翻译方案的编译程序能同时进行语法分析和语义分析
- 语法制导翻译方案( SDT )是在产生式右部中嵌入了程序片段( 称为语义动作)的CFG
- 将一个S-SDD转换为SDT的方法是:将每个语义动作都放在产生式的最后
非递归的预测分析过程中进行翻译
- 要想在非递归的预测分析过程中进行翻译,需要扩展语法分析栈
- 非终结符A的继承属性和综合属性的计算时机不同
- 将非终结符A的继承属性和综合属性存放在不同的记录中
- 综合属性在A出现之前不可以计算
- 继承属性在A的儿子们都分析完毕之前就能计算
- 综合记录用于存放非终结符综合属性值
- 动作记录,用来存放指向将被执行的语义动作代码的指针
- 分析栈中的每一个记录都对应着一段执行代码
- 综合记录出栈时,要将综合属性值复制给后面特定的语义动作
- 变量展开时( 即变量本身的记录出栈时),如果其含有继承属性,则要将继承属性值复制给后面特定的语义动作