4 移进规约分析
移进:把下一个输入符号移进栈
归约:当知道栈顶是某个句柄的末尾时,确定句柄首在栈中的位置,然后决定用什么非终结符在栈中替换句柄
这个分析过程具有如下重要性质:句柄总是出现在栈顶,决不出现在栈的中间。
示例
注:下面每一步操作是先有 栈 和 输入 的格局,根据此格局确定第三列的 动作,操作动作的结果形成了下一行的格局。

由于 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→¶\_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(...) 出现二义
本文阅读量