S -> ABCD
A -> ae | af | ag | ah
B -> b | ε
C -> hcd | bcd | cd
D -> e | f | g | h
我已经在2和4上尝试过左分解,但是我在很多作品中都坚持使用|
。
答案 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
我们可以从头开始重复分析,然后找到以下内容: