📜  简化上下文无关语法

📅  最后修改于: 2022-05-13 01:54:10.563000             🧑  作者: Mango

简化上下文无关语法

上下文无关文法 (CFG) 的定义允许我们开发各种各样的文法。大多数情况下,CFG 的某些产品没有用,而且是多余的。发生这种情况是因为 CFG 的定义并没有限制我们制作这些多余的产品。

通过简化 CFG,我们从一个文法中删除了所有这些多余的产生式,同时保持转换后的文法与原始文法等价。如果两个文法产生相同的语言,则称它们为等价文法。简化 CFG 是必要的,以便以后将它们转换为 Normal 形式。

冗余产品的类型和删除它们的程序如下所述。
1. 无用产生式——永远不能参与任何字符串推导的产生式,称为无用产生式。同样,永远不能参与任何字符串推导的变量称为无用变量。例如。

S -> abS | abA | abB
A -> cd
B -> aB
C -> dc                         

在上面的例子中,产生式 'C -> dc' 是无用的,因为变量 'C' 永远不会出现在任何字符串的派生中。其他产生式的编写方式使得变量“C”永远无法从起始变量“S”到达。

生产 'B ->aB' 也是无用的,因为它永远不会终止。如果它永远不会终止,那么它永远不会产生字符串。因此,生产永远不能参与任何派生。

为了删除无用的产生式,我们首先找到所有不会导致终端字符串的变量,例如变量'B'。然后我们删除所有出现变量“B”的产生式。
所以修改后的语法变成了——

S -> abS | abA
A -> cd
C -> dc

然后,我们尝试识别从起始变量(例如变量“C”)永远无法到达的所有变量。然后我们删除所有出现变量“C”的产生式。
下面的语法现在没有无用的产生 -

S -> abS | abA
A -> cd

2. λ 产生式 - 'A -> λ' 类型的产生式称为 λ 式产生式(也称为 lambda 式产生式和空式产生式)。这些产生式只能从那些不生成 λ(空字符串)的文法中删除。语法可能包含空产生式但不产生空字符串。

要删除空产生式,我们首先必须找到所有可以为空的变量。如果 λ 可以从“A”派生,则变量“A”称为可为空的。对于 'A -> λ' 类型的所有产生式,'A' 是一个可为空的变量。对于 'B -> A1A2…An ' 类型的所有产生式,其中所有 'Ai's 都是可空变量,'B' 也是可空变量。

在找到所有可以为空的变量之后,我们现在可以开始构造空产生式自由文法了。对于原始语法中的所有产生式,我们添加原始产生式以及通过用λ替换产生式中的可空变量可以形成的产生式的所有组合。如果产生式的 RHS 上的所有变量都是可以为空的,那么我们不会将 'A -> λ' 添加到新语法中。一个例子可以说明这一点。考虑语法 -

S -> ABCd                        (1)
A -> BC                                (2)
B -> bB | λ                        (3)    
C -> cC | λ                        (4)    

让我们首先找到所有可以为空的变量。变量“B”和“C”显然可以为空,因为它们在其生产的 RHS 上包含“λ”。变量“A”也可以为空,因为在 (2) 中,RHS 上的两个变量也可以为空。同样,变量“S”也可以为空。所以变量 'S' 、 'A' 、 'B' 和 'C' 是可为空的变量。

让我们创建新的语法。我们从第一个生产开始。按原样添加第一个产品。然后我们创建所有可能的组合,这些组合可以通过用 λ 替换可空变量来形成。因此第 (1) 行现在变为 'S -> ABCd | ABd |醋酸盐 | BCD |广告 |镉 |镉 | d '。我们将相同的规则应用于第 (2) 行,但我们不添加 'A -> λ',即使它是可能的组合。我们删除所有类型为“V -> λ”的产生式。新语法现在变成了——

S -> ABCd | ABd | ACd | BCd | Ad  |  Bd  |Cd | d
A -> BC | B | C
B -> bB | b
C -> cC | c

3. 单位产品——“A -> B”类型的产品称为单位产品。
为了从原始语法 'G' 创建一个单元生产自由语法 'Guf' ,我们遵循下面提到的过程。

首先在“Guf”中添加“G”的所有非单元产生式。然后对于语法 'G' 中的每个变量 'A' ,找到所有变量 'B' 使得 'A *=> B'。现在,对于像 'A' 和 'B' 这样的所有变量,添加 'A -> x1 | x2 | …xn' 到 'Guf' 其中 'B -> x1 | x2 | …xn ' 在 'Guf' 中。 x1 , x2 ... xn 都不是单变量,因为我们只在“Guf”中添加了非单位产生式。因此,生成的语法是免费的。例如。

S -> Aa | B
A -> b | B
B -> A | a

让我们在“Guf”中添加“G”的所有非单位产生式。 “Guf”现在变成了——

S -> Aa
A -> b
B -> a

现在我们找到所有满足'X *=> Z'的变量。它们是“S*=>B”、“A *=> B”和“B *=> A”。对于 'A *=> B' ,我们添加 'A -> a' 因为 'B ->a' 存在于 'Guf' 中。 'Guf' 现在变成

S -> Aa
A -> b | a
B -> a

对于 'B *=> A' ,我们添加 'B -> b' 因为 'A -> b' 存在于 'Guf' 中。新语法现在变成

S -> Aa
A -> b | a
B -> a | b

我们对 'S*=>B' 遵循相同的步骤,最终得到以下语法 -

S -> Aa | b | a
A -> b | a
B -> a | b

现在删除 B -> a|b ,因为它不会出现在产生式 'S' 中,所以下面的语法变成了,

S->Aa|b|a
A->b|a

注意:要删除上面提到的各种产生式,首先删除空产生式,然后是单元产生式,最后,删除无用的产生式。遵循此顺序对于获得正确的结果非常重要。