From 8273692408156dfef87ded5c334ed3170d40132e Mon Sep 17 00:00:00 2001 From: Ulya Trofimovich Date: Tue, 5 Apr 2016 23:01:33 +0100 Subject: [PATCH] Moved conditions and contexts from global scope to block scope. Directives like '/*!re2c:types*/' and '/*!re2c:contexts*/' have global scope, they are not binded to any particular block and therefore accumulate items (conditions/contexts/etc.) from the whole program. There's currently no way to bind these directives to a particular block (re2c will probably add scoping rules in future). However, things like default context declaration or condition dispatch have block scope (it's only natural that they are binded to the block that generates them). Unrelated change: context marker should be set for each condition, re2c must generate it after condition label: this way code that skips condition dispatch and jums directly to condition label will still have context marker adjusted properly. --- re2c/bootstrap/src/parse/lex.cc | 2 +- re2c/bootstrap/src/parse/lex_conf.cc | 6 +- re2c/bootstrap/src/parse/parser.cc | 4 +- re2c/src/codegen/emit_dfa.cc | 23 ++-- re2c/src/codegen/output.cc | 110 ++++++++---------- re2c/src/codegen/output.h | 23 ++-- re2c/src/ir/compile.cc | 4 +- re2c/src/parse/lex_conf.re | 4 +- re2c/src/parse/parser.ypp | 4 +- .../contexts/cond_star0.ci--input(custom).c | 2 +- re2c/test/contexts/cond_star0.ci.c | 2 +- .../contexts/cond_star1.ci--input(custom).c | 2 +- re2c/test/contexts/cond_star1.ci.c | 2 +- re2c/test/contexts/cond_star2.ci.c | 3 +- 14 files changed, 91 insertions(+), 100 deletions(-) diff --git a/re2c/bootstrap/src/parse/lex.cc b/re2c/bootstrap/src/parse/lex.cc index ff7ff99f..ced8ae14 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 Sun Apr 3 08:30:42 2016 */ +/* Generated by re2c 0.16 on Tue Apr 5 23:00:02 2016 */ #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 48ba8d2f..c851a55b 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 Tue Apr 5 11:39:03 2016 */ +/* Generated by re2c 0.16 on Tue Apr 5 23:00:02 2016 */ #line 1 "../src/parse/lex_conf.re" #include "src/util/c99_stdint.h" #include @@ -1324,7 +1324,7 @@ yy272: if (yych == '=') goto yy334; yy273: #line 163 "../src/parse/lex_conf.re" - { out.set_user_start_label (lex_conf_string ()); return; } + { out.block().user_start_label = lex_conf_string(); return; } #line 1329 "src/parse/lex_conf.cc" yy274: yych = (unsigned char)*++cur; @@ -1830,7 +1830,7 @@ yy395: yy396: cur = ctx; #line 162 "../src/parse/lex_conf.re" - { out.set_force_start_label (lex_conf_bool()); return; } + { out.block().force_start_label = lex_conf_bool(); return; } #line 1835 "src/parse/lex_conf.cc" yy397: ++cur; diff --git a/re2c/bootstrap/src/parse/parser.cc b/re2c/bootstrap/src/parse/parser.cc index 7793fac4..714eb1bf 100644 --- a/re2c/bootstrap/src/parse/parser.cc +++ b/re2c/bootstrap/src/parse/parser.cc @@ -2211,7 +2211,7 @@ void parse(Scanner& i, Output & o) } encodingOld = opts->encoding; } - o.source.set_block_line (in->get_cline ()); + o.source.block().line = in->get_cline(); uint32_t ind = opts->topIndent; if (opts->cFlag) { @@ -2238,8 +2238,8 @@ void parse(Scanner& i, Output & o) // Note that "0" inserts first, which is important. condnames.insert (condnames.begin (), "0"); } - o.types = condnames; } + o.source.block().types = condnames; size_t nCount = specMap.size(); diff --git a/re2c/src/codegen/emit_dfa.cc b/re2c/src/codegen/emit_dfa.cc index 6bdf4c67..fa44bb86 100644 --- a/re2c/src/codegen/emit_dfa.cc +++ b/re2c/src/codegen/emit_dfa.cc @@ -142,7 +142,8 @@ void DFA::emit_dot( void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBrace) { - OutputFile & o = output.source; + OutputFile &o = output.source; + OutputBlock &ob = o.block(); std::set ctxnames; if (base_ctxmarker) { @@ -151,7 +152,7 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra ctxnames.insert(contexts[*i].name()); } } - output.contexts.insert(ctxnames.begin(), ctxnames.end()); + ob.contexts.insert(ctxnames.begin(), ctxnames.end()); } bool bProlog = (!opts->cFlag || !bWroteCondCheck); @@ -170,7 +171,7 @@ 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, o.get_force_start_label ()); + count_used_labels (used_labels, start_label, initial_label, ob.force_start_label); head->action.set_initial (initial_label, head->action.type == Action::SAVE); @@ -188,13 +189,13 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra emit_end(*skeleton, o, need_backup, need_backupctx); } } else if (opts->target == opt_t::DOT) { - emit_dot(o, isLastCond, output.types); + emit_dot(o, isLastCond, ob.types); } else { // Generate prolog if (bProlog) { o.ws("\n").wdelay_line_info (); - if ((!opts->fFlag && o.get_used_yyaccept ()) + if ((!opts->fFlag && ob.used_yyaccept) || (!opts->fFlag && opts->bEmitYYCh) || (opts->bFlag && !opts->cFlag && BitMap::first) || (opts->cFlag && !bWroteCondCheck && opts->gFlag) @@ -215,10 +216,7 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra o.wind(ind).wstring(opts->yyctype).ws(" ").wstring(opts->yych).ws(";\n"); } o.wdelay_yyaccept_init (ind); - if (base_ctxmarker) { - o.wdelay_contexts(ind, NULL); - o.wstring(opts->input_api.stmt_backupctx(ind)); - } + o.wdelay_contexts(ind, NULL); } else { @@ -233,7 +231,7 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra { if (opts->cFlag && !bWroteCondCheck && opts->gFlag) { - genCondTable(o, ind, output.types); + genCondTable(o, ind, ob.types); } o.wdelay_state_goto (ind); if (opts->cFlag) @@ -246,7 +244,7 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra o.wuser_start_label (); if (opts->cFlag && !bWroteCondCheck) { - genCondGoto(o, ind, output.types); + genCondGoto(o, ind, ob.types); } } if (opts->cFlag && !cond.empty()) @@ -259,6 +257,9 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra } o.wstring(opts->condPrefix).wstring(cond).ws(":\n"); } + if (base_ctxmarker) { + o.wstring(opts->input_api.stmt_backupctx(ind)); + } if (opts->cFlag && opts->bFlag && BitMap::first) { o.wind(ind++).ws("{\n"); diff --git a/re2c/src/codegen/output.cc b/re2c/src/codegen/output.cc index 182533cf..983a0a93 100644 --- a/re2c/src/codegen/output.cc +++ b/re2c/src/codegen/output.cc @@ -47,6 +47,8 @@ OutputBlock::OutputBlock () , force_start_label (false) , user_start_label () , line (0) + , types () + , contexts () { fragments.push_back (new OutputFragment (OutputFragment::CODE, 0)); } @@ -96,9 +98,14 @@ OutputFile::~OutputFile () } } +OutputBlock& OutputFile::block() +{ + return *blocks.back(); +} + std::ostream & OutputFile::stream () { - return blocks.back ()->fragments.back ()->stream; + return block().fragments.back ()->stream; } OutputFile &OutputFile::wraw(const char *s, const char *e) @@ -146,7 +153,7 @@ OutputFile & OutputFile::wversion_time () OutputFile & OutputFile::wuser_start_label () { - const std::string label = blocks.back ()->user_start_label; + const std::string label = block().user_start_label; if (!label.empty ()) { wstring(label).ws(":\n"); @@ -198,7 +205,7 @@ OutputFile & OutputFile::wind (uint32_t ind) void OutputFile::insert_code () { - blocks.back ()->fragments.push_back (new OutputFragment (OutputFragment::CODE, 0)); + block().fragments.push_back (new OutputFragment (OutputFragment::CODE, 0)); } OutputFile &OutputFile::wdelay_contexts(uint32_t ind, const ConfContexts *cf) @@ -215,7 +222,7 @@ OutputFile &OutputFile::wdelay_contexts(uint32_t ind, const ConfContexts *cf) OutputFile & OutputFile::wdelay_line_info () { - blocks.back ()->fragments.push_back (new OutputFragment (OutputFragment::LINE_INFO, 0)); + block().fragments.push_back (new OutputFragment (OutputFragment::LINE_INFO, 0)); insert_code (); return *this; } @@ -224,7 +231,7 @@ OutputFile & OutputFile::wdelay_state_goto (uint32_t ind) { if (opts->fFlag && !bWroteGetState) { - blocks.back ()->fragments.push_back (new OutputFragment (OutputFragment::STATE_GOTO, ind)); + block().fragments.push_back (new OutputFragment (OutputFragment::STATE_GOTO, ind)); insert_code (); bWroteGetState = true; } @@ -234,76 +241,57 @@ OutputFile & OutputFile::wdelay_state_goto (uint32_t ind) OutputFile & OutputFile::wdelay_types () { warn_condition_order = false; // see note [condition order] - blocks.back ()->fragments.push_back (new OutputFragment (OutputFragment::TYPES, 0)); + block().fragments.push_back (new OutputFragment (OutputFragment::TYPES, 0)); insert_code (); return *this; } OutputFile & OutputFile::wdelay_warn_condition_order () { - blocks.back ()->fragments.push_back (new OutputFragment (OutputFragment::WARN_CONDITION_ORDER, 0)); + block().fragments.push_back (new OutputFragment (OutputFragment::WARN_CONDITION_ORDER, 0)); insert_code (); return *this; } OutputFile & OutputFile::wdelay_yyaccept_init (uint32_t ind) { - blocks.back ()->fragments.push_back (new OutputFragment (OutputFragment::YYACCEPT_INIT, ind)); + block().fragments.push_back (new OutputFragment (OutputFragment::YYACCEPT_INIT, ind)); insert_code (); return *this; } OutputFile & OutputFile::wdelay_yymaxfill () { - blocks.back ()->fragments.push_back (new OutputFragment (OutputFragment::YYMAXFILL, 0)); + block().fragments.push_back (new OutputFragment (OutputFragment::YYMAXFILL, 0)); insert_code (); return *this; } -void OutputFile::set_used_yyaccept () -{ - blocks.back ()->used_yyaccept = true; -} - -bool OutputFile::get_used_yyaccept () const -{ - return blocks.back ()->used_yyaccept; -} - -void OutputFile::set_force_start_label (bool force) -{ - blocks.back ()->force_start_label = force; -} - -void OutputFile::set_user_start_label (const std::string & label) -{ - blocks.back ()->user_start_label = label; -} - -bool OutputFile::get_force_start_label () const +void OutputFile::new_block () { - return blocks.back ()->force_start_label; + blocks.push_back (new OutputBlock ()); + insert_code (); } -void OutputFile::set_block_line (uint32_t l) +void OutputFile::global_lists( + uniq_vector_t &types, + std::set &contexts) const { - blocks.back ()->line = l; -} + for (unsigned int i = 0; i < blocks.size(); ++i) { -uint32_t OutputFile::get_block_line () const -{ - return blocks.back ()->line; -} + const std::vector &ts = blocks[i]->types; + for (size_t j = 0; j < ts.size(); ++j) { + types.find_or_add(ts[j]); + } -void OutputFile::new_block () -{ - blocks.push_back (new OutputBlock ()); - insert_code (); + const std::set &cs = blocks[i]->contexts; + contexts.insert(cs.begin(), cs.end()); + } } void OutputFile::emit( - const std::vector &types, - const std::set &contexts, + const uniq_vector_t &global_types, + const std::set &global_contexts, size_t max_fill) { if (file != NULL) @@ -321,9 +309,9 @@ void OutputFile::emit( break; case OutputFragment::CONTEXTS: if (f.contexts) { - output_contexts(f.stream, *f.contexts, contexts); + output_contexts(f.stream, *f.contexts, global_contexts); } else if (default_contexts) { - output_contexts_default(f.stream, f.indent, contexts); + output_contexts_default(f.stream, f.indent, b.contexts); } break; case OutputFragment::LINE_INFO: @@ -333,7 +321,7 @@ void OutputFile::emit( output_state_goto (f.stream, f.indent, 0); break; case OutputFragment::TYPES: - output_types (f.stream, f.indent, types); + output_types (f.stream, f.indent, global_types); break; case OutputFragment::WARN_CONDITION_ORDER: if (warn_condition_order) // see note [condition order] @@ -375,12 +363,12 @@ bool HeaderFile::open () return file != NULL; } -void HeaderFile::emit (const std::vector & types) +void HeaderFile::emit(const uniq_vector_t &types) { output_version_time (stream); output_line_info (stream, 3, file_name); stream << "\n"; - output_types (stream, 0, types); + output_types(stream, 0, types); } HeaderFile::~HeaderFile () @@ -396,9 +384,7 @@ HeaderFile::~HeaderFile () Output::Output(const std::string &source_name, const std::string &header_name) : source(source_name) , header(header_name) - , types() , skeletons() - , contexts() , max_fill(1) {} @@ -406,8 +392,12 @@ Output::~Output () { if (!warn.error ()) { - source.emit (types, contexts, max_fill); - header.emit (types); + uniq_vector_t types; + std::set contexts; + source.global_lists(types, contexts); + + source.emit(types, contexts, max_fill); + header.emit(types); } } @@ -487,14 +477,16 @@ void output_line_info (std::ostream & o, uint32_t line_number, const std::string } } -void output_types (std::ostream & o, uint32_t ind, const std::vector & types) +void output_types( + std::ostream &o, + uint32_t ind, + const uniq_vector_t &types) { - o << indent (ind++) << "enum " << opts->yycondtype << " {\n"; - for (unsigned int i = 0; i < types.size (); ++i) - { - o << indent (ind) << opts->condEnumPrefix << types[i] << ",\n"; + o << indent(ind++) << "enum " << opts->yycondtype << " {\n"; + for (size_t i = 0; i < types.size(); ++i) { + o << indent(ind) << opts->condEnumPrefix << types[i] << ",\n"; } - o << indent (--ind) << "};\n"; + o << indent(--ind) << "};\n"; } void output_version_time (std::ostream & o) diff --git a/re2c/src/codegen/output.h b/re2c/src/codegen/output.h index 641ecf46..63adfa36 100644 --- a/re2c/src/codegen/output.h +++ b/re2c/src/codegen/output.h @@ -13,6 +13,7 @@ #include "src/codegen/label.h" #include "src/util/counter.h" #include "src/util/forbid_copy.h" +#include "src/util/uniq_vector.h" namespace re2c { @@ -58,6 +59,8 @@ struct OutputBlock bool force_start_label; std::string user_start_label; uint32_t line; + std::vector types; + std::set contexts; OutputBlock (); ~OutputBlock (); @@ -81,6 +84,7 @@ public: ~OutputFile (); std::ostream & stream (); + OutputBlock &block(); void insert_code (); bool open (); void new_block (); @@ -111,16 +115,11 @@ public: OutputFile & wdelay_yyaccept_init (uint32_t ind); OutputFile & wdelay_yymaxfill (); - void set_used_yyaccept (); - bool get_used_yyaccept () const; - void set_force_start_label (bool force); - void set_user_start_label (const std::string & label); - bool get_force_start_label () const; - void set_block_line (uint32_t l); - uint32_t get_block_line () const; + void global_lists(uniq_vector_t &types, + std::set &contexts) const; - void emit(const std::vector &types, - const std::set &contexts, size_t max_fill); + void emit(const uniq_vector_t &global_types, + const std::set &global_contexts, size_t max_fill); FORBID_COPY (OutputFile); }; @@ -130,7 +129,7 @@ struct HeaderFile HeaderFile(const std::string &fn); ~HeaderFile (); bool open (); - void emit (const std::vector & types); + void emit(const uniq_vector_t &types); private: std::ostringstream stream; @@ -144,9 +143,7 @@ struct Output { OutputFile source; HeaderFile header; - std::vector types; std::set skeletons; - std::set contexts; size_t max_fill; Output(const std::string &source_name, const std::string &header_name); @@ -159,7 +156,7 @@ void output_contexts_default(std::ostream &o, uint32_t ind, const std::set &contexts); void output_line_info (std::ostream &, uint32_t, const std::string&); void output_state_goto (std::ostream &, uint32_t, uint32_t); -void output_types (std::ostream &, uint32_t, const std::vector &); +void output_types(std::ostream &o, uint32_t, const uniq_vector_t &types); void output_version_time (std::ostream &); void output_yyaccept_init (std::ostream &, uint32_t, bool); void output_yymaxfill (std::ostream &, size_t); diff --git a/re2c/src/ir/compile.cc b/re2c/src/ir/compile.cc index 44ca9d75..effc28e6 100644 --- a/re2c/src/ir/compile.cc +++ b/re2c/src/ir/compile.cc @@ -35,7 +35,7 @@ static smart_ptr compile_rules( const std::string &cond, uint32_t cunits) { - const uint32_t line = output.source.get_block_line(); + const uint32_t line = output.source.block().line; const std::string name = make_name(cond, line); // The original set of code units (charset) might be very large. @@ -105,7 +105,7 @@ static smart_ptr compile_rules( output.max_fill = std::max (output.max_fill, adfa->max_fill); if (adfa->need_accept) { - output.source.set_used_yyaccept (); + output.source.block().used_yyaccept = true; } return make_smart_ptr(adfa); diff --git a/re2c/src/parse/lex_conf.re b/re2c/src/parse/lex_conf.re index 066185d9..bcc66479 100644 --- a/re2c/src/parse/lex_conf.re +++ b/re2c/src/parse/lex_conf.re @@ -159,8 +159,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.set_force_start_label (lex_conf_bool()); return; } - "startlabel" { out.set_user_start_label (lex_conf_string ()); return; } + "startlabel" / conf_assign number { out.block().force_start_label = lex_conf_bool(); return; } + "startlabel" { out.block().user_start_label = 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 71fe0662..bfc4665b 100644 --- a/re2c/src/parse/parser.ypp +++ b/re2c/src/parse/parser.ypp @@ -543,7 +543,7 @@ void parse(Scanner& i, Output & o) } encodingOld = opts->encoding; } - o.source.set_block_line (in->get_cline ()); + o.source.block().line = in->get_cline(); uint32_t ind = opts->topIndent; if (opts->cFlag) { @@ -570,8 +570,8 @@ void parse(Scanner& i, Output & o) // Note that "0" inserts first, which is important. condnames.insert (condnames.begin (), "0"); } - o.types = condnames; } + o.source.block().types = condnames; size_t nCount = specMap.size(); diff --git a/re2c/test/contexts/cond_star0.ci--input(custom).c b/re2c/test/contexts/cond_star0.ci--input(custom).c index 782f45a4..8150a0fe 100644 --- a/re2c/test/contexts/cond_star0.ci--input(custom).c +++ b/re2c/test/contexts/cond_star0.ci--input(custom).c @@ -4,12 +4,12 @@ YYCTYPE yych; long yyctx0; long yyctx1; - YYBACKUPCTX (); switch (YYGETCONDITION()) { case yycc1: goto yyc_c1; } /* *********************************** */ yyc_c1: + YYBACKUPCTX (); if (YYLESSTHAN (3)) YYFILL(3); yych = YYPEEK (); switch (yych) { diff --git a/re2c/test/contexts/cond_star0.ci.c b/re2c/test/contexts/cond_star0.ci.c index 6b0c874f..dc58f637 100644 --- a/re2c/test/contexts/cond_star0.ci.c +++ b/re2c/test/contexts/cond_star0.ci.c @@ -4,12 +4,12 @@ YYCTYPE yych; long yyctx0; long yyctx1; - YYCTXMARKER = YYCURSOR; switch (YYGETCONDITION()) { case yycc1: goto yyc_c1; } /* *********************************** */ yyc_c1: + YYCTXMARKER = YYCURSOR; if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; switch (yych) { diff --git a/re2c/test/contexts/cond_star1.ci--input(custom).c b/re2c/test/contexts/cond_star1.ci--input(custom).c index 6089be53..795caee6 100644 --- a/re2c/test/contexts/cond_star1.ci--input(custom).c +++ b/re2c/test/contexts/cond_star1.ci--input(custom).c @@ -4,13 +4,13 @@ YYCTYPE yych; long yyctx0; long yyctx1; - YYBACKUPCTX (); switch (YYGETCONDITION()) { case yycc1: goto yyc_c1; case yycc2: goto yyc_c2; } /* *********************************** */ yyc_c1: + YYBACKUPCTX (); if (YYLESSTHAN (3)) YYFILL(3); yych = YYPEEK (); switch (yych) { diff --git a/re2c/test/contexts/cond_star1.ci.c b/re2c/test/contexts/cond_star1.ci.c index 11e69bfd..88f19999 100644 --- a/re2c/test/contexts/cond_star1.ci.c +++ b/re2c/test/contexts/cond_star1.ci.c @@ -4,13 +4,13 @@ YYCTYPE yych; long yyctx0; long yyctx1; - YYCTXMARKER = YYCURSOR; switch (YYGETCONDITION()) { case yycc1: goto yyc_c1; case yycc2: goto yyc_c2; } /* *********************************** */ yyc_c1: + YYCTXMARKER = YYCURSOR; if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; switch (yych) { diff --git a/re2c/test/contexts/cond_star2.ci.c b/re2c/test/contexts/cond_star2.ci.c index b8f39e13..a254b249 100644 --- a/re2c/test/contexts/cond_star2.ci.c +++ b/re2c/test/contexts/cond_star2.ci.c @@ -5,13 +5,13 @@ long yyctx0; long yyctx1; long yyctx3; - YYCTXMARKER = YYCURSOR; switch (YYGETCONDITION()) { case yycc1: goto yyc_c1; case yycc2: goto yyc_c2; } /* *********************************** */ yyc_c1: + YYCTXMARKER = YYCURSOR; if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; switch (yych) { @@ -60,6 +60,7 @@ yy11: } /* *********************************** */ yyc_c2: + YYCTXMARKER = YYCURSOR; if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; switch (yych) { -- 2.40.0