]> granicus.if.org Git - re2c/commitdiff
Support '--skeleton' with conditions and multiple re2c blocks.
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 16 Sep 2015 10:25:29 +0000 (11:25 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 16 Sep 2015 10:25:29 +0000 (11:25 +0100)
13 files changed:
re2c/src/codegen/emit.h
re2c/src/codegen/emit_action.cc
re2c/src/codegen/emit_dfa.cc
re2c/src/codegen/output.cc
re2c/src/codegen/output.h
re2c/src/codegen/skeleton/generate_code.cc
re2c/src/codegen/skeleton/generate_data.cc
re2c/src/codegen/skeleton/skeleton.cc
re2c/src/codegen/skeleton/skeleton.h
re2c/src/ir/bytecode/bytecode.cc
re2c/src/ir/dfa/dfa.cc
re2c/src/ir/dfa/dfa.h
re2c/src/parse/parser.ypp

index 772ad62d1a6f012f2ea356f3a5eb95d62a880c8f..854edaab5463a065a57509a1854c8f78bc0700db 100644 (file)
@@ -15,6 +15,7 @@ void emit_action
        , bool & readCh
        , const State * const s
        , const std::string & condName
+       , const std::string & name
        , const std::set<label_t> & used_labels
        , bool save_yyaccept
        );
index a20badda596c6599c7cec1062f71cfa4061d1fa8..ecefd16a6c355d9d24c5550378b3105a4997823f 100644 (file)
@@ -14,7 +14,7 @@ static void emit_initial       (OutputFile & o, uint32_t ind, bool & readCh, con
 static void emit_save          (OutputFile & o, uint32_t ind, bool & readCh, const State * const s, uint32_t save, bool save_yyaccept);
 static void emit_accept_binary (OutputFile & o, uint32_t ind, bool & readCh, const State * const s, const accept_t & accept, uint32_t l, uint32_t r);
 static void emit_accept        (OutputFile & o, uint32_t ind, bool & readCh, const State * const s, const accept_t & accept);
-static void emit_rule          (OutputFile & o, uint32_t ind, const State * const s, const RuleOp * const rule, const std::string & condName);
+static void emit_rule          (OutputFile & o, uint32_t ind, const State * const s, const RuleOp * const rule, const std::string & condName, const std::string & name);
 static void genYYFill          (OutputFile & o, uint32_t need);
 static void genSetCondition    (OutputFile & o, uint32_t ind, const std::string & newcond);
 
@@ -25,6 +25,7 @@ void emit_action
        , bool & readCh
        , const State * const s
        , const std::string & condName
+       , const std::string & name
        , const std::set<label_t> & used_labels
        , bool save_yyaccept
        )
@@ -46,7 +47,7 @@ void emit_action
                        emit_accept (o, ind, readCh, s, * action.info.accepts);
                        break;
                case Action::RULE:
-                       emit_rule (o, ind, s, action.info.rule, condName);
+                       emit_rule (o, ind, s, action.info.rule, condName, name);
                        break;
        }
 }
@@ -230,7 +231,7 @@ void emit_accept (OutputFile & o, uint32_t ind, bool & readCh, const State * con
        }
 }
 
-void emit_rule (OutputFile & o, uint32_t ind, const State * const s, const RuleOp * const rule, const std::string & condName)
+void emit_rule (OutputFile & o, uint32_t ind, const State * const s, const RuleOp * const rule, const std::string & condName, const std::string & name)
 {
        if (DFlag)
        {
@@ -251,7 +252,7 @@ void emit_rule (OutputFile & o, uint32_t ind, const State * const s, const RuleO
 
        if (flag_skeleton)
        {
-               Skeleton::emit_action (o, ind, rule->rank);
+               Skeleton::emit_action (o, ind, rule->rank, name);
        }
        else
        {
index 1f524b3d0f7ffa8717c1fa264d2116db44090aa8..fd42e60048d2e2a89f36283c01c78ef289a00157 100644 (file)
@@ -90,6 +90,18 @@ void DFA::count_used_labels (std::set<label_t> & used, label_t start, label_t in
        }
 }
 
+void DFA::emit_body (OutputFile & o, uint32_t& ind, const std::set<label_t> & used_labels) const
+{
+       const bool save_yyaccept = accepts.size () > 1;
+       for (State * s = head; s; s = s->next)
+       {
+               bool readCh = false;
+               emit_state (o, ind, s, used_labels.count (s->label));
+               emit_action (s->action, o, ind, readCh, s, cond, name, used_labels, save_yyaccept);
+               s->go.emit(o, ind, readCh);
+       }
+}
+
 void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBrace)
 {
        OutputFile & o = output.source;
@@ -114,129 +126,118 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra
 
        head->action.set_initial (initial_label, head->action.type == Action::SAVE);
 
-       // Generate prolog
        skeleton->warn_undefined_control_flow ();
+
        if (flag_skeleton)
        {
                skeleton->emit_data (o.file_name);
-               skeleton->emit_prolog (o, output.max_fill);
+               skeleton->emit_start (o, output.max_fill);
+               uint32_t i = 2;
+               emit_body (o, i, used_labels);
+               skeleton->emit_end (o);
        }
-       if (bProlog)
+       else
        {
-               o << "\n";
-               o.insert_line_info ();
-
-               if (DFlag)
-               {
-                       bPrologBrace = true;
-                       o << "digraph re2c {\n";
-               }
-               else if ((!fFlag && o.get_used_yyaccept ())
-               ||  (!fFlag && bEmitYYCh)
-               ||  (bFlag && !cFlag && BitMap::first)
-               ||  (cFlag && !bWroteCondCheck && gFlag)
-               ||  (fFlag && !bWroteGetState && gFlag)
-               )
-               {
-                       bPrologBrace = true;
-                       o << indent(ind++) << "{\n";
-               }
-               else if (ind == 0)
+               // Generate prolog
+               if (bProlog)
                {
-                       ind = 1;
-               }
-
-               if (!fFlag && !DFlag)
-               {
-                       if (bEmitYYCh)
+                       o << "\n";
+                       o.insert_line_info ();
+                       if (DFlag)
+                       {
+                               bPrologBrace = true;
+                               o << "digraph re2c {\n";
+                       }
+                       else if ((!fFlag && o.get_used_yyaccept ())
+                       ||  (!fFlag && bEmitYYCh)
+                       ||  (bFlag && !cFlag && BitMap::first)
+                       ||  (cFlag && !bWroteCondCheck && gFlag)
+                       ||  (fFlag && !bWroteGetState && gFlag)
+                       )
+                       {
+                               bPrologBrace = true;
+                               o << indent(ind++) << "{\n";
+                       }
+                       else if (ind == 0)
+                       {
+                               ind = 1;
+                       }
+                       if (!fFlag && !DFlag)
+                       {
+                               if (bEmitYYCh)
+                               {
+                                       o << indent(ind) << mapCodeName["YYCTYPE"] << " " << mapCodeName["yych"] << ";\n";
+                               }
+                               o.insert_yyaccept_init (ind);
+                       }
+                       else
                        {
-                               o << indent(ind) << mapCodeName["YYCTYPE"] << " " << mapCodeName["yych"] << ";\n";
+                               o << "\n";
                        }
-                       o.insert_yyaccept_init (ind);
                }
-               else
+               if (bFlag && !cFlag && BitMap::first)
                {
-                       o << "\n";
+                       BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256);
                }
-       }
-       if (bFlag && !cFlag && BitMap::first)
-       {
-               BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256);
-       }
-       if (bProlog)
-       {
-               if (cFlag && !bWroteCondCheck && gFlag)
+               if (bProlog)
                {
-                       genCondTable(o, ind, output.types);
+                       if (cFlag && !bWroteCondCheck && gFlag)
+                       {
+                               genCondTable(o, ind, output.types);
+                       }
+                       o.insert_state_goto (ind);
+                       if (cFlag && !DFlag)
+                       {
+                               if (used_labels.count(start_label))
+                               {
+                                       o << labelPrefix << start_label << ":\n";
+                               }
+                       }
+                       o.write_user_start_label ();
+                       if (cFlag && !bWroteCondCheck)
+                       {
+                               genCondGoto(o, ind, output.types);
+                       }
                }
-               o.insert_state_goto (ind);
-               if (cFlag && !DFlag)
+               if (cFlag && !cond.empty())
                {
-                       if (used_labels.count(start_label))
+                       if (condDivider.length())
+                       {
+                               o << replaceParam(condDivider, condDividerParam, cond) << "\n";
+                       }
+                       if (DFlag)
+                       {
+                               o << cond << " -> " << head->label << "\n";
+                       }
+                       else
                        {
-                               o << labelPrefix << start_label << ":\n";
+                               o << condPrefix << cond << ":\n";
                        }
                }
-               o.write_user_start_label ();
-               if (cFlag && !bWroteCondCheck)
+               if (cFlag && bFlag && BitMap::first)
                {
-                       genCondGoto(o, ind, output.types);
+                       o << indent(ind++) << "{\n";
+                       BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256);
                }
-       }
-
-       if (cFlag && !cond.empty())
-       {
-               if (condDivider.length())
+               // If DFA has transitions to initial state, then initial state
+               // has a piece of code that advances input position. Wee must
+               // skip it when entering DFA.
+               if (used_labels.count(head->label))
                {
-                       o << replaceParam(condDivider, condDividerParam, cond) << "\n";
+                       o << indent(ind) << "goto " << labelPrefix << initial_label << ";\n";
                }
-
-               if (DFlag)
+               // Generate code
+               emit_body (o, ind, used_labels);
+               if (cFlag && bFlag && BitMap::first)
                {
-                       o << cond << " -> " << head->label << "\n";
+                       o << indent(--ind) << "}\n";
                }
-               else
+               // Generate epilog
+               if ((!cFlag || isLastCond) && bPrologBrace)
                {
-                       o << condPrefix << cond << ":\n";
+                       o << indent(--ind) << "}\n";
                }
        }
