如何将此歧义语法转换为非歧义语法?

时间:2019-03-24 18:45:49

标签: grammar context-free-grammar ambiguous-grammar

S -> ABCD
A -> ae | af | ag | ah
B -> b | ε
C -> hcd | bcd | cd
D -> e | f | g | h

我已经在2和4上尝试过左分解,但是我在很多作品中都坚持使用|

1 个答案:

答案 0 :(得分:0)

在此语法中,有96种方法可以得出一连串的结尾。我们怀疑其中一些派生会产生多余的终端字符串,因此所生成语言中的字符串数实际上少于96。我们希望对其进行排列,以使终端字符串的每个派生都产生不同的字符串。

我们可以列出所有96个派生类,按派生字符串对其进行排序,然后找出如何避免这种歧义的方法。这将花费比我想要的时间更长的时间,而且我们可能可以通过分析智能地缩小重复字符串的搜索空间。

我们别无选择,只能使用生产S-> ABCD。接下来,我们必须选择A-> ae,A-> af,A-> ag,A-> ah之一。到目前为止,在所有选择中仍然没有歧义。接下来,我们必须选择B-> b或B-> e。仍然没有歧义。正是由于我们选择去除C的生产方式,我们才首次引入了歧义。问题在于cd是hcd和bcd的后缀,并且当连接到另一个字符串时,可能会创建后缀hcd或bcd本身。考虑到这一点,我们发现以下重复的推导:

S -> ABCD -> axBCD -> axbCD -> axbcdD -> axbcy
S -> ABCD -> axBCD -> axCD -> axbcD -> axbcy

以上,x代表符号e,f,g或h之一; y代表符号e,f,g或h之一。之所以会产生歧义,是因为我们可以从B-> b或C-> bcd中获得b。

在继续之前,我们应该重写语法以消除这种歧义。除非我们克服了这个障碍,否则毫无意义。我们该如何解决呢?在这种情况下,请考虑将符号A和B组合为新符号A'时的语法。那么结果将是:

A' -> ae | af | ag | ah | aeb | aef | aeg | aeh

但是,我们会发现相同的问题仍然存在;问题最初不在B和A的生产之间,而是在B和C的生产之间。我们可以尝试:

B' -> hcd | bcd | cd | bhcd | bbcd

至关重要的是,请注意,我们仅在上面列出了5个术语,而不是6个术语-因为一个产品B'-> bcd通过合并这些相邻产品而产生了两次。当您看到这种情况时,就意味着您正在消除歧义。是新语法吗?

S  -> ABCD
A  -> ae | af | ag | ah
B' -> cd | hcd | bcd | bhcd | bbcd
C  -> e | f | g | h

我们可以从头开始重复分析,然后找到以下内容:

  • 我们必须选择S-> ABCD
  • 我们必须选择A-> ae,A-> af,A-> ag,A-> ah之一,并且没有选择会引起歧义
  • 我们必须选择B'的产生式之一,并且它们不能引入歧义,因为我们要附加的所有前缀都具有相同的基本长度(2个符号),并且这些前缀都是明确导出的
  • 我们必须选择D的产生式之一,并且它们不能引入歧义,因为我们要附加的所有前缀仅包含一个在末尾出现的d实例,因此我们始终可以清楚地知道引入的符号在哪里由B'端的生产开始,由D的生产引入的符号开始