如何防止多个空规则发生 reduce/reduce 冲突?
How to prevent reduce/reduce conflicts for multiple empty rules?
我刚刚开始学习 Bison 的诀窍,对空规则非常困惑。所以我的第一个问题是,只能一个规则匹配空吗?我正在阅读 here 并想知道,如果我需要 2 条可以包含“0 或更多内容”的规则怎么办。这不会给解析器造成歧义吗?我已经对此进行了测试,它给了我一个 reduce/reduce 冲突。
更让我困惑的是我测试了一些玩具规则,例如:
rule1: TOKEN { printf("rule1"); }
| ANOTHER_TOKEN { printf("rule1"); }
;
rule2: ANOTHER_TOKEN { printf("rule2"); }
;
这显然是模棱两可的,因为规则 1 和规则 2 匹配相同的输入(我已经测试过了),但这并没有给我一个 reduce/reduce 冲突警告。有什么原因吗?应该不惜一切代价避免像上面的代码这样的事情吗?
您可以根据需要在同一 right-hand 侧设置任意数量的规则,无论它是否为空,只要它们永远不适用。
这很好:
foo_list: %empty
| foo_list foo
bar_list: %empty
| bar_list bar
但是,如果您随后尝试这样做,就会产生歧义:
either_list: foo_list | bar_list
因为空 either_list
指的是哪个备选方案并不清楚。两个空规则都适用。
另一方面,这很好:
both_list: foo_list bar_list
这里一个空 both_list
明确包含一个空 foo_list
后跟一个空 bar_list
.
(注意:第二个例子要求foo
和bar
可以通过第一个token来区分。如果不是,你会得到一个shift-reduce冲突。)
我刚刚开始学习 Bison 的诀窍,对空规则非常困惑。所以我的第一个问题是,只能一个规则匹配空吗?我正在阅读 here 并想知道,如果我需要 2 条可以包含“0 或更多内容”的规则怎么办。这不会给解析器造成歧义吗?我已经对此进行了测试,它给了我一个 reduce/reduce 冲突。
更让我困惑的是我测试了一些玩具规则,例如:
rule1: TOKEN { printf("rule1"); }
| ANOTHER_TOKEN { printf("rule1"); }
;
rule2: ANOTHER_TOKEN { printf("rule2"); }
;
这显然是模棱两可的,因为规则 1 和规则 2 匹配相同的输入(我已经测试过了),但这并没有给我一个 reduce/reduce 冲突警告。有什么原因吗?应该不惜一切代价避免像上面的代码这样的事情吗?
您可以根据需要在同一 right-hand 侧设置任意数量的规则,无论它是否为空,只要它们永远不适用。
这很好:
foo_list: %empty
| foo_list foo
bar_list: %empty
| bar_list bar
但是,如果您随后尝试这样做,就会产生歧义:
either_list: foo_list | bar_list
因为空 either_list
指的是哪个备选方案并不清楚。两个空规则都适用。
另一方面,这很好:
both_list: foo_list bar_list
这里一个空 both_list
明确包含一个空 foo_list
后跟一个空 bar_list
.
(注意:第二个例子要求foo
和bar
可以通过第一个token来区分。如果不是,你会得到一个shift-reduce冲突。)