static void getForwardReach(const raw_dfa &rdfa, map<s32, CharReach> &look) { if (rdfa.states.size() < 2) { return; } ue2::flat_set<dstate_id_t> curr, next; curr.insert(rdfa.start_anchored); for (u32 i = 0; i < MAX_FWD_LEN && !curr.empty(); i++) { next.clear(); CharReach cr; for (const auto state_id : curr) { const dstate &ds = rdfa.states[state_id]; if (!ds.reports.empty() || !ds.reports_eod.empty()) { return; } for (unsigned c = 0; c < N_CHARS; c++) { dstate_id_t succ = ds.next[rdfa.alpha_remap[c]]; if (succ != DEAD_STATE) { cr.set(c); next.insert(succ); } } } assert(cr.any()); look[i] |= cr; curr.swap(next); } }
static void getForwardReach(const NGHolder &g, u32 top, map<s32, CharReach> &look) { ue2::flat_set<NFAVertex> curr, next; // Consider only successors of start with the required top. for (const auto &e : out_edges_range(g.start, g)) { NFAVertex v = target(e, g); if (v == g.startDs) { continue; } if (g[e].top == top) { curr.insert(v); } } for (u32 i = 0; i < MAX_FWD_LEN; i++) { if (curr.empty() || contains(curr, g.accept) || contains(curr, g.acceptEod)) { break; } next.clear(); CharReach cr; for (auto v : curr) { assert(!is_special(v, g)); cr |= g[v].char_reach; insert(&next, adjacent_vertices(v, g)); } assert(cr.any()); look[i] |= cr; curr.swap(next); } }
static void getBackwardReach(const NGHolder &g, ReportID report, u32 lag, map<s32, CharReach> &look) { ue2::flat_set<NFAVertex> curr, next; for (auto v : inv_adjacent_vertices_range(g.accept, g)) { if (contains(g[v].reports, report)) { curr.insert(v); } } for (u32 i = lag + 1; i <= MAX_BACK_LEN; i++) { if (curr.empty() || contains(curr, g.start) || contains(curr, g.startDs)) { break; } next.clear(); CharReach cr; for (auto v : curr) { assert(!is_special(v, g)); cr |= g[v].char_reach; insert(&next, inv_adjacent_vertices(v, g)); } assert(cr.any()); look[0 - i] |= cr; curr.swap(next); } }