我的语法中有以下规则:
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令牌,也会产生一个shift / reduce冲突。我还尝试删除“%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)
答案 0 :(得分:2)
我在宣布%left TTHEN
时摆脱了冲突。我不能给你一个完整的解释,但是运算符优先级与逐个比较运算符有关。
答案 1 :(得分: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
标记移入堆栈。您必须确定规则的优先级,在这种情况下,您必须使用ELSE
和if_statement
使%nonassoc
令牌的优先级高于%prec
。 %nonassoc
ELSE
优先级THEN
超过%prec
,使用if_statment
优先级if_else_statment
小于TestList
且冲突已经解决了。
答案 2 :(得分:0)
这是一个经常被问到的问题。请查看解释冲突解决方案如何运作的Reforming the grammar to remove shift reduce conflict in if-then-else。