-       if (cFlag && bFlag && BitMap::first)
-       {
-               o << indent(ind++) << "{\n";
-               BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256);
-       }
-
-       // If DFA has transitions to initial state, then initial state
-       // has a piece of code that advances input position. Wee must
-       // skip it when entering DFA.
-       if (used_labels.count(head->label))
-       {
-               o << indent(ind) << "goto " << labelPrefix << initial_label << ";\n";
-       }
-
-       // Generate code
-       const bool save_yyaccept = accepts.size () > 1;
-       for (State * s = head; s; s = s->next)
-       {
-               bool readCh = false;
-               emit_state (o, ind, s, used_labels.count (s->label));
-               emit_action (s->action, o, ind, readCh, s, cond, used_labels, save_yyaccept);
-               s->go.emit(o, ind, readCh);
-       }
-
-       if (cFlag && bFlag && BitMap::first)
-       {
-               o << indent(--ind) << "}\n";
-       }
-       // Generate epilog
-       if ((!cFlag || isLastCond) && bPrologBrace)
-       {
-               o << indent(--ind) << "}\n";
-       }
-       if (flag_skeleton)
-       {
-               Skeleton::emit_epilog (o);
-       }
 
        // Cleanup
        if (BitMap::first)
index 854d1862828aa6425b5503dd64e9feb43ff5bed5..2095159ce533ecde69110c325976ba8b85c9841d 100644 (file)
@@ -346,6 +346,7 @@ HeaderFile::~HeaderFile ()
 Output::Output (const char * source_name, const char * header_name)
        : source (source_name)
        , header (header_name)
+       , names ()
        , types ()
        , max_fill (1)
 {}
index fa0de2803c06a03a15a2d8311134cb397222dfbd..29b0ccb589ea62ec6d912689855344de68424cc8 100644 (file)
@@ -127,6 +127,7 @@ struct Output
 {
        OutputFile source;
        HeaderFile header;
+       std::vector<std::string> names;
        std::vector<std::string> types;
        uint32_t max_fill;
 
index 4a053a3010485cab3ceed4b5600c01bca6d09c58..9cc0e26d897e9348956eee70934e00fa5b36639a 100644 (file)
@@ -1,5 +1,7 @@
+#include "src/codegen/bitmap.h"
 #include "src/codegen/indent.h"
 #include "src/codegen/skeleton/skeleton.h"
+#include "src/conf/msg.h"
 
 namespace re2c
 {
@@ -28,24 +30,31 @@ static void exact_uint (OutputFile & o, size_t width)
        }
 }
 
