#语法制导
语义分析的主流技术是语法制导翻译技术。
语法制导是带有属性和规则的上下文无关文法。
属性:在上下文无关文法的基础上,为每个文法符号(终结符或非终结符)配备若干相关的“值”,称为属性。属性可以计算和传递。
规则:对于文法的每个产生式都配备了一组属性的计算规则。
#综合属性和继承属性
每个文法产生式 $A \rightarrow \alpha$ 有一组形式为 $b : = f \left( c _ { 1 } , c _ { 2 } , \cdots , c _ { k } \right)$ 的语义规则,其中 $f$ 是函数,$b$ 和 $c _ { 1 } , c _ { 2 } , \cdots , c _ { k }$ 是该产生式文法符号的属性。
#综合属性
如果 $b$ 是 $A$ 的属性,$c _ { 1 } , c _ { 2 } , \cdots , c _ { k }$ 是产生式右部文法符号的属性或 $A$ 的其它属性。属性值由分析树中它的子结点的属性值来计算。
#继承属性
如果 $b$ 是产生式右部某个文法符号 $A$ 的属性, $c _ { 1 } , c _ { 2 } , \cdots , c _ { k }$ 是产生式右部文法符号的属性或 $A$ 的其它属性。属性值由结点的兄弟结点及父结点的属性值来计算。
#关于属性
- 终结符只有综合属性,并且这些综合属性通常由词法分析器提供。因为终结符没有任何的子结点。
- 非终结符号既有综合属性也可有继承属性,文法的开始符号没有继承属性,除非另外加以说明。因为开始符号没有任何的兄弟结点或者父结点。
- 文法符号的综合属性集和继承属性集的交集应为空。
- 对出现在产生式右边的继承属性和出现在产生式左边的综合属性都必须提供一个计算规则。属性计算规则中只能使用相应产生式中的文法符号的属性。
- 出现在产生式左边的继承属性和出现在产生式右边的综合属性不由所给的产生式的属性计算规则进行计算,它们由其它产生式的属性规则计算或者由属性计算器的参数提供。
#属性文法
属性文法是指语义规则函数无副作用的语法制导定义。
副作用指的是过程调用或程序段(比如打印值、输出中间代码等)。
🌰在产生式的语义规则中定义 print(E.val)
#注释分析树
每个结点的属性值都标注出来的分析树,称为注释分析树。
分析树是(最左、最右)推导的图形表示。每个分支结点由非终结符标记,子结点由该终结符本次推导所用产生式的右部的各符号依次标记。
#属性依赖图
在一棵分析树中的结点的继承属性和综合属性之间的相互依赖关系可以由称作依赖图的一个有向图来描述。
#构造方法
- 为每一个包含过程调用的语义规则引入一个虚拟综合属性 b,这样把每一个语义规则都写成 $b : = f \left( c _ { 1 } , c _ { 2 } , \cdots , c _ { k } \right)$ 的形式。
- 依赖图中为每一个属性设置一个结点,如果属性b依赖于属性 c,则从属性c的结点有一条有向边连到属性 b 的结点。
简单的说,如果一个属性 n 需要另一个属性 m 才能进行计算,那么添加一个有向线由 m 指向 n。
#属性的计算次序
良定义的:若一个属性文法不存在属性之间的循环依赖关系,则称该文法为良定义的。
如果是良定义的,那么依赖图的任一拓扑排序都是一个合理的属性计算顺序。