From: Ulya Trofimovich Date: Sun, 1 Jan 2017 18:47:06 +0000 (+0000) Subject: Consistently use current block's options for code generation. X-Git-Tag: 1.0~39^2~153 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aa4aa2e673585f1e6f45771930aa53b3a0fc0806;p=re2c Consistently use current block's options for code generation. --- diff --git a/re2c/bootstrap/src/parse/lex.cc b/re2c/bootstrap/src/parse/lex.cc index 3dc2caac..0580479f 100644 --- a/re2c/bootstrap/src/parse/lex.cc +++ b/re2c/bootstrap/src/parse/lex.cc @@ -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 diff --git a/re2c/bootstrap/src/parse/lex_conf.cc b/re2c/bootstrap/src/parse/lex_conf.cc index ead68c73..9044a370 100644 --- a/re2c/bootstrap/src/parse/lex_conf.cc +++ b/re2c/bootstrap/src/parse/lex_conf.cc @@ -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 @@ -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; diff --git a/re2c/bootstrap/src/parse/parser.cc b/re2c/bootstrap/src/parse/parser.cc index 397897ec..6cce158d 100644 --- a/re2c/bootstrap/src/parse/parser.cc +++ b/re2c/bootstrap/src/parse/parser.cc @@ -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(); diff --git a/re2c/src/codegen/bitmap.cc b/re2c/src/codegen/bitmap.cc index fa8ba437..e6f1d1bc 100644 --- a/re2c/src/codegen/bitmap.cc +++ b/re2c/src/codegen/bitmap.cc @@ -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(maps.size()); riter_t b = maps.rbegin(), e = maps.rend(); diff --git a/re2c/src/codegen/emit.h b/re2c/src/codegen/emit.h index 171460c1..8733bf36 100644 --- a/re2c/src/codegen/emit.h +++ b/re2c/src/codegen/emit.h @@ -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); diff --git a/re2c/src/codegen/emit_action.cc b/re2c/src/codegen/emit_action.cc index d2b2b24d..ab4f8ada 100644 --- a/re2c/src/codegen/emit_action.cc +++ b/re2c/src/codegen/emit_action.cc @@ -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 &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, diff --git a/re2c/src/codegen/emit_dfa.cc b/re2c/src/codegen/emit_dfa.cc index 2fecac96..3989cbfe 100644 --- a/re2c/src/codegen/emit_dfa.cc +++ b/re2c/src/codegen/emit_dfa.cc @@ -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 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 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); diff --git a/re2c/src/codegen/go.h b/re2c/src/codegen/go.h index fa99ce26..2340c167 100644 --- a/re2c/src/codegen/go.h +++ b/re2c/src/codegen/go.h @@ -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 & used); diff --git a/re2c/src/codegen/go_construct.cc b/re2c/src/codegen/go_construct.cc index 28952709..b84cf971 100644 --- a/re2c/src/codegen/go_construct.cc +++ b/re2c/src/codegen/go_construct.cc @@ -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) { diff --git a/re2c/src/codegen/go_emit.cc b/re2c/src/codegen/go_emit.cc index 6a0d9729..5a711ea5 100644 --- a/re2c/src/codegen/go_emit.cc +++ b/re2c/src/codegen/go_emit.cc @@ -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]); } diff --git a/re2c/src/codegen/input_api.cc b/re2c/src/codegen/input_api.cc index 1c952b4d..68fc5c3c 100644 --- a/re2c/src/codegen/input_api.cc +++ b/re2c/src/codegen/input_api.cc @@ -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) { diff --git a/re2c/src/codegen/input_api.h b/re2c/src/codegen/input_api.h index e4643b18..00c26d62 100644 --- a/re2c/src/codegen/input_api.h +++ b/re2c/src/codegen/input_api.h @@ -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); diff --git a/re2c/src/codegen/output.cc b/re2c/src/codegen/output.cc index 85b51e3d..c06c1ae1 100644 --- a/re2c/src/codegen/output.cc +++ b/re2c/src/codegen/output.cc @@ -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 &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 = ""; file = stdout; @@ -426,7 +431,7 @@ bool OutputFile::emit(const uniq_vector_t &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 &global_types, return true; } -bool HeaderFile::emit(const uniq_vector_t &types, Opt &opts) +bool HeaderFile::emit(const opt_t *opts, const uniq_vector_t &types) { if (!opts->tFlag) { return true; @@ -495,10 +500,10 @@ bool HeaderFile::emit(const uniq_vector_t &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 &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 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 &types, Opt &opts) +void output_types(std::ostream &o, uint32_t ind, const opt_t *opts, + const uniq_vector_t &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); diff --git a/re2c/src/codegen/output.h b/re2c/src/codegen/output.h index dce545f4..7fa60f3f 100644 --- a/re2c/src/codegen/output.h +++ b/re2c/src/codegen/output.h @@ -72,8 +72,6 @@ struct OutputBlock { std::vector fragments; bool used_yyaccept; - bool force_start_label; - std::string user_start_label; uint32_t line; std::vector types; std::set 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 &types, Opt &opts); + bool emit(const opt_t *opts, const uniq_vector_t &types); FORBID_COPY (HeaderFile); }; @@ -162,7 +159,7 @@ struct Output std::set 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 &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 &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 &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 &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); diff --git a/re2c/src/conf/opt.cc b/re2c/src/conf/opt.cc index b655ba39..e29f268e 100644 --- a/re2c/src/conf/opt.cc +++ b/re2c/src/conf/opt.cc @@ -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 diff --git a/re2c/src/conf/opt.h b/re2c/src/conf/opt.h index 6d237203..40799208 100644 --- a/re2c/src/conf/opt.h +++ b/re2c/src/conf/opt.h @@ -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); diff --git a/re2c/src/ir/adfa/adfa.h b/re2c/src/ir/adfa/adfa.h index 7cb61bf9..f72cb662 100644 --- a/re2c/src/ir/adfa/adfa.h +++ b/re2c/src/ir/adfa/adfa.h @@ -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 &); diff --git a/re2c/src/ir/adfa/prepare.cc b/re2c/src/ir/adfa/prepare.cc index 10c20fac..551419d3 100644 --- a/re2c/src/ir/adfa/prepare.cc +++ b/re2c/src/ir/adfa/prepare.cc @@ -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 rule2state(rules.size()); diff --git a/re2c/src/ir/compile.cc b/re2c/src/ir/compile.cc index 89e06189..cf80dfd1 100644 --- a/re2c/src/ir/compile.cc +++ b/re2c/src/ir/compile.cc @@ -29,7 +29,7 @@ static std::string make_name(const std::string &cond, uint32_t line) smart_ptr 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 &rules = spec.rules; const size_t defrule = spec.defs.empty() diff --git a/re2c/src/ir/skeleton/generate_code.cc b/re2c/src/ir/skeleton/generate_code.cc index d306c2c6..fb8a5fcd 100644 --- a/re2c/src/ir/skeleton/generate_code.cc +++ b/re2c/src/ir/skeleton/generate_code.cc @@ -97,7 +97,7 @@ void emit_start(OutputFile &o, size_t maxfill, const std::string &name, const std::set &tagnames, const std::set &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"); diff --git a/re2c/src/main.cc b/re2c/src/main.cc index ed9b5f20..6018408c 100644 --- a/re2c/src/main.cc +++ b/re2c/src/main.cc @@ -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; } diff --git a/re2c/src/parse/lex_conf.re b/re2c/src/parse/lex_conf.re index 8807c3bf..8f1fa69f 100644 --- a/re2c/src/parse/lex_conf.re +++ b/re2c/src/parse/lex_conf.re @@ -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; } diff --git a/re2c/src/parse/parser.ypp b/re2c/src/parse/parser.ypp index c42b7c2b..f7e1134f 100644 --- a/re2c/src/parse/parser.ypp +++ b/re2c/src/parse/parser.ypp @@ -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(); diff --git a/re2c/src/parse/scanner.cc b/re2c/src/parse/scanner.cc index 32462573..e92ceaac 100644 --- a/re2c/src/parse/scanner.cc +++ b/re2c/src/parse/scanner.cc @@ -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) {} diff --git a/re2c/src/parse/scanner.h b/re2c/src/parse/scanner.h index c6ca91eb..d8a78c98 100644 --- a/re2c/src/parse/scanner.h +++ b/re2c/src/parse/scanner.h @@ -87,7 +87,7 @@ private: size_t tok_len () const; public: - Scanner(Input &, OutputFile &); + Scanner(Input &, OutputFile &, Opt &); ~Scanner(); enum ParseMode { diff --git a/re2c/test/push.--skeleton.c b/re2c/test/push.--skeleton.c index 9269dad1..c268bf22 100644 --- a/re2c/test/push.--skeleton.c +++ b/re2c/test/push.--skeleton.c @@ -150,7 +150,6 @@ int lex_line261() token = cursor; YYCTYPE yych; -yy0: if (YYLESSTHAN (7)) YYFILL(7); yych = YYPEEK (); switch (yych) {