]> granicus.if.org Git - re2c/commitdiff
Continued adding "--skeleton" switch.
authorUlya Trofimovich <skvadrik@gmail.com>
Mon, 6 Apr 2015 17:44:59 +0000 (18:44 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Mon, 6 Apr 2015 17:44:59 +0000 (18:44 +0100)
Output generated strings directly to file instead of storing them
in memory.

re2c/actions.cc
re2c/bootstrap/parser.cc
re2c/code.cc
re2c/dfa.h
re2c/parser.y
re2c/re.h

index 24356cf0d57983325a4eabebe15354bf412d47bc..46359003ed55a889823ff4570d61b907f655ffc0 100644 (file)
@@ -1046,7 +1046,7 @@ CharSet::~CharSet()
        delete[] ptn;
 }
 
-smart_ptr<DFA> genCode(RegExp *re)
+smart_ptr<DFA> genCode(RegExp *re, Output & output, uint ind)
 {
        CharSet cs;
        re->split(cs);
@@ -1099,7 +1099,14 @@ smart_ptr<DFA> genCode(RegExp *re)
                }
        }
 
-       return make_smart_ptr(new DFA(ins, size, 0, encoding.nCodeUnits(), rep));
+       smart_ptr<DFA> dfa = make_smart_ptr(new DFA(ins, size, 0, encoding.nCodeUnits(), rep));
+       if (flag_skeleton)
+       {
+               dfa->output_skeleton_prolog (output.source, ind);
+       }
+       dfa->prepare (output.max_fill);
+
+       return dfa;
 }
 
 } // end namespace re2c
index d24aa1991f7f16d794ac019dc3c14b5e646c57a1..79c665eaca0ad0952842b7ed0eed4c09142cf3bc 100644 (file)
@@ -2376,14 +2376,7 @@ void parse(Scanner& i, Output & o)
                                                        it->second.second = it->second.second ? mkAlt(def, it->second.second) : def;
                                                }
                                        }
