【计算理论】上下文无关语法 ( CFG ) 转为 下推自动机 ( PDA )





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



上下文无关语法 ( CFG ) :

SaTbbS \to aTb | b
TTaεT \to Ta|\varepsilon


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





II . 下推自动机 ( PDA ) 三个状态



该 自动机 共包含 33 个状态 , qstartq_{start} , qloopq_{loop} , qacceptq_{accept} , 最后一个状态是 可接受状态 ;

在这里插入图片描述





III . 下推自动机 ( PDA ) qstartq_{start} 状态



1 . 首先在 栈顶 放入 KK 字符 , 用于当做栈底的标识 ;


生成指令 : ε,εK\varepsilon , \varepsilon \to K ;

开始状态 qstartq_{start} 状态 , 读取 ε,εK\varepsilon , \varepsilon \to K 指令 , 读取空字符 , 使用 KK 替换栈顶的空字符 , 就是将 KK 放入栈中 ;

状态跳转 : 之后跳转到 qloopq_{loop} 状态 ;


当前的 下推自动机 ( CFG ) 设计 :
在这里插入图片描述





IV . 下推自动机 ( PDA ) qloopq_{loop} 状态



1 . qloopq_{loop} 状态下 在栈中模仿 上下文无关语法 ( CFG ) 的规则替换 ;


上下文无关语法 ( CFG ) :

SaTbbS \to aTb | b
TTaεT \to Ta|\varepsilon


2 . 对照上述 上下文无关语法 ( CFG ) , 逐条生成指令 :


SaTbS \to aTb 对应的指令 : ε,SaTb\varepsilon , S \to aTb , 读取 ε\varepsilon 时 , 使用 aTbaTb 替换栈顶的 SS ; 即如果栈顶是 SS , 使用 aTbaTb 替换栈顶的 SS ;

SbS \to b 对应的指令 : ε,Sb\varepsilon , S \to b , 读取 ε\varepsilon 时 , 使用 bb 替换栈顶的 SS ; 即如果栈顶是 SS , 使用 bb 替换栈顶的 SS ;

TTaT \to Ta 对应的指令 : ε,TTa\varepsilon , T \to Ta , 读取 ε\varepsilon 时 , 使用 TaTa 替换栈顶的 TT ; 即如果栈顶是 TT , 使用 TaTa 替换栈顶的 TT ;

TεT \to \varepsilon 对应的指令 : ε,Tε\varepsilon , T \to \varepsilon , 读取 ε\varepsilon 时 , 使用 ε\varepsilon 替换栈顶的 TT ; 即如果栈顶是 TT , 使用 ε\varepsilon 替换栈顶的 TT ;

如果栈上有终端字符 aa , 要将栈里的终端字符 aa 移除 , 对应指令是 a,aεa , a \to \varepsilon , 如果读取到字符 aa 时 , 从栈顶将字符 aa 移除 ;

如果栈上有终端字符 bb , 要将栈里的终端字符 bb 移除 , 对应指令是 b,bεb , b \to \varepsilon , 如果读取到字符 bb 时 , 从栈顶将字符 bb 移除 ;

在这里插入图片描述





V . 下推自动机 ( PDA ) qacceptq_{accept} 状态



1 . qacceptq_{accept} 状态 :


qloopq_{loop} 状态下 , 将栈内的除 KK 外所有的字符都移除完毕 , 开始向 qacceptq_{accept} 状态跳转 ;

此时需要生成指令 ε,Kε\varepsilon , K \to \varepsilon , 读取 空字符 ε\varepsilon , 使用 空字符 ε\varepsilon 替换栈顶的 KK 字符 , 此时栈清空了 ;

在这里插入图片描述





VI . 下推自动机 ( PDA ) 指令分解



1 . 非法指令分解


上述生成的

  • ε,SaTb\varepsilon , S \to aTb
  • ε,TTa\varepsilon , T \to Ta

两个指令是不合法的 , 在栈中 , 一个字符 ( 或空字符串 ε\varepsilon ) 只能由 一个字符 ( 或空字符串 ε\varepsilon ) 替换 ;


上述不合法的规则 , 多个字符替换栈顶的一个字符 , 需要进行分解操作 ;



2 . ε,SaTb\varepsilon , S \to aTb 指令分解流程 :


qloopq_{loop} 状态 跳转到 新的状态 qloop1q_{loop1} , 跳转读取的指令时 ε,Sb\varepsilon , S \to b , 读取空字符 , 然后使用 bb 替换栈顶的 SS 字符 ;

在这里插入图片描述


qloop1q_{loop1} 状态 跳转到 新的状态 qloop2q_{loop2} , 跳转读取的指令时 ε,εT\varepsilon , \varepsilon \to T , 读取空字符 , 然后使用 TT 替换栈顶的 ε\varepsilon 字符 , 相当于在栈中放入了 TT 字符 ;

在这里插入图片描述

qloop2q_{loop2} 状态 跳转到 原来的状态 qloopq_{loop} , 跳转读取的指令时 ε,εa\varepsilon , \varepsilon \to a , 读取空字符 , 然后使用 aa 替换栈顶的 ε\varepsilon 字符 , 相当于在栈中放入了 aa 字符 ;

在这里插入图片描述


分解 ε,SaTb\varepsilon , S \to aTb 后的 33 个指令 :

  • ε,Sb\varepsilon , S \to b
  • ε,εT\varepsilon , \varepsilon \to T
  • ε,εa\varepsilon , \varepsilon \to a

上述三个指令都是合法的 , 上述 33 个指令 串联后的效果等价于 ε,SaTb\varepsilon , S \to aTb 操作 , 等价于上下文无关语法的 SaTbS \to aTb 规则效果 ;



3 . ε,TTa\varepsilon , T \to Ta 指令分解流程 :


qloopq_{loop} 状态 跳转到 新的状态 qloop3q_{loop3} , 跳转读取的指令时 ε,Sa\varepsilon , S \to a , 读取空字符 , 然后使用 aa 替换栈顶的 SS 字符 ;

在这里插入图片描述

qloop3q_{loop3} 状态 跳转到 原来的状态 qloopq_{loop} , 跳转读取的指令时 ε,εT\varepsilon , \varepsilon \to T , 读取空字符 , 然后使用 TT 替换栈顶的 ε\varepsilon 字符 , 相当于在栈中放入了 TT 字符 ;

在这里插入图片描述


分解 ε,TTa\varepsilon , T \to Ta 后的 22 个指令 :

  • ε,Sa\varepsilon , S \to a
  • ε,εT\varepsilon , \varepsilon \to T

上述 22 个指令都是合法的 , 上述 22 个指令 串联后的效果等价于 ε,TTa\varepsilon , T \to Ta 指令 , 等价于上下文无关语法的 TTaT \to Ta 规则效果 ;





VII . 最终转换成的 下推自动机 ( PDA ) 结果



最终的 上下文无关语法 ( CFG ) 转为的 下推自动机 ( PDA ) 样式 :

在这里插入图片描述

上下文无关语法 ( CFG ) 与 下推自动机 ( PDA ) 是等价的 , 给定一个 下推自动机 ( PDA ) , 构造 上下文无关语法 ( CFG ) , 该语法生成的语言 , 就是该 下推自动机 ( PDA ) 所认识的语言 ;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章