yacc - 这个 YACC 代码是如何产生 shift/reduce 冲突的?(很简单)
问题描述
我真的试图理解为什么这会产生冲突,但我认为我遗漏了一些东西。
%token D
%start a
%%
a
: b
| a '+' b
;
b
: c
| c '+' '+'
;
c
: D
;
我发现相同的“+”字符造成了问题,但我在这段代码中找不到任何歧义......
我真的很感激
解决方案
让我们按如下方式标记您的替代方案:
a
: b // a1
| a '+' b // a2
;
b
: c // b1
| c '+' '+' // b2
;
现在,如果解析器刚刚解析了 ac
并且下一个标记是 a '+'
,则有两种可能性:+
可以是 的一部分c '+' '+'
,在这种情况下b2
应该选择,或者+
可以是 的一部分a '+' b
,在这种情况下b1
应该选择并且a2
将被选择下一个。但是,如果没有看到第二个,解析器无法知道是哪一个,+
而 YACC 作为LALR(1)
解析器生成器,只能向前看一个令牌,而不是两个。
所以这就是为什么你会发生冲突。正如已经指出的,解决这个问题的方法是制作++
一个令牌。这还有一个好处,即在 中不再允许使用空格++
,这更接近于现有语言的语法。
推荐阅读
- python - 尝试用python查询两个mysql数据库并将结果写入google sheet(每天自动更新)
- python - 为什么我的代码没有在 main def 中发布请求的列?
- c - C 常量表达式。const 变量作为常量表达式
- google-apps-script - 来自文件夹的主数据表,拉取的文件之间没有空格
- javascript - 从 json 文件创建 2D 字典以获取计数
- java - Weblogic 升级到 12.2.1.3.0 java.lang.NoSuchMethodError: org.springframework.util.ReflectionUtils.accessibleConstructor
- git - 为什么冲突标记是以它们的方式创建的,为什么合并会以这种方式工作?
- python - 这种表的一种热编码
- javascript - 在 pjax 重新加载容器后,Laravel livewire 点击未执行
- javascript - axios 中的 GET/POST 不工作,但 fetch 工作