From: Ulya Trofimovich Date: Mon, 6 Apr 2015 17:44:59 +0000 (+0100) Subject: Continued adding "--skeleton" switch. X-Git-Tag: 0.15~314 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c6178c064d1bd8258847cef4ea64b1dfaab21216;p=re2c Continued adding "--skeleton" switch. Output generated strings directly to file instead of storing them in memory. --- diff --git a/re2c/actions.cc b/re2c/actions.cc index 24356cf0..46359003 100644 --- a/re2c/actions.cc +++ b/re2c/actions.cc @@ -1046,7 +1046,7 @@ CharSet::~CharSet() delete[] ptn; } -smart_ptr genCode(RegExp *re) +smart_ptr genCode(RegExp *re, Output & output, uint ind) { CharSet cs; re->split(cs); @@ -1099,7 +1099,14 @@ smart_ptr genCode(RegExp *re) } } - return make_smart_ptr(new DFA(ins, size, 0, encoding.nCodeUnits(), rep)); + smart_ptr 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 diff --git a/re2c/bootstrap/parser.cc b/re2c/bootstrap/parser.cc index d24aa199..79c665ea 100644 --- a/re2c/bootstrap/parser.cc +++ b/re2c/bootstrap/parser.cc @@ -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()) { diff --git a/re2c/code.cc b/re2c/code.cc index 12025c16..f0409e4b 100644 --- a/re2c/code.cc +++ b/re2c/code.cc @@ -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, uint> > & xs, std::vector & 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, uint> > zs; + for (uint j = 0; j < xs.size (); ++j) + { + std::vector 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, uint> > & xs, std::vector, uint> > & ys) -{ - if (s == NULL) - { - for (uint i = 0; i < xs.size (); ++i) - { - ys.push_back (std::make_pair (std::vector (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 (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, uint> > zs; - for (uint j = 0; j < xs.size (); ++j) - { - std::vector 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, uint> > xs; - std::vector, uint> > ys; + std::vector ys; std::vector 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) diff --git a/re2c/dfa.h b/re2c/dfa.h index c5501029..a8a737c6 100644 --- a/re2c/dfa.h +++ b/re2c/dfa.h @@ -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&); diff --git a/re2c/parser.y b/re2c/parser.y index 8bc660f0..bdf8ca4b 100644 --- a/re2c/parser.y +++ b/re2c/parser.y @@ -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()) { diff --git a/re2c/re.h b/re2c/re.h index 9605fb6a..f4219fcd 100644 --- a/re2c/re.h +++ b/re2c/re.h @@ -391,7 +391,7 @@ typedef std::map DefaultMap; class DFA; -extern smart_ptr genCode(RegExp*); +extern smart_ptr 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&);