remove util functions from ng_rose.

This commit is contained in:
Alex Coyte 2017-01-05 10:50:59 +11:00 committed by Matthew Barr
parent 8741759c3a
commit a43116c6d4
5 changed files with 125 additions and 94 deletions

View File

@ -807,86 +807,7 @@ bool can_match(const NGHolder &g, const ue2_literal &lit, bool overhang_ok) {
return !curr.empty(); return !curr.empty();
} }
u32 removeTrailingLiteralStates(NGHolder &g, const ue2_literal &lit, static
u32 max_delay, bool overhang_ok) {
assert(isCorrectlyTopped(g));
if (max_delay == MO_INVALID_IDX) {
max_delay--;
}
DEBUG_PRINTF("killing off '%s'\n", dumpString(lit).c_str());
set<NFAVertex> curr, next;
curr.insert(g.accept);
auto it = lit.rbegin();
for (u32 delay = max_delay; delay > 0 && it != lit.rend(); delay--, ++it) {
next.clear();
for (auto v : curr) {
for (auto u : inv_adjacent_vertices_range(v, g)) {
if (u == g.start) {
if (overhang_ok) {
DEBUG_PRINTF("bail\n");
goto bail; /* things got complicated */
} else {
continue; /* it is not possible for a lhs literal to
* overhang the start */
}
}
const CharReach &cr = g[u].char_reach;
if (!overlaps(*it, cr)) {
DEBUG_PRINTF("skip\n");
continue;
}
if (isSubsetOf(*it, cr)) {
next.insert(u);
} else {
DEBUG_PRINTF("bail\n");
goto bail; /* things got complicated */
}
}
}
curr.swap(next);
}
bail:
if (curr.empty()) {
/* This can happen when we have an edge representing a cross from two
* sides of an alternation. This whole edge needs to be marked as
* dead */
assert(0); /* should have been picked up by can match */
return MO_INVALID_IDX;
}
u32 delay = distance(lit.rbegin(), it);
assert(delay <= max_delay);
assert(delay <= lit.length());
DEBUG_PRINTF("managed delay %u (of max %u)\n", delay, max_delay);
set<NFAVertex> pred;
for (auto v : curr) {
insert(&pred, inv_adjacent_vertices_range(v, g));
}
clear_in_edges(g.accept, g);
clearReports(g);
for (auto v : pred) {
NFAEdge e = add_edge(v, g.accept, g);
g[v].reports.insert(0);
if (is_triggered(g) && v == g.start) {
g[e].tops.insert(DEFAULT_TOP);
}
}
pruneUseless(g);
assert(allMatchStatesHaveReports(g));
assert(isCorrectlyTopped(g));
DEBUG_PRINTF("graph has %zu vertices left\n", num_vertices(g));
return delay;
}
void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit, void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
u32 delay, const vector<NFAVertex> &preds) { u32 delay, const vector<NFAVertex> &preds) {
assert(delay <= lit.length()); assert(delay <= lit.length());
@ -922,6 +843,7 @@ void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
assert(isCorrectlyTopped(g)); assert(isCorrectlyTopped(g));
} }
static
void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit, void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
u32 delay) { u32 delay) {
vector<NFAVertex> preds; vector<NFAVertex> preds;

View File

@ -63,18 +63,6 @@ bool finalChanceRose(RoseBuild &rose, const NGHolder &h, bool prefilter,
bool checkRose(const ReportManager &rm, const NGHolder &h, bool prefilter, bool checkRose(const ReportManager &rm, const NGHolder &h, bool prefilter,
const CompileContext &cc); const CompileContext &cc);
/** \brief Returns the delay or MO_INVALID_IDX if the graph cannot match with
* the trailing literal. */
u32 removeTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
u32 max_delay, bool overhang_ok = true);
void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
u32 delay);
void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
u32 delay,
const std::vector<NFAVertex> &preds);
} // namespace ue2 } // namespace ue2
#endif // NG_ROSE_H #endif // NG_ROSE_H

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2016, Intel Corporation * Copyright (c) 2015-2017, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -34,6 +34,7 @@
#include "grey.h" #include "grey.h"
#include "ng_depth.h" // for NFAVertexDepth #include "ng_depth.h" // for NFAVertexDepth
#include "ng_dump.h" #include "ng_dump.h"
#include "ng_prune.h"
#include "ue2common.h" #include "ue2common.h"
#include "nfa/limex_limits.h" // for NFA_MAX_TOP_MASKS. #include "nfa/limex_limits.h" // for NFA_MAX_TOP_MASKS.
#include "parser/position.h" #include "parser/position.h"
@ -43,6 +44,7 @@
#include "util/ue2string.h" #include "util/ue2string.h"
#include "util/report_manager.h" #include "util/report_manager.h"
#include <limits>
#include <map> #include <map>
#include <set> #include <set>
#include <boost/graph/filtered_graph.hpp> #include <boost/graph/filtered_graph.hpp>
@ -672,6 +674,86 @@ void reverseHolder(const NGHolder &g_in, NGHolder &g) {
assert(num_edges(g) == num_edges(g_in)); assert(num_edges(g) == num_edges(g_in));
} }
u32 removeTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
u32 max_delay, bool overhang_ok) {
assert(isCorrectlyTopped(g));
if (max_delay == numeric_limits<u32>::max()) {
max_delay--;
}
DEBUG_PRINTF("killing off '%s'\n", dumpString(lit).c_str());
set<NFAVertex> curr, next;
curr.insert(g.accept);
auto it = lit.rbegin();
for (u32 delay = max_delay; delay > 0 && it != lit.rend(); delay--, ++it) {
next.clear();
for (auto v : curr) {
for (auto u : inv_adjacent_vertices_range(v, g)) {
if (u == g.start) {
if (overhang_ok) {
DEBUG_PRINTF("bail\n");
goto bail; /* things got complicated */
} else {
continue; /* it is not possible for a lhs literal to
* overhang the start */
}
}
const CharReach &cr = g[u].char_reach;
if (!overlaps(*it, cr)) {
DEBUG_PRINTF("skip\n");
continue;
}
if (isSubsetOf(*it, cr)) {
next.insert(u);
} else {
DEBUG_PRINTF("bail\n");
goto bail; /* things got complicated */
}
}
}
curr.swap(next);
}
bail:
if (curr.empty()) {
/* This can happen when we have an edge representing a cross from two
* sides of an alternation. This whole edge needs to be marked as
* dead */
assert(0); /* should have been picked up by can match */
return numeric_limits<u32>::max();
}
u32 delay = distance(lit.rbegin(), it);
assert(delay <= max_delay);
assert(delay <= lit.length());
DEBUG_PRINTF("managed delay %u (of max %u)\n", delay, max_delay);
set<NFAVertex> pred;
for (auto v : curr) {
insert(&pred, inv_adjacent_vertices_range(v, g));
}
clear_in_edges(g.accept, g);
clearReports(g);
for (auto v : pred) {
NFAEdge e = add_edge(v, g.accept, g);
g[v].reports.insert(0);
if (is_triggered(g) && v == g.start) {
g[e].tops.insert(DEFAULT_TOP);
}
}
pruneUseless(g);
assert(allMatchStatesHaveReports(g));
assert(isCorrectlyTopped(g));
DEBUG_PRINTF("graph has %zu vertices left\n", num_vertices(g));
return delay;
}
#ifndef NDEBUG #ifndef NDEBUG
bool allMatchStatesHaveReports(const NGHolder &g) { bool allMatchStatesHaveReports(const NGHolder &g) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2016, Intel Corporation * Copyright (c) 2015-2017, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -275,6 +275,11 @@ void duplicateReport(NGHolder &g, ReportID r_old, ReportID r_new);
* accepts. */ * accepts. */
void reverseHolder(const NGHolder &g, NGHolder &out); void reverseHolder(const NGHolder &g, NGHolder &out);
/** \brief Returns the delay or ~0U if the graph cannot match with
* the trailing literal. */
u32 removeTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
u32 max_delay, bool overhang_ok = true);
#ifndef NDEBUG #ifndef NDEBUG
// Assertions: only available in internal builds. // Assertions: only available in internal builds.

