在研究语法分析器时,大部分语法分析器都期望文法是无二义性的,否则,我们就不能为一个句子唯一地选定语法分析树。但是在某种情况下,使用经过精心选择的二义性文法可以带来方便。此时需要使用消二义性规则来“抛弃”不想要的语法分析树,只为每个句子留下一棵语法分析树。
假如我们要将if then else语句加入某一文法G中,我们可以给出无二义性文法如下:
stmt -> matched_stmt
| open_stmt
matched_stmt -> if expr then matched_stmt else macthed_stmt
| other
open_stmt -> if expr then stmt
| if expr then matched_stmt else open_stmt
其中加粗的为终结符。
接下来,我们可以为上面的文法构造语法分析表,这里我们并不会做这一步,而是先来看一下上边语言的一个二义性文法:
S -> iEtSS' | a
S' -> eS | €
E -> b
其中i、t、e分别代表终结符if、then、else,€代表空串。
我们先为上边的二义性文法构造语法分析表,这里使用预测分析法的构造方法构造,如下:
a b e i t $
S S->a S->iEtSS'
S' S'->€ S'->€
S'->eS
E E->b
现在,当在输入中看到e时,解决选择使用哪个产生式的问题就会显露出此文法的二义性。解决这个二义性问题时,我们选择产生式S'->eS。这个选择就相当于把else和前面的最近的then关联起来。所以我们就可以简单的删掉上表中M[S',e]中的S'->€来消除二义性,此时得到的语法分析表中的每个条目都唯一的指定了一个产生式,或者标明一个语法错误。
通过使用二义性文法,我们得到了预期的预测分析表,此时我们在回过来看看无二义性文法的预测分析表,虽然没有构建,但我们不难看出无二义性文法的预测分析表要比我们上边得到的复杂,至少构造过程要比我们上边的复杂。由此,我们看到,可以使用精心设计的二义性文法来简化语法分析器的设计。