-void Skeleton::emit_prolog (OutputFile & o, uint32_t maxfill) const
+void Skeleton::emit_prolog (OutputFile & o)
 {
-       const uint32_t default_rule = maxkey ();
-
        o << "\n" << "#include <stdio.h>";
        o << "\n" << "#include <stdlib.h> // malloc, free";
        o << "\n" << "#include <string.h> // memset";
        o << "\n";
+       o << "\n" << "static size_t filesize (FILE * f)";
+       o << "\n" << "{";
+       o << "\n" << indString << "const long pos = ftell (f);";
+       o << "\n" << indString << "fseek (f, 0, SEEK_END);";
+       o << "\n" << indString << "const long size = ftell (f);";
+       o << "\n" << indString << "fseek (f, pos, SEEK_SET);";
+       o << "\n" << indString << "return (size_t) size;";
+       o << "\n" << "}";
+       o << "\n";
+}
 
-       o << "\n" << "typedef ";
-       exact_uint (o, encoding.szCodeUnit ());
-       o << " YYCTYPE;";
+void Skeleton::emit_start (OutputFile & o, uint32_t maxfill) const
+{
+       const uint32_t default_rule = maxkey ();
 
-       o << "\n" << "typedef ";
+       o << "\n" << "#define YYCTYPE ";
+       exact_uint (o, encoding.szCodeUnit ());
+       o << "\n" << "#define YYKEYTYPE ";
        exact_uint (o, sizeof_key);
-       o << " YYKEYTYPE;";
-
-       o << "\n";
        o << "\n" << "#define YYPEEK() *cursor";
        o << "\n" << "#define YYSKIP() ++cursor";
        o << "\n" << "#define YYBACKUP() marker = cursor";
@@ -55,11 +64,7 @@ void Skeleton::emit_prolog (OutputFile & o, uint32_t maxfill) const
        o << "\n" << "#define YYLESSTHAN(n) (limit - cursor) < n";
        o << "\n" << "#define YYFILL(n) { break; }";
        o << "\n";
-       o << "\n" << "static inline YYKEYTYPE length       (const YYKEYTYPE * keys, unsigned int i) { return keys [3 * i]; }";
-       o << "\n" << "static inline YYKEYTYPE match_length (const YYKEYTYPE * keys, unsigned int i) { return keys [3 * i + 1]; }";
-       o << "\n" << "static inline YYKEYTYPE rule         (const YYKEYTYPE * keys, unsigned int i) { return keys [3 * i + 2]; }";
-       o << "\n";
-       o << "\n" << "static inline int action";
+       o << "\n" << "static int action_" << name;
        o << "\n" << indString << "( unsigned int i";
        o << "\n" << indString << ", const YYKEYTYPE * keys";
        o << "\n" << indString << ", const YYCTYPE * start";
@@ -70,27 +75,28 @@ void Skeleton::emit_prolog (OutputFile & o, uint32_t maxfill) const
        o << "\n" << "{";
        o << "\n" << indString << "const long pos = token - start;";
        o << "\n" << indString << "const long len_act = *cursor - token;";
-       o << "\n" << indString << "const long len_exp = (long) match_length (keys, i);";
-       o << "\n" << indString << "const YYKEYTYPE rule_exp = rule (keys, i);";
+       o << "\n" << indString << "const long len_exp = (long) keys [3 * i + 1];";
+       o << "\n" << indString << "const YYKEYTYPE rule_exp = keys [3 * i + 2];";
        o << "\n" << indString << "if (rule_exp == " << default_rule << ")";
        o << "\n" << indString << "{";
        o << "\n" << indString << indString << "fprintf";
        o << "\n" << indString << indString << indString << "( stderr";
-       o << "\n" << indString << indString << indString << ", \"warning: control flow is undefined for input\"";
+       o << "\n" << indString << indString << indString << ", \"warning: " << incond (cond) << "control flow is undefined for input\"";
        o << "\n" << indString << indString << indString << indString << "\" at position %ld, rerun re2c with '-W'\\n\"";
        o << "\n" << indString << indString << indString << ", pos";
        o << "\n" << indString << indString << indString << ");";
        o << "\n" << indString << "}";
        o << "\n" << indString << "if (len_act == len_exp && rule_act == rule_exp)";
        o << "\n" << indString << "{";
-       o << "\n" << indString << indString << "*cursor = token + length (keys, i);";
+       o << "\n" << indString << indString << "const YYKEYTYPE offset = keys[3 * i];";
+       o << "\n" << indString << indString << "*cursor = token + offset;";
        o << "\n" << indString << indString << "return 0;";
        o << "\n" << indString << "}";
        o << "\n" << indString << "else";
        o << "\n" << indString << "{";
        o << "\n" << indString << indString << "fprintf";
        o << "\n" << indString << indString << indString << "( stderr";
-       o << "\n" << indString << indString << indString << ", \"error: at position %ld (iteration %u):\\n\"";
+       o << "\n" << indString << indString << indString << ", \"error: " << incond (cond) << "at position %ld (iteration %u):\\n\"";
        o << "\n" << indString << indString << indString << indString << "\"\\texpected: match length %ld, rule %u\\n\"";
        o << "\n" << indString << indString << indString << indString << "\"\\tactual:   match length %ld, rule %u\\n\"";
        o << "\n" << indString << indString << indString << ", pos";
@@ -104,27 +110,18 @@ void Skeleton::emit_prolog (OutputFile & o, uint32_t maxfill) const
        o << "\n" << indString << "}";
        o << "\n" << "}";
        o << "\n";
-       o << "\n" << "static inline size_t filesize (FILE * f)";
+       o << "\n" << "int lex_" << name << " ()";
        o << "\n" << "{";
-       o << "\n" << indString << "const long pos = ftell (f);";
-       o << "\n" << indString << "fseek (f, 0, SEEK_END);";
-       o << "\n" << indString << "const long size = ftell (f);";
-       o << "\n" << indString << "fseek (f, pos, SEEK_SET);";
-       o << "\n" << indString << "return (size_t) size;";
-       o << "\n" << "}";
-       o << "\n";
-       o << "\n" << "int main ()";
-       o << "\n" << "{";
-       o << "\n" << indString << "FILE * finput = fopen (\"" << o.file_name << ".input" << "\", \"rb\");";
+       o << "\n" << indString << "FILE * finput = fopen (\"" << o.file_name << "." << name << ".input" << "\", \"rb\");";
        o << "\n" << indString << "if (!finput)";
        o << "\n" << indString << "{";
-       o << "\n" << indString << indString << "fprintf (stderr, \"cannot open file '%s'\\n\", \"" << o.file_name << ".input\");";
+       o << "\n" << indString << indString << "fprintf (stderr, \"cannot open file '%s'\\n\", \"" << o.file_name << "." << name << ".input\");";
        o << "\n" << indString << indString << "return 1;";
        o << "\n" << indString << "}";
-       o << "\n" << indString << "FILE * fkeys = fopen (\"" << o.file_name << ".keys" << "\", \"rb\");";
+       o << "\n" << indString << "FILE * fkeys = fopen (\"" << o.file_name << "." << name << ".keys" << "\", \"rb\");";
        o << "\n" << indString << "if (!fkeys)";
        o << "\n" << indString << "{";
-       o << "\n" << indString << indString << "fprintf (stderr, \"cannot open file '%s'\\n\", \"" << o.file_name << ".keys\");";
+       o << "\n" << indString << indString << "fprintf (stderr, \"cannot open file '%s'\\n\", \"" << o.file_name << "." << name << ".keys\");";
        o << "\n" << indString << indString << "return 1;";
        o << "\n" << indString << "}";
        o << "\n";
@@ -150,10 +147,17 @@ void Skeleton::emit_prolog (OutputFile & o, uint32_t maxfill) const
        o << "\n" << indString << "for (i = 0; status == 0 && cursor < eof && i < keys_count; ++i)";
        o << "\n" << indString << "{";
        o << "\n" << indString << indString << "const YYCTYPE * token = cursor;";
+       o << "\n" << indString << indString << "YYCTYPE yych;";
+       o.insert_yyaccept_init (2);
+       o << "\n";
+       if (bFlag && BitMap::first)
+       {
+               BitMap::gen (o, 2, 0, std::min (0xFFu, encoding.nCodeUnits ()));
+       }
        o << "\n";
 }
 
