继承属性inh和综合属性syn的作用
因为文法不是为了翻译而定义的,而是以语法分析为目的进行定义的,因此可能会产生语法分析树的结构和源代码的抽象语法不"匹配”.
例如,下面的文法便是按照人类的算术习惯定义的.比如加法就定义为 E = E + T E=E+T E=E+T,乘法就定义为 T = T × F T=T\times F T=T×F.但如果要进行语法分析,这两个文法就存在左递归的问题,需要消除左递归,
例如,对于乘法 T = T × F T=T\times F T=T×F,消除左递归后的文法如下.
可见,由于 T ′ T' T′的引入,导致语法分析树的结构与人们的乘法习惯不匹配.这时候就需要继承属性inh和综合属性syn解决这种不匹配.
例如,对于本例子,运算符 ∗ * ∗分量是通过继承得到的。更淮确地说, 产生式 T ′ → ∗ F T 1 ′ T^{\prime} \rightarrow* F T_{1}^{\prime} T′→∗FT1′的头 T ′ T^{\prime} T′继承了产生式体中*的左运算分量。给定一个项 x ∗ y ∗ z x * y * z x∗y∗z, 对应于 ∗ y ∗ z * y * z ∗y∗z的子树的根结点䉻继承了 x x x的值。对应于 ∗ z * z ∗z的子树的根结点继承了 x ∗ y x * y x∗y的 值 。 如 果 项 中 还 有 更 茤 的 因 子 , ~我 们 可 以 继续这样的处理过程。当所有的因子都处理完毕后, 这个结果就通过综合属性上传到树的根部.
上面是龙书的原话,其实挺难以理解的,我们用例子帮助理解.例如上图, F . v a l F.val F.val和 F × T ′ F\times T' F×T′的值通过inh从左到右,从上往下传递(蓝色箭头),直到叶节点 T ′ → ϵ T'\to \epsilon T′→ϵ,此时计算结束,结果通过syn从下往上(绿色节点)传递到根节点 T . v a l T.val T.val.最终结果如下.