警告:"rule useless in parser due to conflicts" 在 Bison 中
Warning: "rule useless in parser due to conflicts" in Bison
我正在尝试制作一个 C 词法分析器,但我有一些警告:
rule useless in parser due to conflicts: sentenceList: sentenceList sentence
rule useless in parser due to conflicts: sentSelection: IF '(' expression ')' sentence
rule useless in parser due to conflicts: sentSelection: IF '(' expression ')' sentence ELSE sentence
rule useless in parser due to conflicts: sentSelection: SWITCH '(' expression ')' sentence
rule useless in parser due to conflicts: sentIteration: WHILE '(' expression ')' sentence
rule useless in parser due to conflicts: sentIteration: FOR '(' expression ';' expression ';' expression ')' sentence
这是警告来自的代码部分:
input: /* nothing */
| input line
;
line: '\n'
| sentence '\n'
;
sentence : sentComposed
|sentSelection
|sentExpression
|sentIteration
;
sentComposed: statementsList
|sentenceList
;
statementsList: statement
| statementsList statement
;
sentenceList: sentence
|sentenceList sentence
;
sentExpression: expression ';'
|';'
;
sentSelection: IF '(' expression ')' sentence
|IF '(' expression ')' sentence ELSE sentence
|SWITCH '(' expression ')' sentence
;
sentIteration: WHILE '(' expression ')' sentence
|DO sentence WHILE '(' expression ')' ';'
|FOR '(' expression ';' expression ';' expression ')' sentence
;
statement: DATATYPE varList
;
varList: aVar
|varList ',' aVar
;
aVar: variable inicial
;
variable: IDENTIFIER
;
initial: '=' NUM
;
我刚刚添加了更多信息
大写字母中的每个单词都是标记。
如果您需要任何其他信息,请告诉我
这里是您的语法的相当简化(但完整)的摘录。我已将 expression
声明为终端,以避免必须定义它:
%token expression IF
%%
sentence : sentComposed
|sentSelection
|sentExpression
sentComposed: sentenceList
sentenceList: sentence
|sentenceList sentence
sentExpression: expression ';'
|';'
sentSelection: IF '(' expression ')' sentence
当我 运行 通过 bison 时,它报告:
ez.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
ez.y: warning: 8 reduce/reduce conflicts [-Wconflicts-rr]
这些冲突是实际问题,如以下警告 ("due to conflicts") 所示:
ez.y:8.18-38: warning: rule useless in parser due to conflicts [-Wother]
|sentenceList sentence
^^^^^^^^^^^^^^^^^^^^^
ez.y:11.18-47: warning: rule useless in parser due to conflicts [-Wother]
sentSelection: IF '(' expression ')' sentence
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
当 bison 发现语法冲突时,它会根据一个简单的过程解决冲突:
- shift-reduce 冲突已解决,有利于 shift
- 化简-化简冲突的解决有利于语法中较早发生的产生式。
一旦这样做,可能会发现某些产品再也无法使用,因为它已从可能已减少的所有上下文中删除。这是语法有问题的明显迹象。 [注1]
这里的基本问题是 sentComposed
意味着语句可以只是 st运行g 在一起形成一个更长的语句。那么如果你写会发生什么:
IF (e) statement1 statement2
可能 statement1 statement2
是为了简化为单个 sentComposed
,这是 IF
的目标,所以这两个语句仅在 [=24= 时执行] 是真的。或者可能是 sentComposed
由带有目标 statement1
的 IF
语句组成,后跟 statement2
。在 C 术语中,区别在于:
if (e) { statement1; statement2; }
和
{ if (e) { statement1; } statement2; }
所以这是一个真正的歧义,您可能需要重新考虑缺少大括号才能修复它。
但这不是唯一的问题;你也有一堆减少减少冲突。这些以更简单的方式出现,因为上述语法的一部分是以下循环:
sentence: sentComposed
sentComposed: sentenceList
sentenceList: sentence
该循环意味着您的语法允许将单个 sentence
包装在任意数量的单位缩减中。你当然不是故意的;我确定您的意图是 sentComposed
仅在实际需要时使用。但是野牛不知道你的意图;它只知道你说什么。
同样,当您弄清楚您实际想要如何识别 sentComposed
的边界时,您可能会解决这个问题。
备注:
在某些情况下,冲突实际上并不是问题。例如,这两个产生式之间存在 shift-reduce 冲突;所谓"dangling-else"歧义:
sentSelection: IF '(' expression ')' sentence
|IF '(' expression ')' sentence ELSE sentence
在嵌套的 IF
语句中:
IF (e) IF (f) s1 ELSE s2
不清楚 ELSE
应该应用于内部还是外部 IF
。如果它适用于内部 IF
,则必须将其移位以允许 sentSelection
的第二次产生。如果它适用于外部 IF
,则必须先执行归约以完成内部(else-less)IF
,然后再将 ELSE
移入外部 IF
。 Bison 的默认操作 ("prefer shift") 在这种情况下完全正确,即立即移动 ELSE
。 (事实上,这就是为什么选择默认值 "prefer shift")。
我正在尝试制作一个 C 词法分析器,但我有一些警告:
rule useless in parser due to conflicts: sentenceList: sentenceList sentence
rule useless in parser due to conflicts: sentSelection: IF '(' expression ')' sentence
rule useless in parser due to conflicts: sentSelection: IF '(' expression ')' sentence ELSE sentence
rule useless in parser due to conflicts: sentSelection: SWITCH '(' expression ')' sentence
rule useless in parser due to conflicts: sentIteration: WHILE '(' expression ')' sentence
rule useless in parser due to conflicts: sentIteration: FOR '(' expression ';' expression ';' expression ')' sentence
这是警告来自的代码部分:
input: /* nothing */
| input line
;
line: '\n'
| sentence '\n'
;
sentence : sentComposed
|sentSelection
|sentExpression
|sentIteration
;
sentComposed: statementsList
|sentenceList
;
statementsList: statement
| statementsList statement
;
sentenceList: sentence
|sentenceList sentence
;
sentExpression: expression ';'
|';'
;
sentSelection: IF '(' expression ')' sentence
|IF '(' expression ')' sentence ELSE sentence
|SWITCH '(' expression ')' sentence
;
sentIteration: WHILE '(' expression ')' sentence
|DO sentence WHILE '(' expression ')' ';'
|FOR '(' expression ';' expression ';' expression ')' sentence
;
statement: DATATYPE varList
;
varList: aVar
|varList ',' aVar
;
aVar: variable inicial
;
variable: IDENTIFIER
;
initial: '=' NUM
;
我刚刚添加了更多信息 大写字母中的每个单词都是标记。 如果您需要任何其他信息,请告诉我
这里是您的语法的相当简化(但完整)的摘录。我已将 expression
声明为终端,以避免必须定义它:
%token expression IF
%%
sentence : sentComposed
|sentSelection
|sentExpression
sentComposed: sentenceList
sentenceList: sentence
|sentenceList sentence
sentExpression: expression ';'
|';'
sentSelection: IF '(' expression ')' sentence
当我 运行 通过 bison 时,它报告:
ez.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
ez.y: warning: 8 reduce/reduce conflicts [-Wconflicts-rr]
这些冲突是实际问题,如以下警告 ("due to conflicts") 所示:
ez.y:8.18-38: warning: rule useless in parser due to conflicts [-Wother]
|sentenceList sentence
^^^^^^^^^^^^^^^^^^^^^
ez.y:11.18-47: warning: rule useless in parser due to conflicts [-Wother]
sentSelection: IF '(' expression ')' sentence
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
当 bison 发现语法冲突时,它会根据一个简单的过程解决冲突:
- shift-reduce 冲突已解决,有利于 shift
- 化简-化简冲突的解决有利于语法中较早发生的产生式。
一旦这样做,可能会发现某些产品再也无法使用,因为它已从可能已减少的所有上下文中删除。这是语法有问题的明显迹象。 [注1]
这里的基本问题是 sentComposed
意味着语句可以只是 st运行g 在一起形成一个更长的语句。那么如果你写会发生什么:
IF (e) statement1 statement2
可能 statement1 statement2
是为了简化为单个 sentComposed
,这是 IF
的目标,所以这两个语句仅在 [=24= 时执行] 是真的。或者可能是 sentComposed
由带有目标 statement1
的 IF
语句组成,后跟 statement2
。在 C 术语中,区别在于:
if (e) { statement1; statement2; }
和
{ if (e) { statement1; } statement2; }
所以这是一个真正的歧义,您可能需要重新考虑缺少大括号才能修复它。
但这不是唯一的问题;你也有一堆减少减少冲突。这些以更简单的方式出现,因为上述语法的一部分是以下循环:
sentence: sentComposed
sentComposed: sentenceList
sentenceList: sentence
该循环意味着您的语法允许将单个 sentence
包装在任意数量的单位缩减中。你当然不是故意的;我确定您的意图是 sentComposed
仅在实际需要时使用。但是野牛不知道你的意图;它只知道你说什么。
同样,当您弄清楚您实际想要如何识别 sentComposed
的边界时,您可能会解决这个问题。
备注:
在某些情况下,冲突实际上并不是问题。例如,这两个产生式之间存在 shift-reduce 冲突;所谓"dangling-else"歧义:
sentSelection: IF '(' expression ')' sentence |IF '(' expression ')' sentence ELSE sentence
在嵌套的
IF
语句中:IF (e) IF (f) s1 ELSE s2
不清楚
ELSE
应该应用于内部还是外部IF
。如果它适用于内部IF
,则必须将其移位以允许sentSelection
的第二次产生。如果它适用于外部IF
,则必须先执行归约以完成内部(else-less)IF
,然后再将ELSE
移入外部IF
。 Bison 的默认操作 ("prefer shift") 在这种情况下完全正确,即立即移动ELSE
。 (事实上,这就是为什么选择默认值 "prefer shift")。