View File

@ -1821,6 +1821,40 @@ bool makeTransientFromLongLiteral(NGHolder &h, RoseInGraph &vg,
return true; return true;
} }
static
void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
u32 delay, const vector<NFAVertex> &preds) {
assert(delay <= lit.length());
assert(isCorrectlyTopped(g));
DEBUG_PRINTF("adding on '%s' %u\n", dumpString(lit).c_str(), delay);
NFAVertex prev = g.accept;
auto it = lit.rbegin();
while (delay--) {
NFAVertex curr = add_vertex(g);
assert(it != lit.rend());
g[curr].char_reach = *it;
add_edge(curr, prev, g);
++it;
prev = curr;
}
for (auto v : preds) {
NFAEdge e = add_edge(v, prev, g);
if (v == g.start && is_triggered(g)) {
g[e].tops.insert(DEFAULT_TOP);
}
}
// Every predecessor of accept must have a report.
set_report(g, 0);
renumber_vertices(g);
renumber_edges(g);
assert(allMatchStatesHaveReports(g));
assert(isCorrectlyTopped(g));
}
static static
void restoreTrailingLiteralStates(NGHolder &g, void restoreTrailingLiteralStates(NGHolder &g,
const vector<pair<ue2_literal, u32>> &lits) { const vector<pair<ue2_literal, u32>> &lits) {