RE(Regular Expression)到最小DFA(Deterministic Finite Automaton)的转换是构建正则表达式引擎的基础,并且也是构建词法分析器的基础.
RE
RE描述了一个定义在某个字母表Σ上的字符串集合L,并且空字符串ε也属于L集合.形式化的定义并不好理解,但是相对其他非形式化的定义来说更加简洁和准确.这里的正则表达式和平常所用的处理字符串的正则表达式是同一个,但是这里更加简单.这里的RE只有三个基本的操作:
(1)选择 取并集.符号:|. 比如两个字符串集合R和S的选择操作,记作R|S.
(2)连接 字符串之间的拼接.两个字符串集合R和S的连接为RS.
(3)闭包 符号:* 字符串集合R的闭包R*是指把R与自身连接零次或者多次形成的所有集合的并集.
由这几个简单的操作可以得到我们平常接触的正则表达式的所有扩展.
有限状态自动机(Finite Automaton,FA)
我说的时候喜欢加上状态两个字,因为FA的关键动作就是状态间的转移.FA有一个状态集S,对于每一个输入都会让FA的状态进行转移.如果能够从起始状态转移到接受状态,那么输入序列就被识别了.不存在空字符串ε的状态转移.
非确定性有限状态自动机(Non-deterministic Finite Automaton,NFA).对于同一输入转移到多个不同的状态或者存在空字符串ε的状态转移的FA.
确定性有限状态自动机(Deterministic Finite Automaton,DFA).对于任何确定的输入都只有唯一确定的转移且不存在空字符串ε的状态转移的FA.
从正则表达式到NFA
上面描述的RE的基本操作的简单NFA:
a的NFA b的NFA ab的NFA a|b a的闭包:a*的NFA只要有了这三个RE基本操作的NFA,我们就能对任何组合得来的RE求出对应的NFA. 构造"a(b|c)*"的NFA举例
NFA到DFA
NFA到DFA 是对NFA的简化过程.
NFA到DFA的子集构造算法(The Subset Construction):从将初始状态划分为一个初始状态子集开始,构造状态子集(经过零个或多个空字符串ε转移到的状态和已在子集中的状态都是构造的新的状态子集),存在c属于字母表Σ,经过一个c的转移(必须有c的转移),能够使得从状态子集ni转移到状态子集nj,则在DFA中有在c的输入下从状态子集ni转移到状态子集nj的转移.最后不再有新的状态子集出现.根据状态子集的转移依次构造DFA.
DFA到最小DFA
最小化DFA用到的是等价状态集合的划分来构建.一开始只有两个状态集,一个接受状态集合,一个非接受状态集合.对于每一个状态集合Sp,如果存在c属于字母表Σ,使得Sp中的状态转移到不同的状态集合(包括没有转移的空状态集合),则拆分Sp,使得拆分后的状态集合中的每一个状态不可能转移到不同的状态集合.其中状态集合之间的转移构成最小化DFA中的转移.
"a(b|c)*"最小化DFA的初始划分 "a(b|c)*"的最小DFA
网友评论