本文是对编译原理中NFA到DFA的转换作的总结,该代码参考了编译原理中词法分析的相关内容.
闭包
NFA即不肯定有穷状态机,而DFA是肯定有穷状态机。spa
从本质上讲NFA与利用其构造而成的DFA是等价的,但由于NFA某一状态离开的路径可能有多条,所以经常在构造出NFA后将前面的状态集合作一抽象以构建对于每一状态离开路径只有一条的DFA。code
NFA到DFA的构造方法经常使用到两点,即子集构造法与闭包传递.it
1.0-closure(s) 可以从NFA的状态S开始只经过0转换到达的NFA的状态集合 2.0-closure(T) 可以从T中的某个NFA状态s开始只经过0转换到达的NFA的状态集合 3.move(T,a) 可以从T中某个状态s触发只经过标号为a的转换转换达到的NFA状态集合 /**子集构造法*/ NFA-DFA-CONVERT(nfa, dfa) s0 -> nfa的开始状态 U -> 0-closure(s0) push U into dfa without mark while ( T -> find one in dfa without mark){ mark T; for(every possible intput a) U' -> 0-closure(move(T, a)) if(U' is not in dfa) push U' into dfa without mark set dfa[T, a]->U' } /**计算0-closure(T)的闭包传递*/ CLOSURE(T) push all status in T into stack S push all status in T into U while(S is not empty){ t->pop one from S; for(每一个从t状态能经过空串转换获得的状态U') if(U'不在U中){ push U' into U; push U' into S; } } return U;
总结
dfa的每一个状态是对nfa状态集合的二次抽象.以此达到每一个状态只有一条离开路径.
编译