上下文无关文法相关算法

286 阅读2分钟

定理 3.6.1 (a)有多项式算法,任给一个上下文无关文法,构造一台等价的下推自动机,CFGPDACFG \rightarrow PDA

(b)有多项式算法,任给一台下推自动机,构建一个等价的上下文无关文法,PDACFGPDA \rightarrow CFG

(c)有多项式算法,任给上下文无关文法GG以及字符串xx,判断是否xL(G)x \in L(G)



定义 3.6.1 如果R(VΣ)×V2R \subseteq (V - \Sigma) \times V^2,则称上下文无关文法G=(V,Σ,R,S)G = (V,\Sigma,R,S)Chomsky范式

换句话说,Chomsky范式的规则右侧必须长度为2,长度小于2的上下文无关语言无法由Chomsky范式文法生成。



定理 3.6.2 对于任意的上下文无关文法GG,存在Chomsky范式的上下文无关文法GG'使得L(G)=L(G)(Σ{e})L(G') = L(G) - (\Sigma \cup \{e\}),并且GG'的构造可以在GG的规模的多项式时间内完成。


接下来从一个例子中体会生成Chomsky范式的过程。



例 3.6.1 以生成平衡括号串集合的文法为例子,其规则为SSS,S(S),SeS \rightarrow SS,S \rightarrow (S), S \rightarrow e。 先把一条长规则S(S)S \rightarrow (S)替换为两条规则S(S1,S1S)S \rightarrow (S_1 , S_1 \rightarrow S)


STEP1:删除规则中e相关的规则。

先确定可删除的非终结符集合

E={AVΣ:Ae}\mathscr{E} = \{ A \in V -\Sigma:A \stackrel{*}{\Rightarrow} e\}

即所有能够推导出空串的非终结符集合。使用如下闭包算法得到E\mathscr{E}


E:=E:= \varnothing
while有一条规则AαA \rightarrow \alpha,其中αE\alpha \in \mathscr{E}^*
do 把 AA 加入 E\mathscr{E}


得到集合E\mathscr{E}之后即可依据下述规则开始删除所有的e规则,
对每一条ABCA \rightarrow BC或者ACBA \rightarrow CB形式的规则,其中BE,CVB \in \mathscr{E},C \in V,在原有规则中加入ACA \rightarrow C

对应到本例子中E={S}\mathscr{E} = \{S\},添加规则SS,S1)S \rightarrow S,S_1 \rightarrow )
此时文法中只剩下右侧长度为1或2的规则。

STEP2:尝试去掉短规则。

对每一个符号AA求出其所能推导出的符号的集合,同样使用闭包算法。


D(A):={A}\mathscr{D}(A) := \{ A \}
while 有一个规则BCB \rightarrow C,其中BD(A)B \in \mathscr{D}(A)CD(A)C \notin \mathscr{D}(A)
do 把CC加入D(A)\mathscr{D}(A)


随后删除所有的短规则。

并且,将所有形如ABCA \rightarrow BC的规则替换为ABCA \rightarrow B'C',其中BD(B),CD(C)B' \in \mathscr{D}(B) , C' \in \mathscr{D}(C)。实际上,对于闭包只含有自己的符号无需作此替换。

最后,对于每一条规则ABCA \rightarrow BC,当AD(S){S}A \in \mathscr{D}(S) - \{S\},加入一条规则SBCS \rightarrow BC

对于本例,D(S1)={S1,)}\mathscr{D}(S_1) = \{S_1 , ) \}(非平凡的),其余符号均只能推导出自己本身(平凡的)。
先删除长度为1的短规则,这里删除S1)S_1 \rightarrow )
S1S_1出现在S(S1S \rightarrow (S_1的右侧,接下去添加一条规则S()S \rightarrow (),替换了S1S_1



综合以上,得出最后的Chomsky范式下的规则

SSS,S(S1,S1S),S()S \rightarrow SS,S \rightarrow (S_1,S_1 \rightarrow S),S \rightarrow ()


Chomsky范式的优点在于可以用一个简单的多项式算法判断一个字符串能否由该文法生成。

下面给出一个动态规划算法

先定义N[i,i+s]N[i,i+s]GG中能够推导出xixi+sx_i \cdots x_{i+s}的字符集合。


for i:=i := 1 to n do N[i,i]:={xi}N[i,i] := \{x_i\}
for s:=s := 1 to n-1 do
for i:=i := 1 to n-s do
for k:=k := i to i+s-1 do
if 有 ABCRA \rightarrow BC \in RBN[i,k]B \in N[i,k]CN[k+1,i+s]C \in N[k+1,i+s]
then 把 AA 加入 N[i,i+s]N[i,i+s];
if SN[1,n]S \in N[1,n] then 接受 xx