From 93c51642e8f52accbb26db45ed8802be9fd41fc9 Mon Sep 17 00:00:00 2001 From: Ulya Trofimovich Date: Fri, 17 Apr 2015 17:00:23 +0100 Subject: [PATCH] Continued adding "--skeleton" switch. More code cleanup: pre-initialize paths for final states and default state, so that NULL can be used as a terminating condition for path-generating function. Fixed memleaks. --- re2c/skeleton.cc | 100 +++++++++++++++++++++++++++++------------------ re2c/skeleton.h | 9 +++-- 2 files changed, 67 insertions(+), 42 deletions(-) diff --git a/re2c/skeleton.cc b/re2c/skeleton.cc index 7e3c5add..1a99edd3 100644 --- a/re2c/skeleton.cc +++ b/re2c/skeleton.cc @@ -6,12 +6,13 @@ namespace re2c { Skeleton::Skeleton (const DFA & dfa) - : states (new SkeletonState [dfa.nStates + 1]) + : states_count (dfa.nStates + 1) + , states (new SkeletonState [states_count]) { uint i; std::map m; - m[NULL] = &states[dfa.nStates]; // default state + m[NULL] = &states[states_count - 1]; // default state i = 0; for (State * s = dfa.head; s; s = s->next, ++i) { @@ -146,35 +147,38 @@ void update (Prefix & p, SkeletonState * s) } } -void append (Prefix & p1, const Prefix * p2) +void append (Prefix & p1, const Prefix & p2) { - if (p2->rule != ~0u) + if (p2.rule != ~0u) { - p1.length = p1.chars.size () + p2->length; - p1.rule = p2->rule; + p1.length = p1.chars.size () + p2.length; + p1.rule = p2.rule; } - for (uint i = 0; i < p2->chars.size (); ++i) + for (uint i = 0; i < p2.chars.size (); ++i) { - p1.chars.push_back (p2->chars[i]); + p1.chars.push_back (p2.chars[i]); } } -void generate_data (DataFile & o, uint ind, SkeletonState * s, std::vector & xs, std::vector & ys) +void dump_paths (DataFile & o, uint ind, const std::vector & path) { - if (s->is_end ()) + o.file << indent (ind); + for (uint i = 0 ; i < path.size (); ++i) { - s->path = new Prefix (std::vector (), 0, s->rule); - for (uint i = 0; i < xs.size (); ++i) + prtChOrHex (o.file, path[i]); + o.file << ","; + } + o.file << "\n"; +} + +void generate (DataFile & o, uint ind, SkeletonState * s, std::vector & prefixes, std::vector & results) +{ + if (s == NULL) + { + for (uint i = 0; i < prefixes.size (); ++i) { - o.file << indent (ind); - for (uint j = 0 ; j < xs[i].chars.size (); ++j) - { - prtChOrHex (o.file, xs[i].chars[j]); - o.file << ","; - } - o.file << "\n"; - update (xs[i], s); - ys.push_back (Result (xs[i])); + results.push_back (Result (prefixes[i])); + dump_paths (o, ind, prefixes[i].chars); } } else if (s->visited < 2) @@ -183,13 +187,12 @@ void generate_data (DataFile & o, uint ind, SkeletonState * s, std::vectorpath != NULL) { - std::vector zs (xs); + std::vector zs (prefixes); for (uint i = 0; i < zs.size (); ++i) { - append (zs[i], s->path); + append (zs[i], * s->path); } - SkeletonState null; - generate_data (o, ind, &null, zs, ys); + generate (o, ind, NULL, zs, results); } else { @@ -199,13 +202,13 @@ void generate_data (DataFile & o, uint ind, SkeletonState * s, std::vectorsecond.size (); } - const uint xs_size = xs.size (); - for (uint i = 0; xs.size () < out_arrows; ++i) + const uint prefixes_size = prefixes.size (); + for (uint i = 0; prefixes.size () < out_arrows; ++i) { - xs.push_back (xs[i]); + prefixes.push_back (prefixes[i]); } - for (; out_arrows < xs.size (); ++out_arrows) + for (; out_arrows < prefixes.size (); ++out_arrows) { s->go.begin ()->second.push_back (s->go.begin ()->second.back ()); } @@ -216,25 +219,47 @@ void generate_data (DataFile & o, uint ind, SkeletonState * s, std::vector zs; for (uint j = 0; j < i->second.size (); ++j) { - zs.push_back (xs[k++]); + zs.push_back (prefixes[k++]); update (zs[j], s); zs[j].chars.push_back (i->second[j]); } - generate_data (o, ind, i->first, zs, ys); + generate (o, ind, i->first, zs, results); if (s->path == NULL && i->first->path != NULL) { - s->path = new Prefix (std::vector (), 0, s->rule); - s->path->chars.push_back (i->second[0]); - append (* s->path, i->first->path); + s->path = new Prefix (std::vector (1, i->second[0]), 0, s->rule); + append (* s->path, * i->first->path); } } - xs.resize (xs_size, xs[0]); + prefixes.resize (prefixes_size, prefixes[0]); } s->visited--; } } +void Skeleton::generate_data (DataFile & o, uint ind, std::vector & results) +{ + // set paths for final states and default state + // (those with zero outgoing arrows) + for (uint i = 0; i < states_count; ++i) + { + if (states[i].is_end ()) + { + states[i].path = new Prefix (std::vector (), 0, states[i].rule); + } + } + std::vector prefixes; + prefixes.push_back (Prefix (std::vector (), 0, ~0)); + + generate (o, ind, states, prefixes, results); + + // cleanup: delete all paths + for (uint i = 0; i < states_count; ++i) + { + delete states[i].path; + } +} + void Skeleton::emit_data (DataFile & o) { fprintf (stderr, "%lx\n%lx\n", 0xFFFFffffFFFFffff, count ()); @@ -268,11 +293,8 @@ void Skeleton::emit_data (DataFile & o) o.file << indent (ind) << "YYCTYPE data [] =\n"; o.file << indent (ind) << "{\n"; - std::vector xs; std::vector ys; - std::vector x; - xs.push_back (Prefix (x, 0, ~0)); - generate_data (o, ind + 1, states, xs, ys); + generate_data (o, ind + 1, ys); const uint count = ys.size (); diff --git a/re2c/skeleton.h b/re2c/skeleton.h index 5605988a..35accabe 100644 --- a/re2c/skeleton.h +++ b/re2c/skeleton.h @@ -15,7 +15,7 @@ struct Prefix std::vector chars; uint length; uint rule; - Prefix (const std::vector & cs, uint l, uint r) + inline Prefix (const std::vector & cs, uint l, uint r) : chars (cs) , length (l) , rule (r) @@ -27,7 +27,7 @@ struct Result uint processed; uint consumed; uint rule; - explicit Result (const Prefix & p) + inline explicit Result (const Prefix & p) : processed (p.chars.size ()) , consumed (p.length) , rule (p.rule) @@ -55,19 +55,22 @@ struct SkeletonState struct Skeleton { + const uint states_count; SkeletonState * states; Skeleton (const DFA & dfa); ~Skeleton (); unsigned long count (); + void generate_data (DataFile & o, uint ind, std::vector & results); void emit_data (DataFile & o); }; unsigned long count_data (SkeletonState * s, unsigned long count); -void generate_data (DataFile & o, uint ind, SkeletonState * s, std::vector & xs, std::vector & ys); void skeleton_emit_prolog (OutputFile & o, uint ind, const char * data_name); void skeleton_emit_epilog (OutputFile & o, uint ind); void update (Prefix & p, SkeletonState * s); void append (Prefix & p1, const Prefix * p2); +void dump_paths (DataFile & o, uint ind, const std::vector & path); +void generate (DataFile & o, uint ind, SkeletonState * s, std::vector & prefixes, std::vector & results); } // namespace re2c -- 2.40.0