]> granicus.if.org Git - re2c/commitdiff
Consistently use current block's options for code generation.
authorUlya Trofimovich <skvadrik@gmail.com>
Sun, 1 Jan 2017 18:47:06 +0000 (18:47 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Sun, 1 Jan 2017 18:47:06 +0000 (18:47 +0000)
26 files changed:
re2c/bootstrap/src/parse/lex.cc
re2c/bootstrap/src/parse/lex_conf.cc
re2c/bootstrap/src/parse/parser.cc
re2c/src/codegen/bitmap.cc
re2c/src/codegen/emit.h
re2c/src/codegen/emit_action.cc
re2c/src/codegen/emit_dfa.cc
re2c/src/codegen/go.h
re2c/src/codegen/go_construct.cc
re2c/src/codegen/go_emit.cc
re2c/src/codegen/input_api.cc
re2c/src/codegen/input_api.h
re2c/src/codegen/output.cc
re2c/src/codegen/output.h
re2c/src/conf/opt.cc
re2c/src/conf/opt.h
re2c/src/ir/adfa/adfa.h
re2c/src/ir/adfa/prepare.cc
re2c/src/ir/compile.cc
re2c/src/ir/skeleton/generate_code.cc
re2c/src/main.cc
re2c/src/parse/lex_conf.re
re2c/src/parse/parser.ypp
re2c/src/parse/scanner.cc
re2c/src/parse/scanner.h
re2c/test/push.--skeleton.c

index 3dc2caaccd944a84fd8c1e8918a9b418d13f1ebf..0580479fba54933c270035acad32f5f664814430 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.16 on Thu Dec 29 16:34:43 2016 */
+/* Generated by re2c 0.16 on Sun Jan  1 18:41:52 2017 */
 #line 1 "../src/parse/lex.re"
 #include "src/util/c99_stdint.h"
 #include <stddef.h>
index ead68c73214b79a5eede03513ccd6b49a468cd94..9044a370191ecd8044a1bb519e1ef8a50ef79592 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.16 on Fri Dec 30 11:03:32 2016 */
+/* Generated by re2c 0.16 on Sat Dec 31 21:47:22 2016 */
 #line 1 "../src/parse/lex_conf.re"
 #include "src/util/c99_stdint.h"
 #include <string>
@@ -1377,7 +1377,7 @@ yy283:
        }
 yy284:
 #line 164 "../src/parse/lex_conf.re"
-       { out.block().user_start_label = lex_conf_string(); return; }
+       { opts.set_startlabel       (lex_conf_string()); return; }
 #line 1382 "src/parse/lex_conf.cc"
 yy285:
        yych = (unsigned char)*++cur;
@@ -1885,7 +1885,7 @@ yy407:
 yy408:
        cur = ctx;
 #line 163 "../src/parse/lex_conf.re"
-       { out.block().force_start_label = lex_conf_bool(); return; }
+       { opts.set_startlabel_force (lex_conf_bool());   return; }
 #line 1890 "src/parse/lex_conf.cc"
 yy409:
        ++cur;
index 397897ec5b464819954d1b0a0d168ab4d1c2e742..6cce158dab3c510079004b345cd7370d257d34f5 100644 (file)
@@ -2056,9 +2056,10 @@ void parse(Scanner &input, Output & o)
        ScannerState rules_state, curr_state;
        Opt &opts = input.opts;
 