-void Skeleton::emit_epilog (OutputFile & o)
+void Skeleton::emit_end (OutputFile & o) const
 {
        o << "\n" << indString << "}";
        o << "\n" << indString << "if (status == 0)";
@@ -161,12 +165,12 @@ void Skeleton::emit_epilog (OutputFile & o)
        o << "\n" << indString << indString << "if (cursor != eof)";
        o << "\n" << indString << indString << "{";
        o << "\n" << indString << indString << indString << "status = 1;";
-       o << "\n" << indString << indString << indString << "fprintf (stderr, \"error: unused input strings left\\n\");";
+       o << "\n" << indString << indString << indString << "fprintf (stderr, \"error: " << incond (cond) << "unused input strings left\\n\");";
        o << "\n" << indString << indString << "}";
        o << "\n" << indString << indString << "if (i != keys_count)";
        o << "\n" << indString << indString << "{";
        o << "\n" << indString << indString << indString << "status = 1;";
-       o << "\n" << indString << indString << indString << "fprintf (stderr, \"error: unused keys left\\n\");";
+       o << "\n" << indString << indString << indString << "fprintf (stderr, \"error: " << incond (cond) << "unused keys left\\n\");";
        o << "\n" << indString << indString << "}";
        o << "\n" << indString << "}";
        o << "\n" << indString << "free (input);";
@@ -178,6 +182,7 @@ void Skeleton::emit_epilog (OutputFile & o)
        o << "\n" << "}";
        o << "\n";
        o << "\n" << "#undef YYCTYPE";
+       o << "\n" << "#undef YYKEYTYPE";
        o << "\n" << "#undef YYPEEK";
        o << "\n" << "#undef YYSKIP";
        o << "\n" << "#undef YYBACKUP";
@@ -189,9 +194,25 @@ void Skeleton::emit_epilog (OutputFile & o)
        o << "\n";
 }
 
