文章目录
第5章 上下文无关文法与下推自动机
CFG 的化简
无用符号
无用符号:
- X ∈ V ∪ T X{\in}V{\cup}T X∈V∪T ,但 X X X 并不出现在由 S S S 派生而来的任何字符串中
- X ∈ V X{\in}V X∈V ,但 X X X 派生不出任何终结符号串(缺失、死循环)
消除方法:
- 第一类无用符号,使用正推的方法:先将 S S S 放入结果集中;对于每次新放入结果集的变元,将其能够推导出的变元和终结符号也放入结果集中;重复,直至结果集不再增大;
- 第二类无用符号,使用倒推的方法:先将一步就能生成终结符号的变元加入结果集中;遍历每个生成式,若右部的变元全部都在结果集中,则将左部变元加入结果集;重复,直至结果集不再增大;将仅能由被删除的变元派生来的终结符号也删除;
(消除无用符号时,应当先消除 2 类再消除 1 类,因为先 1 类再 2 类的话有些终结符号不会被删除(不过我感觉如果仅仅考虑无用变元符号的化简,那么 1 类 2 类的消除顺序好像不太重要))
此外,对于 ε \varepsilon ε-生成式( A → ε A\to\varepsilon A→ε )、单一生成式( A → B A\to B A→B 或 A → a A\to a A→a ),都可以通过合并到前一步来化简,最终得到化简过后的 CFG
CNF 和 GNF 范式
CNF 范式
Chomsky 范式:任何不包含 ε \varepsilon ε 的 CFL ,都可由生成式仅为 A → B C A\to BC A→BC 或 A → a A\to a A→a 形式的文法产生
算法:
- 先将所有终结符 a a a 都看作变元 [ a ] [a] [a] ,增加生成式 [ a ] → a [a]\to a [a]→a ;若 A → α a β A\to \alpha a\beta A→αaβ ,则 A → α [ a ] β A\to\alpha[a]\beta A→α[a]β ;
- 对于 A → A 1 A 2 . . . A n A\to A_1A_2...A_n A→A1A2...An ,令 D n − 1 = A 1 A 2 . . . A n − 1 D_{n-1}=A_1A_2...A_{n-1} Dn−1=A1A2...An−1 ,则 A → D n − 1 A n A\to D_{n-1}A_n A→Dn−1An ;逐层展开
GNF 范式
Greibach 范式:任何不包含 ε \varepsilon ε 的 CFL ,都可由生成式仅为 A → a α A\to a\alpha A→aα ( α \alpha α 可为空)形式的文法产生
算法:
- ( i ≤ j i{\le}j i≤j )将所有变元标上序号( A i ( i = 1 , 2 , . . . ) A_i\,(i=1,2,...) Ai(i=1,2,...) ),保证不满足 GNF 范式的生成式不会出现大序号推出小序号开头的情况,即若 A i → A j α A_i\to A_j\alpha Ai→Ajα ,则 i ≤ j i{\le}j i≤j;(具体做法为从左部为第二小序号的生成式开始,从小到大遍历,将右部开头的变元反复用已经满足序号左小于等于右开头的生成式替换,直至该生成式序号左小于等于右开头)
- ( B i B_i Bi )对于左部序号等于右部开头的序号的生成式( A i → A i α A_i\to A_i\alpha Ai→Aiα ),使用如下变元 B i B_i Bi 替换:
{ A i → A i α 1 ∣ A i α 2 ∣ . . . ∣ A i α r A i → β 1 ∣ β 2 ∣ . . . ∣ β s \left \{ \begin{array}{ll} A_i\to A_i\alpha_1|A_i\alpha_2|...|A_i\alpha_r\\ A_i\to \beta_1|\beta_2|...|\beta_s \\ \end{array} \right. {Ai→Aiα1∣Aiα2∣...∣AiαrAi→β1∣β2∣...∣βs
(其中
β
\beta
β 已经均为终结符号开头了)替换为:
{
A
i
→
β
j
A
i
→
β
j
B
i
(
j
=
1
,
2
,
.
.
.
,
s
)
{
B
i
→
α
j
B
i
→
α
j
B
i
(
j
=
1
,
2
,
.
.
.
,
s
)
\left \{ \begin{array}{ll} A_i \to\beta_j\\ A_i \to\beta_jB_i &(j=1,2,...,s) \end{array} \right. \\ \left \{ \begin{array}{ll} B_i \to\alpha_j \\ B_i \to\alpha_jB_i &(j=1,2,...,s) \end{array} \right.
{Ai→βjAi→βjBi(j=1,2,...,s){Bi→αjBi→αjBi(j=1,2,...,s)
-
( A → a α A\to a\alpha A→aα )此时不满足 GNF 、且不含 B i B_i Bi 的生成式都满足序号左小于等于右开头了;则对于左部为最大序号的变元的生成式而言,其都满足 GNF,故从左部为第二大序号的生成式开始,从大到小遍历,将右部开头为序号大于左部的变元替换为满足 GNF的生成式的右部
-
( A A A 带入 B B B )最后处理 B i B_i Bi ;由于 α j \alpha_j αj 只含有 A i A_i Ai 或终结符,不含有 B B B ,且此时左部为 A A A 的生成式都已经满足 GNF ,故只要将开头为 A A A 的 α j \alpha_j αj 的开头替换掉即可
例:(第一步即包含了算法的第一、二步)
PDA 与 CFG
下推自动机
一个 下推自动机(简称 PDA)是一个七元组 M = ( Q , Σ , Γ , δ , q 0 , Z 0 , F ) M=(Q,\Sigma,\Gamma,\delta,q_0,Z_0,F) M=(Q,Σ,Γ,δ,q0,Z0,F) ,其中:
- Q Q Q 是有穷状态集
- Σ \Sigma Σ 是有穷的输入字母表
- Γ \Gamma Γ 是有穷的栈符号表
- δ \delta δ 是转移函数, δ : Q × ( Σ ∪ { ε } ) × Γ → Q × Γ ∗ \delta:Q{\times}({\Sigma}{\cup}\{\varepsilon\}){\times}\Gamma\to Q\times{\Gamma}^{\ast} δ:Q×(Σ∪{ε})×Γ→Q×Γ∗ 的有穷子集
- q 0 ∈ Q q_0{\,}{\in}{\,}Q q0∈Q ,是初始状态
- Z 0 ∈ Γ Z_0{\,}{\in}{\,}\Gamma Z0∈Γ ,是栈底符号
- F ⊆ Q F{\subseteq}Q F⊆Q ,是终结状态集
转移函数的一般形式为:(即转移函数是不确定的)(
γ
\gamma
γ 可以为空,即退栈)
δ
(
q
,
a
,
Z
)
=
{
(
p
1
,
γ
1
)
,
(
p
2
,
γ
2
)
,
.
.
.
,
(
p
m
,
γ
m
)
}
\delta(q,a,Z)=\{(p_1,\gamma_1),(p_2,\gamma_2),...,(p_m,\gamma_m)\}
δ(q,a,Z)={(p1,γ1),(p2,γ2),...,(pm,γm)}
PDA 的 **接受方式 **有两种:
- 按栈空方式接受,即栈中为空时接受,此时 F F F 可以不写
- 按接受状态接受,即状态到达 F F F 中的某一状态时接受
(栈空 → \to → 接受:在栈底垫一个特殊字符,遇到该字符时就是代表栈空了,此时转为接受状态)
(接受 → \to → 栈空:到达接受状态以后,不论栈中还有什么字符,一律消去)
CFG → \to → PDA
构造:根据 CFG G = ( V , T , P , S ) G=(V,T,P,S) G=(V,T,P,S) ,构造 PDA M = ( { q } , T , V , δ , q , S , ∅ ) M=(\{q\},T,V,\delta,q,S,\varnothing) M=({q},T,V,δ,q,S,∅)
将 CFG 转化为 GNF 范式;只需要一个状态,将变元看作栈中符号,按栈空方式接受;
对于生成式 A → a α A\to a\alpha A→aα 对应转移函数 δ ( q , a , A ) \delta(q,a,A) δ(q,a,A) 包含 ( q , α ) (q,\alpha) (q,α) ;若 α \alpha α 中有变元 b b b ,则将 b b b 看作栈中符号 [ b ] [b] [b] ,并增加 δ ( q , b , [ b ] ) \delta(q,b,[b]) δ(q,b,[b]) 包含 ( q , ε ) (q,\varepsilon) (q,ε) ;
PDA → \to → CFG
这个比较复杂,结合例题来理解比较好
构造:根据 PDA M = ( Q , Σ , Γ , δ , q 0 , Z 0 , ∅ ) M=(Q,\Sigma,\Gamma,\delta,q_0,Z_0,\varnothing) M=(Q,Σ,Γ,δ,q0,Z0,∅) ,构造 CFG G = ( V , Σ , P , S ) G=(V,\Sigma,P,S) G=(V,Σ,P,S) ,其中:
V = { [ q , A , p ] ∣ q , p ∈ Q , A ∈ Γ } ∪ { S } V=\{[q,A,p]|q,p{\,}{\in}{\,}Q,{\,}A{\,}{\in}{\,}{\Gamma}\}{\cup}\{S\} V={[q,A,p]∣q,p∈Q,A∈Γ}∪{S} ,代表状态 q q q 经由接受 A A A 所派生出来的字符串后,可以到达 p p p 状态;也指当前状态为 q q q ,栈顶为 A A A ;
P P P 分为两类:
- S → [ q 0 , Z 0 , q ] , ∀ q ∈ Q S\to [q_0,Z_0,q],{\,}\forall q{\,}{\in}{\,}Q S→[q0,Z0,q],∀q∈Q
- 当 δ ( q , a , A ) \delta(q,a,A) δ(q,a,A) 包含 ( q 1 , B 1 , B 2 , . . . , B m ) (q_1,B_1,B_2,...,B_m) (q1,B1,B2,...,Bm) 时,则有:
[ q 1 , A , q m + 1 ] → a [ q 1 , B 1 , q 2 ] [ q 2 , B 2 , q 3 ] . . . [ q m , B m , q m + 1 ] [q_1,A,q_{m+1}]\to a[q_1,B_1,q_2][q_2,B_2,q_3]...[q_m,B_m,q_{m+1}] [q1,A,qm+1]→a[q1,B1,q2][q2,B2,q3]...[qm,Bm,qm+1]
其中 q 2 , q 3 , . . . , q m + 1 q_2,q_3,...,q_{m+1} q2,q3,...,qm+1 取自 Q Q Q 中任何状态;若 m = 0 m=0 m=0 (即退栈操作),则有 [ q , A , q 1 ] → a [q,A,q_1]\to a [q,A,q1]→a
例:
比如对于变元 [ q 1 , X , q 0 ] [q_1,X,q_0] [q1,X,q0] ,它是无效变元:因为只有 δ ( q 1 , ε , X ) = { ( q 1 , ε ) } \delta(q_1,\varepsilon,X)=\{(q_1,\varepsilon)\} δ(q1,ε,X)={(q1,ε)} 和 δ ( q 1 , 1 , X ) = { ( q 0 , ε ) } \delta(q_1,1,X)=\{(q_0,\varepsilon)\} δ(q1,1,X)={(q0,ε)} 满足 δ ( q 1 , ? , X ) \delta(q_1,?,X) δ(q1,?,X) 的条件,但是这俩都是退栈操作,必须是 [ q 1 , X , q 1 ] [q_1,X,q_1] [q1,X,q1] 才能变化,而不能是随意的 [ q 1 , X , ? ] [q_1,X,?] [q1,X,?]