如何检测 bison 中的 shift/reduce 冲突?
How to detect shift/reduce conflicts in bison?
我是 Bison 的新手。
我已经制作了 .y 文件,但在编译时出现此错误:
警告:42 shift/reduce 冲突 [-Wconflicts-sr]
我打开了生成的 .output 文件,我看到了以下内容,但无法理解,也无法找出问题所在。
这是我的 .output 文件的一部分:
State 63
56 expr_decl: KW_NOT expr_decl . [KW_END, KW_OR, OP_OR, KW_AND, OP_AND, '>', OP_LESSOREQUAL, OP_GREATEROREQUAL, '=', OP_NOTEQUAL, '<', '*', '/', KW_DIV, KW_MOD, ';', ')', '+', '-']
59 | expr_decl . '*' expr_decl
60 | expr_decl . '/' expr_decl
61 | expr_decl . KW_DIV expr_decl
62 | expr_decl . KW_MOD expr_decl
63 | expr_decl . '+' expr_decl
64 | expr_decl . '-' expr_decl
65 | expr_decl . '=' expr_decl
66 | expr_decl . '<' expr_decl
67 | expr_decl . '>' expr_decl
68 | expr_decl . OP_NOTEQUAL expr_decl
69 | expr_decl . OP_LESSOREQUAL expr_decl
70 | expr_decl . OP_GREATEROREQUAL expr_decl
71 | expr_decl . OP_AND expr_decl
72 | expr_decl . KW_AND expr_decl
73 | expr_decl . KW_OR expr_decl
74 | expr_decl . OP_OR expr_decl
'+' shift, and go to state 87
'-' shift, and go to state 88
'+' [reduce using rule 56 (expr_decl)]
'-' [reduce using rule 56 (expr_decl)]
$default reduce using rule 56 (expr_decl)
Conflict between rule 56 and token KW_OR resolved as reduce (KW_OR < KW_NOT).
Conflict between rule 56 and token OP_OR resolved as reduce (OP_OR < KW_NOT).
Conflict between rule 56 and token KW_AND resolved as reduce (KW_AND < KW_NOT).
Conflict between rule 56 and token OP_AND resolved as reduce (OP_AND < KW_NOT).
Conflict between rule 56 and token '>' resolved as reduce ('>' < KW_NOT).
Conflict between rule 56 and token OP_LESSOREQUAL resolved as reduce (OP_LESSOREQUAL < KW_NOT).
Conflict between rule 56 and token OP_GREATEROREQUAL resolved as reduce (OP_GREATEROREQUAL < KW_NOT).
Conflict between rule 56 and token '=' resolved as reduce ('=' < KW_NOT).
Conflict between rule 56 and token OP_NOTEQUAL resolved as reduce (OP_NOTEQUAL < KW_NOT).
Conflict between rule 56 and token '<' resolved as reduce ('<' < KW_NOT).
Conflict between rule 56 and token '*' resolved as reduce ('*' < KW_NOT).
Conflict between rule 56 and token '/' resolved as reduce ('/' < KW_NOT).
Conflict between rule 56 and token KW_DIV resolved as reduce (KW_DIV < KW_NOT).
Conflict between rule 56 and token KW_MOD resolved as reduce (KW_MOD < KW_NOT).
有什么帮助吗?我已经搜索了几个小时,但仍然一无所获..
这是我的声明部分:
%left KW_OR OP_OR
%left KW_AND OP_AND
%left '>' OP_LESSOREQUAL OP_GREATEROREQUAL
%left '=' OP_NOTEQUAL '<'
%left OP_PLUS OP_MINUS
%left '*' '/' KW_DIV KW_MOD
%left cast
%right POSITIVE NEGATIVE
%right KW_NOT '!'
这是我在 bison 中的规则:
expr_decl :
| REAL
| POSINT
| '!' expr_decl { $$ = template("!(%s)", ); }
| KW_NOT expr_decl { $$ = template("not(%s)", ); }
| '+' expr_decl %prec POSITIVE { $$ = template("+(%s)", ); }
| '-' expr_decl %prec NEGATIVE { $$ = template("-(%s)", ); }
| expr_decl '*' expr_decl { $$ = template("%s * %s", , ); }
| expr_decl '/' expr_decl { $$ = template("%s / %s", , ); }
| expr_decl KW_DIV expr_decl { $$ = template("%s div %s", , ); }
| expr_decl KW_MOD expr_decl { $$ = template("%s mod %s", , ); }
| expr_decl '+' expr_decl %prec OP_PLUS{ $$ = template("%s + %s", , ); }
| expr_decl '-' expr_decl %prec OP_MINUS{ $$ = template("%s + %s", , ); }
| expr_decl '=' expr_decl { $$ = template("%s = %s", , ); }
| expr_decl '<' expr_decl { $$ = template("%s < %s", , ); }
| expr_decl '>' expr_decl { $$ = template("%s > %s", , ); }
| expr_decl OP_NOTEQUAL expr_decl { $$ = template("%s <> %s", , ); }
| expr_decl OP_LESSOREQUAL expr_decl { $$ = template("%s <= %s", , ); }
| expr_decl OP_GREATEROREQUAL expr_decl { $$ = template("%s >= %s", , ); }
| expr_decl OP_AND expr_decl { $$ = template("%s && %s", , ); }
| expr_decl KW_AND expr_decl { $$ = template("%s and %s", , ); }
| expr_decl KW_OR expr_decl { $$ = template("%s || %s", , ); }
| expr_decl OP_OR expr_decl { $$ = template("%s or %s", , ); }
| '(' expr_decl ')' { $$ = template("(%s)", ); }
;
这部分输出文件:
'+' shift, and go to state 87
'-' shift, and go to state 88
'+' [reduce using rule 56 (expr_decl)]
'-' [reduce using rule 56 (expr_decl)]
告诉您在此状态下您有两个 shift/reduce 冲突,在前瞻符号 '+'
和 '-'
上。 reduce 操作周围的 [
..]
表示该操作已被删除(解决有利于转变的冲突)。
消息:
Conflict between rule 56 and token KW_OR resolved as reduce (KW_OR < KW_NOT).
Conflict between rule 56 and token OP_OR resolved as reduce (OP_OR < KW_NOT).
Conflict between rule 56 and token KW_AND resolved as reduce (KW_AND < KW_NOT).
:
告诉您有关 shift/reduce 已通过语法中的优先规则解决的冲突(因此不包括在警告中的 42 shift/reduce 冲突中)。
优先规则无法解决 '+'
和 '-'
的冲突,因为您没有为这些标记设置优先顺序。
我是 Bison 的新手。 我已经制作了 .y 文件,但在编译时出现此错误:
警告:42 shift/reduce 冲突 [-Wconflicts-sr]
我打开了生成的 .output 文件,我看到了以下内容,但无法理解,也无法找出问题所在。
这是我的 .output 文件的一部分:
State 63
56 expr_decl: KW_NOT expr_decl . [KW_END, KW_OR, OP_OR, KW_AND, OP_AND, '>', OP_LESSOREQUAL, OP_GREATEROREQUAL, '=', OP_NOTEQUAL, '<', '*', '/', KW_DIV, KW_MOD, ';', ')', '+', '-']
59 | expr_decl . '*' expr_decl
60 | expr_decl . '/' expr_decl
61 | expr_decl . KW_DIV expr_decl
62 | expr_decl . KW_MOD expr_decl
63 | expr_decl . '+' expr_decl
64 | expr_decl . '-' expr_decl
65 | expr_decl . '=' expr_decl
66 | expr_decl . '<' expr_decl
67 | expr_decl . '>' expr_decl
68 | expr_decl . OP_NOTEQUAL expr_decl
69 | expr_decl . OP_LESSOREQUAL expr_decl
70 | expr_decl . OP_GREATEROREQUAL expr_decl
71 | expr_decl . OP_AND expr_decl
72 | expr_decl . KW_AND expr_decl
73 | expr_decl . KW_OR expr_decl
74 | expr_decl . OP_OR expr_decl
'+' shift, and go to state 87
'-' shift, and go to state 88
'+' [reduce using rule 56 (expr_decl)]
'-' [reduce using rule 56 (expr_decl)]
$default reduce using rule 56 (expr_decl)
Conflict between rule 56 and token KW_OR resolved as reduce (KW_OR < KW_NOT).
Conflict between rule 56 and token OP_OR resolved as reduce (OP_OR < KW_NOT).
Conflict between rule 56 and token KW_AND resolved as reduce (KW_AND < KW_NOT).
Conflict between rule 56 and token OP_AND resolved as reduce (OP_AND < KW_NOT).
Conflict between rule 56 and token '>' resolved as reduce ('>' < KW_NOT).
Conflict between rule 56 and token OP_LESSOREQUAL resolved as reduce (OP_LESSOREQUAL < KW_NOT).
Conflict between rule 56 and token OP_GREATEROREQUAL resolved as reduce (OP_GREATEROREQUAL < KW_NOT).
Conflict between rule 56 and token '=' resolved as reduce ('=' < KW_NOT).
Conflict between rule 56 and token OP_NOTEQUAL resolved as reduce (OP_NOTEQUAL < KW_NOT).
Conflict between rule 56 and token '<' resolved as reduce ('<' < KW_NOT).
Conflict between rule 56 and token '*' resolved as reduce ('*' < KW_NOT).
Conflict between rule 56 and token '/' resolved as reduce ('/' < KW_NOT).
Conflict between rule 56 and token KW_DIV resolved as reduce (KW_DIV < KW_NOT).
Conflict between rule 56 and token KW_MOD resolved as reduce (KW_MOD < KW_NOT).
有什么帮助吗?我已经搜索了几个小时,但仍然一无所获..
这是我的声明部分:
%left KW_OR OP_OR
%left KW_AND OP_AND
%left '>' OP_LESSOREQUAL OP_GREATEROREQUAL
%left '=' OP_NOTEQUAL '<'
%left OP_PLUS OP_MINUS
%left '*' '/' KW_DIV KW_MOD
%left cast
%right POSITIVE NEGATIVE
%right KW_NOT '!'
这是我在 bison 中的规则:
expr_decl :
| REAL
| POSINT
| '!' expr_decl { $$ = template("!(%s)", ); }
| KW_NOT expr_decl { $$ = template("not(%s)", ); }
| '+' expr_decl %prec POSITIVE { $$ = template("+(%s)", ); }
| '-' expr_decl %prec NEGATIVE { $$ = template("-(%s)", ); }
| expr_decl '*' expr_decl { $$ = template("%s * %s", , ); }
| expr_decl '/' expr_decl { $$ = template("%s / %s", , ); }
| expr_decl KW_DIV expr_decl { $$ = template("%s div %s", , ); }
| expr_decl KW_MOD expr_decl { $$ = template("%s mod %s", , ); }
| expr_decl '+' expr_decl %prec OP_PLUS{ $$ = template("%s + %s", , ); }
| expr_decl '-' expr_decl %prec OP_MINUS{ $$ = template("%s + %s", , ); }
| expr_decl '=' expr_decl { $$ = template("%s = %s", , ); }
| expr_decl '<' expr_decl { $$ = template("%s < %s", , ); }
| expr_decl '>' expr_decl { $$ = template("%s > %s", , ); }
| expr_decl OP_NOTEQUAL expr_decl { $$ = template("%s <> %s", , ); }
| expr_decl OP_LESSOREQUAL expr_decl { $$ = template("%s <= %s", , ); }
| expr_decl OP_GREATEROREQUAL expr_decl { $$ = template("%s >= %s", , ); }
| expr_decl OP_AND expr_decl { $$ = template("%s && %s", , ); }
| expr_decl KW_AND expr_decl { $$ = template("%s and %s", , ); }
| expr_decl KW_OR expr_decl { $$ = template("%s || %s", , ); }
| expr_decl OP_OR expr_decl { $$ = template("%s or %s", , ); }
| '(' expr_decl ')' { $$ = template("(%s)", ); }
;
这部分输出文件:
'+' shift, and go to state 87
'-' shift, and go to state 88
'+' [reduce using rule 56 (expr_decl)]
'-' [reduce using rule 56 (expr_decl)]
告诉您在此状态下您有两个 shift/reduce 冲突,在前瞻符号 '+'
和 '-'
上。 reduce 操作周围的 [
..]
表示该操作已被删除(解决有利于转变的冲突)。
消息:
Conflict between rule 56 and token KW_OR resolved as reduce (KW_OR < KW_NOT).
Conflict between rule 56 and token OP_OR resolved as reduce (OP_OR < KW_NOT).
Conflict between rule 56 and token KW_AND resolved as reduce (KW_AND < KW_NOT).
:
告诉您有关 shift/reduce 已通过语法中的优先规则解决的冲突(因此不包括在警告中的 42 shift/reduce 冲突中)。
优先规则无法解决 '+'
和 '-'
的冲突,因为您没有为这些标记设置优先顺序。