-void Skeleton::emit_action (OutputFile & o, uint32_t ind, rule_rank_t rank)
+void Skeleton::emit_epilog (OutputFile & o, const std::vector<std::string> & names)
+{
+       o << "\n" << "int main ()";
+       o << "\n" << "{";
+
+       const size_t names_count = names.size ();
+       for (size_t i = 0; i < names_count; ++i)
+       {
+               o << "\n" << indString << "if (lex_" << names[i] << " () != 0) return 1;";
+       }
+
+       o << "\n" << indString << "return 0;";
+       o << "\n" << "}";
+       o << "\n";
+}
+
+void Skeleton::emit_action (OutputFile & o, uint32_t ind, rule_rank_t rank, const std::string & name)
 {
-       o << indent (ind) << "status = action (i, keys, input, token, &cursor, " << rank << ");\n";
+       o << indent (ind) << "status = action_" << name << " (i, keys, input, token, &cursor, " << rank << ");\n";
        o << indent (ind) << "continue;\n";
 }
 
index b7b691dc39a1ad3a8aee1f6e576256622a5de034..ae34d5c2cbb80e7aac33d52606beaea200bc2489 100644 (file)
@@ -222,14 +222,14 @@ void Skeleton::generate_paths (FILE * input, FILE * keys)
 
 void Skeleton::emit_data (const char * fname)
 {
-       const std::string input_name = std::string (fname) + ".input";
+       const std::string input_name = std::string (fname) + "." + name + ".input";
        FILE * input = fopen (input_name.c_str (), "wb");
        if (!input)
        {
                error ("cannot open file: %s", input_name.c_str ());
                exit (1);
        }
-       const std::string keys_name = std::string (fname) + ".keys";
+       const std::string keys_name = std::string (fname) + "." + name + ".keys";
        FILE * keys = fopen (keys_name.c_str (), "wb");
        if (!keys)
        {
index ae41fb63dd063e78e88e1763d47fc1e9bb5beaa0..e87e572a4ab3eac22805be1cabed8c3672ac6b7f 100644 (file)
@@ -56,7 +56,8 @@ bool Node::end () const
 
 Skeleton::Skeleton (const DFA & dfa)
        // +1 for default DFA state (NULL)
-       : cond (dfa.cond)
+       : name (dfa.name)
+       , cond (dfa.cond)
        , line (dfa.line)
        , nodes_count (dfa.nStates + 1) // +1 for default state
        , nodes (new Node [nodes_count])
index 804e6479085ff0e530eccd2534a41f1882677b3e..707d2f2c06cec74776218869de6388c65a381336 100644 (file)
@@ -60,7 +60,8 @@ struct Node
 
 struct Skeleton
 {
-       const std::string cond;
+       const std::string & name;
+       const std::string & cond;
        const uint32_t line;
 
        const uint32_t nodes_count;
@@ -71,9 +72,11 @@ struct Skeleton
        ~Skeleton ();
        void warn_undefined_control_flow ();
        void emit_data (const char * fname);
-       void emit_prolog (OutputFile & o, uint32_t maxfill) const;
-       static void emit_epilog (OutputFile & o);
-       static void emit_action (OutputFile & o, uint32_t ind, rule_rank_t rank);
+       static void emit_prolog (OutputFile & o);
+       void emit_start (OutputFile & o, uint32_t maxfill) const;
+       void emit_end (OutputFile & o) const;
+       static void emit_epilog (OutputFile & o, const std::vector<std::string> & names);
+       static void emit_action (OutputFile & o, uint32_t ind, rule_rank_t rank, const std::string & name);
 
        template <typename key_t>
                static key_t maxkey ();
index 068d80aa26e1c61632028c2b3084365aa08843f3..8d2ed241f01f52b31cad360c62c6fc4495141378 100644 (file)
@@ -64,6 +64,7 @@ smart_ptr<DFA> genCode (RegExp *re, Output & output, const std::string & cond)
                , rep
                ));
 
+       output.names.push_back (dfa->name);
        dfa->prepare (output.source, output.max_fill);
 
        return dfa;
index e41f9ba0fdd0b1fe5fc74a480337a0599f335127..a58e42250a1fa1e5fee7bb91a43088b8884d1b89 100644 (file)
@@ -48,6 +48,7 @@ DFA::DFA
        )
        : accepts ()
        , skeleton (NULL)
