From: Ulya Trofimovich Date: Sat, 14 Apr 2018 20:50:32 +0000 (+0100) Subject: If the input starts with a re2c block, apply re2c configurations immediately. (see... X-Git-Tag: 1.1~48 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fe4bf2e3857fd29b8d00264a2540366db57da4d6;p=re2c If the input starts with a re2c block, apply re2c configurations immediately. (see #201). --- diff --git a/re2c/bootstrap/src/ast/lex.cc b/re2c/bootstrap/src/ast/lex.cc index fac2b2f1..83282857 100644 --- a/re2c/bootstrap/src/ast/lex.cc +++ b/re2c/bootstrap/src/ast/lex.cc @@ -1,4 +1,4 @@ -/* Generated by re2c 1.0.3 on Sat Apr 14 00:20:54 2018 */ +/* Generated by re2c 1.0.3 on Sat Apr 14 21:01:06 2018 */ #line 1 "../src/ast/lex.re" #include "src/util/c99_stdint.h" #include @@ -664,9 +664,9 @@ yy125: #line 115 "../src/ast/lex.re" { out.wraw(tok, ptr); - out.wdelay_line_info(); + out.wdelay_line_info_output(); out.wdelay_types(); - out.wline_info(cline, get_fname().c_str()); + out.wdelay_line_info_input(cline, get_fname()); lex_end_of_comment(out); goto echo; } @@ -769,7 +769,7 @@ yy147: { if (ignored > 0) { cline += ignored; - out.wline_info(cline, get_fname().c_str()); + out.wdelay_line_info_input(cline, get_fname()); } tok = pos = cur; return; diff --git a/re2c/src/ast/lex.re b/re2c/src/ast/lex.re index c3885f98..bb8d6650 100644 --- a/re2c/src/ast/lex.re +++ b/re2c/src/ast/lex.re @@ -114,9 +114,9 @@ echo: "/*!types:re2c" { out.wraw(tok, ptr); - out.wdelay_line_info(); + out.wdelay_line_info_output(); out.wdelay_types(); - out.wline_info(cline, get_fname().c_str()); + out.wdelay_line_info_input(cline, get_fname()); lex_end_of_comment(out); goto echo; } @@ -165,7 +165,7 @@ void Scanner::lex_end_of_comment(OutputFile &out) eoc { if (ignored > 0) { cline += ignored; - out.wline_info(cline, get_fname().c_str()); + out.wdelay_line_info_input(cline, get_fname()); } tok = pos = cur; return; diff --git a/re2c/src/code/emit_action.cc b/re2c/src/code/emit_action.cc index d37d41ce..732e0cef 100644 --- a/re2c/src/code/emit_action.cc +++ b/re2c/src/code/emit_action.cc @@ -184,9 +184,9 @@ void emit_rule(OutputFile &o, uint32_t ind, const DFA &dfa, size_t rule_idx) if (!dfa.setup.empty()) { o.wind(ind).wstring(dfa.setup).ws("\n"); } - o.wline_info(code->fline, code->fname.c_str()) + o.wdelay_line_info_input(code->fline, code->fname) .wind(ind).wstring(code->text).ws("\n") - .wdelay_line_info(); + .wdelay_line_info_output(); } else if (!cond.empty()) { strrreplace(s = opts->condGoto, opts->condGotoParam, opts->condPrefix + cond); o.wind(ind).wstring(s).ws("\n"); diff --git a/re2c/src/code/emit_dfa.cc b/re2c/src/code/emit_dfa.cc index 18c600a0..33a040e9 100644 --- a/re2c/src/code/emit_dfa.cc +++ b/re2c/src/code/emit_dfa.cc @@ -192,7 +192,7 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra // Generate prolog if (bProlog) { - o.ws("\n").wdelay_line_info (); + o.ws("\n").wdelay_line_info_output (); if ((!opts->fFlag && ob.used_yyaccept) || (!opts->fFlag && opts->bEmitYYCh) || (opts->bFlag && !opts->cFlag && !bitmaps.empty()) diff --git a/re2c/src/code/output.cc b/re2c/src/code/output.cc index 0695c341..fc0fff49 100644 --- a/re2c/src/code/output.cc +++ b/re2c/src/code/output.cc @@ -25,7 +25,11 @@ OutputFragment::OutputFragment (type_t t, uint32_t i) OutputFragment::~OutputFragment() { - if (type == STAGS || type == MTAGS) delete tags; + if (type == STAGS || type == MTAGS) { + delete tags; + } else if (type == LINE_INFO_INPUT) { + delete line_info; + } } uint32_t OutputFragment::count_lines () const @@ -46,6 +50,7 @@ uint32_t OutputFragment::count_lines () const OutputBlock::OutputBlock () : fragments () , used_yyaccept (false) + , have_user_code (false) , line (0) , types () , stags () @@ -93,9 +98,15 @@ std::ostream & OutputFile::stream () OutputFile &OutputFile::wraw(const char *s, const char *e) { - if (block().opts->target == TARGET_CODE) { + if (s != e && block().opts->target == TARGET_CODE) { insert_code(); + // scan for non-whitespace characters + bool &code = block().have_user_code; + for (const char *p = s; !code && p < e; ++p) { + code = !isspace(*p); + } + // convert CR LF to LF std::ostream &o = stream(); for (const char *p = s;; ++p) { @@ -146,13 +157,6 @@ OutputFile & OutputFile::wu32_width (uint32_t n, int w) return *this; } -OutputFile & OutputFile::wline_info (uint32_t l, const char * fn) -{ - insert_code(); - output_line_info (stream (), l, fn, block().opts->iFlag); - return *this; -} - OutputFile & OutputFile::wversion_time () { insert_code(); @@ -238,9 +242,17 @@ OutputFile &OutputFile::wdelay_tags(const ConfTags *cf, bool mtags) return *this; } -OutputFile & OutputFile::wdelay_line_info () +OutputFile & OutputFile::wdelay_line_info_input (uint32_t l, const std::string &fn) +{ + OutputFragment *frag = new OutputFragment(OutputFragment::LINE_INFO_INPUT, 0); + frag->line_info = new LineInfo(l, fn); + blocks.back()->fragments.push_back(frag); + return *this; +} + +OutputFile & OutputFile::wdelay_line_info_output () { - block().fragments.push_back (new OutputFragment (OutputFragment::LINE_INFO, 0)); + block().fragments.push_back (new OutputFragment (OutputFragment::LINE_INFO_OUTPUT, 0)); return *this; } @@ -341,6 +353,21 @@ void OutputFile::new_block(Opt &opts) opts.reset_startlabel(); } +void OutputFile::fix_first_block_opts() +{ + // If the initial block contains only whitespace and no user code, + // then re2c options specified in the first re2c block are also + // applied to the initial block. + if (blocks.size() >= 2) { + OutputBlock + *fst = blocks[0], + *snd = blocks[1]; + if (!fst->have_user_code) { + *const_cast(fst->opts) = *snd->opts; + } + } +} + void OutputFile::global_lists(uniq_vector_t &types, std::set &stags, std::set &mtags) const { @@ -435,6 +462,8 @@ bool OutputFile::emit(const uniq_vector_t &global_types, } } + fix_first_block_opts(); + unsigned int line_count = 1; for (unsigned int j = 0; j < blocks.size(); ++j) { OutputBlock & b = * blocks[j]; @@ -453,7 +482,10 @@ bool OutputFile::emit(const uniq_vector_t &global_types, switch (f.type) { case OutputFragment::EMPTY: case OutputFragment::CODE: break; - case OutputFragment::LINE_INFO: + case OutputFragment::LINE_INFO_INPUT: + output_line_info(o, f.line_info->line, f.line_info->filename, bopt->iFlag); + break; + case OutputFragment::LINE_INFO_OUTPUT: output_line_info(o, line_count + 1, filename, bopt->iFlag); break; case OutputFragment::COND_GOTO: diff --git a/re2c/src/code/output.h b/re2c/src/code/output.h index 6b769aa7..2f040ffb 100644 --- a/re2c/src/code/output.h +++ b/re2c/src/code/output.h @@ -34,6 +34,15 @@ struct ConfTags : format(f), separator(s) {} }; +struct LineInfo +{ + uint32_t line; + std::string filename; + + LineInfo(uint32_t l, const std::string &fn) + : line(l), filename(fn) {} +}; + struct OutputFragment { enum type_t @@ -41,7 +50,8 @@ struct OutputFragment // , CONFIG , COND_GOTO , COND_TABLE - , LINE_INFO + , LINE_INFO_INPUT + , LINE_INFO_OUTPUT , STATE_GOTO , STAGS , MTAGS @@ -67,7 +77,8 @@ struct OutputFragment uint32_t indent; union { - const ConfTags* tags; + const ConfTags *tags; + const LineInfo *line_info; }; OutputFragment (type_t t, uint32_t i); @@ -79,6 +90,7 @@ struct OutputBlock { std::vector fragments; bool used_yyaccept; + bool have_user_code; uint32_t line; std::vector types; std::set stags; @@ -123,14 +135,14 @@ public: OutputFile & ws (const char * s); OutputFile & wlabel (label_t l); OutputFile & wrange (uint32_t u, uint32_t l); - OutputFile & wline_info (uint32_t l, const char * fn); OutputFile & wversion_time (); OutputFile & wuser_start_label (); OutputFile & wind (uint32_t ind); // delayed output OutputFile & wdelay_tags(const ConfTags *cf, bool mtags); - OutputFile & wdelay_line_info (); + OutputFile & wdelay_line_info_input (uint32_t l, const std::string &fn); + OutputFile & wdelay_line_info_output (); OutputFile & wdelay_cond_goto(uint32_t ind); OutputFile & wdelay_cond_table(uint32_t ind); OutputFile & wdelay_state_goto (uint32_t ind); @@ -142,6 +154,7 @@ public: OutputFile& wdelay_peek(uint32_t ind, bool peek); OutputFile& wdelay_backup(uint32_t ind, bool backup); + void fix_first_block_opts(); void global_lists(uniq_vector_t &types, std::set &stags, std::set &mtags) const; diff --git a/re2c/src/compile.cc b/re2c/src/compile.cc index 51ac7e21..7e088dea 100644 --- a/re2c/src/compile.cc +++ b/re2c/src/compile.cc @@ -129,16 +129,19 @@ void compile(Scanner &input, Output &output, Opt &opts) typedef std::vector > dfas_t; o.new_block(opts); - o.wversion_time().wline_info(input.get_cline(), input.get_fname().c_str()); + o.wversion_time(); + o.wdelay_line_info_input(input.get_cline(), input.get_fname()); if (globopts->target == TARGET_SKELETON) { emit_prolog(o); } - for (Scanner::ParseMode mode; (mode = input.echo(o)) != Scanner::Stop;) { - + for (;;) { + // parse everything up to the next re2c block + Scanner::ParseMode mode = input.echo(o); + if (mode == Scanner::Stop) break; validate_mode(mode, globopts->rFlag, ropts, input); - // parse next re2c block + // parse the next re2c block specs_t specs; if (mode == Scanner::Reuse) { specs = rspecs; @@ -177,7 +180,7 @@ void compile(Scanner &input, Output &output, Opt &opts) } } - o.wline_info (input.get_cline (), input.get_fname ().c_str ()); + o.wdelay_line_info_input(input.get_cline(), input.get_fname()); } if (globopts->target == TARGET_SKELETON) { diff --git a/re2c/src/conf/opt.h b/re2c/src/conf/opt.h index f6380835..8e7387fe 100644 --- a/re2c/src/conf/opt.h +++ b/re2c/src/conf/opt.h @@ -214,7 +214,6 @@ struct opt_t # undef MUTOPT1 # undef MUTOPT {} - FORBID_COPY(opt_t); }; // see note [constant and mutable options] diff --git a/re2c/test/config/flags.c b/re2c/test/config/flags.c index 8d5fcb7e..f6b3cb39 100644 --- a/re2c/test/config/flags.c +++ b/re2c/test/config/flags.c @@ -1,3 +1,2 @@ /* Generated by re2c */ -#line 1 "config/flags.re"