clos1.push_back(clos_t(nfa.root, ZERO_TAGS));
closure(clos1, clos2, tagpool, rules, badtags);
- find_state(clos2, clospool);
+ clospool.insert(clos2);
+ // closures are in sync with DFA states
for (size_t i = 0; i < clospool.size(); ++i) {
const closure_t &clos0 = clospool[i];
+
+ // create new DFA state
dfa_state_t *s = new dfa_state_t(nchars);
states.push_back(s);
- for (size_t c = 0; c < nchars; ++c) {
- reach(clos0, clos1, charset[c]);
- s->tags[c] = closure(clos1, clos2, tagpool, rules, badtags);
- s->arcs[c] = find_state(clos2, clospool);
- }
-
+ // check if the new state is final
// see note [at most one final item per closure]
- cclositer_t
- e = clos0.end(),
+ cclositer_t e = clos0.end(),
f = std::find_if(clos0.begin(), e, clos_t::final);
if (f != e) {
s->rule = f->state->rule;
s->rule_tags = f->tagidx;
}
+
+ // for each alphabet symbol, build tagged epsilon-closure
+ // of all NFA states reachable on that symbol, then try to
+ // find identical closure or add the new one
+ for (size_t c = 0; c < nchars; ++c) {
+ reach(clos0, clos1, charset[c]);
+ s->tags[c] = closure(clos1, clos2, tagpool, rules, badtags);
+ s->arcs[c] = clospool.insert(clos2);
+ }
}
warn_bad_tags(badtags, tags, rules, cond);
size_t clospool_t::insert(const closure_t &clos)
{
+ // empty closure corresponds to default state
+ if (clos.empty()) {
+ return dfa_t::NIL;
+ }
+
const uint32_t hash = hashclos(clos);
// try to find an identical DFA state
return lookup.push(hash, new closure_t(clos));
}
-size_t find_state(const closure_t &clos, clospool_t &clospool)
-{
- // empty closure corresponds to default state
- if (clos.empty()) {
- return dfa_t::NIL;
- }
-
- return clospool.insert(clos);
-}
-
} // namespace re2c