-                                       dfa_map[it->first] = genCode(it->second.second);
-
-                                       if (flag_skeleton)
-                                       {
-                                               dfa_map[it->first]->output_skeleton_prolog (o, topIndent);
-                                       }
-
-                                       dfa_map[it->first]->prepare(o.max_fill);
+                                       dfa_map[it->first] = genCode(it->second.second, o, topIndent);
                                }
                                if (parseMode != Scanner::Rules && dfa_map.find(it->first) != dfa_map.end())
                                {
@@ -2404,14 +2397,7 @@ void parse(Scanner& i, Output & o)
                        {
                                if (parseMode != Scanner::Reuse)
                                {
-                                       dfa_map[""] = genCode(spec);
-
-                                       if (flag_skeleton)
-                                       {
-                                               dfa_map[""]->output_skeleton_prolog (o, topIndent);
-                                       }
-
-                                       dfa_map[""]->prepare(o.max_fill);
+                                       dfa_map[""] = genCode(spec, o, topIndent);
                                }
                                if (parseMode != Scanner::Rules && dfa_map.find("") != dfa_map.end())
                                {
index 12025c161ae62c34e58c1e87e4cd11065abe40a2..f0409e4b4a31bb46d2694c93a4e85962e1036451 100644 (file)
@@ -1046,10 +1046,48 @@ void DFA::prepare(uint & max_fill)
        }
 }
 
-void DFA::output_skeleton_prolog (Output & output, uint ind)
+static void generate_data (OutputFile & o, uint ind, State * s, const std::vector<std::pair<std::vector<uint>, uint> > & xs, std::vector<uint> & ys)
 {
-       OutputFile & o = output.source;
+       const bool is_default = s == NULL;
+       const bool is_final = !is_default && s->go.nSpans == 1 && s->go.span[0].to == NULL;
+       if (is_final || is_default)
+       {
+               for (uint i = 0; i < xs.size (); ++i)
+               {
+                       o << indent (ind);
+                       for (uint j = 0 ; j < xs[i].first.size (); ++j)
+                       {
+                               o.write_char_hex (xs[i].first[j]);
+                               o << ",";
+                       }
+                       o << "\n";
+                       ys.push_back (xs[i].first.size ());
+                       ys.push_back (is_final ? xs[i].first.size () : xs[i].second);
+               }
+       }
+       else if (!s->generated)
+       {
+               s->generated = true;
+               for (uint i = 0; i < s->go.nSpans; ++i)
+               {
+                       std::vector<std::pair<std::vector<uint>, uint> > zs;
+                       for (uint j = 0; j < xs.size (); ++j)
+                       {
+                               std::vector<uint> z (xs[j].first);
+                               z.push_back (s->go.span[i].ub - 1);
+                               const uint l = s->rule == NULL
+                                       ? xs[j].second
+                                       : xs[j].first.size ();
+                               zs.push_back (std::make_pair (z, l));
+                       }
+                       generate_data (o, ind, s->go.span[i].to, zs, ys);
+               }
+               s->generated = false;
+       }
+}
 
+void DFA::output_skeleton_prolog (OutputFile & o, uint ind)
+{
        std::string yyctype;
        switch (encoding.szCodeUnit ())
        {
@@ -1076,86 +1114,24 @@ void DFA::output_skeleton_prolog (Output & output, uint ind)
        o << "#define " << mapCodeName["YYRESTORECTX"] << "() cursor = ctxmarker\n";
        o << "#define " << mapCodeName["YYLESSTHAN"] << "(n) (limit - cursor) < n\n";
        o << "#define " << mapCodeName["YYFILL"] << "(n) { break; }\n";
-       generate (output, ind);
-       o << indent (ind) << "const YYCTYPE * cursor = data;\n";
-       o << indent (ind) << "const YYCTYPE * marker = data;\n";
-       o << indent (ind) << "const YYCTYPE * ctxmarker = data;\n";
-       o << indent (ind) << "const YYCTYPE * const limit = &data[data_size - 1];\n";
-       o << indent (ind) << "for (;;)\n";
-       o << indent (ind) << "{\n";
-}
 
-void DFA::output_skeleton_epilog (OutputFile & o, uint ind)
-{
-       o << indent (ind) << "}\n";
-
-       o << "return 0; }\n";
-}
-
-static void generate_data (State * s, const std::vector<std::pair<std::vector<uint>, uint> > & xs, std::vector<std::pair<std::vector<uint>, uint> > & ys)
-{
-       if (s == NULL)
-       {
-               for (uint i = 0; i < xs.size (); ++i)
-               {
-                       ys.push_back (std::make_pair (std::vector<uint> (xs[i].first), xs[i].second));
-               }
-       }
-       else if (s->go.nSpans == 1 && s->go.span[0].to == NULL)
-       {
-               for (uint i = 0; i < xs.size (); ++i)
-               {
-                       ys.push_back (std::make_pair (std::vector<uint> (xs[i].first), xs[i].first.size ()));
-               }
-       }
-       else if (!s->generated)
-       {
-               s->generated = true;
-               for (uint i = 0; i < s->go.nSpans; ++i)
-               {
-                       std::vector<std::pair<std::vector<uint>, uint> > zs;
-                       for (uint j = 0; j < xs.size (); ++j)
-                       {
-                               std::vector<uint> z (xs[j].first);
-                               z.push_back (s->go.span[i].ub - 1);
-                               const uint l = s->rule == NULL
-                                       ? xs[j].second
-                                       : xs[j].first.size ();
-                               zs.push_back (std::make_pair (z, l));
-                       }
-                       generate_data (s->go.span[i].to, zs, ys);
-               }
-               s->generated = false;
-       }
-}
-
-void DFA::generate (Output & output, uint ind)
-{
-       OutputFile & o = output.source;
+       o << indent (ind) << "// These strings correspond to paths in DFA.\n";
+       o << indent (ind) << "YYCTYPE data [] =\n";
+       o << indent (ind) << "{\n";
 
        std::vector<std::pair<std::vector<uint>, uint> > xs;
-       std::vector<std::pair<std::vector<uint>, uint> > ys;
+       std::vector<uint> ys;
        std::vector<uint> x;
        xs.push_back (std::make_pair (x, 0));
-       generate_data (head, xs, ys);
+       generate_data (o, ind + 1, head, xs, ys);
 
-       o << indent (ind) << "// These strings correspond to paths in DFA.\n";
-       o << indent (ind) << "YYCTYPE data [] =\n";
-       o << indent (ind) << "{\n";
        uint max_len = 0;
-       for (uint i = 0; i < ys.size (); ++i)
+       for (uint i = 1; i < ys.size (); i += 2)
        {
-               if (max_len < ys[i].second)
-               {
-                       max_len = ys[i].second;
-               }
-               o << indent (ind + 1);
-               for (uint j = 0 ; j < ys[i].first.size (); ++j)
+               if (max_len < ys[i])
                {
-                       o.write_char_hex (ys[i].first[j]);
-                       o << ",";
+                       max_len = ys[i];
                }
-               o << "\n";
        }
        o << indent (ind + 1);
        for (uint j = 0 ; j < max_len; ++j) // pad with YMAXFILL zeroes
@@ -1169,13 +1145,27 @@ void DFA::generate (Output & output, uint ind)
        uint pos = 0;
        o << indent (ind) << "unsigned int positions [] =\n";
        o << indent (ind) << "{\n";
-       for (uint i = 0; i < ys.size (); ++i)
+       for (uint i = 0; i < ys.size (); i += 2)
        {
-               pos += ys[i].first.size ();
-               o << indent (ind + 1) << pos << "," << ys[i].second << ",\n";
+               pos += ys[i];
+               o << indent (ind + 1) << pos << "," << ys[i + 1] << ",\n";
        }
        o << indent (ind) << "};\n";
-       o << indent (ind) << "const unsigned int positions_size = " << ys.size () * 2 << ";\n";
+       o << indent (ind) << "const unsigned int positions_size = " << ys.size () << ";\n";
+
+       o << indent (ind) << "const YYCTYPE * cursor = data;\n";
+       o << indent (ind) << "const YYCTYPE * marker = data;\n";
+       o << indent (ind) << "const YYCTYPE * ctxmarker = data;\n";
+       o << indent (ind) << "const YYCTYPE * const limit = &data[data_size - 1];\n";
+       o << indent (ind) << "for (;;)\n";
+       o << indent (ind) << "{\n";
+}
+
+void DFA::output_skeleton_epilog (OutputFile & o, uint ind)
+{
+       o << indent (ind) << "}\n";
+
+       o << "return 0; }\n";
 }
 
 void DFA::emit(Output & output, uint& ind, const RegExpMap* specMap, const std::string& condName, bool isLastCond, bool& bPrologBrace)
index c55010293454881933b61311d4ea7656681483cc..a8a737c657bdb6251cf708a88c414f8d9781a745 100644 (file)
@@ -226,8 +226,7 @@ public:
        void findSCCs();
        void findBaseState();
        void prepare(uint &);
-       void generate (Output & o, uint ind);
-       void output_skeleton_prolog (Output & o, uint ind);
+       void output_skeleton_prolog (OutputFile & o, uint ind);
        void output_skeleton_epilog (OutputFile & o, uint ind);
        void emit(Output &, uint&, const RegExpMap*, const std::string&, bool, bool&);
 
index 8bc660f07767b8ebcc3280a70fe9640d3902231e..bdf8ca4b004225e49de21a1718bf0c3654ae57b4 100644 (file)
@@ -656,14 +656,7 @@ void parse(Scanner& i, Output & o)
                                                        it->second.second = it->second.second ? mkAlt(def, it->second.second) : def;
                                                }
                                        }
