0

考虑以下(当然是荒谬的 - 为了说明这一点,它已被大大简化)语法:

negationExpression
    : TOK_MINUS constantExpression %prec UNARYOP
    | testRule
    ;

constantExpression
    : TOK_INTEGER_CONSTANT
    | TOK_FLOAT_CONSTANT
    ;

testRule
    : negationExpression constantExpression  // call this Rule 1
    | constantExpression   // Rule 2
    ;

在此语法上运行时,Bison 不会抱怨减少/减少冲突,但对我来说似乎有一个。假设我们已经解析了 anegationExpression和 a constantExpression; 对我来说,基于上述定义,解析器现在可以做两件事:

  1. testRule使用上面的规则 1将序列简化为
  2. 使用上面的规则 2将 减少constantExpression到(在这种情况下将保持不变,因此解析堆栈将如下所示:)testRulenegationExpressionnegationExpression testRule

但是没有发出警告,当我查看 Bison 生成的 .output 文件时,似乎没有任何歧义:

state 5

    6 testRule: constantExpression .

    $default  reduce using rule 6 (testRule)
...
state 9

    5 testRule: negationExpression constantExpression .

    $default  reduce using rule 5 (testRule)

根据野牛文档

如果有两个或多个规则适用于相同的输入序列,则会发生 reduce/reduce 冲突。

这不正是这里的情况吗?

4

1 回答 1

1

不,它不适用于这里。

“输入序列”是一个不幸的措辞;真正的意思是“相同的输入”,或者更明确地说,“有效输入的相同前缀子序列”。换句话说,如果有两个或多个规则可以应用于整个输入,直到当前读取点(并考虑到前瞻)。

在你的语法中,testRule永远不要遵循任何东西。它 (and negationExpression) 只能在某些推导的最开始被归约。因此,如果(部分缩减的)输入以 结尾negationExpression constantExpression,则不可能缩减constantExpression为,testRule因为起始符号的推导不能包含testRule在非初始位置。

于 2017-04-10T19:25:02.740 回答