自动机:以下语言的 CFG

Automata: CFG for following language

请看以下语言:

(a, b, c)* − {a<sup>n</sup>b<sup>n</sup>c<sup> n</sup>|n≥0}

我的问题是:如何为其编写上下文无关文法?

一般来说,当某些东西被排除在语法之外(即有“-”符号)时,我该如何编写语法?

没有算法可以确定一种语言是否是上下文无关的。所以你提出的问题没有通用的解决方案也就不足为奇了。

上下文无关语言在互补、集差或交集下不封闭。 (但它们在连接、集合并集和 Kleene 星形下是封闭的。)无论如何

{a<sup>n</sup>b<sup>n</sup>c<sup>n</sup>|n≥ 0}

不是上下文无关的语言,但它的补充(如您的问题)是上下文无关的。这个事实的证明(通过为补语构造上下文无关文法)是补语下CFG非闭包的标准例子。

概括地说,您的语言 L 可以由以下的并集组成:

  • 字母表 {a,b,c} 中字母顺序不正确的所有字符串。换句话说,包含子字符串 bacbca.

  • 的所有字符串
  • {a<sup>i</sup>b<sup>j</sup>c<sup>k</sup>|i,j,k≥0∧i≠j}

  • {a<sup>i</sup>b<sup>j</sup>c<sup>k</sup>|i,j,k≥0∧j≠k}

(a, b, c)* − {a^nb^nc^n|n≥0}

这表示您可以选择 a、b 或 c 中的任何一个,并重复其中的任何一个,例如abccbaabaab 或 abca 或 bccc

对于 a*,您可以使用 A->aA |e 或者 A->AA | a | e

使用该规则,您可以:

S -> A | B | C A->aA |e | AS B->bB |e | BS C->cC |e | CS

在 A、B 和 C 中包含 S 是可以使用的,如果整个东西上面有一个 Kleene 星 (....)*,并且允许您回到开始并添加另一个符号。

我不知道如何创建排除符号的语法,但从逻辑上讲,如果 - 不是可用的终端符号,那么您已经排除了它。