Syntax 用于打印解析字符串的语法的语法定向定义 >考虑下面的语法: S->SaS|bB B->AcB| ε A->dAd| ε

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

对于上面给出的语法,编写语法导向的定义 打印正在分析的字符串,并为字符串“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 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,从而使其所有终端都被打印出来。您可能认识到这与树的无序遍历非常相似。

您是对的。干得好!是的,你对带注释的树也有意见吗。我只是依赖于综合属性。我们必须使用继承属性吗?我认为,在这种情况下,要使用继承属性,必须将整个语法更改为非左递归。