]> granicus.if.org Git - re2c/commitdiff
Split options into constant and mutable; restricted access to mutable ones.
authorUlya Trofimovich <skvadrik@gmail.com>
Tue, 7 Mar 2017 21:29:17 +0000 (21:29 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Tue, 7 Mar 2017 21:57:05 +0000 (21:57 +0000)
Some options are immutable (target, output files; global switches like
conditions, reuse mode, storable states; support of flex syntax, etc.).
These options are passed as command-line arguments and never change.
It is safe to read them from any program point after parsing command-line
arguments.

Other options are configurable; they have block scope (may be specified
anywhere inside of the block and still affect the whole block).
Reading mutable options of yet unparsed block is not allowed because
they may affect the way RE2C parses current block (RE2C would be tempted
to base decisions on the latest option value, which may not be the final
one).

15 files changed:
re2c/bootstrap/src/ast/lex.cc
re2c/bootstrap/src/ast/lex_conf.cc
re2c/bootstrap/src/ast/parser.cc
re2c/bootstrap/src/conf/parse_opts.cc
re2c/src/ast/lex.re
re2c/src/ast/lex_conf.re
re2c/src/ast/parser.h
re2c/src/ast/parser.ypp
re2c/src/ast/scanner.cc
re2c/src/ast/scanner.h
re2c/src/code/output.cc
re2c/src/conf/opt.cc
re2c/src/conf/opt.h
re2c/src/conf/parse_opts.re
re2c/src/main.cc

index 35f1bede9217360b8ce8c05018c4c6e3f72222d5..dd4cfd8127dfa706dde565ef9d7613ed1c617ff9 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.16 on Tue Mar  7 18:21:50 2017 */
+/* Generated by re2c 0.16 on Tue Mar  7 21:23:28 2017 */
 #line 1 "../src/ast/lex.re"
 #include "src/util/c99_stdint.h"
 #include <stddef.h>
@@ -39,7 +39,7 @@ namespace re2c
 #line 57 "../src/ast/lex.re"
 
 
-Scanner::ParseMode Scanner::echo()
+Scanner::ParseMode Scanner::echo(OutputFile &out)
 {
        if (eof && cur == eof) // Catch EOF
        {
@@ -513,7 +513,7 @@ yy89:
        {
                out.wraw(tok, ptr);
                out.wdelay_yymaxfill();
-               lex_end_of_comment();
+               lex_end_of_comment(out);
                goto echo;
        }
 #line 520 "src/ast/lex.cc"
@@ -554,7 +554,7 @@ yy99:
 #line 115 "../src/ast/lex.re"
        {
                out.wraw(tok, ptr);
-               lex_tags();
+               lex_tags(out);
                goto echo;
        }
 #line 561 "src/ast/lex.cc"
@@ -586,7 +586,7 @@ yy106:
                out.wdelay_line_info();
                out.wdelay_types();
                out.wline_info(cline, get_fname().c_str());
-               lex_end_of_comment();
+               lex_end_of_comment(out);
                goto echo;
        }
 #line 593 "src/ast/lex.cc"
@@ -599,7 +599,7 @@ yy109:
 #line 86 "../src/ast/lex.re"
        {
                out.wraw(tok, ptr);
-               lex_end_of_comment();
+               lex_end_of_comment(out);
                goto echo;
        }
 #line 606 "src/ast/lex.cc"
@@ -611,7 +611,7 @@ yy111:
        {
                out.wraw(tok, ptr);
                out.wdelay_state_goto(0);
-               lex_end_of_comment();
+               lex_end_of_comment(out);
                goto echo;
        }
 #line 618 "src/ast/lex.cc"
@@ -620,7 +620,7 @@ yy111:
 
 }
 
-void Scanner::lex_end_of_comment()
+void Scanner::lex_end_of_comment(OutputFile &out)
 {
        uint32_t ignored = 0;
        for (;;) {
@@ -677,7 +677,7 @@ yy123:
 }
 }
 
-void Scanner::lex_tags()
+void Scanner::lex_tags(OutputFile &out)
 {
        std::string fmt, sep;
        for (;;) {
@@ -837,7 +837,7 @@ yy152:
 }
 }
 
-int Scanner::scan()
+int Scanner::scan(const conopt_t *globopts)
 {
        uint32_t depth, code_line;
 scan:
@@ -1170,7 +1170,7 @@ yy198:
        YYCURSOR -= 1;
 #line 294 "../src/ast/lex.re"
        {
-                                       if (!opts->FFlag) {
+                                       if (!globopts->FFlag) {
                                                yylval.str = new std::string (tok, tok_len());
                                                return TOKEN_ID;
                                        } else {
@@ -1318,7 +1318,7 @@ yy219:
 #line 276 "../src/ast/lex.re"
        {
                                        yylval.str = new std::string (tok, tok_len ());
-                                       if (opts->FFlag)
+                                       if (globopts->FFlag)
                                        {
                                                lexer_state = LEX_FLEX_NAME;
                                                return TOKEN_FID;
@@ -1364,7 +1364,7 @@ yy227:
        ++YYCURSOR;
 #line 266 "../src/ast/lex.re"
        {
-                                       if (!opts->FFlag) {
+                                       if (!globopts->FFlag) {
                                                fatal("curly braces for names only allowed with -F switch");
                                        }
                                        yylval.str = new std::string (tok + 1, tok_len () - 2); // -2 to omit braces
@@ -1406,7 +1406,7 @@ yy235:
 yy236:
        ++YYCURSOR;
 #line 274 "../src/ast/lex.re"
-       { lex_conf (); return TOKEN_CONF; }
+       { return TOKEN_CONF; }
 #line 1411 "src/ast/lex.cc"
 yy238:
        ++YYCURSOR;
index 658aaad1ef4eeb624e70c56445d0dbcf28ee2489..09250480fe8ccd1f9b674041b5b5ed3abcb0d9f8 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.16 on Tue Mar  7 18:49:39 2017 */
+/* Generated by re2c 0.16 on Tue Mar  7 21:23:26 2017 */
 #line 1 "../src/ast/lex_conf.re"
 #include "src/util/c99_stdint.h"
 #include <string>
@@ -16,7 +16,7 @@ namespace re2c
 #line 35 "../src/ast/lex_conf.re"
 
 
-void Scanner::lex_conf ()
+void Scanner::lex_conf(Opt &opts)
 {
        tok = cur;
 
@@ -503,7 +503,7 @@ yy90:
                goto yy3;
        }
 #line 57 "../src/ast/lex_conf.re"
-       { lex_conf_enc(Enc::UTF8);   return; }
+       { lex_conf_enc(Enc::UTF8, opts);   return; }
 #line 508 "src/ast/lex_conf.cc"
 yy92:
        yych = (unsigned char)*++cur;
@@ -591,7 +591,7 @@ yy99:
        }
 yy100:
 #line 53 "../src/ast/lex_conf.re"
-       { lex_conf_enc(Enc::EBCDIC); return; }
+       { lex_conf_enc(Enc::EBCDIC, opts); return; }
 #line 596 "src/ast/lex_conf.cc"
 yy101:
        yych = (unsigned char)*++cur;
@@ -665,7 +665,7 @@ yy110:
        }
 yy111:
 #line 54 "../src/ast/lex_conf.re"
-       { lex_conf_enc(Enc::UTF32);  return; }
+       { lex_conf_enc(Enc::UTF32, opts);  return; }
 #line 670 "src/ast/lex_conf.cc"
 yy112:
        yych = (unsigned char)*++cur;
@@ -686,7 +686,7 @@ yy112:
        }
 yy113:
 #line 55 "../src/ast/lex_conf.re"
-       { lex_conf_enc(Enc::UCS2);   return; }
+       { lex_conf_enc(Enc::UCS2, opts);   return; }
 #line 691 "src/ast/lex_conf.cc"
 yy114:
        yych = (unsigned char)*++cur;
@@ -694,7 +694,7 @@ yy114:
                goto yy3;
        }
 #line 56 "../src/ast/lex_conf.re"
-       { lex_conf_enc(Enc::UTF16);  return; }
+       { lex_conf_enc(Enc::UTF16, opts);  return; }
 #line 699 "src/ast/lex_conf.cc"
 yy116:
        yych = (unsigned char)*++cur;
@@ -1479,7 +1479,7 @@ yy290:
                goto yy3;
        }
 #line 60 "../src/ast/lex_conf.re"
-       { lex_conf_input();            return; }
+       { lex_conf_input(opts);            return; }
 #line 1484 "src/ast/lex_conf.cc"
 yy292:
        yych = (unsigned char)*++cur;
@@ -2798,7 +2798,7 @@ yy592:
                goto yy3;
        }
 #line 61 "../src/ast/lex_conf.re"
-       { lex_conf_empty_class();      return; }
+       { lex_conf_empty_class(opts);      return; }
 #line 2803 "src/ast/lex_conf.cc"
 yy594:
        yych = (unsigned char)*++cur;
@@ -3143,7 +3143,7 @@ yy670:
                goto yy3;
        }
 #line 59 "../src/ast/lex_conf.re"
-       { lex_conf_encoding_policy();  return; }
+       { lex_conf_encoding_policy(opts);  return; }
 #line 3148 "src/ast/lex_conf.cc"
 yy672:
        yych = (unsigned char)*++cur;
@@ -3183,7 +3183,7 @@ yy680:
                goto yy3;
        }
 #line 62 "../src/ast/lex_conf.re"
-       { lex_conf_dfa_minimization(); return; }
+       { lex_conf_dfa_minimization(opts); return; }
 #line 3188 "src/ast/lex_conf.cc"
 yy682:
        yych = (unsigned char)*++cur;
@@ -3276,7 +3276,7 @@ yy703:
 
 }
 
-void Scanner::lex_conf_encoding_policy()
+void Scanner::lex_conf_encoding_policy(Opt &opts)
 {
        lex_conf_assign ();
 
@@ -3381,7 +3381,7 @@ end:
        lex_conf_semicolon();
 }
 
-void Scanner::lex_conf_input()
+void Scanner::lex_conf_input(Opt &opts)
 {
        lex_conf_assign ();
 
@@ -3461,7 +3461,7 @@ end:
        lex_conf_semicolon();
 }
 
-void Scanner::lex_conf_empty_class()
+void Scanner::lex_conf_empty_class(Opt &opts)
 {
        lex_conf_assign ();
 
@@ -3569,7 +3569,7 @@ end:
        lex_conf_semicolon();
 }
 
-void Scanner::lex_conf_dfa_minimization()
+void Scanner::lex_conf_dfa_minimization(Opt &opts)
 {
        lex_conf_assign ();
 
@@ -3637,7 +3637,7 @@ end:
        lex_conf_semicolon();
 }
 