-                                       dfa_map[it->first] = genCode(it->second.second);
-
-                                       if (flag_skeleton)
-                                       {
-                                               dfa_map[it->first]->output_skeleton_prolog (o, topIndent);
-                                       }
-
-                                       dfa_map[it->first]->prepare(o.max_fill);
+                                       dfa_map[it->first] = genCode(it->second.second, o, topIndent);
                                }
                                if (parseMode != Scanner::Rules && dfa_map.find(it->first) != dfa_map.end())
                                {
@@ -684,14 +677,7 @@ void parse(Scanner& i, Output & o)
                        {
                                if (parseMode != Scanner::Reuse)
                                {
-                                       dfa_map[""] = genCode(spec);
-
-                                       if (flag_skeleton)
-                                       {
-                                               dfa_map[""]->output_skeleton_prolog (o, topIndent);
-                                       }
-
-                                       dfa_map[""]->prepare(o.max_fill);
+                                       dfa_map[""] = genCode(spec, o, topIndent);
                                }
                                if (parseMode != Scanner::Rules && dfa_map.find("") != dfa_map.end())
                                {
index 9605fb6aee7a5f5de18001efdf852bc8927b4ce0..f4219fcd7f4a22c8d350ca28429a4ea7ae34dc63 100644 (file)
--- a/re2c/re.h
+++ b/re2c/re.h
@@ -391,7 +391,7 @@ typedef std::map<std::string, Token*>   DefaultMap;
 
 class DFA;
 
-extern smart_ptr<DFA> genCode(RegExp*);
+extern smart_ptr<DFA> genCode(RegExp*, Output & output, uint ind);
 extern void genCondTable(OutputFile &, uint, const RegExpMap&);
 extern void genCondGoto(OutputFile &, uint, const RegExpMap&);
 extern void genTypes(Output &, const RegExpMap&);