If statement 美洲野牛在其他地方晃来晃去

If statement 美洲野牛在其他地方晃来晃去,if-statement,compiler-construction,grammar,bison,If Statement,Compiler Construction,Grammar,Bison,我的语法中有以下规则: block: TLBRACE statements TRBRACE | TLBRACE TRBRACE ; statements: statement | statements statement ; stateme

我的语法中有以下规则:

block:                  TLBRACE statements TRBRACE
                        | TLBRACE TRBRACE
                        ;


statements:             statement 
                        | statements statement 
                        ;

statement:              TIF TLPAREN expression TRPAREN TTHEN statement
                        | TIF TLPAREN expression TRPAREN TTHEN statement TELSE statement
                        | TWHILE TLPAREN expression TRPAREN statement 
                        | TDO statement TLPAREN expression TRPAREN 
                        | TFOR TLPAREN forinits TSEMICOLON expression TSEMICOLON expressions TRPAREN statement 
                        | block 
                        | declaration TSEMICOLON
                        | expression TSEMICOLON
                        ;
我意识到了悬而未决的问题。这就是我在语法文件顶部指定“%left TELSE”的原因。无论如何,即使我指示Bison优先使用TELSE令牌,也会产生移位/减少冲突。我还试图删除“%left TELSE”命令(只是想看看它是否有什么不同),但没有任何更改。我总是有同样的转变/减少冲突

我使用--verbose标志向Bison获得的输出是:

State 117

   32 statement: "if" "(" expression ")" "then" statement .  ["identifier", "string value", "double", "int", "lint", "message", "string", "double value", "int value", "(", "{", "}", "-", "do", "else", "for", "if", "while", "binary not"]
   33          | "if" "(" expression ")" "then" statement . "else" statement

    "else"  shift and going to state 122

    "else"    [reducing with rule 32 (statement)]
    $default  reducing with rule 32 (statement) 

当声明
%离开时,我消除了冲突。我不能给你一个完整的解释,但运算符优先级与逐个比较运算符有关。

这是一个常见问题。看一看哪一个解释了冲突解决的工作原理。

使用nonassoc解决此问题的最佳方法

%nonassoc THEN

%nonassoc ELSE

%%


statement:              TIF TLPAREN expression TRPAREN TTHEN statement %prec THEN

                        | TIF TLPAREN expression TRPAREN TTHEN statement TELSE statement


%%
在这里,解析器将标记推入堆栈,当
推送表达式时,如果下一个标记是
ELSE
,则会发生冲突


解析器应该根据
IF_语句
规则减少IF表达式,或者将下一个
ELSE
标记转移到堆栈中。您必须确定规则的优先级,在这种情况下,您必须使用
%nonassoc
%prec
ELSE
标记赋予比
if\u语句更高的优先级。在
%nonassoc
中,
ELSE
的优先级大于
THEN
,并且通过使用
%prec
如果station
的优先级小于
如果ELSE station
并且冲突已解决。

shift/reduce是一个警告,而不是一个错误。如果我指定,我希望不会发生shift/reduce冲突“%left TELSE”。没有写入任何错误。使用语句的生产规则是什么?看起来您可能正在使用令牌“else”“在你的语法中有两次。我编辑了要回答的问题。我认为你的答案是正确的,因为我通过去掉“then”标记去掉了移位/减少冲突。谢谢,谢谢你的回答。您是否可以添加一些解释,说明为什么这是最好的方法,以及它到底做了什么?在这里,解析器将令牌推入堆栈,当推送expr时,下一个令牌为ELSE时,将发生冲突,解析器应根据IF_语句规则减少IF expr,或者将下一个令牌移到堆栈中。您必须确定规则的优先级,在这种情况下,您必须使用%nonassoc和%prec为ELSE标记赋予比if_语句更高的优先级。在%nonassoc中,ELSE的优先级大于THEN,并且通过使用%prec priority of if_station小于if_ELSE station,不会发生冲突。谢谢!选择
edit
,将其包含在答案中可能不是一个坏主意。这次我给你建议了一个。