// 所有从from通过一次ch到达的NFA状态 // 这里有-1,表示上次fill只有一个最终状态,即-1 static States expand(const std::vector<NFATran>& trans, const States& from, char ch) { States to; for (States::const_iterator it = from.begin(); it != from.end(); ++it) { int s = *it; if (s == -1) { to.clear(); to.insert(-1); break; } const NFATran& tran = trans[s]; NFATran::const_iterator tit = tran.find(ch); if (tit == tran.end()) { continue; } const States& next = tit->second; for (States::const_iterator nit = next.begin(); nit != next.end(); ++nit) { to.insert(*nit); } } return to; }
// 所有能从from通过EPSILON能达到的NFA状态(包括from) static States fill(const std::vector<NFATran>& trans, const States& last, const States& from, bool* is_last) { std::queue<int> q; for (States::const_iterator it = from.begin(); it != from.end(); ++it) { q.push(*it); } // ends表示终点(即最终状态),要判断这次转移是否只有-1 States ends; States to; while (!q.empty()) { int s = q.front(); q.pop(); to.insert(s); if (last.find(s) != last.end()) { *is_last = true; } if (s == -1) { ends.insert(-1); continue; } const NFATran& tran = trans[s]; NFATran::const_iterator it = tran.find(EPSILON); if (it == tran.end()) { ends.insert(s); continue; } const States& next = it->second; for (States::const_iterator nit = next.begin(); nit != next.end(); ++nit) { if (to.find(*nit) == to.end()) { q.push(*nit); } } } if (ends.find(-1) == ends.end() || ends.size() > 1) { to.erase(-1); } else { to.clear(); to.insert(-1); } return to; }
bool DFAConverter::build(int start, const States& last, const std::vector<NFATran>& trans, const std::map<size_t, Tag>& tags) { reset(); std::map<States, int> nfa_to_dfa; States v; v.insert(-1); nfa_to_dfa[v] = -1; v.clear(); bool is_last = false; v.insert(start); v = fill(trans, last, v, &is_last); _start = new_state(); nfa_to_dfa[v] = _start; if (is_last) { _last.insert(_start); } merge_tags(v, tags, _start, &_tags); std::queue<States> q; q.push(v); while (!q.empty()) { v = q.front(); q.pop(); int from = nfa_to_dfa[v]; std::set<Byte> dedup; dedup.insert(EPSILON); for (States::const_iterator it = v.begin(); it != v.end(); ++it) { int s = *it; assert(s >= 0); const NFATran& tran = trans[s]; for (NFATran::const_iterator it = tran.begin(); it != tran.end(); ++it) { if (dedup.find(it->first) != dedup.end()) { continue; } is_last = false; States next = expand(trans, v, it->first); next = fill(trans, last, next, &is_last); int to = -1; if (nfa_to_dfa.find(next) == nfa_to_dfa.end()) { to = new_state(); nfa_to_dfa[next] = to; q.push(next); if (is_last) { _last.insert(to); } merge_tags(next, tags, to, &_tags); } else { to = nfa_to_dfa[next]; } _trans[from][it->first] = to; dedup.insert(it->first); } } } return true; }