考虑字符串 a^p b^p c^p d^p。这个字符串肯定是语言。如果语言是正则的,并且存在正则文法,那么它就满足正则语言泵引理的要求:即上面给出的字符串可以写成 uvx where |uv| 0 并且对于所有自然数 n,u(v^n)x 也在语言中。 v 包含的内容有七种情况: 只是 a;甲和乙;只是 b; b和c;只是 c; c和d;或者只是d。在任何情况下,抽 v 将改变一种符号的实例数,但不会改变相应符号的实例数(语言要求的实例数完全相同)。所以,语言不可能是正则的。
同样,上下文无关语言的抽引引理要求上面给出的字符串写成 uvxyz where |vxy| 0 并且对于所有自然数 n,u(v^n)x(y^n)z 也是该语言的字符串。我们在这里得到与上面完全相同的情况并得出完全相同的结论:语言不能是上下文无关的。
考虑到这一切,我们不妨只针对不受限制的语法(也许可以为这种语言获得上下文相关的语法,但这不是要求的)。我们希望 a 和 c 的数量相同,b 和 d 的数量相同,并且我们希望它们按字母顺序排列。我们可以这样开始:
S -> ACS | BDS | T
这让我们可以得到与 C 相同数量的 A 和 D 相同数量的字符串,以 T 结尾。接下来,我们需要一些规则来允许将符号 A、B、C 和 D 放入正确的顺序:
BA -> AB
CA -> AC
DA -> AD
CB -> BC
DB -> BD
DC -> CD
最后,我们需要一种方法将非终结符 A、B、C 和 D 转换为终结符 a、b、c 和 d,除非它们都按顺序排列,否则它无法工作。我们可以使用 T(以及其他一些即将介绍的符号)从右向左扫动,边走边转换:
DT -> Td
CT -> Uc
BT -> Vb
AT -> Wa
T -> e
CU -> Uc
BU -> Vb
AU -> Wa
U -> e
BV -> Vb
AV -> Wa
V -> e
AW -> Wa
W -> e
非终结符 T、U、V 和 W 允许将 A-D、A-C、A-B 和 A 分别转换为 a-d、a-c、a-b 和 a。我们也可以随时去掉这个标记符号。消除所有非终结符得到终结符串(即按照这个文法生成字符串)的唯一方法是从右到左扫一扫,转换所有遇到的符号,最后使用 X -> e 规则中的任何一个需要消除标记。这仅在符号按从右到左的降序转换时才有效,因此它们必须按照需要从左到右按升序排列。因为 S 的产生式引入了配对的 A、C 和 B、D,所以也满足了这个要求。