diff --git a/src/nfagraph/ng_literal_decorated.cpp b/src/nfagraph/ng_literal_decorated.cpp index 89c01a6c..3ba810f9 100644 --- a/src/nfagraph/ng_literal_decorated.cpp +++ b/src/nfagraph/ng_literal_decorated.cpp @@ -210,6 +210,11 @@ bool handleDecoratedLiterals(RoseBuild &rose, const NGHolder &g, return false; } + if (!hasNarrowReachVertex(g)) { + DEBUG_PRINTF("no narrow reach vertices\n"); + return false; + } + if (hasLargeDegreeVertex(g)) { DEBUG_PRINTF("large degree\n"); return false; diff --git a/src/nfagraph/ng_util.cpp b/src/nfagraph/ng_util.cpp index 0776fa04..c0ad6199 100644 --- a/src/nfagraph/ng_util.cpp +++ b/src/nfagraph/ng_util.cpp @@ -257,6 +257,12 @@ bool hasBigCycles(const NGHolder &g) { return false; } +bool hasNarrowReachVertex(const NGHolder &g, size_t max_reach_count) { + return any_of_in(vertices_range(g), [&](NFAVertex v) { + return !is_special(v, g) && g[v].char_reach.count() < max_reach_count; + }); +} + bool can_never_match(const NGHolder &g) { assert(edge(g.accept, g.acceptEod, g).second); if (in_degree(g.accept, g) == 0 && in_degree(g.acceptEod, g) == 1) { diff --git a/src/nfagraph/ng_util.h b/src/nfagraph/ng_util.h index 1d3a6f32..4c529a83 100644 --- a/src/nfagraph/ng_util.h +++ b/src/nfagraph/ng_util.h @@ -233,6 +233,12 @@ bool hasReachableCycle(const NGHolder &g, NFAVertex src); /** True if g has any cycles which are not self-loops. */ bool hasBigCycles(const NGHolder &g); +/** + * \brief True if g has at least one non-special vertex with reach smaller than + * max_reach_count. The default of 200 is pretty conservative. + */ +bool hasNarrowReachVertex(const NGHolder &g, size_t max_reach_count = 200); + /** Returns the set of all vertices that appear in any of the graph's cycles. */ std::set findVerticesInCycles(const NGHolder &g); diff --git a/src/nfagraph/ng_violet.cpp b/src/nfagraph/ng_violet.cpp index c9460b93..2e1171ab 100644 --- a/src/nfagraph/ng_violet.cpp +++ b/src/nfagraph/ng_violet.cpp @@ -2954,9 +2954,7 @@ RoseInGraph doInitialVioletTransform(const NGHolder &h, bool last_chance, /* Avoid running the Violet analysis at all on graphs with no vertices with * small reach, since we will not be able to extract any literals. */ - if (all_of_in(vertices_range(h), [&](NFAVertex v) { - return is_special(v, h) || h[v].char_reach.count() >= 200; - })) { + if (!hasNarrowReachVertex(h)) { DEBUG_PRINTF("fail, no vertices with small reach\n"); return vg; }