+       , name (c)
        , cond (c)
        , line (l)
        , lbChar(lb)
@@ -59,6 +60,13 @@ DFA::DFA
        , free_ins(ins)
        , free_rep(rep)
 {
+       if (name.empty ())
+       {
+               std::ostringstream s;
+               s << "line" << line;
+               name = s.str ();
+       }
+
        Ins **work = new Ins * [ni + 1];
        uint32_t nc = ub - lb;
        GoTo *goTo = new GoTo[nc];
index 3aa1df08f88c50fa2caa15475441bbfab6656392..9725ac99c495112c8a8ab21b6ca9d8f3f3b7c52d 100644 (file)
@@ -16,6 +16,7 @@ class DFA
        Skeleton * skeleton;
 
 public:
+       std::string name;
        const std::string cond;
        const uint32_t line;
 
@@ -47,6 +48,7 @@ public:
        void findBaseState ();
        void prepare (OutputFile & o, uint32_t &);
        void count_used_labels (std::set<label_t> & used, label_t prolog, label_t start, bool force_start) const;
+       void emit_body (OutputFile &, uint32_t &, const std::set<label_t> & used_labels) const;
        void emit (Output &, uint32_t &, bool, bool &);
 
        friend std::ostream & operator << (std::ostream &, const DFA &);
index ea98d9db2d54229d49b3d34fec9964cd52adfc60..1f7fc524c60eb5e7a7bae859c4ae3ef6c8ae0727 100644 (file)
@@ -8,6 +8,7 @@
 #include <set>
 
 #include "config.h"
+#include "src/codegen/skeleton/skeleton.h"
 #include "src/ir/bytecode/bytecode.h"
 #include "src/ir/regexp/encoding/enc.h"
 #include "src/ir/regexp/encoding/range_suffix.h"
@@ -767,6 +768,10 @@ void parse(Scanner& i, Output & o)
 
        o.source.write_version_time ();
        o.source.write_line_info (in->get_cline (), in->get_fname ().c_str ());
+       if (flag_skeleton)
+       {
+               Skeleton::emit_prolog (o.source);
+       }
 
        Enc encodingOld = encoding;
        
@@ -975,6 +980,11 @@ void parse(Scanner& i, Output & o)
                }
        }
 
+       if (flag_skeleton)
+       {
+               Skeleton::emit_epilog (o.source, o.names);
+       }
+
        parse_cleanup();
        in = NULL;
 }