📜  将上下文无关语法转换为乔姆斯基范式(1)

📅  最后修改于: 2023-12-03 15:39:14.477000             🧑  作者: Mango

将上下文无关语法转换为乔姆斯基范式

简介

上下文无关语法(Context-Free Grammar,CFG)在计算机科学中有广泛的应用,用于描述自然语言、编程语言等。但是,用上下文无关语法描述语言时,可能会出现一些问题,如歧义性、文法冗余等。

乔姆斯基范式(Chomsky Normal Form,CNF)是一种在语法上的规范化形式,可以将任何上下文无关语法转换为它的等价范式。这种转换可以方便依靠算法处理语法,并减少语法的歧义性和冗余性。因此,将上下文无关语法转换为乔姆斯基范式是编译原理、自然语言处理等领域中的一个基本问题。

什么是上下文无关语法?

上下文无关语法是一种形式化的语言文法,是由产生式规则(也称为产生式、产生关系)组成的。产生式规则定义了一个符号集合,以及如何由这些符号组成序列。

形式化地,一个上下文无关语法是四元组 $G = (V, T, P, S)$,有以下特点:

  • $V$ 是一个非终结符符号集合(Variables);
  • $T$ 是一个终结符符号集合(Terminals);
  • $P$ 是一个产生式规则集合(Production rules),每条规则指定一个非终结符号的代换;
  • $S$ 是一个起始符号(Start symbol),它是一个 $V$ 中的一员。

语法 $G$ 用于定义由 $S$ 派生的 $T$ 的语言 $L(G)$。这种语言包括所有可以由产生式集 $P$ 执行有限次代换得到的终结符串。

什么是乔姆斯基范式?

乔姆斯基范式是一个形式化的语法规范。乔姆斯基范式将上下文无关语法定义为一个加强版的形式化语法,其中每个产生式只能是以下两种形式之一:

  • $A \to BC$,其中 $A, B, C$ 为非终结符号;
  • $A \to a$,其中 $A$ 为非终结符号,$a$ 为终结符号。

换句话说,在乔姆斯基范式中,每个产生式要么是 A 直接推导出两个非终结符,要么是 A 直接推导出一个终结符。

如何将上下文无关语法转换为乔姆斯基范式?

将上下文无关语法转换为乔姆斯基范式的基本步骤如下:

步骤一:去除产生式中的 ε-规则

在上下文无关语法中,有可能存在一些 ε-规则,即可以从某个非终结符号 $A$ 推导出一个空串的规则。为了将上下文无关语法转换为乔姆斯基范式,需要先将所有的 ε-规则都去除。

具体地,对于每个非终结符号 $A$,首先找出所有可以由 $A$ 推导出的字符串中,长度最短的一个字符串。若这个最短字符串长度为 $0$,即它可以直接推导出空串,则将所有可以推导出该最短字符串的产生式都删除。

然后,对于剩余的所有产生式中包含 $A$ 的产生式,将它们中所有的 $A$ 替换为一个新的非终结符号 $B_A$,并添加以下两个新的产生式:

  • $B_A \to A$
  • $B_A \to \varepsilon$

这些新的产生式保证了 $B_A$ 可以被推导出空串,从而代替原来的非终结符号 $A$。

步骤二:将一般产生式 $A \to x_1 x_2 ... x_n$ 转换为 $A \to B_1 B_2; B_1 \to x_1 B_3; B_3 \to x_2 B_4; B_{n-2} \to x_{n-1} x_n$

使用这个方法可以确保 CFG 的每个产生式都符合乔姆斯基范式的形式。

具体地,假设 $A \to x_1 x_2 ... x_n$ 是一个产生式,其中 $x_i$ 是一个非终结符或终结符。为了将它转换成乔姆斯基范式,我们需要将它分解为两个较小的产生式:

  • $A \to B_1 B_2$
  • $B_1 \to x_1 B_3; B_3 \to x_2 B_4; ...; B_{n-2} \to x_{n-1} x_n$

其中,$B_i$ 是一个新的非终结符号,$B_2$ 和 $B_{n-1}$ 是所有的“中间符号”。注意,这个过程并不改变语言的终结符串。

步骤三:将产生式中的链式规则转换为乔姆斯基范式

链式规则是指形如 $A \to B$ 的产生式,其中 $A$ 和 $B$ 都是非终结符号。

具体地,乔姆斯基范式中不允许出现链式规则,因此需要将它们转换为符合乔姆斯基范式的形式。这里使用递归方法。对于每个链式规则 $A \to B$,我们将每个可以从 $B$ 推导出的产生式 $B \to \alpha$ 都翻译为 $A \to \alpha$。

步骤四:将所有的单个终结符号转换为新的终结符号

到这一步为止,我们的文法形式已经符合基本的乔姆斯基范式。但是,还需要将所有的终结符合并到一个符号中。具体地,对于每个终结符号 $t$,都添加一个新的非终结符号 $T$,使得 $T \to t$。

这些新的非终结符可以看作是 $\varepsilon$-产生式规则的一种变种。这里我们并不是将非终结符预测为 $ε$,而是将单个终结符规约为一个自有的非终结符。

复杂度分析

由于两个步骤都需要将非终结符号拆分成若干个更小的子串,仅考虑上下文无关文法的长度,该算法的时间复杂度为 $O(n^3)$。但是,实际上,该算法实现中优化了一些操作,可以达到 $O(n^2)$ 的时间复杂度。