-void Scanner::lex_conf_enc(Enc::type_t enc)
+void Scanner::lex_conf_enc(Enc::type_t enc, Opt &opts)
 {
        if (lex_conf_bool()) {
                opts.set_encoding(enc);
index d0f5f5ead01301791e2cb9eead61f4fb2b50faf3..b99e52a5d15ab30ed0a99880ea1a8ba17dbd98b3 100644 (file)
@@ -1447,7 +1447,13 @@ yyreduce:
   YY_REDUCE_PRINT (yyn);
   switch (yyn)
     {
-        case 7:
+        case 3:
+
+    { context.input.lex_conf(context.opts); }
+
+    break;
+
+  case 7:
 
     {
                if (!context.symtab.insert(std::make_pair(*(yyvsp[-2].str), (yyvsp[-1].regexp))).second) {
@@ -1963,7 +1969,7 @@ void yyerror(context_t &context, const char* s)
 
 int yylex(context_t &context)
 {
-       return context.input.scan();
+       return context.input.scan(&context.opts.glob);
 }
 
 } // extern "C"
@@ -1971,27 +1977,27 @@ int yylex(context_t &context)
 namespace re2c
 {
 
-void parse(Scanner &input, Output &output)
+void parse(Scanner &input, Output &output, Opt &opts)
 {
        specs_t rspecs;
        symtab_t symtab;
-       Opt &opts = input.opts;
+       const conopt_t *globopts = &opts.glob;
        const opt_t *ropts = NULL;
        OutputFile &o = output.source;
 
        o.new_block(opts);
        o.wversion_time().wline_info(input.get_cline(), input.get_fname().c_str());
-       if (opts->target == TARGET_SKELETON) {
+       if (globopts->target == TARGET_SKELETON) {
                emit_prolog(o);
        }
 
-       for (Scanner::ParseMode mode; (mode = input.echo()) != Scanner::Stop;) {
+       for (Scanner::ParseMode mode; (mode = input.echo(o)) != Scanner::Stop;) {
 
-               check_mode(mode, opts->rFlag, ropts, input);
+               check_mode(mode, globopts->rFlag, ropts, input);
 
                // parse next re2c block
                specs_t specs;
-               context_t context = {input, specs, symtab};
+               context_t context = {input, specs, symtab, opts};
                if (mode == Scanner::Reuse) {
                        specs = rspecs;
                        opts.restore(ropts);
@@ -2012,7 +2018,7 @@ void parse(Scanner &input, Output &output)
                        ropts = o.block().opts;
                } else {
                        // validate and normalize AST
-                       check_specs(specs, opts->cFlag);
+                       check_specs(specs, globopts->cFlag);
                        prepare_specs(specs);
 
                        // compile AST to DFA
@@ -2024,7 +2030,7 @@ void parse(Scanner &input, Output &output)
 
                        // compile DFA to code
                        bool prolog = false;
-                       uint32_t ind = opts->topIndent;
+                       uint32_t ind = o.block().opts->topIndent;
                        for (dfas_t::const_iterator i = dfas.begin(); i != dfas.end(); ++i) {
                                (*i)->emit(output, ind, (i + 1) == dfas.end(), prolog);
                        }
@@ -2033,7 +2039,7 @@ void parse(Scanner &input, Output &output)
                o.wline_info (input.get_cline (), input.get_fname ().c_str ());
        }
 
-       if (opts->target == TARGET_SKELETON) {
+       if (globopts->target == TARGET_SKELETON) {
                emit_epilog (o, output.skeletons);
        }
 
index 90045fa20eed8e893d520311b65bc3457637e346..b390735c424e15dd083177786d70cff45b603d87 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.16 on Tue Mar  7 18:22:57 2017 */
+/* Generated by re2c 0.16 on Tue Mar  7 21:26:57 2017 */
 #line 1 "../src/conf/parse_opts.re"
 #include "src/code/input_api.h"
 #include "src/conf/msg.h"
@@ -15,7 +15,7 @@ static inline bool next (char * & arg, char ** & argv)
        return arg != NULL;
 }
 
-parse_opts_t parse_opts (char **argv, Opt &opts, Warn &warn)
+parse_opts_t parse_opts(char **argv, conopt_t &globopts, Opt &opts, Warn &warn)
 {
 #define YYCTYPE unsigned char
        char * YYCURSOR;
@@ -935,12 +935,12 @@ yy204:
 #line 936 "src/conf/parse_opts.cc"
 yy206:
        ++YYCURSOR;
-#line 121 "../src/conf/parse_opts.re"
+#line 123 "../src/conf/parse_opts.re"
        { goto opt_short; }
 #line 941 "src/conf/parse_opts.cc"
 yy208:
        ++YYCURSOR;
-#line 116 "../src/conf/parse_opts.re"
+#line 118 "../src/conf/parse_opts.re"
        { opts.set_encoding(Enc::UTF8);   goto opt_short; }
 #line 946 "src/conf/parse_opts.cc"
 yy210:
@@ -950,23 +950,23 @@ yy210:
 #line 951 "src/conf/parse_opts.cc"
 yy212:
        ++YYCURSOR;
-#line 103 "../src/conf/parse_opts.re"
-       { opts.set_target (TARGET_DOT);      goto opt_short; }
+#line 102 "../src/conf/parse_opts.re"
+       { globopts.target = TARGET_DOT;      goto opt_short; }
 #line 956 "src/conf/parse_opts.cc"
 yy214:
        ++YYCURSOR;
-#line 105 "../src/conf/parse_opts.re"
-       { opts.set_FFlag (true);             goto opt_short; }
+#line 104 "../src/conf/parse_opts.re"
+       { globopts.FFlag = true;             goto opt_short; }
 #line 961 "src/conf/parse_opts.cc"
 yy216:
        ++YYCURSOR;
-#line 110 "../src/conf/parse_opts.re"
-       { opts.set_target (TARGET_SKELETON); goto opt_short; }
+#line 106 "../src/conf/parse_opts.re"
+       { globopts.target = TARGET_SKELETON; goto opt_short; }
 #line 966 "src/conf/parse_opts.cc"
 yy218:
        ++YYCURSOR;
-#line 111 "../src/conf/parse_opts.re"
-       { opts.set_tags (true);              goto opt_short; }
+#line 113 "../src/conf/parse_opts.re"
+       { opts.set_tags(true);            goto opt_short; }
 #line 971 "src/conf/parse_opts.cc"
 yy220:
        ++YYCURSOR;
@@ -975,64 +975,64 @@ yy220:
 #line 976 "src/conf/parse_opts.cc"
 yy222:
        ++YYCURSOR;
-#line 100 "../src/conf/parse_opts.re"
-       { opts.set_bFlag (true);             goto opt_short; }
+#line 108 "../src/conf/parse_opts.re"
+       { opts.set_bFlag(true);           goto opt_short; }
 #line 981 "src/conf/parse_opts.cc"
 yy224:
        ++YYCURSOR;
 #line 101 "../src/conf/parse_opts.re"
-       { opts.set_cFlag (true);             goto opt_short; }
+       { globopts.cFlag = true;             goto opt_short; }
 #line 986 "src/conf/parse_opts.cc"
 yy226:
        ++YYCURSOR;
-#line 102 "../src/conf/parse_opts.re"
-       { opts.set_dFlag (true);             goto opt_short; }
+#line 109 "../src/conf/parse_opts.re"
+       { opts.set_dFlag(true);           goto opt_short; }
 #line 991 "src/conf/parse_opts.cc"
 yy228:
        ++YYCURSOR;
-#line 112 "../src/conf/parse_opts.re"
+#line 114 "../src/conf/parse_opts.re"
        { opts.set_encoding(Enc::EBCDIC); goto opt_short; }
 #line 996 "src/conf/parse_opts.cc"
 yy230:
        ++YYCURSOR;
-#line 104 "../src/conf/parse_opts.re"
-       { opts.set_fFlag (true);             goto opt_short; }
+#line 103 "../src/conf/parse_opts.re"
+       { globopts.fFlag = true;             goto opt_short; }
 #line 1001 "src/conf/parse_opts.cc"
 yy232:
        ++YYCURSOR;
-#line 106 "../src/conf/parse_opts.re"
-       { opts.set_gFlag (true);             goto opt_short; }
+#line 110 "../src/conf/parse_opts.re"
+       { opts.set_gFlag(true);           goto opt_short; }
 #line 1006 "src/conf/parse_opts.cc"
 yy234:
        ++YYCURSOR;
-#line 107 "../src/conf/parse_opts.re"
-       { opts.set_iFlag (true);             goto opt_short; }
+#line 111 "../src/conf/parse_opts.re"
+       { opts.set_iFlag(true);           goto opt_short; }
 #line 1011 "src/conf/parse_opts.cc"
 yy236:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= 0x00) goto yy252;
-#line 118 "../src/conf/parse_opts.re"
+#line 120 "../src/conf/parse_opts.re"
        { *argv = YYCURSOR;                                                             goto opt_output; }
 #line 1017 "src/conf/parse_opts.cc"
 yy238:
        ++YYCURSOR;
-#line 108 "../src/conf/parse_opts.re"
-       { opts.set_rFlag (true);             goto opt_short; }
+#line 105 "../src/conf/parse_opts.re"
+       { globopts.rFlag = true;             goto opt_short; }
 #line 1022 "src/conf/parse_opts.cc"
 yy240:
        ++YYCURSOR;
-#line 109 "../src/conf/parse_opts.re"
-       { opts.set_sFlag (true);             goto opt_short; }
+#line 112 "../src/conf/parse_opts.re"
+       { opts.set_sFlag(true);           goto opt_short; }
 #line 1027 "src/conf/parse_opts.cc"
 yy242:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= 0x00) goto yy254;
-#line 120 "../src/conf/parse_opts.re"
+#line 122 "../src/conf/parse_opts.re"
        { *argv = YYCURSOR;                                                                  goto opt_header; }
 #line 1033 "src/conf/parse_opts.cc"
 yy244:
        ++YYCURSOR;
-#line 113 "../src/conf/parse_opts.re"
+#line 115 "../src/conf/parse_opts.re"
        { opts.set_encoding(Enc::UTF32);  goto opt_short; }
 #line 1038 "src/conf/parse_opts.cc"
 yy246:
@@ -1042,26 +1042,26 @@ yy246:
 #line 1043 "src/conf/parse_opts.cc"
 yy248:
        ++YYCURSOR;
-#line 114 "../src/conf/parse_opts.re"
+#line 116 "../src/conf/parse_opts.re"
        { opts.set_encoding(Enc::UCS2);   goto opt_short; }
 #line 1048 "src/conf/parse_opts.cc"
 yy250:
        ++YYCURSOR;
-#line 115 "../src/conf/parse_opts.re"
+#line 117 "../src/conf/parse_opts.re"
        { opts.set_encoding(Enc::UTF16);  goto opt_short; }
 #line 1053 "src/conf/parse_opts.cc"
 yy252:
        ++YYCURSOR;
-#line 117 "../src/conf/parse_opts.re"
+#line 119 "../src/conf/parse_opts.re"
        { if (!next (YYCURSOR, argv)) { error_arg ("-o, --output"); return EXIT_FAIL; } goto opt_output; }
 #line 1058 "src/conf/parse_opts.cc"
 yy254:
        ++YYCURSOR;
-#line 119 "../src/conf/parse_opts.re"
+#line 121 "../src/conf/parse_opts.re"
        { if (!next (YYCURSOR, argv)) { error_arg ("-t, --type-header"); return EXIT_FAIL; } goto opt_header; }
 #line 1063 "src/conf/parse_opts.cc"
 }
-#line 122 "../src/conf/parse_opts.re"
+#line 124 "../src/conf/parse_opts.re"
 
 
 opt_long:
@@ -1092,7 +1092,7 @@ opt_long:
 yy258:
        ++YYCURSOR;
 yy259:
-#line 127 "../src/conf/parse_opts.re"
+#line 129 "../src/conf/parse_opts.re"
        {
                error ("bad long option: %s", *argv);
                return EXIT_FAIL;
@@ -1450,8 +1450,8 @@ yy339:
        goto yy277;
 yy340:
        ++YYCURSOR;
-#line 153 "../src/conf/parse_opts.re"
-       { opts.set_encoding(Enc::EBCDIC); goto opt; }
+#line 157 "../src/conf/parse_opts.re"
+       { opts.set_encoding(Enc::EBCDIC);    goto opt; }
 #line 1456 "src/conf/parse_opts.cc"
 yy342:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -1606,7 +1606,7 @@ yy377:
        goto yy277;
 yy378:
        ++YYCURSOR;
-#line 131 "../src/conf/parse_opts.re"
+#line 133 "../src/conf/parse_opts.re"
        { usage ();   return EXIT_OK; }
 #line 1612 "src/conf/parse_opts.cc"
 yy380:
@@ -1663,7 +1663,7 @@ yy392:
        goto yy277;
 yy393:
        ++YYCURSOR;
-#line 149 "../src/conf/parse_opts.re"
+#line 153 "../src/conf/parse_opts.re"
        { opts.set_tags (true);              goto opt; }
 #line 1669 "src/conf/parse_opts.cc"
 yy395:
@@ -1748,7 +1748,7 @@ yy414:
        goto yy277;
 yy415:
        ++YYCURSOR;
-#line 161 "../src/conf/parse_opts.re"
+#line 165 "../src/conf/parse_opts.re"
        { goto opt_input; }
 #line 1754 "src/conf/parse_opts.cc"
 yy417:
@@ -1813,8 +1813,8 @@ yy431:
        goto yy277;
 yy432:
        ++YYCURSOR;
-#line 157 "../src/conf/parse_opts.re"
-       { opts.set_encoding(Enc::UTF8);   goto opt; }
+#line 161 "../src/conf/parse_opts.re"
+       { opts.set_encoding(Enc::UTF8);      goto opt; }
 #line 1819 "src/conf/parse_opts.cc"
 yy434:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -1903,7 +1903,7 @@ yy454:
        goto yy277;
 yy455:
        ++YYCURSOR;
-#line 158 "../src/conf/parse_opts.re"
+#line 162 "../src/conf/parse_opts.re"
        { if (!next (YYCURSOR, argv)) { error_arg ("-o, --output"); return EXIT_FAIL; } goto opt_output; }
 #line 1909 "src/conf/parse_opts.cc"
 yy457:
@@ -1940,12 +1940,12 @@ yy464:
        goto yy277;
 yy465:
        ++YYCURSOR;
-#line 156 "../src/conf/parse_opts.re"
-       { opts.set_encoding(Enc::UTF16);  goto opt; }
+#line 160 "../src/conf/parse_opts.re"
+       { opts.set_encoding(Enc::UTF16);     goto opt; }
 #line 1946 "src/conf/parse_opts.cc"
 yy467:
        ++YYCURSOR;
-#line 133 "../src/conf/parse_opts.re"
+#line 135 "../src/conf/parse_opts.re"
        { vernum ();  return EXIT_OK; }
 #line 1951 "src/conf/parse_opts.cc"
 yy469:
@@ -2062,12 +2062,12 @@ yy496:
        goto yy277;
 yy497:
        ++YYCURSOR;
-#line 154 "../src/conf/parse_opts.re"
-       { opts.set_encoding(Enc::UTF32);  goto opt; }
+#line 158 "../src/conf/parse_opts.re"
+       { opts.set_encoding(Enc::UTF32);     goto opt; }
 #line 2068 "src/conf/parse_opts.cc"
 yy499:
        ++YYCURSOR;
-#line 132 "../src/conf/parse_opts.re"
+#line 134 "../src/conf/parse_opts.re"
        { version (); return EXIT_OK; }
 #line 2073 "src/conf/parse_opts.cc"
 yy501:
@@ -2113,8 +2113,8 @@ yy509:
        }
 yy510:
        ++YYCURSOR;
-#line 166 "../src/conf/parse_opts.re"
-       { opts.set_dump_nfa(true);        goto opt; }
+#line 170 "../src/conf/parse_opts.re"
+       { globopts.dump_nfa = true;        goto opt; }
 #line 2119 "src/conf/parse_opts.cc"
 yy512:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -2122,8 +2122,8 @@ yy512:
        goto yy277;
 yy513:
        ++YYCURSOR;
-#line 137 "../src/conf/parse_opts.re"
-       { opts.set_target (TARGET_DOT);      goto opt; }
+#line 138 "../src/conf/parse_opts.re"
+       { globopts.target = TARGET_DOT;      goto opt; }
 #line 2128 "src/conf/parse_opts.cc"
 yy515:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -2163,8 +2163,8 @@ yy523:
        goto yy277;
 yy524:
        ++YYCURSOR;
-#line 142 "../src/conf/parse_opts.re"
-       { opts.set_rFlag (true);             goto opt; }
+#line 141 "../src/conf/parse_opts.re"
+       { globopts.rFlag = true;             goto opt; }
 #line 2169 "src/conf/parse_opts.cc"
 yy526:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -2172,8 +2172,8 @@ yy526:
        goto yy277;
 yy527:
        ++YYCURSOR;
-#line 148 "../src/conf/parse_opts.re"
-       { opts.set_target (TARGET_SKELETON); goto opt; }
+#line 144 "../src/conf/parse_opts.re"
+       { globopts.target = TARGET_SKELETON; goto opt; }
 #line 2178 "src/conf/parse_opts.cc"
 yy529:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -2217,8 +2217,8 @@ yy538:
        goto yy277;
 yy539:
        ++YYCURSOR;
-#line 171 "../src/conf/parse_opts.re"
-       { opts.set_dump_adfa(true);       goto opt; }
+#line 175 "../src/conf/parse_opts.re"
+       { globopts.dump_adfa = true;       goto opt; }
 #line 2223 "src/conf/parse_opts.cc"
 yy541:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -2338,7 +2338,7 @@ yy569:
        goto yy277;
 yy570:
        ++YYCURSOR;
-#line 152 "../src/conf/parse_opts.re"
+#line 156 "../src/conf/parse_opts.re"
        { opts.set_eager_skip(true);         goto opt; }
 #line 2344 "src/conf/parse_opts.cc"
 yy572:
@@ -2355,7 +2355,7 @@ yy574:
        goto yy277;
 yy575:
        ++YYCURSOR;
-#line 143 "../src/conf/parse_opts.re"
+#line 150 "../src/conf/parse_opts.re"
        { opts.set_sFlag (true);             goto opt; }
 #line 2361 "src/conf/parse_opts.cc"
 yy577:
@@ -2372,8 +2372,8 @@ yy579:
        goto yy277;
 yy580:
        ++YYCURSOR;
-#line 145 "../src/conf/parse_opts.re"
-       { opts.set_version (false);          goto opt; }
+#line 143 "../src/conf/parse_opts.re"
+       { globopts.version = false;          goto opt; }
 #line 2378 "src/conf/parse_opts.cc"
 yy582:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -2397,12 +2397,12 @@ yy586:
        goto yy277;
 yy587:
        ++YYCURSOR;
-#line 155 "../src/conf/parse_opts.re"
-       { opts.set_encoding(Enc::UCS2);   goto opt; }
+#line 159 "../src/conf/parse_opts.re"
+       { opts.set_encoding(Enc::UCS2);      goto opt; }
 #line 2403 "src/conf/parse_opts.cc"
 yy589:
        ++YYCURSOR;
-#line 134 "../src/conf/parse_opts.re"
+#line 146 "../src/conf/parse_opts.re"
        { opts.set_bFlag (true);             goto opt; }
 #line 2408 "src/conf/parse_opts.cc"
 yy591:
@@ -2443,7 +2443,7 @@ yy599:
        goto yy277;
 yy600:
        ++YYCURSOR;
-#line 162 "../src/conf/parse_opts.re"
+#line 166 "../src/conf/parse_opts.re"
        { goto opt_empty_class; }
 #line 2449 "src/conf/parse_opts.cc"
 yy602:
@@ -2452,8 +2452,8 @@ yy602:
        goto yy277;
 yy603:
        ++YYCURSOR;
-#line 139 "../src/conf/parse_opts.re"
-       { opts.set_FFlag (true);             goto opt; }
+#line 140 "../src/conf/parse_opts.re"
+       { globopts.FFlag = true;             goto opt; }
 #line 2458 "src/conf/parse_opts.cc"
 yy605:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -2473,7 +2473,7 @@ yy608:
        goto yy277;
 yy609:
        ++YYCURSOR;
-#line 164 "../src/conf/parse_opts.re"
+#line 168 "../src/conf/parse_opts.re"
        { goto opt; }
 #line 2479 "src/conf/parse_opts.cc"
 yy611:
@@ -2486,7 +2486,7 @@ yy612:
        goto yy277;
 yy613:
        ++YYCURSOR;
-#line 159 "../src/conf/parse_opts.re"
+#line 163 "../src/conf/parse_opts.re"
        { if (!next (YYCURSOR, argv)) { error_arg ("-t, --type-header"); return EXIT_FAIL; } goto opt_header; }
 #line 2492 "src/conf/parse_opts.cc"
 yy615:
@@ -2503,7 +2503,7 @@ yy617:
        goto yy277;
 yy618:
        ++YYCURSOR;
-#line 136 "../src/conf/parse_opts.re"
+#line 147 "../src/conf/parse_opts.re"
        { opts.set_dFlag (true);             goto opt; }
 #line 2509 "src/conf/parse_opts.cc"
 yy620:
@@ -2512,18 +2512,18 @@ yy620:
        goto yy277;
 yy621:
        ++YYCURSOR;
-#line 168 "../src/conf/parse_opts.re"
-       { opts.set_dump_dfa_det(true);    goto opt; }
+#line 172 "../src/conf/parse_opts.re"
+       { globopts.dump_dfa_det = true;    goto opt; }
 #line 2518 "src/conf/parse_opts.cc"
 yy623:
        ++YYCURSOR;
-#line 170 "../src/conf/parse_opts.re"
-       { opts.set_dump_dfa_min(true);    goto opt; }
+#line 174 "../src/conf/parse_opts.re"
+       { globopts.dump_dfa_min = true;    goto opt; }
 #line 2523 "src/conf/parse_opts.cc"
 yy625:
        ++YYCURSOR;
-#line 167 "../src/conf/parse_opts.re"
-       { opts.set_dump_dfa_raw(true);    goto opt; }
+#line 171 "../src/conf/parse_opts.re"
+       { globopts.dump_dfa_raw = true;    goto opt; }
 #line 2528 "src/conf/parse_opts.cc"
 yy627:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -2543,7 +2543,7 @@ yy630:
        goto yy277;
 yy631:
        ++YYCURSOR;
-#line 151 "../src/conf/parse_opts.re"
+#line 155 "../src/conf/parse_opts.re"
        { opts.set_lookahead(false);         goto opt; }
 #line 2549 "src/conf/parse_opts.cc"
 yy633:
@@ -2564,7 +2564,7 @@ yy636:
        goto yy277;
 yy637:
        ++YYCURSOR;
-#line 147 "../src/conf/parse_opts.re"
+#line 152 "../src/conf/parse_opts.re"
        { opts.set_bCaseInverted (true);     goto opt; }
 #line 2570 "src/conf/parse_opts.cc"
 yy639:
@@ -2585,7 +2585,7 @@ yy642:
        goto yy277;
 yy643:
        ++YYCURSOR;
-#line 141 "../src/conf/parse_opts.re"
+#line 149 "../src/conf/parse_opts.re"
        { opts.set_iFlag (true);             goto opt; }
 #line 2591 "src/conf/parse_opts.cc"
 yy645:
@@ -2610,7 +2610,7 @@ yy649:
        goto yy277;
 yy650:
        ++YYCURSOR;
-#line 140 "../src/conf/parse_opts.re"
+#line 148 "../src/conf/parse_opts.re"
        { opts.set_gFlag (true);             goto opt; }
 #line 2616 "src/conf/parse_opts.cc"
 yy652:
@@ -2631,8 +2631,8 @@ yy655:
        goto yy277;
 yy656:
        ++YYCURSOR;
-#line 150 "../src/conf/parse_opts.re"
-       { opts.set_posix_captures (true);    goto opt; }
+#line 154 "../src/conf/parse_opts.re"
+       { opts.set_posix_captures(true);     goto opt; }
 #line 2637 "src/conf/parse_opts.cc"
 yy658:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -2640,8 +2640,8 @@ yy658:
        goto yy277;
 yy659:
        ++YYCURSOR;
-#line 138 "../src/conf/parse_opts.re"
-       { opts.set_fFlag (true);             goto opt; }
+#line 139 "../src/conf/parse_opts.re"
+       { globopts.fFlag = true;             goto opt; }
 #line 2646 "src/conf/parse_opts.cc"
 yy661:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -2653,12 +2653,12 @@ yy662:
        goto yy277;
 yy663:
        ++YYCURSOR;
-#line 169 "../src/conf/parse_opts.re"
-       { opts.set_dump_dfa_tagopt(true); goto opt; }
+#line 173 "../src/conf/parse_opts.re"
+       { globopts.dump_dfa_tagopt = true; goto opt; }
 #line 2659 "src/conf/parse_opts.cc"
 yy665:
        ++YYCURSOR;
-#line 160 "../src/conf/parse_opts.re"
+#line 164 "../src/conf/parse_opts.re"
        { goto opt_encoding_policy; }
 #line 2664 "src/conf/parse_opts.cc"
 yy667:
@@ -2671,12 +2671,12 @@ yy668:
        goto yy277;
 yy669:
        ++YYCURSOR;
-#line 146 "../src/conf/parse_opts.re"
+#line 151 "../src/conf/parse_opts.re"
        { opts.set_bCaseInsensitive (true);  goto opt; }
 #line 2677 "src/conf/parse_opts.cc"
 yy671:
        ++YYCURSOR;
-#line 163 "../src/conf/parse_opts.re"
+#line 167 "../src/conf/parse_opts.re"
        { goto opt_dfa_minimization; }
 #line 2682 "src/conf/parse_opts.cc"
 yy673:
@@ -2685,18 +2685,18 @@ yy673:
        goto yy277;
 yy674:
        ++YYCURSOR;
-#line 135 "../src/conf/parse_opts.re"
-       { opts.set_cFlag (true);             goto opt; }
+#line 137 "../src/conf/parse_opts.re"
+       { globopts.cFlag = true;             goto opt; }
 #line 2691 "src/conf/parse_opts.cc"
 yy676:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych >= 0x01) goto yy277;
        ++YYCURSOR;
-#line 144 "../src/conf/parse_opts.re"
-       { opts.set_bNoGenerationDate (true); goto opt; }
+#line 142 "../src/conf/parse_opts.re"
+       { globopts.bNoGenerationDate = true; goto opt; }
 #line 2698 "src/conf/parse_opts.cc"
 }
-#line 172 "../src/conf/parse_opts.re"
+#line 176 "../src/conf/parse_opts.re"
 
 
 opt_output:
@@ -2743,7 +2743,7 @@ opt_output:
        if (yych != '-') goto yy683;
 yy681:
        ++YYCURSOR;
-#line 177 "../src/conf/parse_opts.re"
+#line 181 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option -o, --output: %s", *argv);
                return EXIT_FAIL;
@@ -2755,11 +2755,11 @@ yy683:
                goto yy683;
        }
        ++YYCURSOR;
-#line 181 "../src/conf/parse_opts.re"
-       { opts.set_output_file(*argv); goto opt; }
+#line 185 "../src/conf/parse_opts.re"
+       { globopts.output_file = *argv; goto opt; }
 #line 2761 "src/conf/parse_opts.cc"
 }
-#line 182 "../src/conf/parse_opts.re"
+#line 186 "../src/conf/parse_opts.re"
 
 
 opt_header:
@@ -2806,7 +2806,7 @@ opt_header:
        if (yych != '-') goto yy691;
 yy689:
        ++YYCURSOR;
-#line 187 "../src/conf/parse_opts.re"
+#line 191 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option -t, --type-header: %s", *argv);
                return EXIT_FAIL;
@@ -2818,11 +2818,11 @@ yy691:
                goto yy691;
        }
        ++YYCURSOR;
-#line 191 "../src/conf/parse_opts.re"
-       { opts.set_header_file (*argv); goto opt; }
+#line 195 "../src/conf/parse_opts.re"
+       { globopts.header_file = *argv; goto opt; }
 #line 2824 "src/conf/parse_opts.cc"
 }
-#line 192 "../src/conf/parse_opts.re"
+#line 196 "../src/conf/parse_opts.re"
 
 
 opt_encoding_policy:
@@ -2844,7 +2844,7 @@ opt_encoding_policy:
        }
        ++YYCURSOR;
 yy698:
