如何清除移位/重用警告? [英] How to remove shift/reduse warning?

查看:114
本文介绍了如何清除移位/重用警告?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个编译器,现在正在尝试制作解析器. 我收到此状态的警告: 状态89

I am trying to make a compiler and I am now trying to make the parser. I get a warning on this state : State 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
 ;

这里的问题是什么,我应该如何解决?我已经解决了一些移位/减少问题,但通常我不了解这个问题是什么. 非常感谢

What is the problem here and how could i probably fix it?I have already fixed some shift/reduce problems, but generally i haven't understand what this problem is. Thank you very much

推荐答案

您的问题引用的语法具有以下含义:

The grammar quoted by your question has the production:

cond: '(' cond ')'

但是在输出文件中引用的内容是:

But the one quoted from the output file has the production:

cond: '(' expr ')'

还有其他一些差异可以清楚地表明输出文件不是由引用的语法生成的.这使回答问题的任务变得复杂,尽管从根本上讲,这两种情况下的问题都是相同的.我将输出文件用作其余答案的参考.

There are some other discrepancies which make it clear that the output file was not generated from the quoted​ grammar. That complicates the task of answering your question, although at the root the problem is the same in both cases. I'm using the output file as a reference for the remainder of the answer.

因为您也有:

cond: expr

在任何cond派生带括号的字符串的上下文中都存在歧义. (状态119所示的冲突很清楚地表明了这一点.)例如,假设解析器遇到

there is an ambiguity in any context in which a cond derives a parenthesized string. (The conflict shown for State 119 shows that pretty clearly.) Suppose, for example, the parser encounters

not ( x )

x只能被还原为expr(通过l_value),但是有两种可能性:

x can only be reduced to expr (via l_value), but then there are two possibilities:

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

在允许使用cond的所有情况下都存在这种歧义.

This ambiguity exists in all contexts where cond is allowed.

将表达式按语法划分为布尔表达式和非布尔表达式是很棘手的,而且几乎没有必要.您最终允许将任何表达式用作布尔值(cond: expr),并且很有可能您将允许(或者您的用户希望您允许)将布尔值分配给变量.因此,最简单,最常见的解决方案是只说一个值是一个值,而一个表达式是一个表达式,而无需使用特殊大小写的布尔值.

Dividing expressions syntactically into boolean and non-boolean expressions is tricky, and mostly unnecessary. You eventually allow any expression to be used as a boolean (cond: expr), and it is quite likely that you will allow (or your users will expect you to allow) a boolean value to be assigned to a variable. So the easiest and most common solution is to just say that a value is a value and an expression is an expression, without special-casing booleans.

如果您确实需要在语法上将两者分开,则可以在

If you really feel the need to syntactically separate the two, you'll find an example in this recent question.

这篇关于如何清除移位/重用警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