我是否应该手动应用生产规则来查找此语法生成的语言?这很乏味,有什么技巧/小费可以加快速度吗?
G = {{S, B}, {a, b}, P, S}
P = {S -> aSa | aBa, B -> bB | b}
编辑:我发现Matajon的答案很好,就是考虑非终端符号生成的每种语言,然后将它们组合起来。
但是当我必须解决一些像这样的复杂例子时,我仍然感到困惑:
G = {{S, R, T}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, P, S}
P = {S -> A | AS | BR | CT,
R -> AR | BT | C | CS,
T -> AT | B | BS | CR,
A -> 0 | 3 | 6 | 9,
B -> 1 | 4 | 7,
C -> 2 | 5 | 8}
疯了,不是吗?摘自过去的考试(编程语言课程)。
答案 0 :(得分:2)
我不知道任何一般技巧,但通常有助于考虑从每个非终端产生的语言。
在您的示例中,从B生成的语言显然是L(B) = {b}^+
。然后你考虑S规则,使用第一条规则,你可以生成句子形式{a^n.S.a^n | n >= 1}
。如果您对这些句子形式使用第二条规则或仅使用S,则可以生成句子形式{a^n.B.a^n | n >= 1}
。
休息非常简单,你将这两件事结合起来并获得L(G) = {a^n.b^+.a^n | n >= 1}
顺便说一句,在语法终端和非终结符的定义中是集合,而不是元组。第三个组件是生产规则,而不是开始符号。所以你应该写G = {{S, B}, {a, b}, P, S}
。
修改强>
实际上,有一种方法可以解决你的第二个例子,而不必过多考虑像烹饪书这样的东西。因为,第二个无上下文语法生成的语言实际上是常规的。
当您将A,B和C的规则替换为前三个规则时,您将获得
P' = {S -> 0 | 3 | 6 | 9 | 0S | 3S | 6S | 9S | 1R | 4R | 7R | 2T | 5T | 8T
R -> 0R | 3R | 6R | 9R | 1T | 4T | 7T | 2 | 5 | 8 | 2S | 5S | 8S
T -> 0T | 3T | 6T | 9T | 1 | 4 | 7 | 1S | 4S | 7S | 2R | 5R | 8R}
P'
是常规语法。因此,您可以将其转换为非确定性有限自动机(有非常简单的方法,查找它)然后将生成的NFA转换为正则表达式(这不是那么简单,但如果您遵循算法并且不会丢失,你应该没事)。从正则表达式来看,它很容易分辨它描述的语言。
此外,一旦您拥有此语言的NFA,您就可以查看它并确定其逻辑行为(它与单词1,4,7
和2,5,8
的计数有关。{{1他们的差异。想一想,这是你的功课,毕竟:-))
当然,如果你没有无上下文语法生成常规语言,你就不能使用这个技巧。没有通用的方法来说明语法生成的语言(CFG的语言平等问题是不可判定的),你必须考虑每一个例子,并在其逻辑结构中寻找相似性和模式。
答案 1 :(得分:0)
我认为您只需要应用生产规则。