]> granicus.if.org Git - re2c/commitdiff
Continued adding "--skeleton" switch.
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 15 Apr 2015 12:40:19 +0000 (13:40 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 15 Apr 2015 12:40:19 +0000 (13:40 +0100)
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).

re2c/code.cc
re2c/skeleton.cc
re2c/skeleton.h

index 15c180b548a71d6f91ab6b7262fb3cfb9e51b2c8..7cc21c3449dfa5481965a2480f7f1c92c28c63d8 100644 (file)
@@ -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)
        {
index 5f1840c0edb2d2adc1f1bb7a9fb692b86a120fea..95efc7ca972500403ae08352581b74f19efddc5a 100644 (file)
@@ -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<Prefix> & xs, std::vector<Result> & 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<Prefix> & xs, std::vector<Result> & 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<uint> (), 0, s->rule);
+                       }
+               }
+       }
+       else if (s->visited < 2)
+       {
+               s->visited++;
+               const bool is_accepting = s->rule != ~0u;
+               if (s->path != NULL)
+               {
+                       std::vector<Prefix> 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<Prefix> 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<uint> (), 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;
index d0b1256eb6a207a8aeac15439d86cda3e64877c8..a68051220e6282414f58d2717340beddce4c5e3c 100644 (file)
 namespace re2c
 {
 
-struct SkeletonState
-{
-       typedef std::map<SkeletonState *, std::vector<std::pair<uint, uint> > > 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<uint> chars;
@@ -54,6 +34,27 @@ struct Result
        {}
 };
 
+struct SkeletonState
+{
+       typedef std::map<SkeletonState *, std::vector<uint> > 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<Prefix> & xs, std::vector<Result> & ys);
+void generate_data (DataFile & o, uint ind, SkeletonState * s, std::vector<Prefix> & xs, std::vector<Result> & ys);
 void skeleton_emit_prolog (OutputFile & o, uint ind, const char * data_name);
 void skeleton_emit_epilog (OutputFile & o, uint ind);