【计算理论】计算理论总结 ( 上下文无关文法 CFG 转为下推自动机 PDA 示例 2 ) ★★

文章目录

  • 一、上下文无关文法 CFG 转为下推自动机 PDA 流程
  • 二、上下文无关文法 CFG 转为下推自动机 PDA 示例 2

参考博客 :

  • 【计算理论】上下文无关语法 ( 语法组成 | 规则 | 语法 | 语法示例 | 约定的简写形式 | 语法分析树 )
  • 【计算理论】上下文无关语法 ( 代数表达式 | 代数表达式示例 | 确定性有限自动机 DFA 转为 上下文无关语法 )
  • 【计算理论】上下文无关语法 CFG ( CFG 设计示例 | CFG 歧义性 | Chomsky 范式 | 上下文无关语法 转为 Chomsky 范式 )
  • 【计算理论】下推自动机 PDA 及 计算示例
  • 【计算理论】下推自动机 PDA ( 设计下推自动机 | 上下文无关语法 CFG 等价于 下推自动机 PDA )
  • 【计算理论】上下文无关语法 ( CFG ) 转为 下推自动机 ( PDA )
  • 【计算理论】下推自动机 PDA ( 上下文无关语言 CFL 的 泵引理 | 泵引理反证示例 | 自动机扩展 )

一、上下文无关文法 CFG 转为下推自动机 PDA 流程


上下文无关文法 CFG 转为下推自动机 PDA 流程 :

① 开始状态 : 开始状态

\rm q_{start}

, 跳转到

\rm q_{loop}

状态的指令

\rm \varepsilon , \varepsilon \to K

, 使用

\rm K

替换栈内空字符

\varepsilon

, 即将

\rm K

放入栈中 ;

② 循环状态 :

\rm q_{loop}

状态的指令都是从本状态指向本状态 , 生成两种指令 , 一种是基本指令 , 一种是终端字符指令 ;

基本指令

\rm S \to aTb|b

生成为

\rm \varepsilon , S \to aTb

\rm \varepsilon , S \to b

两条指令 , 前面都是读取空字符作为栈读取的信息 ;

终端字符指令 , 如果存在终端字符

\rm a

\rm b

, 那么生成

\rm a, a \to \varepsilon

\rm b, b \to \varepsilon

两条指令 , 含义是读取栈顶

\rm a

字符 , 将该字符使用空字符替代 , 即从栈中删除该字符 ;

③ 接受状态 :

\rm q_{loop}

状态跳转到

\rm q_{accept}

指令是

\rm \varepsilon , K \to \varepsilon

, 栈顶读取到

\rm K

字符删除 ;

④ 拆分指令 : 在循环状态

\rm q_{loop}

中的基本指令中存在多字符指令 , 如

\rm \varepsilon , S \to aTb

, 读取到空字符

\varepsilon

, 使用

\rm aTb

字符替换栈顶的

\rm S

字符 , 这是

3

个字符 , 肯定不行 , 需要逐个放进去 , 先放

\rm b

, 再放

\rm T

, 最后放

\rm a

;

最终分解为

\rm \varepsilon , S \to b

读取空字符放入

\rm b

到栈顶 ,

\rm \varepsilon , \varepsilon \to T

读取空字符放入

\rm T

到栈顶 ,

\rm \varepsilon , \varepsilon \to a

读取空字符放入

\rm a

到栈顶 ;

二、上下文无关文法 CFG 转为下推自动机 PDA 示例 2


将上下文无关语法 ( CFG ) 转为下推自动机 ( PDA ) :

\rm R \to XRX | S
\rm S \to aTb | bTa
\rm T \to XTX | X |\varepsilon
\rm X \to a | b

上下文无关文法 CFG 转为下推自动机 PDA 流程 :

① 开始状态 : 开始状态

\rm q_{start}

, 跳转到

\rm q_{loop}

状态的指令

\rm \varepsilon , \varepsilon \to K

, 使用

\rm K

