码迷,mamicode.com
首页 > 其他好文 > 详细

读龙书学编译原理 词法分析(4)...

时间:2016-05-07 00:46:59      阅读:268      评论:0      收藏:0      [点我收藏+]

标签:

接下来的步骤就是从NFA转换为DFA...首先要思考的第一个问题是为什么要从NFA转换到DFA, 那么我们可以先来看看他们的区别, 通俗来讲, NFA就是说给定一个输入的字符, 可以有多种状态可以选择, 而DFA的话, 就只有一种状态可以选择... 由这里就可以发现, 其实DFA在代码的实现难度上是要小于NFA的, 所以我们才会考虑将NFA转化为DFA...

这个算法一般叫做子集构造算法, 该算法的核心过程有两点 : 

1. 对于给定的一个输入,  找出该状态所能到达的状态.

2. 对于上面得到的所有状态的集合求 ε 闭包 (也就是求所有状态通过ε之后所能得到的状态,循环求至不出现新的状态为止)

 

还是用之前那张图

技术分享

 

为什么这个算法能够运行终止呢 ?

原因在于 状态数是有限的, 最坏的情况下 有 2^n 个q, 时间复杂度也就是2^n, 现实中不常出现...

然后ε 闭包, 这个比较简单, 可以用树的搜索方法来dfs 和 bfs

技术分享

技术分享

 

所以最终子集构造算法就是这个样子

技术分享

稍微解释一下这个算法的话 : 首先 n0 是之前nfa 中的起始状态, 那么为什么要对这个点求 eps_closure呢 ?  就是为了避免图中右边这种情况, 起始状态就有很多条eps边. Q是最终生成的所有状态的集合, 所以现将q0所代表的集合(从Q的角度看, 整个q0只是一个单一的状态而已)放进去. 那么我们要通过q0来探索, 所以把q0加入这个worklist, 然后对其中的每一个状态n(q0里面可能有n0, n1, n2 ...), 遍历所有可能的输入字符, 每一次遍历(如果存在delta转化的话) 都可以看做是生成了一个状态(也就是基于状态qn 的状态集合), 也就是代码中的t, t有两个用处, 首先是把t 加入到状态转换表 D[q, c]中, 也就是在状态q 碰到输入字符是c的情况就转换到状态t. 另外一个作用是将t加入Q和workLIst中,  加入Q是为了防止重复 (Q是我们将要构造的DFA的状态集合), worklist是为了遍历这种状态, 看下由它又能转换到哪个状态. 这个过程不断持续, 直至所有可能的状态有出现为止...

读龙书学编译原理 词法分析(4)...

标签:

原文地址:http://www.cnblogs.com/nzhl/p/5467474.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!