3 自下而上计算
L 属性的自下而上计算
- 能实现任何基于 LL(1)文法的 L 属性定义
- 能实现许多基于 LR(1)文法的 L 属性定义
删除嵌入的动作
原来的翻译方案:
- E→TR
- R→+T\{\textbf{print}('+')\}R_1|-T\{\textbf{print}('-')\}R_1|\varepsilon
- T→\text{num}\{\textbf{print}(\text{num}.val)\}
把每个动作以 M→\varepsilon 形式的产生式替换,继承属性转成综合属性:
- E→TR
- R→+T\boldsymbol{M}R_1|-T\boldsymbol{N}R_1|\varepsilon
- T→\text{num}\{\textbf{print}(\text{num}.val)\}
- M→\varepsilon\{\textbf{print}('+')\}
- N→\varepsilon\{\textbf{print}('-')\}
继承属性在分析栈中
属性位置不可预测
- S→aAC\quad C.i=A.s
- S→bABC\quad C.i=A.s
- C→c\quad C.s=g(C.i)
问题:A 和 C 之间可能有 B,也可能没有,C.i 的值有两种可能
方法:增加标记非终结符,使得位置可以预测
- S→aAC\quad C.i=A.s
- S→bABMC\quad M.i=A.s;\ C.i=M.s
- C→c\quad C.s=g(C.i)
- M→\epsilon\quad M.s=M.i
继承属性是综合属性的函数
- S→aAC\quad C.i=f(A.s)
- C→c\quad C.s=g(C.i)
问题:继承属性不直接等于某个综合属性
方法:增加标记非终结符,把 f(A.s) 的计算移到对标记非终结符归约时进行
- S→aANC\quad N.i=A.s;\ C.i=N.s
- N→\epsilon\quad N.s=f(N.i)
- C→c\quad C.s=g(C.i)