]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
allow outfixes to be converted to prefixes of the eod event literal
authorAlex Coyte <a.coyte@intel.com>
Wed, 11 Jan 2017 03:38:18 +0000 (14:38 +1100)
committerMatthew Barr <matthew.barr@intel.com>
Wed, 26 Apr 2017 04:44:03 +0000 (14:44 +1000)
src/rose/rose_build_add.cpp

index da26e126ba4b8659d8b7bea83322e9f7d256f213..b601f943a1b6916c294b68c354038dcfa6a80a08 100644 (file)
@@ -1783,9 +1783,70 @@ void populateOutfixInfo(OutfixInfo &outfix, const NGHolder &h,
     populateReverseAccelerationInfo(outfix.rev_info, h);
 }
 
+static
+bool addEodOutfix(RoseBuildImpl &build, const NGHolder &h) {
+    map<flat_set<ReportID>, ReportID> report_remap;
+    shared_ptr<NGHolder> eod_leftfix
+        = makeRoseEodPrefix(h, build, report_remap);
+
+    bool nfa_ok = isImplementableNFA(h, &build.rm, build.cc);
+
+    /* TODO: check if early dfa is possible */
+
+    if (!nfa_ok) {
+        DEBUG_PRINTF("could not build as  NFA\n");
+        return false;
+    }
+
+    u32 eod_event = getEodEventID(build);
+
+    auto &g = build.g;
+    for (const auto &report_mapping : report_remap) {
+        RoseVertex v = add_vertex(g);
+        g[v].literals.insert(eod_event);
+        build.literal_info[eod_event].vertices.insert(v);
+
+        g[v].left.graph = eod_leftfix;
+        g[v].left.leftfix_report = report_mapping.second;
+        g[v].left.lag = 0;
+        RoseEdge e1 = add_edge(build.anchored_root, v, g);
+        g[e1].minBound = 0;
+        g[e1].maxBound = ROSE_BOUND_INF;
+        g[v].min_offset = findMinWidth(*eod_leftfix);
+        g[v].max_offset = ROSE_BOUND_INF;
+
+        depth max_width = findMaxWidth(*g[v].left.graph);
+        if (max_width.is_finite() && isPureAnchored(*eod_leftfix)) {
+            g[e1].maxBound = max_width;
+            g[v].max_offset = max_width;
+        }
+
+        g[e1].history = ROSE_ROLE_HISTORY_NONE; // handled by prefix
+        RoseVertex w = add_vertex(g);
+        g[w].eod_accept = true;
+        g[w].reports = report_mapping.first;
+        g[w].min_offset = g[v].min_offset;
+        g[w].max_offset = g[v].max_offset;
+        RoseEdge e = add_edge(v, w, g);
+        g[e].minBound = 0;
+        g[e].maxBound = 0;
+        g[e].history = ROSE_ROLE_HISTORY_NONE;
+        DEBUG_PRINTF("accept eod vertex (index=%zu)\n", g[w].index);
+    }
+
+    return true;
+}
+
 bool RoseBuildImpl::addOutfix(const NGHolder &h) {
     DEBUG_PRINTF("%zu vertices, %zu edges\n", num_vertices(h), num_edges(h));
 
+    /* TODO: handle more than one report */
+    if (!in_degree(h.accept, h)
+        && all_reports(h).size() == 1
+        && addEodOutfix(*this, h)) {
+        return true;
+    }
+
     const u32 nfa_states = isImplementableNFA(h, &rm, cc);
     if (nfa_states) {
         DEBUG_PRINTF("implementable as an NFA in %u states\n", nfa_states);