]> granicus.if.org Git - re2c/commitdiff
Buffer statements into a list to avoid complex pre-counting.
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 5 Oct 2016 20:56:58 +0000 (21:56 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 5 Oct 2016 20:56:58 +0000 (21:56 +0100)
Formatting of 'if' or 'case' statements depends on the number of
statements in the correspoonding code block: multi-statement blockss
must be wrapped in braces or extra-tabulated.

Estimating the number of lines has never been particularly elegant,
but it gets worse every time we add possible new instructions to
transitions.

re2c/src/codegen/emit.h
re2c/src/codegen/emit_action.cc
re2c/src/codegen/go_emit.cc

index ff105bff815aaec462a8e314dccd29a8f2f4499f..e4bbe3ce9b4115cb77f2c107224e5436163a5cb6 100644 (file)
@@ -6,15 +6,17 @@
 
 namespace re2c {
 
+typedef std::vector<std::string> code_lines_t;
+
 void emit_action(OutputFile &o, uint32_t ind, bool &readCh,
        const DFA &dfa, const State *s, const std::set<label_t> &used_labels);
-void gen_goto(OutputFile &o, uint32_t ind, bool &readCh,
+void gen_goto_plain(OutputFile &o, uint32_t ind, bool &readCh,
        const State *to, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
 void gen_goto_case(OutputFile &o, uint32_t ind, bool &readCh,
        const State *to, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
 void gen_goto_if(OutputFile &o, uint32_t ind, bool &readCh,
        const State *to, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
-void gen_settags(OutputFile &o, uint32_t ind, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
+void gen_settags(code_lines_t &code, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
 std::string vartag_name(const std::string *name, size_t rule);
 std::string vartag_expr(const std::string *name, size_t rule);
 std::string vartag_name_fallback(const Tag &tag);
index fb1a5d40e3ade666d3aaefcd80351fc5cc98ab3c..b798e273db637073f209082a16188e7e6414884a 100644 (file)
@@ -15,6 +15,7 @@
 #include "src/parse/code.h"
 #include "src/parse/loc.h"
 #include "src/util/strrreplace.h"
+#include "src/util/to_string.h"
 
 namespace re2c
 {
@@ -31,6 +32,7 @@ static void emit_rule(OutputFile &o, uint32_t ind, const DFA &dfa, size_t rule_i
 static void genYYFill(OutputFile &o, size_t need);
 static void genSetCondition(OutputFile &o, uint32_t ind, const std::string &cond);
 static void genSetState(OutputFile &o, uint32_t ind, uint32_t fillIndex);
+static void gen_goto(code_lines_t &code, bool &readCh, const State *to, const DFA &dfa, const tagcmd_t &tags, bool restore_fallback);
 
 void emit_action(OutputFile &o, uint32_t ind, bool &readCh,
        const DFA &dfa, const State *s, const std::set<label_t> &used_labels)
@@ -140,7 +142,7 @@ void emit_accept_binary(OutputFile &o, uint32_t ind, bool &readCh,
                o.wind(--ind).ws("}\n");
        } else {
                const accept_t &acc = *s->action.info.accepts;
-               gen_goto(o, ind, readCh, acc[l].first, dfa, acc[l].second, true);
+               gen_goto_plain(o, ind, readCh, acc[l].first, dfa, acc[l].second, true);
        }
 }
 
@@ -162,7 +164,7 @@ void emit_accept(OutputFile &o, uint32_t ind, bool &readCh,
 
        // only one possible 'yyaccept' value: unconditional jump
        if (nacc == 1) {
-               gen_goto(o, ind, readCh, acc[0].first, dfa, acc[0].second, true);
+               gen_goto_plain(o, ind, readCh, acc[0].first, dfa, acc[0].second, true);
                return;
        }
 
@@ -320,13 +322,17 @@ void gen_goto_case(OutputFile &o, uint32_t ind, bool &readCh,
        const State *to, const DFA &dfa, const tagcmd_t &tags,
        bool restore_fallback)
 {
-       const bool multiline = readCh || !tags.empty();
+       code_lines_t code;
+       gen_goto(code, readCh, to, dfa, tags, restore_fallback);
+       const size_t lines = code.size();
 
-       if (multiline) {
-               o.ws("\n");
-               gen_goto(o, ind + 1, readCh, to, dfa, tags, restore_fallback);
+       if (lines == 1) {
+               o.wind(1).wstring(code[0]);
        } else {
-               gen_goto(o, 1, readCh, to, dfa, tags, restore_fallback);
+               o.ws("\n");
+               for (size_t i = 0; i < lines; ++i) {
+                       o.wind(ind + 1).wstring(code[i]);
+               }
        }
 }
 
@@ -334,45 +340,59 @@ void gen_goto_if(OutputFile &o, uint32_t ind, bool &readCh,
        const State *to, const DFA &dfa, const tagcmd_t &tags,
        bool restore_fallback)
 {
-       const int32_t linecount = (readCh && to != NULL)
-               + !tags.empty()
-               + (to != NULL);
+       code_lines_t code;
+       gen_goto(code, readCh, to, dfa, tags, restore_fallback);
+       const size_t lines = code.size();
 
-       if (linecount > 1) {
+       if (lines == 1) {
+               o.wstring(code[0]);
+       } else {
                o.ws("{\n");
-               gen_goto(o, ind + 1, readCh, to, dfa, tags, restore_fallback);
+               for (size_t i = 0; i < lines; ++i) {
+                       o.wind(ind + 1).wstring(code[i]);
+               }
                o.wind(ind).ws("}\n");
-       } else {
-               gen_goto(o, 0, readCh, to, dfa, tags, restore_fallback);
        }
 }
 
-void gen_goto(OutputFile &o, uint32_t ind, bool &readCh,
+void gen_goto_plain(OutputFile &o, uint32_t ind, bool &readCh,
        const State *to, const DFA &dfa, const tagcmd_t &tags,
        bool restore_fallback)
+{
+       code_lines_t code;
+       gen_goto(code, readCh, to, dfa, tags, restore_fallback);
+       const size_t lines = code.size();
+
+       for (size_t i = 0; i < lines; ++i) {
+               o.wind(ind).wstring(code[i]);
+       }
+}
+
+void gen_goto(code_lines_t &code, bool &readCh, const State *to,
+       const DFA &dfa, const tagcmd_t &tags, bool restore_fallback)
 {
        if (to == NULL) {
                readCh = false;
        }
        if (readCh) {
-               o.wstring(opts->input_api.stmt_peek(ind));
+               code.push_back(opts->input_api.stmt_peek(0));
                readCh = false;
        }
-       gen_settags(o, ind, dfa, tags, restore_fallback);
+       gen_settags(code, dfa, tags, restore_fallback);
        if (to) {
-               o.wind(ind).ws("goto ").wstring(opts->labelPrefix)
-                       .wlabel(to->label).ws(";\n");
+               code.push_back("goto " + opts->labelPrefix
+                       + to_string(to->label) + ";\n");
        }
 }
 
-void gen_settags(OutputFile &o, uint32_t ind, const DFA &dfa,
+void gen_settags(code_lines_t &code, const DFA &dfa,
        const tagcmd_t &cmd, bool restore_fallback)
 {
        if (cmd.empty()) return;
 
        if (!dfa.basetag) {
                assert(cmd.copy == ZERO_TAGS);
-               o.wstring(opts->input_api.stmt_backupctx(ind));
+               code.push_back(opts->input_api.stmt_backupctx(0));
                return;
        }
 
@@ -386,11 +406,12 @@ void gen_settags(OutputFile &o, uint32_t ind, const DFA &dfa,
                                x = vartag_expr(tag.name, tag.rule),
                                y = vartag_expr_fallback(tag);
                        if (restore_fallback) std::swap(x, y);
-                       o.wind(ind).wstring(y).ws(" = ").wstring(x).ws(";\n");
+                       code.push_back(y + " = " + x + ";\n");
                }
        }
        if (cmd.set != ZERO_TAGS) {
-               o.wstring(opts->input_api.stmt_dist(ind, dfa.tagpool[cmd.set], tags));
+               code.push_back(opts->input_api.stmt_dist(0,
+                       dfa.tagpool[cmd.set], tags));
        }
 }
 
index f31783ab7e0c32d08df644d3838b767bddbe9e46..7970c99794decaf06b07e4d742e9e28cf2a2968a 100644 (file)
@@ -117,7 +117,7 @@ void Linear::emit(OutputFile &o, uint32_t ind, const DFA &dfa, bool &readCh)
                        output_if(o, ind, readCh, cond->compare, cond->value);
                        gen_goto_if(o, ind, readCh, b.to, dfa, b.tags, false);
                } else {
-                       gen_goto(o, ind, readCh, b.to, dfa, b.tags, false);
+                       gen_goto_plain(o, ind, readCh, b.to, dfa, b.tags, false);
                }
        }
 }
@@ -151,7 +151,7 @@ void GoBitmap::emit (OutputFile & o, uint32_t ind, const DFA &dfa, bool & readCh
                o.wu32(bitmap->m);
        }
        o.ws(") {\n");
-       gen_goto(o, ind + 1, readCh, bitmap_state, dfa, tagcmd_t(), false);
+       gen_goto_plain(o, ind + 1, readCh, bitmap_state, dfa, tagcmd_t(), false);
        o.wind(ind).ws("}\n");
        if (lgo != NULL)
        {
@@ -232,7 +232,12 @@ void Dot::emit(OutputFile &o, const DFA &dfa)
 
 void Go::emit (OutputFile & o, uint32_t ind, const DFA &dfa, bool & readCh)
 {
-       gen_settags(o, ind, dfa, tags, false);
+       code_lines_t code;
+       gen_settags(code, dfa, tags, NULL);
+       for (size_t i = 0; i < code.size(); ++i) {
+               o.wind(ind).wstring(code[i]);
+       }
+
        switch (type) {
                case EMPTY:
                        break;