【问题标题】:Why can't a compiler have a "shift/shift" conflict?为什么编译器不能有“移位/移位”冲突?
【发布时间】:2012-11-26 15:25:09
【问题描述】:

我目前正在研究编译器,据我所知,在 LR(0) 中存在“shift/reduce”或“reduce/reduce”冲突的情况,但不可能有“shift/shift”冲突!为什么我们不能有“班次/班次”冲突?

【问题讨论】:

  • 存在 reduce-reduce 冲突,因为它们是可以选择减少句柄的 2 个产生式。存在 shift-reduce 冲突,因为您可以通过一些生产来进行 shift 和 reduce,并且显然仍然可以继续进行解析。移位只意味着一件事,您推进输入流,因此不会发生移位冲突。

标签: parsing compiler-construction compilation lr


【解决方案1】:

当解析器无法判断是移位(将下一个输入标记推入解析堆栈顶部)还是归约(从解析堆栈中弹出一系列终端和非终端)时,就会发生移位/归约冲突。归约/归约冲突是解析器知道归约,但不知道要执行哪个归约。

如果您遇到移位/移位冲突,解析器会知道它需要将下一个标记推入其解析堆栈,但不知道如何去做。由于只有一种方法可以将令牌推送到解析堆栈上,因此这种形式通常不会有任何冲突。

也就是说,如果您有一个奇怪的设置,其中有两个或多个转换从给定的解析状态引出并标有相同的终端符号,那么理论上可能存在移位/移位冲突。在那种情况下,冲突将是是否转移并进入一个状态或转移并进入另一个状态。如果您尝试将自动机压缩为更少的状态并且操作不正确,或者您尝试构建非确定性解析自动机,则可能会发生这种情况。实际上,这永远不会发生。

希望这会有所帮助!

【讨论】:

  • LL 解析器中的 FIRST-FIRST 冲突被左分解消除了,我还读到左分解用于消除不确定性。语法非确定性的 FIRST-FIRST 冲突表现也是如此。 Shift-Shift 冲突(如果我们假设它存在)也类似于 FF 冲突。同样,我阅读了强制关联和/或优先级消除了 SR 和 RR 冲突,也消除了语法的歧义。那么SR和RR冲突是语法歧义的表现吗?
  • 语法既可以是确定性的,也可以是左因子的——两者并不相互排斥。 (顺便说一下,您的意思是“模棱两可”而不是“确定性”吗?)并非所有 FIRST/FIRST 冲突都可以通过左分解来消除,因为某些语言不是 LL(1),因此没有任何 LL (1) 语法。因为 LL 和 LR 解析器以根本不同的方式工作,所以我认为在 FIRST/FIRST 冲突和 shift/shift 或 shift/reduce 冲突之间画一个平行线并不容易。这些发生的原因非常不同。
  • 虽然每个模棱两可的语法都会导致移位/归约或归约/归约冲突,但反之则不然。你可以有一个明确的语法,但仍然会导致这些冲突,因为并非所有上下文无关语言都有 LR 语法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
相关资源
最近更新 更多