]> granicus.if.org Git - re2c/commitdiff
If the input starts with a re2c block, apply re2c configurations immediately. (see...
authorUlya Trofimovich <skvadrik@gmail.com>
Sat, 14 Apr 2018 20:50:32 +0000 (21:50 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Sat, 14 Apr 2018 20:50:32 +0000 (21:50 +0100)
re2c/bootstrap/src/ast/lex.cc
re2c/src/ast/lex.re
re2c/src/code/emit_action.cc
re2c/src/code/emit_dfa.cc
re2c/src/code/output.cc
re2c/src/code/output.h
re2c/src/compile.cc
re2c/src/conf/opt.h
re2c/test/config/flags.c

index fac2b2f1dd5f3d2d30f5e767b32589564678bd39..832828572d321aee78d12b56a04f9dab665d2b95 100644 (file)
@@ -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 <stddef.h>
@@ -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;
index c3885f98e50788335e7731df63e20e9bbeda951f..bb8d66509076b4635f549f4075ae8fd67bc16d7d 100644 (file)
@@ -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;
index d37d41cec315c1d51a2d49474ca530434fcc6099..732e0cef8675c5dc83151641fa182c4f77951bf5 100644 (file)
@@ -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");
index 18c600a0ee915ad000ac46be0323a9e4d2f3f59e..33a040e902664f409e2137df3ffbb0544ff8a8b1 100644 (file)
@@ -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())
index 0695c341d6a3a23b0598747f594c606b144f2c41..fc0fff49ca92fe467f9f48df5953bf8b181268ab 100644 (file)
@@ -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<opt_t *>(fst->opts) = *snd->opts;
+               }
+       }
+}
+
 void OutputFile::global_lists(uniq_vector_t<std::string> &types,
        std::set<std::string> &stags, std::set<std::string> &mtags) const
 {
@@ -435,6 +462,8 @@ bool OutputFile::emit(const uniq_vector_t<std::string> &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<std::string> &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:
index 6b769aa7e1ab0763d74d58a951ef331445b8a408..2f040ffb47610b1cc00853e925a0162f1954133d 100644 (file)
@@ -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<OutputFragment *> fragments;
        bool used_yyaccept;
+       bool have_user_code;
        uint32_t line;
        std::vector<std::string> types;
        std::set<std::string> 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<std::string> &types,
                std::set<std::string> &stags, std::set<std::string> &mtags) const;
 
index 51ac7e21dd2d565d302b351af2f944eec033408b..7e088dea83a109eda6da62f9bd978a7c30071a84 100644 (file)
@@ -129,16 +129,19 @@ void compile(Scanner &input, Output &output, Opt &opts)
        typedef std::vector<smart_ptr<DFA> > 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) {
index f638083529ff7631f0127270f2c73e3c915affd3..8e7387fef31281dda4abe9a58cf0fc00fff23553 100644 (file)
@@ -214,7 +214,6 @@ struct opt_t
 #              undef MUTOPT1
 #              undef MUTOPT
        {}
-       FORBID_COPY(opt_t);
 };
 
 // see note [constant and mutable options]
index 8d5fcb7e98722e47281d473fdc3dd4a0e3d9a8e2..f6b3cb39b430b0761e2501db1f14e63e64df33cb 100644 (file)
@@ -1,3 +1,2 @@
 /* Generated by re2c */
-#line 1 "config/flags.re"