为什么这个语法没有减少/减少冲突?

时间:2017-04-10 18:23:51

标签: parsing bison reduce-reduce-conflict

考虑下面的内容(诚然荒谬 - 它已被大大简化以说明这一点)语法:

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在使用这个语法时没有抱怨减少/减少冲突,但对我来说似乎有一个。假设我们已经解析了negationExpressionconstantExpression;对我来说,根据上面的定义,解析器现在可以做两件事:

  1. 使用上面的规则1
  2. 将序列缩减为testRule
  3. 使用上面的规则2将constantExpression缩减为testRule(在这种情况下,negationExpression将保持不变,因此解析堆栈将如下所示:negationExpression testRule
  4. 但是没有发出警告,当我看到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)
    

    根据Bison docs

      

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

    这不是正确的情况吗?

1 个答案:

答案 0 :(得分:1)

不,这里不适用。

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

在你的语法中,testRule从不遵循任何事情。它(和negationExpression)只能在某些推导的最开始时减少。因此,如果(部分缩减的)输入以negationExpression constantExpression结尾,则无法将constantExpression缩减为testRule,因为起始符号的派生不能包含testRule - 初始位置。