形式陈述
CFG–PDA 等价定理断言:语言 L 能由某个上下文无关文法 公理库 上下文无关文法 Context-free grammar · CFG 每条产生式左侧是单个非终结符的生成系统。 生成,当且仅当存在非确定性下推自动机 公理库 下推自动机 Pushdown automaton · PDA 带无界栈存储的有限控制自动机。 接受 L 。等价的是语言表达能力,不是推导树、运行次数或表示大小。下面给出双向构造的核心。
从 CFG 到 PDA,可把开始符号压栈;栈顶为非终结符 A 时,机器用 ε 转移非确定选择产生式 A → α ,以 α 替换 A ;栈顶为终结符 a 时,只有下一输入也是 a 才读取并弹出。输入与栈同时耗尽时接受。
三元变量与全部规则
反向构造固定按空栈接受 的 NPDA P ,初态 q 0 、初始栈符号 Z 0 。接受要求输入读完且栈为空,终点控制状态不限。沿用 PDA 页的模型:一步检查并替换一个栈顶符号,空栈后没有可执行动作;栈顶在左。
为每个 u , v ∈ Q 和 X ∈ Γ 引入变量 [ u X v ] ,它要满足
[ u X v ] ⇒ ∗ w ⟺ ( u , w , X ) ⊢ ∗ ( v , ε , ε ) . 将任意输入后缀 z 与栈后缀 β 补回,右侧等价于一段从 ( u , w z , X β ) 到 ( v , z , β ) 的运行,其中终点是首次露出指定原后缀 β 的时刻。此前栈均为 η β 、η ≠ ε ,且没有检查或改写 β 中的符号。这不是允许中途弹入 β 、后来再把同样字符压回去的任意运行。
先考虑每步替换串长度至多二的机器。若 ( r , α ) ∈ δ ( u , a , X ) ,a ∈ Σ ∪ { ε } ,加入以下规则:
动作的替换串 α
文法规则
需要枚举的状态
ε
[ u X r ] → a
只有动作实际到达的 r
Y
[ u X v ] → a [ r Y v ]
所有 v ∈ Q
Y Z
[ u X v ] → a [ r Y s ] [ s Z v ]
所有 s , v ∈ Q
若 a = ε ,右侧不写出终结符前缀。最后加新开始符号 S ,对每个 v ∈ Q 加入 S → [ q 0 Z 0 v ] 。这就是完整构造;没有另加“猜到正确状态就接受”的规则。
长度二的规则先完成去掉 Y 的子任务,在中间状态 s 首次露出 Z ,再完成去掉 Z 的子任务。一般替换 α = Y 1 ⋯ Y k 也可直接使用
[ u X v k ] → a [ r Y 1 v 1 ] [ v 1 Y 2 v 2 ] ⋯ [ v k − 1 Y k v k ] , 遍历全部 v 1 , … , v k 。因此长度二规范化不是定理成立的必要条件,只是让规则与证明更易展开。下面给出一个完全列出的规范例子,随后证明变量语义的两个方向。
对 NPDA,按终态接受与按空栈接受可经新初态、受保护的底标记与清栈阶段转换。构造保证语言相同,通常会增加状态或文法变量,不保证运行条数、歧义或表示大小不变,也不保证保持确定性。
直觉
文法与 PDA 是同一种嵌套机制的生成、识别两面。文法推导把尚未展开的非终结符当作待办结构,PDA 栈也保存尚待匹配或展开的任务;产生式选择对应栈顶替换,终结符匹配对应消费输入。反向构造较复杂,是因为文法必须预先概括一段运行“从某状态压着某符号开始,到哪个状态恰好弹掉它”的所有可能。非确定性承担选择产生式或猜测分解的角色。
图片加载失败 CFG–PDA 嵌套对应
例子与边界
对文法 S → a S b ∣ ε ,PDA 初始栈为 S 。选择第一条规则把栈顶替换为 aSb,随后匹配输入 a,递归处理 S ,最后匹配 b;选择 ε 规则结束嵌套,因此接受恰好 a n b n 。按“剩余输入,栈顶在左的栈”记录,图中 aabb 的完整对应为
( a a b b , S ) ⊢ ( a a b b , a S b ) ⊢ ( a b b , S b ) ⊢ ( a b b , a S b b ) ⊢ ( b b , S b b ) ⊢ ( b b , b b ) ⊢ ( b , b ) ⊢ ( ε , ε ) . 展开规则不消费输入,匹配终结符才消费输入。实现替换 S ↦ a S b 时若逐个压入,就要依次压 b , S , a ,使 a 留在栈顶。每一步均保持“已读前缀加上当前栈串,是文法能导出的句型”这一不变式;栈和输入同时为空,才得到完整推导。
边界是确定性:CFG 到 PDA 的直接构造会在一个非终结符有多条产生式时非确定选择,不能据此得到 DPDA。全部 CFL 都有 NPDA,但只有严格子类有确定 PDA;文法无歧义也不自动保证对应语言是确定性上下文无关的。
从六个动作列出全部八个变量
现在从机器出发。取 Q = { p , q } 、Γ = { Z , A } 、初态 p 、初始栈 Z ,恰有以下六个动作:
当前状态
读取
栈顶
新状态
替换串
p
a
Z
p
A Z
p
a
A
p
A A
p
b
A
q
ε
q
b
A
q
ε
p
ε
Z
q
ε
q
ε
Z
q
ε
没有列出的动作均不存在。状态 p 可连续读 a 压入 A ;首个 b 进入 q ,以后只能读 b 弹栈。按空栈接受,输入仍须读完。尤其在初始时立即弹掉 Z 的分支只接受空字,不能在还有输入时凭空结束。
三元变量恰有 2 ⋅ 2 ⋅ 2 = 8 个。下表逐行列出全部右侧;同一行的“或”表示不同规则,无产生式 不表示产生空字:
变量
全部产生式右侧
[ p Z p ]
a [ p A p ] [ p Z p ] 或 a [ p A q ] [ q Z p ]
[ p Z q ]
a [ p A p ] [ p Z q ] 或 a [ p A q ] [ q Z q ] 或 ε
[ p A p ]
a [ p A p ] [ p A p ] 或 a [ p A q ] [ q A p ]
[ p A q ]
a [ p A p ] [ p A q ] 或 a [ p A q ] [ q A q ] 或 b
[ q Z p ]
无产生式
[ q Z q ]
ε
[ q A p ]
无产生式
[ q A q ]
b
另有 S → [ p Z p ] 与 S → [ p Z q ] ,共十二条变量规则和两条开始规则。例如第一动作把 Z 换成 A Z ,所以对两个中间状态、两个终点状态各生成一条规则,正好贡献表中前两行的四条带 a 规则。
在 aabb 上,机器接受运行是
( p , a a b b , Z ) ⊢ ( p , a b b , A Z ) ⊢ ( p , b b , A A Z ) ⊢ ( q , b , A Z ) ⊢ ( q , ε , Z ) ⊢ ( q , ε , ε ) . 完整文法中的最左推导与它对应:
S ⇒ [ p Z q ] ⇒ a [ p A q ] [ q Z q ] ⇒ a a [ p A q ] [ q A q ] [ q Z q ] ⇒ a a b [ q A q ] [ q Z q ] ⇒ a a b b [ q Z q ] ⇒ a a b b . 最后的 [ q Z q ] → ε 对应真实的底符号弹出动作,不能删掉这一步而宣称栈已经空了。开始规则只选终点状态;其后五次展开才对应五个机器动作。
有规则不等于能产生终结字
[ q Z p ] 、[ q A p ] 没有规则;[ p A p ] 的规则或者继续依赖自己,或者依赖 [ q A p ] ,没有有限推导的终结基例。因此这三个变量都不能生成终结字,[ p Z p ] 也因依赖它们而不能生成。其余四个变量都有直接的终结右侧。
删去这四个不生成变量以及含它们的规则,保留下来的文法为
S → [ p Z q ] , [ p Z q ] → a [ p A q ] [ q Z q ] ∣ ε , [ p A q ] → a [ p A q ] [ q A q ] ∣ b , [ q Z q ] → ε , [ q A q ] → b . 代入后两项并令 B = [ p A q ] ,可写成 S → a B ∣ ε 、B → a B b ∣ b 。B 每次递归同时增加一个 a 与一个 b ,最后用 b 结束,故生成 a k b k + 1 ;S 恰好生成 a n b n 。这与前面的单变量文法等价,但不是说“删无用变量”一步便直接得到 S → a S b ∣ ε 。
机器上也可独立核对:读过 a n 后栈为 A n Z ,每个 b 恰好去掉一个 A ,且进入 q 后不能再读 a 。短一个 b 会留栈,多一个 b 没有可用动作,交错输入也无法通过。两种描述得到相同语言,而不只是恰好都接受 aabb 。
推论与应用
为什么三元变量与受保护栈段等价
先证运行推出推导 ,对受保护栈段的动作数作强归纳 公理库 强归纳法 Strong induction · Complete induction 归纳步可假设所有较小自然数情形成立。 。零个动作不能去掉顶部的 X ,所以没有零步情形。设首动作读取 a ,把 X 换成 α ,并进入 r ;a 可以为空。
若 α = ε ,这一步已首次露出 β ,由栈段定义运行必须就在此结束。因此终点是 r 、所读字是 a ,直接使用 [ u X r ] → a 。
若 α = Y ,首动作后剩余运行恰是去掉 Y 的较短受保护段。设它消费 x 并到达 v ,归纳得到 [ r Y v ] ⇒ ∗ x ,再用 [ u X v ] → a [ r Y v ] 。
若 α = Y Z ,后续运行终将去掉这两个原栈位置。考虑首次露出未触动的 Z β 的时刻:设状态为 s ,此前在首动作之后消费 x ,此后消费 y 。于是运行分成
( r , x y z , Y Z β ) ⊢ ∗ ( s , y z , Z β ) ⊢ ∗ ( v , z , β ) . 一栈顶动作不能越过尚未去掉的 Y 而直接修改原 Z ,所以这个切点存在。两段分别去掉 Y 、Z ,都是比原段短的受保护段;归纳得到 [ r Y s ] ⇒ ∗ x 和 [ s Z v ] ⇒ ∗ y ,再使用长度二规则,生成 a x y 。切点跟踪的是原有栈位置,不是碰巧出现相同字母的任意时刻。
反向证推导推出运行 ,对有限推导树 公理库 语法树 Parse tree · Derivation tree 用有序树记录产生式层次,以完整例子区分推导顺序、文法歧义、优先级及抽象语法树。 作结构归纳。叶规则 [ u X r ] → a 本身就是一个真实弹栈动作。一子树规则先执行首动作,再把子树给出的运行放在 β 上;两子树规则先把 X 换成 Y Z ,把第一子树的运行放在后缀 Z β 上,首次露出该后缀后,再把第二子树的运行放在 β 上。它们在规则写出的中间状态 s 接续,且终点之前不会触碰原 β 。
这两个归纳证明所有变量的语义。取 β = z = ε ,再由开始规则枚举终点,便有 L ( G ) = N ( P ) 。证明不能简单改成按输入字长归纳:ε 动作可能让非空子运行消费零个符号,字长未必严格下降。
任意机器怎样进入这个规范接口
若原机器按终态接受,加入新初态 i 、清栈态 d 和新底标记 ⊥ 。新机器初始栈为 ⊥ ,先用 ε 动作替换为 Z 0 ⊥ 并进入原 q 0 。原动作照旧,但它们不能匹配新增 ⊥ 。
从每个原终态 f ,对每个 X ∈ Γ ∪ { ⊥ } ,允许 ε 弹出 X 并进入 d ;d 再以 ε 动作逐个弹栈,没有读字符动作或返回旧状态的出口。只有这个阶段能弹掉新底标记。原来在非终态弹空旧栈不会误收;原来在终态且旧栈已空,也可以通过弹 ⊥ 接受。
原接受运行后接清栈,就得到新接受运行。反之,新接受运行必须从某个原终态进入清栈,而清栈不消费输入;既然最终输入读完,进入时便已读完,之前的模拟就是原接受运行。允许提前猜测进入清栈不会误收,因为剩余输入无法再被消费。这一证明没有假设机器能主动检测“输入已经结束”。
若某动作替换为 Y 1 ⋯ Y k 、k ≥ 3 ,可以为它增加专用控制状态 c k − 1 , … , c 2 ,记 c 1 = r 。第一步按原动作读取 a ,把 X 换成 Y k − 1 Y k 并进入 c k − 1 ;随后对 j = k − 1 , … , 2 ,仅允许
( c j , ε , Y j ) ↦ ( c j − 1 , Y j − 1 Y j ) . 栈依次成为 Y k − 1 Y k β , … , Y 1 ⋯ Y k β ,输入只在首步消费。新状态没有别的出口,中间也不会露出 β ,所以整个链恰好模拟一个旧动作。每步替换长度不超过二,无需凭空在空栈上压入符号。
若规范化后有 n 个状态、g 个栈符号和 t 个动作,三元变量数为 n 2 g ,加上新开始符号;每个长度二动作产生 n 2 条规则,长度一产生 n 条,弹栈动作只产生一条。这解释了为什么语言等价不意味着表示大小相近。
定理把上下文无关文法 公理库 上下文无关文法 Context-free grammar · CFG 每条产生式左侧是单个非终结符的生成系统。 的生成视角与下推自动机 公理库 下推自动机 Pushdown automaton · PDA 带无界栈存储的有限控制自动机。 的运行视角统一起来。可用文法闭包与范式证明语言性质,也可用栈机器设计识别算法。
编译原理中,语法规格被转换为带栈解析器;在理论上,该等价支撑 CFL 的成员判定、闭包分析和与确定 PDA 公理库 确定性下推自动机 Deterministic pushdown automaton · DPDA 每个配置至多有一个可用转移且读入与 ε 转移不冲突的下推自动机。 子类的比较。
终点自测:从六动作表独立列出十四条规则,标出四个不能生成终结字的变量,写出 aabb 的运行及最左推导;再说明二符号替换的中间状态对应哪个首次弹栈边界,以及为何 ε 动作迫使证明采用运行步数而非输入长度。
参考资料
John E. Hopcroft, Rajeev Motwani, and Jeffrey D. Ullman, Introduction to Automata Theory, Languages, and Computation, 3rd ed., Pearson, 2006,Chs. 5–6, pushdown automata and context-free grammars。
Michael Sipser, Introduction to the Theory of Computation, 3rd ed., Cengage, 2013,Ch. 2, equivalence of pushdown automata and context-free grammars。
Old Dominion University CS390, Pushdown Automata , Fall 2024 course notes,§§2.1–2.2,双向构造。
Alfred V. Aho, Columbia COMS W3261, Lecture 9: CFG's and PDA's ,§2 给出一般长度的三元变量构造与单栈符号运行命题,§3 讨论不生成与不可达变量。上面的八变量表、规范化链和双向栈段归纳按本页模型展开,不将讲义中未展开的归纳冒称为原文完整证明。