跳转至

4 移进规约分析

移进:把下一个输入符号移进栈

归约:当知道栈顶是某个句柄的末尾时,确定句柄首在栈中的位置,然后决定用什么非终结符在栈中替换句柄

这个分析过程具有如下重要性质:句柄总是出现在栈顶,决不出现在栈的中间。

示例

注:下面每一步操作是先有 输入 的格局,根据此格局确定第三列的 动作,操作动作的结果形成了下一行的格局。

image-20221003115508528

由于 E*E 可以是句柄,也可以不是句柄(二义文法),所以运行到这一步不知道是移进还是归约了。

移进-归约待解决的问题

移进-归约分析需要解决的问题

  • 冲突时,如何决策是选择移进还是归约
  • 进行归约时,怎么确定句柄
  • 进行归约时,如何确定选择哪一个产生式

移进-归约分析的冲突

移进-归约冲突

\begin{aligned} stmt→&\textbf{if }expr\textbf{ then }stmt\newline &|\textbf{if }expr\textbf{ then }stmt\textbf{ else }stmt\newline &|\textbf{other} \end{aligned}

如果现在有格局:

  • 栈:\textbf{if }expr\textbf{ then }stmt
  • 输入:\textbf{else }stmt\$

一般优先移进。(else 最近匹配)

归约-归约冲突

\begin{aligned} stmt→&\textbf{id}(para\_list)\newline para\_list→&para\_list,\textbf{id}|\textbf{id}\newline expr→&\textbf{id}(expr\_list)|\textbf{id}\newline expr\_list→&expr\_list,expr|expr \end{aligned}

也就是说 id(...) 可能是函数调用,也有可能是取某个数组元素(不同于 C)

如果现在有格局:

  • 栈:...\textbf{id}(\textbf{id}
  • 输入:,\textbf{id})...

方法一:用位于前面的产生式归约

方法二:改写文法,不允许 id(...) 出现二义

本文阅读量