]> granicus.if.org Git - re2c/commitdiff
Separated 'Go' stuff: construction and output.
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 18 Mar 2015 10:55:43 +0000 (10:55 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 18 Mar 2015 10:55:43 +0000 (10:55 +0000)
re2c/Makefile.am
re2c/go.h
re2c/go_construct.cc [moved from re2c/go.cc with 53% similarity]
re2c/go_emit.cc [new file with mode: 0644]

index a72132d3ebf3f0c696145ac304e66027165ac692..085a32638a8abe5ab9ab84393b24a99e032d6b3f 100755 (executable)
@@ -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 \
index f84e01d0156d4b32dea39dcf5a94bc455c2a7511..b9e183e6c6c7b031aaa1ed5ee921dacd12b9faa1 100644 (file)
--- 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
 
similarity index 53%
rename from re2c/go.cc
rename to re2c/go_construct.cc
index 06fa4dcacd801a88627b404ebf24a96c1b3fcfc6..99ec7776e3722b4ff3e99561738f8079d8e68eca 100644 (file)
@@ -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 (file)
index 0000000..2dc2603
--- /dev/null
@@ -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