flat_set<dstate_id_t> hinted;
if (trust_daddy_states) {
hinted.insert(currState.daddy);
+ addIfEarlier(hinted, info.raw.start_floating, curr_id);
+ addIfEarlier(hinted, info.raw.start_anchored, curr_id);
} else {
hinted = find_daddy_candidates(info, curr_id);
}
if (self_loop_width > MAX_SHERMAN_SELF_LOOP) {
DEBUG_PRINTF("%hu is banned wide self loop (%u)\n", curr_id,
- self_loop_width);
+ self_loop_width);
return;
}
* edges and reports.
*/
static
-void buildAutomaton(LitTrie &trie) {
+void buildAutomaton(LitTrie &trie,
+ map<LitTrieVertex, LitTrieVertex> &failure_map) {
assert(isSaneTrie(trie));
// Find our failure transitions and reports.
- map<LitTrieVertex, LitTrieVertex> failure_map;
vector<LitTrieVertex> ordering;
ACVisitor ac_vis(trie, failure_map, ordering);
boost::breadth_first_search(trie, trie.root, visitor(ac_vis));
unique_ptr<raw_dfa> buildDfa(LitTrie &trie, bool nocase) {
DEBUG_PRINTF("trie has %zu states\n", num_vertices(trie));
- buildAutomaton(trie);
+ map<LitTrieVertex, LitTrieVertex> failure_map;
+ buildAutomaton(trie, failure_map);
auto rdfa = make_unique<raw_dfa>(NFA_OUTFIX);
DEBUG_PRINTF("state %zu\n", u_state);
assert(u_state < rdfa->states.size());
auto &ds = rdfa->states[u_state];
- ds.daddy = root_state;
ds.reports = trie[u].reports;
-
if (!ds.reports.empty()) {
DEBUG_PRINTF("reports: %s\n", as_string_list(ds.reports).c_str());
}
+ // Set daddy state from failure map.
+ if (u == trie.root) {
+ ds.daddy = DEAD_STATE;
+ } else {
+ assert(contains(failure_map, u));
+ ds.daddy = trie[failure_map.at(u)].index + 1;
+ }
+
// By default, transition back to the root.
fill(ds.next.begin(), ds.next.end(), root_state);
// TOP should be a self-loop.