From: Ulya Trofimovich Date: Wed, 18 Mar 2015 10:55:43 +0000 (+0000) Subject: Separated 'Go' stuff: construction and output. X-Git-Tag: 0.15~339 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=79d56ad7113c61f08b3ef3c8c8ea0c670bbb5d32;p=re2c Separated 'Go' stuff: construction and output. --- diff --git a/re2c/Makefile.am b/re2c/Makefile.am index a72132d3..085a3263 100755 --- a/re2c/Makefile.am +++ b/re2c/Makefile.am @@ -2,7 +2,7 @@ bin_PROGRAMS = re2c win_BINARIES = $(WINBUILDDIR)/re2c.exe -re2c_SOURCES = code.cc dfa.cc go.cc main.cc parser.cc actions.cc scanner.re substr.cc range.cc \ +re2c_SOURCES = code.cc dfa.cc go_construct.cc go_emit.cc main.cc parser.cc actions.cc scanner.re substr.cc range.cc \ translate.cc scanner.cc mbo_getopt.cc print.cc input.cc input_api.cc output.cc \ enc.cc utf8.cc utf8_range.cc utf8_regexp.cc utf16.cc utf16_range.cc utf16_regexp.cc range_suffix.cc \ basics.h code.h code_names.h dfa.h go.h enc.h indent.h input.h input_api.h free_list.h globals.h ins.h \ diff --git a/re2c/go.h b/re2c/go.h index f84e01d0..b9e183e6 100644 --- a/re2c/go.h +++ b/re2c/go.h @@ -154,6 +154,11 @@ struct Go bool matches(const Span * b1, uint n1, const State * s1, const Span * b2, uint n2, const State * s2); uint unmap (Span * new_span, const Span * old_span, uint old_nspans, const State * x); +std::string space (uint this_label); +std::string output_yych (bool & readCh); +void output_if (OutputFile & o, uint ind, bool & readCh, const std::string & compare, uint value); +void output_goto (OutputFile & o, uint ind, bool & readCh, uint to); +std::string output_hgo (OutputFile & o, uint ind, bool & readCh, SwitchIf * hgo); } // namespace re2c diff --git a/re2c/go.cc b/re2c/go_construct.cc similarity index 53% rename from re2c/go.cc rename to re2c/go_construct.cc index 06fa4dca..99ec7776 100644 --- a/re2c/go.cc +++ b/re2c/go_construct.cc @@ -1,100 +1,9 @@ #include "dfa.h" #include "go.h" -#include "indent.h" -#include "print.h" namespace re2c { -static std::string space(uint this_label) -{ - int nl = next_label > 999999 ? 6 : next_label > 99999 ? 5 : next_label > 9999 ? 4 : next_label > 999 ? 3 : next_label > 99 ? 2 : next_label > 9 ? 1 : 0; - int tl = this_label > 999999 ? 6 : this_label > 99999 ? 5 : this_label > 9999 ? 4 : this_label > 999 ? 3 : this_label > 99 ? 2 : this_label > 9 ? 1 : 0; - return std::string(std::max(1, nl - tl + 1), ' '); -} - -static std::string output_yych (bool & readCh) -{ - if (readCh) - { - readCh = false; - return "(" + input_api.expr_peek_save () + ")"; - } - else - { - return mapCodeName["yych"]; - } -} - -static void output_if (OutputFile & o, uint ind, bool & readCh, const std::string & compare, uint value) -{ - o << indent(ind) << "if (" << output_yych (readCh) << " " << compare << " "; - o.write_char_hex (value); - o << ") "; -} - -static void output_goto (OutputFile & o, uint ind, bool & readCh, uint to) -{ - if (readCh) - { - o << input_api.stmt_peek (ind); - readCh = false; - } - o << indent (ind) << "goto " << labelPrefix << to << ";\n"; - vUsedLabels.insert(to); -} - -static std::string output_hgo (OutputFile & o, uint ind, bool & readCh, SwitchIf * hgo) -{ - std::string yych = output_yych (readCh); - if (hgo != NULL) - { - o << indent (ind) << "if (" << yych <<" & ~0xFF) {\n"; - hgo->emit (o, ind + 1, readCh); - o << indent (ind) << "} else "; - yych = mapCodeName["yych"]; - } - else - { - o << indent (ind); - } - return yych; -} - -uint Span::show (std::ostream & o, uint lb) const -{ - if (to) - { - printSpan(o, lb, ub); - o << " " << to->label << "; "; - } - return ub; -} - -void Case::emit (OutputFile & o, uint ind) -{ - for (uint i = 0; i < ranges.size (); ++i) - { - for (uint b = ranges[i].first; b < ranges[i].second; ++b) - { - o << indent (ind) << "case "; - o.write_char_hex (b); - o << ":"; - if (dFlag && encoding.is (Enc::EBCDIC)) - { - const uint c = encoding.decodeUnsafe (b); - if (isprint (c)) - o << " /* " << std::string (1, c) << " */"; - } - bool last_case = i == ranges.size () - 1 && b == ranges[i].second - 1; - if (!last_case) - { - o << "\n"; - } - } - } -} - Cases::Cases (const Span * span, uint span_size) : def (span_size == 0 ? NULL : span[span_size - 1].to) , cases (new Case[span_size]) @@ -127,22 +36,6 @@ void Cases::add (uint lb, uint ub, State * to) ++cases_size; } -void Cases::emit (OutputFile & o, uint ind, bool & readCh) -{ - o << indent(ind) << "switch (" << output_yych (readCh) << ") {\n"; - for (uint i = 0; i < cases_size; ++i) - { - if (cases[i].to != def) - { - cases[i].emit (o, ind); - output_goto (o, 1, readCh, cases[i].to->label); - } - } - o << indent (ind) << "default:"; - output_goto (o, 1, readCh, def->label); - o << indent (ind) << "}\n"; -} - Cond::Cond (const std::string & cmp, uint val) : compare (cmp) , value (val) @@ -154,16 +47,6 @@ Binary::Binary (const Span * s, uint n, const State * next) , els (new If (n - n / 2 > 4 ? If::BINARY : If::LINEAR, &s[n / 2], n - n / 2, next)) {} -void Binary::emit (OutputFile & o, uint ind, bool & readCh) -{ - output_if (o, ind, readCh, cond->compare, cond->value); - o << "{\n"; - thn->emit (o, ind + 1, readCh); - o << indent (ind) << "} else {\n"; - els->emit (o, ind + 1, readCh); - o << indent (ind) << "}\n"; -} - Linear::Linear (const Span * s, uint n, const State * next) : branches () { @@ -206,22 +89,6 @@ Linear::Linear (const Span * s, uint n, const State * next) } } -void Linear::emit (OutputFile & o, uint ind, bool & readCh) -{ - for (uint i = 0; i < branches.size (); ++i) - { - if (branches[i].first != NULL) - { - output_if (o, ind, readCh, branches[i].first->compare, branches[i].first->value); - output_goto (o, 0, readCh, branches[i].second->label); - } - else - { - output_goto (o, ind, readCh, branches[i].second->label); - } - } -} - If::If (type_t t, const Span * sp, uint nsp, const State * next) : type (t) , info () @@ -237,19 +104,6 @@ If::If (type_t t, const Span * sp, uint nsp, const State * next) } } -void If::emit (OutputFile & o, uint ind, bool & readCh) -{ - switch (type) - { - case BINARY: - info.binary->emit (o, ind, readCh); - break; - case LINEAR: - info.linear->emit (o, ind, readCh); - break; - } -} - SwitchIf::SwitchIf (const Span * sp, uint nsp, const State * next) : type (IF) , info () @@ -269,19 +123,6 @@ SwitchIf::SwitchIf (const Span * sp, uint nsp, const State * next) } } -void SwitchIf::emit (OutputFile & o, uint ind, bool & readCh) -{ - switch (type) - { - case SWITCH: - info.cases->emit (o, ind, readCh); - break; - case IF: - info.ifs->emit (o, ind, readCh); - break; - } -} - Bitmap::Bitmap (const Span * span, uint nSpans, const Span * hspan, uint hSpans, const BitMap * bm, const State * bm_state, const State * next) : bitmap (bm) , bitmap_state (bm_state) @@ -296,27 +137,6 @@ Bitmap::Bitmap (const Span * span, uint nSpans, const Span * hspan, uint hSpans, delete bspan; } -void Bitmap::emit (OutputFile & o, uint ind, bool & readCh) -{ - std::string yych = output_hgo (o, ind, readCh, hgo); - o << "if (" << mapCodeName["yybm"] << "[" << bitmap->i << "+" << yych << "] & "; - if (yybmHexTable) - { - o.write_hex (bitmap->m); - } - else - { - o << (uint) bitmap->m; - } - o << ") {\n"; - output_goto (o, ind + 1, readCh, bitmap_state->label); - o << indent (ind) << "}\n"; - if (lgo != NULL) - { - lgo->emit (o, ind, readCh); - } -} - CpgotoTable::CpgotoTable (const Span * span, uint nSpans) : table (new uint [0x100]) { @@ -331,69 +151,16 @@ CpgotoTable::CpgotoTable (const Span * span, uint nSpans) } } -void CpgotoTable::emit (OutputFile & o, uint ind) -{ - o << indent (ind) << "static void *" << mapCodeName["yytarget"] << "[256] = {\n"; - o << indent (++ind); - for (uint i = 0; i <= 0xFF; ++i) - { - o << "&&" << labelPrefix << table[i]; - if (i == 0xFF) - { - o << "\n"; - } - else if (i % 8 == 7) - { - o << ",\n" << indent (ind); - } - else - { - o << "," << space (table[i]); - } - } - o << indent (--ind) << "};\n"; -} - Cpgoto::Cpgoto (const Span * span, uint nSpans, const Span * hspan, uint hSpans, const State * next) : hgo (hSpans == 0 ? NULL : new SwitchIf (hspan, hSpans, next)) , table (new CpgotoTable (span, nSpans)) {} -void Cpgoto::emit (OutputFile & o, uint ind, bool & readCh) -{ - std::string yych = output_hgo (o, ind, readCh, hgo); - o << "{\n"; - table->emit (o, ++ind); - o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << yych << "];\n"; - o << indent(--ind) << "}\n"; -} - Dot::Dot (const Span * sp, uint nsp, const State * s) : from (s) , cases (new Cases (sp, nsp)) {} -void Dot::emit (OutputFile & o) -{ - const uint n = cases->cases_size; - if (n == 1) - { - o << from->label << " -> " << cases->cases[0].to->label << "\n"; - } - else - { - for (uint i = 0; i < n; ++i) - { - o << from->label << " -> " << cases->cases[i].to->label << " [label=\""; - for (uint j = 0; j < cases->cases[i].ranges.size (); ++j) - { - o.write_range (cases->cases[i].ranges[j].first, cases->cases[i].ranges[j].second); - } - o << "\"]\n"; - } - } -} - Go::Go () : nSpans (0) , span (NULL) @@ -466,27 +233,6 @@ void Go::init (const State * from) } } -void Go::emit (OutputFile & o, uint ind, bool & readCh) -{ - switch (type) - { - case NONE: - break; - case SWITCH_IF: - info.switchif->emit (o, ind, readCh); - break; - case BITMAP: - info.bitmap->emit (o, ind, readCh); - break; - case CPGOTO: - info.cpgoto->emit (o, ind, readCh); - break; - case DOT: - info.dot->emit (o); - break; - } -} - // All spans in b1 that lead to s1 are pairwise equal to that in b2 leading to s2 bool matches(const Span * b1, uint n1, const State * s1, const Span * b2, uint n2, const State * s2) { diff --git a/re2c/go_emit.cc b/re2c/go_emit.cc new file mode 100644 index 00000000..2dc26032 --- /dev/null +++ b/re2c/go_emit.cc @@ -0,0 +1,261 @@ +#include "dfa.h" +#include "go.h" +#include "indent.h" +#include "print.h" + +namespace re2c +{ + +std::string space(uint this_label) +{ + int nl = next_label > 999999 ? 6 : next_label > 99999 ? 5 : next_label > 9999 ? 4 : next_label > 999 ? 3 : next_label > 99 ? 2 : next_label > 9 ? 1 : 0; + int tl = this_label > 999999 ? 6 : this_label > 99999 ? 5 : this_label > 9999 ? 4 : this_label > 999 ? 3 : this_label > 99 ? 2 : this_label > 9 ? 1 : 0; + return std::string(std::max(1, nl - tl + 1), ' '); +} + +std::string output_yych (bool & readCh) +{ + if (readCh) + { + readCh = false; + return "(" + input_api.expr_peek_save () + ")"; + } + else + { + return mapCodeName["yych"]; + } +} + +void output_if (OutputFile & o, uint ind, bool & readCh, const std::string & compare, uint value) +{ + o << indent(ind) << "if (" << output_yych (readCh) << " " << compare << " "; + o.write_char_hex (value); + o << ") "; +} + +void output_goto (OutputFile & o, uint ind, bool & readCh, uint to) +{ + if (readCh) + { + o << input_api.stmt_peek (ind); + readCh = false; + } + o << indent (ind) << "goto " << labelPrefix << to << ";\n"; + vUsedLabels.insert(to); +} + +std::string output_hgo (OutputFile & o, uint ind, bool & readCh, SwitchIf * hgo) +{ + std::string yych = output_yych (readCh); + if (hgo != NULL) + { + o << indent (ind) << "if (" << yych <<" & ~0xFF) {\n"; + hgo->emit (o, ind + 1, readCh); + o << indent (ind) << "} else "; + yych = mapCodeName["yych"]; + } + else + { + o << indent (ind); + } + return yych; +} + +uint Span::show (std::ostream & o, uint lb) const +{ + if (to) + { + printSpan(o, lb, ub); + o << " " << to->label << "; "; + } + return ub; +} + +void Case::emit (OutputFile & o, uint ind) +{ + for (uint i = 0; i < ranges.size (); ++i) + { + for (uint b = ranges[i].first; b < ranges[i].second; ++b) + { + o << indent (ind) << "case "; + o.write_char_hex (b); + o << ":"; + if (dFlag && encoding.is (Enc::EBCDIC)) + { + const uint c = encoding.decodeUnsafe (b); + if (isprint (c)) + o << " /* " << std::string (1, c) << " */"; + } + bool last_case = i == ranges.size () - 1 && b == ranges[i].second - 1; + if (!last_case) + { + o << "\n"; + } + } + } +} + +void Cases::emit (OutputFile & o, uint ind, bool & readCh) +{ + o << indent(ind) << "switch (" << output_yych (readCh) << ") {\n"; + for (uint i = 0; i < cases_size; ++i) + { + if (cases[i].to != def) + { + cases[i].emit (o, ind); + output_goto (o, 1, readCh, cases[i].to->label); + } + } + o << indent (ind) << "default:"; + output_goto (o, 1, readCh, def->label); + o << indent (ind) << "}\n"; +} + +void Binary::emit (OutputFile & o, uint ind, bool & readCh) +{ + output_if (o, ind, readCh, cond->compare, cond->value); + o << "{\n"; + thn->emit (o, ind + 1, readCh); + o << indent (ind) << "} else {\n"; + els->emit (o, ind + 1, readCh); + o << indent (ind) << "}\n"; +} + +void Linear::emit (OutputFile & o, uint ind, bool & readCh) +{ + for (uint i = 0; i < branches.size (); ++i) + { + if (branches[i].first != NULL) + { + output_if (o, ind, readCh, branches[i].first->compare, branches[i].first->value); + output_goto (o, 0, readCh, branches[i].second->label); + } + else + { + output_goto (o, ind, readCh, branches[i].second->label); + } + } +} + +void If::emit (OutputFile & o, uint ind, bool & readCh) +{ + switch (type) + { + case BINARY: + info.binary->emit (o, ind, readCh); + break; + case LINEAR: + info.linear->emit (o, ind, readCh); + break; + } +} + +void SwitchIf::emit (OutputFile & o, uint ind, bool & readCh) +{ + switch (type) + { + case SWITCH: + info.cases->emit (o, ind, readCh); + break; + case IF: + info.ifs->emit (o, ind, readCh); + break; + } +} + +void Bitmap::emit (OutputFile & o, uint ind, bool & readCh) +{ + std::string yych = output_hgo (o, ind, readCh, hgo); + o << "if (" << mapCodeName["yybm"] << "[" << bitmap->i << "+" << yych << "] & "; + if (yybmHexTable) + { + o.write_hex (bitmap->m); + } + else + { + o << (uint) bitmap->m; + } + o << ") {\n"; + output_goto (o, ind + 1, readCh, bitmap_state->label); + o << indent (ind) << "}\n"; + if (lgo != NULL) + { + lgo->emit (o, ind, readCh); + } +} + +void CpgotoTable::emit (OutputFile & o, uint ind) +{ + o << indent (ind) << "static void *" << mapCodeName["yytarget"] << "[256] = {\n"; + o << indent (++ind); + for (uint i = 0; i <= 0xFF; ++i) + { + o << "&&" << labelPrefix << table[i]; + if (i == 0xFF) + { + o << "\n"; + } + else if (i % 8 == 7) + { + o << ",\n" << indent (ind); + } + else + { + o << "," << space (table[i]); + } + } + o << indent (--ind) << "};\n"; +} + +void Cpgoto::emit (OutputFile & o, uint ind, bool & readCh) +{ + std::string yych = output_hgo (o, ind, readCh, hgo); + o << "{\n"; + table->emit (o, ++ind); + o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << yych << "];\n"; + o << indent(--ind) << "}\n"; +} + +void Dot::emit (OutputFile & o) +{ + const uint n = cases->cases_size; + if (n == 1) + { + o << from->label << " -> " << cases->cases[0].to->label << "\n"; + } + else + { + for (uint i = 0; i < n; ++i) + { + o << from->label << " -> " << cases->cases[i].to->label << " [label=\""; + for (uint j = 0; j < cases->cases[i].ranges.size (); ++j) + { + o.write_range (cases->cases[i].ranges[j].first, cases->cases[i].ranges[j].second); + } + o << "\"]\n"; + } + } +} + +void Go::emit (OutputFile & o, uint ind, bool & readCh) +{ + switch (type) + { + case NONE: + break; + case SWITCH_IF: + info.switchif->emit (o, ind, readCh); + break; + case BITMAP: + info.bitmap->emit (o, ind, readCh); + break; + case CPGOTO: + info.cpgoto->emit (o, ind, readCh); + break; + case DOT: + info.dot->emit (o); + break; + } +} + +} // namespace re2c