替换栈内空字符

\varepsilon

, 即将

\rm K

放入栈中 ;

② 循环状态 :

\rm q_{loop}

状态的指令都是从本状态指向本状态 , 生成两种指令 , 一种是基本指令 , 一种是终端字符指令 ;

基本指令

\rm R \to XRX | S

生成为 :

\rm \varepsilon , R \to XRX

\rm \varepsilon , R \to S

两条指令 , 前面都是读取空字符作为栈读取的信息 ;

基本指令

\rm S \to aTb | bTa

生成为 :

\rm \varepsilon , S \to aTb

\rm \varepsilon , S \to bTa

两条指令 , 前面都是读取空字符作为栈读取的信息 ;

基本指令

\rm T \to XTX | X |\varepsilon

生成为 :

\rm \varepsilon , T \to XTX

,

\rm \varepsilon , T \to X

,

\rm \varepsilon , T \to \varepsilon

三条指令 , 前面都是读取空字符作为栈读取的信息 ;

基本指令

\rm X \to a | b

生成为 :

\rm \varepsilon , X \to a

\rm \varepsilon , X \to b

两条指令 , 前面都是读取空字符作为栈读取的信息 ;

终端字符指令 : 如果存在终端字符

\rm a

\rm b

, 那么生成

\rm a, a \to \varepsilon

\rm b, b \to \varepsilon

两条指令 , 含义是读取栈顶

\rm a

字符 , 将该字符使用空字符替代 , 即从栈中删除该字符 ;

③ 接受状态 :

\rm q_{loop}

状态跳转到

\rm q_{accept}

指令是

\rm \varepsilon , K \to \varepsilon

, 栈顶读取到

\rm K

字符删除 ;

④ 拆分指令 : 在循环状态

\rm q_{loop}

中的基本指令中存在多字符指令 , 如

\rm \varepsilon , R \to XRX

, 读取到空字符

\varepsilon

, 使用

\rm XRX

字符替换栈顶的

\rm R

字符 , 这是

3

个字符 , 肯定不行 , 需要逐个放进去 , 先放

\rm X

( 第三个 ) , 再放

\rm R

, 最后放

\rm X

( 第一个 ) ;

\rm \varepsilon , R \to XRX

最终分解为 :

\rm \varepsilon , R \to X

读取空字符后 , 使用

\rm X

字符替换栈顶

\rm R

字符 ,

\rm \varepsilon , \varepsilon \to R

读取空字符后 , 将

\rm R

字符放到到栈顶 ,

\rm \varepsilon , \varepsilon \to X

读取空字符后 , 将

\rm X

字符放到到栈顶 ;

\rm \varepsilon , S \to aTb

最终分解为 :

\rm \varepsilon , S \to b

读取空字符后 , 使用

\rm b

字符替换栈顶

\rm S

字符 ,

\rm \varepsilon , \varepsilon \to T

读取空字符后 , 将

\rm T

字符放到到栈顶 ,

\rm \varepsilon , \varepsilon \to a

读取空字符后 , 将

\rm a

字符放到到栈顶 ;

\rm \varepsilon , S \to bTa

最终分解为 :

\rm \varepsilon , S \to a

读取空字符后 , 使用

\rm a

字符替换栈顶

\rm S

字符 ,

\rm \varepsilon , \varepsilon \to T

读取空字符后 , 将

\rm T

字符放到到栈顶 ,

\rm \varepsilon , \varepsilon \to b

读取空字符后 , 将

\rm b

字符放到到栈顶 ;

\rm \varepsilon , T \to XTX
\rm \varepsilon , T \to X

读取空字符后 , 使用

\rm X

字符替换栈顶

\rm T

字符 ,

\rm \varepsilon , \varepsilon \to T

读取空字符后 , 将

\rm T

字符放到到栈顶 ,

\rm \varepsilon , \varepsilon \to X

读取空字符后 , 将

\rm X

字符放到到栈顶 ;

最终的下推自动机样式 :