-#line 202 "../src/conf/parse_opts.re"
+#line 206 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option --encoding-policy (expected: ignore | substitute | fail): %s", *argv);
                return EXIT_FAIL;
@@ -2902,7 +2902,7 @@ yy711:
        goto yy703;
 yy712:
        ++YYCURSOR;
-#line 208 "../src/conf/parse_opts.re"
+#line 212 "../src/conf/parse_opts.re"
        { opts.set_encoding_policy (Enc::POLICY_FAIL);       goto opt; }
 #line 2908 "src/conf/parse_opts.cc"
 yy714:
@@ -2923,7 +2923,7 @@ yy717:
        goto yy703;
 yy718:
        ++YYCURSOR;
-#line 206 "../src/conf/parse_opts.re"
+#line 210 "../src/conf/parse_opts.re"
        { opts.set_encoding_policy (Enc::POLICY_IGNORE);     goto opt; }
 #line 2929 "src/conf/parse_opts.cc"
 yy720:
@@ -2936,11 +2936,11 @@ yy720:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych >= 0x01) goto yy703;
        ++YYCURSOR;
-#line 207 "../src/conf/parse_opts.re"
+#line 211 "../src/conf/parse_opts.re"
        { opts.set_encoding_policy (Enc::POLICY_SUBSTITUTE); goto opt; }
 #line 2942 "src/conf/parse_opts.cc"
 }
