OpenDSA 完整目录

Chapter 27 Grammars

| 关于   «  1. 推导与语法分析树   ::   目录   ::   3. 强制运算顺序  »

2. 二义性文法

2.1. 第二个示例文法

在上一节的 第一个示例文法 中,我们开发了一个包含三个非终结符(即 \(<exp>, <term>\) 、 \(<var>\) )的代数表达式文法。是否可以为同一语言开发一个更简单的文法,例如使用更少非终结符的文法?下面是一个仅使用两个非终结符 \(<exp>\) 和 \(<var>\) 的候选文法。

\[\begin{split}\begin{eqnarray*} <exp> &::=& <exp> + <exp> \\ &|& <exp> - <exp> \\ &|& <exp> * <exp> \\ &|& <exp> / <exp> \\ &|& <var> \\ &|& ( <exp> ) \\ <var> &::=& A\ |\ B\ |\ C\ |\ \ldots\ |\ X\ |\ Y\ |\ Z \end{eqnarray*}\end{split}\]

让我们试着用这个文法来分析表达式 \(A+B*C\) 。该文法为我们提供了许多开始分析过程的选项。我们可以选择先使用带 \(+\) 运算符的那条产生式,如下面的幻灯片所示。

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

我们也可以从带 \(*\) 运算符的产生式开始,这时分析过程如下面的幻灯片所示。

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

请注意,上面两个幻灯片都生成了该文法的合法语法分析树。然而问题在于,这两棵语法分析树并不相同。在两棵树的第一棵中,B 会与 C 相乘,这符合通常的运算符优先级。但在第二个幻灯片生成的语法分析树中,B 会与 A 相加,这违背了通常的运算符优先级。

2.2. 文法中的二义性

如果一个文法允许为同一个表达式构造两棵(或更多)不同的语法分析树,就称它为 二义性文法 (ambiguous grammar)。应当始终避免二义性文法,因为它所允许的多棵语法分析树使我们无法利用语法分析树为它们所表示的表达式赋予唯一的意义(或值,或语义)。

本节的题集包含四道复习题,其中前三道涉及同一个文法。

2.3. 二义性文法 —— 第 1 部分

第一道题是关于确定给定字符串在给定文法中有多少棵语法分析树。

2.4. 二义性文法 —— 第 2 部分

这道题是关于确定另一个字符串在同一文法中有多少棵语法分析树。

2.5. 二义性文法 —— 第 3 部分

这道题再次关于确定又一个字符串在同一文法中有多少棵语法分析树。

2.6. 发现二义性

这道题让你练习发现文法中的二义性,同时也练习说服自己某个文法不是二义性的。

   «  1. 推导与语法分析树   ::   目录   ::   3. 强制运算顺序  »

关闭窗口