mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
rose: pick up more prefix->lookaround conversions
This commit is contained in:
parent
d3c56b532b
commit
cdaf705a87
@ -1160,7 +1160,11 @@ bool buildLeftfixes(RoseBuildImpl &tbi, build_context &bc,
|
||||
u32 lag = g[v].left.lag;
|
||||
bool is_transient = contains(tbi.transient, leftfix);
|
||||
|
||||
if (is_transient && tbi.cc.grey.roseLookaroundMasks) {
|
||||
// Transient leftfixes can sometimes be implemented solely with
|
||||
// lookarounds, in which case we don't need to build an engine.
|
||||
// TODO: Handle SOM-tracking cases as well.
|
||||
if (cc.grey.roseLookaroundMasks && is_transient &&
|
||||
!g[v].left.tracksSom()) {
|
||||
vector<LookEntry> lookaround;
|
||||
if (makeLeftfixLookaround(tbi, v, lookaround)) {
|
||||
DEBUG_PRINTF("implementing as lookaround!\n");
|
||||
|
@ -538,6 +538,36 @@ void findLookaroundMasks(const RoseBuildImpl &tbi, const RoseVertex v,
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
bool hasSingleFloatingStart(const NGHolder &g) {
|
||||
NFAVertex initial = NGHolder::null_vertex();
|
||||
for (auto v : adjacent_vertices_range(g.startDs, g)) {
|
||||
if (v == g.startDs) {
|
||||
continue;
|
||||
}
|
||||
if (initial != NGHolder::null_vertex()) {
|
||||
DEBUG_PRINTF("more than one start\n");
|
||||
return false;
|
||||
}
|
||||
initial = v;
|
||||
}
|
||||
|
||||
if (initial == NGHolder::null_vertex()) {
|
||||
DEBUG_PRINTF("no floating starts\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Anchored start must have no successors other than startDs and initial.
|
||||
for (auto v : adjacent_vertices_range(g.start, g)) {
|
||||
if (v != initial && v != g.startDs) {
|
||||
DEBUG_PRINTF("anchored start\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool getTransientPrefixReach(const NGHolder &g, u32 lag,
|
||||
map<s32, CharReach> &look) {
|
||||
@ -546,15 +576,9 @@ bool getTransientPrefixReach(const NGHolder &g, u32 lag,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Currently we don't handle anchored prefixes, as we would need to be able
|
||||
// to represent the bounds from the anchor as well.
|
||||
if (out_degree(g.start, g) != 1) {
|
||||
DEBUG_PRINTF("anchored\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (out_degree(g.startDs, g) != 2) {
|
||||
DEBUG_PRINTF("more than one start\n");
|
||||
// Must be a floating chain wired to startDs.
|
||||
if (!hasSingleFloatingStart(g)) {
|
||||
DEBUG_PRINTF("not a single floating start\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -569,12 +593,28 @@ bool getTransientPrefixReach(const NGHolder &g, u32 lag,
|
||||
|
||||
look[0 - i] = g[v].char_reach;
|
||||
|
||||
if (in_degree(v, g) != 1) {
|
||||
NFAVertex next = NGHolder::null_vertex();
|
||||
for (auto u : inv_adjacent_vertices_range(v, g)) {
|
||||
if (u == g.start) {
|
||||
continue; // Benign, checked by hasSingleFloatingStart
|
||||
}
|
||||
if (next == NGHolder::null_vertex()) {
|
||||
next = u;
|
||||
continue;
|
||||
}
|
||||
DEBUG_PRINTF("branch\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
v = *(inv_adjacent_vertices(v, g).first);
|
||||
if (next == NGHolder::null_vertex() || next == v) {
|
||||
DEBUG_PRINTF("no predecessor or only self-loop\n");
|
||||
// This graph is malformed -- all vertices in a graph that makes it
|
||||
// to this analysis should have predecessors.
|
||||
assert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
v = next;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user