-       o.source.new_block();
-       o.source.wversion_time ()
-               .wline_info (input.get_cline (), input.get_fname ().c_str ());
+       o.source.new_block(opts);
+
+       o.source.wversion_time()
+               .wline_info(input.get_cline(), input.get_fname().c_str());
        if (opts->target == opt_t::SKELETON)
        {
                emit_prolog (o.source);
@@ -2067,9 +2068,6 @@ void parse(Scanner &input, Output & o)
        Enc encodingOld = opts->encoding;
        for (Scanner::ParseMode mode; (mode = input.echo()) != Scanner::Stop;) {
 
-               o.source.block().opts = opts.snapshot();
-               o.source.new_block();
-
                input.save_state(curr_state);
                if (opts->rFlag && mode == Scanner::Rules && !dfas.empty())
                {
@@ -2114,6 +2112,9 @@ void parse(Scanner &input, Output & o)
                        encodingOld = opts->encoding;
                }
 
+               // start new output block with accumulated options
+               o.source.new_block(opts);
+
                // compile regular expressions to automata
                if (mode != Scanner::Reuse) {
                        check(specs, opts->cFlag);
@@ -2142,7 +2143,6 @@ void parse(Scanner &input, Output & o)
        {
                emit_epilog (o.source, o.skeletons);
        }
-       o.source.block().opts = opts.snapshot();
 
        RegExp::flist.clear();
        Code::flist.clear();
index fa8ba4371b9009665533170e1425586a4b78beb1..e6f1d1bc0c1a1f23bf2ab9a1a8acda964802bff4 100644 (file)
@@ -47,7 +47,7 @@ void bitmaps_t::gen(OutputFile &o, uint32_t ind)
 {
        if (empty() || !used) return;
 
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        const uint32_t nmap = static_cast<uint32_t>(maps.size());
        riter_t b = maps.rbegin(), e = maps.rend();
 
index 171460c12cb31bb9ec9689cd70f0390388a8f2ee..8733bf366e44552a1a44850dd38b974e053d1b46 100644 (file)
@@ -12,7 +12,7 @@ void emit_action(OutputFile &o, uint32_t ind, const DFA &dfa, const State *s, co
 void gen_goto_plain(OutputFile &o, uint32_t ind, const State *to, const DFA &dfa, tcid_t tcid);
 void gen_goto_case(OutputFile &o, uint32_t ind, const State *to, const DFA &dfa, tcid_t tcid);
 void gen_goto_if(OutputFile &o, uint32_t ind, const State *to, const DFA &dfa, tcid_t tcid);
-void gen_settags(code_lines_t &code, const DFA &dfa, tcid_t tcid, Opt &opts);
+void gen_settags(code_lines_t &code, const DFA &dfa, tcid_t tcid, const opt_t *opts);
 std::string vartag_name(tagver_t ver, const std::string &prefix);
 std::string vartag_expr(tagver_t ver, const std::string &prefix, const std::string &expression);
 
index d2b2b24d96c3263b1be311072e246a94196feea9..ab4f8ada9d6b8b46460d3abe0689b6ce3acff71c 100644 (file)
@@ -22,13 +22,13 @@ static void emit_accept_binary (OutputFile &o, uint32_t ind, const DFA &dfa, con
 static void emit_accept        (OutputFile &o, uint32_t ind, const DFA &dfa, const accept_t &acc);
 static void emit_rule          (OutputFile &o, uint32_t ind, const DFA &dfa, size_t rule_idx);
 static void gen_fintags        (OutputFile &o, uint32_t ind, const DFA &dfa, const Rule &rule);
-static void gen_goto           (code_lines_t &code, const State *to, const DFA &dfa, tcid_t tcid, Opt &opts);
+static void gen_goto           (code_lines_t &code, const State *to, const DFA &dfa, tcid_t tcid, const opt_t *opts);
 static bool endstate           (const State *s);
 
 void emit_action(OutputFile &o, uint32_t ind, const DFA &dfa,
        const State *s, const std::set<label_t> &used_labels)
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        switch (s->action.type) {
        case Action::MATCH:
                o.wdelay_skip(ind, true);
@@ -79,7 +79,7 @@ void emit_action(OutputFile &o, uint32_t ind, const DFA &dfa,
 void emit_accept_binary(OutputFile &o, uint32_t ind, const DFA &dfa,
        const accept_t &acc, size_t l, size_t r)
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        if (l < r) {
                const size_t m = (l + r) >> 1;
                o.wind(ind).ws("if (").wstring(opts->yyaccept)
@@ -95,7 +95,7 @@ void emit_accept_binary(OutputFile &o, uint32_t ind, const DFA &dfa,
 
 void emit_accept(OutputFile &o, uint32_t ind, const DFA &dfa, const accept_t &acc)
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        const size_t nacc = acc.size();
 
        if (nacc == 0) return;
@@ -153,7 +153,7 @@ void emit_accept(OutputFile &o, uint32_t ind, const DFA &dfa, const accept_t &ac
 
 void emit_rule(OutputFile &o, uint32_t ind, const DFA &dfa, size_t rule_idx)
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        const Rule &rule = dfa.rules[rule_idx];
        const Code *code = rule.code;
        const std::string &cond = code->cond;
@@ -192,7 +192,7 @@ void need(OutputFile &o, uint32_t ind, size_t some)
 {
        if (some == 0) return;
 
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        std::string s;
 
        if (opts->fFlag) {
@@ -230,7 +230,7 @@ void gen_goto_case(OutputFile &o, uint32_t ind, const State *to,
        const DFA &dfa, tcid_t tcid)
 {
        code_lines_t code;
-       gen_goto(code, to, dfa, tcid, o.opts);
+       gen_goto(code, to, dfa, tcid, o.block().opts);
        const size_t lines = code.size();
 
        if (lines == 1) {
@@ -247,7 +247,7 @@ void gen_goto_if(OutputFile &o, uint32_t ind, const State *to,
        const DFA &dfa, tcid_t tcid)
 {
        code_lines_t code;
-       gen_goto(code, to, dfa, tcid, o.opts);
+       gen_goto(code, to, dfa, tcid, o.block().opts);
        const size_t lines = code.size();
 
        if (lines == 1) {
@@ -265,7 +265,7 @@ void gen_goto_plain(OutputFile &o, uint32_t ind, const State *to,
        const DFA &dfa, tcid_t tcid)
 {
        code_lines_t code;
-       gen_goto(code, to, dfa, tcid, o.opts);
+       gen_goto(code, to, dfa, tcid, o.block().opts);
        const size_t lines = code.size();
 
        for (size_t i = 0; i < lines; ++i) {
@@ -274,7 +274,7 @@ void gen_goto_plain(OutputFile &o, uint32_t ind, const State *to,
 }
 
 void gen_goto(code_lines_t &code, const State *to, const DFA &dfa,
-       tcid_t tcid, Opt &opts)
+       tcid_t tcid, const opt_t *opts)
 {
        gen_settags(code, dfa, tcid, opts);
        if (to) {
@@ -283,7 +283,7 @@ void gen_goto(code_lines_t &code, const State *to, const DFA &dfa,
        }
 }
 
-void gen_settags(code_lines_t &code, const DFA &dfa, tcid_t tcid, Opt &opts)
+void gen_settags(code_lines_t &code, const DFA &dfa, tcid_t tcid, const opt_t *opts)
 {
        const bool generic = opts->input_api == INPUT_CUSTOM;
        const std::string
@@ -347,7 +347,7 @@ void gen_settags(code_lines_t &code, const DFA &dfa, tcid_t tcid, Opt &opts)
 
 void gen_fintags(OutputFile &o, uint32_t ind, const DFA &dfa, const Rule &rule)
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        const bool generic = opts->input_api == INPUT_CUSTOM;
        const std::string
                &prefix = opts->tags_prefix,
index 2fecac96e3fb0d9176231ccb915081356b1673d2..3989cbfe7d61251fe093aaa4fc1335833e077d50 100644 (file)
@@ -24,7 +24,7 @@ static void emit_state(OutputFile & o, uint32_t ind, const State * s, bool used_
 
 void emit_state (OutputFile & o, uint32_t ind, const State * s, bool used_label)
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        if (used_label)
        {
                o.wstring(opts->labelPrefix).wlabel(s->label).ws(":\n");
@@ -69,7 +69,7 @@ void DFA::emit_body(OutputFile &o, uint32_t& ind,
        // has a piece of code that advances input position. Wee must
        // skip it when entering DFA.
        if (used_labels.count(head->label)) {
-               o.wind(ind).ws("goto ").wstring(o.opts->labelPrefix)
+               o.wind(ind).ws("goto ").wstring(o.block().opts->labelPrefix)
                        .wlabel(initial).ws(";\n");
        }
 
@@ -82,7 +82,7 @@ void DFA::emit_body(OutputFile &o, uint32_t& ind,
 
 void DFA::emit_dot(OutputFile &o, bool last_cond) const
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        if (!opts->cFlag || !o.cond_goto) {
                o.ws("digraph re2c {\n");
        }
@@ -119,7 +119,7 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra
 {
        OutputFile &o = output.source;
        OutputBlock &ob = o.block();
-       Opt &opts = o.opts;
+       const opt_t *opts = ob.opts;
 
        std::set<std::string> tagnames, tagvars;
        if (!oldstyle_ctxmarker) {
@@ -158,7 +158,8 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra
                s->label = o.label_counter.next ();
        }
        std::set<label_t> used_labels;
-       count_used_labels (used_labels, start_label, initial_label, ob.force_start_label, opts->fFlag);
+       count_used_labels (used_labels, start_label, initial_label,
+               opts->startlabel_force && opts->startlabel.empty(), opts->fFlag);
 
        head->action.set_initial(initial_label);
 
index fa99ce2614cba452012862075ddc06a75497f547..2340c167caecfef6598bd90ef39ca908c418066f 100644 (file)
@@ -214,7 +214,7 @@ struct Go
 
        Go ();
        ~Go ();
-       void init(const State* from, Opt &opts, bitmaps_t &bitmaps);
+       void init(const State* from, const opt_t *opts, bitmaps_t &bitmaps);
        void emit (OutputFile & o, uint32_t ind, const DFA &dfa);
        void used_labels (std::set<label_t> & used);
 
index 2895270947ccd788cf338e6ad154dd15abe26ecf..b84cf971d773a5b4150a1716351025bcabbcc579 100644 (file)
@@ -192,7 +192,7 @@ Go::Go ()
        , info ()
 {}
 
-void Go::init (const State * from, Opt &opts, bitmaps_t &bitmaps)
+void Go::init(const State *from, const opt_t *opts, bitmaps_t &bitmaps)
 {
        if (nSpans == 0)
        {
index 6a0d9729662cfe42f795d978381eb9fc6f5a6007..5a711ea56ffbced0aae4f25a601eed25ed080393 100644 (file)
@@ -22,12 +22,12 @@ static std::string output_hgo (OutputFile & o, uint32_t ind, const DFA &dfa, Swi
 
 void output_if (OutputFile & o, uint32_t ind, const std::string & compare, uint32_t value)
 {
-       o.wind(ind).ws("if (").wstring(o.opts->yych).ws(" ").wstring(compare).ws(" ").wc_hex (value).ws(") ");
+       o.wind(ind).ws("if (").wstring(o.block().opts->yych).ws(" ").wstring(compare).ws(" ").wc_hex (value).ws(") ");
 }
 
 std::string output_hgo (OutputFile & o, uint32_t ind, const DFA &dfa, SwitchIf * hgo)
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        std::string yych = opts->yych;
        if (hgo != NULL)
        {
@@ -45,7 +45,7 @@ std::string output_hgo (OutputFile & o, uint32_t ind, const DFA &dfa, SwitchIf *
 
 void Case::emit (OutputFile & o, uint32_t ind) const
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        for (uint32_t i = 0; i < ranges.size (); ++i)
        {
                for (uint32_t b = ranges[i].first; b < ranges[i].second; ++b)
@@ -68,7 +68,7 @@ void Case::emit (OutputFile & o, uint32_t ind) const
 
 void Cases::emit(OutputFile &o, uint32_t ind, const DFA &dfa) const
 {
-       o.wind(ind).ws("switch (").wstring(o.opts->yych).ws(") {\n");
+       o.wind(ind).ws("switch (").wstring(o.block().opts->yych).ws(") {\n");
 
        for (uint32_t i = 1; i < cases_size; ++i) {
                const Case &c = cases[i];
@@ -126,7 +126,7 @@ void SwitchIf::emit(OutputFile &o, uint32_t ind, const DFA &dfa)
 
 void GoBitmap::emit (OutputFile & o, uint32_t ind, const DFA &dfa)
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        std::string yych = output_hgo (o, ind, dfa, hgo);
        o.ws("if (").wstring(opts->yybm).ws("[").wu32(bitmap->i).ws("+").wstring(yych).ws("] & ");
        if (opts->yybmHexTable)
@@ -161,7 +161,7 @@ label_t CpgotoTable::max_label () const
 
 void CpgotoTable::emit (OutputFile & o, uint32_t ind)
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        o.wind(ind).ws("static void *").wstring(opts->yytarget).ws("[256] = {\n");
        o.wind(++ind);
        const uint32_t max_digits = max_label ().width ();
@@ -190,13 +190,13 @@ void Cpgoto::emit (OutputFile & o, uint32_t ind, const DFA &dfa)
        std::string yych = output_hgo (o, ind, dfa, hgo);
        o.ws("{\n");
        table->emit (o, ++ind);
-       o.wind(ind).ws("goto *").wstring(o.opts->yytarget).ws("[").wstring(yych).ws("];\n");
+       o.wind(ind).ws("goto *").wstring(o.block().opts->yytarget).ws("[").wstring(yych).ws("];\n");
        o.wind(--ind).ws("}\n");
 }
 
 void Dot::emit(OutputFile &o, const DFA &dfa)
 {
-       const std::string &prefix = o.opts->tags_prefix;
+       const std::string &prefix = o.block().opts->tags_prefix;
        const uint32_t n = cases->cases_size;
        if (n == 1) {
                o.wlabel(from->label).ws(" -> ").wlabel(cases->cases[0].to->label).ws("\n");
@@ -223,7 +223,7 @@ void Dot::emit(OutputFile &o, const DFA &dfa)
 void Go::emit (OutputFile & o, uint32_t ind, const DFA &dfa)
 {
        code_lines_t code;
-       gen_settags(code, dfa, tags, o.opts);
+       gen_settags(code, dfa, tags, o.block().opts);
        for (size_t i = 0; i < code.size(); ++i) {
                o.wind(ind).wstring(code[i]);
        }
index 1c952b4d426f20b6027f69f333098698e26b822c..68fc5c3c98ed1410b8a830d551ae0e019d6c6e2f 100644 (file)
@@ -7,14 +7,14 @@
 namespace re2c
 {
 
-std::string output_expr_peek(Opt &opts)
+std::string output_expr_peek(const opt_t *opts)
 {
        return opts->input_api == INPUT_DEFAULT
                ? "*" + opts->yycursor
                : opts->yypeek + " ()";
 }
 
-std::string output_restore(uint32_t ind, Opt &opts)
+std::string output_restore(uint32_t ind, const opt_t *opts)
 {
        std::string s = opts->input_api == INPUT_DEFAULT
                ? opts->yycursor + " = " + opts->yymarker
@@ -22,7 +22,7 @@ std::string output_restore(uint32_t ind, Opt &opts)
        return indent(ind, opts->indString) + s + ";\n";
 }
 
-std::string output_expr_lessthan(size_t n, Opt &opts)
+std::string output_expr_lessthan(size_t n, const opt_t *opts)
 {
        std::ostringstream s;
        if (opts->input_api == INPUT_CUSTOM) {
index e4643b18e5fdfba8c421244de5651c589acb1890..00c26d627e63bd165062830c01b3f82f169de135 100644 (file)
@@ -7,7 +7,6 @@
 namespace re2c
 {
 
-struct Opt;
 struct opt_t;
 
 enum input_api_t
@@ -16,9 +15,9 @@ enum input_api_t
        INPUT_CUSTOM
 };
 
-std::string output_expr_peek     (Opt &opts);
-std::string output_restore       (uint32_t ind, Opt &opts);
-std::string output_expr_lessthan (size_t n, Opt &opts);
+std::string output_expr_peek     (const opt_t *opts);
+std::string output_restore       (uint32_t ind, const opt_t *opts);
+std::string output_expr_lessthan (size_t n, const opt_t *opts);
 
 void output_peek             (std::ostream &o, uint32_t ind, const opt_t *opts);
 void output_skip             (std::ostream &o, uint32_t ind, const opt_t *opts);
index 85b51e3df0d609756e4461d612261c494be3daf0..c06c1ae1ee0c5313cfd8c458c9415da7cabf4a0d 100644 (file)
@@ -42,8 +42,6 @@ uint32_t OutputFragment::count_lines ()
 OutputBlock::OutputBlock ()
        : fragments ()
        , used_yyaccept (false)
-       , force_start_label (false)
-       , user_start_label ()
        , line (0)
        , types ()
        , tags ()
@@ -61,14 +59,13 @@ OutputBlock::~OutputBlock ()
        delete opts;
 }
 
-OutputFile::OutputFile(Opt &o, Warn &w)
+OutputFile::OutputFile(bool tflag, Warn &w)
        : blocks ()
        , label_counter ()
        , fill_index(0)
        , state_goto(false)
        , cond_goto(false)
-       , warn_condition_order (!o->tFlag) // see note [condition order]
-       , opts(o)
+       , warn_condition_order (!tflag) // see note [condition order]
        , warn(w)
 {}
 
@@ -99,13 +96,14 @@ OutputFile &OutputFile::wraw(const char *s, const char *e)
 OutputFile & OutputFile::wu32_hex (uint32_t n)
 {
        insert_code();
-       prtHex(stream(), n, opts->encoding.szCodeUnit());
+       prtHex(stream(), n, block().opts->encoding.szCodeUnit());
        return *this;
 }
 
 OutputFile & OutputFile::wc_hex (uint32_t n)
 {
        insert_code();
+       const opt_t *opts = block().opts;
        const Enc &e = opts->encoding;
        prtChOrHex(stream(), n, e.szCodeUnit(), e.type() == Enc::EBCDIC, opts->target == opt_t::DOT);
        return *this;
@@ -114,6 +112,7 @@ OutputFile & OutputFile::wc_hex (uint32_t n)
 OutputFile & OutputFile::wrange (uint32_t l, uint32_t u)
 {
        insert_code();
+       const opt_t *opts = block().opts;
        const Enc &e = opts->encoding;
        printSpan(stream(), l, u, e.szCodeUnit(), e.type() == Enc::EBCDIC, opts->target == opt_t::DOT);
        return *this;
@@ -130,22 +129,22 @@ OutputFile & OutputFile::wu32_width (uint32_t n, int w)
 OutputFile & OutputFile::wline_info (uint32_t l, const char * fn)
 {
        insert_code();
-       output_line_info (stream (), l, fn, opts->iFlag);
+       output_line_info (stream (), l, fn, block().opts->iFlag);
        return *this;
 }
 
 OutputFile & OutputFile::wversion_time ()
 {
        insert_code();
-       output_version_time (stream (), opts);
+       output_version_time(stream(), block().opts->version, !block().opts->bNoGenerationDate);
        return *this;
 }
 
 OutputFile & OutputFile::wuser_start_label ()
 {
        insert_code();
-       const std::string label = block().user_start_label;
-       if (!label.empty ())
+       const std::string label = block().opts->startlabel;
+       if (!label.empty())
        {
                wstring(label).ws(":\n");
        }
@@ -197,7 +196,7 @@ OutputFile & OutputFile::wlabel (label_t l)
 OutputFile & OutputFile::wind (uint32_t ind)
 {
        insert_code();
-       stream () << indent(ind, opts->indString);
+       stream () << indent(ind, block().opts->indString);
        return *this;
 }
 
@@ -224,7 +223,7 @@ OutputFile & OutputFile::wdelay_line_info ()
 
 OutputFile & OutputFile::wdelay_cond_goto(uint32_t ind)
 {
-       if (opts->cFlag && !cond_goto) {
+       if (block().opts->cFlag && !cond_goto) {
                block().fragments.push_back(new OutputFragment(OutputFragment::COND_GOTO, ind));
                cond_goto = true;
        }
@@ -233,7 +232,7 @@ OutputFile & OutputFile::wdelay_cond_goto(uint32_t ind)
 
 OutputFile & OutputFile::wdelay_cond_table(uint32_t ind)
 {
-       if (opts->gFlag && opts->cFlag && !cond_goto) {
+       if (block().opts->gFlag && block().opts->cFlag && !cond_goto) {
                block().fragments.push_back(new OutputFragment(OutputFragment::COND_TABLE, ind));
        }
        return *this;
@@ -241,7 +240,7 @@ OutputFile & OutputFile::wdelay_cond_table(uint32_t ind)
 
 OutputFile & OutputFile::wdelay_state_goto (uint32_t ind)
 {
-       if (opts->fFlag && !state_goto) {
+       if (block().opts->fFlag && !state_goto) {
                block().fragments.push_back (new OutputFragment (OutputFragment::STATE_GOTO, ind));
                state_goto = true;
        }
@@ -294,9 +293,15 @@ OutputFile& OutputFile::wdelay_backup(uint32_t ind, bool backup)
        return *this;
 }
 
-void OutputFile::new_block ()
+void OutputFile::new_block(Opt &opts)
 {
-       blocks.push_back (new OutputBlock ());
+       OutputBlock *b = new OutputBlock;
+       b->opts = opts.snapshot();
+       blocks.push_back(b);
+
+       // start label hapens to be the only option
+       // that must be reset for each new block
+       opts.reset_startlabel();
 }
 
 void OutputFile::global_lists(
@@ -379,7 +384,7 @@ bool OutputFile::emit(const uniq_vector_t<std::string> &global_types,
        size_t max_fill)
 {
        FILE *file = NULL;
-       std::string filename = opts->output_file;
+       std::string filename = block().opts->output_file;
        if (filename.empty()) {
                filename = "<stdout>";
                file = stdout;
@@ -426,7 +431,7 @@ bool OutputFile::emit(const uniq_vector_t<std::string> &global_types,
                                output_tags(o, *f.tags, global_tags);
                                break;
                        case OutputFragment::TYPES:
-                               output_types(o, ind, global_types, opts);
+                               output_types(o, ind, block().opts, global_types);
                                break;
                        case OutputFragment::YYACCEPT_INIT:
                                output_yyaccept_init(o, ind, b.used_yyaccept, bopt);
@@ -476,7 +481,7 @@ bool OutputFile::emit(const uniq_vector_t<std::string> &global_types,
        return true;
 }
 
-bool HeaderFile::emit(const uniq_vector_t<std::string> &types, Opt &opts)
+bool HeaderFile::emit(const opt_t *opts, const uniq_vector_t<std::string> &types)
 {
        if (!opts->tFlag) {
                return true;
@@ -495,10 +500,10 @@ bool HeaderFile::emit(const uniq_vector_t<std::string> &types, Opt &opts)
                }
        }
 
-       output_version_time(stream, opts);
+       output_version_time(stream, opts->version, !opts->bNoGenerationDate);
        output_line_info(stream, 3, filename, opts->iFlag);
        stream << "\n";
-       output_types(stream, 0, types, opts);
+       output_types(stream, 0, opts, types);
 
        std::string content = stream.str();
        fwrite(content.c_str(), 1, content.size(), file);
@@ -507,8 +512,8 @@ bool HeaderFile::emit(const uniq_vector_t<std::string> &types, Opt &opts)
        return true;
 }
 
-Output::Output(Opt &o, Warn &w)
-       : source(o, w)
+Output::Output(bool tflag, Warn &w)
+       : source(tflag, w)
        , header()
        , skeletons()
        , max_fill(1)
@@ -524,8 +529,11 @@ bool Output::emit()
        std::set<std::string> tags;
        source.global_lists(types, tags);
 
+       // global options are last block's options
+       const opt_t *opts = source.block().opts;
+
        return source.emit(types, tags, max_fill)
-               && header.emit(types, source.opts);
+               && header.emit(opts, types);
 }
 
 void output_tags(std::ostream &o, const ConfTags &conf,
@@ -596,10 +604,8 @@ void output_line_info(std::ostream &o, uint32_t line,
        }
 }
 
-void output_types(
-       std::ostream &o,
-       uint32_t ind,
-       const uniq_vector_t<std::string> &types, Opt &opts)
+void output_types(std::ostream &o, uint32_t ind, const opt_t *opts,
+       const uniq_vector_t<std::string> &types)
 {
        const std::string indstr = opts->indString;
        o << indent(ind++, indstr) << "enum " << opts->yycondtype << " {\n";
@@ -609,15 +615,13 @@ void output_types(
        o << indent(--ind, indstr) << "};\n";
 }
 
-void output_version_time (std::ostream & o, Opt &opts)
+void output_version_time(std::ostream &o, bool version, bool date)
 {
        o << "/* Generated by re2c";
-       if (opts->version)
-       {
+       if (version) {
                o << " " << PACKAGE_VERSION;
        }
-       if (!opts->bNoGenerationDate)
-       {
+       if (date) {
                o << " on ";
                time_t now = time (NULL);
                o.write (ctime (&now), 24);
index dce545f4f2d2251392c9b487a7ab31d57985a4ed..7fa60f3f0e29b7b0a06e14c6351094f4fad766f0 100644 (file)
@@ -72,8 +72,6 @@ struct OutputBlock
 {
        std::vector<OutputFragment *> fragments;
        bool used_yyaccept;
-       bool force_start_label;
-       std::string user_start_label;
        uint32_t line;
        std::vector<std::string> types;
        std::set<std::string> tags;
@@ -94,17 +92,16 @@ public:
        bool state_goto;
        bool cond_goto;
        bool warn_condition_order;
-       Opt &opts;
        Warn &warn;
 
-       OutputFile(Opt &o, Warn &w);
+       OutputFile(bool tflag, Warn &w);
        ~OutputFile();
 
        std::ostream & stream ();
        OutputBlock &block();
        void insert_code ();
        bool open ();
-       void new_block ();
+       void new_block(Opt &opts);
 
        // immediate output
        OutputFile & wraw (const char *s, const char *e);
@@ -151,7 +148,7 @@ class HeaderFile
 
 public:
        HeaderFile(): stream() {}
-       bool emit(const uniq_vector_t<std::string> &types, Opt &opts);
+       bool emit(const opt_t *opts, const uniq_vector_t<std::string> &types);
        FORBID_COPY (HeaderFile);
 };
 
@@ -162,7 +159,7 @@ struct Output
        std::set<std::string> skeletons;
        size_t max_fill;
 
-       Output(Opt &o, Warn &w);
+       Output(bool tflag, Warn &w);
        bool emit();
 };
 
@@ -171,8 +168,8 @@ void output_line_info     (std::ostream &o, uint32_t line, const std::string &fn
 void output_cond_goto     (std::ostream &o, uint32_t ind, const std::vector<std::string> &conds, const opt_t *opts, Warn &warn, bool warn_cond_order, uint32_t line);
 void output_cond_table    (std::ostream &o, uint32_t ind, const std::vector<std::string> &conds, const opt_t *opts);
 void output_state_goto    (std::ostream &o, uint32_t ind, uint32_t start_label, uint32_t fill_index, const opt_t *opts);
-void output_types         (std::ostream &o, uint32_t ind, const uniq_vector_t<std::string> &types, Opt &opts);
-void output_version_time  (std::ostream &o, Opt &opts);
+void output_types         (std::ostream &o, uint32_t ind, const opt_t *opts, const uniq_vector_t<std::string> &types);
+void output_version_time  (std::ostream &o, bool version, bool date);
 void output_yyaccept_init (std::ostream &o, uint32_t ind, bool, const opt_t *opts);
 void output_yymaxfill     (std::ostream &o, size_t max_fill);
 
index b655ba3948cbaa7085be389fb2b8007a8dfeeb24..e29f268e22a4c3260be5f7018668f2635658a48c 100644 (file)
@@ -111,6 +111,8 @@ void opt_t::fix ()
                        fill_arg_use = Opt::baseopt.fill_arg_use;
                        fill_naked = Opt::baseopt.fill_naked;
                        labelPrefix = Opt::baseopt.labelPrefix;
+                       startlabel = Opt::baseopt.startlabel;
+                       startlabel_force = Opt::baseopt.startlabel_force;
                        dump_dfa_raw = Opt::baseopt.dump_dfa_raw;
                        dump_dfa_det = Opt::baseopt.dump_dfa_det;
                        dump_dfa_tagopt = Opt::baseopt.dump_dfa_tagopt;
@@ -300,6 +302,12 @@ void Opt::reset_encoding (const Enc & enc)
        useropt->encoding = enc;
 }
 
+void Opt::reset_startlabel()
+{
+       useropt->startlabel       = Opt::baseopt.startlabel;
+       useropt->startlabel_force = Opt::baseopt.startlabel_force;
+}
+
 void Opt::reset_mapCodeName ()
 {
        // historically arranged set of names
index 6d2372036092c6d61c9a5c33f8563404209ba486..40799208e185ae2df075957fa35bb54b6235388f 100644 (file)
@@ -112,6 +112,8 @@ namespace re2c
        OPT (bool, fill_naked, false) \
        /* labels */ \
        OPT (std::string, labelPrefix, "yy") \
+       OPT (std::string, startlabel, "") \
+       OPT (bool, startlabel_force, false) \
        /* internals */ \
        OPT (dfa_minimization_t, dfa_minimization, DFA_MINIMIZATION_MOORE) \
        OPT (bool, bijective_mapping, true) \
@@ -208,6 +210,7 @@ public:
 
        // bad temporary hacks, should be fixed by proper scoping of config (parts).
        void reset_encoding (const Enc & enc);
+       void reset_startlabel();
        void reset_mapCodeName ();
 
        FORBID_COPY (Opt);
index 7cb61bf91966dee964127485c22a923f7d4c08b3..f72cb6624d3c3438c7f726ef411d04e2400078db 100644 (file)
@@ -94,7 +94,7 @@ struct DFA
                );
        ~DFA ();
        void reorder();
-       void prepare(Opt &opts);
+       void prepare(const opt_t *opts);
        void calc_stats(uint32_t line, bool explicit_tags);
        void emit (Output &, uint32_t &, bool, bool &);
 
index 10c20fac6844686f42477998f20956f0547bdf65..551419d3513f1f314c46e1ef69ccf1ec198396c4 100644 (file)
@@ -99,7 +99,7 @@ void DFA::findBaseState()
        operator delete (span);
 }
 
-void DFA::prepare (Opt &opts)
+void DFA::prepare(const opt_t *opts)
 {
        // create rule states
        std::vector<State*> rule2state(rules.size());
index 89e0618943ed6ca899744460f681491bc65d5ba8..cf80dfd1c94024f924456172f6641a4fa80a319e 100644 (file)
@@ -29,7 +29,7 @@ static std::string make_name(const std::string &cond, uint32_t line)
 
 smart_ptr<DFA> compile(const spec_t &spec, Output &output)
 {
-       Opt &opts = output.source.opts;
+       const opt_t *opts = output.source.block().opts;
        Warn &warn = output.source.warn;
        const std::vector<RegExpRule> &rules = spec.rules;
        const size_t defrule = spec.defs.empty()
index d306c2c629e7f7080d3f2de62f8891715b8c35ba..fb8a5fcdfe2caa10392a347f5b2dc453c6c9757d 100644 (file)
@@ -97,7 +97,7 @@ void emit_start(OutputFile &o, size_t maxfill, const std::string &name,
        const std::set<std::string> &tagnames, const std::set<std::string> &tagvars,
        bitmaps_t &bitmaps)
 {
-       Opt &opts = o.opts;
+       const opt_t *opts = o.block().opts;
        const size_t sizeof_cunit = opts->encoding.szCodeUnit();
        const size_t norule = rule2key(Rule::NONE, sizeof_key, def);
        std::string filename = opts->output_file;
@@ -325,7 +325,7 @@ void emit_end(OutputFile &o, const std::string &name, bool backup, bool oldstyle
                o.ws("\n#undef YYBACKUPCTX");
                o.ws("\n#undef YYRESTORECTX");
        }
-       if (o.opts->tags) {
+       if (o.block().opts->tags) {
                o.ws("\n#undef YYBACKUPTAG");
                o.ws("\n#undef YYRESTORETAG");
                o.ws("\n#undef YYCOPYTAG");
index ed9b5f201b3c1e96bb8bfc281c5e5e030e1ab6d1..6018408c4dc6a1f46014ed58135da46cf8f88fa9 100644 (file)
@@ -32,10 +32,10 @@ int main(int, char *argv[])
        }
 
        // set up the output streams
-       re2c::Output output(opts, warn);
+       re2c::Output output(opts->tFlag, warn);
 
-       Scanner scanner (input, output.source);
-       parse (scanner, output);
+       Scanner scanner(input, output.source, opts);
+       parse(scanner, output);
        if (!output.emit()) {
                return 1;
        }
index 8807c3bf3a09bbd344e77a6064be0e3114ff64e1..8f1fa69f7165c973b81ff779e799bdc90eb29e64 100644 (file)
@@ -160,8 +160,8 @@ void Scanner::lex_conf ()
        "labelprefix" { opts.set_labelPrefix (lex_conf_string ()); return; }
 
        // try to lex number first, otherwize it would be lexed as a naked string
-       "startlabel" / conf_assign number { out.block().force_start_label = lex_conf_bool(); return; }
-       "startlabel"                      { out.block().user_start_label = lex_conf_string(); return; }
+       "startlabel" / conf_assign number { opts.set_startlabel_force (lex_conf_bool());   return; }
+       "startlabel"                      { opts.set_startlabel       (lex_conf_string()); return; }
 
        // deprecated
        "variable:yystable" { lex_conf_string (); return; }
index c42b7c2b15b5d23fae16101074e8ba5bb079e7f5..f7e1134fe54e65ca1dc0476f8074486c85996442 100644 (file)
@@ -431,9 +431,10 @@ void parse(Scanner &input, Output & o)
        ScannerState rules_state, curr_state;
        Opt &opts = input.opts;
 
-       o.source.new_block();
-       o.source.wversion_time ()
-               .wline_info (input.get_cline (), input.get_fname ().c_str ());
+       o.source.new_block(opts);
+
+       o.source.wversion_time()
+               .wline_info(input.get_cline(), input.get_fname().c_str());
        if (opts->target == opt_t::SKELETON)
        {
                emit_prolog (o.source);
@@ -442,9 +443,6 @@ void parse(Scanner &input, Output & o)
        Enc encodingOld = opts->encoding;
        for (Scanner::ParseMode mode; (mode = input.echo()) != Scanner::Stop;) {
 
-               o.source.block().opts = opts.snapshot();
-               o.source.new_block();
-
                input.save_state(curr_state);
                if (opts->rFlag && mode == Scanner::Rules && !dfas.empty())
                {
@@ -489,6 +487,9 @@ void parse(Scanner &input, Output & o)
                        encodingOld = opts->encoding;
                }
 
+               // start new output block with accumulated options
+               o.source.new_block(opts);
+
                // compile regular expressions to automata
                if (mode != Scanner::Reuse) {
                        check(specs, opts->cFlag);
@@ -517,7 +518,6 @@ void parse(Scanner &input, Output & o)
        {
                emit_epilog (o.source, o.skeletons);
        }
-       o.source.block().opts = opts.snapshot();
 
        RegExp::flist.clear();
        Code::flist.clear();
index 32462573fb0ed6f35d57f2a226b83dc76883af94..e92ceaac23349b865731453c8690ce1a104167bc 100644 (file)
@@ -56,11 +56,11 @@ ScannerState & ScannerState::operator = (const ScannerState & s)
        return * this;
 }
 
-Scanner::Scanner (Input & i, OutputFile & o)
+Scanner::Scanner (Input & i, OutputFile & o, Opt &p)
        : ScannerState ()
        , in (i)
        , out (o)
-       , opts (o.opts)
+       , opts (p)
        , warn (o.warn)
 {}
 
index c6ca91ebb13baddbc99c4b8fdafb9fa0b03c8182..d8a78c98a24f06f04d19f54702cd383a3dc5b6da 100644 (file)
@@ -87,7 +87,7 @@ private:
        size_t tok_len () const;
 
 public:
-       Scanner(Input &, OutputFile &);
+       Scanner(Input &, OutputFile &, Opt &);
        ~Scanner();
 
        enum ParseMode {
index 9269dad11d9e131325bcc0ae865af57e2e8a5882..c268bf222a0f93e474867b0407dd1a2662dd48a8 100644 (file)
@@ -150,7 +150,6 @@ int lex_line261()
         token = cursor;
         YYCTYPE yych;
 
-yy0:
         if (YYLESSTHAN (7)) YYFILL(7);
         yych = YYPEEK ();
         switch (yych) {