From: Ulya Trofimovich Date: Wed, 15 Apr 2015 12:40:19 +0000 (+0100) Subject: Continued adding "--skeleton" switch. X-Git-Tag: 0.15~306 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dfcdfd8b7766883287dc7dfb3a3bdf9fd7b9ec46;p=re2c Continued adding "--skeleton" switch. Reduced the amount of generated data (no exponential growth now). Generate enough paths to cover all DFA transition (well, not exactly all: only upper and lower bounds of a range). Respect cycles (loop once). --- diff --git a/re2c/code.cc b/re2c/code.cc index 15c180b5..7cc21c34 100644 --- a/re2c/code.cc +++ b/re2c/code.cc @@ -563,7 +563,9 @@ void Rule::emit(Output & output, uint ind, bool &, const std::string& condName) o << "{ if (cursor == &data[result[i].endpos] && result[i].rule == " << rule->accept << ") "; o << "{ cursor = &data[result[i].startpos]; continue; }"; o << " else "; - o << "{ printf (\"error\\n\"); return 1; } }"; + o << "{ printf (\"error: %lu/%u, %u/%u, '%s'\\n\", cursor - data, result[i].endpos, result[i].rule, " + << rule->accept + << ", &data[result[i].startpos]); return 1; } }"; } else if (rule->code->autogen) { diff --git a/re2c/skeleton.cc b/re2c/skeleton.cc index 5f1840c0..95efc7ca 100644 --- a/re2c/skeleton.cc +++ b/re2c/skeleton.cc @@ -22,13 +22,18 @@ Skeleton::Skeleton (const DFA & dfa) uint lb = 0; for (uint j = 0; j < s->go.nSpans; ++j) { - states[i].go[m[s->go.span[j].to]].push_back (std::make_pair (lb, s->go.span[j].ub - 1)); + states[i].go[m[s->go.span[j].to]].push_back (lb); + if (lb != s->go.span[j].ub - 1) + { + states[i].go[m[s->go.span[j].to]].push_back (s->go.span[j].ub - 1); + } lb = s->go.span[j].ub; } states[i].rule = s->rule ? s->rule->accept : ~0u; - states[i].visited = false; + states[i].visited = 0; + states[i].path = NULL; } } @@ -43,20 +48,15 @@ unsigned long count_data (SkeletonState * s, unsigned long count) { return count; } - else if (!s->visited) + else if (s->visited < 2) { - s->visited = true; + s->visited++; unsigned long result = 0; for (SkeletonState::go_t::iterator i = s->go.begin (); i != s->go.end (); ++i) { - uint c = 0; - for (uint j = 0; j < i->second.size (); ++j) - { - c += 1 + (i->second[j].first != i->second[j].second); - } - result += count_data (i->first, c * count); + result += count_data (i->first, i->second.size () * count); } - s->visited = false; + s->visited--; return result; } else @@ -70,6 +70,7 @@ unsigned long Skeleton::count () return count_data (states, 1); } +/* void generate_data (DataFile & o, uint ind, SkeletonState * s, const std::vector & xs, std::vector & ys) { if (is_final (s) || is_default (s)) @@ -128,10 +129,124 @@ void generate_data (DataFile & o, uint ind, SkeletonState * s, const std::vector s->visited = false; } } +*/ + +void generate_data (DataFile & o, uint ind, SkeletonState * s, std::vector & xs, std::vector & ys) +{ + if (is_final (s) || is_default (s)) + { + for (uint i = 0; i < xs.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"; + const uint processed = xs[i].chars.size (); + const uint consumed = is_final (s) + ? xs[i].chars.size () + : xs[i].length; + const uint rule = is_final (s) + ? s->rule + : xs[i].rule; + ys.push_back (Result (processed, consumed, rule)); + if (is_final (s)) + { + s->path = new Prefix (std::vector (), 0, s->rule); + } + } + } + else if (s->visited < 2) + { + s->visited++; + const bool is_accepting = s->rule != ~0u; + if (s->path != NULL) + { + std::vector zs (xs); + for (uint i = 0; i < zs.size (); ++i) + { + zs[i].length = s->path->rule != ~0u + ? zs[i].chars.size () + s->path->length + : is_accepting + ? zs[i].chars.size () + : zs[i].length; + zs[i].rule = s->path->rule != ~0u + ? s->path->rule + : is_accepting + ? s->rule + : zs[i].rule; + for (int j = s->path->chars.size () - 1; j >= 0; --j) + { + zs[i].chars.push_back (s->path->chars[j]); + } + } + generate_data (o, ind, NULL, zs, ys); + } + else + { + uint out_arrows = 0; + for (SkeletonState::go_t::iterator i = s->go.begin (); i != s->go.end (); ++i) + { + out_arrows += i->second.size (); + } + + const uint xs_size = xs.size (); + for (uint i = 0; xs.size () < out_arrows; ++i) + { + xs.push_back (xs[i]); + } + + for (; out_arrows < xs.size (); ++out_arrows) + { + s->go.begin ()->second.push_back (s->go.begin ()->second.back ()); + } + + uint k = 0; + for (SkeletonState::go_t::iterator i = s->go.begin (); i != s->go.end (); ++i) + { + std::vector zs; + for (uint j = 0; j < i->second.size (); ++j) + { + zs.push_back (xs[k++]); + zs[j].length = is_accepting ? zs[j].chars.size () : zs[j].length; + zs[j].rule = is_accepting ? s->rule : zs[j].rule; + zs[j].chars.push_back (i->second[j]); + } + generate_data (o, ind, i->first, zs, ys); + if (s->path == NULL) + { + if (i->first == NULL) + { + const uint r = is_accepting ? s->rule : ~0u; + s->path = new Prefix (std::vector (), 0, r); + s->path->chars.push_back (i->second[0]); + } + else if (i->first->path != NULL) + { + const uint l = i->first->path->rule != ~0u + ? i->first->path->length + 1 + : 0; + const uint r = i->first->path->rule != ~0u + ? i->first->path->rule + : is_accepting + ? s->rule + : ~0u; + s->path = new Prefix (i->first->path->chars, l, r); + s->path->chars.push_back (i->second[0]); + } + } + } + xs.resize (xs_size, xs[0]); + } + s->visited--; + } +} void Skeleton::emit_data (DataFile & o) { -fprintf (stderr, "%lx\n%lx\n", 0xFFFFffffFFFFffff, count ()); +//fprintf (stderr, "%lx\n%lx\n", 0xFFFFffffFFFFffff, count ()); uint ind = 0; std::string yyctype; diff --git a/re2c/skeleton.h b/re2c/skeleton.h index d0b1256e..a6805122 100644 --- a/re2c/skeleton.h +++ b/re2c/skeleton.h @@ -10,26 +10,6 @@ namespace re2c { -struct SkeletonState -{ - typedef std::map > > go_t; - go_t go; - uint rule; - bool visited; -}; - -inline bool is_default (SkeletonState * s) -{ - return s == NULL; -} - -inline bool is_final (SkeletonState * s) -{ - return s != NULL - && s->go.size () == 1 - && s->go.begin ()->first == NULL; -} - struct Prefix { std::vector chars; @@ -54,6 +34,27 @@ struct Result {} }; +struct SkeletonState +{ + typedef std::map > go_t; + go_t go; + uint rule; + uchar visited; + Prefix * path; +}; + +inline bool is_default (SkeletonState * s) +{ + return s == NULL; +} + +inline bool is_final (SkeletonState * s) +{ + return s != NULL + && s->go.size () == 1 + && s->go.begin ()->first == NULL; +} + struct Skeleton { SkeletonState * states; @@ -64,7 +65,7 @@ struct Skeleton }; unsigned long count_data (SkeletonState * s, unsigned long count); -void generate_data (DataFile & o, uint ind, SkeletonState * s, const std::vector & xs, std::vector & ys); +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);