RE转NFA,NFA转DFA 发表于 2017-10-29 | 分类于 原理 , 编译原理 字数统计: 341 字 简单笔记 Thompson算法 —— RE -> NFA基本思想 基本的RE直接构造 复合的RE递归构造 123456e -> eps -> 单个字符c // 前两种可以直接构造 -> e1e2 -> e1|e2 -> e1* // 后三种递归构造 eps c e1e2 e1|e2 e1* 实例 a(b|c)* 子集构造算法 —— NFA -> DFA基本思想12345678910111213141516171819- 0 => 记为q0,添加进Q状态集中,下同- q0 ——a——> 1 ==a(eps)==> 1 2 3 4 6 *9 => 记为q1- q1 ——b——> 5 // delta(q1)集合,对每个q1元素的b通路 ==b(eps)==> 5 8 *9 3 4 6 => 记为q2 // eps-闭包(eps-closure) ——c——> 7 ==c(eps)==> 7 8 *9 3 4 6 => 记为q3 - q2 ——c——> 7 ==c(eps)==> 7 8 9 3 4 6 == q3 ——b——> 5 ==b(eps)==> 5 8 9 3 4 6 == q2- q3 ——b——> 5 ==b(eps)==> 5 8 9 3 4 6 == q2 ——c——> 7 ==c(eps)==> 7 8 9 3 4 6 == q3 算法伪代码由上面的基本思想,容易得到以下代码:1234567891011q0 <- eps_closure(n0)Q <- {q0}workList <- q0while (!workList.empty()) q <- workList.pop() for each character c // 256个ASCII码 t <- eps_closure(delta(q, c)) if (t not in Q) add t to Q add t to workList D[q, c] <- t // DFA记录此状态转换 eps-闭包的计算:深度优先1234567set closure = {}void eps_closure(x) closure += {x} for each (y| x --eps--> y) if (!visited(y)) eps_closure(y) // 递归 eps-闭包的计算:宽度优先1234567891011set closure = {}Q = [] // queuevoid eps_closure(x) Q = [x] while (!Q.empty()) q <- Q.deQueue() closure += q for each (y| q --eps--> y) if (!visited(y)) Q.enQueue(y) 本文作者: Gaufoo 本文链接: https://gaufoo.com/REtoNFAtoDFA/ 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 许可协议。转载请注明出处!