-#line 209 "../src/conf/parse_opts.re"
+#line 213 "../src/conf/parse_opts.re"
 
 
 opt_input:
@@ -2960,7 +2960,7 @@ opt_input:
 yy728:
        ++YYCURSOR;
 yy729:
-#line 219 "../src/conf/parse_opts.re"
+#line 223 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option --input (expected: default | custom): %s", *argv);
                return EXIT_FAIL;
@@ -3018,18 +3018,18 @@ yy742:
        goto yy733;
 yy743:
        ++YYCURSOR;
-#line 224 "../src/conf/parse_opts.re"
+#line 228 "../src/conf/parse_opts.re"
        { opts.set_input_api(INPUT_CUSTOM);  goto opt; }
 #line 3024 "src/conf/parse_opts.cc"
 yy745:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych >= 0x01) goto yy733;
        ++YYCURSOR;
-#line 223 "../src/conf/parse_opts.re"
+#line 227 "../src/conf/parse_opts.re"
        { opts.set_input_api(INPUT_DEFAULT); goto opt; }
 #line 3031 "src/conf/parse_opts.cc"
 }
-#line 225 "../src/conf/parse_opts.re"
+#line 229 "../src/conf/parse_opts.re"
 
 
 opt_empty_class:
@@ -3047,7 +3047,7 @@ opt_empty_class:
        if (yych == 'm') goto yy753;
        ++YYCURSOR;
 yy751:
-#line 235 "../src/conf/parse_opts.re"
+#line 239 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option --empty-class (expected: match-empty | match-none | error): %s", *argv);
                return EXIT_FAIL;
@@ -3097,7 +3097,7 @@ yy762:
        goto yy755;
 yy763:
        ++YYCURSOR;
-#line 241 "../src/conf/parse_opts.re"
+#line 245 "../src/conf/parse_opts.re"
        { opts.set_empty_class_policy (EMPTY_CLASS_ERROR);       goto opt; }
 #line 3103 "src/conf/parse_opts.cc"
 yy765:
@@ -3143,16 +3143,16 @@ yy774:
        goto yy755;
 yy775:
        ++YYCURSOR;
-#line 240 "../src/conf/parse_opts.re"
+#line 244 "../src/conf/parse_opts.re"
        { opts.set_empty_class_policy (EMPTY_CLASS_MATCH_NONE);  goto opt; }
 #line 3149 "src/conf/parse_opts.cc"
 yy777:
        ++YYCURSOR;
-#line 239 "../src/conf/parse_opts.re"
+#line 243 "../src/conf/parse_opts.re"
        { opts.set_empty_class_policy (EMPTY_CLASS_MATCH_EMPTY); goto opt; }
 #line 3154 "src/conf/parse_opts.cc"
 }
-#line 242 "../src/conf/parse_opts.re"
+#line 246 "../src/conf/parse_opts.re"
 
 
 opt_dfa_minimization:
@@ -3170,7 +3170,7 @@ opt_dfa_minimization:
        if (yych == 't') goto yy784;
        ++YYCURSOR;
 yy782:
-#line 252 "../src/conf/parse_opts.re"
+#line 256 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option --dfa-minimization (expected: table | moore): %s", *argv);
                return EXIT_FAIL;
@@ -3220,16 +3220,16 @@ yy793:
        goto yy786;
 yy794:
        ++YYCURSOR;
-#line 257 "../src/conf/parse_opts.re"
+#line 261 "../src/conf/parse_opts.re"
        { opts.set_dfa_minimization (DFA_MINIMIZATION_MOORE); goto opt; }
 #line 3226 "src/conf/parse_opts.cc"
 yy796:
        ++YYCURSOR;
-#line 256 "../src/conf/parse_opts.re"
+#line 260 "../src/conf/parse_opts.re"
        { opts.set_dfa_minimization (DFA_MINIMIZATION_TABLE); goto opt; }
 #line 3231 "src/conf/parse_opts.cc"
 }
-#line 258 "../src/conf/parse_opts.re"
+#line 262 "../src/conf/parse_opts.re"
 
 
 end:
@@ -3238,6 +3238,7 @@ end:
                error ("no source file");
                return EXIT_FAIL;
        }
+       globopts.fix();
 
        return OK;
 
index 5acdf77754dd875abd2bfc1c53674094f831a841..a028f6287125eb96dea23e0ca7184eae69a51752 100644 (file)
@@ -56,7 +56,7 @@ lineinf = lineno (space+ dstring)? eol;
        esc_simple = esc [abfnrtv\\];
 */
 
-Scanner::ParseMode Scanner::echo()
+Scanner::ParseMode Scanner::echo(OutputFile &out)
 {
        if (eof && cur == eof) // Catch EOF
        {
@@ -85,21 +85,21 @@ echo:
 
        "/*!ignore:re2c" {
                out.wraw(tok, ptr);
-               lex_end_of_comment();
+               lex_end_of_comment(out);
                goto echo;
        }
 
        "/*!max:re2c" {
                out.wraw(tok, ptr);
                out.wdelay_yymaxfill();
-               lex_end_of_comment();
+               lex_end_of_comment(out);
                goto echo;
        }
 
        "/*!getstate:re2c" {
                out.wraw(tok, ptr);
                out.wdelay_state_goto(0);
-               lex_end_of_comment();
+               lex_end_of_comment(out);
                goto echo;
        }
 
@@ -108,13 +108,13 @@ echo:
                out.wdelay_line_info();
                out.wdelay_types();
                out.wline_info(cline, get_fname().c_str());
-               lex_end_of_comment();
+               lex_end_of_comment(out);
                goto echo;
        }
 
        "/*!tags:re2c" {
                out.wraw(tok, ptr);
-               lex_tags();
+               lex_tags(out);
                goto echo;
        }
 
@@ -139,7 +139,7 @@ echo:
 */
 }
 
-void Scanner::lex_end_of_comment()
+void Scanner::lex_end_of_comment(OutputFile &out)
 {
        uint32_t ignored = 0;
        for (;;) {/*!re2c
@@ -158,7 +158,7 @@ void Scanner::lex_end_of_comment()
        */}
 }
 
-void Scanner::lex_tags()
+void Scanner::lex_tags(OutputFile &out)
 {
        std::string fmt, sep;
        for (;;) {/*!re2c
@@ -177,7 +177,7 @@ void Scanner::lex_tags()
        */}
 }
 
