如何删除班次/减少警告?

时间:2017-04-13 11:18:40

标签: bison compiler-warnings shift-reduce-conflict

我正在尝试创建一个编译器,我现在正在尝试创建解析器。 我收到有关这种状态的警告:     国家89

   62 expr: '(' expr . ')'
   66     | expr . '+' expr
   67     | expr . '-' expr
   68     | expr . '*' expr
   69     | expr . '/' expr
   70     | expr . '%' expr
   74     | expr . '&' expr
   75     | expr . '|' expr
   77 cond: expr .
   78     | '(' expr . ')'
   82     | expr . '=' expr
   83     | expr . "<>" expr
   84     | expr . '<' expr
   85     | expr . '>' expr
   86     | expr . ">=" expr
   87     | expr . "<=" expr

    "<>"  shift, and go to state 91
    ">="  shift, and go to state 92
    "<="  shift, and go to state 93
    '+'   shift, and go to state 94
    '-'   shift, and go to state 95
    '|'   shift, and go to state 96
    '*'   shift, and go to state 97
    '/'   shift, and go to state 98
    '%'   shift, and go to state 99
    '&'   shift, and go to state 100
    '='   shift, and go to state 101
    '<'   shift, and go to state 102
    '>'   shift, and go to state 103
    ')'   shift, and go to state 119


$default  reduce using rule 77 (cond)


State 119

   62 expr: '(' expr ')' .
   78 cond: '(' expr ')' .

    "and"     reduce using rule 62 (expr)
    "and"     [reduce using rule 78 (cond)]
    "or"      reduce using rule 62 (expr)
    "or"      [reduce using rule 78 (cond)]
    ':'       reduce using rule 62 (expr)
    ':'       [reduce using rule 78 (cond)]
    ')'       reduce using rule 62 (expr)
    ')'       [reduce using rule 78 (cond)]
    $default  reduce using rule 62 (expr)

这部分的语法是:

expr:
    T_const |
    T_char_const | 
    l_value | 
    '(' expr ')' | 
    func_call |
    '+' expr | 
    '-' expr | 
    expr '+' expr |
    expr '-' expr | 
    expr '*' expr | 
    expr '/' expr | 
    expr '%' expr |
    T_true | T_false |
    '!' expr | 
     expr '&' expr |
    expr '|' expr
;

cond:
    '(' cond ')' |
     expr |
     T_not cond |
     cond T_and cond |
     cond T_or  cond |
     expr '=' expr |
     expr T_not_equal expr |
     expr '<' expr |
     expr '>' expr |
     expr T_greater_equal expr |
     expr T_less_equal expr
 ;

这里有什么问题,我怎么可能解决它?我已经解决了一些转移/减少问题,但通常我不明白这个问题是什么。 非常感谢你

1 个答案:

答案 0 :(得分:1)

你的问题所引用的语法有:

cond: '(' cond ')'

但是输出文件中引用的那个有生产:

cond: '(' expr ')'

还有一些其他差异表明输出文件不是从引用的语法生成的。这使得回答你的问题的任务变得复杂,尽管从根本上说问题在两种情况下都是相同的。我正在使用输出文件作为答案的其余部分的参考。

既然你也有:

cond: expr

cond派生带括号的字符串的任何上下文中都存在歧义。 (状态119显示的冲突非常清楚。)例如,假设解析器遇到

not ( x )

x只能缩减为expr(通过l_value),但有两种可能性:

not ( expr ) => not expr [ from expr: ( expr ) ]
             => not cond [ from cond: expr ]
not ( expr ) => not cond  [ from cond: ( eχpr ) ]

这种歧义存在于允许cond的所有上下文中。

将表达式语法分成布尔表达式和非布尔表达式是很棘手的,而且大部分都是不必要的。您最终允许任何表达式用作布尔值(cond: expr),并且您很可能允许(或您的用户希望您允许)将布尔值分配给变量。所以最简单和最常见的解决方案就是只说一个值是一个值,一个表达式是一个表达式,没有特殊的套管布尔值。

如果你真的觉得需要在语法上区分这两者,你会在this recent question中找到一个例子。