📜  使用 LR 解析器解析歧义文法

📅  最后修改于: 2021-09-27 14:28:17             🧑  作者: Mango

LR 解析器可用于解析歧义文法。 LR 解析器根据语法的某些规则(运算符的优先级和/或结合性)解决歧义语法解析表中的冲突(移位/归约或归约/归约)。

例子:
让我们采用以下歧义语法:

E -> E+E
E -> E*E
E -> id 

让我们假设,语法的运算符(+ 和 *)的优先级和结合性如下:

  • “+”和“*”都是左结合的,
  • “*”的优先级高于“+”的优先级。

如果我们使用 LALR(1) 解析器,LR(1) 项 DFA 将是:

从 LR(1) 项 DFA 中我们可以看到状态 I 5和 I 6中存在 shift/reduce 冲突。所以解析表如下:

在“+”和“*”上的 I 5和 I 6中都有 shift 和 reduce 移动。为了解决这个冲突,即确定哪些移动要保留,哪些要从表中丢弃,我们将使用运算符的优先级和结合性。
考虑输入字符串:

id + id + id 

让我们看看解析器根据上面的解析表移动到冲突状态。

  • 如果我们像解析器 1 一样在符号“+”上进行 I 5状态的归约移动,那么输入字符串的左边“+”在右边“+”之前被归约,这使得“+”左结合。
  • 如果我们在解析器 2 中对符号“+”进行 I 5状态的移位移动,那么输入字符串的右“+”在左“+”之前减少,这使得“+”右结合。

类似地,对符号“*”进行 I 5状态的移位移动将使“*”比“+”具有更高的优先级,因为“*”将在“+”之前减少。在符号“*”上进行 I 5状态的减少移动将使“+”比“*”具有更高的优先级,因为“+”将在“*”之前减少。与 I 5类似,也可以解决来自 I 6 的冲突。

根据我们例子的优先级和结合性,冲突解决如下,

  • “+”上 I 5处的 shift/reduce 冲突通过保持 reduce 移动并丢弃 shift 移动来解决,这使得“+”左结合。
  • “*”上 I 5处的 shift/reduce 冲突通过保持 shift 移动并丢弃 reduce 移动来解决,这将使“*”比“+”具有更高的优先级。
  • “+”上 I 6处的 shift/reduce 冲突通过保留 reduce 移动并丢弃 shift 移动来解决,这将使“*”比“+”具有更高的优先级。
  • “*”上 I 6处的 shift/reduce 冲突通过保持 reduce 移动并丢弃 shift 移动来解决,这使得“*”左结合。

一般情况下,解析器生成工具YAAC解决由于语法不明确引起的冲突如下:

  • 解析表中的移位/减少冲突通过优先移动移动而不是减少移动来解决。如果字符串被接受进行移位移动,则移除减少移动,否则移除移位移动。
  • 解析表中的减少/减少冲突通过优先考虑第一个减少移动而不是第二个减少移动来解决。如果第一次减少移动接受字符串,则删除第二次减少移动,否则删除第一次减少移动。

相关的 GATE 问题:

  • GATE-CS-2005 |第 85 题
  • GATE-CS-2005 |第 86 题