如何在Bison中解决这种减少/减少冲突的问题?

时间:2012-06-07 06:58:52

标签: bison ambiguity reduce-reduce-conflict

以下是[filename] .output的摘录     国家94

   32 expr: expr . opt_at_type '.' TYPEID '(' opt_expr_list ')'
   39     | expr . '+' expr
   40     | expr . '-' expr
   41     | expr . '*' expr
   42     | expr . '/' expr
   42     | expr '/' expr .
   44     | expr . '<' expr
   45     | expr . LE expr
   46     | expr . '=' expr

    '@'  shift, and go to state 73

    '.'       reduce using rule 23 (opt_at_type)
    '.'       [reduce using rule 42 (expr)]
    $default  reduce using rule 42 (expr)

    opt_at_type  go to state 74

opt_at_type定义为:

    opt_at_type:
            { $$ = idtable.add_string("SELF_TYPE"); }
            |       '@' TYPEID
            { $$ = $2;   }
            ;

你能告诉我为什么会这样吗?

2 个答案:

答案 0 :(得分:1)

您遇到的问题是,仅考虑yacc优先级以解决转移/减少冲突,而不是减少/减少。在这种情况下,opt_at_type规则可以匹配空字符串(它是可选的),从而导致减少/减少冲突。

要解决此问题,您需要解除规则以摆脱epsilon生产:

expr: expr '.' TYPEID '(' opt_expr_list ')'
    | expr '@' TYPEID '.' TYPEID '(' opt_expr_list ')'
    | expr '+' expr
       :

如果没有epsilon生产,它不需要提前减少,因此冲突变成了转移/减少冲突,通常可以通过yacc优先级来解决。

答案 1 :(得分:0)

当Bison看到以下内容时:

expr '/' expr '.'

它不知道这是否等同于:

1) expr opt_at_type '.'

OR

2) expr '/' expr opt_at_type '.'

对于1)它会首先将expr '/' expr减少到expr,而对于2)它会先减少/ *清空* /到opt_at_type

所以我们发现了歧义,为了解决这个问题,你必须确定你想要的语法。一种解决方案是将第一个expr规则作为单独的规则,以便它不能在其他表达式中使用,如下所示:

typeexpr: expr opt_at_type '.' TYPEID '(' opt_expr_list ')'