Syntax 用于打印解析字符串的语法的语法定向定义 >考虑下面的语法: S->SaS|bB B->AcB| ε A->dAd| ε
对于上面给出的语法,编写语法导向的定义 打印正在分析的字符串,并为字符串“bddcab”构造带注释的分析树 解决方案: 现在重写上面的语法,我们有:Syntax 用于打印解析字符串的语法的语法定向定义 >考虑下面的语法: S->SaS|bB B->AcB| ε A->dAd| ε,syntax,context-free-grammar,parse-tree,Syntax,Context Free Grammar,Parse Tree,对于上面给出的语法,编写语法导向的定义 打印正在分析的字符串,并为字符串“bddcab”构造带注释的分析树 解决方案: 现在重写上面的语法,我们有: S->S1aS2 S->bB B->AcB1 B-> ε A->dA1d A-> ε ( The numbers 1 and 2 following the non-terminal actually denote subscripts. And the su
S->S1aS2
S->bB
B->AcB1
B-> ε
A->dA1d
A-> ε
( The numbers 1 and 2 following the non-terminal actually denote subscripts. And the subscripts in above grammar denote instances of the non-terminal.)
以上语法与语义规则一致
Productions Semantic Rules
S->S1aS2 S.val=S1.val+a.lexval + S2.val { print S.val }
S->bB S.val=b.lexval + B.val { Print S.val}
B->AcB1 B.val=A.val+c.lexval + B1.val
B-> ε
A->dA1d A.val=d.lexval + A1.val + d.lexval
A-> ε
** The '+' operator is merely for concatenation.
这个解决方案行吗?我觉得这可能不准确
这是带注释的解析树。我认为s规则中的那些打印操作会适得其反,因为s可能会出现多次 S可以生成SaS。但每一个都可以生成SA 基本上,如果要将打印表示构建为语义属性,则只有在语法完全求值后才能在语法之外进行打印,以确保只执行一次 这可以通过引入一个伪开始符号X来表示。S仅被减少到X一次,因此打印只发生一次,从顶级
S
拉出最后的val
X -> S { print S.val } // print the top-level S's val, just once.
另一种方法是使用真正的语法定向打印,这样,当解析减少时,打印的副作用就会发生。例如,右侧符号中类似Yacc的嵌入规则:
S -> S1 a { print a.lexeme } S2 { /* other semantic rules go here */ }
在识别终端的每个规则中,一旦识别出终端,就立即打印它。在这里,我们知道S1的缩减会导致它的所有终端都被打印出来(通过语法中类似的规则)。然后我们识别出一个
a
并将其打印出来,然后识别并缩小S2,从而使其所有终端都被打印出来。您可能认识到这与树的无序遍历非常相似。您是对的。干得好!是的,你对带注释的树也有意见吗。我只是依赖于综合属性。我们必须使用继承属性吗?我认为,在这种情况下,要使用继承属性,必须将整个语法更改为非左递归。