void Tracematch::advance_current_states(States& current_states, UINT32 symbol_id) { list<Vertex> next_states; unordered_set<Vertex> visited_states; OutEdgeIterator oei, oei_end; list<Vertex>::iterator i = current_states.begin(); while (i != current_states.end()) { if (visited_states.find(*i) == visited_states.end()) { /* Unvisited state */ for (boost::tie(oei, oei_end) = boost::out_edges(*i, graph); oei != oei_end; ++oei) { /* Epsilon transition */ if (graph[*oei].symbol_id == SYMBOL_ID_EPSILON) { current_states.push_back(boost::target(*oei, graph)); } /* Match */ else if (graph[*oei].symbol_id == symbol_id) { next_states.push_back(boost::target(*oei, graph)); } } visited_states.insert(*i); } /* Erase this element */ current_states.erase(i++); } current_states = next_states; }
bool Tracematch::current_states_is_end(const States& current_states) { States states = current_states; unordered_set<Vertex> visited_states; OutEdgeIterator oei, oei_end; list<Vertex>::iterator i = states.begin(); while (i != states.end()) { if (visited_states.find(*i) == visited_states.end()) { /* Unvisited state */ if (*i == graph_properties.end) { return true; } for (boost::tie(oei, oei_end) = boost::out_edges(*i, graph); oei != oei_end; ++oei) { /* Epsilon transition */ if (graph[*oei].symbol_id == SYMBOL_ID_EPSILON) { states.push_back(boost::target(*oei, graph)); } } visited_states.insert(*i); } /* Erase this element */ states.erase(i++); } return false; }
// 所有能从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; }