-int Scanner::scan()
+int Scanner::scan(const conopt_t *globopts)
 {
        uint32_t depth, code_line;
 scan:
@@ -264,18 +264,18 @@ scan:
                                }
 
        "{" name "}"    {
-                                       if (!opts->FFlag) {
+                                       if (!globopts->FFlag) {
                                                fatal("curly braces for names only allowed with -F switch");
                                        }
                                        yylval.str = new std::string (tok + 1, tok_len () - 2); // -2 to omit braces
                                        return TOKEN_ID;
                                }
 
-       "re2c:" { lex_conf (); return TOKEN_CONF; }
+       "re2c:" { return TOKEN_CONF; }
 
        name / (space+ [^=>,])  {
                                        yylval.str = new std::string (tok, tok_len ());
-                                       if (opts->FFlag)
+                                       if (globopts->FFlag)
                                        {
                                                lexer_state = LEX_FLEX_NAME;
                                                return TOKEN_FID;
@@ -292,7 +292,7 @@ scan:
                                }
 
        name / [^]      {
-                                       if (!opts->FFlag) {
+                                       if (!globopts->FFlag) {
                                                yylval.str = new std::string (tok, tok_len());
                                                return TOKEN_ID;
                                        } else {
index a6b46400e64ed5d89d900c9e3a2378fd5c29c63e..3b78b1262270005b904f789fc742dcc54808123c 100644 (file)
@@ -34,7 +34,7 @@ namespace re2c
        number = "0" | ("-"? [1-9] [0-9]*);
 */
 
-void Scanner::lex_conf ()
+void Scanner::lex_conf(Opt &opts)
 {
        tok = cur;
 /*!re2c
@@ -50,16 +50,16 @@ void Scanner::lex_conf ()
        "flags:no-lookahead"                 { opts.set_lookahead(!lex_conf_bool());         return; }
        "flags:eager-skip"                   { opts.set_eager_skip(lex_conf_bool());         return; }
 
-       "flags:" ("e" | "ecb")        { lex_conf_enc(Enc::EBCDIC); return; }
-       "flags:" ("u" | "unicode")    { lex_conf_enc(Enc::UTF32);  return; }
-       "flags:" ("w" | "wide-chars") { lex_conf_enc(Enc::UCS2);   return; }
-       "flags:" ("x" | "utf-16")     { lex_conf_enc(Enc::UTF16);  return; }
-       "flags:" ("8" | "utf-8")      { lex_conf_enc(Enc::UTF8);   return; }
+       "flags:" ("e" | "ecb")        { lex_conf_enc(Enc::EBCDIC, opts); return; }
+       "flags:" ("u" | "unicode")    { lex_conf_enc(Enc::UTF32, opts);  return; }
+       "flags:" ("w" | "wide-chars") { lex_conf_enc(Enc::UCS2, opts);   return; }
+       "flags:" ("x" | "utf-16")     { lex_conf_enc(Enc::UTF16, opts);  return; }
+       "flags:" ("8" | "utf-8")      { lex_conf_enc(Enc::UTF8, opts);   return; }
 
-       "flags:encoding-policy"  { lex_conf_encoding_policy();  return; }
-       "flags:input"            { lex_conf_input();            return; }
-       "flags:empty-class"      { lex_conf_empty_class();      return; }
-       "flags:dfa-minimization" { lex_conf_dfa_minimization(); return; }
+       "flags:encoding-policy"  { lex_conf_encoding_policy(opts);  return; }
+       "flags:input"            { lex_conf_input(opts);            return; }
+       "flags:empty-class"      { lex_conf_empty_class(opts);      return; }
+       "flags:dfa-minimization" { lex_conf_dfa_minimization(opts); return; }
 
        "define:YYCONDTYPE"           { opts.set_yycondtype       (lex_conf_string ()); return; }
        "define:YYGETCONDITION"       { opts.set_cond_get         (lex_conf_string ()); return; }
@@ -163,7 +163,7 @@ void Scanner::lex_conf ()
 */
 }
 
-void Scanner::lex_conf_encoding_policy()
+void Scanner::lex_conf_encoding_policy(Opt &opts)
 {
        lex_conf_assign ();
 /*!re2c
@@ -177,7 +177,7 @@ end:
        lex_conf_semicolon();
 }
 
-void Scanner::lex_conf_input()
+void Scanner::lex_conf_input(Opt &opts)
 {
        lex_conf_assign ();
 /*!re2c
@@ -190,7 +190,7 @@ end:
        lex_conf_semicolon();
 }
 
-void Scanner::lex_conf_empty_class()
+void Scanner::lex_conf_empty_class(Opt &opts)
 {
        lex_conf_assign ();
 /*!re2c
@@ -204,7 +204,7 @@ end:
        lex_conf_semicolon();
 }
 
-void Scanner::lex_conf_dfa_minimization()
+void Scanner::lex_conf_dfa_minimization(Opt &opts)
 {
        lex_conf_assign ();
 /*!re2c
@@ -217,7 +217,7 @@ end:
        lex_conf_semicolon();
 }
 
-void Scanner::lex_conf_enc(Enc::type_t enc)
+void Scanner::lex_conf_enc(Enc::type_t enc, Opt &opts)
 {
        if (lex_conf_bool()) {
                opts.set_encoding(enc);
index 543ad5dea746e18504115985ccc6ee7a019b2a14..563441d0106151b1990fd490c7cfdcd8e141174d 100644 (file)
@@ -14,7 +14,7 @@ namespace re2c
 
 struct DFA;
 
-void parse(Scanner &input, Output &output);
+void parse(Scanner &input, Output &output, Opt &opts);
 
 struct spec_t
 {
@@ -37,6 +37,7 @@ struct context_t
        Scanner &input;
        specs_t &specs;
        symtab_t &symtab;
+       Opt &opts;
 };
 
 } // namespace re2c
index 047049eb88a2d98c102799859f9c19eac132a3e9..75fbec77dde7ef79ea43e218b913477f6db6869c 100644 (file)
@@ -219,7 +219,7 @@ static spec_t &find(specs_t &specs, const std::string &name)
 
 spec
        : /* empty */
-       | spec TOKEN_CONF
+       | spec TOKEN_CONF { context.input.lex_conf(context.opts); }
        | spec def
        | spec rule
        | spec TOKEN_LINE_INFO
@@ -408,7 +408,7 @@ void yyerror(context_t &context, const char* s)
 
 int yylex(context_t &context)
 {
-       return context.input.scan();
+       return context.input.scan(&context.opts.glob);
 }
 
 } // extern "C"
@@ -416,27 +416,27 @@ int yylex(context_t &context)
 namespace re2c
 {
 
-void parse(Scanner &input, Output &output)
+void parse(Scanner &input, Output &output, Opt &opts)
 {
        specs_t rspecs;
        symtab_t symtab;
-       Opt &opts = input.opts;
+       const conopt_t *globopts = &opts.glob;
        const opt_t *ropts = NULL;
        OutputFile &o = output.source;
 
        o.new_block(opts);
        o.wversion_time().wline_info(input.get_cline(), input.get_fname().c_str());
-       if (opts->target == TARGET_SKELETON) {
+       if (globopts->target == TARGET_SKELETON) {
                emit_prolog(o);
        }
 
-       for (Scanner::ParseMode mode; (mode = input.echo()) != Scanner::Stop;) {
+       for (Scanner::ParseMode mode; (mode = input.echo(o)) != Scanner::Stop;) {
 
-               check_mode(mode, opts->rFlag, ropts, input);
+               check_mode(mode, globopts->rFlag, ropts, input);
 
                // parse next re2c block
                specs_t specs;
-               context_t context = {input, specs, symtab};
+               context_t context = {input, specs, symtab, opts};
                if (mode == Scanner::Reuse) {
                        specs = rspecs;
                        opts.restore(ropts);
@@ -457,7 +457,7 @@ void parse(Scanner &input, Output &output)
                        ropts = o.block().opts;
                } else {
                        // validate and normalize AST
-                       check_specs(specs, opts->cFlag);
+                       check_specs(specs, globopts->cFlag);
                        prepare_specs(specs);
 
                        // compile AST to DFA
@@ -469,7 +469,7 @@ void parse(Scanner &input, Output &output)
 
                        // compile DFA to code
                        bool prolog = false;
-                       uint32_t ind = opts->topIndent;
+                       uint32_t ind = o.block().opts->topIndent;
                        for (dfas_t::const_iterator i = dfas.begin(); i != dfas.end(); ++i) {
                                (*i)->emit(output, ind, (i + 1) == dfas.end(), prolog);
                        }
@@ -478,7 +478,7 @@ void parse(Scanner &input, Output &output)
                o.wline_info (input.get_cline (), input.get_fname ().c_str ());
        }
 
-       if (opts->target == TARGET_SKELETON) {
+       if (globopts->target == TARGET_SKELETON) {
                emit_epilog (o, output.skeletons);
        }
 
index 3651096d43e5a7fb7d1f6cd46f3b78cb9974b522..3ce2b2aa438e6d4e595e74da28c3b79a29a60c02 100644 (file)
@@ -35,13 +35,8 @@ ScannerState::ScannerState ()
        , lexer_state (LEX_NORMAL)
 {}
 
-Scanner::Scanner (Input & i, OutputFile & o, Opt &p)
-       : ScannerState ()
-       , in (i)
-       , out (o)
-       , opts (p)
-       , warn (o.warn)
-{}
+Scanner::Scanner(Input &i, Warn &w)
+       : ScannerState(), in(i), warn(w) {}
 
 void Scanner::fill (uint32_t need)
 {
index ef0fe2e271daf6427e770d5530018c5a78610547..96fe51a58ed0c1fbff767cb2bb3ac9f35a2b4588 100644 (file)
@@ -52,49 +52,37 @@ struct ScannerState
 class Scanner: private ScannerState
 {
        static const uint32_t BSIZE;
-
        Input & in;
-public:
-       OutputFile & out;
-       Opt &opts;
        Warn &warn;
 
-private:
        void fill (uint32_t);
-       void lex_end_of_comment();
-       void lex_tags();
+       void lex_end_of_comment(OutputFile &out);
+       void lex_tags(OutputFile &out);
        void set_sourceline ();
        uint32_t lex_cls_chr();
        uint32_t lex_str_chr(char quote, bool &end);
        const AST *lex_cls(bool neg);
        const AST *lex_str(char quote);
-       void lex_conf ();
-       void lex_conf_encoding_policy();
-       void lex_conf_input();
-       void lex_conf_empty_class();
-       void lex_conf_dfa_minimization();
-       void lex_conf_enc(Enc::type_t enc);
+       void lex_conf_encoding_policy(Opt &opts);
+       void lex_conf_input(Opt &opts);
+       void lex_conf_empty_class(Opt &opts);
+       void lex_conf_dfa_minimization(Opt &opts);
+       void lex_conf_enc(Enc::type_t enc, Opt &opts);
        void lex_conf_assign();
        void lex_conf_semicolon();
        int32_t lex_conf_number();
        bool lex_conf_bool();
        std::string lex_conf_string();
-
        size_t tok_len () const;
 
 public:
-       Scanner(Input &, OutputFile &, Opt &);
-       ~Scanner();
+       enum ParseMode {Stop, Parse, Reuse, Rules};
 
-       enum ParseMode {
-               Stop,
-               Parse,
-               Reuse,
-               Rules
-       };
-
-       ParseMode echo();
-       int scan();
+       Scanner(Input&, Warn &w);
+       ~Scanner();
+       ParseMode echo(OutputFile &out);
+       int scan(const conopt_t *globopts);
+       void lex_conf(Opt &opts);
        uint32_t get_cline() const;
        uint32_t get_column() const;
        const std::string & get_fname () const;
index 2d2de59a2d9f6b0088eeeb539b5b8320a202783f..f3363b6dfb0ee5f6630e72d1f04a1f689f0dcdd4 100644 (file)
@@ -492,21 +492,13 @@ bool OutputFile::emit(const uniq_vector_t<std::string> &global_types,
 
 bool HeaderFile::emit(const opt_t *opts, const uniq_vector_t<std::string> &types)
 {
-       if (!opts->tFlag) {
-               return true;
-       }
+       const std::string &filename = opts->header_file;
+       if (filename.empty()) return true;
 
-       FILE *file = NULL;
-       std::string filename = opts->header_file;
-       if (filename.empty()) {
-               filename = "<stdout>.h";
-               file = stdout;
-       } else {
-               file = fopen(filename.c_str(), "wb");
-               if (!file) {
-                       error("cannot open header file: %s", filename.c_str());
-                       return false;
-               }
+       FILE *file = fopen(filename.c_str(), "wb");
+       if (!file) {
+               error("cannot open header file: %s", filename.c_str());
+               return false;
        }
 
        output_version_time(stream, opts->version, !opts->bNoGenerationDate);
index 5633537239af63330798a605b72269e4bb813e66..97c79a93447a3fb79779d1d08675ee220fdc4152 100644 (file)
@@ -4,38 +4,22 @@
 namespace re2c
 {
 
-opt_t::opt_t ()
-#define OPT1(type, name, value) : name (value)
-#define OPT(type, name, value)  , name (value)
-       RE2C_OPTS
-#undef OPT1
-#undef OPT
-{}
-
-opt_t::opt_t (const opt_t & opt)
-#define OPT1(type, name, value) : name (opt.name)
-#define OPT(type, name, value)  , name (opt.name)
-       RE2C_OPTS
-#undef OPT1
-#undef OPT
-{}
-
-opt_t & opt_t::operator = (const opt_t & opt)
+void conopt_t::fix()
 {
-#define OPT1 OPT
-#define OPT(type, name, value) name = opt.name;
-       RE2C_OPTS
-#undef OPT1
-#undef OPT
-       return *this;
+       if (target == TARGET_SKELETON) {
+               fFlag = false;
+               header_file = "";
+       }
+       if (!cFlag) {
+               header_file = "";
+       }
 }
 
-void opt_t::fix ()
+void mutopt_t::fix(const conopt_t *globopts)
 {
        // some options either make no sense or must have fixed value
        // with current target: reset them to default
-       switch (target)
-       {
+       switch (globopts->target) {
                case TARGET_DOT:
                        // default code generation options
                        sFlag = Opt::baseopt.sFlag;
@@ -54,8 +38,6 @@ void opt_t::fix ()
                        condDivider = Opt::baseopt.condDivider;
                        condDividerParam = Opt::baseopt.condDividerParam;
                        // default environment bindings
-                       tFlag = Opt::baseopt.tFlag;
-                       header_file = Opt::baseopt.header_file;
                        yycondtype = Opt::baseopt.yycondtype;
                        cond_get = Opt::baseopt.cond_get;
                        cond_get_naked = Opt::baseopt.cond_get_naked;
@@ -67,7 +49,6 @@ void opt_t::fix ()
                        condEnumPrefix = Opt::baseopt.condEnumPrefix;
                        condGoto = Opt::baseopt.condGoto;
                        condGotoParam = Opt::baseopt.condGotoParam;
-                       fFlag = Opt::baseopt.fFlag;
                        state_get = Opt::baseopt.state_get;
                        state_get_naked = Opt::baseopt.state_get_naked;
                        state_set = Opt::baseopt.state_set;
@@ -113,12 +94,6 @@ void opt_t::fix ()
                        labelPrefix = Opt::baseopt.labelPrefix;
                        startlabel = Opt::baseopt.startlabel;
                        startlabel_force = Opt::baseopt.startlabel_force;
-                       dump_nfa = Opt::baseopt.dump_nfa;
-                       dump_dfa_raw = Opt::baseopt.dump_dfa_raw;
-                       dump_dfa_det = Opt::baseopt.dump_dfa_det;
-                       dump_dfa_tagopt = Opt::baseopt.dump_dfa_tagopt;
-                       dump_dfa_min = Opt::baseopt.dump_dfa_min;
-                       dump_adfa = Opt::baseopt.dump_adfa;
                        break;
                default:
                        break;
@@ -130,10 +105,7 @@ void opt_t::fix ()
        }
 
        // respect hierarchy
-       if (!cFlag)
-       {
-               tFlag = Opt::baseopt.tFlag;
-               header_file = Opt::baseopt.header_file;
+       if (!globopts->cFlag) {
                yycondtype = Opt::baseopt.yycondtype;
                cond_get = Opt::baseopt.cond_get;
                cond_get_naked = Opt::baseopt.cond_get_naked;
@@ -148,8 +120,7 @@ void opt_t::fix ()
                condGoto = Opt::baseopt.condGoto;
                condGotoParam = Opt::baseopt.condGotoParam;
        }
-       if (!fFlag)
-       {
+       if (!globopts->fFlag) {
                state_get = Opt::baseopt.state_get;
                state_get_naked = Opt::baseopt.state_get_naked;
                state_set = Opt::baseopt.state_set;
@@ -214,8 +185,7 @@ void opt_t::fix ()
        }
 
        // force individual options
-       switch (target)
-       {
+       switch (globopts->target) {
                case TARGET_DOT:
                        iFlag = true;
                        break;
@@ -247,48 +217,12 @@ void opt_t::fix ()
                bFlag = true;
                sFlag = true;
        }
-       if (!header_file.empty())
-       {
-               tFlag = true;
-       }
        if (!lookahead) {
                eager_skip = true;
        }
 }
 
-realopt_t::realopt_t (useropt_t & opt)
-       : real ()
-       , user (opt)
-{}
-
-const opt_t * realopt_t::operator -> ()
-{
-       sync ();
-       return &real;
-}
-
-void realopt_t::sync ()
-{
-       if (user.diverge)
-       {
-               real = user.opt;
-               real.fix ();
-               user.diverge = false;
-       }
-}
-
-useropt_t::useropt_t ()
-       : opt ()
-       , diverge (true)
-{}
-
-opt_t * useropt_t::operator -> ()
-{
-       diverge = true;
-       return &opt;
-}
-
-const opt_t Opt::baseopt;
+const mutopt_t Opt::baseopt;
 
 bool Opt::source (const char *s)
 {
@@ -306,43 +240,43 @@ bool Opt::source (const char *s)
 
 void Opt::reset_startlabel()
 {
-       useropt->startlabel       = Opt::baseopt.startlabel;
-       useropt->startlabel_force = Opt::baseopt.startlabel_force;
+       set_startlabel(Opt::baseopt.startlabel);
+       set_startlabel_force(Opt::baseopt.startlabel_force);
 }
 
 void Opt::reset_mapCodeName ()
 {
        // historically arranged set of names
        // no actual reason why these particular options should be reset
-       useropt->cond_get = Opt::baseopt.cond_get;
-       useropt->cond_set = Opt::baseopt.cond_set;
-       useropt->fill = Opt::baseopt.fill;
-       useropt->state_get = Opt::baseopt.state_get;
-       useropt->state_set = Opt::baseopt.state_set;
-       useropt->yybackup = Opt::baseopt.yybackup;
-       useropt->yybackupctx = Opt::baseopt.yybackupctx;
-       useropt->yybackuptag = Opt::baseopt.yybackuptag;
-       useropt->yycondtype = Opt::baseopt.yycondtype;
-       useropt->yyctxmarker = Opt::baseopt.yyctxmarker;
-       useropt->yyctype = Opt::baseopt.yyctype;
-       useropt->yycursor = Opt::baseopt.yycursor;
-       useropt->yydebug = Opt::baseopt.yydebug;
-       useropt->yylessthan = Opt::baseopt.yylessthan;
-       useropt->yylimit = Opt::baseopt.yylimit;
-       useropt->yymarker = Opt::baseopt.yymarker;
-       useropt->yypeek = Opt::baseopt.yypeek;
-       useropt->yyrestore = Opt::baseopt.yyrestore;
-       useropt->yyrestorectx = Opt::baseopt.yyrestorectx;
-       useropt->yyrestoretag = Opt::baseopt.yyrestoretag;
-       useropt->yycopytag = Opt::baseopt.yycopytag;
-       useropt->yyskip = Opt::baseopt.yyskip;
-       useropt->yyfilllabel = Opt::baseopt.yyfilllabel;
-       useropt->yynext = Opt::baseopt.yynext;
-       useropt->yyaccept = Opt::baseopt.yyaccept;
-       useropt->yybm = Opt::baseopt.yybm;
-       useropt->yych = Opt::baseopt.yych;
-       useropt->yyctable = Opt::baseopt.yyctable;
-       useropt->yytarget = Opt::baseopt.yytarget;
+       set_cond_get(Opt::baseopt.cond_get);
+       set_cond_set(Opt::baseopt.cond_set);
+       set_fill(Opt::baseopt.fill);
+       set_state_get(Opt::baseopt.state_get);
+       set_state_set(Opt::baseopt.state_set);
+       set_yybackup(Opt::baseopt.yybackup);
+       set_yybackupctx(Opt::baseopt.yybackupctx);
+       set_yybackuptag(Opt::baseopt.yybackuptag);
+       set_yycondtype(Opt::baseopt.yycondtype);
+       set_yyctxmarker(Opt::baseopt.yyctxmarker);
+       set_yyctype(Opt::baseopt.yyctype);
+       set_yycursor(Opt::baseopt.yycursor);
+       set_yydebug(Opt::baseopt.yydebug);
+       set_yylessthan(Opt::baseopt.yylessthan);
+       set_yylimit(Opt::baseopt.yylimit);
+       set_yymarker(Opt::baseopt.yymarker);
+       set_yypeek(Opt::baseopt.yypeek);
+       set_yyrestore(Opt::baseopt.yyrestore);
+       set_yyrestorectx(Opt::baseopt.yyrestorectx);
+       set_yyrestoretag(Opt::baseopt.yyrestoretag);
+       set_yycopytag(Opt::baseopt.yycopytag);
+       set_yyskip(Opt::baseopt.yyskip);
+       set_yyfilllabel(Opt::baseopt.yyfilllabel);
+       set_yynext(Opt::baseopt.yynext);
+       set_yyaccept(Opt::baseopt.yyaccept);
+       set_yybm(Opt::baseopt.yybm);
+       set_yych(Opt::baseopt.yych);
+       set_yyctable(Opt::baseopt.yyctable);
+       set_yytarget(Opt::baseopt.yytarget);
 }
 
 } // namespace re2c
index 32481a0eb072137471a58e5818b499ce386902e5..80d520ef4d5e502466ffab3b67e0289b8a71eba9 100644 (file)
@@ -22,205 +22,264 @@ enum target_t
        TARGET_SKELETON
 };
 
-#define RE2C_OPTS \
-       /* target */ \
-       OPT1 (target_t, target, TARGET_CODE) \
-       /* output file */ \
-       OPT (std::string, output_file, "") \
-       /* fingerprint */ \
-       OPT (bool, bNoGenerationDate, false) \
-       OPT (bool, version, true) \
+/* note [constant and mutable options]
+ *
+ * Some options are immutable (target, output files; global switches like
+ * conditions, reuse mode, storable states; support of flex syntax, etc.).
+ * These options are passed as command-line arguments and never change.
+ * It is safe to read them from any program point after parsing command-line
+ * arguments.
+ *
+ * Other options are configurable; they have block scope (may be specified
+ * anywhere inside of the block and still affect the whole block).
+ * Reading mutable options of yet unparsed block is not allowed because
+ * they may affect the way RE2C parses current block (RE2C would be tempted
+ * to base decisions on the latest option value, which may not be the final
+ * one).
+ */
+
+#define RE2C_CONSTOPTS \
+       CONSTOPT1 (target_t, target, TARGET_CODE) \
+       CONSTOPT (std::string, output_file, "") \
+       CONSTOPT (std::string, header_file, "") \
+       CONSTOPT (bool, bNoGenerationDate, false) \
+       CONSTOPT (bool, version, true) \
+       CONSTOPT (bool, cFlag, false) \
+       CONSTOPT (bool, fFlag, false) \
+       CONSTOPT (bool, rFlag, false) \
+       CONSTOPT (bool, FFlag, false) \
+       /* debug */ \
+       CONSTOPT (bool, dump_nfa, false) \
+       CONSTOPT (bool, dump_dfa_raw, false) \
+       CONSTOPT (bool, dump_dfa_det, false) \
+       CONSTOPT (bool, dump_dfa_tagopt, false) \
+       CONSTOPT (bool, dump_dfa_min, false) \
+       CONSTOPT (bool, dump_adfa, false)
+
+#define RE2C_MUTOPTS \
        /* regular expressions */ \
-       OPT (Enc, encoding, Enc ()) \
-       OPT (bool, bCaseInsensitive, false) \
-       OPT (bool, bCaseInverted, false) \
-       OPT (empty_class_policy_t, empty_class_policy, EMPTY_CLASS_MATCH_EMPTY) \
+       MUTOPT1 (Enc, encoding, Enc ()) \
+       MUTOPT (bool, bCaseInsensitive, false) \
+       MUTOPT (bool, bCaseInverted, false) \
+       MUTOPT (empty_class_policy_t, empty_class_policy, EMPTY_CLASS_MATCH_EMPTY) \
        /* conditions */ \
-       OPT (bool, cFlag, false) \
-       OPT (bool, tFlag, false) \
-       OPT (std::string, header_file, "") \
-       OPT (std::string, yycondtype, "YYCONDTYPE") \
-       OPT (std::string, cond_get, "YYGETCONDITION") \
-       OPT (bool, cond_get_naked, false) \
-       OPT (std::string, cond_set, "YYSETCONDITION" ) \
-       OPT (std::string, cond_set_arg, "@@" ) \
-       OPT (bool, cond_set_naked, false ) \
-       OPT (std::string, yyctable, "yyctable") \
-       OPT (std::string, condPrefix, "yyc_") \
-       OPT (std::string, condEnumPrefix, "yyc") \
-       OPT (std::string, condDivider, "/* *********************************** */") \
-       OPT (std::string, condDividerParam, "@@") \
-       OPT (std::string, condGoto, "goto @@;") \
-       OPT (std::string, condGotoParam, "@@") \
+       MUTOPT (std::string, yycondtype, "YYCONDTYPE") \
+       MUTOPT (std::string, cond_get, "YYGETCONDITION") \
+       MUTOPT (bool, cond_get_naked, false) \
+       MUTOPT (std::string, cond_set, "YYSETCONDITION" ) \
+       MUTOPT (std::string, cond_set_arg, "@@" ) \
+       MUTOPT (bool, cond_set_naked, false ) \
+       MUTOPT (std::string, yyctable, "yyctable") \
+       MUTOPT (std::string, condPrefix, "yyc_") \
+       MUTOPT (std::string, condEnumPrefix, "yyc") \
+       MUTOPT (std::string, condDivider, "/* *********************************** */") \
+       MUTOPT (std::string, condDividerParam, "@@") \
+       MUTOPT (std::string, condGoto, "goto @@;") \
+       MUTOPT (std::string, condGotoParam, "@@") \
        /* states */ \
-       OPT (bool, fFlag, false) \
-       OPT (std::string, state_get, "YYGETSTATE") \
-       OPT (bool, state_get_naked, false) \
-       OPT (std::string, state_set, "YYSETSTATE") \
-       OPT (std::string, state_set_arg, "@@") \
-       OPT (bool, state_set_naked, false) \
-       OPT (std::string, yyfilllabel, "yyFillLabel") \
-       OPT (std::string, yynext, "yyNext") \
-       OPT (std::string, yyaccept, "yyaccept") \
-       OPT (bool, bUseStateAbort, false) \
-       OPT (bool, bUseStateNext, false) \
+       MUTOPT (std::string, state_get, "YYGETSTATE") \
+       MUTOPT (bool, state_get_naked, false) \
+       MUTOPT (std::string, state_set, "YYSETSTATE") \
+       MUTOPT (std::string, state_set_arg, "@@") \
+       MUTOPT (bool, state_set_naked, false) \
+       MUTOPT (std::string, yyfilllabel, "yyFillLabel") \
+       MUTOPT (std::string, yynext, "yyNext") \
+       MUTOPT (std::string, yyaccept, "yyaccept") \
+       MUTOPT (bool, bUseStateAbort, false) \
+       MUTOPT (bool, bUseStateNext, false) \
        /* tags */ \
-       OPT (bool, tags, false) \
-       OPT (std::string, tags_default, "NULL") \
-       OPT (std::string, tags_prefix, "yyt") \
-       OPT (std::string, tags_expression, "@@") \
-       OPT (bool, posix_captures, false) \
-       /* reuse */ \
-       OPT (bool, rFlag, false) \
-       /* partial flex syntax support */ \
-       OPT (bool, FFlag, false) \
+       MUTOPT (bool, tags, false) \
+       MUTOPT (std::string, tags_default, "NULL") \
+       MUTOPT (std::string, tags_prefix, "yyt") \
+       MUTOPT (std::string, tags_expression, "@@") \
+       MUTOPT (bool, posix_captures, false) \
        /* code generation */ \
-       OPT (bool, sFlag, false) \
-       OPT (bool, bFlag, false) \
-       OPT (std::string, yybm, "yybm") \
-       OPT (bool, yybmHexTable, false) \
-       OPT (bool, gFlag, false) \
-       OPT (std::string, yytarget, "yytarget") \
-       OPT (uint32_t, cGotoThreshold, 9) \
+       MUTOPT (bool, sFlag, false) \
+       MUTOPT (bool, bFlag, false) \
+       MUTOPT (std::string, yybm, "yybm") \
+       MUTOPT (bool, yybmHexTable, false) \
+       MUTOPT (bool, gFlag, false) \
+       MUTOPT (std::string, yytarget, "yytarget") \
+       MUTOPT (uint32_t, cGotoThreshold, 9) \
        /* formatting */ \
-       OPT (uint32_t, topIndent, 0) \
-       OPT (std::string, indString, "\t") \
+       MUTOPT (uint32_t, topIndent, 0) \
+       MUTOPT (std::string, indString, "\t") \
        /* input API */ \
-       OPT (input_api_t, input_api, INPUT_DEFAULT) \
-       OPT (std::string, yycursor, "YYCURSOR") \
-       OPT (std::string, yymarker, "YYMARKER") \
-       OPT (std::string, yyctxmarker, "YYCTXMARKER") \
-       OPT (std::string, yylimit, "YYLIMIT") \
-       OPT (std::string, yypeek, "YYPEEK") \
-       OPT (std::string, yyskip, "YYSKIP") \
-       OPT (std::string, yybackup, "YYBACKUP") \
-       OPT (std::string, yybackupctx, "YYBACKUPCTX") \
-       OPT (std::string, yybackuptag, "YYBACKUPTAG") \
-       OPT (std::string, yyrestore, "YYRESTORE") \
-       OPT (std::string, yyrestorectx, "YYRESTORECTX") \
-       OPT (std::string, yyrestoretag, "YYRESTORETAG") \
-       OPT (std::string, yycopytag, "YYCOPYTAG") \
-       OPT (std::string, yylessthan, "YYLESSTHAN") \
+       MUTOPT (input_api_t, input_api, INPUT_DEFAULT) \
+       MUTOPT (std::string, yycursor, "YYCURSOR") \
+       MUTOPT (std::string, yymarker, "YYMARKER") \
+       MUTOPT (std::string, yyctxmarker, "YYCTXMARKER") \
+       MUTOPT (std::string, yylimit, "YYLIMIT") \
+       MUTOPT (std::string, yypeek, "YYPEEK") \
+       MUTOPT (std::string, yyskip, "YYSKIP") \
+       MUTOPT (std::string, yybackup, "YYBACKUP") \
+       MUTOPT (std::string, yybackupctx, "YYBACKUPCTX") \
+       MUTOPT (std::string, yybackuptag, "YYBACKUPTAG") \
+       MUTOPT (std::string, yyrestore, "YYRESTORE") \
+       MUTOPT (std::string, yyrestorectx, "YYRESTORECTX") \
+       MUTOPT (std::string, yyrestoretag, "YYRESTORETAG") \
+       MUTOPT (std::string, yycopytag, "YYCOPYTAG") \
+       MUTOPT (std::string, yylessthan, "YYLESSTHAN") \
        /* #line directives */ \
-       OPT (bool, iFlag, false) \
+       MUTOPT (bool, iFlag, false) \
        /* debug */ \
-       OPT (bool, dFlag, false) \
-       OPT (std::string, yydebug, "YYDEBUG") \
+       MUTOPT (bool, dFlag, false) \
+       MUTOPT (std::string, yydebug, "YYDEBUG") \
        /* yych */ \
-       OPT (std::string, yyctype, "YYCTYPE") \
-       OPT (std::string, yych, "yych") \
-       OPT (bool, bEmitYYCh, true) \
-       OPT (bool, yychConversion, false) \
+       MUTOPT (std::string, yyctype, "YYCTYPE") \
+       MUTOPT (std::string, yych, "yych") \
+       MUTOPT (bool, bEmitYYCh, true) \
+       MUTOPT (bool, yychConversion, false) \
        /* YYFILL */ \
-       OPT (std::string, fill, "YYFILL") \
-       OPT (bool, fill_use, true) \
-       OPT (bool, fill_check, true) \
-       OPT (std::string, fill_arg, "@@") \
-       OPT (bool, fill_arg_use, true) \
-       OPT (bool, fill_naked, false) \
+       MUTOPT (std::string, fill, "YYFILL") \
+       MUTOPT (bool, fill_use, true) \
+       MUTOPT (bool, fill_check, true) \
+       MUTOPT (std::string, fill_arg, "@@") \
+       MUTOPT (bool, fill_arg_use, true) \
+       MUTOPT (bool, fill_naked, false) \
        /* labels */ \
-       OPT (std::string, labelPrefix, "yy") \
-       OPT (std::string, startlabel, "") \
-       OPT (bool, startlabel_force, false) \
+       MUTOPT (std::string, labelPrefix, "yy") \
+       MUTOPT (std::string, startlabel, "") \
+       MUTOPT (bool, startlabel_force, false) \
        /* internals */ \
-       OPT (dfa_minimization_t, dfa_minimization, DFA_MINIMIZATION_MOORE) \
-       OPT (bool, lookahead, true) \
-       OPT (bool, eager_skip, false) \
-       /* dump */ \
-       OPT (bool, dump_nfa, false) \
-       OPT (bool, dump_dfa_raw, false) \
-       OPT (bool, dump_dfa_det, false) \
-       OPT (bool, dump_dfa_tagopt, false) \
-       OPT (bool, dump_dfa_min, false) \
-       OPT (bool, dump_adfa, false)
+       MUTOPT (dfa_minimization_t, dfa_minimization, DFA_MINIMIZATION_MOORE) \
+       MUTOPT (bool, lookahead, true) \
+       MUTOPT (bool, eager_skip, false)
 
-struct opt_t
+struct conopt_t
 {
-#define OPT1 OPT
-#define OPT(type, name, value) type name;
-       RE2C_OPTS
-#undef OPT1
-#undef OPT
-
-       opt_t ();
-       opt_t (const opt_t & opt);
-       opt_t & operator = (const opt_t & opt);
-       void fix ();
+#      define CONSTOPT1 CONSTOPT
+#      define CONSTOPT(type, name, value) type name;
+       RE2C_CONSTOPTS
+#      undef CONSTOPT1
+#      undef CONSTOPT
+
+       conopt_t()
+#              define CONSTOPT1(type, name, value) : name(value)
+#              define CONSTOPT(type, name, value)  , name(value)
+               RE2C_CONSTOPTS
+#              undef CONSTOPT1
+#              undef CONSTOPT
+       {}
+       void fix();
+       FORBID_COPY(conopt_t);
 };
 
-class useropt_t;
-class realopt_t
+struct mutopt_t
 {
-       opt_t real;
-       useropt_t & user;
-public:
-       realopt_t (useropt_t & opt);
-       const opt_t * operator -> ();
-       void sync ();
-       friend struct Opt;
+#      define MUTOPT1 MUTOPT
+#      define MUTOPT(type, name, value) type name;
+       RE2C_MUTOPTS
+#      undef MUTOPT1
+#      undef MUTOPT
+
+       mutopt_t()
+#              define MUTOPT1(type, name, value) : name(value)
+#              define MUTOPT(type, name, value)  , name(value)
+               RE2C_MUTOPTS
+#              undef MUTOPT1
+#              undef MUTOPT
+       {}
+       void fix(const conopt_t *globopts);
+       FORBID_COPY(mutopt_t);
 };
 
-class useropt_t
+struct opt_t
 {
-       opt_t opt;
-       bool diverge;
-public:
-       useropt_t ();
-       opt_t * operator -> ();
-       friend void realopt_t::sync ();
-       friend struct Opt;
+#      define CONSTOPT1 CONSTOPT
+#      define CONSTOPT(type, name, value) type name;
+       RE2C_CONSTOPTS
+#      undef CONSTOPT1
+#      undef CONSTOPT
+
+#      define MUTOPT1 MUTOPT
+#      define MUTOPT(type, name, value) type name;
+       RE2C_MUTOPTS
+#      undef MUTOPT1
+#      undef MUTOPT
+
+       opt_t(const conopt_t &con, const mutopt_t &mut)
+#              define CONSTOPT1(type, name, value) : name(con.name)
+#              define CONSTOPT(type, name, value)  , name(con.name)
+               RE2C_CONSTOPTS
+#              undef CONSTOPT1
+#              undef CONSTOPT
+#              define MUTOPT1 MUTOPT
+#              define MUTOPT(type, name, value) , name(mut.name)
+               RE2C_MUTOPTS
+#              undef MUTOPT1
+#              undef MUTOPT
+       {}
+       FORBID_COPY(opt_t);
 };
 
+// see note [constant and mutable options]
 struct Opt
 {
-       static const opt_t baseopt;
+       static const mutopt_t baseopt;
 
        const char *source_file;
+       const conopt_t &glob;
 
 private:
-       useropt_t useropt;
-       realopt_t realopt;
+       mutopt_t user;
+       mutopt_t real;
+       bool diverge;
+
+       void sync()
+       {
+               if (!diverge) return;
+#              define MUTOPT1 MUTOPT
+#              define MUTOPT(type, name, value) real.name = user.name;
+               RE2C_MUTOPTS
+#              undef MUTOPT1
+#              undef MUTOPT
+               real.fix(&glob);
+               diverge = false;
+       }
 
 public:
-       Opt ()
-               : source_file (NULL)
-               , useropt ()
-               , realopt (useropt)
+       explicit Opt(const conopt_t &globopts)
+               : source_file(NULL)
+               , glob(globopts)
+               , user()
+               , real()
+               , diverge(true)
        {}
 
        const opt_t *snapshot()
        {
-               realopt.sync();
-               return new opt_t(realopt.real);
+               sync();
+               return new opt_t(glob, real);
        }
 
        void restore(const opt_t *opts)
        {
-               useropt.opt = *opts;
-               realopt.sync();
-       }
-
-       // read-only access, forces options syncronization
-       const opt_t * operator -> ()
-       {
-               return realopt.operator -> ();
+#              define MUTOPT1 MUTOPT
+#              define MUTOPT(type, name, value) user.name = opts->name;
+               RE2C_MUTOPTS
+#              undef MUTOPT1
+#              undef MUTOPT
+               diverge = true;
+               sync();
        }
 
        bool source (const char *s);
 
-       // Inplace configurations are applied immediately when parsed.
-       // This is very bad: first, re2c behaviour is changed in the middle
-       // of the block; second, config is resynced too often (every
-       // attempt to read config that has been updated results in
-       // automatic resync). It is much better to set all options at once.
-       void set_encoding(Enc::type_t t)          { useropt->encoding.set(t); }
-       void unset_encoding(Enc::type_t t)        { useropt->encoding.unset(t); }
-       void set_encoding_policy(Enc::policy_t p) { useropt->encoding.setPolicy(p); }
-#define OPT1 OPT
-#define OPT(type, name, value) void set_##name (type arg) { useropt->name = arg; }
-       RE2C_OPTS
-#undef OPT1
-#undef OPT
+       // RE2C allows to set configurations anywhere inside of a block
+       // (in the beginning, intermixed with rules, in the end): they will
+       // affect the whole block anyway. Thus one is not allowed to read
+       // configurations until the whole block has been parsed. Immutable
+       // options, on the contrary, are accessible for reading all the time
+       // (the parser itself depends on them).
+       void set_encoding(Enc::type_t t)          { user.encoding.set(t); }
+       void unset_encoding(Enc::type_t t)        { user.encoding.unset(t); }
+       void set_encoding_policy(Enc::policy_t p) { user.encoding.setPolicy(p); }
+#define MUTOPT1 MUTOPT
+#define MUTOPT(type, name, value) void set_##name (type arg) { user.name = arg; diverge = true; }
+       RE2C_MUTOPTS
+#undef MUTOPT1
+#undef MUTOPT
 
        // bad temporary hacks, should be fixed by proper scoping of config (parts).
        void reset_startlabel();
@@ -236,7 +295,7 @@ enum parse_opts_t
        EXIT_FAIL
 };
 
-parse_opts_t parse_opts(char **argv, Opt &opts, Warn &warn);
+parse_opts_t parse_opts(char **argv, conopt_t &globopts, Opt &opts, Warn &warn);
 
 } // namespace re2c
 
index fe7927bab28445002bf66afac151c4ef7f96edfc..136368d75dbd7be2feb6f4b426f7bf7a7700e03e 100644 (file)
@@ -13,7 +13,7 @@ static inline bool next (char * & arg, char ** & argv)
        return arg != NULL;
 }
 
-parse_opts_t parse_opts (char **argv, Opt &opts, Warn &warn)
+parse_opts_t parse_opts(char **argv, conopt_t &globopts, Opt &opts, Warn &warn)
 {
 #define YYCTYPE unsigned char
        char * YYCURSOR;
@@ -97,18 +97,20 @@ opt_short:
        [?h] { usage ();   return EXIT_OK; }
        "v"  { version (); return EXIT_OK; }
        "V"  { vernum ();  return EXIT_OK; }
-       "b" { opts.set_bFlag (true);             goto opt_short; }
-       "c" { opts.set_cFlag (true);             goto opt_short; }
-       "d" { opts.set_dFlag (true);             goto opt_short; }
-       "D" { opts.set_target (TARGET_DOT);      goto opt_short; }
-       "f" { opts.set_fFlag (true);             goto opt_short; }
-       "F" { opts.set_FFlag (true);             goto opt_short; }
-       "g" { opts.set_gFlag (true);             goto opt_short; }
-       "i" { opts.set_iFlag (true);             goto opt_short; }
-       "r" { opts.set_rFlag (true);             goto opt_short; }
-       "s" { opts.set_sFlag (true);             goto opt_short; }
-       "S" { opts.set_target (TARGET_SKELETON); goto opt_short; }
-       "T" { opts.set_tags (true);              goto opt_short; }
+
+       "c" { globopts.cFlag = true;             goto opt_short; }
+       "D" { globopts.target = TARGET_DOT;      goto opt_short; }
+       "f" { globopts.fFlag = true;             goto opt_short; }
+       "F" { globopts.FFlag = true;             goto opt_short; }
+       "r" { globopts.rFlag = true;             goto opt_short; }
+       "S" { globopts.target = TARGET_SKELETON; goto opt_short; }
+
+       "b" { opts.set_bFlag(true);           goto opt_short; }
+       "d" { opts.set_dFlag(true);           goto opt_short; }
+       "g" { opts.set_gFlag(true);           goto opt_short; }
+       "i" { opts.set_iFlag(true);           goto opt_short; }
+       "s" { opts.set_sFlag(true);           goto opt_short; }
+       "T" { opts.set_tags(true);            goto opt_short; }
        "e" { opts.set_encoding(Enc::EBCDIC); goto opt_short; }
        "u" { opts.set_encoding(Enc::UTF32);  goto opt_short; }
        "w" { opts.set_encoding(Enc::UCS2);   goto opt_short; }
@@ -131,30 +133,32 @@ opt_long:
        "help"                  end { usage ();   return EXIT_OK; }
        "version"               end { version (); return EXIT_OK; }
        "vernum"                end { vernum ();  return EXIT_OK; }
+
+       "start-conditions"      end { globopts.cFlag = true;             goto opt; }
+       "emit-dot"              end { globopts.target = TARGET_DOT;      goto opt; }
+       "storable-state"        end { globopts.fFlag = true;             goto opt; }
+       "flex-syntax"           end { globopts.FFlag = true;             goto opt; }
+       "reusable"              end { globopts.rFlag = true;             goto opt; }
+       "no-generation-date"    end { globopts.bNoGenerationDate = true; goto opt; }
+       "no-version"            end { globopts.version = false;          goto opt; }
+       "skeleton"              end { globopts.target = TARGET_SKELETON; goto opt; }
+
        "bit-vectors"           end { opts.set_bFlag (true);             goto opt; }
-       "start-conditions"      end { opts.set_cFlag (true);             goto opt; }
        "debug-output"          end { opts.set_dFlag (true);             goto opt; }
-       "emit-dot"              end { opts.set_target (TARGET_DOT);      goto opt; }
-       "storable-state"        end { opts.set_fFlag (true);             goto opt; }
-       "flex-syntax"           end { opts.set_FFlag (true);             goto opt; }
        "computed-gotos"        end { opts.set_gFlag (true);             goto opt; }
        "no-debug-info"         end { opts.set_iFlag (true);             goto opt; }
-       "reusable"              end { opts.set_rFlag (true);             goto opt; }
        "nested-ifs"            end { opts.set_sFlag (true);             goto opt; }
-       "no-generation-date"    end { opts.set_bNoGenerationDate (true); goto opt; }
-       "no-version"            end { opts.set_version (false);          goto opt; }
        "case-insensitive"      end { opts.set_bCaseInsensitive (true);  goto opt; }
        "case-inverted"         end { opts.set_bCaseInverted (true);     goto opt; }
-       "skeleton"              end { opts.set_target (TARGET_SKELETON); goto opt; }
        "tags"                  end { opts.set_tags (true);              goto opt; }
-       "posix-captures"        end { opts.set_posix_captures (true);    goto opt; }
+       "posix-captures"        end { opts.set_posix_captures(true);     goto opt; }
        "no-lookahead"          end { opts.set_lookahead(false);         goto opt; }
        "eager-skip"            end { opts.set_eager_skip(true);         goto opt; }
-       "ecb"                   end { opts.set_encoding(Enc::EBCDIC); goto opt; }
-       "unicode"               end { opts.set_encoding(Enc::UTF32);  goto opt; }
-       "wide-chars"            end { opts.set_encoding(Enc::UCS2);   goto opt; }
-       "utf-16"                end { opts.set_encoding(Enc::UTF16);  goto opt; }
-       "utf-8"                 end { opts.set_encoding(Enc::UTF8);   goto opt; }
+       "ecb"                   end { opts.set_encoding(Enc::EBCDIC);    goto opt; }
+       "unicode"               end { opts.set_encoding(Enc::UTF32);     goto opt; }
+       "wide-chars"            end { opts.set_encoding(Enc::UCS2);      goto opt; }
+       "utf-16"                end { opts.set_encoding(Enc::UTF16);     goto opt; }
+       "utf-8"                 end { opts.set_encoding(Enc::UTF8);      goto opt; }
        "output"                end { if (!next (YYCURSOR, argv)) { error_arg ("-o, --output"); return EXIT_FAIL; } goto opt_output; }
        "type-header"           end { if (!next (YYCURSOR, argv)) { error_arg ("-t, --type-header"); return EXIT_FAIL; } goto opt_header; }
        "encoding-policy"       end { goto opt_encoding_policy; }
@@ -163,12 +167,12 @@ opt_long:
        "dfa-minimization"      end { goto opt_dfa_minimization; }
        "single-pass"           end { goto opt; } // deprecated
 
-       "dump-nfa"              end { opts.set_dump_nfa(true);        goto opt; }
-       "dump-dfa-raw"          end { opts.set_dump_dfa_raw(true);    goto opt; }
-       "dump-dfa-det"          end { opts.set_dump_dfa_det(true);    goto opt; }
-       "dump-dfa-tagopt"       end { opts.set_dump_dfa_tagopt(true); goto opt; }
-       "dump-dfa-min"          end { opts.set_dump_dfa_min(true);    goto opt; }
-       "dump-adfa"             end { opts.set_dump_adfa(true);       goto opt; }
+       "dump-nfa"              end { globopts.dump_nfa = true;        goto opt; }
+       "dump-dfa-raw"          end { globopts.dump_dfa_raw = true;    goto opt; }
+       "dump-dfa-det"          end { globopts.dump_dfa_det = true;    goto opt; }
+       "dump-dfa-tagopt"       end { globopts.dump_dfa_tagopt = true; goto opt; }
+       "dump-dfa-min"          end { globopts.dump_dfa_min = true;    goto opt; }
+       "dump-adfa"             end { globopts.dump_adfa = true;       goto opt; }
 */
 
 opt_output:
@@ -178,7 +182,7 @@ opt_output:
                error ("bad argument to option -o, --output: %s", *argv);
                return EXIT_FAIL;
        }
-       filename end { opts.set_output_file(*argv); goto opt; }
+       filename end { globopts.output_file = *argv; goto opt; }
 */
 
 opt_header:
@@ -188,7 +192,7 @@ opt_header:
                error ("bad argument to option -t, --type-header: %s", *argv);
                return EXIT_FAIL;
        }
-       filename end { opts.set_header_file (*argv); goto opt; }
+       filename end { globopts.header_file = *argv; goto opt; }
 */
 
 opt_encoding_policy:
@@ -263,6 +267,7 @@ end:
                error ("no source file");
                return EXIT_FAIL;
        }
+       globopts.fix();
 
        return OK;
 
index a5f6c1c890033f764b946b6b7f2921f99f03862f..7637bc27aa92998e5bf98f83512850065dfd8925 100644 (file)
@@ -13,32 +13,26 @@ using namespace re2c;
 
 int main(int, char *argv[])
 {
-       Opt opts;
+       conopt_t globopts;
+       Opt opts(globopts);
        Warn warn;
 
-       switch (parse_opts(argv, opts, warn))
-       {
+       switch (parse_opts(argv, globopts, opts, warn)) {
                case OK:        break;
                case EXIT_OK:   return 0;
                case EXIT_FAIL: return 1;
        }
 
-       // set up the source stream
-       re2c::Input input (opts.source_file);
-       if (!input.open ())
-       {
-               error ("cannot open source file: %s", opts.source_file);
+       re2c::Input input(opts.source_file);
+       if (!input.open()) {
+               error("cannot open source file: %s", opts.source_file);
                return 1;
        }
+       Scanner scanner(input, warn);
+       Output output(warn);
 
-       // set up the output streams
-       re2c::Output output(warn);
+       parse(scanner, output, opts);
+       if (!output.emit()) return 1;
 
-       Scanner scanner(input, output.source, opts);
-       parse(scanner, output);
-       if (!output.emit()) {
-               return 1;
-       }
-
-       return warn.error () ? 1 : 0;
+       return warn.error() ? 1 : 0;
 }