2

我的语法中有以下规则:

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
                        ;

我知道悬空的 else 问题。这就是我在语法文件顶部指定“%left TELSE”的原因。无论如何,即使我指示 Bison 优先使用 TELSE 令牌,也会产生移位/减少冲突。我还尝试删除“%left TELSE”命令(只是看看它是否有任何区别)并且没有任何变化。我总是有同样的转变/减少冲突。

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

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) 
4

3 回答 3

2

我在声明时摆脱了冲突%left TTHEN。我不能给你一个完整的解释,但运算符优先级与一个接一个地比较运算符有关。

于 2013-04-24T14:38:29.083 回答
1

使用%nonassoc.

%nonassoc THEN

%nonassoc ELSE

%%


statement:              TIF TLPAREN expression TRPAREN TTHEN statement %prec THEN

                        | TIF TLPAREN expression TRPAREN TTHEN statement TELSE statement


%%

在这里,解析器将令牌推入堆栈,当IF表达式被推送时,下一个令牌是ELSE,就会发生冲突。

解析器应该根据if_statement规则减少 IF 表达式,或者它应该将下一个ELSE标记移入堆栈。您必须确定规则的优先级,在这种情况下,您必须比使用and赋予ELSE令牌更高的优先级。在优先级大于,并且通过使用优先级小于并且冲突得到解决。if_statement%nonassoc%prec%nonassocELSETHEN%precif_statmentif_else_statment

于 2017-12-28T08:23:19.173 回答
0

这是一个经常被问到的问题。看看改革语法以消除 if-then-else 中的 shift reduce 冲突,它解释了冲突解决的工作原理。

于 2013-04-25T12:12:49.047 回答