]> granicus.if.org Git - re2c/commitdiff
Added partial submatch extraction.
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 23 Mar 2016 17:40:21 +0000 (17:40 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 23 Mar 2016 17:41:27 +0000 (17:41 +0000)
Enabled with '-C, --contexts' option.

Warning '-Wselfoverlapping-contexts'.

104 files changed:
re2c/Makefile.am
re2c/bootstrap/src/conf/parse_opts.cc
re2c/bootstrap/src/parse/lex.cc
re2c/bootstrap/src/parse/lex_conf.cc
re2c/bootstrap/src/parse/parser.cc
re2c/bootstrap/src/parse/y.tab.h
re2c/src/codegen/emit.h
re2c/src/codegen/emit_action.cc
re2c/src/codegen/emit_dfa.cc
re2c/src/codegen/input_api.cc
re2c/src/codegen/input_api.h
re2c/src/codegen/output.cc
re2c/src/codegen/output.h
re2c/src/conf/opt.cc
re2c/src/conf/opt.h
re2c/src/conf/parse_opts.re
re2c/src/conf/warn.cc
re2c/src/conf/warn.h
re2c/src/ir/adfa/adfa.cc
re2c/src/ir/adfa/adfa.h
re2c/src/ir/adfa/prepare.cc
re2c/src/ir/compile.cc
re2c/src/ir/dfa/context_deduplication.cc [new file with mode: 0644]
re2c/src/ir/dfa/context_selfoverlap.cc [new file with mode: 0644]
re2c/src/ir/dfa/determinization.cc
re2c/src/ir/dfa/dfa.h
re2c/src/ir/dfa/minimization.cc
re2c/src/ir/nfa/nfa.cc
re2c/src/ir/nfa/nfa.h
re2c/src/ir/regexp/make_rule.cc
re2c/src/ir/regexp/regexp.h
re2c/src/ir/regexp/split_charset.cc
re2c/src/ir/skeleton/generate_code.cc
re2c/src/ir/skeleton/path.h
re2c/src/ir/skeleton/skeleton.cc
re2c/src/ir/skeleton/skeleton.h
re2c/src/parse/lex.re
re2c/src/parse/parser.h
re2c/src/parse/parser.ypp
re2c/src/parse/rules.h
re2c/src/parse/spec.h
re2c/src/util/intersect_sorted.h [new file with mode: 0644]
re2c/test/contexts/cond_star0.ci--input(custom).c [new file with mode: 0644]
re2c/test/contexts/cond_star0.ci--input(custom).re [new file with mode: 0644]
re2c/test/contexts/cond_star0.ci.c [new file with mode: 0644]
re2c/test/contexts/cond_star0.ci.re [new file with mode: 0644]
re2c/test/contexts/cond_star1.ci--input(custom).c [new file with mode: 0644]
re2c/test/contexts/cond_star1.ci--input(custom).re [new file with mode: 0644]
re2c/test/contexts/cond_star1.ci.c [new file with mode: 0644]
re2c/test/contexts/cond_star1.ci.re [new file with mode: 0644]
re2c/test/contexts/cond_star2.ci.c [new file with mode: 0644]
re2c/test/contexts/cond_star2.ci.re [new file with mode: 0644]
re2c/test/contexts/dedup0.i--input(custom).c [new file with mode: 0644]
re2c/test/contexts/dedup0.i--input(custom).re [new file with mode: 0644]
re2c/test/contexts/dedup0.i.c [new file with mode: 0644]
re2c/test/contexts/dedup0.i.re [new file with mode: 0644]
re2c/test/contexts/dedup1.i--input(custom).c [new file with mode: 0644]
re2c/test/contexts/dedup1.i--input(custom).re [new file with mode: 0644]
re2c/test/contexts/dedup1.i.c [new file with mode: 0644]
re2c/test/contexts/dedup1.i.re [new file with mode: 0644]
re2c/test/contexts/dedup2.i--input(custom).c [new file with mode: 0644]
re2c/test/contexts/dedup2.i--input(custom).re [new file with mode: 0644]
re2c/test/contexts/dedup2.i.c [new file with mode: 0644]
re2c/test/contexts/dedup2.i.re [new file with mode: 0644]
re2c/test/contexts/dedup3.i--input(custom).c [new file with mode: 0644]
re2c/test/contexts/dedup3.i--input(custom).re [new file with mode: 0644]
re2c/test/contexts/dedup3.i.c [new file with mode: 0644]
re2c/test/contexts/dedup3.i.re [new file with mode: 0644]
re2c/test/contexts/fix2.i--contexts.c [new file with mode: 0644]
re2c/test/contexts/fix2.i--contexts.re [new file with mode: 0644]
re2c/test/contexts/fix2_trail.i--contexts--input(custom).c [new file with mode: 0644]
re2c/test/contexts/fix2_trail.i--contexts--input(custom).re [new file with mode: 0644]
re2c/test/contexts/fix2_trail.i--contexts.c [new file with mode: 0644]
re2c/test/contexts/fix2_trail.i--contexts.re [new file with mode: 0644]
re2c/test/contexts/fix3.i--contexts.c [new file with mode: 0644]
re2c/test/contexts/fix3.i--contexts.re [new file with mode: 0644]
re2c/test/contexts/fix3_trail.i--contexts--input(custom).c [new file with mode: 0644]
re2c/test/contexts/fix3_trail.i--contexts--input(custom).re [new file with mode: 0644]
re2c/test/contexts/fix3_trail.i--contexts.c [new file with mode: 0644]
re2c/test/contexts/fix3_trail.i--contexts.re [new file with mode: 0644]
re2c/test/contexts/fix4.i--contexts.c [new file with mode: 0644]
re2c/test/contexts/fix4.i--contexts.re [new file with mode: 0644]
re2c/test/contexts/fix4_trail.i--contexts--input(custom).c [new file with mode: 0644]
re2c/test/contexts/fix4_trail.i--contexts--input(custom).re [new file with mode: 0644]
re2c/test/contexts/fix4_trail.i--contexts.c [new file with mode: 0644]
re2c/test/contexts/fix4_trail.i--contexts.re [new file with mode: 0644]
re2c/test/contexts/fix5.i--contexts.c [new file with mode: 0644]
re2c/test/contexts/fix5.i--contexts.re [new file with mode: 0644]
re2c/test/contexts/fix5_trail.i--contexts--input(custom).c [new file with mode: 0644]
re2c/test/contexts/fix5_trail.i--contexts--input(custom).re [new file with mode: 0644]
re2c/test/contexts/fix5_trail.i--contexts.c [new file with mode: 0644]
re2c/test/contexts/fix5_trail.i--contexts.re [new file with mode: 0644]
re2c/test/contexts/overlap.i--input(custom).c [new file with mode: 0644]
re2c/test/contexts/overlap.i--input(custom).re [new file with mode: 0644]
re2c/test/contexts/overlap.i.c [new file with mode: 0644]
re2c/test/contexts/overlap.i.re [new file with mode: 0644]
re2c/test/contexts/selfoverlap1.i--contexts.c [new file with mode: 0644]
re2c/test/contexts/selfoverlap1.i--contexts.re [new file with mode: 0644]
re2c/test/contexts/selfoverlap1_trail.i--contexts.c [new file with mode: 0644]
re2c/test/contexts/selfoverlap1_trail.i--contexts.re [new file with mode: 0644]
re2c/test/contexts/selfoverlap1_trail.i.c [new file with mode: 0644]
re2c/test/contexts/selfoverlap1_trail.i.re [new file with mode: 0644]
re2c/test/input6.--empty-class(match-empty).c
re2c/test/input6.c

index 8087739bea7879444113d0fd0d93b7d5f62aaaf1..f095f25da4d1bc6c3f58c31e6dab3ec594e4e396 100644 (file)
@@ -55,6 +55,7 @@ SRC_HDR = \
        src/util/counter.h \
        src/util/forbid_copy.h \
        src/util/free_list.h \
+       src/util/intersect_sorted.h \
        src/util/local_increment.h \
        src/util/ord_hash_set.h \
        src/util/range.h \
@@ -81,6 +82,8 @@ SRC = \
        src/ir/nfa/nfa.cc \
        src/ir/adfa/adfa.cc \
        src/ir/adfa/prepare.cc \
+       src/ir/dfa/context_deduplication.cc \
+       src/ir/dfa/context_selfoverlap.cc \
        src/ir/dfa/determinization.cc \
        src/ir/dfa/fallback.cc \
        src/ir/dfa/fillpoints.cc \
index 9eb07989e0435cb5777276eea0fcdec6e1674cae..61c47b278e799111b55d4b7da442d3b982ad1d11 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.16 on Thu Jan 21 10:47:47 2016 */
+/* Generated by re2c 0.16 on Wed Mar 23 14:54:33 2016 */
 #line 1 "../src/conf/parse_opts.re"
 #include "src/codegen/input_api.h"
 #include "src/conf/msg.h"
@@ -275,335 +275,336 @@ yy48:
        goto yy45;
 yy49:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'w') goto yy55;
+       if (yych == 'e') goto yy55;
+       if (yych == 'w') goto yy56;
        goto yy45;
 yy50:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'n') goto yy56;
-       if (yych == 's') goto yy57;
+       if (yych == 'n') goto yy57;
+       if (yych == 's') goto yy58;
        goto yy45;
 yy51:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy58;
+       if (yych == 'n') goto yy59;
 yy52:
        YYCURSOR = YYMARKER;
        goto yy45;
 yy53:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy59;
+       if (yych == 'p') goto yy60;
        goto yy52;
 yy54:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy60;
+       if (yych == 't') goto yy61;
        goto yy52;
 yy55:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy61;
+       if (yych == 'l') goto yy62;
        goto yy52;
 yy56:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy62;
-       if (yych == 'r') goto yy63;
+       if (yych == 'a') goto yy63;
        goto yy52;
 yy57:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy64;
+       if (yych == 'd') goto yy64;
+       if (yych == 'r') goto yy65;
        goto yy52;
 yy58:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy65;
+       if (yych == 'e') goto yy66;
        goto yy52;
 yy59:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy66;
+       if (yych == 'd') goto yy67;
        goto yy52;
 yy60:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy67;
+       if (yych == 't') goto yy68;
        goto yy52;
 yy61:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy68;
+       if (yych == 'c') goto yy69;
        goto yy52;
 yy62:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy69;
+       if (yych == 'f') goto yy70;
        goto yy52;
 yy63:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy70;
+       if (yych == 'p') goto yy71;
        goto yy52;
 yy64:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy71;
+       if (yych == 'e') goto yy72;
        goto yy52;
 yy65:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy72;
+       if (yych == 'e') goto yy73;
        goto yy52;
 yy66:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'y') goto yy73;
+       if (yych == 'l') goto yy74;
        goto yy52;
 yy67:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'h') goto yy74;
+       if (yych == 'i') goto yy75;
        goto yy52;
 yy68:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy75;
+       if (yych == 'y') goto yy76;
        goto yy52;
 yy69:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'f') goto yy76;
+       if (yych == 'h') goto yy77;
        goto yy52;
 yy70:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy77;
+       if (yych == 'o') goto yy78;
        goto yy52;
 yy71:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy78;
+       if (yych == 'p') goto yy79;
        goto yy52;
 yy72:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy79;
+       if (yych == 'f') goto yy80;
        goto yy52;
 yy73:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy80;
+       if (yych == 'a') goto yy81;
        goto yy52;
 yy74:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy81;
+       if (yych == 'e') goto yy82;
        goto yy52;
 yy75:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy82;
+       if (yych == 't') goto yy83;
        goto yy52;
 yy76:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy83;
+       if (yych == '-') goto yy84;
        goto yy52;
 yy77:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy84;
+       if (yych == '-') goto yy85;
        goto yy52;
 yy78:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy85;
+       if (yych == 'v') goto yy86;
        goto yy52;
 yy79:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy86;
+       if (yych == 'e') goto yy87;
        goto yy52;
 yy80:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy87;
+       if (yych == 'i') goto yy88;
        goto yy52;
 yy81:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy88;
+       if (yych == 'c') goto yy89;
        goto yy52;
 yy82:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy89;
+       if (yych == 's') goto yy90;
        goto yy52;
 yy83:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy90;
+       if (yych == 'i') goto yy91;
        goto yy52;
 yy84:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'h') goto yy91;
+       if (yych == 'c') goto yy92;
        goto yy52;
 yy85:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy92;
+       if (yych == 'e') goto yy93;
        goto yy52;
 yy86:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy93;
+       if (yych == 'e') goto yy94;
        goto yy52;
 yy87:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'h') goto yy94;
+       if (yych == 'd') goto yy95;
        goto yy52;
 yy88:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'm') goto yy95;
+       if (yych == 'n') goto yy96;
        goto yy52;
 yy89:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy96;
+       if (yych == 'h') goto yy97;
        goto yy52;
 yy90:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy97;
+       if (yych == 's') goto yy98;
        goto yy52;
 yy91:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy98;
+       if (yych == 'o') goto yy99;
        goto yy52;
 yy92:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy99;
+       if (yych == 'h') goto yy100;
        goto yy52;
 yy93:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy100;
+       if (yych == 'm') goto yy101;
        goto yy52;
 yy94:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy101;
+       if (yych == 'r') goto yy102;
        goto yy52;
 yy95:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy102;
+       if (yych == '-') goto yy103;
        goto yy52;
 yy96:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy103;
+       if (yych == 'e') goto yy104;
        goto yy52;
 yy97:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy104;
+       if (yych == 'a') goto yy105;
        goto yy52;
 yy98:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'b') goto yy105;
+       if (yych == '-') goto yy106;
        goto yy52;
 yy99:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy106;
+       if (yych == 'n') goto yy107;
        goto yy52;
 yy100:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy107;
+       if (yych == 'a') goto yy108;
        goto yy52;
 yy101:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy108;
+       if (yych == 'p') goto yy109;
        goto yy52;
 yy102:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy109;
+       if (yych == 'l') goto yy110;
        goto yy52;
 yy103:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy110;
+       if (yych == 'r') goto yy111;
        goto yy52;
 yy104:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy111;
+       if (yych == 'd') goto yy112;
        goto yy52;
 yy105:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy112;
+       if (yych == 'b') goto yy113;
        goto yy52;
 yy106:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy113;
+       if (yych == 'e') goto yy114;
        goto yy52;
 yy107:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy114;
+       if (yych == '-') goto yy115;
        goto yy52;
 yy108:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy115;
+       if (yych == 'r') goto yy116;
        goto yy52;
 yy109:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'y') goto yy116;
+       if (yych == 't') goto yy117;
        goto yy52;
 yy110:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy117;
+       if (yych == 'a') goto yy118;
        goto yy52;
 yy111:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy118;
+       if (yych == 'a') goto yy119;
        goto yy52;
 yy112:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy119;
+       if (yych == '-') goto yy120;
        goto yy52;
 yy113:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy120;
+       if (yych == 'l') goto yy121;
        goto yy52;
 yy114:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy121;
+       if (yych == 's') goto yy122;
        goto yy52;
 yy115:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy122;
+       if (yych == 'o') goto yy123;
        goto yy52;
 yy116:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy123;
+       if (yych == 'a') goto yy124;
        goto yy52;
 yy117:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'g') goto yy124;
+       if (yych == 'y') goto yy125;
        goto yy52;
 yy118:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy125;
+       if (yych == 'p') goto yy126;
        goto yy52;
 yy119:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy126;
+       if (yych == 'n') goto yy127;
        goto yy52;
 yy120:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy127;
+       if (yych == 'c') goto yy128;
        goto yy52;
 yy121:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy128;
+       if (yych == 'e') goto yy129;
        goto yy52;
 yy122:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy129;
+       if (yych == 'c') goto yy130;
        goto yy52;
 yy123:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy130;
+       if (yych == 'r') goto yy131;
        goto yy52;
 yy124:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy131;
+       if (yych == 'c') goto yy132;
        goto yy52;
 yy125:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy132;
+       if (yych == '-') goto yy133;
        goto yy52;
 yy126:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy133;
+       if (yych == 'p') goto yy134;
        goto yy52;
 yy127:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy134;
+       if (yych == 'g') goto yy135;
        goto yy52;
 yy128:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy135;
+       if (yych == 'o') goto yy136;
        goto yy52;
 yy129:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy136;
+       if (yych == '-') goto yy137;
        goto yy52;
 yy130:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy137;
+       if (yych == 'a') goto yy138;
        goto yy52;
 yy131:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy138;
+       if (yych == 'd') goto yy139;
        goto yy52;
 yy132:
        yych = (YYCTYPE)*++YYCURSOR;
@@ -611,1682 +612,1820 @@ yy132:
        goto yy52;
 yy133:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'u') goto yy141;
+       if (yych == 's') goto yy141;
        goto yy52;
 yy134:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy142;
+       if (yych == 'i') goto yy142;
        goto yy52;
 yy135:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy143;
+       if (yych == 'e') goto yy143;
        goto yy52;
 yy136:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy144;
+       if (yych == 'n') goto yy144;
        goto yy52;
 yy137:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == 'r') goto yy145;
        goto yy52;
 yy138:
-       ++YYCURSOR;
-#line 84 "../src/conf/parse_opts.re"
-       { warn.set (Warn::SWAPPED_RANGE,          option); goto opt; }
-#line 637 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'p') goto yy146;
+       goto yy52;
+yy139:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'e') goto yy147;
+       goto yy52;
 yy140:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy146;
+       if (yych == 'e') goto yy148;
        goto yy52;
 yy141:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy147;
+       if (yych == 't') goto yy149;
        goto yy52;
 yy142:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy148;
+       if (yych == 'n') goto yy150;
        goto yy52;
 yy143:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy150;
+       if (yych <= 0x00) goto yy151;
        goto yy52;
 yy144:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy152;
+       if (yych == 't') goto yy153;
        goto yy52;
 yy145:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy153;
+       if (yych == 'u') goto yy154;
        goto yy52;
 yy146:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy154;
+       if (yych == 'e') goto yy155;
        goto yy52;
 yy147:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy155;
+       if (yych == 'r') goto yy156;
        goto yy52;
 yy148:
-       ++YYCURSOR;
-#line 87 "../src/conf/parse_opts.re"
-       { warn.set (Warn::USELESS_ESCAPE,         option); goto opt; }
-#line 674 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'r') goto yy157;
+       goto yy52;
+yy149:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'r') goto yy158;
+       goto yy52;
 yy150:
-       ++YYCURSOR;
-#line 81 "../src/conf/parse_opts.re"
-       { warn.set (Warn::CONDITION_ORDER,        option); goto opt; }
-#line 679 "src/conf/parse_opts.cc"
-yy152:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy156;
+       if (yych == 'g') goto yy159;
        goto yy52;
+yy151:
+       ++YYCURSOR;
+#line 85 "../src/conf/parse_opts.re"
+       { warn.set (Warn::SWAPPED_RANGE,            option); goto opt; }
+#line 690 "src/conf/parse_opts.cc"
 yy153:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy157;
+       if (yych == 'r') goto yy160;
        goto yy52;
 yy154:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy158;
+       if (yych == 'l') goto yy161;
        goto yy52;
 yy155:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy159;
+       if (yych <= 0x00) goto yy162;
        goto yy52;
 yy156:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy160;
+       if (yych <= 0x00) goto yy164;
        goto yy52;
 yy157:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'g') goto yy161;
+       if (yych == '-') goto yy166;
        goto yy52;
 yy158:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy162;
+       if (yych == 'i') goto yy167;
        goto yy52;
 yy159:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy163;
+       if (yych == '-') goto yy168;
        goto yy52;
 yy160:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy165;
+       if (yych == 'o') goto yy169;
        goto yy52;
 yy161:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy166;
+       if (yych == 'e') goto yy170;
        goto yy52;
 yy162:
+       ++YYCURSOR;
+#line 88 "../src/conf/parse_opts.re"
+       { warn.set (Warn::USELESS_ESCAPE,           option); goto opt; }
+#line 731 "src/conf/parse_opts.cc"
+yy164:
+       ++YYCURSOR;
+#line 81 "../src/conf/parse_opts.re"
+       { warn.set (Warn::CONDITION_ORDER,          option); goto opt; }
+#line 736 "src/conf/parse_opts.cc"
+yy166:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'f') goto yy168;
+       if (yych == 'c') goto yy171;
        goto yy52;
-yy163:
-       ++YYCURSOR;
-#line 86 "../src/conf/parse_opts.re"
-       { warn.set (Warn::UNREACHABLE_RULES,      option); goto opt; }
-#line 728 "src/conf/parse_opts.cc"
-yy165:
+yy167:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy169;
+       if (yych == 'n') goto yy172;
        goto yy52;
-yy166:
-       ++YYCURSOR;
-#line 83 "../src/conf/parse_opts.re"
-       { warn.set (Warn::MATCH_EMPTY_STRING,     option); goto opt; }
-#line 737 "src/conf/parse_opts.cc"
 yy168:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy170;
+       if (yych == 'c') goto yy173;
        goto yy52;
 yy169:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy171;
+       if (yych == 'l') goto yy174;
        goto yy52;
 yy170:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy172;
+       if (yych == 's') goto yy175;
        goto yy52;
 yy171:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy173;
+       if (yych == 'l') goto yy176;
        goto yy52;
 yy172:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'w') goto yy175;
+       if (yych == 'g') goto yy177;
        goto yy52;
 yy173:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'o') goto yy178;
+       goto yy52;
+yy174:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == '-') goto yy179;
+       goto yy52;
+yy175:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy180;
+       goto yy52;
+yy176:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'a') goto yy182;
+       goto yy52;
+yy177:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy183;
+       goto yy52;
+yy178:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'n') goto yy185;
+       goto yy52;
+yy179:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'f') goto yy186;
+       goto yy52;
+yy180:
+       ++YYCURSOR;
+#line 87 "../src/conf/parse_opts.re"
+       { warn.set (Warn::UNREACHABLE_RULES,        option); goto opt; }
+#line 797 "src/conf/parse_opts.cc"
+yy182:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 's') goto yy187;
+       goto yy52;
+yy183:
+       ++YYCURSOR;
+#line 83 "../src/conf/parse_opts.re"
+       { warn.set (Warn::MATCH_EMPTY_STRING,       option); goto opt; }
+#line 806 "src/conf/parse_opts.cc"
+yy185:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 't') goto yy188;
+       goto yy52;
+yy186:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'l') goto yy189;
+       goto yy52;
+yy187:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 's') goto yy190;
+       goto yy52;
+yy188:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'e') goto yy191;
+       goto yy52;
+yy189:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'o') goto yy192;
+       goto yy52;
+yy190:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy193;
+       goto yy52;
+yy191:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'x') goto yy195;
+       goto yy52;
+yy192:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'w') goto yy196;
+       goto yy52;
+yy193:
        ++YYCURSOR;
 #line 82 "../src/conf/parse_opts.re"
-       { warn.set (Warn::EMPTY_CHARACTER_CLASS,  option); goto opt; }
-#line 762 "src/conf/parse_opts.cc"
-yy175:
+       { warn.set (Warn::EMPTY_CHARACTER_CLASS,    option); goto opt; }
+#line 843 "src/conf/parse_opts.cc"
+yy195:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 't') goto yy197;
+       goto yy52;
+yy196:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy198;
+       goto yy52;
+yy197:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 's') goto yy200;
+       goto yy52;
+yy198:
+       ++YYCURSOR;
+#line 86 "../src/conf/parse_opts.re"
+       { warn.set (Warn::UNDEFINED_CONTROL_FLOW,   option); goto opt; }
+#line 860 "src/conf/parse_opts.cc"
+yy200:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych >= 0x01) goto yy52;
        ++YYCURSOR;
-#line 85 "../src/conf/parse_opts.re"
-       { warn.set (Warn::UNDEFINED_CONTROL_FLOW, option); goto opt; }
-#line 769 "src/conf/parse_opts.cc"
+#line 84 "../src/conf/parse_opts.re"
+       { warn.set (Warn::SELFOVERLAPPING_CONTEXTS, option); goto opt; }
+#line 867 "src/conf/parse_opts.cc"
 }
-#line 88 "../src/conf/parse_opts.re"
+#line 89 "../src/conf/parse_opts.re"
 
 
 opt_short:
 
-#line 776 "src/conf/parse_opts.cc"
+#line 874 "src/conf/parse_opts.cc"
 {
        YYCTYPE yych;
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 'b') {
                if (yych <= 'C') {
                        if (yych <= '7') {
-                               if (yych <= 0x00) goto yy180;
-                               if (yych == '1') goto yy184;
-                               goto yy182;
+                               if (yych <= 0x00) goto yy205;
+                               if (yych == '1') goto yy209;
+                               goto yy207;
                        } else {
-                               if (yych <= '8') goto yy186;
-                               if (yych == '?') goto yy188;
-                               goto yy182;
+                               if (yych <= '>') {
+                                       if (yych <= '8') goto yy211;
+                                       goto yy207;
+                               } else {
+                                       if (yych <= '?') goto yy213;
+                                       if (yych <= 'B') goto yy207;
+                                       goto yy215;
+                               }
                        }
                } else {
                        if (yych <= 'R') {
-                               if (yych <= 'D') goto yy190;
-                               if (yych == 'F') goto yy192;
-                               goto yy182;
+                               if (yych <= 'D') goto yy217;
+                               if (yych == 'F') goto yy219;
+                               goto yy207;
                        } else {
                                if (yych <= 'U') {
-                                       if (yych <= 'S') goto yy194;
-                                       goto yy182;
+                                       if (yych <= 'S') goto yy221;
+                                       goto yy207;
                                } else {
-                                       if (yych <= 'V') goto yy196;
-                                       if (yych <= 'a') goto yy182;
-                                       goto yy198;
+                                       if (yych <= 'V') goto yy223;
+                                       if (yych <= 'a') goto yy207;
+                                       goto yy225;
                                }
                        }
                }
        } else {
                if (yych <= 'o') {
                        if (yych <= 'f') {
-                               if (yych <= 'c') goto yy200;
-                               if (yych <= 'd') goto yy202;
-                               if (yych <= 'e') goto yy204;
-                               goto yy206;
+                               if (yych <= 'c') goto yy227;
+                               if (yych <= 'd') goto yy229;
+                               if (yych <= 'e') goto yy231;
+                               goto yy233;
                        } else {
                                if (yych <= 'h') {
-                                       if (yych <= 'g') goto yy208;
-                                       goto yy188;
+                                       if (yych <= 'g') goto yy235;
+                                       goto yy213;
                                } else {
-                                       if (yych <= 'i') goto yy210;
-                                       if (yych <= 'n') goto yy182;
-                                       goto yy212;
+                                       if (yych <= 'i') goto yy237;
+                                       if (yych <= 'n') goto yy207;
+                                       goto yy239;
                                }
                        }
                } else {
                        if (yych <= 't') {
-                               if (yych <= 'q') goto yy182;
-                               if (yych <= 'r') goto yy214;
-                               if (yych <= 's') goto yy216;
-                               goto yy218;
+                               if (yych <= 'q') goto yy207;
+                               if (yych <= 'r') goto yy241;
+                               if (yych <= 's') goto yy243;
+                               goto yy245;
                        } else {
                                if (yych <= 'v') {
-                                       if (yych <= 'u') goto yy220;
-                                       goto yy222;
+                                       if (yych <= 'u') goto yy247;
+                                       goto yy249;
                                } else {
-                                       if (yych <= 'w') goto yy224;
-                                       if (yych <= 'x') goto yy226;
-                                       goto yy182;
+                                       if (yych <= 'w') goto yy251;
+                                       if (yych <= 'x') goto yy253;
+                                       goto yy207;
                                }
                        }
                }
        }
-yy180:
+yy205:
        ++YYCURSOR;
-#line 97 "../src/conf/parse_opts.re"
+#line 98 "../src/conf/parse_opts.re"
        { goto opt; }
-#line 846 "src/conf/parse_opts.cc"
-yy182:
+#line 949 "src/conf/parse_opts.cc"
+yy207:
        ++YYCURSOR;
-#line 93 "../src/conf/parse_opts.re"
+#line 94 "../src/conf/parse_opts.re"
        {
                error ("bad short option: %s", *argv);
                return EXIT_FAIL;
        }
-#line 854 "src/conf/parse_opts.cc"
-yy184:
+#line 957 "src/conf/parse_opts.cc"
+yy209:
        ++YYCURSOR;
-#line 121 "../src/conf/parse_opts.re"
+#line 123 "../src/conf/parse_opts.re"
        { goto opt_short; }
-#line 859 "src/conf/parse_opts.cc"
-yy186:
+#line 962 "src/conf/parse_opts.cc"
+yy211:
        ++YYCURSOR;
-#line 116 "../src/conf/parse_opts.re"
+#line 118 "../src/conf/parse_opts.re"
        { if (!opts.set_encoding (Enc::UTF8))   { error_encoding (); return EXIT_FAIL; } goto opt_short; }
-#line 864 "src/conf/parse_opts.cc"
-yy188:
+#line 967 "src/conf/parse_opts.cc"
+yy213:
        ++YYCURSOR;
-#line 98 "../src/conf/parse_opts.re"
+#line 99 "../src/conf/parse_opts.re"
        { usage ();   return EXIT_OK; }
-#line 869 "src/conf/parse_opts.cc"
-yy190:
+#line 972 "src/conf/parse_opts.cc"
+yy215:
        ++YYCURSOR;
 #line 104 "../src/conf/parse_opts.re"
-       { opts.set_target (opt_t::DOT);      goto opt_short; }
-#line 874 "src/conf/parse_opts.cc"
-yy192:
+       { opts.set_contexts (true);          goto opt_short; }
+#line 977 "src/conf/parse_opts.cc"
+yy217:
        ++YYCURSOR;
 #line 106 "../src/conf/parse_opts.re"
+       { opts.set_target (opt_t::DOT);      goto opt_short; }
+#line 982 "src/conf/parse_opts.cc"
+yy219:
+       ++YYCURSOR;
+#line 108 "../src/conf/parse_opts.re"
        { opts.set_FFlag (true);             goto opt_short; }
-#line 879 "src/conf/parse_opts.cc"
-yy194:
+#line 987 "src/conf/parse_opts.cc"
+yy221:
        ++YYCURSOR;
-#line 111 "../src/conf/parse_opts.re"
+#line 113 "../src/conf/parse_opts.re"
        { opts.set_target (opt_t::SKELETON); goto opt_short; }
-#line 884 "src/conf/parse_opts.cc"
-yy196:
+#line 992 "src/conf/parse_opts.cc"
+yy223:
        ++YYCURSOR;
-#line 100 "../src/conf/parse_opts.re"
+#line 101 "../src/conf/parse_opts.re"
        { vernum ();  return EXIT_OK; }
-#line 889 "src/conf/parse_opts.cc"
-yy198:
+#line 997 "src/conf/parse_opts.cc"
+yy225:
        ++YYCURSOR;
-#line 101 "../src/conf/parse_opts.re"
+#line 102 "../src/conf/parse_opts.re"
        { opts.set_bFlag (true);             goto opt_short; }
-#line 894 "src/conf/parse_opts.cc"
-yy200:
+#line 1002 "src/conf/parse_opts.cc"
+yy227:
        ++YYCURSOR;
-#line 102 "../src/conf/parse_opts.re"
+#line 103 "../src/conf/parse_opts.re"
        { opts.set_cFlag (true);             goto opt_short; }
-#line 899 "src/conf/parse_opts.cc"
-yy202:
+#line 1007 "src/conf/parse_opts.cc"
+yy229:
        ++YYCURSOR;
-#line 103 "../src/conf/parse_opts.re"
+#line 105 "../src/conf/parse_opts.re"
        { opts.set_dFlag (true);             goto opt_short; }
-#line 904 "src/conf/parse_opts.cc"
-yy204:
+#line 1012 "src/conf/parse_opts.cc"
+yy231:
        ++YYCURSOR;
-#line 112 "../src/conf/parse_opts.re"
+#line 114 "../src/conf/parse_opts.re"
        { if (!opts.set_encoding (Enc::EBCDIC)) { error_encoding (); return EXIT_FAIL; } goto opt_short; }
-#line 909 "src/conf/parse_opts.cc"
-yy206:
+#line 1017 "src/conf/parse_opts.cc"
+yy233:
        ++YYCURSOR;
-#line 105 "../src/conf/parse_opts.re"
+#line 107 "../src/conf/parse_opts.re"
        { opts.set_fFlag (true);             goto opt_short; }
-#line 914 "src/conf/parse_opts.cc"
-yy208:
+#line 1022 "src/conf/parse_opts.cc"
+yy235:
        ++YYCURSOR;
-#line 107 "../src/conf/parse_opts.re"
+#line 109 "../src/conf/parse_opts.re"
        { opts.set_gFlag (true);             goto opt_short; }
-#line 919 "src/conf/parse_opts.cc"
-yy210:
+#line 1027 "src/conf/parse_opts.cc"
+yy237:
        ++YYCURSOR;
-#line 108 "../src/conf/parse_opts.re"
+#line 110 "../src/conf/parse_opts.re"
        { opts.set_iFlag (true);             goto opt_short; }
-#line 924 "src/conf/parse_opts.cc"
-yy212:
+#line 1032 "src/conf/parse_opts.cc"
+yy239:
        ++YYCURSOR;
-       if ((yych = (YYCTYPE)*YYCURSOR) <= 0x00) goto yy228;
-#line 118 "../src/conf/parse_opts.re"
+       if ((yych = (YYCTYPE)*YYCURSOR) <= 0x00) goto yy255;
+#line 120 "../src/conf/parse_opts.re"
        { *argv = YYCURSOR;                                                             goto opt_output; }
-#line 930 "src/conf/parse_opts.cc"
-yy214:
+#line 1038 "src/conf/parse_opts.cc"
+yy241:
        ++YYCURSOR;
-#line 109 "../src/conf/parse_opts.re"
+#line 111 "../src/conf/parse_opts.re"
        { opts.set_rFlag (true);             goto opt_short; }
-#line 935 "src/conf/parse_opts.cc"
-yy216:
+#line 1043 "src/conf/parse_opts.cc"
+yy243:
        ++YYCURSOR;
-#line 110 "../src/conf/parse_opts.re"
+#line 112 "../src/conf/parse_opts.re"
        { opts.set_sFlag (true);             goto opt_short; }
-#line 940 "src/conf/parse_opts.cc"
-yy218:
+#line 1048 "src/conf/parse_opts.cc"
+yy245:
        ++YYCURSOR;
-       if ((yych = (YYCTYPE)*YYCURSOR) <= 0x00) goto yy230;
-#line 120 "../src/conf/parse_opts.re"
+       if ((yych = (YYCTYPE)*YYCURSOR) <= 0x00) goto yy257;
+#line 122 "../src/conf/parse_opts.re"
        { *argv = YYCURSOR;                                                                  goto opt_header; }
-#line 946 "src/conf/parse_opts.cc"
-yy220:
+#line 1054 "src/conf/parse_opts.cc"
+yy247:
        ++YYCURSOR;
-#line 113 "../src/conf/parse_opts.re"
+#line 115 "../src/conf/parse_opts.re"
        { if (!opts.set_encoding (Enc::UTF32))  { error_encoding (); return EXIT_FAIL; } goto opt_short; }
-#line 951 "src/conf/parse_opts.cc"
-yy222:
+#line 1059 "src/conf/parse_opts.cc"
+yy249:
        ++YYCURSOR;
-#line 99 "../src/conf/parse_opts.re"
+#line 100 "../src/conf/parse_opts.re"
        { version (); return EXIT_OK; }
-#line 956 "src/conf/parse_opts.cc"
-yy224:
+#line 1064 "src/conf/parse_opts.cc"
+yy251:
        ++YYCURSOR;
-#line 114 "../src/conf/parse_opts.re"
+#line 116 "../src/conf/parse_opts.re"
        { if (!opts.set_encoding (Enc::UCS2))   { error_encoding (); return EXIT_FAIL; } goto opt_short; }
-#line 961 "src/conf/parse_opts.cc"
-yy226:
+#line 1069 "src/conf/parse_opts.cc"
+yy253:
        ++YYCURSOR;
-#line 115 "../src/conf/parse_opts.re"
+#line 117 "../src/conf/parse_opts.re"
        { if (!opts.set_encoding (Enc::UTF16))  { error_encoding (); return EXIT_FAIL; } goto opt_short; }
-#line 966 "src/conf/parse_opts.cc"
-yy228:
+#line 1074 "src/conf/parse_opts.cc"
+yy255:
        ++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 971 "src/conf/parse_opts.cc"
-yy230:
+#line 1079 "src/conf/parse_opts.cc"
+yy257:
        ++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 976 "src/conf/parse_opts.cc"
+#line 1084 "src/conf/parse_opts.cc"
 }
-#line 122 "../src/conf/parse_opts.re"
+#line 124 "../src/conf/parse_opts.re"
 
 
 opt_long:
 
-#line 983 "src/conf/parse_opts.cc"
+#line 1091 "src/conf/parse_opts.cc"
 {
        YYCTYPE yych;
        yych = (YYCTYPE)*YYCURSOR;
        switch (yych) {
-       case 'b':       goto yy236;
-       case 'c':       goto yy237;
-       case 'd':       goto yy238;
-       case 'e':       goto yy239;
-       case 'f':       goto yy240;
-       case 'h':       goto yy241;
-       case 'i':       goto yy242;
-       case 'n':       goto yy243;
-       case 'o':       goto yy244;
-       case 'r':       goto yy245;
-       case 's':       goto yy246;
-       case 't':       goto yy247;
-       case 'u':       goto yy248;
-       case 'v':       goto yy249;
-       case 'w':       goto yy250;
-       default:        goto yy234;
+       case 'b':       goto yy263;
+       case 'c':       goto yy264;
+       case 'd':       goto yy265;
+       case 'e':       goto yy266;
+       case 'f':       goto yy267;
+       case 'h':       goto yy268;
+       case 'i':       goto yy269;
+       case 'n':       goto yy270;
+       case 'o':       goto yy271;
+       case 'r':       goto yy272;
+       case 's':       goto yy273;
+       case 't':       goto yy274;
+       case 'u':       goto yy275;
+       case 'v':       goto yy276;
+       case 'w':       goto yy277;
+       default:        goto yy261;
        }
-yy234:
+yy261:
        ++YYCURSOR;
-yy235:
-#line 127 "../src/conf/parse_opts.re"
+yy262:
+#line 129 "../src/conf/parse_opts.re"
        {
                error ("bad long option: %s", *argv);
                return EXIT_FAIL;
        }
-#line 1013 "src/conf/parse_opts.cc"
-yy236:
+#line 1121 "src/conf/parse_opts.cc"
+yy263:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'i') goto yy251;
-       goto yy235;
-yy237:
+       if (yych == 'i') goto yy278;
+       goto yy262;
+yy264:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'a') goto yy253;
-       if (yych == 'o') goto yy254;
-       goto yy235;
-yy238:
+       if (yych == 'a') goto yy280;
+       if (yych == 'o') goto yy281;
+       goto yy262;
+yy265:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych <= 'd') goto yy235;
-       if (yych <= 'e') goto yy255;
-       if (yych <= 'f') goto yy256;
-       goto yy235;
-yy239:
+       if (yych <= 'd') goto yy262;
+       if (yych <= 'e') goto yy282;
+       if (yych <= 'f') goto yy283;
+       goto yy262;
+yy266:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= 'l') {
-               if (yych == 'c') goto yy257;
-               goto yy235;
+               if (yych == 'c') goto yy284;
+               goto yy262;
        } else {
-               if (yych <= 'm') goto yy258;
-               if (yych <= 'n') goto yy259;
-               goto yy235;
+               if (yych <= 'm') goto yy285;
+               if (yych <= 'n') goto yy286;
+               goto yy262;
        }
-yy240:
+yy267:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'l') goto yy260;
-       goto yy235;
-yy241:
+       if (yych == 'l') goto yy287;
+       goto yy262;
+yy268:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'e') goto yy261;
-       goto yy235;
-yy242:
+       if (yych == 'e') goto yy288;
+       goto yy262;
+yy269:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'n') goto yy262;
-       goto yy235;
-yy243:
+       if (yych == 'n') goto yy289;
+       goto yy262;
+yy270:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'e') goto yy263;
-       if (yych == 'o') goto yy264;
-       goto yy235;
-yy244:
+       if (yych == 'e') goto yy290;
+       if (yych == 'o') goto yy291;
+       goto yy262;
+yy271:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'u') goto yy265;
-       goto yy235;
-yy245:
+       if (yych == 'u') goto yy292;
+       goto yy262;
+yy272:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'e') goto yy266;
-       goto yy235;
-yy246:
+       if (yych == 'e') goto yy293;
+       goto yy262;
+yy273:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= 'j') {
-               if (yych == 'i') goto yy267;
-               goto yy235;
+               if (yych == 'i') goto yy294;
+               goto yy262;
        } else {
-               if (yych <= 'k') goto yy268;
-               if (yych == 't') goto yy269;
-               goto yy235;
+               if (yych <= 'k') goto yy295;
+               if (yych == 't') goto yy296;
+               goto yy262;
        }
-yy247:
-       yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'y') goto yy270;
-       goto yy235;
-yy248:
-       yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'n') goto yy271;
-       if (yych == 't') goto yy272;
-       goto yy235;
-yy249:
-       yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'e') goto yy273;
-       goto yy235;
-yy250:
-       yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'i') goto yy274;
-       goto yy235;
-yy251:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy275;
-yy252:
-       YYCURSOR = YYMARKER;
-       goto yy235;
-yy253:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy276;
-       goto yy252;
-yy254:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'm') goto yy277;
-       goto yy252;
-yy255:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'b') goto yy278;
-       goto yy252;
-yy256:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy279;
-       goto yy252;
-yy257:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'b') goto yy280;
-       goto yy252;
-yy258:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy281;
-       if (yych == 'p') goto yy282;
-       goto yy252;
-yy259:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy283;
-       goto yy252;
-yy260:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy284;
-       goto yy252;
-yy261:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy285;
-       goto yy252;
-yy262:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy286;
-       goto yy252;
-yy263:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy287;
-       goto yy252;
-yy264:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy288;
-       goto yy252;
-yy265:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy289;
-       goto yy252;
-yy266:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'u') goto yy290;
-       goto yy252;
-yy267:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy291;
-       goto yy252;
-yy268:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy292;
-       goto yy252;
-yy269:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy293;
-       if (yych == 'o') goto yy294;
-       goto yy252;
-yy270:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy295;
-       goto yy252;
-yy271:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy296;
-       goto yy252;
-yy272:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'f') goto yy297;
-       goto yy252;
-yy273:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy298;
-       goto yy252;
 yy274:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy299;
-       goto yy252;
+       yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
+       if (yych == 'y') goto yy297;
+       goto yy262;
 yy275:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy300;
-       goto yy252;
+       yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
+       if (yych == 'n') goto yy298;
+       if (yych == 't') goto yy299;
+       goto yy262;
 yy276:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy301;
-       goto yy252;
+       yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
+       if (yych == 'e') goto yy300;
+       goto yy262;
 yy277:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy302;
-       goto yy252;
+       yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
+       if (yych == 'i') goto yy301;
+       goto yy262;
 yy278:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'u') goto yy303;
-       goto yy252;
+       if (yych == 't') goto yy302;
 yy279:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy304;
-       goto yy252;
+       YYCURSOR = YYMARKER;
+       goto yy262;
 yy280:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy305;
-       goto yy252;
+       if (yych == 's') goto yy303;
+       goto yy279;
 yy281:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy307;
-       goto yy252;
+       if (yych <= 'l') goto yy279;
+       if (yych <= 'm') goto yy304;
+       if (yych <= 'n') goto yy305;
+       goto yy279;
 yy282:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy308;
-       goto yy252;
+       if (yych == 'b') goto yy306;
+       goto yy279;
 yy283:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy309;
-       goto yy252;
+       if (yych == 'a') goto yy307;
+       goto yy279;
 yy284:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'x') goto yy310;
-       goto yy252;
+       if (yych == 'b') goto yy308;
+       goto yy279;
 yy285:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy311;
-       goto yy252;
+       if (yych == 'i') goto yy309;
+       if (yych == 'p') goto yy310;
+       goto yy279;
 yy286:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'u') goto yy312;
-       goto yy252;
+       if (yych == 'c') goto yy311;
+       goto yy279;
 yy287:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy313;
-       goto yy252;
+       if (yych == 'e') goto yy312;
+       goto yy279;
 yy288:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 'f') {
-               if (yych == 'd') goto yy314;
-               goto yy252;
-       } else {
-               if (yych <= 'g') goto yy315;
-               if (yych == 'v') goto yy316;
-               goto yy252;
-       }
+       if (yych == 'l') goto yy313;
+       goto yy279;
 yy289:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy317;
-       goto yy252;
+       if (yych == 'p') goto yy314;
+       goto yy279;
 yy290:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy318;
-       goto yy252;
+       if (yych == 's') goto yy315;
+       goto yy279;
 yy291:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'g') goto yy319;
-       goto yy252;
+       if (yych == '-') goto yy316;
+       goto yy279;
 yy292:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy320;
-       goto yy252;
+       if (yych == 't') goto yy317;
+       goto yy279;
 yy293:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy321;
-       goto yy252;
+       if (yych == 'u') goto yy318;
+       goto yy279;
 yy294:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy322;
-       goto yy252;
+       if (yych == 'n') goto yy319;
+       goto yy279;
 yy295:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy323;
-       goto yy252;
+       if (yych == 'e') goto yy320;
+       goto yy279;
 yy296:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy324;
-       goto yy252;
+       if (yych == 'a') goto yy321;
+       if (yych == 'o') goto yy322;
+       goto yy279;
 yy297:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy325;
-       goto yy252;
+       if (yych == 'p') goto yy323;
+       goto yy279;
 yy298:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy326;
-       if (yych == 's') goto yy327;
-       goto yy252;
+       if (yych == 'i') goto yy324;
+       goto yy279;
 yy299:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy328;
-       goto yy252;
+       if (yych == 'f') goto yy325;
+       goto yy279;
 yy300:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'v') goto yy329;
-       goto yy252;
+       if (yych == 'r') goto yy326;
+       goto yy279;
 yy301:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy330;
-       goto yy252;
+       if (yych == 'd') goto yy327;
+       goto yy279;
 yy302:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'u') goto yy331;
-       goto yy252;
+       if (yych == '-') goto yy328;
+       goto yy279;
 yy303:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'g') goto yy332;
-       goto yy252;
+       if (yych == 'e') goto yy329;
+       goto yy279;
 yy304:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'm') goto yy333;
-       goto yy252;
+       if (yych == 'p') goto yy330;
+       goto yy279;
 yy305:
-       ++YYCURSOR;
-#line 149 "../src/conf/parse_opts.re"
-       { if (!opts.set_encoding (Enc::EBCDIC)) { error_encoding (); return EXIT_FAIL; } goto opt; }
-#line 1318 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 't') goto yy331;
+       goto yy279;
+yy306:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'u') goto yy332;
+       goto yy279;
 yy307:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy334;
-       goto yy252;
+       if (yych == '-') goto yy333;
+       goto yy279;
 yy308:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'y') goto yy335;
-       goto yy252;
+       if (yych <= 0x00) goto yy334;
+       goto yy279;
 yy309:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy336;
-       goto yy252;
+       if (yych == 't') goto yy336;
+       goto yy279;
 yy310:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy337;
-       goto yy252;
+       if (yych == 't') goto yy337;
+       goto yy279;
 yy311:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy338;
-       goto yy252;
+       if (yych == 'o') goto yy338;
+       goto yy279;
 yy312:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy340;
-       goto yy252;
+       if (yych == 'x') goto yy339;
+       goto yy279;
 yy313:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy341;
-       goto yy252;
+       if (yych == 'p') goto yy340;
+       goto yy279;
 yy314:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy342;
-       goto yy252;
+       if (yych == 'u') goto yy341;
+       goto yy279;
 yy315:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy343;
-       goto yy252;
+       if (yych == 't') goto yy342;
+       goto yy279;
 yy316:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy344;
-       goto yy252;
+       if (yych <= 'f') {
+               if (yych == 'd') goto yy343;
+               goto yy279;
+       } else {
+               if (yych <= 'g') goto yy344;
+               if (yych == 'v') goto yy345;
+               goto yy279;
+       }
 yy317:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'u') goto yy345;
-       goto yy252;
+       if (yych == 'p') goto yy346;
+       goto yy279;
 yy318:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy346;
-       goto yy252;
+       if (yych == 's') goto yy347;
+       goto yy279;
 yy319:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy347;
-       goto yy252;
+       if (yych == 'g') goto yy348;
+       goto yy279;
 yy320:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy348;
-       goto yy252;
+       if (yych == 'l') goto yy349;
+       goto yy279;
 yy321:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy349;
-       goto yy252;
+       if (yych == 'r') goto yy350;
+       goto yy279;
 yy322:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy350;
-       goto yy252;
+       if (yych == 'r') goto yy351;
+       goto yy279;
 yy323:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy351;
-       goto yy252;
+       if (yych == 'e') goto yy352;
+       goto yy279;
 yy324:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy352;
-       goto yy252;
+       if (yych == 'c') goto yy353;
+       goto yy279;
 yy325:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '1') goto yy353;
-       if (yych == '8') goto yy354;
-       goto yy252;
+       if (yych == '-') goto yy354;
+       goto yy279;
 yy326:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'u') goto yy355;
-       goto yy252;
+       if (yych == 'n') goto yy355;
+       if (yych == 's') goto yy356;
+       goto yy279;
 yy327:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy356;
-       goto yy252;
+       if (yych == 'e') goto yy357;
+       goto yy279;
 yy328:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy357;
-       goto yy252;
+       if (yych == 'v') goto yy358;
+       goto yy279;
 yy329:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy358;
-       goto yy252;
+       if (yych == '-') goto yy359;
+       goto yy279;
 yy330:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy359;
-       goto yy252;
+       if (yych == 'u') goto yy360;
+       goto yy279;
 yy331:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy360;
-       goto yy252;
+       if (yych == 'e') goto yy361;
+       goto yy279;
 yy332:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy361;
-       goto yy252;
+       if (yych == 'g') goto yy362;
+       goto yy279;
 yy333:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy362;
-       goto yy252;
+       if (yych == 'm') goto yy363;
+       goto yy279;
 yy334:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy363;
-       goto yy252;
-yy335:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy364;
-       goto yy252;
+       ++YYCURSOR;
+#line 152 "../src/conf/parse_opts.re"
+       { if (!opts.set_encoding (Enc::EBCDIC)) { error_encoding (); return EXIT_FAIL; } goto opt; }
+#line 1436 "src/conf/parse_opts.cc"
 yy336:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy365;
-       goto yy252;
+       if (yych == '-') goto yy364;
+       goto yy279;
 yy337:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy366;
-       goto yy252;
+       if (yych == 'y') goto yy365;
+       goto yy279;
 yy338:
-       ++YYCURSOR;
-#line 131 "../src/conf/parse_opts.re"
-       { usage ();   return EXIT_OK; }
-#line 1448 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'd') goto yy366;
+       goto yy279;
+yy339:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == '-') goto yy367;
+       goto yy279;
 yy340:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy367;
-       goto yy252;
+       if (yych <= 0x00) goto yy368;
+       goto yy279;
 yy341:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy369;
-       goto yy252;
+       if (yych == 't') goto yy370;
+       goto yy279;
 yy342:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'b') goto yy370;
-       goto yy252;
+       if (yych == 'e') goto yy371;
+       goto yy279;
 yy343:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy371;
-       goto yy252;
+       if (yych == 'e') goto yy372;
+       goto yy279;
 yy344:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy372;
-       goto yy252;
+       if (yych == 'e') goto yy373;
+       goto yy279;
 yy345:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy373;
-       goto yy252;
+       if (yych == 'e') goto yy374;
+       goto yy279;
 yy346:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'b') goto yy374;
-       goto yy252;
+       if (yych == 'u') goto yy375;
+       goto yy279;
 yy347:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy375;
-       goto yy252;
+       if (yych == 'a') goto yy376;
+       goto yy279;
 yy348:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy376;
-       goto yy252;
+       if (yych == 'l') goto yy377;
+       goto yy279;
 yy349:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy377;
-       goto yy252;
+       if (yych == 'e') goto yy378;
+       goto yy279;
 yy350:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'b') goto yy378;
-       goto yy252;
+       if (yych == 't') goto yy379;
+       goto yy279;
 yy351:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'h') goto yy379;
-       goto yy252;
+       if (yych == 'a') goto yy380;
+       goto yy279;
 yy352:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy380;
-       goto yy252;
+       if (yych == '-') goto yy381;
+       goto yy279;
 yy353:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '6') goto yy381;
-       goto yy252;
+       if (yych == 'o') goto yy382;
+       goto yy279;
 yy354:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy382;
-       goto yy252;
+       if (yych == '1') goto yy383;
+       if (yych == '8') goto yy384;
+       goto yy279;
 yy355:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'm') goto yy384;
-       goto yy252;
+       if (yych == 'u') goto yy385;
+       goto yy279;
 yy356:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy385;
-       goto yy252;
+       if (yych == 'i') goto yy386;
+       goto yy279;
 yy357:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy386;
-       goto yy252;
+       if (yych == '-') goto yy387;
+       goto yy279;
 yy358:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy387;
-       goto yy252;
+       if (yych == 'e') goto yy388;
+       goto yy279;
 yy359:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy388;
-       goto yy252;
+       if (yych == 'i') goto yy389;
+       goto yy279;
 yy360:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy389;
-       goto yy252;
+       if (yych == 't') goto yy390;
+       goto yy279;
 yy361:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy390;
-       goto yy252;
+       if (yych == 'x') goto yy391;
+       goto yy279;
 yy362:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy391;
-       goto yy252;
+       if (yych == '-') goto yy392;
+       goto yy279;
 yy363:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy392;
-       goto yy252;
+       if (yych == 'i') goto yy393;
+       goto yy279;
 yy364:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy393;
-       goto yy252;
+       if (yych == 'd') goto yy394;
+       goto yy279;
 yy365:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy394;
-       goto yy252;
+       if (yych == '-') goto yy395;
+       goto yy279;
 yy366:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'y') goto yy395;
-       goto yy252;
+       if (yych == 'i') goto yy396;
+       goto yy279;
 yy367:
-       ++YYCURSOR;
-#line 157 "../src/conf/parse_opts.re"
-       { goto opt_input; }
-#line 1561 "src/conf/parse_opts.cc"
-yy369:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy396;
-       goto yy252;
+       if (yych == 's') goto yy397;
+       goto yy279;
+yy368:
+       ++YYCURSOR;
+#line 133 "../src/conf/parse_opts.re"
+       { usage ();   return EXIT_OK; }
+#line 1570 "src/conf/parse_opts.cc"
 yy370:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'u') goto yy397;
-       goto yy252;
+       if (yych <= 0x00) goto yy398;
+       goto yy279;
 yy371:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy398;
-       goto yy252;
+       if (yych == 'd') goto yy400;
+       goto yy279;
 yy372:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy399;
-       goto yy252;
+       if (yych == 'b') goto yy401;
+       goto yy279;
 yy373:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy400;
-       goto yy252;
+       if (yych == 'n') goto yy402;
+       goto yy279;
 yy374:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy402;
-       goto yy252;
+       if (yych == 'r') goto yy403;
+       goto yy279;
 yy375:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy403;
-       goto yy252;
+       if (yych == 't') goto yy404;
+       goto yy279;
 yy376:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy404;
-       goto yy252;
+       if (yych == 'b') goto yy405;
+       goto yy279;
 yy377:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy405;
-       goto yy252;
+       if (yych == 'e') goto yy406;
+       goto yy279;
 yy378:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy406;
-       goto yy252;
+       if (yych == 't') goto yy407;
+       goto yy279;
 yy379:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy407;
-       goto yy252;
+       if (yych == '-') goto yy408;
+       goto yy279;
 yy380:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy408;
-       goto yy252;
+       if (yych == 'b') goto yy409;
+       goto yy279;
 yy381:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy409;
-       goto yy252;
+       if (yych == 'h') goto yy410;
+       goto yy279;
 yy382:
-       ++YYCURSOR;
-#line 153 "../src/conf/parse_opts.re"
-       { if (!opts.set_encoding (Enc::UTF8))   { error_encoding (); return EXIT_FAIL; } goto opt; }
-#line 1618 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'd') goto yy411;
+       goto yy279;
+yy383:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == '6') goto yy412;
+       goto yy279;
 yy384:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy411;
-       goto yy252;
+       if (yych <= 0x00) goto yy413;
+       goto yy279;
 yy385:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy413;
-       goto yy252;
+       if (yych == 'm') goto yy415;
+       goto yy279;
 yy386:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'h') goto yy414;
-       goto yy252;
+       if (yych == 'o') goto yy416;
+       goto yy279;
 yy387:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy415;
-       goto yy252;
+       if (yych == 'c') goto yy417;
+       goto yy279;
 yy388:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy416;
-       if (yych == 'v') goto yy417;
-       goto yy252;
+       if (yych == 'c') goto yy418;
+       goto yy279;
 yy389:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy418;
-       goto yy252;
+       if (yych == 'n') goto yy419;
+       goto yy279;
 yy390:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'u') goto yy419;
-       goto yy252;
+       if (yych == 'e') goto yy420;
+       goto yy279;
 yy391:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy420;
-       goto yy252;
+       if (yych == 't') goto yy421;
+       goto yy279;
 yy392:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy421;
-       goto yy252;
+       if (yych == 'o') goto yy422;
+       goto yy279;
 yy393:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy422;
-       goto yy252;
+       if (yych == 'n') goto yy423;
+       goto yy279;
 yy394:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'g') goto yy423;
-       goto yy252;
+       if (yych == 'o') goto yy424;
+       goto yy279;
 yy395:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy424;
-       goto yy252;
+       if (yych == 'c') goto yy425;
+       goto yy279;
 yy396:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy425;
-       goto yy252;
+       if (yych == 'n') goto yy426;
+       goto yy279;
 yy397:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'g') goto yy426;
-       goto yy252;
+       if (yych == 'y') goto yy427;
+       goto yy279;
 yy398:
+       ++YYCURSOR;
+#line 160 "../src/conf/parse_opts.re"
+       { goto opt_input; }
+#line 1687 "src/conf/parse_opts.cc"
+yy400:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy427;
-       goto yy252;
-yy399:
+       if (yych == '-') goto yy428;
+       goto yy279;
+yy401:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy428;
-       goto yy252;
-yy400:
-       ++YYCURSOR;
-#line 154 "../src/conf/parse_opts.re"
-       { if (!next (YYCURSOR, argv)) { error_arg ("-o, --output"); return EXIT_FAIL; } goto opt_output; }
-#line 1688 "src/conf/parse_opts.cc"
+       if (yych == 'u') goto yy429;
+       goto yy279;
 yy402:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy429;
-       goto yy252;
+       if (yych == 'e') goto yy430;
+       goto yy279;
 yy403:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy430;
-       goto yy252;
+       if (yych == 's') goto yy431;
+       goto yy279;
 yy404:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy431;
-       goto yy252;
+       if (yych <= 0x00) goto yy432;
+       goto yy279;
 yy405:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy432;
-       goto yy252;
+       if (yych == 'l') goto yy434;
+       goto yy279;
 yy406:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy433;
-       goto yy252;
+       if (yych == '-') goto yy435;
+       goto yy279;
 yy407:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy434;
-       goto yy252;
+       if (yych == 'o') goto yy436;
+       goto yy279;
 yy408:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy435;
-       goto yy252;
+       if (yych == 'c') goto yy437;
+       goto yy279;
 yy409:
-       ++YYCURSOR;
-#line 152 "../src/conf/parse_opts.re"
-       { if (!opts.set_encoding (Enc::UTF16))  { error_encoding (); return EXIT_FAIL; } goto opt; }
-#line 1721 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'l') goto yy438;
+       goto yy279;
+yy410:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'e') goto yy439;
+       goto yy279;
 yy411:
-       ++YYCURSOR;
-#line 133 "../src/conf/parse_opts.re"
-       { vernum ();  return EXIT_OK; }
-#line 1726 "src/conf/parse_opts.cc"
-yy413:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy437;
-       goto yy252;
-yy414:
+       if (yych == 'e') goto yy440;
+       goto yy279;
+yy412:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy439;
-       goto yy252;
+       if (yych <= 0x00) goto yy441;
+       goto yy279;
+yy413:
+       ++YYCURSOR;
+#line 156 "../src/conf/parse_opts.re"
+       { if (!opts.set_encoding (Enc::UTF8))   { error_encoding (); return EXIT_FAIL; } goto opt; }
+#line 1744 "src/conf/parse_opts.cc"
 yy415:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy440;
-       goto yy252;
+       if (yych <= 0x00) goto yy443;
+       goto yy279;
 yy416:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy441;
-       goto yy252;
+       if (yych == 'n') goto yy445;
+       goto yy279;
 yy417:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy442;
-       goto yy252;
+       if (yych == 'h') goto yy446;
+       goto yy279;
 yy418:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy443;
-       goto yy252;
+       if (yych == 't') goto yy447;
+       goto yy279;
 yy419:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy444;
-       goto yy252;
+       if (yych == 's') goto yy448;
+       if (yych == 'v') goto yy449;
+       goto yy279;
 yy420:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'm') goto yy445;
-       goto yy252;
+       if (yych == 'd') goto yy450;
+       goto yy279;
 yy421:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy446;
-       goto yy252;
+       if (yych == 's') goto yy451;
+       goto yy279;
 yy422:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy448;
-       goto yy252;
+       if (yych == 'u') goto yy452;
+       goto yy279;
 yy423:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy449;
-       goto yy252;
+       if (yych == 'i') goto yy453;
+       goto yy279;
 yy424:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy450;
-       goto yy252;
+       if (yych == 't') goto yy454;
+       goto yy279;
 yy425:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'f') goto yy451;
-       goto yy252;
+       if (yych == 'l') goto yy455;
+       goto yy279;
 yy426:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy452;
-       goto yy252;
+       if (yych == 'g') goto yy456;
+       goto yy279;
 yy427:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy453;
-       goto yy252;
+       if (yych == 'n') goto yy457;
+       goto yy279;
 yy428:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy454;
-       goto yy252;
+       if (yych == 'i') goto yy458;
+       goto yy279;
 yy429:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy455;
-       goto yy252;
+       if (yych == 'g') goto yy459;
+       goto yy279;
 yy430:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy457;
-       goto yy252;
+       if (yych == 'r') goto yy460;
+       goto yy279;
 yy431:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy458;
-       goto yy252;
+       if (yych == 'i') goto yy461;
+       goto yy279;
 yy432:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy460;
-       goto yy252;
-yy433:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy461;
-       goto yy252;
+       ++YYCURSOR;
+#line 157 "../src/conf/parse_opts.re"
+       { if (!next (YYCURSOR, argv)) { error_arg ("-o, --output"); return EXIT_FAIL; } goto opt_output; }
+#line 1818 "src/conf/parse_opts.cc"
 yy434:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy462;
-       goto yy252;
+       if (yych == 'e') goto yy462;
+       goto yy279;
 yy435:
-       ++YYCURSOR;
-#line 150 "../src/conf/parse_opts.re"
-       { if (!opts.set_encoding (Enc::UTF32))  { error_encoding (); return EXIT_FAIL; } goto opt; }
-#line 1819 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'p') goto yy463;
+       goto yy279;
+yy436:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'n') goto yy464;
+       goto yy279;
 yy437:
-       ++YYCURSOR;
-#line 132 "../src/conf/parse_opts.re"
-       { version (); return EXIT_OK; }
-#line 1824 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'o') goto yy465;
+       goto yy279;
+yy438:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'e') goto yy466;
+       goto yy279;
 yy439:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy463;
-       goto yy252;
+       if (yych == 'a') goto yy467;
+       goto yy279;
 yy440:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy464;
-       goto yy252;
+       if (yych <= 0x00) goto yy468;
+       goto yy279;
 yy441:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy465;
-       goto yy252;
-yy442:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy466;
-       goto yy252;
+       ++YYCURSOR;
+#line 155 "../src/conf/parse_opts.re"
+       { if (!opts.set_encoding (Enc::UTF16))  { error_encoding (); return EXIT_FAIL; } goto opt; }
+#line 1851 "src/conf/parse_opts.cc"
 yy443:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'g') goto yy467;
-       goto yy252;
-yy444:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy468;
-       goto yy252;
+       ++YYCURSOR;
+#line 135 "../src/conf/parse_opts.re"
+       { vernum ();  return EXIT_OK; }
+#line 1856 "src/conf/parse_opts.cc"
 yy445:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy469;
-       goto yy252;
+       if (yych <= 0x00) goto yy470;
+       goto yy279;
 yy446:
-       ++YYCURSOR;
-#line 137 "../src/conf/parse_opts.re"
-       { opts.set_target (opt_t::DOT);      goto opt; }
-#line 1857 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'a') goto yy472;
+       goto yy279;
+yy447:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'o') goto yy473;
+       goto yy279;
 yy448:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy470;
-       goto yy252;
+       if (yych == 'e') goto yy474;
+       goto yy279;
 yy449:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy471;
-       goto yy252;
+       if (yych == 'e') goto yy475;
+       goto yy279;
 yy450:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy472;
-       goto yy252;
+       if (yych == '-') goto yy476;
+       goto yy279;
 yy451:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy473;
-       goto yy252;
+       if (yych <= 0x00) goto yy477;
+       goto yy279;
 yy452:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy474;
-       goto yy252;
+       if (yych == 't') goto yy479;
+       goto yy279;
 yy453:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy475;
-       goto yy252;
+       if (yych == 'm') goto yy480;
+       goto yy279;
 yy454:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy476;
-       goto yy252;
+       if (yych <= 0x00) goto yy481;
+       goto yy279;
 yy455:
-       ++YYCURSOR;
-#line 142 "../src/conf/parse_opts.re"
-       { opts.set_rFlag (true);             goto opt; }
-#line 1890 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'a') goto yy483;
+       goto yy279;
+yy456:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == '-') goto yy484;
+       goto yy279;
 yy457:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy477;
-       goto yy252;
+       if (yych == 't') goto yy485;
+       goto yy279;
 yy458:
-       ++YYCURSOR;
-#line 148 "../src/conf/parse_opts.re"
-       { opts.set_target (opt_t::SKELETON); goto opt; }
-#line 1899 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'f') goto yy486;
+       goto yy279;
+yy459:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == '-') goto yy487;
+       goto yy279;
 yy460:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy478;
-       goto yy252;
+       if (yych == 'a') goto yy488;
+       goto yy279;
 yy461:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy479;
-       goto yy252;
+       if (yych == 'o') goto yy489;
+       goto yy279;
 yy462:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy480;
-       goto yy252;
+       if (yych <= 0x00) goto yy490;
+       goto yy279;
 yy463:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy481;
-       goto yy252;
+       if (yych == 'a') goto yy492;
+       goto yy279;
 yy464:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy482;
-       goto yy252;
+       if (yych <= 0x00) goto yy493;
+       goto yy279;
 yy465:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy483;
-       goto yy252;
+       if (yych == 'n') goto yy495;
+       goto yy279;
 yy466:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy484;
-       goto yy252;
+       if (yych == '-') goto yy496;
+       goto yy279;
 yy467:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy485;
-       goto yy252;
+       if (yych == 'd') goto yy497;
+       goto yy279;
 yy468:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'u') goto yy486;
-       goto yy252;
-yy469:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'z') goto yy487;
-       goto yy252;
+       ++YYCURSOR;
+#line 153 "../src/conf/parse_opts.re"
+       { if (!opts.set_encoding (Enc::UTF32))  { error_encoding (); return EXIT_FAIL; } goto opt; }
+#line 1953 "src/conf/parse_opts.cc"
 yy470:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy488;
-       goto yy252;
-yy471:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy489;
-       goto yy252;
+       ++YYCURSOR;
+#line 134 "../src/conf/parse_opts.re"
+       { version (); return EXIT_OK; }
+#line 1958 "src/conf/parse_opts.cc"
 yy472:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'x') goto yy490;
-       goto yy252;
+       if (yych == 'r') goto yy498;
+       goto yy279;
 yy473:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy491;
-       goto yy252;
+       if (yych == 'r') goto yy499;
+       goto yy279;
 yy474:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy493;
-       goto yy252;
+       if (yych == 'n') goto yy500;
+       goto yy279;
 yy475:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy494;
-       goto yy252;
+       if (yych == 'r') goto yy501;
+       goto yy279;
 yy476:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy495;
-       goto yy252;
+       if (yych == 'g') goto yy502;
+       goto yy279;
 yy477:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy497;
-       goto yy252;
-yy478:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy498;
-       goto yy252;
+       ++YYCURSOR;
+#line 138 "../src/conf/parse_opts.re"
+       { opts.set_contexts (true);          goto opt; }
+#line 1983 "src/conf/parse_opts.cc"
 yy479:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy499;
-       goto yy252;
+       if (yych == 'p') goto yy503;
+       goto yy279;
 yy480:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy500;
-       goto yy252;
+       if (yych == 'i') goto yy504;
+       goto yy279;
 yy481:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy501;
-       goto yy252;
-yy482:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy503;
-       goto yy252;
+       ++YYCURSOR;
+#line 140 "../src/conf/parse_opts.re"
+       { opts.set_target (opt_t::DOT);      goto opt; }
+#line 1996 "src/conf/parse_opts.cc"
 yy483:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy505;
-       goto yy252;
+       if (yych == 's') goto yy505;
+       goto yy279;
 yy484:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy506;
-       goto yy252;
+       if (yych == 'p') goto yy506;
+       goto yy279;
 yy485:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy507;
-       goto yy252;
+       if (yych == 'a') goto yy507;
+       goto yy279;
 yy486:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy508;
-       goto yy252;
+       if (yych == 's') goto yy508;
+       goto yy279;
 yy487:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy509;
-       goto yy252;
+       if (yych == 'i') goto yy509;
+       goto yy279;
 yy488:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy510;
-       goto yy252;
+       if (yych == 't') goto yy510;
+       goto yy279;
 yy489:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy512;
-       goto yy252;
+       if (yych == 'n') goto yy511;
+       goto yy279;
 yy490:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy513;
-       goto yy252;
-yy491:
        ++YYCURSOR;
-#line 143 "../src/conf/parse_opts.re"
-       { opts.set_sFlag (true);             goto opt; }
-#line 2028 "src/conf/parse_opts.cc"
+#line 145 "../src/conf/parse_opts.re"
+       { opts.set_rFlag (true);             goto opt; }
+#line 2029 "src/conf/parse_opts.cc"
+yy492:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 's') goto yy512;
+       goto yy279;
 yy493:
+       ++YYCURSOR;
+#line 151 "../src/conf/parse_opts.re"
+       { opts.set_target (opt_t::SKELETON); goto opt; }
+#line 2038 "src/conf/parse_opts.cc"
+yy495:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'f') goto yy515;
-       goto yy252;
-yy494:
+       if (yych == 'd') goto yy513;
+       goto yy279;
+yy496:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy516;
-       goto yy252;
-yy495:
-       ++YYCURSOR;
-#line 145 "../src/conf/parse_opts.re"
-       { opts.set_version (false);          goto opt; }
-#line 2041 "src/conf/parse_opts.cc"
+       if (yych == 's') goto yy514;
+       goto yy279;
 yy497:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy517;
-       goto yy252;
+       if (yych == 'e') goto yy515;
+       goto yy279;
 yy498:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy519;
-       goto yy252;
+       if (yych == 's') goto yy516;
+       goto yy279;
 yy499:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy520;
-       goto yy252;
+       if (yych == 's') goto yy517;
+       goto yy279;
 yy500:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy521;
-       goto yy252;
+       if (yych == 's') goto yy518;
+       goto yy279;
 yy501:
-       ++YYCURSOR;
-#line 151 "../src/conf/parse_opts.re"
-       { if (!opts.set_encoding (Enc::UCS2))   { error_encoding (); return EXIT_FAIL; } goto opt; }
-#line 2062 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 't') goto yy519;
+       goto yy279;
+yy502:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'o') goto yy520;
+       goto yy279;
 yy503:
-       ++YYCURSOR;
-#line 134 "../src/conf/parse_opts.re"
-       { opts.set_bFlag (true);             goto opt; }
-#line 2067 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'u') goto yy521;
+       goto yy279;
+yy504:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'z') goto yy522;
+       goto yy279;
 yy505:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy523;
-       goto yy252;
+       if (yych == 's') goto yy523;
+       goto yy279;
 yy506:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy524;
-       goto yy252;
+       if (yych == 'o') goto yy524;
+       goto yy279;
 yy507:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy525;
-       goto yy252;
+       if (yych == 'x') goto yy525;
+       goto yy279;
 yy508:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= 0x00) goto yy526;
-       goto yy252;
+       goto yy279;
 yy509:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy528;
-       goto yy252;
+       if (yych == 'n') goto yy528;
+       goto yy279;
 yy510:
-       ++YYCURSOR;
-#line 158 "../src/conf/parse_opts.re"
-       { goto opt_empty_class; }
-#line 2092 "src/conf/parse_opts.cc"
-yy512:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == 'i') goto yy529;
-       goto yy252;
+       goto yy279;
+yy511:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy530;
+       goto yy279;
+yy512:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 's') goto yy532;
+       goto yy279;
 yy513:
-       ++YYCURSOR;
-#line 139 "../src/conf/parse_opts.re"
-       { opts.set_FFlag (true);             goto opt; }
-#line 2101 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'i') goto yy533;
+       goto yy279;
+yy514:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 't') goto yy534;
+       goto yy279;
 yy515:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy530;
-       goto yy252;
+       if (yych == 'r') goto yy535;
+       goto yy279;
 yy516:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy531;
-       goto yy252;
+       if (yych <= 0x00) goto yy536;
+       goto yy279;
 yy517:
-       ++YYCURSOR;
-#line 160 "../src/conf/parse_opts.re"
-       { goto opt; }
-#line 2114 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy538;
+       goto yy279;
+yy518:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'i') goto yy540;
+       goto yy279;
 yy519:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy532;
-       goto yy252;
+       if (yych == 'e') goto yy541;
+       goto yy279;
 yy520:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy533;
-       goto yy252;
+       if (yych == 't') goto yy542;
+       goto yy279;
 yy521:
-       ++YYCURSOR;
-#line 155 "../src/conf/parse_opts.re"
-       { if (!next (YYCURSOR, argv)) { error_arg ("-t, --type-header"); return EXIT_FAIL; } goto opt_header; }
-#line 2127 "src/conf/parse_opts.cc"
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 't') goto yy543;
+       goto yy279;
+yy522:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'a') goto yy544;
+       goto yy279;
 yy523:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy534;
-       goto yy252;
+       if (yych <= 0x00) goto yy545;
+       goto yy279;
 yy524:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy535;
-       goto yy252;
+       if (yych == 'l') goto yy547;
+       goto yy279;
 yy525:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy537;
-       goto yy252;
+       if (yych <= 0x00) goto yy548;
+       goto yy279;
 yy526:
        ++YYCURSOR;
-#line 136 "../src/conf/parse_opts.re"
-       { opts.set_dFlag (true);             goto opt; }
-#line 2144 "src/conf/parse_opts.cc"
+#line 146 "../src/conf/parse_opts.re"
+       { opts.set_sFlag (true);             goto opt; }
+#line 2167 "src/conf/parse_opts.cc"
 yy528:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy538;
-       goto yy252;
+       if (yych == 'f') goto yy550;
+       goto yy279;
 yy529:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy539;
-       goto yy252;
+       if (yych == 'o') goto yy551;
+       goto yy279;
 yy530:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy540;
-       goto yy252;
-yy531:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy542;
-       goto yy252;
+       ++YYCURSOR;
+#line 148 "../src/conf/parse_opts.re"
+       { opts.set_version (false);          goto opt; }
+#line 2180 "src/conf/parse_opts.cc"
 yy532:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy543;
-       goto yy252;
+       if (yych <= 0x00) goto yy552;
+       goto yy279;
 yy533:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy544;
-       goto yy252;
+       if (yych == 't') goto yy554;
+       goto yy279;
 yy534:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'v') goto yy545;
-       goto yy252;
+       if (yych == 'a') goto yy555;
+       goto yy279;
 yy535:
-       ++YYCURSOR;
-#line 147 "../src/conf/parse_opts.re"
-       { opts.set_bCaseInverted (true);     goto opt; }
-#line 2177 "src/conf/parse_opts.cc"
-yy537:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy546;
-       goto yy252;
+       if (yych <= 0x00) goto yy556;
+       goto yy279;
+yy536:
+       ++YYCURSOR;
+#line 154 "../src/conf/parse_opts.re"
+       { if (!opts.set_encoding (Enc::UCS2))   { error_encoding (); return EXIT_FAIL; } goto opt; }
+#line 2201 "src/conf/parse_opts.cc"
 yy538:
+       ++YYCURSOR;
+#line 136 "../src/conf/parse_opts.re"
+       { opts.set_bFlag (true);             goto opt; }
+#line 2206 "src/conf/parse_opts.cc"
+yy540:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy548;
-       goto yy252;
-yy539:
+       if (yych == 't') goto yy558;
+       goto yy279;
+yy541:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'y') goto yy549;
-       goto yy252;
-yy540:
-       ++YYCURSOR;
-#line 141 "../src/conf/parse_opts.re"
-       { opts.set_iFlag (true);             goto opt; }
-#line 2194 "src/conf/parse_opts.cc"
+       if (yych == 'd') goto yy559;
+       goto yy279;
 yy542:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'd') goto yy550;
-       goto yy252;
+       if (yych == 'o') goto yy560;
+       goto yy279;
 yy543:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy551;
-       goto yy252;
+       if (yych <= 0x00) goto yy561;
+       goto yy279;
 yy544:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy552;
-       goto yy252;
+       if (yych == 't') goto yy563;
+       goto yy279;
 yy545:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy554;
-       goto yy252;
-yy546:
        ++YYCURSOR;
-#line 140 "../src/conf/parse_opts.re"
-       { opts.set_gFlag (true);             goto opt; }
-#line 2215 "src/conf/parse_opts.cc"
-yy548:
-       yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy555;
-       goto yy252;
-yy549:
+#line 161 "../src/conf/parse_opts.re"
+       { goto opt_empty_class; }
+#line 2231 "src/conf/parse_opts.cc"
+yy547:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy556;
-       goto yy252;
+       if (yych == 'i') goto yy564;
+       goto yy279;
+yy548:
+       ++YYCURSOR;
+#line 142 "../src/conf/parse_opts.re"
+       { opts.set_FFlag (true);             goto opt; }
+#line 2240 "src/conf/parse_opts.cc"
 yy550:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy558;
-       goto yy252;
+       if (yych == 'o') goto yy565;
+       goto yy279;
 yy551:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy559;
-       goto yy252;
+       if (yych == 'n') goto yy566;
+       goto yy279;
 yy552:
        ++YYCURSOR;
-#line 138 "../src/conf/parse_opts.re"
-       { opts.set_fFlag (true);             goto opt; }
-#line 2236 "src/conf/parse_opts.cc"
+#line 163 "../src/conf/parse_opts.re"
+       { goto opt; }
+#line 2253 "src/conf/parse_opts.cc"
 yy554:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy560;
-       goto yy252;
+       if (yych == 'i') goto yy567;
+       goto yy279;
 yy555:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy562;
-       goto yy252;
+       if (yych == 't') goto yy568;
+       goto yy279;
 yy556:
        ++YYCURSOR;
-#line 156 "../src/conf/parse_opts.re"
-       { goto opt_encoding_policy; }
-#line 2249 "src/conf/parse_opts.cc"
+#line 158 "../src/conf/parse_opts.re"
+       { if (!next (YYCURSOR, argv)) { error_arg ("-t, --type-header"); return EXIT_FAIL; } goto opt_header; }
+#line 2266 "src/conf/parse_opts.cc"
 yy558:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy564;
-       goto yy252;
+       if (yych == 'i') goto yy569;
+       goto yy279;
 yy559:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy565;
-       goto yy252;
+       if (yych <= 0x00) goto yy570;
+       goto yy279;
 yy560:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 's') goto yy572;
+       goto yy279;
+yy561:
        ++YYCURSOR;
-#line 146 "../src/conf/parse_opts.re"
-       { opts.set_bCaseInsensitive (true);  goto opt; }
-#line 2262 "src/conf/parse_opts.cc"
-yy562:
+#line 139 "../src/conf/parse_opts.re"
+       { opts.set_dFlag (true);             goto opt; }
+#line 2283 "src/conf/parse_opts.cc"
+yy563:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'i') goto yy573;
+       goto yy279;
+yy564:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'c') goto yy574;
+       goto yy279;
+yy565:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy575;
+       goto yy279;
+yy566:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == '-') goto yy577;
+       goto yy279;
+yy567:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'o') goto yy578;
+       goto yy279;
+yy568:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'e') goto yy579;
+       goto yy279;
+yy569:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'v') goto yy580;
+       goto yy279;
+yy570:
+       ++YYCURSOR;
+#line 150 "../src/conf/parse_opts.re"
+       { opts.set_bCaseInverted (true);     goto opt; }
+#line 2316 "src/conf/parse_opts.cc"
+yy572:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy581;
+       goto yy279;
+yy573:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'o') goto yy583;
+       goto yy279;
+yy574:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'y') goto yy584;
+       goto yy279;
+yy575:
+       ++YYCURSOR;
+#line 144 "../src/conf/parse_opts.re"
+       { opts.set_iFlag (true);             goto opt; }
+#line 2333 "src/conf/parse_opts.cc"
+yy577:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'd') goto yy585;
+       goto yy279;
+yy578:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'n') goto yy586;
+       goto yy279;
+yy579:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy587;
+       goto yy279;
+yy580:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'e') goto yy589;
+       goto yy279;
+yy581:
+       ++YYCURSOR;
+#line 143 "../src/conf/parse_opts.re"
+       { opts.set_gFlag (true);             goto opt; }
+#line 2354 "src/conf/parse_opts.cc"
+yy583:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'n') goto yy590;
+       goto yy279;
+yy584:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy591;
+       goto yy279;
+yy585:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 'a') goto yy593;
+       goto yy279;
+yy586:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 's') goto yy594;
+       goto yy279;
+yy587:
+       ++YYCURSOR;
+#line 141 "../src/conf/parse_opts.re"
+       { opts.set_fFlag (true);             goto opt; }
+#line 2375 "src/conf/parse_opts.cc"
+yy589:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy595;
+       goto yy279;
+yy590:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy597;
+       goto yy279;
+yy591:
        ++YYCURSOR;
 #line 159 "../src/conf/parse_opts.re"
+       { goto opt_encoding_policy; }
+#line 2388 "src/conf/parse_opts.cc"
+yy593:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych == 't') goto yy599;
+       goto yy279;
+yy594:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 0x00) goto yy600;
+       goto yy279;
+yy595:
+       ++YYCURSOR;
+#line 149 "../src/conf/parse_opts.re"
+       { opts.set_bCaseInsensitive (true);  goto opt; }
+#line 2401 "src/conf/parse_opts.cc"
+yy597:
+       ++YYCURSOR;
+#line 162 "../src/conf/parse_opts.re"
        { goto opt_dfa_minimization; }
-#line 2267 "src/conf/parse_opts.cc"
-yy564:
+#line 2406 "src/conf/parse_opts.cc"
+yy599:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy567;
-       goto yy252;
-yy565:
+       if (yych == 'e') goto yy602;
+       goto yy279;
+yy600:
        ++YYCURSOR;
-#line 135 "../src/conf/parse_opts.re"
+#line 137 "../src/conf/parse_opts.re"
        { opts.set_cFlag (true);             goto opt; }
-#line 2276 "src/conf/parse_opts.cc"
-yy567:
+#line 2415 "src/conf/parse_opts.cc"
+yy602:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych >= 0x01) goto yy252;
+       if (yych >= 0x01) goto yy279;
        ++YYCURSOR;
-#line 144 "../src/conf/parse_opts.re"
+#line 147 "../src/conf/parse_opts.re"
        { opts.set_bNoGenerationDate (true); goto opt; }
-#line 2283 "src/conf/parse_opts.cc"
+#line 2422 "src/conf/parse_opts.cc"
 }
-#line 161 "../src/conf/parse_opts.re"
+#line 164 "../src/conf/parse_opts.re"
 
 
 opt_output:
 
-#line 2290 "src/conf/parse_opts.cc"
+#line 2429 "src/conf/parse_opts.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -2324,39 +2463,39 @@ opt_output:
                128, 128, 128, 128, 128, 128, 128, 128, 
        };
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych <= 0x00) goto yy572;
-       if (yych != '-') goto yy574;
-yy572:
+       if (yych <= 0x00) goto yy607;
+       if (yych != '-') goto yy609;
+yy607:
        ++YYCURSOR;
-#line 166 "../src/conf/parse_opts.re"
+#line 169 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option -o, --output: %s", *argv);
                return EXIT_FAIL;
        }
-#line 2337 "src/conf/parse_opts.cc"
-yy574:
+#line 2476 "src/conf/parse_opts.cc"
+yy609:
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy578;
-yy575:
+       goto yy613;
+yy610:
        ++YYCURSOR;
-#line 170 "../src/conf/parse_opts.re"
+#line 173 "../src/conf/parse_opts.re"
        { if (!opts.output (*argv)) return EXIT_FAIL; goto opt; }
-#line 2345 "src/conf/parse_opts.cc"
-yy577:
+#line 2484 "src/conf/parse_opts.cc"
+yy612:
        ++YYCURSOR;
        yych = (YYCTYPE)*YYCURSOR;
-yy578:
+yy613:
        if (yybm[0+yych] & 128) {
-               goto yy577;
+               goto yy612;
        }
-       goto yy575;
+       goto yy610;
 }
-#line 171 "../src/conf/parse_opts.re"
+#line 174 "../src/conf/parse_opts.re"
 
 
 opt_header:
 
-#line 2360 "src/conf/parse_opts.cc"
+#line 2499 "src/conf/parse_opts.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -2394,34 +2533,34 @@ opt_header:
                128, 128, 128, 128, 128, 128, 128, 128, 
        };
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych <= 0x00) goto yy581;
-       if (yych != '-') goto yy583;
-yy581:
+       if (yych <= 0x00) goto yy616;
+       if (yych != '-') goto yy618;
+yy616:
        ++YYCURSOR;
-#line 176 "../src/conf/parse_opts.re"
+#line 179 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option -t, --type-header: %s", *argv);
                return EXIT_FAIL;
        }
-#line 2407 "src/conf/parse_opts.cc"
-yy583:
+#line 2546 "src/conf/parse_opts.cc"
+yy618:
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy587;
-yy584:
+       goto yy622;
+yy619:
        ++YYCURSOR;
-#line 180 "../src/conf/parse_opts.re"
+#line 183 "../src/conf/parse_opts.re"
        { opts.set_header_file (*argv); goto opt; }
-#line 2415 "src/conf/parse_opts.cc"
-yy586:
+#line 2554 "src/conf/parse_opts.cc"
+yy621:
        ++YYCURSOR;
        yych = (YYCTYPE)*YYCURSOR;
-yy587:
+yy622:
        if (yybm[0+yych] & 128) {
-               goto yy586;
+               goto yy621;
        }
-       goto yy584;
+       goto yy619;
 }
-#line 181 "../src/conf/parse_opts.re"
+#line 184 "../src/conf/parse_opts.re"
 
 
 opt_encoding_policy:
@@ -2431,115 +2570,115 @@ opt_encoding_policy:
                return EXIT_FAIL;
        }
 
-#line 2435 "src/conf/parse_opts.cc"
+#line 2574 "src/conf/parse_opts.cc"
 {
        YYCTYPE yych;
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 'h') {
-               if (yych == 'f') goto yy592;
+               if (yych == 'f') goto yy627;
        } else {
-               if (yych <= 'i') goto yy593;
-               if (yych == 's') goto yy594;
+               if (yych <= 'i') goto yy628;
+               if (yych == 's') goto yy629;
        }
        ++YYCURSOR;
-yy591:
-#line 191 "../src/conf/parse_opts.re"
+yy626:
+#line 194 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option --encoding-policy (expected: ignore | substitute | fail): %s", *argv);
                return EXIT_FAIL;
        }
-#line 2452 "src/conf/parse_opts.cc"
-yy592:
+#line 2591 "src/conf/parse_opts.cc"
+yy627:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'a') goto yy595;
-       goto yy591;
-yy593:
+       if (yych == 'a') goto yy630;
+       goto yy626;
+yy628:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'g') goto yy597;
-       goto yy591;
-yy594:
+       if (yych == 'g') goto yy632;
+       goto yy626;
+yy629:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'u') goto yy598;
-       goto yy591;
-yy595:
+       if (yych == 'u') goto yy633;
+       goto yy626;
+yy630:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy599;
-yy596:
+       if (yych == 'i') goto yy634;
+yy631:
        YYCURSOR = YYMARKER;
-       goto yy591;
-yy597:
+       goto yy626;
+yy632:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy600;
-       goto yy596;
-yy598:
+       if (yych == 'n') goto yy635;
+       goto yy631;
+yy633:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'b') goto yy601;
-       goto yy596;
-yy599:
+       if (yych == 'b') goto yy636;
+       goto yy631;
+yy634:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy602;
-       goto yy596;
-yy600:
+       if (yych == 'l') goto yy637;
+       goto yy631;
+yy635:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy603;
-       goto yy596;
-yy601:
+       if (yych == 'o') goto yy638;
+       goto yy631;
+yy636:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy604;
-       goto yy596;
-yy602:
+       if (yych == 's') goto yy639;
+       goto yy631;
+yy637:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy605;
-       goto yy596;
-yy603:
+       if (yych <= 0x00) goto yy640;
+       goto yy631;
+yy638:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy607;
-       goto yy596;
-yy604:
+       if (yych == 'r') goto yy642;
+       goto yy631;
+yy639:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy608;
-       goto yy596;
-yy605:
+       if (yych == 't') goto yy643;
+       goto yy631;
+yy640:
        ++YYCURSOR;
-#line 197 "../src/conf/parse_opts.re"
+#line 200 "../src/conf/parse_opts.re"
        { opts.set_encoding_policy (Enc::POLICY_FAIL);       goto opt; }
-#line 2507 "src/conf/parse_opts.cc"
-yy607:
+#line 2646 "src/conf/parse_opts.cc"
+yy642:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy609;
-       goto yy596;
-yy608:
+       if (yych == 'e') goto yy644;
+       goto yy631;
+yy643:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy610;
-       goto yy596;
-yy609:
+       if (yych == 'i') goto yy645;
+       goto yy631;
+yy644:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy611;
-       goto yy596;
-yy610:
+       if (yych <= 0x00) goto yy646;
+       goto yy631;
+yy645:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy613;
-       goto yy596;
-yy611:
+       if (yych == 't') goto yy648;
+       goto yy631;
+yy646:
        ++YYCURSOR;
-#line 195 "../src/conf/parse_opts.re"
+#line 198 "../src/conf/parse_opts.re"
        { opts.set_encoding_policy (Enc::POLICY_IGNORE);     goto opt; }
-#line 2528 "src/conf/parse_opts.cc"
-yy613:
+#line 2667 "src/conf/parse_opts.cc"
+yy648:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'u') goto yy596;
+       if (yych != 'u') goto yy631;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 't') goto yy596;
+       if (yych != 't') goto yy631;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'e') goto yy596;
+       if (yych != 'e') goto yy631;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych >= 0x01) goto yy596;
+       if (yych >= 0x01) goto yy631;
        ++YYCURSOR;
-#line 196 "../src/conf/parse_opts.re"
+#line 199 "../src/conf/parse_opts.re"
        { opts.set_encoding_policy (Enc::POLICY_SUBSTITUTE); goto opt; }
-#line 2541 "src/conf/parse_opts.cc"
+#line 2680 "src/conf/parse_opts.cc"
 }
-#line 198 "../src/conf/parse_opts.re"
+#line 201 "../src/conf/parse_opts.re"
 
 
 opt_input:
@@ -2549,86 +2688,86 @@ opt_input:
                return EXIT_FAIL;
        }
 
-#line 2553 "src/conf/parse_opts.cc"
+#line 2692 "src/conf/parse_opts.cc"
 {
        YYCTYPE yych;
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych <= 'b') goto yy621;
-       if (yych <= 'c') goto yy623;
-       if (yych <= 'd') goto yy624;
-yy621:
+       if (yych <= 'b') goto yy656;
+       if (yych <= 'c') goto yy658;
+       if (yych <= 'd') goto yy659;
+yy656:
        ++YYCURSOR;
-yy622:
-#line 208 "../src/conf/parse_opts.re"
+yy657:
+#line 211 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option --input (expected: default | custom): %s", *argv);
                return EXIT_FAIL;
        }
-#line 2568 "src/conf/parse_opts.cc"
-yy623:
+#line 2707 "src/conf/parse_opts.cc"
+yy658:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'u') goto yy625;
-       goto yy622;
-yy624:
+       if (yych == 'u') goto yy660;
+       goto yy657;
+yy659:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'e') goto yy627;
-       goto yy622;
-yy625:
+       if (yych == 'e') goto yy662;
+       goto yy657;
+yy660:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 's') goto yy628;
-yy626:
+       if (yych == 's') goto yy663;
+yy661:
        YYCURSOR = YYMARKER;
-       goto yy622;
-yy627:
+       goto yy657;
+yy662:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'f') goto yy629;
-       goto yy626;
-yy628:
+       if (yych == 'f') goto yy664;
+       goto yy661;
+yy663:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy630;
-       goto yy626;
-yy629:
+       if (yych == 't') goto yy665;
+       goto yy661;
+yy664:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'a') goto yy631;
-       goto yy626;
-yy630:
+       if (yych == 'a') goto yy666;
+       goto yy661;
+yy665:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy632;
-       goto yy626;
-yy631:
+       if (yych == 'o') goto yy667;
+       goto yy661;
+yy666:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'u') goto yy633;
-       goto yy626;
-yy632:
+       if (yych == 'u') goto yy668;
+       goto yy661;
+yy667:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'm') goto yy634;
-       goto yy626;
-yy633:
+       if (yych == 'm') goto yy669;
+       goto yy661;
+yy668:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy635;
-       goto yy626;
-yy634:
+       if (yych == 'l') goto yy670;
+       goto yy661;
+yy669:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy636;
-       goto yy626;
-yy635:
+       if (yych <= 0x00) goto yy671;
+       goto yy661;
+yy670:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy638;
-       goto yy626;
-yy636:
+       if (yych == 't') goto yy673;
+       goto yy661;
+yy671:
        ++YYCURSOR;
-#line 213 "../src/conf/parse_opts.re"
+#line 216 "../src/conf/parse_opts.re"
        { opts.set_input_api (InputAPI::CUSTOM);  goto opt; }
-#line 2623 "src/conf/parse_opts.cc"
-yy638:
+#line 2762 "src/conf/parse_opts.cc"
+yy673:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych >= 0x01) goto yy626;
+       if (yych >= 0x01) goto yy661;
        ++YYCURSOR;
-#line 212 "../src/conf/parse_opts.re"
+#line 215 "../src/conf/parse_opts.re"
        { opts.set_input_api (InputAPI::DEFAULT); goto opt; }
-#line 2630 "src/conf/parse_opts.cc"
+#line 2769 "src/conf/parse_opts.cc"
 }
-#line 214 "../src/conf/parse_opts.re"
+#line 217 "../src/conf/parse_opts.re"
 
 
 opt_empty_class:
@@ -2638,120 +2777,120 @@ opt_empty_class:
                return EXIT_FAIL;
        }
 
-#line 2642 "src/conf/parse_opts.cc"
+#line 2781 "src/conf/parse_opts.cc"
 {
        YYCTYPE yych;
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == 'e') goto yy645;
-       if (yych == 'm') goto yy646;
+       if (yych == 'e') goto yy680;
+       if (yych == 'm') goto yy681;
        ++YYCURSOR;
-yy644:
-#line 224 "../src/conf/parse_opts.re"
+yy679:
+#line 227 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option --empty-class (expected: match-empty | match-none | error): %s", *argv);
                return EXIT_FAIL;
        }
-#line 2655 "src/conf/parse_opts.cc"
-yy645:
+#line 2794 "src/conf/parse_opts.cc"
+yy680:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'r') goto yy647;
-       goto yy644;
-yy646:
+       if (yych == 'r') goto yy682;
+       goto yy679;
+yy681:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'a') goto yy649;
-       goto yy644;
-yy647:
+       if (yych == 'a') goto yy684;
+       goto yy679;
+yy682:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy650;
-yy648:
+       if (yych == 'r') goto yy685;
+yy683:
        YYCURSOR = YYMARKER;
-       goto yy644;
-yy649:
+       goto yy679;
+yy684:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy651;
-       goto yy648;
-yy650:
+       if (yych == 't') goto yy686;
+       goto yy683;
+yy685:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy652;
-       goto yy648;
-yy651:
+       if (yych == 'o') goto yy687;
+       goto yy683;
+yy686:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'c') goto yy653;
-       goto yy648;
-yy652:
+       if (yych == 'c') goto yy688;
+       goto yy683;
+yy687:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy654;
-       goto yy648;
-yy653:
+       if (yych == 'r') goto yy689;
+       goto yy683;
+yy688:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'h') goto yy655;
-       goto yy648;
-yy654:
+       if (yych == 'h') goto yy690;
+       goto yy683;
+yy689:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy656;
-       goto yy648;
-yy655:
+       if (yych <= 0x00) goto yy691;
+       goto yy683;
+yy690:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '-') goto yy658;
-       goto yy648;
-yy656:
+       if (yych == '-') goto yy693;
+       goto yy683;
+yy691:
        ++YYCURSOR;
-#line 230 "../src/conf/parse_opts.re"
+#line 233 "../src/conf/parse_opts.re"
        { opts.set_empty_class_policy (EMPTY_CLASS_ERROR);       goto opt; }
-#line 2702 "src/conf/parse_opts.cc"
-yy658:
+#line 2841 "src/conf/parse_opts.cc"
+yy693:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy659;
-       if (yych == 'n') goto yy660;
-       goto yy648;
-yy659:
+       if (yych == 'e') goto yy694;
+       if (yych == 'n') goto yy695;
+       goto yy683;
+yy694:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'm') goto yy661;
-       goto yy648;
-yy660:
+       if (yych == 'm') goto yy696;
+       goto yy683;
+yy695:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy662;
-       goto yy648;
-yy661:
+       if (yych == 'o') goto yy697;
+       goto yy683;
+yy696:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'p') goto yy663;
-       goto yy648;
-yy662:
+       if (yych == 'p') goto yy698;
+       goto yy683;
+yy697:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy664;
-       goto yy648;
-yy663:
+       if (yych == 'n') goto yy699;
+       goto yy683;
+yy698:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 't') goto yy665;
-       goto yy648;
-yy664:
+       if (yych == 't') goto yy700;
+       goto yy683;
+yy699:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy666;
-       goto yy648;
-yy665:
+       if (yych == 'e') goto yy701;
+       goto yy683;
+yy700:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'y') goto yy667;
-       goto yy648;
-yy666:
+       if (yych == 'y') goto yy702;
+       goto yy683;
+yy701:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy668;
-       goto yy648;
-yy667:
+       if (yych <= 0x00) goto yy703;
+       goto yy683;
+yy702:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy670;
-       goto yy648;
-yy668:
+       if (yych <= 0x00) goto yy705;
+       goto yy683;
+yy703:
        ++YYCURSOR;
-#line 229 "../src/conf/parse_opts.re"
+#line 232 "../src/conf/parse_opts.re"
        { opts.set_empty_class_policy (EMPTY_CLASS_MATCH_NONE);  goto opt; }
-#line 2748 "src/conf/parse_opts.cc"
-yy670:
+#line 2887 "src/conf/parse_opts.cc"
+yy705:
        ++YYCURSOR;
-#line 228 "../src/conf/parse_opts.re"
+#line 231 "../src/conf/parse_opts.re"
        { opts.set_empty_class_policy (EMPTY_CLASS_MATCH_EMPTY); goto opt; }
-#line 2753 "src/conf/parse_opts.cc"
+#line 2892 "src/conf/parse_opts.cc"
 }
-#line 231 "../src/conf/parse_opts.re"
+#line 234 "../src/conf/parse_opts.re"
 
 
 opt_dfa_minimization:
@@ -2761,74 +2900,74 @@ opt_dfa_minimization:
                return EXIT_FAIL;
        }
 
-#line 2765 "src/conf/parse_opts.cc"
+#line 2904 "src/conf/parse_opts.cc"
 {
        YYCTYPE yych;
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == 'm') goto yy676;
-       if (yych == 't') goto yy677;
+       if (yych == 'm') goto yy711;
+       if (yych == 't') goto yy712;
        ++YYCURSOR;
-yy675:
-#line 241 "../src/conf/parse_opts.re"
+yy710:
+#line 244 "../src/conf/parse_opts.re"
        {
                error ("bad argument to option --dfa-minimization (expected: table | moore): %s", *argv);
                return EXIT_FAIL;
        }
-#line 2778 "src/conf/parse_opts.cc"
-yy676:
+#line 2917 "src/conf/parse_opts.cc"
+yy711:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'o') goto yy678;
-       goto yy675;
-yy677:
+       if (yych == 'o') goto yy713;
+       goto yy710;
+yy712:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == 'a') goto yy680;
-       goto yy675;
-yy678:
+       if (yych == 'a') goto yy715;
+       goto yy710;
+yy713:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'o') goto yy681;
-yy679:
+       if (yych == 'o') goto yy716;
+yy714:
        YYCURSOR = YYMARKER;
-       goto yy675;
-yy680:
+       goto yy710;
+yy715:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'b') goto yy682;
-       goto yy679;
-yy681:
+       if (yych == 'b') goto yy717;
+       goto yy714;
+yy716:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'r') goto yy683;
-       goto yy679;
-yy682:
+       if (yych == 'r') goto yy718;
+       goto yy714;
+yy717:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'l') goto yy684;
-       goto yy679;
-yy683:
+       if (yych == 'l') goto yy719;
+       goto yy714;
+yy718:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy685;
-       goto yy679;
-yy684:
+       if (yych == 'e') goto yy720;
+       goto yy714;
+yy719:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy686;
-       goto yy679;
-yy685:
+       if (yych == 'e') goto yy721;
+       goto yy714;
+yy720:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy687;
-       goto yy679;
-yy686:
+       if (yych <= 0x00) goto yy722;
+       goto yy714;
+yy721:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= 0x00) goto yy689;
-       goto yy679;
-yy687:
+       if (yych <= 0x00) goto yy724;
+       goto yy714;
+yy722:
        ++YYCURSOR;
-#line 246 "../src/conf/parse_opts.re"
+#line 249 "../src/conf/parse_opts.re"
        { opts.set_dfa_minimization (DFA_MINIMIZATION_MOORE); goto opt; }
-#line 2825 "src/conf/parse_opts.cc"
-yy689:
+#line 2964 "src/conf/parse_opts.cc"
+yy724:
        ++YYCURSOR;
-#line 245 "../src/conf/parse_opts.re"
+#line 248 "../src/conf/parse_opts.re"
        { opts.set_dfa_minimization (DFA_MINIMIZATION_TABLE); goto opt; }
-#line 2830 "src/conf/parse_opts.cc"
+#line 2969 "src/conf/parse_opts.cc"
 }
-#line 247 "../src/conf/parse_opts.re"
+#line 250 "../src/conf/parse_opts.re"
 
 
 end:
index 2b0858388a5011f62200110cc26ff405bd9aea1d..bedbdddb1d343c0120725a6eaacf97f7cf925528 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.16 on Tue Mar 15 17:24:03 2016 */
+/* Generated by re2c 0.16 on Wed Mar 23 17:38:25 2016 */
 #line 1 "../src/parse/lex.re"
 #include "src/util/c99_stdint.h"
 #include <stddef.h>
@@ -789,9 +789,10 @@ start:
                        } else {
                                if (yych <= '@') {
                                        if (yych <= '?') goto yy129;
+                                       goto yy137;
                                } else {
                                        if (yych <= 'Z') goto yy134;
-                                       if (yych <= '[') goto yy137;
+                                       if (yych <= '[') goto yy138;
                                        goto yy125;
                                }
                        }
@@ -801,10 +802,10 @@ start:
                                if (yych >= 'a') goto yy134;
                        } else {
                                if (yych <= 'z') {
-                                       if (yych <= 'r') goto yy139;
+                                       if (yych <= 'r') goto yy140;
                                        goto yy134;
                                } else {
-                                       if (yych <= '{') goto yy140;
+                                       if (yych <= '{') goto yy141;
                                        if (yych <= '|') goto yy125;
                                }
                        }
@@ -813,12 +814,12 @@ start:
 yy112:
        ++YYCURSOR;
 yy113:
-#line 387 "../src/parse/lex.re"
+#line 393 "../src/parse/lex.re"
        {
                                        fatalf("unexpected character: '%c'", *tok);
                                        goto scan;
                                }
-#line 822 "src/parse/lex.cc"
+#line 823 "src/parse/lex.cc"
 yy114:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -826,29 +827,29 @@ yy114:
        if (yybm[0+yych] & 16) {
                goto yy114;
        }
-#line 371 "../src/parse/lex.re"
+#line 377 "../src/parse/lex.re"
        {
                                        goto scan;
                                }
-#line 834 "src/parse/lex.cc"
+#line 835 "src/parse/lex.cc"
 yy117:
        yyaccept = 0;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy142;
+               if (yych == '\t') goto yy143;
        } else {
-               if (yych <= ' ') goto yy142;
-               if (yych == '#') goto yy145;
+               if (yych <= ' ') goto yy143;
+               if (yych == '#') goto yy146;
        }
 yy118:
-#line 380 "../src/parse/lex.re"
+#line 386 "../src/parse/lex.re"
        {
                                        if (cur == eof) return 0;
                                        pos = cur;
                                        cline++;
                                        goto scan;
                                }
-#line 852 "src/parse/lex.cc"
+#line 853 "src/parse/lex.cc"
 yy119:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych == '\n') goto yy117;
@@ -857,114 +858,131 @@ yy120:
        ++YYCURSOR;
 #line 264 "../src/parse/lex.re"
        { yylval.regexp = lex_str('"',  opts->bCaseInsensitive ||  opts->bCaseInverted); return TOKEN_REGEXP; }
-#line 861 "src/parse/lex.cc"
+#line 862 "src/parse/lex.cc"
 yy122:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '}') goto yy147;
+       if (yych == '}') goto yy148;
        goto yy113;
 yy123:
        ++YYCURSOR;
 #line 263 "../src/parse/lex.re"
        { yylval.regexp = lex_str('\'', opts->bCaseInsensitive || !opts->bCaseInverted); return TOKEN_REGEXP; }
-#line 870 "src/parse/lex.cc"
+#line 871 "src/parse/lex.cc"
 yy125:
        ++YYCURSOR;
 yy126:
-#line 274 "../src/parse/lex.re"
+#line 280 "../src/parse/lex.re"
        {
                                        return *tok;
                                }
-#line 878 "src/parse/lex.cc"
+#line 879 "src/parse/lex.cc"
 yy127:
        ++YYCURSOR;
-       if ((yych = (YYCTYPE)*YYCURSOR) == '/') goto yy147;
-#line 278 "../src/parse/lex.re"
+       if ((yych = (YYCTYPE)*YYCURSOR) == '/') goto yy148;
+#line 284 "../src/parse/lex.re"
        {
                                        yylval.op = *tok;
                                        return TOKEN_STAR;
                                }
-#line 887 "src/parse/lex.cc"
+#line 888 "src/parse/lex.cc"
 yy129:
        ++YYCURSOR;
-#line 282 "../src/parse/lex.re"
+#line 288 "../src/parse/lex.re"
        {
                                        yylval.op = *tok;
                                        return TOKEN_CLOSE;
                                }
-#line 895 "src/parse/lex.cc"
+#line 896 "src/parse/lex.cc"
 yy131:
        ++YYCURSOR;
-#line 366 "../src/parse/lex.re"
+#line 372 "../src/parse/lex.re"
        {
                                        yylval.regexp = mkDot();
                                        return TOKEN_REGEXP;
                                }
-#line 903 "src/parse/lex.cc"
+#line 904 "src/parse/lex.cc"
 yy133:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '*') goto yy149;
-       if (yych == '/') goto yy151;
+       if (yych == '*') goto yy150;
+       if (yych == '/') goto yy152;
        goto yy126;
 yy134:
        yych = (YYCTYPE)*++YYCURSOR;
        YYCTXMARKER = YYCURSOR;
-       goto yy159;
+       goto yy160;
 yy135:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '=') goto yy160;
+       if (yych == '=') goto yy161;
        goto yy113;
 yy136:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == '!') goto yy162;
-       if (yych == '>') goto yy164;
+       if (yych == '!') goto yy163;
+       if (yych == '>') goto yy165;
        goto yy126;
 yy137:
+       yych = (YYCTYPE)*++YYCURSOR;
+       if (yych <= 'Z') {
+               if (yych <= '/') goto yy113;
+               if (yych <= '9') goto yy166;
+               if (yych <= '@') goto yy113;
+               goto yy166;
+       } else {
+               if (yych <= '_') {
+                       if (yych <= '^') goto yy113;
+                       goto yy166;
+               } else {
+                       if (yych <= '`') goto yy113;
+                       if (yych <= 'z') goto yy166;
+                       goto yy113;
+               }
+       }
+yy138:
        ++YYCURSOR;
-       if ((yych = (YYCTYPE)*YYCURSOR) == '^') goto yy165;
+       if ((yych = (YYCTYPE)*YYCURSOR) == '^') goto yy169;
 #line 265 "../src/parse/lex.re"
        { yylval.regexp = lex_cls(false); return TOKEN_REGEXP; }
-#line 928 "src/parse/lex.cc"
-yy139:
+#line 946 "src/parse/lex.cc"
+yy140:
        yych = (YYCTYPE)*++YYCURSOR;
        YYCTXMARKER = YYCURSOR;
-       if (yych == 'e') goto yy167;
-       goto yy159;
-yy140:
+       if (yych == 'e') goto yy171;
+       goto yy160;
+yy141:
        yyaccept = 2;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yybm[0+yych] & 64) {
-               goto yy170;
+               goto yy174;
        }
        if (yych <= 'Z') {
-               if (yych == ',') goto yy168;
-               if (yych >= 'A') goto yy172;
+               if (yych == ',') goto yy172;
+               if (yych >= 'A') goto yy176;
        } else {
                if (yych <= '_') {
-                       if (yych >= '_') goto yy172;
+                       if (yych >= '_') goto yy176;
                } else {
-                       if (yych <= '`') goto yy141;
-                       if (yych <= 'z') goto yy172;
+                       if (yych <= '`') goto yy142;
+                       if (yych <= 'z') goto yy176;
                }
        }
-yy141:
+yy142:
 #line 234 "../src/parse/lex.re"
        {
                                        depth = 1;
                                        goto code;
                                }
-#line 957 "src/parse/lex.cc"
-yy142:
+#line 975 "src/parse/lex.cc"
+yy143:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy142;
+               if (yych == '\t') goto yy143;
        } else {
-               if (yych <= ' ') goto yy142;
-               if (yych == '#') goto yy145;
+               if (yych <= ' ') goto yy143;
+               if (yych == '#') goto yy146;
        }
-yy144:
+yy145:
        YYCURSOR = YYMARKER;
        if (yyaccept <= 1) {
                if (yyaccept == 0) {
@@ -974,50 +992,50 @@ yy144:
                }
        } else {
                if (yyaccept == 2) {
-                       goto yy141;
+                       goto yy142;
                } else {
-                       goto yy169;
+                       goto yy173;
                }
        }
-yy145:
+yy146:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy145;
-               goto yy144;
+               if (yych == '\t') goto yy146;
+               goto yy145;
        } else {
-               if (yych <= ' ') goto yy145;
-               if (yych == 'l') goto yy174;
-               goto yy144;
+               if (yych <= ' ') goto yy146;
+               if (yych == 'l') goto yy178;
+               goto yy145;
        }
-yy147:
+yy148:
        ++YYCURSOR;
 #line 258 "../src/parse/lex.re"
        {
                                        tok = cur;
                                        return 0;
                                }
-#line 1002 "src/parse/lex.cc"
-yy149:
+#line 1020 "src/parse/lex.cc"
+yy150:
        ++YYCURSOR;
 #line 252 "../src/parse/lex.re"
        {
                                        depth = 1;
                                        goto comment;
                                }
-#line 1010 "src/parse/lex.cc"
-yy151:
+#line 1028 "src/parse/lex.cc"
+yy152:
        ++YYCURSOR;
 #line 249 "../src/parse/lex.re"
        {
                                goto nextLine;
                        }
-#line 1017 "src/parse/lex.cc"
-yy153:
+#line 1035 "src/parse/lex.cc"
+yy154:
        ++YYCURSOR;
        YYCURSOR -= 1;
-#line 350 "../src/parse/lex.re"
+#line 356 "../src/parse/lex.re"
        {
                                        if (!opts->FFlag) {
                                                yylval.str = new std::string (tok, tok_len());
@@ -1033,134 +1051,157 @@ yy153:
                                                return TOKEN_REGEXP;
                                        }
                                }
-#line 1037 "src/parse/lex.cc"
-yy155:
-       yych = (YYCTYPE)*++YYCURSOR;
-       goto yy178;
+#line 1055 "src/parse/lex.cc"
 yy156:
+       yych = (YYCTYPE)*++YYCURSOR;
+       goto yy182;
+yy157:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 345 "../src/parse/lex.re"
+#line 351 "../src/parse/lex.re"
        {
                                        yylval.str = new std::string (tok, tok_len ());
                                        return TOKEN_ID;
                                }
-#line 1049 "src/parse/lex.cc"
-yy158:
+#line 1067 "src/parse/lex.cc"
+yy159:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        YYCTXMARKER = YYCURSOR;
-yy159:
+yy160:
        if (yybm[0+yych] & 32) {
-               goto yy158;
+               goto yy159;
        }
        if (yych <= ' ') {
-               if (yych == '\t') goto yy155;
-               if (yych <= 0x1F) goto yy153;
-               goto yy155;
+               if (yych == '\t') goto yy156;
+               if (yych <= 0x1F) goto yy154;
+               goto yy156;
        } else {
                if (yych <= ',') {
-                       if (yych <= '+') goto yy153;
-                       goto yy156;
+                       if (yych <= '+') goto yy154;
+                       goto yy157;
                } else {
-                       if (yych <= '<') goto yy153;
-                       if (yych <= '>') goto yy156;
-                       goto yy153;
+                       if (yych <= '<') goto yy154;
+                       if (yych <= '>') goto yy157;
+                       goto yy154;
                }
        }
-yy160:
+yy161:
        ++YYCURSOR;
-       if ((yych = (YYCTYPE)*YYCURSOR) == '>') goto yy179;
+       if ((yych = (YYCTYPE)*YYCURSOR) == '>') goto yy183;
 #line 243 "../src/parse/lex.re"
        {
                                        tok += 2; /* skip ":=" */
                                        depth = 0;
                                        goto code;
                                }
-#line 1082 "src/parse/lex.cc"
-yy162:
+#line 1100 "src/parse/lex.cc"
+yy163:
        ++YYCURSOR;
 #line 271 "../src/parse/lex.re"
        {
                                        return TOKEN_SETUP;
                                }
-#line 1089 "src/parse/lex.cc"
-yy164:
+#line 1107 "src/parse/lex.cc"
+yy165:
        yych = (YYCTYPE)*++YYCURSOR;
        YYCTXMARKER = YYCURSOR;
-       goto yy182;
-yy165:
+       goto yy186;
+yy166:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = (YYCTYPE)*YYCURSOR;
+       if (yych <= 'Z') {
+               if (yych <= '/') goto yy168;
+               if (yych <= '9') goto yy166;
+               if (yych >= 'A') goto yy166;
+       } else {
+               if (yych <= '_') {
+                       if (yych >= '_') goto yy166;
+               } else {
+                       if (yych <= '`') goto yy168;
+                       if (yych <= 'z') goto yy166;
+               }
+       }
+yy168:
+#line 275 "../src/parse/lex.re"
+       {
+               yylval.str = new std::string(tok + 1, tok_len() - 1);
+               return TOKEN_CTX;
+       }
+#line 1134 "src/parse/lex.cc"
+yy169:
        ++YYCURSOR;
 #line 266 "../src/parse/lex.re"
        { yylval.regexp = lex_cls(true);  return TOKEN_REGEXP; }
-#line 1098 "src/parse/lex.cc"
-yy167:
+#line 1139 "src/parse/lex.cc"
+yy171:
        yych = (YYCTYPE)*++YYCURSOR;
        YYCTXMARKER = YYCURSOR;
-       if (yych == '2') goto yy187;
-       goto yy159;
-yy168:
+       if (yych == '2') goto yy191;
+       goto yy160;
+yy172:
        ++YYCURSOR;
-yy169:
-#line 318 "../src/parse/lex.re"
+yy173:
+#line 324 "../src/parse/lex.re"
        {
                                        fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers");
                                }
-#line 1111 "src/parse/lex.cc"
-yy170:
+#line 1152 "src/parse/lex.cc"
+yy174:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 64) {
-               goto yy170;
+               goto yy174;
        }
        if (yych <= '^') {
                if (yych <= ',') {
-                       if (yych <= '+') goto yy144;
-                       goto yy188;
+                       if (yych <= '+') goto yy145;
+                       goto yy192;
                } else {
-                       if (yych <= '@') goto yy144;
-                       if (yych >= '[') goto yy144;
+                       if (yych <= '@') goto yy145;
+                       if (yych >= '[') goto yy145;
                }
        } else {
                if (yych <= 'z') {
-                       if (yych == '`') goto yy144;
+                       if (yych == '`') goto yy145;
                } else {
-                       if (yych == '}') goto yy189;
-                       goto yy144;
+                       if (yych == '}') goto yy193;
+                       goto yy145;
                }
        }
-yy172:
+yy176:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '^') {
                if (yych <= '9') {
-                       if (yych <= '/') goto yy144;
-                       goto yy172;
+                       if (yych <= '/') goto yy145;
+                       goto yy176;
                } else {
-                       if (yych <= '@') goto yy144;
-                       if (yych <= 'Z') goto yy172;
-                       goto yy144;
+                       if (yych <= '@') goto yy145;
+                       if (yych <= 'Z') goto yy176;
+                       goto yy145;
                }
        } else {
                if (yych <= 'z') {
-                       if (yych == '`') goto yy144;
-                       goto yy172;
+                       if (yych == '`') goto yy145;
+                       goto yy176;
                } else {
-                       if (yych == '}') goto yy191;
-                       goto yy144;
+                       if (yych == '}') goto yy195;
+                       goto yy145;
                }
        }
-yy174:
+yy178:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'i') goto yy193;
-       goto yy144;
-yy175:
+       if (yych == 'i') goto yy197;
+       goto yy145;
+yy179:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 332 "../src/parse/lex.re"
+#line 338 "../src/parse/lex.re"
        {
                                        yylval.str = new std::string (tok, tok_len ());
                                        if (opts->FFlag)
@@ -1173,87 +1214,87 @@ yy175:
                                                return TOKEN_ID;
                                        }
                                }
-#line 1177 "src/parse/lex.cc"
-yy177:
+#line 1218 "src/parse/lex.cc"
+yy181:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy178:
+yy182:
        if (yych <= ' ') {
-               if (yych == '\t') goto yy177;
-               if (yych <= 0x1F) goto yy175;
-               goto yy177;
+               if (yych == '\t') goto yy181;
+               if (yych <= 0x1F) goto yy179;
+               goto yy181;
        } else {
                if (yych <= ',') {
-                       if (yych <= '+') goto yy175;
-                       goto yy156;
+                       if (yych <= '+') goto yy179;
+                       goto yy157;
                } else {
-                       if (yych <= '<') goto yy175;
-                       if (yych <= '>') goto yy156;
-                       goto yy175;
+                       if (yych <= '<') goto yy179;
+                       if (yych <= '>') goto yy157;
+                       goto yy179;
                }
        }
-yy179:
+yy183:
        ++YYCURSOR;
        YYCURSOR -= 2;
 #line 239 "../src/parse/lex.re"
        {
                                        return *tok;
                                }
-#line 1204 "src/parse/lex.cc"
-yy181:
+#line 1245 "src/parse/lex.cc"
+yy185:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
-yy182:
+yy186:
        if (yych <= '9') {
                if (yych <= '\t') {
-                       if (yych <= 0x08) goto yy144;
-                       goto yy181;
+                       if (yych <= 0x08) goto yy145;
+                       goto yy185;
                } else {
-                       if (yych == ' ') goto yy181;
-                       goto yy144;
+                       if (yych == ' ') goto yy185;
+                       goto yy145;
                }
        } else {
                if (yych <= '=') {
-                       if (yych <= ':') goto yy183;
-                       if (yych <= '<') goto yy144;
-                       goto yy184;
+                       if (yych <= ':') goto yy187;
+                       if (yych <= '<') goto yy145;
+                       goto yy188;
                } else {
-                       if (yych == '{') goto yy185;
-                       goto yy144;
+                       if (yych == '{') goto yy189;
+                       goto yy145;
                }
        }
-yy183:
+yy187:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '=') goto yy185;
-       goto yy144;
-yy184:
+       if (yych == '=') goto yy189;
+       goto yy145;
+yy188:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != '>') goto yy144;
-yy185:
+       if (yych != '>') goto yy145;
+yy189:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
 #line 268 "../src/parse/lex.re"
        {
                                        return TOKEN_NOCOND;
                                }
-#line 1242 "src/parse/lex.cc"
-yy187:
+#line 1283 "src/parse/lex.cc"
+yy191:
        yych = (YYCTYPE)*++YYCURSOR;
        YYCTXMARKER = YYCURSOR;
-       if (yych == 'c') goto yy194;
-       goto yy159;
-yy188:
+       if (yych == 'c') goto yy198;
+       goto yy160;
+yy192:
        yyaccept = 3;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych <= '/') goto yy169;
-       if (yych <= '9') goto yy195;
-       if (yych == '}') goto yy197;
-       goto yy169;
-yy189:
+       if (yych <= '/') goto yy173;
+       if (yych <= '9') goto yy199;
+       if (yych == '}') goto yy201;
+       goto yy173;
+yy193:
        ++YYCURSOR;
-#line 287 "../src/parse/lex.re"
+#line 293 "../src/parse/lex.re"
        {
                                        if (!s_to_u32_unsafe (tok + 1, cur - 1, yylval.extop.min))
                                        {
@@ -1262,10 +1303,10 @@ yy189:
                                        yylval.extop.max = yylval.extop.min;
                                        return TOKEN_CLOSESIZE;
                                }
-#line 1266 "src/parse/lex.cc"
-yy191:
+#line 1307 "src/parse/lex.cc"
+yy195:
        ++YYCURSOR;
-#line 322 "../src/parse/lex.re"
+#line 328 "../src/parse/lex.re"
        {
                                        if (!opts->FFlag) {
                                                fatal("curly braces for names only allowed with -F switch");
@@ -1273,27 +1314,27 @@ yy191:
                                        yylval.str = new std::string (tok + 1, tok_len () - 2); // -2 to omit braces
                                        return TOKEN_ID;
                                }
-#line 1277 "src/parse/lex.cc"
-yy193:
+#line 1318 "src/parse/lex.cc"
+yy197:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'n') goto yy199;
-       goto yy144;
-yy194:
+       if (yych == 'n') goto yy203;
+       goto yy145;
+yy198:
        yych = (YYCTYPE)*++YYCURSOR;
        YYCTXMARKER = YYCURSOR;
-       if (yych == ':') goto yy200;
-       goto yy159;
-yy195:
+       if (yych == ':') goto yy204;
+       goto yy160;
+yy199:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych <= '/') goto yy144;
-       if (yych <= '9') goto yy195;
-       if (yych == '}') goto yy202;
-       goto yy144;
-yy197:
+       if (yych <= '/') goto yy145;
+       if (yych <= '9') goto yy199;
+       if (yych == '}') goto yy206;
+       goto yy145;
+yy201:
        ++YYCURSOR;
-#line 309 "../src/parse/lex.re"
+#line 315 "../src/parse/lex.re"
        {
                                        if (!s_to_u32_unsafe (tok + 1, cur - 2, yylval.extop.min))
                                        {
@@ -1302,19 +1343,19 @@ yy197:
                                        yylval.extop.max = std::numeric_limits<uint32_t>::max();
                                        return TOKEN_CLOSESIZE;
                                }
-#line 1306 "src/parse/lex.cc"
-yy199:
+#line 1347 "src/parse/lex.cc"
+yy203:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy204;
-       goto yy144;
-yy200:
+       if (yych == 'e') goto yy208;
+       goto yy145;
+yy204:
        ++YYCURSOR;
-#line 330 "../src/parse/lex.re"
+#line 336 "../src/parse/lex.re"
        { lex_conf (); return TOKEN_CONF; }
-#line 1315 "src/parse/lex.cc"
-yy202:
+#line 1356 "src/parse/lex.cc"
+yy206:
        ++YYCURSOR;
-#line 296 "../src/parse/lex.re"
+#line 302 "../src/parse/lex.re"
        {
                                        const char * p = strchr (tok, ',');
                                        if (!s_to_u32_unsafe (tok + 1, p, yylval.extop.min))
@@ -1327,132 +1368,132 @@ yy202:
                                        }
                                        return TOKEN_CLOSESIZE;
                                }
-#line 1331 "src/parse/lex.cc"
-yy204:
+#line 1372 "src/parse/lex.cc"
+yy208:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= '0') goto yy206;
-       if (yych <= '9') goto yy144;
-       goto yy206;
-yy205:
+       if (yych <= '0') goto yy210;
+       if (yych <= '9') goto yy145;
+       goto yy210;
+yy209:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        YYCTXMARKER = YYCURSOR;
-yy206:
+yy210:
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy205;
-               goto yy144;
+               if (yych == '\t') goto yy209;
+               goto yy145;
        } else {
-               if (yych <= ' ') goto yy205;
-               if (yych <= '0') goto yy144;
-               if (yych >= ':') goto yy144;
+               if (yych <= ' ') goto yy209;
+               if (yych <= '0') goto yy145;
+               if (yych >= ':') goto yy145;
        }
-yy207:
+yy211:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '\r') {
                if (yych <= '\t') {
-                       if (yych <= 0x08) goto yy144;
+                       if (yych <= 0x08) goto yy145;
                } else {
-                       if (yych <= '\n') goto yy211;
-                       if (yych <= '\f') goto yy144;
-                       goto yy213;
+                       if (yych <= '\n') goto yy215;
+                       if (yych <= '\f') goto yy145;
+                       goto yy217;
                }
        } else {
                if (yych <= ' ') {
-                       if (yych <= 0x1F) goto yy144;
+                       if (yych <= 0x1F) goto yy145;
                } else {
-                       if (yych <= '/') goto yy144;
-                       if (yych <= '9') goto yy207;
-                       goto yy144;
+                       if (yych <= '/') goto yy145;
+                       if (yych <= '9') goto yy211;
+                       goto yy145;
                }
        }
-yy209:
+yy213:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy209;
-               goto yy144;
+               if (yych == '\t') goto yy213;
+               goto yy145;
        } else {
-               if (yych <= ' ') goto yy209;
-               if (yych == '"') goto yy214;
-               goto yy144;
+               if (yych <= ' ') goto yy213;
+               if (yych == '"') goto yy218;
+               goto yy145;
        }
-yy211:
+yy215:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 375 "../src/parse/lex.re"
+#line 381 "../src/parse/lex.re"
        {
                                        set_sourceline ();
                                        goto scan;
                                }
-#line 1392 "src/parse/lex.cc"
-yy213:
+#line 1433 "src/parse/lex.cc"
+yy217:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy211;
-       goto yy144;
-yy214:
+       if (yych == '\n') goto yy215;
+       goto yy145;
+yy218:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 128) {
-               goto yy214;
+               goto yy218;
        }
-       if (yych <= '\n') goto yy144;
-       if (yych >= '#') goto yy217;
+       if (yych <= '\n') goto yy145;
+       if (yych >= '#') goto yy221;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy211;
-       if (yych == '\r') goto yy213;
-       goto yy144;
-yy217:
+       if (yych == '\n') goto yy215;
+       if (yych == '\r') goto yy217;
+       goto yy145;
+yy221:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy144;
-       goto yy214;
+       if (yych == '\n') goto yy145;
+       goto yy218;
 }
-#line 391 "../src/parse/lex.re"
+#line 397 "../src/parse/lex.re"
 
 
 flex_name:
 
-#line 1422 "src/parse/lex.cc"
+#line 1463 "src/parse/lex.cc"
 {
        YYCTYPE yych;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy222;
-       if (yych == '\r') goto yy224;
+       if (yych == '\n') goto yy226;
+       if (yych == '\r') goto yy228;
        ++YYCURSOR;
-yy221:
-#line 402 "../src/parse/lex.re"
+yy225:
+#line 408 "../src/parse/lex.re"
        {
                YYCURSOR = tok;
                goto start;
        }
-#line 1436 "src/parse/lex.cc"
-yy222:
+#line 1477 "src/parse/lex.cc"
+yy226:
        ++YYCURSOR;
-#line 396 "../src/parse/lex.re"
+#line 402 "../src/parse/lex.re"
        {
                YYCURSOR = tok;
                lexer_state = LEX_NORMAL;
                return TOKEN_FID_END;
        }
-#line 1445 "src/parse/lex.cc"
-yy224:
+#line 1486 "src/parse/lex.cc"
+yy228:
        ++YYCURSOR;
-       if ((yych = (YYCTYPE)*YYCURSOR) == '\n') goto yy222;
-       goto yy221;
+       if ((yych = (YYCTYPE)*YYCURSOR) == '\n') goto yy226;
+       goto yy225;
 }
-#line 406 "../src/parse/lex.re"
+#line 412 "../src/parse/lex.re"
 
 
 code:
 
-#line 1456 "src/parse/lex.cc"
+#line 1497 "src/parse/lex.cc"
 {
        YYCTYPE yych;
        unsigned int yyaccept = 0;
@@ -1494,26 +1535,26 @@ code:
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '&') {
                if (yych <= '\n') {
-                       if (yych <= 0x00) goto yy227;
-                       if (yych <= '\t') goto yy229;
-                       goto yy231;
+                       if (yych <= 0x00) goto yy231;
+                       if (yych <= '\t') goto yy233;
+                       goto yy235;
                } else {
-                       if (yych == '"') goto yy233;
-                       goto yy229;
+                       if (yych == '"') goto yy237;
+                       goto yy233;
                }
        } else {
                if (yych <= '{') {
-                       if (yych <= '\'') goto yy234;
-                       if (yych <= 'z') goto yy229;
-                       goto yy235;
+                       if (yych <= '\'') goto yy238;
+                       if (yych <= 'z') goto yy233;
+                       goto yy239;
                } else {
-                       if (yych == '}') goto yy237;
-                       goto yy229;
+                       if (yych == '}') goto yy241;
+                       goto yy233;
                }
        }
-yy227:
+yy231:
        ++YYCURSOR;
-#line 469 "../src/parse/lex.re"
+#line 475 "../src/parse/lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -1525,34 +1566,34 @@ yy227:
                                        }
                                        goto code;
                                }
-#line 1529 "src/parse/lex.cc"
-yy229:
+#line 1570 "src/parse/lex.cc"
+yy233:
        ++YYCURSOR;
-yy230:
-#line 483 "../src/parse/lex.re"
+yy234:
+#line 489 "../src/parse/lex.re"
        {
                                        goto code;
                                }
-#line 1537 "src/parse/lex.cc"
-yy231:
+#line 1578 "src/parse/lex.cc"
+yy235:
        yyaccept = 0;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= '\r') {
                if (yych <= '\t') {
-                       if (yych >= '\t') goto yy239;
+                       if (yych >= '\t') goto yy243;
                } else {
-                       if (yych <= '\n') goto yy241;
-                       if (yych >= '\r') goto yy241;
+                       if (yych <= '\n') goto yy245;
+                       if (yych >= '\r') goto yy245;
                }
        } else {
                if (yych <= ' ') {
-                       if (yych >= ' ') goto yy239;
+                       if (yych >= ' ') goto yy243;
                } else {
-                       if (yych == '#') goto yy242;
+                       if (yych == '#') goto yy246;
                }
        }
-yy232:
-#line 450 "../src/parse/lex.re"
+yy236:
+#line 456 "../src/parse/lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -1572,20 +1613,20 @@ yy232:
                                        cline++;
                                        goto code;
                                }
-#line 1576 "src/parse/lex.cc"
-yy233:
+#line 1617 "src/parse/lex.cc"
+yy237:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == '\n') goto yy230;
-       goto yy246;
-yy234:
+       if (yych == '\n') goto yy234;
+       goto yy250;
+yy238:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == '\n') goto yy230;
-       goto yy251;
-yy235:
+       if (yych == '\n') goto yy234;
+       goto yy255;
+yy239:
        ++YYCURSOR;
-#line 422 "../src/parse/lex.re"
+#line 428 "../src/parse/lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -1597,10 +1638,10 @@ yy235:
                                        }
                                        goto code;
                                }
-#line 1601 "src/parse/lex.cc"
-yy237:
+#line 1642 "src/parse/lex.cc"
+yy241:
        ++YYCURSOR;
-#line 410 "../src/parse/lex.re"
+#line 416 "../src/parse/lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -1613,19 +1654,19 @@ yy237:
                                        }
                                        goto code;
                                }
-#line 1617 "src/parse/lex.cc"
-yy239:
+#line 1658 "src/parse/lex.cc"
+yy243:
        yyaccept = 2;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy253;
+               if (yych == '\t') goto yy257;
        } else {
-               if (yych <= ' ') goto yy253;
-               if (yych == '#') goto yy242;
+               if (yych <= ' ') goto yy257;
+               if (yych == '#') goto yy246;
        }
-yy240:
+yy244:
        YYCURSOR -= 1;
-#line 437 "../src/parse/lex.re"
+#line 443 "../src/parse/lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -1639,175 +1680,175 @@ yy240:
                                        cline++;
                                        goto code;
                                }
-#line 1643 "src/parse/lex.cc"
-yy241:
+#line 1684 "src/parse/lex.cc"
+yy245:
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy240;
-yy242:
+       goto yy244;
+yy246:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 16) {
-               goto yy242;
+               goto yy246;
        }
-       if (yych == 'l') goto yy255;
-yy244:
+       if (yych == 'l') goto yy259;
+yy248:
        YYCURSOR = YYMARKER;
        if (yyaccept <= 1) {
                if (yyaccept == 0) {
-                       goto yy232;
+                       goto yy236;
                } else {
-                       goto yy230;
+                       goto yy234;
                }
        } else {
-               goto yy240;
+               goto yy244;
        }
-yy245:
+yy249:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy246:
+yy250:
        if (yybm[0+yych] & 32) {
-               goto yy245;
+               goto yy249;
        }
-       if (yych <= '\n') goto yy244;
-       if (yych >= '#') goto yy249;
-yy247:
+       if (yych <= '\n') goto yy248;
+       if (yych >= '#') goto yy253;
+yy251:
        ++YYCURSOR;
-#line 480 "../src/parse/lex.re"
+#line 486 "../src/parse/lex.re"
        {
                                        goto code;
                                }
-#line 1682 "src/parse/lex.cc"
-yy249:
+#line 1723 "src/parse/lex.cc"
+yy253:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy244;
-       goto yy245;
-yy250:
+       if (yych == '\n') goto yy248;
+       goto yy249;
+yy254:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy251:
+yy255:
        if (yybm[0+yych] & 64) {
-               goto yy250;
+               goto yy254;
        }
-       if (yych <= '\n') goto yy244;
-       if (yych <= '\'') goto yy247;
+       if (yych <= '\n') goto yy248;
+       if (yych <= '\'') goto yy251;
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy244;
-       goto yy250;
-yy253:
+       if (yych == '\n') goto yy248;
+       goto yy254;
+yy257:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy253;
-               goto yy244;
+               if (yych == '\t') goto yy257;
+               goto yy248;
        } else {
-               if (yych <= ' ') goto yy253;
-               if (yych == '#') goto yy242;
-               goto yy244;
+               if (yych <= ' ') goto yy257;
+               if (yych == '#') goto yy246;
+               goto yy248;
        }
-yy255:
+yy259:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'i') goto yy244;
+       if (yych != 'i') goto yy248;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'n') goto yy244;
+       if (yych != 'n') goto yy248;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'e') goto yy244;
+       if (yych != 'e') goto yy248;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= '0') goto yy260;
-       if (yych <= '9') goto yy244;
-       goto yy260;
-yy259:
+       if (yych <= '0') goto yy264;
+       if (yych <= '9') goto yy248;
+       goto yy264;
+yy263:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        YYCTXMARKER = YYCURSOR;
-yy260:
+yy264:
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy259;
-               goto yy244;
+               if (yych == '\t') goto yy263;
+               goto yy248;
        } else {
-               if (yych <= ' ') goto yy259;
-               if (yych <= '0') goto yy244;
-               if (yych >= ':') goto yy244;
+               if (yych <= ' ') goto yy263;
+               if (yych <= '0') goto yy248;
+               if (yych >= ':') goto yy248;
        }
-yy261:
+yy265:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 128) {
-               goto yy261;
+               goto yy265;
        }
        if (yych <= '\f') {
-               if (yych <= 0x08) goto yy244;
-               if (yych <= '\t') goto yy263;
-               if (yych <= '\n') goto yy265;
-               goto yy244;
+               if (yych <= 0x08) goto yy248;
+               if (yych <= '\t') goto yy267;
+               if (yych <= '\n') goto yy269;
+               goto yy248;
        } else {
-               if (yych <= '\r') goto yy267;
-               if (yych != ' ') goto yy244;
+               if (yych <= '\r') goto yy271;
+               if (yych != ' ') goto yy248;
        }
-yy263:
+yy267:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy263;
-               goto yy244;
+               if (yych == '\t') goto yy267;
+               goto yy248;
        } else {
-               if (yych <= ' ') goto yy263;
-               if (yych == '"') goto yy268;
-               goto yy244;
+               if (yych <= ' ') goto yy267;
+               if (yych == '"') goto yy272;
+               goto yy248;
        }
-yy265:
+yy269:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 433 "../src/parse/lex.re"
+#line 439 "../src/parse/lex.re"
        {
                                        set_sourceline ();
                                        goto code;
                                }
-#line 1777 "src/parse/lex.cc"
-yy267:
+#line 1818 "src/parse/lex.cc"
+yy271:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy265;
-       goto yy244;
-yy268:
+       if (yych == '\n') goto yy269;
+       goto yy248;
+yy272:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '!') {
-               if (yych == '\n') goto yy244;
-               goto yy268;
+               if (yych == '\n') goto yy248;
+               goto yy272;
        } else {
-               if (yych <= '"') goto yy270;
-               if (yych == '\\') goto yy271;
-               goto yy268;
+               if (yych <= '"') goto yy274;
+               if (yych == '\\') goto yy275;
+               goto yy272;
        }
-yy270:
+yy274:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy265;
-       if (yych == '\r') goto yy267;
-       goto yy244;
-yy271:
+       if (yych == '\n') goto yy269;
+       if (yych == '\r') goto yy271;
+       goto yy248;
+yy275:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy244;
-       goto yy268;
+       if (yych == '\n') goto yy248;
+       goto yy272;
 }
-#line 486 "../src/parse/lex.re"
+#line 492 "../src/parse/lex.re"
 
 
 comment:
 
-#line 1811 "src/parse/lex.cc"
+#line 1852 "src/parse/lex.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -1847,14 +1888,14 @@ comment:
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= ')') {
-               if (yych == '\n') goto yy276;
+               if (yych == '\n') goto yy280;
        } else {
-               if (yych <= '*') goto yy278;
-               if (yych == '/') goto yy279;
+               if (yych <= '*') goto yy282;
+               if (yych == '/') goto yy283;
        }
        ++YYCURSOR;
-yy275:
-#line 518 "../src/parse/lex.re"
+yy279:
+#line 524 "../src/parse/lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -1862,15 +1903,15 @@ yy275:
                                        }
                                        goto comment;
                                }
-#line 1866 "src/parse/lex.cc"
-yy276:
+#line 1907 "src/parse/lex.cc"
+yy280:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yybm[0+yych] & 32) {
-               goto yy280;
+               goto yy284;
        }
-       if (yych == '#') goto yy283;
-yy277:
-#line 509 "../src/parse/lex.re"
+       if (yych == '#') goto yy287;
+yy281:
+#line 515 "../src/parse/lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -1880,41 +1921,41 @@ yy277:
                                        cline++;
                                        goto comment;
                                }
-#line 1884 "src/parse/lex.cc"
-yy278:
+#line 1925 "src/parse/lex.cc"
+yy282:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '/') goto yy285;
-       goto yy275;
-yy279:
+       if (yych == '/') goto yy289;
+       goto yy279;
+yy283:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '*') goto yy287;
-       goto yy275;
-yy280:
+       if (yych == '*') goto yy291;
+       goto yy279;
+yy284:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 32) {
-               goto yy280;
+               goto yy284;
        }
-       if (yych == '#') goto yy283;
-yy282:
+       if (yych == '#') goto yy287;
+yy286:
        YYCURSOR = YYMARKER;
-       goto yy277;
-yy283:
+       goto yy281;
+yy287:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy283;
-               goto yy282;
+               if (yych == '\t') goto yy287;
+               goto yy286;
        } else {
-               if (yych <= ' ') goto yy283;
-               if (yych == 'l') goto yy289;
-               goto yy282;
+               if (yych <= ' ') goto yy287;
+               if (yych == 'l') goto yy293;
+               goto yy286;
        }
-yy285:
+yy289:
        ++YYCURSOR;
-#line 490 "../src/parse/lex.re"
+#line 496 "../src/parse/lex.re"
        {
                                        if (--depth == 0)
                                        {
@@ -1925,124 +1966,124 @@ yy285:
                                                goto comment;
                                        }
                                }
-#line 1929 "src/parse/lex.cc"
-yy287:
+#line 1970 "src/parse/lex.cc"
+yy291:
        ++YYCURSOR;
-#line 500 "../src/parse/lex.re"
+#line 506 "../src/parse/lex.re"
        {
                                        ++depth;
                                        fatal("ambiguous /* found");
                                        goto comment;
                                }
-#line 1938 "src/parse/lex.cc"
-yy289:
+#line 1979 "src/parse/lex.cc"
+yy293:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'i') goto yy282;
+       if (yych != 'i') goto yy286;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'n') goto yy282;
+       if (yych != 'n') goto yy286;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'e') goto yy282;
+       if (yych != 'e') goto yy286;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= '0') goto yy294;
-       if (yych <= '9') goto yy282;
-       goto yy294;
-yy293:
+       if (yych <= '0') goto yy298;
+       if (yych <= '9') goto yy286;
+       goto yy298;
+yy297:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        YYCTXMARKER = YYCURSOR;
-yy294:
+yy298:
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy293;
-               goto yy282;
+               if (yych == '\t') goto yy297;
+               goto yy286;
        } else {
-               if (yych <= ' ') goto yy293;
-               if (yych <= '0') goto yy282;
-               if (yych >= ':') goto yy282;
+               if (yych <= ' ') goto yy297;
+               if (yych <= '0') goto yy286;
+               if (yych >= ':') goto yy286;
        }
-yy295:
+yy299:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 64) {
-               goto yy295;
+               goto yy299;
        }
        if (yych <= '\f') {
-               if (yych <= 0x08) goto yy282;
-               if (yych <= '\t') goto yy297;
-               if (yych <= '\n') goto yy299;
-               goto yy282;
+               if (yych <= 0x08) goto yy286;
+               if (yych <= '\t') goto yy301;
+               if (yych <= '\n') goto yy303;
+               goto yy286;
        } else {
-               if (yych <= '\r') goto yy301;
-               if (yych != ' ') goto yy282;
+               if (yych <= '\r') goto yy305;
+               if (yych != ' ') goto yy286;
        }
-yy297:
+yy301:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy297;
-               goto yy282;
+               if (yych == '\t') goto yy301;
+               goto yy286;
        } else {
-               if (yych <= ' ') goto yy297;
-               if (yych == '"') goto yy302;
-               goto yy282;
+               if (yych <= ' ') goto yy301;
+               if (yych == '"') goto yy306;
+               goto yy286;
        }
-yy299:
+yy303:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 505 "../src/parse/lex.re"
+#line 511 "../src/parse/lex.re"
        {
                                        set_sourceline ();
                                        goto comment;
                                }
-#line 2000 "src/parse/lex.cc"
-yy301:
+#line 2041 "src/parse/lex.cc"
+yy305:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy299;
-       goto yy282;
-yy302:
+       if (yych == '\n') goto yy303;
+       goto yy286;
+yy306:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 128) {
-               goto yy302;
+               goto yy306;
        }
-       if (yych <= '\n') goto yy282;
-       if (yych >= '#') goto yy305;
+       if (yych <= '\n') goto yy286;
+       if (yych >= '#') goto yy309;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy299;
-       if (yych == '\r') goto yy301;
-       goto yy282;
-yy305:
+       if (yych == '\n') goto yy303;
+       if (yych == '\r') goto yy305;
+       goto yy286;
+yy309:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy282;
-       goto yy302;
+       if (yych == '\n') goto yy286;
+       goto yy306;
 }
-#line 525 "../src/parse/lex.re"
+#line 531 "../src/parse/lex.re"
 
 
 nextLine:
 
-#line 2030 "src/parse/lex.cc"
+#line 2071 "src/parse/lex.cc"
 {
        YYCTYPE yych;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy310;
+       if (yych == '\n') goto yy314;
        ++YYCURSOR;
-#line 536 "../src/parse/lex.re"
+#line 542 "../src/parse/lex.re"
        {  if(cur == eof) {
                   return 0;
                }
                goto nextLine;
             }
-#line 2043 "src/parse/lex.cc"
-yy310:
+#line 2084 "src/parse/lex.cc"
+yy314:
        ++YYCURSOR;
-#line 529 "../src/parse/lex.re"
+#line 535 "../src/parse/lex.re"
        { if(cur == eof) {
                   return 0;
                }
@@ -2050,9 +2091,9 @@ yy310:
                cline++;
                goto scan;
             }
-#line 2054 "src/parse/lex.cc"
+#line 2095 "src/parse/lex.cc"
 }
-#line 541 "../src/parse/lex.re"
+#line 547 "../src/parse/lex.re"
 
 }
 
@@ -2076,44 +2117,44 @@ const RegExp *Scanner::lex_cls(bool neg)
        uint32_t u, l;
 fst:
        
-#line 2080 "src/parse/lex.cc"
+#line 2121 "src/parse/lex.cc"
 {
        YYCTYPE yych;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == ']') goto yy315;
-#line 565 "../src/parse/lex.re"
+       if (yych == ']') goto yy319;
+#line 571 "../src/parse/lex.re"
        { l = lex_cls_chr(); goto snd; }
-#line 2088 "src/parse/lex.cc"
-yy315:
+#line 2129 "src/parse/lex.cc"
+yy319:
        ++YYCURSOR;
-#line 564 "../src/parse/lex.re"
+#line 570 "../src/parse/lex.re"
        { goto end; }
-#line 2093 "src/parse/lex.cc"
+#line 2134 "src/parse/lex.cc"
 }
-#line 566 "../src/parse/lex.re"
+#line 572 "../src/parse/lex.re"
 
 snd:
        
-#line 2099 "src/parse/lex.cc"
+#line 2140 "src/parse/lex.cc"
 {
        YYCTYPE yych;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*(YYMARKER = YYCURSOR);
-       if (yych == '-') goto yy320;
-yy319:
-#line 569 "../src/parse/lex.re"
+       if (yych == '-') goto yy324;
+yy323:
+#line 575 "../src/parse/lex.re"
        { u = l; goto add; }
-#line 2108 "src/parse/lex.cc"
-yy320:
+#line 2149 "src/parse/lex.cc"
+yy324:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != ']') goto yy322;
+       if (yych != ']') goto yy326;
        YYCURSOR = YYMARKER;
-       goto yy319;
-yy322:
+       goto yy323;
+yy326:
        ++YYCURSOR;
        YYCURSOR -= 1;
-#line 570 "../src/parse/lex.re"
+#line 576 "../src/parse/lex.re"
        {
                        u = lex_cls_chr();
                        if (l > u) {
@@ -2122,9 +2163,9 @@ yy322:
                        }
                        goto add;
                }
-#line 2126 "src/parse/lex.cc"
+#line 2167 "src/parse/lex.cc"
 }
-#line 578 "../src/parse/lex.re"
+#line 584 "../src/parse/lex.re"
 
 add:
        if (!(s = opts->encoding.encodeRange(l, u))) {
@@ -2143,290 +2184,290 @@ uint32_t Scanner::lex_cls_chr()
 {
        tok = cur;
        
-#line 2147 "src/parse/lex.cc"
+#line 2188 "src/parse/lex.cc"
 {
        YYCTYPE yych;
        unsigned int yyaccept = 0;
        if ((YYLIMIT - YYCURSOR) < 10) YYFILL(10);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy328;
-       if (yych == '\\') goto yy330;
+       if (yych == '\n') goto yy332;
+       if (yych == '\\') goto yy334;
        ++YYCURSOR;
-#line 601 "../src/parse/lex.re"
+#line 607 "../src/parse/lex.re"
        { return static_cast<uint8_t>(tok[0]); }
-#line 2158 "src/parse/lex.cc"
-yy328:
+#line 2199 "src/parse/lex.cc"
+yy332:
        ++YYCURSOR;
-#line 596 "../src/parse/lex.re"
+#line 602 "../src/parse/lex.re"
        { fatal ((tok - pos) - tchar, "syntax error"); }
-#line 2163 "src/parse/lex.cc"
-yy330:
+#line 2204 "src/parse/lex.cc"
+yy334:
        ++YYCURSOR;
        if ((yych = (YYCTYPE)*YYCURSOR) <= '`') {
                if (yych <= '7') {
                        if (yych <= ',') {
-                               if (yych != '\n') goto yy332;
+                               if (yych != '\n') goto yy336;
                        } else {
-                               if (yych <= '-') goto yy334;
-                               if (yych <= '/') goto yy332;
-                               if (yych <= '3') goto yy336;
-                               goto yy338;
+                               if (yych <= '-') goto yy338;
+                               if (yych <= '/') goto yy336;
+                               if (yych <= '3') goto yy340;
+                               goto yy342;
                        }
                } else {
                        if (yych <= 'X') {
-                               if (yych == 'U') goto yy339;
-                               if (yych <= 'W') goto yy332;
-                               goto yy341;
+                               if (yych == 'U') goto yy343;
+                               if (yych <= 'W') goto yy336;
+                               goto yy345;
                        } else {
-                               if (yych <= '[') goto yy332;
-                               if (yych <= '\\') goto yy342;
-                               if (yych <= ']') goto yy344;
-                               goto yy332;
+                               if (yych <= '[') goto yy336;
+                               if (yych <= '\\') goto yy346;
+                               if (yych <= ']') goto yy348;
+                               goto yy336;
                        }
                }
        } else {
                if (yych <= 'q') {
                        if (yych <= 'e') {
-                               if (yych <= 'a') goto yy346;
-                               if (yych <= 'b') goto yy348;
-                               goto yy332;
+                               if (yych <= 'a') goto yy350;
+                               if (yych <= 'b') goto yy352;
+                               goto yy336;
                        } else {
-                               if (yych <= 'f') goto yy350;
-                               if (yych == 'n') goto yy352;
-                               goto yy332;
+                               if (yych <= 'f') goto yy354;
+                               if (yych == 'n') goto yy356;
+                               goto yy336;
                        }
                } else {
                        if (yych <= 'u') {
-                               if (yych <= 'r') goto yy354;
-                               if (yych <= 's') goto yy332;
-                               if (yych <= 't') goto yy356;
-                               goto yy341;
+                               if (yych <= 'r') goto yy358;
+                               if (yych <= 's') goto yy336;
+                               if (yych <= 't') goto yy360;
+                               goto yy345;
                        } else {
-                               if (yych <= 'v') goto yy358;
-                               if (yych == 'x') goto yy360;
-                               goto yy332;
+                               if (yych <= 'v') goto yy362;
+                               if (yych == 'x') goto yy364;
+                               goto yy336;
                        }
                }
        }
-#line 599 "../src/parse/lex.re"
+#line 605 "../src/parse/lex.re"
        { fatal ((tok - pos) - tchar, "syntax error in escape sequence"); }
-#line 2214 "src/parse/lex.cc"
-yy332:
+#line 2255 "src/parse/lex.cc"
+yy336:
        ++YYCURSOR;
-#line 614 "../src/parse/lex.re"
+#line 620 "../src/parse/lex.re"
        {
                        warn.useless_escape(tline, tok - pos, tok[1]);
                        return static_cast<uint8_t>(tok[1]);
                }
-#line 2222 "src/parse/lex.cc"
-yy334:
+#line 2263 "src/parse/lex.cc"
+yy338:
        ++YYCURSOR;
-#line 612 "../src/parse/lex.re"
+#line 618 "../src/parse/lex.re"
        { return static_cast<uint8_t>('-'); }
-#line 2227 "src/parse/lex.cc"
-yy336:
+#line 2268 "src/parse/lex.cc"
+yy340:
        yyaccept = 0;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych <= '/') goto yy337;
-       if (yych <= '7') goto yy361;
-yy337:
-#line 598 "../src/parse/lex.re"
+       if (yych <= '/') goto yy341;
+       if (yych <= '7') goto yy365;
+yy341:
+#line 604 "../src/parse/lex.re"
        { fatal ((tok - pos) - tchar, "syntax error in octal escape sequence"); }
-#line 2236 "src/parse/lex.cc"
-yy338:
+#line 2277 "src/parse/lex.cc"
+yy342:
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy337;
-yy339:
+       goto yy341;
+yy343:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= '@') {
-               if (yych <= '/') goto yy340;
-               if (yych <= '9') goto yy363;
+               if (yych <= '/') goto yy344;
+               if (yych <= '9') goto yy367;
        } else {
-               if (yych <= 'F') goto yy363;
-               if (yych <= '`') goto yy340;
-               if (yych <= 'f') goto yy363;
+               if (yych <= 'F') goto yy367;
+               if (yych <= '`') goto yy344;
+               if (yych <= 'f') goto yy367;
        }
-yy340:
-#line 597 "../src/parse/lex.re"
+yy344:
+#line 603 "../src/parse/lex.re"
        { fatal ((tok - pos) - tchar, "syntax error in hexadecimal escape sequence"); }
-#line 2254 "src/parse/lex.cc"
-yy341:
+#line 2295 "src/parse/lex.cc"
+yy345:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= '@') {
-               if (yych <= '/') goto yy340;
-               if (yych <= '9') goto yy364;
-               goto yy340;
+               if (yych <= '/') goto yy344;
+               if (yych <= '9') goto yy368;
+               goto yy344;
        } else {
-               if (yych <= 'F') goto yy364;
-               if (yych <= '`') goto yy340;
-               if (yych <= 'f') goto yy364;
-               goto yy340;
+               if (yych <= 'F') goto yy368;
+               if (yych <= '`') goto yy344;
+               if (yych <= 'f') goto yy368;
+               goto yy344;
        }
-yy342:
+yy346:
        ++YYCURSOR;
-#line 611 "../src/parse/lex.re"
+#line 617 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\\'); }
-#line 2272 "src/parse/lex.cc"
-yy344:
+#line 2313 "src/parse/lex.cc"
+yy348:
        ++YYCURSOR;
-#line 613 "../src/parse/lex.re"
+#line 619 "../src/parse/lex.re"
        { return static_cast<uint8_t>(']'); }
-#line 2277 "src/parse/lex.cc"
-yy346:
+#line 2318 "src/parse/lex.cc"
+yy350:
        ++YYCURSOR;
-#line 604 "../src/parse/lex.re"
+#line 610 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\a'); }
-#line 2282 "src/parse/lex.cc"
-yy348:
+#line 2323 "src/parse/lex.cc"
+yy352:
        ++YYCURSOR;
-#line 605 "../src/parse/lex.re"
+#line 611 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\b'); }
-#line 2287 "src/parse/lex.cc"
-yy350:
+#line 2328 "src/parse/lex.cc"
+yy354:
        ++YYCURSOR;
-#line 606 "../src/parse/lex.re"
+#line 612 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\f'); }
-#line 2292 "src/parse/lex.cc"
-yy352:
+#line 2333 "src/parse/lex.cc"
+yy356:
        ++YYCURSOR;
-#line 607 "../src/parse/lex.re"
+#line 613 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\n'); }
-#line 2297 "src/parse/lex.cc"
-yy354:
+#line 2338 "src/parse/lex.cc"
+yy358:
        ++YYCURSOR;
-#line 608 "../src/parse/lex.re"
+#line 614 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\r'); }
-#line 2302 "src/parse/lex.cc"
-yy356:
+#line 2343 "src/parse/lex.cc"
+yy360:
        ++YYCURSOR;
-#line 609 "../src/parse/lex.re"
+#line 615 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\t'); }
-#line 2307 "src/parse/lex.cc"
-yy358:
+#line 2348 "src/parse/lex.cc"
+yy362:
        ++YYCURSOR;
-#line 610 "../src/parse/lex.re"
+#line 616 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\v'); }
-#line 2312 "src/parse/lex.cc"
-yy360:
+#line 2353 "src/parse/lex.cc"
+yy364:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= '@') {
-               if (yych <= '/') goto yy340;
-               if (yych <= '9') goto yy365;
-               goto yy340;
+               if (yych <= '/') goto yy344;
+               if (yych <= '9') goto yy369;
+               goto yy344;
        } else {
-               if (yych <= 'F') goto yy365;
-               if (yych <= '`') goto yy340;
-               if (yych <= 'f') goto yy365;
-               goto yy340;
+               if (yych <= 'F') goto yy369;
+               if (yych <= '`') goto yy344;
+               if (yych <= 'f') goto yy369;
+               goto yy344;
        }
-yy361:
+yy365:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= '/') goto yy362;
-       if (yych <= '7') goto yy366;
-yy362:
+       if (yych <= '/') goto yy366;
+       if (yych <= '7') goto yy370;
+yy366:
        YYCURSOR = YYMARKER;
        if (yyaccept == 0) {
-               goto yy337;
+               goto yy341;
        } else {
-               goto yy340;
+               goto yy344;
        }
-yy363:
+yy367:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy362;
-               if (yych <= '9') goto yy368;
-               goto yy362;
+               if (yych <= '/') goto yy366;
+               if (yych <= '9') goto yy372;
+               goto yy366;
        } else {
-               if (yych <= 'F') goto yy368;
-               if (yych <= '`') goto yy362;
-               if (yych <= 'f') goto yy368;
-               goto yy362;
+               if (yych <= 'F') goto yy372;
+               if (yych <= '`') goto yy366;
+               if (yych <= 'f') goto yy372;
+               goto yy366;
        }
-yy364:
+yy368:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy362;
-               if (yych <= '9') goto yy369;
-               goto yy362;
+               if (yych <= '/') goto yy366;
+               if (yych <= '9') goto yy373;
+               goto yy366;
        } else {
-               if (yych <= 'F') goto yy369;
-               if (yych <= '`') goto yy362;
-               if (yych <= 'f') goto yy369;
-               goto yy362;
+               if (yych <= 'F') goto yy373;
+               if (yych <= '`') goto yy366;
+               if (yych <= 'f') goto yy373;
+               goto yy366;
        }
-yy365:
+yy369:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy362;
-               if (yych <= '9') goto yy370;
-               goto yy362;
+               if (yych <= '/') goto yy366;
+               if (yych <= '9') goto yy374;
+               goto yy366;
        } else {
-               if (yych <= 'F') goto yy370;
-               if (yych <= '`') goto yy362;
-               if (yych <= 'f') goto yy370;
-               goto yy362;
+               if (yych <= 'F') goto yy374;
+               if (yych <= '`') goto yy366;
+               if (yych <= 'f') goto yy374;
+               goto yy366;
        }
-yy366:
+yy370:
        ++YYCURSOR;
-#line 603 "../src/parse/lex.re"
+#line 609 "../src/parse/lex.re"
        { return unesc_oct(tok, cur); }
-#line 2377 "src/parse/lex.cc"
-yy368:
+#line 2418 "src/parse/lex.cc"
+yy372:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy362;
-               if (yych <= '9') goto yy372;
-               goto yy362;
+               if (yych <= '/') goto yy366;
+               if (yych <= '9') goto yy376;
+               goto yy366;
        } else {
-               if (yych <= 'F') goto yy372;
-               if (yych <= '`') goto yy362;
-               if (yych <= 'f') goto yy372;
-               goto yy362;
+               if (yych <= 'F') goto yy376;
+               if (yych <= '`') goto yy366;
+               if (yych <= 'f') goto yy376;
+               goto yy366;
        }
-yy369:
+yy373:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy362;
-               if (yych <= '9') goto yy365;
-               goto yy362;
+               if (yych <= '/') goto yy366;
+               if (yych <= '9') goto yy369;
+               goto yy366;
        } else {
-               if (yych <= 'F') goto yy365;
-               if (yych <= '`') goto yy362;
-               if (yych <= 'f') goto yy365;
-               goto yy362;
+               if (yych <= 'F') goto yy369;
+               if (yych <= '`') goto yy366;
+               if (yych <= 'f') goto yy369;
+               goto yy366;
        }
-yy370:
+yy374:
        ++YYCURSOR;
-#line 602 "../src/parse/lex.re"
+#line 608 "../src/parse/lex.re"
        { return unesc_hex(tok, cur); }
-#line 2406 "src/parse/lex.cc"
-yy372:
+#line 2447 "src/parse/lex.cc"
+yy376:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy362;
-               if (yych >= ':') goto yy362;
+               if (yych <= '/') goto yy366;
+               if (yych >= ':') goto yy366;
        } else {
-               if (yych <= 'F') goto yy373;
-               if (yych <= '`') goto yy362;
-               if (yych >= 'g') goto yy362;
+               if (yych <= 'F') goto yy377;
+               if (yych <= '`') goto yy366;
+               if (yych >= 'g') goto yy366;
        }
-yy373:
+yy377:
        ++YYCURSOR;
        if ((yych = (YYCTYPE)*YYCURSOR) <= '@') {
-               if (yych <= '/') goto yy362;
-               if (yych <= '9') goto yy364;
-               goto yy362;
+               if (yych <= '/') goto yy366;
+               if (yych <= '9') goto yy368;
+               goto yy366;
        } else {
-               if (yych <= 'F') goto yy364;
-               if (yych <= '`') goto yy362;
-               if (yych <= 'f') goto yy364;
-               goto yy362;
+               if (yych <= 'F') goto yy368;
+               if (yych <= '`') goto yy366;
+               if (yych <= 'f') goto yy368;
+               goto yy366;
        }
 }
-#line 618 "../src/parse/lex.re"
+#line 624 "../src/parse/lex.re"
 
 }
 
@@ -2435,282 +2476,282 @@ uint32_t Scanner::lex_str_chr(char quote, bool &end)
        end = false;
        tok = cur;
        
-#line 2439 "src/parse/lex.cc"
+#line 2480 "src/parse/lex.cc"
 {
        YYCTYPE yych;
        unsigned int yyaccept = 0;
        if ((YYLIMIT - YYCURSOR) < 10) YYFILL(10);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy378;
-       if (yych == '\\') goto yy380;
+       if (yych == '\n') goto yy382;
+       if (yych == '\\') goto yy384;
        ++YYCURSOR;
-#line 631 "../src/parse/lex.re"
+#line 637 "../src/parse/lex.re"
        {
                        end = tok[0] == quote;
                        return static_cast<uint8_t>(tok[0]);
                }
-#line 2453 "src/parse/lex.cc"
-yy378:
+#line 2494 "src/parse/lex.cc"
+yy382:
        ++YYCURSOR;
-#line 626 "../src/parse/lex.re"
+#line 632 "../src/parse/lex.re"
        { fatal ((tok - pos) - tchar, "syntax error"); }
-#line 2458 "src/parse/lex.cc"
-yy380:
+#line 2499 "src/parse/lex.cc"
+yy384:
        ++YYCURSOR;
        if ((yych = (YYCTYPE)*YYCURSOR) <= 'a') {
                if (yych <= 'T') {
                        if (yych <= '/') {
-                               if (yych != '\n') goto yy382;
+                               if (yych != '\n') goto yy386;
                        } else {
-                               if (yych <= '3') goto yy384;
-                               if (yych <= '7') goto yy386;
-                               goto yy382;
+                               if (yych <= '3') goto yy388;
+                               if (yych <= '7') goto yy390;
+                               goto yy386;
                        }
                } else {
                        if (yych <= 'X') {
-                               if (yych <= 'U') goto yy387;
-                               if (yych <= 'W') goto yy382;
-                               goto yy389;
+                               if (yych <= 'U') goto yy391;
+                               if (yych <= 'W') goto yy386;
+                               goto yy393;
                        } else {
-                               if (yych == '\\') goto yy390;
-                               if (yych <= '`') goto yy382;
-                               goto yy392;
+                               if (yych == '\\') goto yy394;
+                               if (yych <= '`') goto yy386;
+                               goto yy396;
                        }
                }
        } else {
                if (yych <= 'r') {
                        if (yych <= 'f') {
-                               if (yych <= 'b') goto yy394;
-                               if (yych <= 'e') goto yy382;
-                               goto yy396;
-                       } else {
-                               if (yych == 'n') goto yy398;
-                               if (yych <= 'q') goto yy382;
+                               if (yych <= 'b') goto yy398;
+                               if (yych <= 'e') goto yy386;
                                goto yy400;
+                       } else {
+                               if (yych == 'n') goto yy402;
+                               if (yych <= 'q') goto yy386;
+                               goto yy404;
                        }
                } else {
                        if (yych <= 'u') {
-                               if (yych <= 's') goto yy382;
-                               if (yych <= 't') goto yy402;
-                               goto yy389;
+                               if (yych <= 's') goto yy386;
+                               if (yych <= 't') goto yy406;
+                               goto yy393;
                        } else {
-                               if (yych <= 'v') goto yy404;
-                               if (yych == 'x') goto yy406;
-                               goto yy382;
+                               if (yych <= 'v') goto yy408;
+                               if (yych == 'x') goto yy410;
+                               goto yy386;
                        }
                }
        }
-#line 629 "../src/parse/lex.re"
+#line 635 "../src/parse/lex.re"
        { fatal ((tok - pos) - tchar, "syntax error in escape sequence"); }
-#line 2506 "src/parse/lex.cc"
-yy382:
+#line 2547 "src/parse/lex.cc"
+yy386:
        ++YYCURSOR;
-#line 645 "../src/parse/lex.re"
+#line 651 "../src/parse/lex.re"
        {
                        if (tok[1] != quote) {
                                warn.useless_escape(tline, tok - pos, tok[1]);
                        }
                        return static_cast<uint8_t>(tok[1]);
                }
-#line 2516 "src/parse/lex.cc"
-yy384:
+#line 2557 "src/parse/lex.cc"
+yy388:
        yyaccept = 0;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych <= '/') goto yy385;
-       if (yych <= '7') goto yy407;
-yy385:
-#line 628 "../src/parse/lex.re"
+       if (yych <= '/') goto yy389;
+       if (yych <= '7') goto yy411;
+yy389:
+#line 634 "../src/parse/lex.re"
        { fatal ((tok - pos) - tchar, "syntax error in octal escape sequence"); }
-#line 2525 "src/parse/lex.cc"
-yy386:
+#line 2566 "src/parse/lex.cc"
+yy390:
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy385;
-yy387:
+       goto yy389;
+yy391:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= '@') {
-               if (yych <= '/') goto yy388;
-               if (yych <= '9') goto yy409;
+               if (yych <= '/') goto yy392;
+               if (yych <= '9') goto yy413;
        } else {
-               if (yych <= 'F') goto yy409;
-               if (yych <= '`') goto yy388;
-               if (yych <= 'f') goto yy409;
+               if (yych <= 'F') goto yy413;
+               if (yych <= '`') goto yy392;
+               if (yych <= 'f') goto yy413;
        }
-yy388:
-#line 627 "../src/parse/lex.re"
+yy392:
+#line 633 "../src/parse/lex.re"
        { fatal ((tok - pos) - tchar, "syntax error in hexadecimal escape sequence"); }
-#line 2543 "src/parse/lex.cc"
-yy389:
+#line 2584 "src/parse/lex.cc"
+yy393:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= '@') {
-               if (yych <= '/') goto yy388;
-               if (yych <= '9') goto yy410;
-               goto yy388;
+               if (yych <= '/') goto yy392;
+               if (yych <= '9') goto yy414;
+               goto yy392;
        } else {
-               if (yych <= 'F') goto yy410;
-               if (yych <= '`') goto yy388;
-               if (yych <= 'f') goto yy410;
-               goto yy388;
+               if (yych <= 'F') goto yy414;
+               if (yych <= '`') goto yy392;
+               if (yych <= 'f') goto yy414;
+               goto yy392;
        }
-yy390:
+yy394:
        ++YYCURSOR;
-#line 644 "../src/parse/lex.re"
+#line 650 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\\'); }
-#line 2561 "src/parse/lex.cc"
-yy392:
+#line 2602 "src/parse/lex.cc"
+yy396:
        ++YYCURSOR;
-#line 637 "../src/parse/lex.re"
+#line 643 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\a'); }
-#line 2566 "src/parse/lex.cc"
-yy394:
+#line 2607 "src/parse/lex.cc"
+yy398:
        ++YYCURSOR;
-#line 638 "../src/parse/lex.re"
+#line 644 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\b'); }
-#line 2571 "src/parse/lex.cc"
-yy396:
+#line 2612 "src/parse/lex.cc"
+yy400:
        ++YYCURSOR;
-#line 639 "../src/parse/lex.re"
+#line 645 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\f'); }
-#line 2576 "src/parse/lex.cc"
-yy398:
+#line 2617 "src/parse/lex.cc"
+yy402:
        ++YYCURSOR;
-#line 640 "../src/parse/lex.re"
+#line 646 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\n'); }
-#line 2581 "src/parse/lex.cc"
-yy400:
+#line 2622 "src/parse/lex.cc"
+yy404:
        ++YYCURSOR;
-#line 641 "../src/parse/lex.re"
+#line 647 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\r'); }
-#line 2586 "src/parse/lex.cc"
-yy402:
+#line 2627 "src/parse/lex.cc"
+yy406:
        ++YYCURSOR;
-#line 642 "../src/parse/lex.re"
+#line 648 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\t'); }
-#line 2591 "src/parse/lex.cc"
-yy404:
+#line 2632 "src/parse/lex.cc"
+yy408:
        ++YYCURSOR;
-#line 643 "../src/parse/lex.re"
+#line 649 "../src/parse/lex.re"
        { return static_cast<uint8_t>('\v'); }
-#line 2596 "src/parse/lex.cc"
-yy406:
+#line 2637 "src/parse/lex.cc"
+yy410:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= '@') {
-               if (yych <= '/') goto yy388;
-               if (yych <= '9') goto yy411;
-               goto yy388;
+               if (yych <= '/') goto yy392;
+               if (yych <= '9') goto yy415;
+               goto yy392;
        } else {
-               if (yych <= 'F') goto yy411;
-               if (yych <= '`') goto yy388;
-               if (yych <= 'f') goto yy411;
-               goto yy388;
+               if (yych <= 'F') goto yy415;
+               if (yych <= '`') goto yy392;
+               if (yych <= 'f') goto yy415;
+               goto yy392;
        }
-yy407:
+yy411:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= '/') goto yy408;
-       if (yych <= '7') goto yy412;
-yy408:
+       if (yych <= '/') goto yy412;
+       if (yych <= '7') goto yy416;
+yy412:
        YYCURSOR = YYMARKER;
        if (yyaccept == 0) {
-               goto yy385;
+               goto yy389;
        } else {
-               goto yy388;
+               goto yy392;
        }
-yy409:
+yy413:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy408;
-               if (yych <= '9') goto yy414;
-               goto yy408;
+               if (yych <= '/') goto yy412;
+               if (yych <= '9') goto yy418;
+               goto yy412;
        } else {
-               if (yych <= 'F') goto yy414;
-               if (yych <= '`') goto yy408;
-               if (yych <= 'f') goto yy414;
-               goto yy408;
+               if (yych <= 'F') goto yy418;
+               if (yych <= '`') goto yy412;
+               if (yych <= 'f') goto yy418;
+               goto yy412;
        }
-yy410:
+yy414:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy408;
-               if (yych <= '9') goto yy415;
-               goto yy408;
+               if (yych <= '/') goto yy412;
+               if (yych <= '9') goto yy419;
+               goto yy412;
        } else {
-               if (yych <= 'F') goto yy415;
-               if (yych <= '`') goto yy408;
-               if (yych <= 'f') goto yy415;
-               goto yy408;
+               if (yych <= 'F') goto yy419;
+               if (yych <= '`') goto yy412;
+               if (yych <= 'f') goto yy419;
+               goto yy412;
        }
-yy411:
+yy415:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy408;
-               if (yych <= '9') goto yy416;
-               goto yy408;
+               if (yych <= '/') goto yy412;
+               if (yych <= '9') goto yy420;
+               goto yy412;
        } else {
-               if (yych <= 'F') goto yy416;
-               if (yych <= '`') goto yy408;
-               if (yych <= 'f') goto yy416;
-               goto yy408;
+               if (yych <= 'F') goto yy420;
+               if (yych <= '`') goto yy412;
+               if (yych <= 'f') goto yy420;
+               goto yy412;
        }
-yy412:
+yy416:
        ++YYCURSOR;
-#line 636 "../src/parse/lex.re"
+#line 642 "../src/parse/lex.re"
        { return unesc_oct(tok, cur); }
-#line 2661 "src/parse/lex.cc"
-yy414:
+#line 2702 "src/parse/lex.cc"
+yy418:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy408;
-               if (yych <= '9') goto yy418;
-               goto yy408;
+               if (yych <= '/') goto yy412;
+               if (yych <= '9') goto yy422;
+               goto yy412;
        } else {
-               if (yych <= 'F') goto yy418;
-               if (yych <= '`') goto yy408;
-               if (yych <= 'f') goto yy418;
-               goto yy408;
+               if (yych <= 'F') goto yy422;
+               if (yych <= '`') goto yy412;
+               if (yych <= 'f') goto yy422;
+               goto yy412;
        }
-yy415:
+yy419:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy408;
-               if (yych <= '9') goto yy411;
-               goto yy408;
+               if (yych <= '/') goto yy412;
+               if (yych <= '9') goto yy415;
+               goto yy412;
        } else {
-               if (yych <= 'F') goto yy411;
-               if (yych <= '`') goto yy408;
-               if (yych <= 'f') goto yy411;
-               goto yy408;
+               if (yych <= 'F') goto yy415;
+               if (yych <= '`') goto yy412;
+               if (yych <= 'f') goto yy415;
+               goto yy412;
        }
-yy416:
+yy420:
        ++YYCURSOR;
-#line 635 "../src/parse/lex.re"
+#line 641 "../src/parse/lex.re"
        { return unesc_hex(tok, cur); }
-#line 2690 "src/parse/lex.cc"
-yy418:
+#line 2731 "src/parse/lex.cc"
+yy422:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy408;
-               if (yych >= ':') goto yy408;
+               if (yych <= '/') goto yy412;
+               if (yych >= ':') goto yy412;
        } else {
-               if (yych <= 'F') goto yy419;
-               if (yych <= '`') goto yy408;
-               if (yych >= 'g') goto yy408;
+               if (yych <= 'F') goto yy423;
+               if (yych <= '`') goto yy412;
+               if (yych >= 'g') goto yy412;
        }
-yy419:
+yy423:
        ++YYCURSOR;
        if ((yych = (YYCTYPE)*YYCURSOR) <= '@') {
-               if (yych <= '/') goto yy408;
-               if (yych <= '9') goto yy410;
-               goto yy408;
+               if (yych <= '/') goto yy412;
+               if (yych <= '9') goto yy414;
+               goto yy412;
        } else {
-               if (yych <= 'F') goto yy410;
-               if (yych <= '`') goto yy408;
-               if (yych <= 'f') goto yy410;
-               goto yy408;
+               if (yych <= 'F') goto yy414;
+               if (yych <= '`') goto yy412;
+               if (yych <= 'f') goto yy414;
+               goto yy412;
        }
 }
-#line 651 "../src/parse/lex.re"
+#line 657 "../src/parse/lex.re"
 
 }
 
@@ -2731,7 +2772,7 @@ void Scanner::set_sourceline ()
 sourceline:
        tok = cur;
 
-#line 2735 "src/parse/lex.cc"
+#line 2776 "src/parse/lex.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -2771,23 +2812,23 @@ sourceline:
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '!') {
-               if (yych == '\n') goto yy424;
+               if (yych == '\n') goto yy428;
        } else {
-               if (yych <= '"') goto yy426;
-               if (yych <= '0') goto yy422;
-               if (yych <= '9') goto yy427;
+               if (yych <= '"') goto yy430;
+               if (yych <= '0') goto yy426;
+               if (yych <= '9') goto yy431;
        }
-yy422:
+yy426:
        ++YYCURSOR;
-yy423:
-#line 694 "../src/parse/lex.re"
+yy427:
+#line 700 "../src/parse/lex.re"
        {
                                        goto sourceline;
                                }
-#line 2788 "src/parse/lex.cc"
-yy424:
+#line 2829 "src/parse/lex.cc"
+yy428:
        ++YYCURSOR;
-#line 682 "../src/parse/lex.re"
+#line 688 "../src/parse/lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -2800,19 +2841,19 @@ yy424:
                                        tok = cur;
                                        return; 
                                }
-#line 2804 "src/parse/lex.cc"
-yy426:
+#line 2845 "src/parse/lex.cc"
+yy430:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == '\n') goto yy423;
-       goto yy431;
-yy427:
+       if (yych == '\n') goto yy427;
+       goto yy435;
+yy431:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 64) {
-               goto yy427;
+               goto yy431;
        }
-#line 671 "../src/parse/lex.re"
+#line 677 "../src/parse/lex.re"
        {
                                        if (!s_to_u32_unsafe (tok, cur, cline))
                                        {
@@ -2820,37 +2861,37 @@ yy427:
                                        }
                                        goto sourceline; 
                                }
-#line 2824 "src/parse/lex.cc"
-yy430:
+#line 2865 "src/parse/lex.cc"
+yy434:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy431:
+yy435:
        if (yybm[0+yych] & 128) {
-               goto yy430;
+               goto yy434;
        }
-       if (yych <= '\n') goto yy432;
-       if (yych <= '"') goto yy433;
-       goto yy435;
-yy432:
+       if (yych <= '\n') goto yy436;
+       if (yych <= '"') goto yy437;
+       goto yy439;
+yy436:
        YYCURSOR = YYMARKER;
-       goto yy423;
-yy433:
+       goto yy427;
+yy437:
        ++YYCURSOR;
-#line 678 "../src/parse/lex.re"
+#line 684 "../src/parse/lex.re"
        {
                                        escape (in.file_name, std::string (tok + 1, tok_len () - 2)); // -2 to omit quotes
                                        goto sourceline; 
                                }
-#line 2846 "src/parse/lex.cc"
-yy435:
+#line 2887 "src/parse/lex.cc"
+yy439:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy432;
-       goto yy430;
+       if (yych == '\n') goto yy436;
+       goto yy434;
 }
-#line 697 "../src/parse/lex.re"
+#line 703 "../src/parse/lex.re"
 
 }
 
index eb0aec7fa18c9d02a1ba8ab792cbdcb062519ded..7b8d484bf45fe75b99dbc500233da144f857129e 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.16 on Thu Jan 21 10:47:47 2016 */
+/* Generated by re2c 0.16 on Wed Mar 23 16:01:26 2016 */
 #line 1 "../src/parse/lex_conf.re"
 #include "src/util/c99_stdint.h"
 #include <string>
index 0a0ae13e5ab78785a8988d39bd5d1a00cbeedb55..de5f3ebc5a1da2f4700f64188c5869112258bd9e 100644 (file)
@@ -117,13 +117,14 @@ static std::vector<std::string> condnames;
 static re2c::SpecMap  specMap;
 static Spec spec;
 static const RegExp *specNone = NULL;
-static RuleList       specStar;
+static SpecStar specStar;
 static const RegExp *star_default = NULL;
 static Scanner          *in = NULL;
 static Scanner::ParseMode  parseMode;
 static SetupMap            ruleSetupMap;
 static bool                foundRules;
 static symbol_table_t symbol_table;
+static zzz_t ctxs;
 
 /* Bison version 1.875 emits a definition that is not working
  * with several g++ version. Hence we disable it here.
@@ -151,8 +152,7 @@ void context_none(CondList *clist)
 void context_rule
        ( CondList * clist
        , const Loc & loc
-       , const RegExp * expr
-       , const RegExp * look
+       , std::pair<std::vector<const RegExp*>, std::vector<std::string*> > * expr
        , const Code * code
        , const std::string * newcond
        )
@@ -166,9 +166,9 @@ void context_rule
                }
 
                const RegExp *rule = make_rule
-                       ( loc
+                       ( specMap[*it].contexts
+                       , loc
                        , expr
-                       , look
                        , rank_counter.next ()
                        , code
                        , newcond
@@ -202,10 +202,9 @@ void default_rule(CondList *clist, const Code * code)
        context_check(clist);
        for(CondList::const_iterator it = clist->begin(); it != clist->end(); ++it)
        {
-               const RegExp * def = make_rule
+               const RegExp * def = make_rule_ctxfree
                        ( code->loc
                        , in->mkDefault ()
-                       , RegExp::nil()
                        , rule_rank_t::def ()
                        , code
                        , NULL
@@ -250,13 +249,14 @@ void default_rule(CondList *clist, const Code * code)
      TOKEN_CLOSESIZE = 259,
      TOKEN_CODE = 260,
      TOKEN_CONF = 261,
-     TOKEN_ID = 262,
-     TOKEN_FID = 263,
-     TOKEN_FID_END = 264,
-     TOKEN_NOCOND = 265,
-     TOKEN_REGEXP = 266,
-     TOKEN_SETUP = 267,
-     TOKEN_STAR = 268
+     TOKEN_CTX = 262,
+     TOKEN_ID = 263,
+     TOKEN_FID = 264,
+     TOKEN_FID_END = 265,
+     TOKEN_NOCOND = 266,
+     TOKEN_REGEXP = 267,
+     TOKEN_SETUP = 268,
+     TOKEN_STAR = 269
    };
 #endif
 
@@ -273,6 +273,7 @@ typedef union YYSTYPE
        re2c::ExtOp extop;
        std::string * str;
        re2c::CondList * clist;
+       re2c::zzz_t *ctxs;
 
 
 
@@ -500,20 +501,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   104
+#define YYLAST   99
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  25
+#define YYNTOKENS  26
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  14
+#define YYNNTS  16
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  49
+#define YYNRULES  53
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  92
+#define YYNSTATES  95
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   268
+#define YYMAXUTOK   269
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -525,15 +526,15 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      23,    24,     2,     2,    20,     2,     2,    16,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    19,    15,
-      17,    14,    18,     2,     2,     2,     2,     2,     2,     2,
+      24,    25,     2,     2,    21,     2,     2,    17,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    20,    16,
+      18,    15,    19,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,    22,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,    23,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,    21,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,    22,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -547,7 +548,7 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    13
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14
 };
 
 #if YYDEBUG
@@ -556,44 +557,47 @@ static const yytype_uint8 yytranslate[] =
 static const yytype_uint8 yyprhs[] =
 {
        0,     0,     3,     4,     7,    10,    15,    19,    24,    28,
-      30,    34,    37,    45,    53,    60,    67,    73,    81,    89,
-      96,   103,   109,   113,   117,   122,   127,   128,   130,   132,
-     136,   137,   141,   142,   145,   147,   151,   153,   157,   159,
-     162,   164,   167,   170,   172,   174,   177,   180,   182,   184
+      30,    33,    36,    43,    50,    57,    64,    70,    77,    84,
+      91,    98,   104,   108,   112,   117,   122,   123,   125,   127,
+     131,   132,   136,   138,   142,   144,   148,   149,   152,   154,
+     158,   160,   164,   166,   169,   171,   174,   177,   179,   181,
+     184,   187,   189,   191
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
-      26,     0,    -1,    -1,    26,    28,    -1,    26,    27,    -1,
-       7,    14,    33,    15,    -1,     8,    33,     9,    -1,     7,
-      14,    33,    16,    -1,     8,    33,    16,    -1,     6,    -1,
-      33,    32,     5,    -1,    13,     5,    -1,    17,    29,    18,
-      33,    32,    31,     5,    -1,    17,    29,    18,    33,    32,
-      19,    31,    -1,    17,    29,    18,    32,    31,     5,    -1,
-      17,    29,    18,    32,    19,    31,    -1,    17,    29,    18,
-      13,     5,    -1,    17,    13,    18,    33,    32,    31,     5,
-      -1,    17,    13,    18,    33,    32,    19,    31,    -1,    17,
-      13,    18,    32,    31,     5,    -1,    17,    13,    18,    32,
-      19,    31,    -1,    17,    13,    18,    13,     5,    -1,    10,
-      31,     5,    -1,    10,    19,    31,    -1,    12,    13,    18,
-       5,    -1,    12,    29,    18,     5,    -1,    -1,    30,    -1,
-       7,    -1,    30,    20,     7,    -1,    -1,    14,    18,     7,
-      -1,    -1,    16,    33,    -1,    34,    -1,    33,    21,    34,
-      -1,    35,    -1,    34,    22,    35,    -1,    36,    -1,    35,
-      36,    -1,    38,    -1,    38,    37,    -1,    38,     4,    -1,
-       3,    -1,    13,    -1,    37,     3,    -1,    37,    13,    -1,
-       7,    -1,    11,    -1,    23,    33,    24,    -1
+      27,     0,    -1,    -1,    27,    29,    -1,    27,    28,    -1,
+       8,    15,    36,    16,    -1,     9,    36,    10,    -1,     8,
+      15,    36,    17,    -1,     9,    36,    17,    -1,     6,    -1,
+      33,     5,    -1,    14,     5,    -1,    18,    30,    19,    33,
+      32,     5,    -1,    18,    30,    19,    33,    20,    32,    -1,
+      18,    30,    19,    35,    32,     5,    -1,    18,    30,    19,
+      35,    20,    32,    -1,    18,    30,    19,    14,     5,    -1,
+      18,    14,    19,    33,    32,     5,    -1,    18,    14,    19,
+      33,    20,    32,    -1,    18,    14,    19,    35,    32,     5,
+      -1,    18,    14,    19,    35,    20,    32,    -1,    18,    14,
+      19,    14,     5,    -1,    11,    32,     5,    -1,    11,    20,
+      32,    -1,    13,    14,    19,     5,    -1,    13,    30,    19,
+       5,    -1,    -1,    31,    -1,     8,    -1,    31,    21,     8,
+      -1,    -1,    15,    19,     8,    -1,    34,    -1,    34,    17,
+      36,    -1,    36,    -1,    34,     7,    36,    -1,    -1,    17,
+      36,    -1,    37,    -1,    36,    22,    37,    -1,    38,    -1,
+      37,    23,    38,    -1,    39,    -1,    38,    39,    -1,    41,
+      -1,    41,    40,    -1,    41,     4,    -1,     3,    -1,    14,
+      -1,    40,     3,    -1,    40,    14,    -1,     8,    -1,    12,
+      -1,    24,    36,    25,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   189,   189,   191,   195,   199,   207,   215,   219,   223,
-     227,   243,   260,   264,   270,   275,   281,   285,   299,   315,
-     320,   326,   341,   358,   377,   383,   391,   394,   401,   407,
-     417,   420,   428,   431,   438,   442,   449,   453,   460,   464,
-     471,   475,   490,   509,   513,   517,   521,   528,   538,   542
+       0,   191,   191,   193,   197,   201,   209,   217,   221,   225,
+     229,   245,   261,   265,   271,   276,   282,   286,   300,   316,
+     321,   327,   341,   357,   375,   381,   389,   392,   399,   405,
+     415,   418,   425,   427,   435,   440,   453,   456,   463,   467,
+     474,   478,   485,   489,   496,   500,   515,   534,   538,   542,
+     546,   553,   563,   567
 };
 #endif
 
@@ -603,11 +607,12 @@ static const yytype_uint16 yyrline[] =
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "TOKEN_CLOSE", "TOKEN_CLOSESIZE",
-  "TOKEN_CODE", "TOKEN_CONF", "TOKEN_ID", "TOKEN_FID", "TOKEN_FID_END",
-  "TOKEN_NOCOND", "TOKEN_REGEXP", "TOKEN_SETUP", "TOKEN_STAR", "'='",
-  "';'", "'/'", "'<'", "'>'", "':'", "','", "'|'", "'\\\\'", "'('", "')'",
-  "$accept", "spec", "decl", "rule", "cond", "clist", "newcond", "look",
-  "expr", "diff", "term", "factor", "close", "primary", 0
+  "TOKEN_CODE", "TOKEN_CONF", "TOKEN_CTX", "TOKEN_ID", "TOKEN_FID",
+  "TOKEN_FID_END", "TOKEN_NOCOND", "TOKEN_REGEXP", "TOKEN_SETUP",
+  "TOKEN_STAR", "'='", "';'", "'/'", "'<'", "'>'", "':'", "','", "'|'",
+  "'\\\\'", "'('", "')'", "$accept", "spec", "decl", "rule", "cond",
+  "clist", "newcond", "trailexpr", "ctxexpr", "look", "expr", "diff",
+  "term", "factor", "close", "primary", 0
 };
 #endif
 
@@ -617,29 +622,31 @@ static const char *const yytname[] =
 static const yytype_uint16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
-     265,   266,   267,   268,    61,    59,    47,    60,    62,    58,
-      44,   124,    92,    40,    41
+     265,   266,   267,   268,   269,    61,    59,    47,    60,    62,
+      58,    44,   124,    92,    40,    41
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    25,    26,    26,    26,    27,    27,    27,    27,    27,
-      28,    28,    28,    28,    28,    28,    28,    28,    28,    28,
-      28,    28,    28,    28,    28,    28,    29,    29,    30,    30,
-      31,    31,    32,    32,    33,    33,    34,    34,    35,    35,
-      36,    36,    36,    37,    37,    37,    37,    38,    38,    38
+       0,    26,    27,    27,    27,    28,    28,    28,    28,    28,
+      29,    29,    29,    29,    29,    29,    29,    29,    29,    29,
+      29,    29,    29,    29,    29,    29,    30,    30,    31,    31,
+      32,    32,    33,    33,    34,    34,    35,    35,    36,    36,
+      37,    37,    38,    38,    39,    39,    39,    40,    40,    40,
+      40,    41,    41,    41
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
        0,     2,     0,     2,     2,     4,     3,     4,     3,     1,
-       3,     2,     7,     7,     6,     6,     5,     7,     7,     6,
+       2,     2,     6,     6,     6,     6,     5,     6,     6,     6,
        6,     5,     3,     3,     4,     4,     0,     1,     1,     3,
-       0,     3,     0,     2,     1,     3,     1,     3,     1,     2,
-       1,     2,     2,     1,     1,     2,     2,     1,     1,     3
+       0,     3,     1,     3,     1,     3,     0,     2,     1,     3,
+       1,     3,     1,     2,     1,     2,     2,     1,     1,     2,
+       2,     1,     1,     3
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -647,47 +654,47 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       2,     0,     1,     9,    47,     0,    30,    48,    26,     0,
-      26,     0,     4,     3,    32,    34,    36,    38,    40,     0,
-      47,     0,     0,    30,     0,    28,     0,     0,    27,    11,
-       0,     0,     0,     0,     0,     0,     0,    39,    43,    42,
-      44,    41,     0,     6,     8,     0,    23,    22,     0,     0,
-       0,    32,    32,    49,    33,    35,    10,    37,    45,    46,
-       5,     7,    31,    24,    25,    29,     0,    30,    32,     0,
-      30,    32,    21,    30,     0,    30,    16,    30,     0,    30,
-      20,    19,    30,     0,    15,    14,    30,     0,    18,    17,
-      13,    12
+       2,     0,     1,     9,    51,     0,    30,    52,    26,     0,
+      26,     0,     4,     3,     0,    32,    34,    38,    40,    42,
+      44,     0,    51,     0,     0,    30,     0,    28,     0,     0,
+      27,    11,     0,     0,     0,    10,     0,     0,     0,     0,
+      43,    47,    46,    48,    45,     0,     6,     8,     0,    23,
+      22,     0,     0,     0,    36,    36,    53,    35,    33,    39,
+      41,    49,    50,     5,     7,    31,    24,    25,    29,     0,
+       0,    30,    30,     0,    30,    30,    21,    37,    30,     0,
+      30,     0,    16,    30,     0,    30,     0,    18,    17,    20,
+      19,    13,    12,    15,    14
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int8 yydefgoto[] =
 {
-      -1,     1,    12,    13,    27,    28,    24,    35,    14,    15,
-      16,    17,    41,    18
+      -1,     1,    12,    13,    29,    30,    26,    14,    15,    72,
+      16,    17,    18,    19,    44,    20
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -43
+#define YYPACT_NINF -25
 static const yytype_int8 yypact[] =
 {
-     -43,    11,   -43,   -43,   -11,    30,    47,   -43,    25,    10,
-      33,    30,   -43,   -43,    48,    17,    30,   -43,     1,    30,
-     -43,     4,    40,    60,    70,   -43,    61,    63,    42,   -43,
-      64,    66,    59,    30,    30,    73,    30,   -43,   -43,   -43,
-     -43,    32,    -9,   -43,   -43,    78,   -43,   -43,    81,    82,
-      83,    20,    44,   -43,    67,    17,   -43,    30,   -43,   -43,
-     -43,   -43,   -43,   -43,   -43,   -43,    84,    51,    48,    86,
-      54,    48,   -43,    60,    87,    57,   -43,    60,    88,    58,
-     -43,   -43,    60,    89,   -43,   -43,    60,    90,   -43,   -43,
-     -43,   -43
+     -25,     9,   -25,   -25,    42,     0,    25,   -25,    21,     6,
+      35,     0,   -25,   -25,    33,    -4,    31,    46,     0,   -25,
+      38,     0,   -25,    -3,    57,    62,    73,   -25,    60,    61,
+      63,   -25,    64,    66,     3,   -25,     0,     0,     0,     0,
+     -25,   -25,   -25,   -25,    23,   -12,   -25,   -25,    74,   -25,
+     -25,    76,    81,    79,    22,    50,   -25,    31,    31,    46,
+       0,   -25,   -25,   -25,   -25,   -25,   -25,   -25,   -25,    83,
+       0,    40,    48,    84,    51,    55,   -25,    31,    62,    85,
+      62,    86,   -25,    62,    87,    62,    88,   -25,   -25,   -25,
+     -25,   -25,   -25,   -25,   -25
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
-     -43,   -43,   -43,   -43,    91,   -43,   -23,   -42,    -3,    62,
-      68,   -15,   -43,   -43
+     -25,   -25,   -25,   -25,    89,   -25,   -24,    18,   -25,    39,
+      -5,    58,    56,   -16,   -25,   -25
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
@@ -697,48 +704,46 @@ static const yytype_int8 yypgoto[] =
 #define YYTABLE_NINF -1
 static const yytype_uint8 yytable[] =
 {
-      46,    37,    21,    19,    38,    39,    60,    61,    32,    67,
-      70,     2,    34,    43,    40,    29,    42,     3,     4,     5,
-      44,     6,     7,     8,     9,    34,    75,    20,    10,    79,
-      54,     7,    25,    66,    11,    58,    33,    20,    26,    36,
-      25,     7,    37,    11,    74,    59,    30,    78,    68,    71,
-      80,    20,    83,    11,    84,     7,    87,    69,    45,    88,
-      33,    22,    50,    90,    33,    22,    23,    11,    22,    34,
-      73,    22,    22,    77,    22,    47,    82,    86,    56,    48,
-      34,    49,    51,    53,    52,    62,    63,    64,    34,    72,
-      65,    76,    81,    85,    89,    91,    55,     0,     0,     0,
-       0,    31,     0,     0,    57
+      23,    49,    40,    36,    63,    64,    34,    46,    22,     2,
+      38,    31,     7,    37,    47,     3,    45,     4,     5,    38,
+       6,     7,     8,     9,    11,    38,    61,    10,    56,    27,
+      22,    57,    58,    11,     7,    28,    69,    62,    35,    70,
+      24,    41,    42,    27,    40,    25,    11,    79,    81,    32,
+      84,    86,    43,    38,    87,    24,    89,    21,    22,    91,
+      78,    93,     7,    24,    73,    77,    24,    70,    80,    39,
+      24,    83,    71,    74,    11,    85,    48,    24,    50,    51,
+      52,    66,    65,    54,    53,    55,    67,    68,    76,    82,
+      88,    90,    92,    94,    75,    60,    59,     0,     0,    33
 };
 
 static const yytype_int8 yycheck[] =
 {
-      23,    16,     5,    14,     3,     4,    15,    16,    11,    51,
-      52,     0,    21,     9,    13,     5,    19,     6,     7,     8,
-      16,    10,    11,    12,    13,    21,    68,     7,    17,    71,
-      33,    11,     7,    13,    23,     3,    16,     7,    13,    22,
-       7,    11,    57,    23,    67,    13,    13,    70,    51,    52,
-      73,     7,    75,    23,    77,    11,    79,    13,    18,    82,
-      16,    14,    20,    86,    16,    14,    19,    23,    14,    21,
-      19,    14,    14,    19,    14,     5,    19,    19,     5,    18,
-      21,    18,    18,    24,    18,     7,     5,     5,    21,     5,
-       7,     5,     5,     5,     5,     5,    34,    -1,    -1,    -1,
-      -1,    10,    -1,    -1,    36
+       5,    25,    18,     7,    16,    17,    11,    10,     8,     0,
+      22,     5,    12,    17,    17,     6,    21,     8,     9,    22,
+      11,    12,    13,    14,    24,    22,     3,    18,    25,     8,
+       8,    36,    37,    24,    12,    14,    14,    14,     5,    17,
+      15,     3,     4,     8,    60,    20,    24,    71,    72,    14,
+      74,    75,    14,    22,    78,    15,    80,    15,     8,    83,
+      20,    85,    12,    15,    14,    70,    15,    17,    20,    23,
+      15,    20,    54,    55,    24,    20,    19,    15,     5,    19,
+      19,     5,     8,    19,    21,    19,     5,     8,     5,     5,
+       5,     5,     5,     5,    55,    39,    38,    -1,    -1,    10
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,    26,     0,     6,     7,     8,    10,    11,    12,    13,
-      17,    23,    27,    28,    33,    34,    35,    36,    38,    14,
-       7,    33,    14,    19,    31,     7,    13,    29,    30,     5,
-      13,    29,    33,    16,    21,    32,    22,    36,     3,     4,
-      13,    37,    33,     9,    16,    18,    31,     5,    18,    18,
-      20,    18,    18,    24,    33,    34,     5,    35,     3,    13,
-      15,    16,     7,     5,     5,     7,    13,    32,    33,    13,
-      32,    33,     5,    19,    31,    32,     5,    19,    31,    32,
-      31,     5,    19,    31,    31,     5,    19,    31,    31,     5,
-      31,     5
+       0,    27,     0,     6,     8,     9,    11,    12,    13,    14,
+      18,    24,    28,    29,    33,    34,    36,    37,    38,    39,
+      41,    15,     8,    36,    15,    20,    32,     8,    14,    30,
+      31,     5,    14,    30,    36,     5,     7,    17,    22,    23,
+      39,     3,     4,    14,    40,    36,    10,    17,    19,    32,
+       5,    19,    19,    21,    19,    19,    25,    36,    36,    37,
+      38,     3,    14,    16,    17,     8,     5,     5,     8,    14,
+      17,    33,    35,    14,    33,    35,     5,    36,    20,    32,
+      20,    32,     5,    20,    32,    20,    32,    32,     5,    32,
+       5,    32,     5,    32,     5
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1620,11 +1625,11 @@ yyreduce:
                                in->fatal("condition or '<*>' required when using -c switch");
                        }
                        const RegExp * rule = make_rule
-                               ( (yyvsp[(3) - (3)].code)->loc
-                               , (yyvsp[(1) - (3)].regexp)
-                               , (yyvsp[(2) - (3)].regexp)
+                               ( spec.contexts
+                               , (yyvsp[(2) - (2)].code)->loc
+                               , (yyvsp[(1) - (2)].ctxs)
                                , rank_counter.next ()
-                               , (yyvsp[(3) - (3)].code)
+                               , (yyvsp[(2) - (2)].code)
                                , NULL
                                );
                        spec.add (rule);
@@ -1636,10 +1641,9 @@ yyreduce:
     {
                        if (opts->cFlag)
                                in->fatal("condition or '<*>' required when using -c switch");
-                       const RegExp * def = make_rule
+                       const RegExp * def = make_rule_ctxfree
                                ( (yyvsp[(2) - (2)].code)->loc
                                , in->mkDefault ()
-                               , RegExp::nil()
                                , rule_rank_t::def ()
                                , (yyvsp[(2) - (2)].code)
                                , NULL
@@ -1654,16 +1658,16 @@ yyreduce:
   case 12:
 
     {
-                       context_rule ((yyvsp[(2) - (7)].clist), (yyvsp[(7) - (7)].code)->loc, (yyvsp[(4) - (7)].regexp), (yyvsp[(5) - (7)].regexp), (yyvsp[(7) - (7)].code), (yyvsp[(6) - (7)].str));
+                       context_rule ((yyvsp[(2) - (6)].clist), (yyvsp[(6) - (6)].code)->loc, (yyvsp[(4) - (6)].ctxs), (yyvsp[(6) - (6)].code), (yyvsp[(5) - (6)].str));
                ;}
     break;
 
   case 13:
 
     {
-                       assert((yyvsp[(7) - (7)].str));
+                       assert((yyvsp[(6) - (6)].str));
                        Loc loc (in->get_fname (), in->get_cline ());
-                       context_rule ((yyvsp[(2) - (7)].clist), loc, (yyvsp[(4) - (7)].regexp), (yyvsp[(5) - (7)].regexp), NULL, (yyvsp[(7) - (7)].str));
+                       context_rule ((yyvsp[(2) - (6)].clist), loc, (yyvsp[(4) - (6)].ctxs), NULL, (yyvsp[(6) - (6)].str));
                ;}
     break;
 
@@ -1696,34 +1700,34 @@ yyreduce:
     {
                        context_check(NULL);
                        const RegExp * rule = make_rule
-                               ( (yyvsp[(7) - (7)].code)->loc
-                               , (yyvsp[(4) - (7)].regexp)
-                               , (yyvsp[(5) - (7)].regexp)
+                               ( specStar.contexts
+                               , (yyvsp[(6) - (6)].code)->loc
+                               , (yyvsp[(4) - (6)].ctxs)
                                , rank_counter.next ()
-                               , (yyvsp[(7) - (7)].code)
-                               , (yyvsp[(6) - (7)].str)
+                               , (yyvsp[(6) - (6)].code)
+                               , (yyvsp[(5) - (6)].str)
                                );
-                       specStar.push_back (rule);
-                       delete (yyvsp[(6) - (7)].str);
+                       specStar.rules.push_back (rule);
+                       delete (yyvsp[(5) - (6)].str);
                ;}
     break;
 
   case 18:
 
     {
-                       assert((yyvsp[(7) - (7)].str));
+                       assert((yyvsp[(6) - (6)].str));
                        context_check(NULL);
                        Loc loc (in->get_fname (), in->get_cline ());
                        const RegExp * rule = make_rule
-                               ( loc
-                               , (yyvsp[(4) - (7)].regexp)
-                               , (yyvsp[(5) - (7)].regexp)
+                               ( specStar.contexts
+                               , loc
+                               , (yyvsp[(4) - (6)].ctxs)
                                , rank_counter.next ()
                                , NULL
-                               , (yyvsp[(7) - (7)].str)
+                               , (yyvsp[(6) - (6)].str)
                                );
-                       specStar.push_back (rule);
-                       delete (yyvsp[(7) - (7)].str);
+                       specStar.rules.push_back (rule);
+                       delete (yyvsp[(6) - (6)].str);
                ;}
     break;
 
@@ -1751,10 +1755,9 @@ yyreduce:
                        {
                                in->fatal ("code to default rule '*' is already defined");
                        }
-                       star_default = make_rule
+                       star_default = make_rule_ctxfree
                                ( (yyvsp[(5) - (5)].code)->loc
                                , in->mkDefault ()
-                               , RegExp::nil()
                                , rule_rank_t::def ()
                                , (yyvsp[(5) - (5)].code)
                                , NULL
@@ -1770,10 +1773,9 @@ yyreduce:
                        {
                                in->fatal("code to handle illegal condition already defined");
                        }
-                       (yyval.regexp) = specNone = make_rule
+                       (yyval.regexp) = specNone = make_rule_ctxfree
                                ( (yyvsp[(3) - (3)].code)->loc
                                , RegExp::nil()
-                               , RegExp::nil()
                                , rank_counter.next ()
                                , (yyvsp[(3) - (3)].code)
                                , (yyvsp[(2) - (3)].str)
@@ -1792,10 +1794,9 @@ yyreduce:
                                in->fatal("code to handle illegal condition already defined");
                        }
                        Loc loc (in->get_fname (), in->get_cline ());
-                       (yyval.regexp) = specNone = make_rule
+                       (yyval.regexp) = specNone = make_rule_ctxfree
                                ( loc
                                , RegExp::nil()
-                               , RegExp::nil()
                                , rank_counter.next ()
                                , NULL
                                , (yyvsp[(3) - (3)].str)
@@ -1868,68 +1869,109 @@ yyreduce:
 
   case 32:
 
+    {
+               (yyval.ctxs) = (yyvsp[(1) - (1)].ctxs);
+       ;}
+    break;
+
+  case 33:
+
+    {
+               // multiple trailing contexts on the same rule are not allowed
+               (yyval.ctxs) = (yyvsp[(1) - (3)].ctxs);
+               (yyval.ctxs)->first.push_back((yyvsp[(3) - (3)].regexp));
+               (yyval.ctxs)->second.push_back(NULL);
+       ;}
+    break;
+
+  case 34:
+
+    {
+               ctxs.first.clear();
+               ctxs.second.clear();
+               (yyval.ctxs) = &ctxs;
+               (yyval.ctxs)->first.push_back((yyvsp[(1) - (1)].regexp));
+       ;}
+    break;
+
+  case 35:
+
+    {
+               if (!opts->contexts) {
+                       delete (yyvsp[(2) - (3)].str);
+                       in->fatal("non-trailing contexts are only allowed"
+                               " with '-C, --contexts' option");
+               }
+               (yyval.ctxs) = (yyvsp[(1) - (3)].ctxs);
+               (yyval.ctxs)->first.push_back((yyvsp[(3) - (3)].regexp));
+               (yyval.ctxs)->second.push_back((yyvsp[(2) - (3)].str));
+       ;}
+    break;
+
+  case 36:
+
     {
                        (yyval.regexp) = RegExp::nil();
                ;}
     break;
 
-  case 33:
+  case 37:
 
     {
                        (yyval.regexp) = (yyvsp[(2) - (2)].regexp);
                ;}
     break;
 
-  case 34:
+  case 38:
 
     {
                        (yyval.regexp) = (yyvsp[(1) - (1)].regexp);
                ;}
     break;
 
-  case 35:
+  case 39:
 
     {
                        (yyval.regexp) = mkAlt((yyvsp[(1) - (3)].regexp), (yyvsp[(3) - (3)].regexp));
                ;}
     break;
 
-  case 36:
+  case 40:
 
     {
                        (yyval.regexp) = (yyvsp[(1) - (1)].regexp);
                ;}
     break;
 
-  case 37:
+  case 41:
 
     {
                        (yyval.regexp) = in->mkDiff((yyvsp[(1) - (3)].regexp), (yyvsp[(3) - (3)].regexp));
                ;}
     break;
 
-  case 38:
+  case 42:
 
     {
                        (yyval.regexp) = (yyvsp[(1) - (1)].regexp);
                ;}
     break;
 
-  case 39:
+  case 43:
 
     {
                        (yyval.regexp) = RegExp::cat((yyvsp[(1) - (2)].regexp), (yyvsp[(2) - (2)].regexp));
                ;}
     break;
 
-  case 40:
+  case 44:
 
     {
                        (yyval.regexp) = (yyvsp[(1) - (1)].regexp);
                ;}
     break;
 
-  case 41:
+  case 45:
 
     {
                        switch((yyvsp[(2) - (2)].op))
@@ -1947,7 +1989,7 @@ yyreduce:
                ;}
     break;
 
-  case 42:
+  case 46:
 
     {
                        if ((yyvsp[(2) - (2)].extop).max == std::numeric_limits<uint32_t>::max())
@@ -1966,35 +2008,35 @@ yyreduce:
                ;}
     break;
 
-  case 43:
+  case 47:
 
     {
                        (yyval.op) = (yyvsp[(1) - (1)].op);
                ;}
     break;
 
-  case 44:
+  case 48:
 
     {
                        (yyval.op) = (yyvsp[(1) - (1)].op);
                ;}
     break;
 
-  case 45:
+  case 49:
 
     {
                        (yyval.op) = ((yyvsp[(1) - (2)].op) == (yyvsp[(2) - (2)].op)) ? (yyvsp[(1) - (2)].op) : '*';
                ;}
     break;
 
-  case 46:
+  case 50:
 
     {
                        (yyval.op) = ((yyvsp[(1) - (2)].op) == (yyvsp[(2) - (2)].op)) ? (yyvsp[(1) - (2)].op) : '*';
                ;}
     break;
 
-  case 47:
+  case 51:
 
     {
                        symbol_table_t::iterator i = symbol_table.find (* (yyvsp[(1) - (1)].str));
@@ -2007,14 +2049,14 @@ yyreduce:
                ;}
     break;
 
-  case 48:
+  case 52:
 
     {
                        (yyval.regexp) = (yyvsp[(1) - (1)].regexp);
                ;}
     break;
 
-  case 49:
+  case 53:
 
     {
                        (yyval.regexp) = (yyvsp[(2) - (3)].regexp);
@@ -2260,7 +2302,7 @@ void parse(Scanner& i, Output & o)
                .wline_info (in->get_cline (), in->get_fname ().c_str ());
        if (opts->target == opt_t::SKELETON)
        {
-               emit_prolog(o.source);
+               emit_prolog (o.source);
        }
 
        Enc encodingOld = opts->encoding;
@@ -2335,9 +2377,13 @@ void parse(Scanner& i, Output & o)
                                // merge <*> rules to all conditions with lowest priority
                                for (it = specMap.begin(); it != specMap.end(); ++it)
                                {
-                                       for (RuleList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp)
-                                       {
-                                               it->second.add(make_rule_copy(*itOp, rank_counter.next()));
+                                       const size_t shift = it->second.contexts.size();
+                                       it->second.contexts.insert(it->second.contexts.end(), specStar.contexts.begin(), specStar.contexts.end());
+                                       std::vector<const RegExp*>::const_iterator
+                                               star = specStar.rules.begin(),
+                                               star_end = specStar.rules.end();
+                                       for (; star != star_end; ++star) {
+                                               it->second.add(make_rule_copy(*star, rank_counter.next(), shift));
                                        }
                                        if (star_default)
                                        {
@@ -2429,7 +2475,7 @@ void parse(Scanner& i, Output & o)
 
        if (opts->target == opt_t::SKELETON)
        {
-               emit_epilog(o.source, o.skeletons);
+               emit_epilog (o.source, o.skeletons);
        }
 
        parse_cleanup();
index 061f7587adfe5ce71068728ad08db1c098d8e080..16136bdd7e03339c5941651caa8935b121ea1968 100644 (file)
      TOKEN_CLOSESIZE = 259,
      TOKEN_CODE = 260,
      TOKEN_CONF = 261,
-     TOKEN_ID = 262,
-     TOKEN_FID = 263,
-     TOKEN_FID_END = 264,
-     TOKEN_NOCOND = 265,
-     TOKEN_REGEXP = 266,
-     TOKEN_SETUP = 267,
-     TOKEN_STAR = 268
+     TOKEN_CTX = 262,
+     TOKEN_ID = 263,
+     TOKEN_FID = 264,
+     TOKEN_FID_END = 265,
+     TOKEN_NOCOND = 266,
+     TOKEN_REGEXP = 267,
+     TOKEN_SETUP = 268,
+     TOKEN_STAR = 269
    };
 #endif
 
@@ -65,6 +66,7 @@ typedef union YYSTYPE
        re2c::ExtOp extop;
        std::string * str;
        re2c::CondList * clist;
+       re2c::zzz_t *ctxs;
 
 
 
index 5d91b14e98996d34ccb2a5a2974090d26dcc60d4..c038f7d07f965279e3240d0252609395456dec90 100644 (file)
@@ -18,6 +18,7 @@ void emit_action
        , const Skeleton * skeleton
        , const std::set<label_t> & used_labels
        , bool save_yyaccept
+       , bool base_ctxmarker
        );
 
 // helpers
index e41bbbafe6ce95ca865d1cac7c392e9218d62581..5703a4fb5b94b981ad41ae7a830e4aae67c559da 100644 (file)
@@ -26,7 +26,9 @@ static void emit_initial       (OutputFile & o, uint32_t ind, bool & readCh, con
 static void emit_save          (OutputFile & o, uint32_t ind, bool & readCh, const State * const s, uint32_t save, bool save_yyaccept);
 static void emit_accept_binary (OutputFile & o, uint32_t ind, bool & readCh, const State * const s, const accept_t & accept, size_t l, size_t r);
 static void emit_accept        (OutputFile & o, uint32_t ind, bool & readCh, const State * const s, const accept_t & accept);
-static void emit_rule          (OutputFile & o, uint32_t ind, const State * const s, const RuleInfo * const rule, const std::string & condName, const Skeleton * skeleton);
+static void emit_rule(OutputFile &o, uint32_t ind, const State *const s,
+       const RuleInfo *const rule, const std::string &condName,
+       const Skeleton *skeleton, bool base_ctxmarker);
 static void genYYFill          (OutputFile & o, size_t need);
 static void genSetCondition    (OutputFile & o, uint32_t ind, const std::string & newcond);
 static void genSetState        (OutputFile & o, uint32_t ind, uint32_t fillIndex);
@@ -41,6 +43,7 @@ void emit_action
        , const Skeleton * skeleton
        , const std::set<label_t> & used_labels
        , bool save_yyaccept
+       , bool base_ctxmarker
        )
 {
        switch (action.type)
@@ -60,12 +63,15 @@ void emit_action
                        emit_accept (o, ind, readCh, s, * action.info.accepts);
                        break;
                case Action::RULE:
-                       emit_rule (o, ind, s, action.info.rule, condName, skeleton);
+                       emit_rule (o, ind, s, action.info.rule, condName, skeleton, base_ctxmarker);
                        break;
        }
-       if (s->isPreCtxt && opts->target != opt_t::DOT)
-       {
-               o.wstring(opts->input_api.stmt_backupctx (ind));
+       if (opts->target != opt_t::DOT && !s->ctxs.empty()) {
+               if (base_ctxmarker) {
+                       o.wstring(opts->input_api.stmt_dist(ind, s->ctxs, skeleton->contexts));
+               } else {
+                       o.wstring(opts->input_api.stmt_backupctx(ind));
+               }
        }
 }
 
@@ -248,7 +254,49 @@ void emit_accept (OutputFile & o, uint32_t ind, bool & readCh, const State * con
        }
 }
 
-void emit_rule (OutputFile & o, uint32_t ind, const State * const s, const RuleInfo * const rule, const std::string & condName, const Skeleton * skeleton)
+static void rreplace_substr(std::string &s,
+       const std::string &s1, const std::string &s2)
+{
+       if (!s1.empty()) {
+               std::string::size_type pos;
+               while ((pos = s.find(s1)) != std::string::npos) {
+                       s.replace(pos, s1.length(), s2);
+               }
+       }
+}
+
+static std::string apply_rule_subst(const RuleInfo *rule, const std::vector<CtxVar> &contexts)
+{
+       std::string action = rule->code->text;
+
+       for (size_t i = 0; i < rule->ctxvar.size(); ++i) {
+               const CtxVar &ctx = contexts[rule->ctxvar[i]];
+               rreplace_substr(action, "@" + *ctx.name,
+                       opts->input_api.expr_ctx(ctx.fullname));
+       }
+
+       for (size_t i = 0; i < rule->ctxfix.size(); ++i) {
+               const CtxFix &ctx = rule->ctxfix[i];
+               const std::string basename = (ctx.base == CtxFix::RIGHTMOST)
+                       ? opts->input_api.expr_dist()
+                       : contexts[ctx.base].fullname;
+               std::ostringstream offs;
+               offs << "(" << basename << " - " << ctx.dist << ")";
+               const std::string ctx_value = opts->input_api.expr_ctx(offs.str());
+               rreplace_substr(action, "@" + *ctx.name, ctx_value);
+       }
+
+       return action;
+}
+
+void emit_rule(
+       OutputFile &o,
+       uint32_t ind,
+       const State *const s,
+       const RuleInfo *const rule,
+       const std::string &condName,
+       const Skeleton *skeleton,
+       bool base_ctxmarker)
 {
        if (opts->target == opt_t::DOT)
        {
@@ -261,15 +309,21 @@ void emit_rule (OutputFile & o, uint32_t ind, const State * const s, const RuleI
                return;
        }
 
-       if (opts->target != opt_t::DOT)
-       {
-               if (rule->ctx_len == ~0u)
-               {
-                       o.wstring(opts->input_api.stmt_restorectx_dynamic(ind));
-               }
-               else if (rule->ctx_len > 0)
-               {
-                       o.wstring(opts->input_api.stmt_restorectx_static(ind, rule->ctx_len));
+       if (opts->target != opt_t::DOT) {
+               switch (rule->trail.type) {
+                       case Trail::NONE:
+                               break;
+                       case Trail::VAR:
+                               if (base_ctxmarker) {
+                                       const std::string name = skeleton->contexts[rule->trail.pld.var].fullname;
+                                       o.wstring(opts->input_api.stmt_restorectx_var_base(ind, name));
+                               } else {
+                                       o.wstring(opts->input_api.stmt_restorectx_var(ind));
+                               }
+                               break;
+                       case Trail::FIX:
+                               o.wstring(opts->input_api.stmt_restorectx_fix(ind, rule->trail.pld.fix));
+                               break;
                }
        }
 
@@ -290,8 +344,9 @@ void emit_rule (OutputFile & o, uint32_t ind, const State * const s, const RuleI
                        {
                                o.wind(ind).wstring(yySetupRule).ws("\n");
                        }
+                       const std::string action = apply_rule_subst(rule, skeleton->contexts);
                        o.wline_info(rule->code->loc.line, rule->code->loc.filename.c_str ())
-                               .wind(ind).wstring(rule->code->text).ws("\n")
+                               .wind(ind).wstring(action).ws("\n")
                                .wdelay_line_info ();
                }
                else if (!rule->newcond.empty ())
index 97b049b2b8fda55dbd44c29ca7187d35f2257862..f02c973f89eb38920d46bca4eb288ad9c77e47ee 100644 (file)
@@ -107,7 +107,8 @@ void DFA::emit_body (OutputFile & o, uint32_t& ind, const std::set<label_t> & us
        {
                bool readCh = false;
                emit_state (o, ind, s, used_labels.count (s->label));
-               emit_action (s->action, o, ind, readCh, s, cond, skeleton, used_labels, save_yyaccept);
+               emit_action (s->action, o, ind, readCh, s, cond, skeleton,
+                       used_labels, save_yyaccept, base_ctxmarker);
                s->go.emit(o, ind, readCh);
        }
 }
@@ -116,6 +117,16 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra
 {
        OutputFile & o = output.source;
 
+       std::set<std::string> ctxnames;
+       if (base_ctxmarker) {
+               for (State *s = head; s; s = s->next) {
+                       for (std::set<size_t>::const_iterator i = s->ctxs.begin(); i != s->ctxs.end(); ++i) {
+                               ctxnames.insert(contexts[*i].fullname);
+                       }
+               }
+               output.contexts.insert(ctxnames.begin(), ctxnames.end());
+       }
+
        bool bProlog = (!opts->cFlag || !bWroteCondCheck);
 
        // start_label points to the beginning of current re2c block
@@ -144,7 +155,8 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra
                if (output.skeletons.insert (name).second)
                {
                        emit_data(*skeleton, o.file_name);
-                       emit_start(*skeleton, o, max_fill, need_backup, need_backupctx, need_accept);
+                       emit_start(*skeleton, o, max_fill, need_backup, need_backupctx,
+                               need_accept, base_ctxmarker, ctxnames);
                        uint32_t i = 2;
                        emit_body (o, i, used_labels, initial_label);
                        emit_end(*skeleton, o, need_backup, need_backupctx);
@@ -182,6 +194,9 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra
                                        o.wind(ind).wstring(opts->yyctype).ws(" ").wstring(opts->yych).ws(";\n");
                                }
                                o.wdelay_yyaccept_init (ind);
+                               if (base_ctxmarker) {
+                                       o.wdelay_contexts(ind);
+                               }
                        }
                        else
                        {
index 6301664767ec4c241523f283e7ecf1eba0b9bcee..7780669b315bb27315e237c7be4c80a94c59fa09 100644 (file)
@@ -90,7 +90,38 @@ std::string InputAPI::stmt_backupctx (uint32_t ind) const
                        s = opts->yybackupctx + " ()";
                        break;
        }
-       return indent (ind) + s + ";\n";
+       return indent(ind) + s + ";\n";
+}
+
+std::string InputAPI::expr_dist () const
+{
+       std::string s;
+       switch (type_) {
+               case DEFAULT:
+                       return "(" + opts->yycursor + " - " + opts->yyctxmarker + ")";
+               case CUSTOM:
+                       return "YYDIST()";
+       }
+}
+
+std::string InputAPI::stmt_dist (uint32_t ind, const std::set<size_t> &ctxs,
+               const std::vector<CtxVar> &contexts) const
+{
+       std::string s = indent(ind);
+       for (std::set<size_t>::const_iterator i = ctxs.begin(); i != ctxs.end(); ++i) {
+               s += contexts[*i].fullname + " = ";
+       }
+       return s + expr_dist() + ";\n";
+}
+
+std::string InputAPI::expr_ctx (const std::string &ctx) const
+{
+       switch (type_) {
+               case DEFAULT:
+                       return "(" + opts->yyctxmarker + " + " + ctx + ")";
+               case CUSTOM:
+                       return "YYCTX(" + ctx + ")";
+       }
 }
 
 std::string InputAPI::stmt_restore (uint32_t ind) const
@@ -108,27 +139,46 @@ std::string InputAPI::stmt_restore (uint32_t ind) const
        return indent (ind) + s + ";\n";
 }
 
-std::string InputAPI::stmt_restorectx_static (uint32_t ind, uint32_t off) const
+std::string InputAPI::stmt_restorectx_fix(uint32_t ind, size_t dist) const
 {
-       assert(type_ == DEFAULT);
        std::ostringstream s;
-       s << indent (ind) << opts->yycursor << " -= " << off << ";\n";
-       return s.str ();
+       switch (type_) {
+               case DEFAULT:
+                       s << opts->yycursor << " -= " << dist;
+                       break;
+               case CUSTOM:
+                       s << opts->yyrestorectx << " (YYDIST() - " << dist << ")";
+                       break;
+       }
+       return indent(ind) + s.str() + ";\n";
 }
 
-std::string InputAPI::stmt_restorectx_dynamic (uint32_t ind) const
+std::string InputAPI::stmt_restorectx_var_base(uint32_t ind, const std::string &ctx) const
 {
        std::string s;
-       switch (type_)
-       {
+       switch (type_) {
                case DEFAULT:
-                       s = indent (ind) + opts->yycursor + " = " + opts->yyctxmarker + ";\n";
+                       s = opts->yycursor + " = " + opts->yyctxmarker + " + " + ctx;
                        break;
                case CUSTOM:
-                       s = indent (ind) + opts->yyrestorectx + " ();\n";
+                       s = opts->yyrestorectx + " (" + ctx + ")";
                        break;
        }
-       return s;
+       return indent(ind) + s + ";\n";
+}
+
+std::string InputAPI::stmt_restorectx_var(uint32_t ind) const
+{
+       std::string s;
+       switch (type_) {
+               case DEFAULT:
+                       s = opts->yycursor + " = " + opts->yyctxmarker;
+                       break;
+               case CUSTOM:
+                       s = opts->yyrestorectx + " ()";
+                       break;
+       }
+       return indent(ind) + s + ";\n";
 }
 
 std::string InputAPI::stmt_skip_peek (uint32_t ind) const
index 3514019d2ffbc25600d5e0c40dec83add33a7053..de76f76ef557aaa6d7a5bdfb9425a4b63c69718a 100644 (file)
@@ -2,11 +2,15 @@
 #define _RE2C_CODEGEN_INPUT_API_
 
 #include "src/util/c99_stdint.h"
+#include <set>
 #include <string>
+#include <vector>
 
 namespace re2c
 {
 
+struct CtxVar;
+
 class InputAPI
 {
 public:
@@ -28,9 +32,14 @@ public:
        std::string stmt_skip (uint32_t ind) const;
        std::string stmt_backup (uint32_t ind) const;
        std::string stmt_backupctx (uint32_t ind) const;
+       std::string expr_dist () const;
+       std::string stmt_dist (uint32_t ind, const std::set<size_t> &ctxs,
+               const std::vector<CtxVar> &contexts) const;
+       std::string expr_ctx (const std::string &ctx) const;
        std::string stmt_restore (uint32_t ind) const;
-       std::string stmt_restorectx_static (uint32_t ind, uint32_t off) const;
-       std::string stmt_restorectx_dynamic (uint32_t ind) const;
+       std::string stmt_restorectx_fix (uint32_t ind, size_t dist) const;
+       std::string stmt_restorectx_var (uint32_t ind) const;
+       std::string stmt_restorectx_var_base (uint32_t ind, const std::string &ctx) const;
        std::string stmt_skip_peek (uint32_t ind) const;
        std::string stmt_skip_backup (uint32_t ind) const;
        std::string stmt_backup_peek (uint32_t ind) const;
index 5276ef77e0195a771d7090c11783d47c698e1087..0e9537a3adb60f13955a37dd49869a327783784b 100644 (file)
@@ -199,6 +199,13 @@ void OutputFile::insert_code ()
        blocks.back ()->fragments.push_back (new OutputFragment (OutputFragment::CODE, 0));
 }
 
+OutputFile &OutputFile::wdelay_contexts(uint32_t ind)
+{
+       blocks.back()->fragments.push_back(new OutputFragment(OutputFragment::CONTEXTS, ind));
+       insert_code();
+       return *this;
+}
+
 OutputFile & OutputFile::wdelay_line_info ()
 {
        blocks.back ()->fragments.push_back (new OutputFragment (OutputFragment::LINE_INFO, 0));
@@ -287,10 +294,10 @@ void OutputFile::new_block ()
        insert_code ();
 }
 
-void OutputFile::emit
-       ( const std::vector<std::string> & types
-       , size_t max_fill
-       )
+void OutputFile::emit(
+       const std::vector<std::string> &types,
+       const std::set<std::string> &contexts,
+       size_t max_fill)
 {
        if (file != NULL)
        {
@@ -305,6 +312,9 @@ void OutputFile::emit
                                {
                                        case OutputFragment::CODE:
                                                break;
+                                       case OutputFragment::CONTEXTS:
+                                               output_contexts(f.stream, f.indent, contexts);
+                                               break;
                                        case OutputFragment::LINE_INFO:
                                                output_line_info (f.stream, line_count + 1, file_name);
                                                break;
@@ -373,6 +383,7 @@ Output::Output (const char * source_name, const char * header_name)
        , header (header_name)
        , types ()
        , skeletons ()
+       , contexts ()
        , max_fill (1)
 {}
 
@@ -380,11 +391,26 @@ Output::~Output ()
 {
        if (!warn.error ())
        {
-               source.emit (types, max_fill);
+               source.emit (types, contexts, max_fill);
                header.emit (types);
        }
 }
 
+void output_contexts(std::ostream &o, uint32_t ind, const std::set<std::string> &contexts)
+{
+       if (!contexts.empty()) {
+               std::set<std::string>::const_iterator
+                       ctx = contexts.begin(),
+                       end = contexts.end();
+               o << indent(ind) << "YYDISTTYPE " << *ctx;
+               for (++ctx; ctx != end; ++ctx) {
+                       o << ", " << *ctx;
+               }
+               o << ";\n";
+       }
+       o << opts->input_api.stmt_backupctx(ind);
+}
+
 void output_state_goto (std::ostream & o, uint32_t ind, uint32_t start_label)
 {
        o << indent(ind) << "switch (" << output_get_state() << ") {\n";
index 774fea3529f392233d68d33d40943adf901d5fad..5f7fd39ff0a4eafa3d80302a299f3b03f60e4d6d 100644 (file)
@@ -23,6 +23,7 @@ struct OutputFragment
 {
        enum type_t
                { CODE
+               , CONTEXTS
 //             , CONFIG
                , LINE_INFO
                , STATE_GOTO
@@ -65,16 +66,12 @@ public:
        counter_t<label_t> label_counter;
        bool warn_condition_order;
 
-private:
-       std::ostream & stream ();
-       void insert_code ();
-
-public:
        OutputFile (const char * fn);
        ~OutputFile ();
 
+       std::ostream & stream ();
+       void insert_code ();
        bool open ();
-
        void new_block ();
 
        // immediate output
@@ -96,6 +93,7 @@ public:
        OutputFile & wind (uint32_t ind);
 
        // delayed output
+       OutputFile & wdelay_contexts(uint32_t ind);
        OutputFile & wdelay_line_info ();
        OutputFile & wdelay_state_goto (uint32_t ind);
        OutputFile & wdelay_types ();
@@ -111,7 +109,8 @@ public:
        void set_block_line (uint32_t l);
        uint32_t get_block_line () const;
 
-       void emit (const std::vector<std::string> & types, size_t max_fill);
+       void emit(const std::vector<std::string> &types,
+               const std::set<std::string> &contexts, size_t max_fill);
 
        FORBID_COPY (OutputFile);
 };
@@ -137,12 +136,14 @@ struct Output
        HeaderFile header;
        std::vector<std::string> types;
        std::set<std::string> skeletons;
+       std::set<std::string> contexts;
        size_t max_fill;
 
        Output (const char * source_name, const char * header_name);
        ~Output ();
 };
 
+void output_contexts(std::ostream &o, uint32_t ind, const std::set<std::string> &contexts);
 void output_line_info (std::ostream &, uint32_t, const char *);
 void output_state_goto (std::ostream &, uint32_t, uint32_t);
 void output_types (std::ostream &, uint32_t, const std::vector<std::string> &);
index fa65ceaa8bafaf3e4302e6bc3549377d127a8ff5..8cb47ba5709d59a578cc5519d5a71b17e285ffb6 100644 (file)
@@ -1,5 +1,6 @@
 #include "src/conf/msg.h"
 #include "src/conf/opt.h"
+#include "src/globals.h"
 
 namespace re2c
 {
@@ -214,6 +215,9 @@ void opt_t::fix ()
                default:
                        break;
        }
+       if (contexts) {
+               warn.set(Warn::SELFOVERLAPPING_CONTEXTS, Warn::WERROR);
+       }
        if (bFlag)
        {
                sFlag = true;
index 30ab21e55aae8cbab384d9e74f57d3dd96657637..25d20fbfa49ad945e917a320582faa25d41d5a01 100644 (file)
@@ -55,6 +55,8 @@ namespace re2c
        OPT (bool, bUseStateAbort, false) \
        OPT (bool, bUseStateNext, false) \
        /* reuse */ \
+       OPT (bool, contexts, false) \
+       /* reuse */ \
        OPT (bool, rFlag, false) \
        /* partial flex syntax support */ \
        OPT (bool, FFlag, false) \
index 5ff3a217559c804c88f5d872568a40d507a1aff1..43e378f8adf423452d80368858c43e64d802df6e 100644 (file)
@@ -78,13 +78,14 @@ opt_warn:
                error ("bad warning: %s", *argv);
                return EXIT_FAIL;
        }
-       "condition-order"        end { warn.set (Warn::CONDITION_ORDER,        option); goto opt; }
-       "empty-character-class"  end { warn.set (Warn::EMPTY_CHARACTER_CLASS,  option); goto opt; }
-       "match-empty-string"     end { warn.set (Warn::MATCH_EMPTY_STRING,     option); goto opt; }
-       "swapped-range"          end { warn.set (Warn::SWAPPED_RANGE,          option); goto opt; }
-       "undefined-control-flow" end { warn.set (Warn::UNDEFINED_CONTROL_FLOW, option); goto opt; }
-       "unreachable-rules"      end { warn.set (Warn::UNREACHABLE_RULES,      option); goto opt; }
-       "useless-escape"         end { warn.set (Warn::USELESS_ESCAPE,         option); goto opt; }
+       "condition-order"          end { warn.set (Warn::CONDITION_ORDER,          option); goto opt; }
+       "empty-character-class"    end { warn.set (Warn::EMPTY_CHARACTER_CLASS,    option); goto opt; }
+       "match-empty-string"       end { warn.set (Warn::MATCH_EMPTY_STRING,       option); goto opt; }
+       "selfoverlapping-contexts" end { warn.set (Warn::SELFOVERLAPPING_CONTEXTS, option); goto opt; }
+       "swapped-range"            end { warn.set (Warn::SWAPPED_RANGE,            option); goto opt; }
+       "undefined-control-flow"   end { warn.set (Warn::UNDEFINED_CONTROL_FLOW,   option); goto opt; }
+       "unreachable-rules"        end { warn.set (Warn::UNREACHABLE_RULES,        option); goto opt; }
+       "useless-escape"           end { warn.set (Warn::USELESS_ESCAPE,           option); goto opt; }
 */
 
 opt_short:
@@ -100,6 +101,7 @@ opt_short:
        "V"  { vernum ();  return EXIT_OK; }
        "b" { opts.set_bFlag (true);             goto opt_short; }
        "c" { opts.set_cFlag (true);             goto opt_short; }
+       "C" { opts.set_contexts (true);          goto opt_short; }
        "d" { opts.set_dFlag (true);             goto opt_short; }
        "D" { opts.set_target (opt_t::DOT);      goto opt_short; }
        "f" { opts.set_fFlag (true);             goto opt_short; }
@@ -133,6 +135,7 @@ opt_long:
        "vernum"             end { vernum ();  return EXIT_OK; }
        "bit-vectors"        end { opts.set_bFlag (true);             goto opt; }
        "start-conditions"   end { opts.set_cFlag (true);             goto opt; }
+       "contexts"           end { opts.set_contexts (true);          goto opt; }
        "debug-output"       end { opts.set_dFlag (true);             goto opt; }
        "emit-dot"           end { opts.set_target (opt_t::DOT);      goto opt; }
        "storable-state"     end { opts.set_fFlag (true);             goto opt; }
index 275466d3d52eadd062a9f59551d881458dbf1e6b..b53acc7d0b7bda6bd4bc4bc672980fb4927e0726 100644 (file)
@@ -118,6 +118,30 @@ void Warn::match_empty_string (uint32_t line)
        }
 }
 
+void Warn::selfoverlapping_contexts(
+       uint32_t line,
+       const std::string &cond,
+       const CtxVar &ctx)
+{
+       if (mask[SELFOVERLAPPING_CONTEXTS] & WARNING)
+       {
+               const bool e = mask[SELFOVERLAPPING_CONTEXTS] & ERROR;
+               error_accuml |= e;
+
+               const char *trail, *name;
+               if (ctx.name == NULL) {
+                       trail = "trailing context";
+                       name = "";
+               } else {
+                       trail = "context ";
+                       name = ctx.name->c_str();
+               }
+               warning(names[SELFOVERLAPPING_CONTEXTS], line, e,
+                       "%s%s %sis self-overlapping", trail, name,
+                       incond(cond).c_str());
+       }
+}
+
 void Warn::swapped_range (uint32_t line, uint32_t l, uint32_t u)
 {
        if (mask[SWAPPED_RANGE] & WARNING)
index f427dbc7fa5cbc81940d745ed9c5dc3e3705fd46..d83f7fc1e5536c359fb21598087649940b507f2d 100644 (file)
@@ -13,13 +13,14 @@ struct path_t;
 struct Skeleton;
 
 #define RE2C_WARNING_TYPES \
-       W (CONDITION_ORDER,        "condition-order"), \
-       W (EMPTY_CHARACTER_CLASS,  "empty-character-class"), \
-       W (MATCH_EMPTY_STRING,     "match-empty-string"), \
-       W (SWAPPED_RANGE,          "swapped-range"), \
-       W (UNDEFINED_CONTROL_FLOW, "undefined-control-flow"), \
-       W (UNREACHABLE_RULES,      "unreachable-rules"), \
-       W (USELESS_ESCAPE,         "useless-escape"),
+       W (CONDITION_ORDER,          "condition-order"), \
+       W (EMPTY_CHARACTER_CLASS,    "empty-character-class"), \
+       W (MATCH_EMPTY_STRING,       "match-empty-string"), \
+       W (SELFOVERLAPPING_CONTEXTS, "selfoverlapping-contexts"), \
+       W (SWAPPED_RANGE,            "swapped-range"), \
+       W (UNDEFINED_CONTROL_FLOW,   "undefined-control-flow"), \
+       W (UNREACHABLE_RULES,        "unreachable-rules"), \
+       W (USELESS_ESCAPE,           "useless-escape"),
 
 class Warn
 {
@@ -58,6 +59,7 @@ public:
        void condition_order (uint32_t line);
        void empty_class (uint32_t line);
        void match_empty_string (uint32_t line);
+       void selfoverlapping_contexts(uint32_t line, const std::string &cond, const CtxVar &ctx);
        void swapped_range (uint32_t line, uint32_t l, uint32_t u);
        void undefined_control_flow (const Skeleton &skel, std::vector<path_t> & paths, bool overflow);
        void unreachable_rule (const std::string & cond, const RuleInfo *rule);
index db400854c74f618f89f591efa90e66aa6b9c4e4e..31a8b3338f5f281035e265b9bc64b72e35bb6aa9 100644 (file)
@@ -4,11 +4,13 @@
 #include <vector>
 #include <utility>
 
+#include "src/conf/opt.h"
 #include "src/codegen/go.h"
 #include "src/ir/adfa/adfa.h"
 #include "src/ir/dfa/dfa.h"
 #include "src/ir/skeleton/skeleton.h"
 #include "src/util/allocate.h"
+#include "src/globals.h"
 
 namespace re2c
 {
@@ -22,6 +24,7 @@ DFA::DFA
        , const std::string &n
        , const std::string &c
        , uint32_t l
+       , bool base_ctx
        )
        : accepts ()
        , skeleton (skel)
@@ -32,12 +35,14 @@ DFA::DFA
        , ubChar(charset.back())
        , nStates(0)
        , head(NULL)
+       , contexts(dfa.contexts)
 
        // statistics
        , max_fill (0)
        , need_backup (false)
-       , need_backupctx (false)
+       , need_backupctx (opts->contexts)
        , need_accept (false)
+       , base_ctxmarker (base_ctx)
 {
        const size_t nstates = dfa.states.size();
        const size_t nchars = dfa.nchars;
@@ -58,7 +63,7 @@ DFA::DFA
                *p = s;
                p = &s->next;
 
-               s->isPreCtxt = t->ctx;
+               s->ctxs = t->ctxs;
                s->rule = t->rule;
                s->fill = fill[i];
                s->go.span = allocate<Span>(nchars);
index b85b4b2c49217155e847d9bf88c06cbf440df9f6..019373368bf48647b7c181ebb12fc7e3f123f98e 100644 (file)
@@ -28,7 +28,7 @@ struct State
        size_t fill;
        bool fallback;
 
-       bool isPreCtxt;
+       std::set<size_t> ctxs;
        bool isBase;
        Go go;
        Action action;
@@ -39,7 +39,7 @@ struct State
                , next (0)
                , fill (0)
                , fallback (false)
-               , isPreCtxt (false)
+               , ctxs ()
                , isBase (false)
                , go ()
                , action ()
@@ -66,12 +66,14 @@ public:
        uint32_t ubChar;
        uint32_t nStates;
        State * head;
+       std::vector<CtxVar> &contexts;
 
        // statistics
        size_t max_fill;
        bool need_backup;
        bool need_backupctx;
        bool need_accept;
+       bool base_ctxmarker;
 
 public:
        DFA     ( const dfa_t &dfa
@@ -82,6 +84,7 @@ public:
                , const std::string &n
                , const std::string &c
                , uint32_t l
+               , bool base_ctx
                );
        ~DFA ();
        void reorder();
index 0856a0c3686e797d65c3a989699d582dbf901d77..40753aabe06362121b48bbee3c7f2b76363c4201 100644 (file)
@@ -243,11 +243,10 @@ void DFA::calc_stats ()
        need_backup = accepts.size () > 0;
 
        // determine if 'YYCTXMARKER' or 'YYBACKUPCTX'/'YYRESTORECTX' pair is used
-       for (State * s = head; s; s = s->next)
-       {
-               if (s->isPreCtxt)
-               {
+       for (State * s = head; s; s = s->next) {
+               if (!s->ctxs.empty()) {
                        need_backupctx = true;
+                       break;
                }
        }
 
index 8bd15d8cbd736f11378d5e0b120ecb053b3e57f2..da9d90aff6d181922c7237225a92faf8522aa446 100644 (file)
@@ -3,6 +3,7 @@
 #include <set>
 
 #include "src/codegen/output.h"
+#include "src/conf/opt.h"
 #include "src/ir/compile.h"
 #include "src/ir/adfa/adfa.h"
 #include "src/ir/dfa/dfa.h"
@@ -10,6 +11,7 @@
 #include "src/ir/regexp/regexp.h"
 #include "src/ir/skeleton/skeleton.h"
 #include "src/parse/spec.h"
+#include "src/globals.h"
 
 namespace re2c {
 
@@ -47,9 +49,9 @@ smart_ptr<DFA> compile (Spec & spec, Output & output, const std::string & cond,
                cs.push_back(*i);
        }
 
-       nfa_t nfa(spec.re);
+       nfa_t nfa(spec);
 
-       dfa_t dfa(nfa, cs);
+       dfa_t dfa(nfa, cs, line, cond);
 
        // skeleton must be constructed after DFA construction
        // but prior to any other DFA transformations
@@ -65,8 +67,25 @@ smart_ptr<DFA> compile (Spec & spec, Output & output, const std::string & cond,
        std::vector<size_t> fallback;
        fallback_states(dfa, fallback);
 
+       // Non-trailing contexts imply the existence of base context marker
+       // that points at the beginning of lexeme. First, it is a feature
+       // of re2c API. Second, it simplifies implementation (otherwise
+       // it would be hard to mix generic API and fixed-length contexts).
+       //
+       // The only case without base context marker is when:
+       //     - only trailing contexts are allowed
+       //     - they don't overlap (one marker is enough for all of them)
+       //     - with generic API fixed-length contexts are forbidden
+       // Note that in this case, if generic API is used, fixed-length
+       // contexts are forbidden (which may cause additional overlaps).
+       const bool multiple_ctxmarkers = deduplicate_contexts(dfa, fallback);
+       const bool base_ctxmarker
+               = multiple_ctxmarkers
+               || opts->contexts;
+
        // ADFA stands for 'DFA with actions'
-       DFA *adfa = new DFA(dfa, fill, fallback, skeleton, cs, name, cond, line);
+       DFA *adfa = new DFA(dfa, fill, fallback, skeleton, cs,
+               name, cond, line, base_ctxmarker);
 
        // see note [reordering DFA states]
        adfa->reorder();
diff --git a/re2c/src/ir/dfa/context_deduplication.cc b/re2c/src/ir/dfa/context_deduplication.cc
new file mode 100644 (file)
index 0000000..4ff0120
--- /dev/null
@@ -0,0 +1,172 @@
+#include <limits>
+#include <set>
+#include <vector>
+
+#include "src/ir/dfa/dfa.h"
+
+namespace re2c
+{
+
+static void calc_live(
+       const dfa_t &dfa,
+       const std::set<size_t> &fallback,
+       std::vector<bool> &visited,
+       std::vector<std::set<size_t> > &live,
+       size_t i)
+{
+       if (!visited[i]) {
+               visited[i] = true;
+
+               dfa_state_t *s = dfa.states[i];
+
+               bool fallthru = false;
+               for (size_t c = 0; c < dfa.nchars; ++c) {
+                       const size_t j = s->arcs[c];
+                       if (j != dfa_t::NIL) {
+                               calc_live(dfa, fallback, visited, live, j);
+                               live[i].insert(live[j].begin(), live[j].end());
+                       } else {
+                               fallthru = true;
+                       }
+               }
+
+               if (s->rule != NULL) {
+                       live[i].insert(s->rule->ctxvar.begin(), s->rule->ctxvar.end());
+                       const Trail &ctx = s->rule->trail;
+                       if (ctx.type == Trail::VAR) {
+                               live[i].insert(ctx.pld.var);
+                       }
+               } else if (fallthru) {
+                       // transition to default state: all fallback rules
+                       // are potentialy reachable, their contexts are alive
+                       live[i].insert(fallback.begin(), fallback.end());
+               }
+       }
+}
+
+bool deduplicate_contexts(
+       const dfa_t &dfa,
+       const std::vector<size_t> &fallback)
+{
+       const size_t nctxs = dfa.contexts.size();
+       if (nctxs < 2) {
+               return false;
+       }
+
+       std::set<size_t> fbctxs;
+       for (size_t i = 0; i < fallback.size(); ++i) {
+               const RuleInfo *rule = dfa.states[fallback[i]]->rule;
+               fbctxs.insert(rule->ctxvar.begin(), rule->ctxvar.end());
+               if (rule->trail.type == Trail::VAR) {
+                       fbctxs.insert(rule->trail.pld.var);
+               }
+       }
+
+       const size_t nstates = dfa.states.size();
+
+       std::vector<bool> visited(nstates);
+       std::vector<std::set<size_t> > live(nstates);
+       calc_live(dfa, fbctxs, visited, live, 0);
+
+       std::vector<size_t> buffer(nctxs);
+       std::vector<bool> xxx(nctxs * nctxs);
+       for (size_t i = 0; i < nstates; ++i) {
+               const std::set<size_t>
+                       &ctxs = dfa.states[i]->ctxs,
+                       &liv = live[i];
+               std::vector<size_t>::iterator
+                       diff = buffer.begin(),
+                       diff_end = std::set_difference(liv.begin(), liv.end(),
+                               ctxs.begin(), ctxs.end(), diff);
+               for (; diff != diff_end; ++diff) {
+                       for (std::set<size_t>::const_iterator j = ctxs.begin(); j != ctxs.end(); ++j) {
+                               xxx[*diff * nctxs + *j] = xxx[*j * nctxs + *diff] = true;
+                       }
+               }
+       }
+
+       // We have a binary relation on the set of all contexts
+       // and must construct set decomposition into subsets such that
+       // all contexts in the same subset are equivalent.
+       //
+       // This problem is isomorphic to partitioning graph into cliques
+       // (aka finding the 'clique cover' of a graph).
+       //
+       // Finding minimal clique cover in arbitrary graph is NP-complete.
+       // We build just some cover (not necessarily minimal).
+       // The algorithm takes quadratic (in the number of contexts) time.
+
+       static const size_t END = std::numeric_limits<size_t>::max();
+       std::vector<size_t>
+               part(nctxs, 0),   // partition: mapping of context to its representative
+               head(nctxs, END), // list of representatives
+               next(nctxs, END); // list of contexts mapped to the same representative
+       // skip the 1st context, it maps to itself
+       for (size_t c = 1; c < nctxs; ++c) {
+               size_t h;
+               for (h = 0; h != END; h = head[h]) {
+                       size_t n;
+                       for (n = h; n != END; n = next[n]) {
+                               if (xxx[c * nctxs + n]) {
+                                       break;
+                               }
+                       }
+                       if (n == END) {
+                               part[c] = h;
+                               next[c] = next[h];
+                               next[h] = c;
+                               break;
+                       }
+               }
+               if (h == END) {
+                       part[c] = c;
+                       head[c] = head[0];
+                       head[0] = c;
+               }
+       }
+       const bool multiple_contexts = head[0] != END;
+
+/*
+       std::vector<size_t> c2c;
+       std::vector<std::vector<size_t> > part;
+       for (size_t i = 0; i < nctxs; ++i) {
+               size_t j;
+               for (j = 0; j < partn.size(); ++j) {
+                       std::vector<size_t> &p = part[j];
+                       size_t k;
+                       for (k = 0; k < p.size(); ++k) {
+                               if (xxx[i * nctxs + p[k]]) {
+                                       break;
+                               }
+                       }
+                       if (k == p.size()) {
+                               break;
+                       }
+               }
+               if (j == part.size()) {
+                       part.push_back(std::vector<size_t>());
+               }
+               part[j].push_back(i);
+               c2c[i] = part[j][0];
+       }
+*/
+       for (size_t i = 0; i < nstates; ++i) {
+               dfa_state_t *s = dfa.states[i];
+               std::set<size_t> ctxs;
+               for (std::set<size_t>::const_iterator j = s->ctxs.begin(); j != s->ctxs.end(); ++j) {
+                       ctxs.insert(part[*j]);
+               }
+               s->ctxs.swap(ctxs);
+       }
+       for (size_t i = 0; i < nctxs; ++i) {
+               dfa.contexts[i].fullname = dfa.contexts[part[i]].fullname;
+       }
+
+       return multiple_contexts;
+}
+
+
+
+
+} // namespace re2c
+
diff --git a/re2c/src/ir/dfa/context_selfoverlap.cc b/re2c/src/ir/dfa/context_selfoverlap.cc
new file mode 100644 (file)
index 0000000..65e3074
--- /dev/null
@@ -0,0 +1,112 @@
+#include <algorithm>
+#include <map>
+#include <vector>
+
+#include "src/conf/warn.h"
+#include "src/ir/dfa/dfa.h"
+#include "src/ir/nfa/nfa.h"
+#include "src/util/intersect_sorted.h"
+#include "src/globals.h"
+
+namespace re2c
+{
+
+static void g(nfa_state_t *n, std::vector<nfa_state_t*> &tail);
+static void e(nfa_state_t *n, std::vector<nfa_state_t*> &tail);
+static void f(nfa_state_t *n, std::vector<nfa_state_t*> &tail);
+
+void check_context_selfoverlap(
+       ord_hash_set_t &kernels,
+       const std::vector<CtxVar> &contexts,
+       uint32_t line,
+       const std::string &cond)
+{
+       const size_t nctxs = contexts.size();
+
+       std::vector<bool> bad(nctxs, false);
+
+       std::map<nfa_state_t*, std::vector<nfa_state_t*> > shadows;
+       for (size_t i = 0; i < kernels.size(); ++i) {
+               nfa_state_t **kernel;
+               const size_t kernel_size = kernels.deref<nfa_state_t*>(i, kernel);
+               for (size_t j = 0; j < kernel_size; ++j) {
+                       nfa_state_t *n = kernel[j];
+                       if (n->type == nfa_state_t::CTX
+                               && !bad[n->value.ctx.info]) {
+                               std::vector<nfa_state_t*> &shadow = shadows[n];
+                               if (shadow.empty()) {
+                                       f(n, shadow);
+                               }
+                               if (intersect_sorted(
+                                       shadow.begin(), shadow.end(),
+                                       kernel, kernel + kernel_size)) {
+                                       bad[n->value.ctx.info] = true;
+                               }
+                       }
+               }
+       }
+
+       for (size_t i = 0; i < nctxs; ++i) {
+               if (bad[i]) {
+                       warn.selfoverlapping_contexts(line, cond, contexts[i]);
+               }
+       }
+}
+
+void f(nfa_state_t *n, std::vector<nfa_state_t*> &tail)
+{
+       e(n, tail);
+       std::sort(tail.begin(), tail.end());
+}
+
+void g(nfa_state_t *n, std::vector<nfa_state_t*> &tail)
+{
+       if (!n->mark)
+       {
+               n->mark = true;
+               tail.push_back(n);
+               switch (n->type)
+               {
+                       case nfa_state_t::ALT:
+                               g(n->value.alt.out2, tail);
+                               g(n->value.alt.out1, tail);
+                               break;
+                       case nfa_state_t::RAN:
+                               g(n->value.ran.out, tail);
+                               break;
+                       case nfa_state_t::CTX:
+                               g(n->value.ctx.out, tail);
+                               break;
+                       case nfa_state_t::FIN:
+                               break;
+               }
+               n->mark = false;
+       }
+}
+
+static void e(nfa_state_t *n, std::vector<nfa_state_t*> &tail)
+{
+       if (!n->mark)
+       {
+               n->mark = true;
+               switch (n->type)
+               {
+                       case nfa_state_t::ALT:
+                               e(n->value.alt.out2, tail);
+                               e(n->value.alt.out1, tail);
+                               break;
+                       case nfa_state_t::RAN:
+                               g(n->value.ran.out, tail);
+                               break;
+                       case nfa_state_t::CTX:
+                               e(n->value.ctx.out, tail);
+                               break;
+                       case nfa_state_t::FIN:
+                               break;
+               }
+               n->mark = false;
+       }
+}
+
+} // namespace re2c
+
index 428e91d37add0d83d8c74ac65078263842723eb8..a164b627ef866cd34d4d29f44a71b9147c3b9ca4 100644 (file)
@@ -9,7 +9,6 @@
 #include "src/ir/regexp/regexp.h"
 #include "src/ir/rule_rank.h"
 #include "src/parse/rules.h"
-#include "src/util/ord_hash_set.h"
 #include "src/util/range.h"
 
 namespace re2c
@@ -90,9 +89,14 @@ static size_t find_state
        return kernels.insert(kernel, size);
 }
 
-dfa_t::dfa_t(const nfa_t &nfa, const charset_t &charset)
+dfa_t::dfa_t(
+       const nfa_t &nfa,
+       const charset_t &charset,
+       uint32_t line,
+       const std::string &cond)
        : states()
        , nchars(charset.size() - 1) // (n + 1) bounds for n ranges
+       , contexts(nfa.contexts)
 {
        std::map<size_t, std::set<RuleInfo*> > s2rules;
        ord_hash_set_t kernels;
@@ -127,7 +131,7 @@ dfa_t::dfa_t(const nfa_t &nfa, const charset_t &charset)
                                        break;
                                }
                                case nfa_state_t::CTX:
-                                       s->ctx = true;
+                                       s->ctxs.insert(n->value.ctx.info);
                                        break;
                                case nfa_state_t::FIN:
                                        s2rules[i].insert(n->value.fin.rule);
@@ -179,6 +183,8 @@ dfa_t::dfa_t(const nfa_t &nfa, const charset_t &charset)
                        }
                }
        }
+
+       check_context_selfoverlap(kernels, contexts, line, cond);
 }
 
 dfa_t::~dfa_t()
index f58a0f03409de6b8390a9e476bdd65e47149b5cd..47d14b4f11b214b6ff154d49a4b2343d25d4e4b3 100644 (file)
@@ -3,10 +3,12 @@
 
 #include "src/util/c99_stdint.h"
 #include <vector>
+#include <set>
 
 #include "src/ir/regexp/regexp.h"
 #include "src/parse/rules.h"
 #include "src/util/forbid_copy.h"
+#include "src/util/ord_hash_set.h"
 
 namespace re2c
 {
@@ -18,12 +20,12 @@ struct dfa_state_t
 {
        size_t *arcs;
        RuleInfo *rule;
-       bool ctx;
+       std::set<size_t> ctxs;
 
        dfa_state_t()
                : arcs(NULL)
                , rule(NULL)
-               , ctx(false)
+               , ctxs()
        {}
        ~dfa_state_t()
        {
@@ -39,9 +41,13 @@ struct dfa_t
 
        std::vector<dfa_state_t*> states;
        const size_t nchars;
+       std::vector<CtxVar> &contexts;
 
-       dfa_t(const nfa_t &nfa, const charset_t &charset);
+       dfa_t(const nfa_t &nfa, const charset_t &charset,
+               uint32_t line, const std::string &cond);
        ~dfa_t();
+
+       FORBID_COPY(dfa_t);
 };
 
 enum dfa_minimization_t
@@ -50,9 +56,13 @@ enum dfa_minimization_t
        DFA_MINIMIZATION_MOORE
 };
 
+void check_context_selfoverlap(ord_hash_set_t &kernels,
+       const std::vector<CtxVar> &contexts,
+       uint32_t line, const std::string &cond);
 void minimization(dfa_t &dfa);
 void fillpoints(const dfa_t &dfa, std::vector<size_t> &fill);
 void fallback_states(const dfa_t &dfa, std::vector<size_t> &fallback);
+bool deduplicate_contexts(const dfa_t &dfa, const std::vector<size_t> &fallback);
 
 } // namespace re2c
 
index b15714c2e8a5d11e0a45a9219bf6937bb2e344c2..397691168f6eefce6de6f12103956ac95d2a252b 100644 (file)
@@ -47,7 +47,7 @@ static void minimization_table(
                for (size_t j = 0; j < i; ++j)
                {
                        dfa_state_t *s2 = states[j];
-                       tbl[i][j] = s1->ctx != s2->ctx
+                       tbl[i][j] = s1->ctxs != s2->ctxs
                                || s1->rule != s2->rule;
                }
        }
@@ -135,11 +135,11 @@ static void minimization_moore(
        size_t *next = new size_t[count];
 
        // see note [distinguish states by contexts]
-       std::map<std::pair<const RuleInfo*, bool>, size_t> init;
+       std::map<std::pair<const RuleInfo*, std::set<size_t> >, size_t> init;
        for (size_t i = 0; i < count; ++i)
        {
                dfa_state_t *s = states[i];
-               std::pair<const RuleInfo*, bool> key(s->rule, s->ctx);
+               std::pair<const RuleInfo*, std::set<size_t> > key(s->rule, s->ctxs);
                if (init.insert(std::make_pair(key, i)).second)
                {
                        part[i] = i;
index 1420e634d9c6235f00fb5a652d6a5fb16b358a18..9566fa35f8dac75b207dcf4ab97abbb919eb7a7c 100644 (file)
@@ -6,11 +6,12 @@ namespace re2c {
 static uint32_t calc_size(const RegExp *re);
 static nfa_state_t *compile(const RegExp *re, nfa_t &nfa, nfa_state_t *n);
 
-nfa_t::nfa_t(const RegExp *re)
-       : max_size(calc_size(re))
+nfa_t::nfa_t(Spec &spec)
+       : max_size(calc_size(spec.re))
        , size(0)
        , states(new nfa_state_t[max_size])
-       , root(compile(re, *this, NULL))
+       , contexts(spec.contexts)
+       , root(compile(spec.re, *this, NULL))
 {}
 
 nfa_t::~nfa_t()
@@ -21,7 +22,6 @@ nfa_t::~nfa_t()
 uint32_t calc_size(const RegExp *re)
 {
        switch (re->tag) {
-               default:
                case RegExp::NIL:
                        return 0;
                case RegExp::SYM:
@@ -36,14 +36,12 @@ uint32_t calc_size(const RegExp *re)
                case RegExp::ITER:
                        return calc_size(re->pld.iter.re)
                                + 1;
-               case RegExp::RULE: {
-                       const uint32_t re_size  = calc_size(re->pld.rule.re) + 1;
-                       uint32_t ctx_size = calc_size(re->pld.rule.ctx);
-                       if (ctx_size > 0) {
-                               ctx_size += 1;
-                       }
-                       return re_size + ctx_size;
-               }
+               case RegExp::CTX:
+                       return calc_size(re->pld.ctx.re)
+                               + 1;
+               case RegExp::RULE:
+                       return calc_size(re->pld.rule.re)
+                               + 1;
        }
 }
 
@@ -71,22 +69,16 @@ nfa_state_t *compile(const RegExp *re, nfa_t &nfa, nfa_state_t *t)
                        s = &nfa.states[nfa.size++];
                        s->alt(t, compile(re->pld.iter.re, nfa, s));
                        break;
-               case RegExp::RULE: {
+               case RegExp::CTX:
+                       s = &nfa.states[nfa.size++];
+                       s->ctx(compile(re->pld.ctx.re, nfa, t),
+                               re->pld.ctx.info);
+                       break;
+               case RegExp::RULE:
                        s = &nfa.states[nfa.size++];
-                       RuleInfo *info = re->pld.rule.info;
-                       s->fin(info);
-                       if (info->ctx_len == ~0u) {
-                               // dynamic context
-                               nfa_state_t *q = compile(re->pld.rule.ctx, nfa, s);
-                               s = &nfa.states[nfa.size++];
-                               s->ctx(q);
-                       } else if (info->ctx_len > 0) {
-                               // static context
-                               s = compile(re->pld.rule.ctx, nfa, s);
-                       }
+                       s->fin(re->pld.rule.info);
                        s = compile(re->pld.rule.re, nfa, s);
                        break;
-               }
        }
        return s;
 }
index f2ed08d2141306ccd1026acf91bae17715f28a68..8045609ec0c32847a09f2c64fd18e6a131825448 100644 (file)
@@ -1,8 +1,12 @@
 #ifndef _RE2C_IR_NFA_NFA_
 #define _RE2C_IR_NFA_NFA_
 
+#include <stddef.h>
 #include "src/util/c99_stdint.h"
+#include <vector>
 
+#include "src/parse/rules.h"
+#include "src/parse/spec.h"
 #include "src/util/forbid_copy.h"
 
 namespace re2c
@@ -36,6 +40,7 @@ struct nfa_state_t
                struct
                {
                        nfa_state_t *out;
+                       size_t info;
                } ctx;
                struct
                {
@@ -58,10 +63,11 @@ struct nfa_state_t
                value.ran.ran = r;
                mark = false;
        }
-       void ctx(nfa_state_t *s)
+       void ctx(nfa_state_t *s, size_t i)
        {
                type = CTX;
                value.ctx.out = s;
+               value.ctx.info = i;
                mark = false;
        }
        void fin(RuleInfo *r)
@@ -77,9 +83,10 @@ struct nfa_t
        const uint32_t max_size;
        uint32_t size;
        nfa_state_t *states;
+       std::vector<CtxVar> &contexts;
        nfa_state_t *root;
 
-       nfa_t(const RegExp *re);
+       nfa_t(Spec &spec);
        ~nfa_t();
 
        FORBID_COPY(nfa_t);
index b4087908cb48df12133dc0ad3dca92cb0d19eac9..b4e6a5fcbb7600babcf84f8d526bb8d2328d464d 100644 (file)
@@ -1,3 +1,6 @@
+#include <limits>
+#include <sstream>
+
 #include "src/conf/opt.h"
 #include "src/globals.h"
 #include "src/ir/regexp/regexp.h"
@@ -7,32 +10,155 @@ namespace re2c
 
 static uint32_t fixlen(const RegExp *re);
 static bool nullable(const RegExp *re);
+static const RegExp *copy_rebase(const RegExp *re, size_t shift);
 
-const RegExp *make_rule(const Loc &loc, const RegExp *r1, const RegExp *r2,
-       rule_rank_t rank, const Code *code, const std::string *newcond)
+CtxVar::CtxVar(const std::string *n, rule_rank_t rank)
+       : name(n)
+       , fullname()
 {
-       uint32_t ctx_len = fixlen(r2);
-       // cannot emulate 'YYCURSOR -= N' operation with generic API
-       if (ctx_len != 0
-               && opts->input_api.type() == InputAPI::CUSTOM) {
-               ctx_len = ~0u;
+       std::ostringstream s;
+       s << "yyctx" << rank;
+       if (name != NULL) {
+               s << *name;
+       }
+       fullname = s.str();
+}
+
+CtxFix::CtxFix(const std::string *n, size_t b, size_t d):
+       name(n),
+       base(b),
+       dist(d)
+{}
+
+const size_t CtxFix::RIGHTMOST = std::numeric_limits<size_t>::max();
+
+const RegExp *make_rule(
+       std::vector<CtxVar> &contexts,
+       const Loc &loc,
+       std::pair<std::vector<const RegExp*>, std::vector<std::string*> > *ctxs,
+       rule_rank_t rank,
+       const Code *code,
+       const std::string *newcond)
+{
+       std::vector<const RegExp*> &rs = ctxs->first;
+       std::vector<std::string*> &ctxnames = ctxs->second;
+       const size_t nctxs = ctxnames.size();
+       assert(rs.size() == nctxs + 1);
+
+       std::vector<size_t> dist(nctxs + 1, 0);
+       std::vector<size_t> base(nctxs + 1, nctxs);
+       // right-fix all contexts
+       for (size_t i = nctxs; i > 0; --i) {
+               const size_t fl = fixlen(rs[i]);
+
+               // generic API needs base to restore fixed-length trailing contexts
+               // and base is only guaranteed when non-trailing contexts are enabled
+               const bool lack_api = !opts->contexts // => every context is trailing
+                       && opts->input_api.type() == InputAPI::CUSTOM;
+
+               if (fl == ~0u || lack_api) {
+                       base[i - 1] = i - 1;
+               } else {
+                       base[i - 1] = base[i];
+                       dist[i - 1] = fl;
+                       if (i < nctxs && ctxnames[i] != NULL) {
+                               dist[i - 1] += dist[i];
+                       }
+               }
+       }
+
+       Trail trail;
+
+       std::vector<size_t> base2var(nctxs + 1, CtxFix::RIGHTMOST);
+       std::vector<size_t> ctxvar;
+       const RegExp *r = rs[0];
+       for (size_t i = 0; i < nctxs; ++i) {
+               const RegExp *s = rs[i + 1];
+               if (base[i] == i) {
+                       const std::string *name = ctxnames[i];
+                       const size_t idx = contexts.size();
+                       base2var[i] = idx;
+                       contexts.push_back(CtxVar(name, rank));
+                       if (name != NULL) {
+                               ctxvar.push_back(idx);
+                       } else {
+                               trail.make_var(idx);
+                       }
+                       s = RegExp::ctx(s, idx);
+               }
+               r = RegExp::cat(r, s);
+       }
+
+       std::vector<CtxFix> ctxfix;
+       for (size_t i = 0; i < nctxs; ++i) {
+               if (base[i] != i) {
+                       const std::string *name = ctxnames[i];
+                       if (name != NULL) {
+                               CtxFix ctx(name, base2var[base[i]], dist[i]);
+                               ctxfix.push_back(ctx);
+                       } else {
+                               trail.make_fix(dist[i]);
+                       }
+               }
        }
-       RuleInfo *info = new RuleInfo(loc, rank, code,
-               newcond, ctx_len, nullable(r1));
-       return RegExp::rule(r1, r2, info);
+
+       bool null = nullable(rs[0]);
+       for (size_t i = 0; i < nctxs && null && ctxnames[i] != NULL; ++i) {
+               null = nullable(rs[i + 1]);
+       }
+
+       RuleInfo *info = new RuleInfo(loc, rank, code, newcond, null, ctxvar, ctxfix, trail);
+       r = RegExp::rule(r, info);
+
+       return r;
 }
 
-// Shallow-copy rule's regexps, but deep-copy rule's info.
-// Used to duplicate <*> rules in conditions: different conditions
-// share regexps (regexps are immutable anyway), but must have an
-// individual copy of rule info (rule reachability and shadow set
-// are different). Also update rule rank.
-const RegExp *make_rule_copy(const RegExp *re, rule_rank_t rank)
+const RegExp *make_rule_ctxfree(
+       const Loc &loc,
+       const RegExp *re,
+       rule_rank_t rank,
+       const Code *code,
+       const std::string *newcond)
 {
-       const RuleInfo *info = re->pld.rule.info;
-       RuleInfo *info_copy = new RuleInfo(info->loc, rank, info->code,
-               &info->newcond, info->ctx_len, info->nullable);
-       return RegExp::rule(re->pld.rule.re, re->pld.rule.ctx, info_copy);
+       RuleInfo *info = new RuleInfo(loc, rank, code, newcond, nullable(re),
+               std::vector<size_t>(), std::vector<CtxFix>(), Trail());
+       return RegExp::rule(re, info);
+}
+
+// Used to duplicate <*> rules in conditions.
+// Duplicates part of regexp containing contexts that must be fixed
+// (the rest of regexp is shared: it's immutable anyway).
+// Duplicates rule info (rule reachability and shadow set differ for
+// different specs, rule rank must be updated).
+const RegExp *make_rule_copy(const RegExp *re, rule_rank_t rank, size_t shift)
+{
+       return RegExp::rule(
+               copy_rebase(re->pld.rule.re, shift),
+               RuleInfo::copy_rebase(re->pld.rule.info, rank, shift));
+}
+
+const RegExp *copy_rebase(const RegExp *re, size_t shift)
+{
+       const RegExp *r = re;
+       switch (re->tag) {
+               case RegExp::CAT:
+                       r = RegExp::cat(
+                               copy_rebase(re->pld.cat.re1, shift),
+                               copy_rebase(re->pld.cat.re2, shift));
+                       break;
+               case RegExp::CTX:
+                       r = RegExp::ctx(
+                               copy_rebase(re->pld.ctx.re, shift),
+                               re->pld.ctx.info + shift);
+                       break;
+               case RegExp::NIL:
+               case RegExp::SYM:
+               case RegExp::ALT:
+               case RegExp::ITER:
+               case RegExp::RULE:
+                       break;
+       }
+       return r;
 }
 
 uint32_t fixlen(const RegExp *re)
@@ -42,14 +168,12 @@ uint32_t fixlen(const RegExp *re)
                        return 0;
                case RegExp::SYM:
                        return 1;
-               case RegExp::ALT:
-               {
+               case RegExp::ALT: {
                        const uint32_t l1 = fixlen(re->pld.alt.re1);
                        const uint32_t l2 = fixlen(re->pld.alt.re2);
                        return l1 == l2 ? l1 : ~0u;
                }
-               case RegExp::CAT:
-               {
+               case RegExp::CAT: {
                        const uint32_t l1 = fixlen(re->pld.cat.re1);
                        if (l1 == ~0u) {
                                return ~0u;
@@ -60,9 +184,10 @@ uint32_t fixlen(const RegExp *re)
                        }
                        return l1 + l2;
                }
+               case RegExp::CTX:
+                       return fixlen(re->pld.ctx.re);
                case RegExp::ITER:
                case RegExp::RULE:
-               default:
                        return ~0u;
        }
 }
@@ -70,7 +195,6 @@ uint32_t fixlen(const RegExp *re)
 bool nullable(const RegExp *re)
 {
        switch (re->tag) {
-               default:
                case RegExp::NIL:
                        return true;
                case RegExp::SYM:
@@ -83,8 +207,10 @@ bool nullable(const RegExp *re)
                                && nullable(re->pld.cat.re2);
                case RegExp::ITER:
                        return true;
+               case RegExp::CTX:
                case RegExp::RULE:
-                       return nullable(re->pld.rule.re);
+                       assert(false);
+                       return false;
        }
 }
 
index 542aa7295fcf8dc15522c5ee6e8a943a64c6d92d..f310d2b7c6a7e582d76be4ebf67559abdb2e06b6 100644 (file)
@@ -26,6 +26,7 @@ struct RegExp
                ALT,
                CAT,
                ITER,
+               CTX,
                RULE
        };
        union payload_t
@@ -51,7 +52,11 @@ struct RegExp
                struct
                {
                        const RegExp *re;
-                       const RegExp *ctx;
+                       size_t info;
+               } ctx;
+               struct
+               {
+                       const RegExp *re;
                        RuleInfo *info;
                } rule;
        };
@@ -91,11 +96,17 @@ struct RegExp
                re->pld.iter.re = r;
                return re;
        }
-       static const RegExp *rule(const RegExp *r1, const RegExp *r2, RuleInfo *i)
+       static const RegExp *ctx(const RegExp *r, size_t i)
+       {
+               RegExp *re = new RegExp(CTX);
+               re->pld.ctx.re = r;
+               re->pld.ctx.info = i;
+               return re;
+       }
+       static const RegExp *rule(const RegExp *r, RuleInfo *i)
        {
                RegExp *re = new RegExp(RULE);
-               re->pld.rule.re = r1;
-               re->pld.rule.ctx = r2;
+               re->pld.rule.re = r;
                re->pld.rule.info = i;
                return re;
        }
index 8056085bd3ad5c81a7527ffb4e3f45f07e615b18..b43fd7d99308783f3606209a5706cffa240f31e7 100644 (file)
@@ -28,9 +28,11 @@ void split(const RegExp* re, std::set<uint32_t> &cs)
                case RegExp::ITER:
                        split(re->pld.iter.re, cs);
                        break;
+               case RegExp::CTX:
+                       split(re->pld.ctx.re, cs);
+                       break;
                case RegExp::RULE:
-                       split(re->pld.rule.re,  cs);
-                       split(re->pld.rule.ctx, cs);
+                       split(re->pld.rule.re, cs);
                        break;
        }
 }
index 1b38f2867a3cf22a3b89e39ef7d8c6643334928d..347f411e00d634e7e9726592f6d4d0ff1f70eced 100644 (file)
@@ -94,7 +94,8 @@ void emit_prolog(OutputFile &o)
 }
 
 void emit_start(const Skeleton &skel, OutputFile &o, size_t maxfill,
-       bool backup, bool backupctx, bool accept)
+       bool backup, bool backupctx, bool accept, bool base_ctxmarker,
+       const std::set<std::string> &ctxnames)
 {
        const size_t
                sizeof_cunit = opts->encoding.szCodeUnit(),
@@ -114,7 +115,13 @@ void emit_start(const Skeleton &skel, OutputFile &o, size_t maxfill,
        }
        if (backupctx) {
                o.ws("\n#define YYBACKUPCTX() ctxmarker = cursor");
-               o.ws("\n#define YYRESTORECTX() cursor = ctxmarker");
+               if(base_ctxmarker) {
+                       o.ws("\n#define YYRESTORECTX(dist) cursor = ctxmarker + dist");
+                       o.ws("\n#define YYDIST() (cursor - ctxmarker)");
+                       o.ws("\n#define YYDISTTYPE long");
+               } else {
+                       o.ws("\n#define YYRESTORECTX() cursor = ctxmarker");
+               }
        }
        o.ws("\n#define YYLESSTHAN(n) (limit - cursor) < n");
        o.ws("\n#define YYFILL(n) { break; }");
@@ -226,6 +233,10 @@ void emit_start(const Skeleton &skel, OutputFile &o, size_t maxfill,
        if (accept) {
                o.ws("\n").wind(2).ws("unsigned int yyaccept = 0;");
        }
+       if (!ctxnames.empty()) {
+               o.ws("\n");
+               output_contexts(o.stream(), 2, ctxnames);
+       }
        o.ws("\n");
        if (opts->bFlag && BitMap::first) {
                BitMap::gen(o, 2, 0, std::min(0x100u, opts->encoding.nCodeUnits()));
index 6aa734a9d04545aa2f32b2e548e5eb9913c90bae..8268c9e6a1089db2718f6655aa5fabbd4957ecfb 100644 (file)
@@ -49,19 +49,24 @@ public:
                        if (rule == NULL) {
                                continue;
                        }
-                       const size_t len = static_cast<size_t>(head - tail) - 1;
-                       switch (rule->ctx_len) {
-                               case 0:
+                       size_t len = static_cast<size_t>(head - tail) - 1;
+
+                       switch (rule->trail.type) {
+                               case Trail::NONE:
                                        return len;
-                               case ~0u:
+                               case Trail::FIX:
+                                       return len - rule->trail.pld.fix;
+                               case Trail::VAR: {
+                                       const size_t ctx = rule->trail.pld.var;
                                        for (; tail != head; ++tail) {
-                                               if (skel.nodes[*tail].ctx) {
+                                               std::set<size_t> &ctxs = skel.nodes[*tail].ctxs;
+                                               if (ctxs.find(ctx) != ctxs.end()) {
                                                        return static_cast<size_t>(head - tail) - 1;
                                                }
                                        }
                                        assert(false);
-                               default:
-                                       return len - rule->ctx_len;
+                                       break;
+                               }
                        }
                }
                return 0;
index 3486e57805d69a13536bc636b40d001dcf1978e2..8fbd5963eb616d60a64290e08123ef1b434b2ab5 100644 (file)
@@ -11,16 +11,16 @@ Node::Node() :
        arcs(),
        arcsets(),
        rule(NULL),
-       ctx(false)
+       ctxs()
 {}
 
 void Node::init(
-       bool c,
+       const std::set<size_t> &cs,
        RuleInfo *r,
        const std::vector<std::pair<size_t, uint32_t> > &a)
 {
        rule = r;
-       ctx = c;
+       ctxs = cs;
 
        uint32_t lb = 0;
        std::vector<std::pair<size_t, uint32_t> >::const_iterator
@@ -64,7 +64,8 @@ Skeleton::Skeleton(
                nodes_count(dfa.states.size() + 1), // +1 for default state
                nodes(new Node[nodes_count]),
                sizeof_key(4),
-               rules(rs)
+               rules(rs),
+               contexts(dfa.contexts)
 {
        const size_t nc = cs.size() - 1;
 
@@ -84,7 +85,7 @@ Skeleton::Skeleton(
                if (arcs.size() == 1 && arcs[0].first == nodes_count - 1) {
                        arcs.clear();
                }
-               nodes[i].init(s->ctx, s->rule, arcs);
+               nodes[i].init(s->ctxs, s->rule, arcs);
        }
 
        const uint32_t maxlen = maxpath(*this);
index 9e5002735852cb085f3f1c230c5cc05718f3bf72..1e00724475b7991a6ec9458e38d5da4b5528ae5b 100644 (file)
@@ -35,10 +35,10 @@ struct Node
        arcs_t arcs;
        arcsets_t arcsets;
        RuleInfo *rule;
-       bool ctx;
+       std::set<size_t> ctxs;
 
        Node();
-       void init(bool b, RuleInfo *r,
+       void init(const std::set<size_t> &cs, RuleInfo *r,
                const std::vector<std::pair<size_t, uint32_t> > &arcs);
        bool end() const;
 
@@ -56,6 +56,7 @@ struct Skeleton
 
        size_t sizeof_key;
        rules_t rules;
+       std::vector<CtxVar> &contexts;
 
        Skeleton(const dfa_t &dfa, const charset_t &cs, const rules_t &rs,
                const std::string &dfa_name, const std::string &dfa_cond,
@@ -86,7 +87,8 @@ void warn_unreachable_nullable_rules(const Skeleton &skel);
 void emit_data(const Skeleton &skel, const char *fname);
 void emit_prolog(OutputFile & o);
 void emit_start(const Skeleton &skel, OutputFile &o, size_t maxfill,
-       bool backup, bool backupctx, bool accept);
+       bool backup, bool backupctx, bool accept, bool base_ctxmarker,
+       const std::set<std::string> &ctxnames);
 void emit_end(const Skeleton &skel, OutputFile &o, bool backup, bool backupctx);
 void emit_epilog(OutputFile &o, const std::set<std::string> &names);
 void emit_action(const Skeleton &skel, OutputFile &o, uint32_t ind,
index 93602175b4d02246dad75aae560595ccd604f326..a4904179dcb503e002c4b4e85b6fab7ebc88c07a 100644 (file)
@@ -271,6 +271,12 @@ start:
        "<!"            {
                                        return TOKEN_SETUP;
                                }
+
+       "@" name {
+               yylval.str = new std::string(tok + 1, tok_len() - 1);
+               return TOKEN_CTX;
+       }
+
        [<>,()|=;/\\]   {
                                        return *tok;
                                }
index f48bd568d63af107f529421d4d9492dc016b83da..dcca10056ed7336abd0c33899b14dbb648f0184c 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef _RE2C_PARSE_PARSER_
 #define _RE2C_PARSE_PARSER_
 
-#include <list>
 #include <map>
 #include <string>
 
@@ -15,16 +14,19 @@ namespace re2c
 
 extern void parse(Scanner &, Output &);
 extern void parse_cleanup();
-const RegExp *make_rule(const Loc &loc, const RegExp *r1, const RegExp *r2,
+const RegExp *make_rule(std::vector<CtxVar> &contexts, const Loc &loc,
+       std::pair<std::vector<const RegExp*>, std::vector<std::string*> > *ctxs,
        rule_rank_t rank, const Code *code, const std::string *newcond);
-const RegExp *make_rule_copy(const RegExp *re, rule_rank_t rank);
+const RegExp *make_rule_ctxfree(const Loc &loc, const RegExp *re,
+       rule_rank_t rank, const Code *code, const std::string *newcond);
+const RegExp *make_rule_copy(const RegExp *re, rule_rank_t rank, size_t shift);
 
 typedef std::set<std::string> CondList;
-typedef std::list<const RegExp*> RuleList;
 typedef std::map<std::string, Spec> SpecMap;
 typedef std::map<std::string, std::pair<uint32_t, std::string> > SetupMap;
 typedef std::map<std::string, const Code *> DefaultMap;
 typedef std::map<std::string, const RegExp *> symbol_table_t;
+typedef std::pair<std::vector<const RegExp*>, std::vector<std::string*> > zzz_t;
 
 } // namespace re2c
 
index 8db2c44a7c76c0b3a872c5bab3bd4b3b9bb1ac5c..6eac39535464291f1bb195289d0c66083ed3e8e6 100644 (file)
@@ -49,13 +49,14 @@ static std::vector<std::string> condnames;
 static re2c::SpecMap  specMap;
 static Spec spec;
 static const RegExp *specNone = NULL;
-static RuleList       specStar;
+static SpecStar specStar;
 static const RegExp *star_default = NULL;
 static Scanner          *in = NULL;
 static Scanner::ParseMode  parseMode;
 static SetupMap            ruleSetupMap;
 static bool                foundRules;
 static symbol_table_t symbol_table;
+static zzz_t ctxs;
 
 /* Bison version 1.875 emits a definition that is not working
  * with several g++ version. Hence we disable it here.
@@ -83,8 +84,7 @@ void context_none(CondList *clist)
 void context_rule
        ( CondList * clist
        , const Loc & loc
-       , const RegExp * expr
-       , const RegExp * look
+       , std::pair<std::vector<const RegExp*>, std::vector<std::string*> > * expr
        , const Code * code
        , const std::string * newcond
        )
@@ -98,9 +98,9 @@ void context_rule
                }
 
                const RegExp *rule = make_rule
-                       ( loc
+                       ( specMap[*it].contexts
+                       , loc
                        , expr
-                       , look
                        , rank_counter.next ()
                        , code
                        , newcond
@@ -134,10 +134,9 @@ void default_rule(CondList *clist, const Code * code)
        context_check(clist);
        for(CondList::const_iterator it = clist->begin(); it != clist->end(); ++it)
        {
-               const RegExp * def = make_rule
+               const RegExp * def = make_rule_ctxfree
                        ( code->loc
                        , in->mkDefault ()
-                       , RegExp::nil()
                        , rule_rank_t::def ()
                        , code
                        , NULL
@@ -161,12 +160,14 @@ void default_rule(CondList *clist, const Code * code)
        re2c::ExtOp extop;
        std::string * str;
        re2c::CondList * clist;
+       re2c::zzz_t *ctxs;
 };
 
 %token TOKEN_CLOSE
 %token TOKEN_CLOSESIZE
 %token TOKEN_CODE
 %token TOKEN_CONF
+%token TOKEN_CTX
 %token TOKEN_ID
 %token TOKEN_FID
 %token TOKEN_FID_END
@@ -179,8 +180,9 @@ void default_rule(CondList *clist, const Code * code)
 %type <extop>   TOKEN_CLOSESIZE
 %type <code>    TOKEN_CODE
 %type <regexp>  TOKEN_REGEXP rule look expr diff term factor primary
-%type <str>     TOKEN_ID TOKEN_FID newcond
+%type <str>     TOKEN_ID TOKEN_FID TOKEN_CTX newcond
 %type <clist>   cond clist
+%type <ctxs>    ctxexpr trailexpr
 
 %%
 
@@ -224,18 +226,18 @@ decl:
 ;
 
 rule:
-               expr look TOKEN_CODE
+               trailexpr TOKEN_CODE
                {
                        if (opts->cFlag)
                        {
                                in->fatal("condition or '<*>' required when using -c switch");
                        }
                        const RegExp * rule = make_rule
-                               ( $3->loc
+                               ( spec.contexts
+                               , $2->loc
                                , $1
-                               , $2
                                , rank_counter.next ()
-                               , $3
+                               , $2
                                , NULL
                                );
                        spec.add (rule);
@@ -244,10 +246,9 @@ rule:
                {
                        if (opts->cFlag)
                                in->fatal("condition or '<*>' required when using -c switch");
-                       const RegExp * def = make_rule
+                       const RegExp * def = make_rule_ctxfree
                                ( $2->loc
                                , in->mkDefault ()
-                               , RegExp::nil()
                                , rule_rank_t::def ()
                                , $2
                                , NULL
@@ -257,15 +258,15 @@ rule:
                                in->fatal("code to default rule is already defined");
                        }
                }
-       |       '<' cond '>' expr look newcond TOKEN_CODE
+       |       '<' cond '>' trailexpr newcond TOKEN_CODE
                {
-                       context_rule ($2, $7->loc, $4, $5, $7, $6);
+                       context_rule ($2, $6->loc, $4, $6, $5);
                }
-       |       '<' cond '>' expr look ':' newcond
+       |       '<' cond '>' trailexpr ':' newcond
                {
-                       assert($7);
+                       assert($6);
                        Loc loc (in->get_fname (), in->get_cline ());
-                       context_rule ($2, loc, $4, $5, NULL, $7);
+                       context_rule ($2, loc, $4, NULL, $6);
                }
        |       '<' cond '>' look newcond TOKEN_CODE
                {
@@ -282,35 +283,35 @@ rule:
                {
                        default_rule($2, $5);
                }
-       |       '<' TOKEN_STAR '>' expr look newcond TOKEN_CODE
+       |       '<' TOKEN_STAR '>' trailexpr newcond TOKEN_CODE
                {
                        context_check(NULL);
                        const RegExp * rule = make_rule
-                               ( $7->loc
+                               ( specStar.contexts
+                               , $6->loc
                                , $4
-                               , $5
                                , rank_counter.next ()
-                               , $7
                                , $6
+                               , $5
                                );
-                       specStar.push_back (rule);
-                       delete $6;
+                       specStar.rules.push_back (rule);
+                       delete $5;
                }
-       |       '<' TOKEN_STAR '>' expr look ':' newcond
+       |       '<' TOKEN_STAR '>' trailexpr ':' newcond
                {
-                       assert($7);
+                       assert($6);
                        context_check(NULL);
                        Loc loc (in->get_fname (), in->get_cline ());
                        const RegExp * rule = make_rule
-                               ( loc
+                               ( specStar.contexts
+                               , loc
                                , $4
-                               , $5
                                , rank_counter.next ()
                                , NULL
-                               , $7
+                               , $6
                                );
-                       specStar.push_back (rule);
-                       delete $7;
+                       specStar.rules.push_back (rule);
+                       delete $6;
                }
        |       '<' TOKEN_STAR '>' look newcond TOKEN_CODE
                {
@@ -329,10 +330,9 @@ rule:
                        {
                                in->fatal ("code to default rule '*' is already defined");
                        }
-                       star_default = make_rule
+                       star_default = make_rule_ctxfree
                                ( $5->loc
                                , in->mkDefault ()
-                               , RegExp::nil()
                                , rule_rank_t::def ()
                                , $5
                                , NULL
@@ -345,10 +345,9 @@ rule:
                        {
                                in->fatal("code to handle illegal condition already defined");
                        }
-                       $$ = specNone = make_rule
+                       $$ = specNone = make_rule_ctxfree
                                ( $3->loc
                                , RegExp::nil()
-                               , RegExp::nil()
                                , rank_counter.next ()
                                , $3
                                , $2
@@ -364,10 +363,9 @@ rule:
                                in->fatal("code to handle illegal condition already defined");
                        }
                        Loc loc (in->get_fname (), in->get_cline ());
-                       $$ = specNone = make_rule
+                       $$ = specNone = make_rule_ctxfree
                                ( loc
                                , RegExp::nil()
-                               , RegExp::nil()
                                , rank_counter.next ()
                                , NULL
                                , $3
@@ -423,6 +421,33 @@ newcond:
                }
 ;
 
+trailexpr:
+       ctxexpr {
+               $$ = $1;
+       } | ctxexpr '/' expr {
+               // multiple trailing contexts on the same rule are not allowed
+               $$ = $1;
+               $$->first.push_back($3);
+               $$->second.push_back(NULL);
+       };
+
+ctxexpr:
+       expr {
+               ctxs.first.clear();
+               ctxs.second.clear();
+               $$ = &ctxs;
+               $$->first.push_back($1);
+       } | ctxexpr TOKEN_CTX expr {
+               if (!opts->contexts) {
+                       delete $2;
+                       in->fatal("non-trailing contexts are only allowed"
+                               " with '-C, --contexts' option");
+               }
+               $$ = $1;
+               $$->first.push_back($3);
+               $$->second.push_back($2);
+       };
+
 look:
                /* empty */
                {
@@ -572,7 +597,7 @@ void parse(Scanner& i, Output & o)
                .wline_info (in->get_cline (), in->get_fname ().c_str ());
        if (opts->target == opt_t::SKELETON)
        {
-               emit_prolog(o.source);
+               emit_prolog (o.source);
        }
 
        Enc encodingOld = opts->encoding;
@@ -647,9 +672,13 @@ void parse(Scanner& i, Output & o)
                                // merge <*> rules to all conditions with lowest priority
                                for (it = specMap.begin(); it != specMap.end(); ++it)
                                {
-                                       for (RuleList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp)
-                                       {
-                                               it->second.add(make_rule_copy(*itOp, rank_counter.next()));
+                                       const size_t shift = it->second.contexts.size();
+                                       it->second.contexts.insert(it->second.contexts.end(), specStar.contexts.begin(), specStar.contexts.end());
+                                       std::vector<const RegExp*>::const_iterator
+                                               star = specStar.rules.begin(),
+                                               star_end = specStar.rules.end();
+                                       for (; star != star_end; ++star) {
+                                               it->second.add(make_rule_copy(*star, rank_counter.next(), shift));
                                        }
                                        if (star_default)
                                        {
@@ -741,7 +770,7 @@ void parse(Scanner& i, Output & o)
 
        if (opts->target == opt_t::SKELETON)
        {
-               emit_epilog(o.source, o.skeletons);
+               emit_epilog (o.source, o.skeletons);
        }
 
        parse_cleanup();
index ce6f69f10c56103b2384b655a32ca9046cd71193..414bf8d141667bbcf9a68629ee3e03d5b3ef22cd 100644 (file)
 namespace re2c
 {
 
+struct CtxVar
+{
+       const std::string *name;
+       std::string fullname;
+
+       CtxVar(const std::string *n, rule_rank_t rank);
+       CtxVar(const CtxVar &ctx):
+               name(ctx.name),
+               fullname(ctx.fullname)
+       {}
+       CtxVar& operator=(const CtxVar &ctx)
+       {
+               name = ctx.name;
+               fullname = ctx.fullname;
+               return *this;
+       }
+};
+
+struct CtxFix
+{
+       static const size_t RIGHTMOST;
+
+       const std::string *name;
+       size_t base;
+       size_t dist;
+
+       CtxFix(const std::string *n, size_t b, size_t d);
+};
+
+struct Trail
+{
+       enum {NONE, VAR, FIX} type;
+       union
+       {
+               size_t var;
+               size_t fix; // trailing context must be the rightmost; no need for base
+       } pld;
+
+       Trail(): type(NONE), pld() {}
+       void make_var(size_t v)
+       {
+               type = VAR;
+               pld.var = v;
+       }
+       void make_fix(size_t f)
+       {
+               type = FIX;
+               pld.fix = f;
+       }
+};
+
 struct RuleInfo
 {
        const Loc loc;
 
-       // ~0u      - dynamic length
-       // (0; ~0u) - static length
-       // 0        - no context
-       uint32_t ctx_len;
+       std::vector<size_t> ctxvar;
+       std::vector<CtxFix> ctxfix;
+       Trail trail;
 
        rule_rank_t rank;
        const Code *code;
@@ -36,11 +86,15 @@ struct RuleInfo
                , rule_rank_t r
                , const Code * c
                , const std::string * cond
-               , uint32_t cl
                , bool nl
+               , const std::vector<size_t> &ctxv
+               , const std::vector<CtxFix> &ctxf
+               , const Trail &tr
                )
                : loc (l)
-               , ctx_len (cl)
+               , ctxvar (ctxv)
+               , ctxfix (ctxf)
+               , trail (tr)
                , rank (r)
                , code (c)
                , newcond (cond ? *cond : "")
@@ -49,6 +103,20 @@ struct RuleInfo
                , nullable (nl)
        {}
 
+       static RuleInfo *copy_rebase(const RuleInfo *rule, rule_rank_t rank, size_t shift)
+       {
+               RuleInfo *r = new RuleInfo(rule->loc, rank,
+                       rule->code, &rule->newcond, rule->nullable,
+                       rule->ctxvar, rule->ctxfix, rule->trail);
+               for (size_t i = 0; i < r->ctxvar.size(); ++i) {
+                       r->ctxvar[i] += shift;
+               }
+               if (r->trail.type == Trail::VAR) {
+                       r->trail.pld.var += shift;
+               }
+               return r;
+       }
+
        FORBID_COPY(RuleInfo);
 };
 
index 88d8ceede9856d9844bbe573024628f0f5969786..6bdd0fccc73cbd3c907941371c178c2397a8df91 100644 (file)
@@ -19,21 +19,18 @@ struct Spec
 {
        const RegExp * re;
        rules_t rules;
+       std::vector<CtxVar> contexts;
 
        Spec ()
                : re (NULL)
                , rules ()
+               , contexts ()
        {}
        Spec (const Spec & spec)
                : re (spec.re)
                , rules (spec.rules)
+               , contexts (spec.contexts)
        {}
-       Spec & operator = (const Spec & spec)
-       {
-               re = spec.re;
-               rules = spec.rules;
-               return *this;
-       }
        bool add_def (const RegExp * r)
        {
                if (std::find_if(rules.begin(), rules.end(), is_def) != rules.end())
@@ -55,6 +52,23 @@ struct Spec
        {
                re = NULL;
                rules.clear ();
+               contexts.clear();
+       }
+
+private:
+       Spec& operator=(const Spec&);
+};
+
+struct SpecStar
+{
+       std::vector<const RegExp*> rules;
+       std::vector<CtxVar> contexts;
+
+       SpecStar(): rules(), contexts() {}
+       void clear()
+       {
+               rules.clear();
+               contexts.clear();
        }
 };
 
diff --git a/re2c/src/util/intersect_sorted.h b/re2c/src/util/intersect_sorted.h
new file mode 100644 (file)
index 0000000..245a837
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _RE2C_UTIL_INTERSECT_SORTED_
+#define _RE2C_UTIL_INTERSECT_SORTED_
+
+namespace re2c {
+
+// test intersection of two sorted ranges
+template<class InputIterator1, class InputIterator2>
+bool intersect_sorted(
+       InputIterator1 first1, InputIterator1 last1,
+       InputIterator2 first2, InputIterator2 last2)
+{
+       for (;first1 != last1 && first2 != last2;) {
+               if (*first2 < *first1) {
+                       ++first2;
+               } else if (*first1 < *first2) {
+                       ++first1;
+               } else {
+                       return true;
+               }
+       }
+       return false;
+}
+
+} // namespace re2c
+
+#endif // _RE2C_UTIL_INTERSECT_
+
diff --git a/re2c/test/contexts/cond_star0.ci--input(custom).c b/re2c/test/contexts/cond_star0.ci--input(custom).c
new file mode 100644 (file)
index 0000000..ee92c6a
--- /dev/null
@@ -0,0 +1,59 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx1;
+       YYBACKUPCTX ();
+       switch (YYGETCONDITION()) {
+       case yycc1: goto yyc_c1;
+       }
+/* *********************************** */
+yyc_c1:
+       if (YYLESSTHAN (3)) YYFILL(3);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'a':       goto yy5;
+       default:        goto yy3;
+       }
+yy3:
+       YYSKIP ();
+       {}
+yy5:
+       YYSKIP ();
+       yyctx1 = YYDIST();
+       switch ((yych = YYPEEK ())) {
+       case 'b':       goto yy7;
+       default:        goto yy6;
+       }
+yy6:
+       YYRESTORECTX (yyctx1);
+       {}
+yy7:
+       YYSKIP ();
+       yyctx0 = YYDIST();
+       switch ((yych = YYPEEK ())) {
+       case 'b':       goto yy9;
+       case 'c':       goto yy11;
+       default:        goto yy8;
+       }
+yy8:
+       YYRESTORECTX (yyctx0);
+       {}
+yy9:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'b':       goto yy9;
+       default:        goto yy6;
+       }
+yy11:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'c':       goto yy11;
+       default:        goto yy8;
+       }
+}
+
diff --git a/re2c/test/contexts/cond_star0.ci--input(custom).re b/re2c/test/contexts/cond_star0.ci--input(custom).re
new file mode 100644 (file)
index 0000000..7083f47
--- /dev/null
@@ -0,0 +1,8 @@
+/*!re2c
+
+    <c1> "ab" / "c"* {}
+
+    <*> "a"  / "b"* {}
+    <*> * {}
+
+*/
diff --git a/re2c/test/contexts/cond_star0.ci.c b/re2c/test/contexts/cond_star0.ci.c
new file mode 100644 (file)
index 0000000..eab8942
--- /dev/null
@@ -0,0 +1,59 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx1;
+       YYCTXMARKER = YYCURSOR;
+       switch (YYGETCONDITION()) {
+       case yycc1: goto yyc_c1;
+       }
+/* *********************************** */
+yyc_c1:
+       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy5;
+       default:        goto yy3;
+       }
+yy3:
+       ++YYCURSOR;
+       {}
+yy5:
+       ++YYCURSOR;
+       yyctx1 = (YYCURSOR - YYCTXMARKER);
+       switch ((yych = *YYCURSOR)) {
+       case 'b':       goto yy7;
+       default:        goto yy6;
+       }
+yy6:
+       YYCURSOR = YYCTXMARKER + yyctx1;
+       {}
+yy7:
+       ++YYCURSOR;
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch ((yych = *YYCURSOR)) {
+       case 'b':       goto yy9;
+       case 'c':       goto yy11;
+       default:        goto yy8;
+       }
+yy8:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy9:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy9;
+       default:        goto yy6;
+       }
+yy11:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy11;
+       default:        goto yy8;
+       }
+}
+
diff --git a/re2c/test/contexts/cond_star0.ci.re b/re2c/test/contexts/cond_star0.ci.re
new file mode 100644 (file)
index 0000000..7083f47
--- /dev/null
@@ -0,0 +1,8 @@
+/*!re2c
+
+    <c1> "ab" / "c"* {}
+
+    <*> "a"  / "b"* {}
+    <*> * {}
+
+*/
diff --git a/re2c/test/contexts/cond_star1.ci--input(custom).c b/re2c/test/contexts/cond_star1.ci--input(custom).c
new file mode 100644 (file)
index 0000000..b271bea
--- /dev/null
@@ -0,0 +1,101 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx2;
+       YYBACKUPCTX ();
+       switch (YYGETCONDITION()) {
+       case yycc1: goto yyc_c1;
+       case yycc2: goto yyc_c2;
+       }
+/* *********************************** */
+yyc_c1:
+       if (YYLESSTHAN (3)) YYFILL(3);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'a':       goto yy5;
+       default:        goto yy3;
+       }
+yy3:
+       YYSKIP ();
+       {}
+yy5:
+       YYSKIP ();
+       yyctx2 = YYDIST();
+       switch ((yych = YYPEEK ())) {
+       case 'b':       goto yy7;
+       default:        goto yy6;
+       }
+yy6:
+       YYRESTORECTX (yyctx2);
+       {}
+yy7:
+       YYSKIP ();
+       yyctx0 = YYDIST();
+       switch ((yych = YYPEEK ())) {
+       case 'b':       goto yy9;
+       case 'c':       goto yy11;
+       default:        goto yy8;
+       }
+yy8:
+       YYRESTORECTX (yyctx0);
+       {}
+yy9:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'b':       goto yy9;
+       default:        goto yy6;
+       }
+yy11:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'c':       goto yy11;
+       default:        goto yy8;
+       }
+/* *********************************** */
+yyc_c2:
+       if (YYLESSTHAN (2)) YYFILL(2);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'a':       goto yy17;
+       default:        goto yy15;
+       }
+yy15:
+       YYSKIP ();
+       {}
+yy17:
+       YYSKIP ();
+       YYBACKUPCTX ();
+       switch ((yych = YYPEEK ())) {
+       case 'b':       goto yy19;
+       case 'c':       goto yy22;
+       default:        goto yy18;
+       }
+yy18:
+       YYRESTORECTX ();
+       {}
+yy19:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'b':       goto yy19;
+       default:        goto yy21;
+       }
+yy21:
+       YYRESTORECTX ();
+       {}
+yy22:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'c':       goto yy22;
+       default:        goto yy18;
+       }
+}
+
diff --git a/re2c/test/contexts/cond_star1.ci--input(custom).re b/re2c/test/contexts/cond_star1.ci--input(custom).re
new file mode 100644 (file)
index 0000000..63b3f95
--- /dev/null
@@ -0,0 +1,10 @@
+/*!re2c
+
+    <c1> "ab" / "c"* {}
+
+    <c2> "a" / "c"* {}
+
+    <*> "a"  / "b"* {}
+    <*> * {}
+
+*/
diff --git a/re2c/test/contexts/cond_star1.ci.c b/re2c/test/contexts/cond_star1.ci.c
new file mode 100644 (file)
index 0000000..86316d6
--- /dev/null
@@ -0,0 +1,101 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx2;
+       YYCTXMARKER = YYCURSOR;
+       switch (YYGETCONDITION()) {
+       case yycc1: goto yyc_c1;
+       case yycc2: goto yyc_c2;
+       }
+/* *********************************** */
+yyc_c1:
+       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy5;
+       default:        goto yy3;
+       }
+yy3:
+       ++YYCURSOR;
+       {}
+yy5:
+       ++YYCURSOR;
+       yyctx2 = (YYCURSOR - YYCTXMARKER);
+       switch ((yych = *YYCURSOR)) {
+       case 'b':       goto yy7;
+       default:        goto yy6;
+       }
+yy6:
+       YYCURSOR = YYCTXMARKER + yyctx2;
+       {}
+yy7:
+       ++YYCURSOR;
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch ((yych = *YYCURSOR)) {
+       case 'b':       goto yy9;
+       case 'c':       goto yy11;
+       default:        goto yy8;
+       }
+yy8:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy9:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy9;
+       default:        goto yy6;
+       }
+yy11:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy11;
+       default:        goto yy8;
+       }
+/* *********************************** */
+yyc_c2:
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy17;
+       default:        goto yy15;
+       }
+yy15:
+       ++YYCURSOR;
+       {}
+yy17:
+       ++YYCURSOR;
+       YYCTXMARKER = YYCURSOR;
+       switch ((yych = *YYCURSOR)) {
+       case 'b':       goto yy19;
+       case 'c':       goto yy22;
+       default:        goto yy18;
+       }
+yy18:
+       YYCURSOR = YYCTXMARKER;
+       {}
+yy19:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy19;
+       default:        goto yy21;
+       }
+yy21:
+       YYCURSOR = YYCTXMARKER;
+       {}
+yy22:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy22;
+       default:        goto yy18;
+       }
+}
+
diff --git a/re2c/test/contexts/cond_star1.ci.re b/re2c/test/contexts/cond_star1.ci.re
new file mode 100644 (file)
index 0000000..63b3f95
--- /dev/null
@@ -0,0 +1,10 @@
+/*!re2c
+
+    <c1> "ab" / "c"* {}
+
+    <c2> "a" / "c"* {}
+
+    <*> "a"  / "b"* {}
+    <*> * {}
+
+*/
diff --git a/re2c/test/contexts/cond_star2.ci.c b/re2c/test/contexts/cond_star2.ci.c
new file mode 100644 (file)
index 0000000..e17eb94
--- /dev/null
@@ -0,0 +1,150 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx1, yyctx4, yyctx6;
+       YYCTXMARKER = YYCURSOR;
+       switch (YYGETCONDITION()) {
+       case yycc1: goto yyc_c1;
+       case yycc2: goto yyc_c2;
+       }
+/* *********************************** */
+yyc_c1:
+       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy5;
+       default:        goto yy3;
+       }
+yy3:
+       ++YYCURSOR;
+       {}
+yy5:
+       ++YYCURSOR;
+       yyctx6 = (YYCURSOR - YYCTXMARKER);
+       switch ((yych = *YYCURSOR)) {
+       case 'b':       goto yy7;
+       default:        goto yy6;
+       }
+yy6:
+       YYCURSOR = YYCTXMARKER + yyctx6;
+       {}
+yy7:
+       ++YYCURSOR;
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch ((yych = *YYCURSOR)) {
+       case 'b':       goto yy9;
+       case 'c':       goto yy11;
+       default:        goto yy8;
+       }
+yy8:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy9:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy9;
+       default:        goto yy6;
+       }
+yy11:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy11;
+       default:        goto yy8;
+       }
+/* *********************************** */
+yyc_c2:
+       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy17;
+       default:        goto yy15;
+       }
+yy15:
+       ++YYCURSOR;
+       yyctx1 = (YYCURSOR - YYCTXMARKER);
+       yych = *YYCURSOR;
+       goto yy20;
+yy16:
+       YYCURSOR = YYCTXMARKER + yyctx1;
+       {}
+yy17:
+       yych = *(YYMARKER = ++YYCURSOR);
+       yyctx1 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case 'a':       goto yy21;
+       case 'b':       goto yy23;
+       case 'c':       goto yy26;
+       default:        goto yy18;
+       }
+yy18:
+       YYCURSOR = YYCTXMARKER + yyctx1;
+       {}
+yy19:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+yy20:
+       switch (yych) {
+       case 'b':       goto yy19;
+       default:        goto yy16;
+       }
+yy21:
+       yych = *++YYCURSOR;
+       yyctx4 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case 'b':       goto yy28;
+       case 'c':       goto yy31;
+       default:        goto yy22;
+       }
+yy22:
+       YYCURSOR = YYMARKER;
+       goto yy18;
+yy23:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy23;
+       default:        goto yy25;
+       }
+yy25:
+       YYCURSOR = YYCTXMARKER + yyctx1;
+       {}
+yy26:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy26;
+       default:        goto yy18;
+       }
+yy28:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy28;
+       default:        goto yy30;
+       }
+yy30:
+       YYCURSOR = YYCTXMARKER + yyctx4;
+       {}
+yy31:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy31;
+       default:        goto yy33;
+       }
+yy33:
+       YYCURSOR = YYCTXMARKER + yyctx4;
+       {}
+}
+
+re2c: warning: line 11: unreachable rule in condition 'c2' (shadowed by rules at lines 5, 6) [-Wunreachable-rules]
diff --git a/re2c/test/contexts/cond_star2.ci.re b/re2c/test/contexts/cond_star2.ci.re
new file mode 100644 (file)
index 0000000..180be91
--- /dev/null
@@ -0,0 +1,14 @@
+/*!re2c
+
+    <c1> "ab" / "c"* {}
+
+    <c2> "a"  / "c"* {}
+    <c2> [a]  / "b"* {}
+    <c2> [^a] / "b"* {}
+    <c2> "aa" / "b"+ {}
+    <c2> "aa" / "c"+ {}
+
+    <*> "a"  / "b"* {}
+    <*> * {}
+
+*/
diff --git a/re2c/test/contexts/dedup0.i--input(custom).c b/re2c/test/contexts/dedup0.i--input(custom).c
new file mode 100644 (file)
index 0000000..7143954
--- /dev/null
@@ -0,0 +1,73 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx2;
+       YYBACKUPCTX ();
+       if (YYLESSTHAN (3)) YYFILL(3);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       YYSKIP ();
+yy3:
+       {}
+yy4:
+       YYSKIP ();
+       YYBACKUP ();
+       yych = YYPEEK ();
+       yyctx0 = YYDIST();
+       switch (yych) {
+       case 'a':       goto yy5;
+       case 'b':       goto yy7;
+       case 'c':       goto yy10;
+       default:        goto yy3;
+       }
+yy5:
+       YYSKIP ();
+       yych = YYPEEK ();
+       yyctx2 = YYDIST();
+       switch (yych) {
+       case 'z':       goto yy13;
+       default:        goto yy6;
+       }
+yy6:
+       YYRESTORE ();
+       goto yy3;
+yy7:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'b':       goto yy7;
+       default:        goto yy9;
+       }
+yy9:
+       YYRESTORECTX (yyctx0);
+       {}
+yy10:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'c':       goto yy10;
+       default:        goto yy12;
+       }
+yy12:
+       YYRESTORECTX (yyctx0);
+       {}
+yy13:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'z':       goto yy13;
+       default:        goto yy15;
+       }
+yy15:
+       YYRESTORECTX (yyctx2);
+       {}
+}
+
diff --git a/re2c/test/contexts/dedup0.i--input(custom).re b/re2c/test/contexts/dedup0.i--input(custom).re
new file mode 100644 (file)
index 0000000..1c04b1a
--- /dev/null
@@ -0,0 +1,6 @@
+/*!re2c
+    "a" / "b"+ {}
+    "a" / "c"+ {}
+    "aa" / "z"+ {}
+    * {}
+*/
diff --git a/re2c/test/contexts/dedup0.i.c b/re2c/test/contexts/dedup0.i.c
new file mode 100644 (file)
index 0000000..57d2a91
--- /dev/null
@@ -0,0 +1,70 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx2;
+       YYCTXMARKER = YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+yy3:
+       {}
+yy4:
+       yych = *(YYMARKER = ++YYCURSOR);
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case 'a':       goto yy5;
+       case 'b':       goto yy7;
+       case 'c':       goto yy10;
+       default:        goto yy3;
+       }
+yy5:
+       yych = *++YYCURSOR;
+       yyctx2 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case 'z':       goto yy13;
+       default:        goto yy6;
+       }
+yy6:
+       YYCURSOR = YYMARKER;
+       goto yy3;
+yy7:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy7;
+       default:        goto yy9;
+       }
+yy9:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy10:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy10;
+       default:        goto yy12;
+       }
+yy12:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy13:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'z':       goto yy13;
+       default:        goto yy15;
+       }
+yy15:
+       YYCURSOR = YYCTXMARKER + yyctx2;
+       {}
+}
+
diff --git a/re2c/test/contexts/dedup0.i.re b/re2c/test/contexts/dedup0.i.re
new file mode 100644 (file)
index 0000000..1c04b1a
--- /dev/null
@@ -0,0 +1,6 @@
+/*!re2c
+    "a" / "b"+ {}
+    "a" / "c"+ {}
+    "aa" / "z"+ {}
+    * {}
+*/
diff --git a/re2c/test/contexts/dedup1.i--input(custom).c b/re2c/test/contexts/dedup1.i--input(custom).c
new file mode 100644 (file)
index 0000000..9d18085
--- /dev/null
@@ -0,0 +1,86 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx2;
+       YYBACKUPCTX ();
+       if (YYLESSTHAN (3)) YYFILL(3);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       YYSKIP ();
+       yyctx0 = YYDIST();
+       yych = YYPEEK ();
+       goto yy7;
+yy3:
+       YYRESTORECTX (yyctx0);
+       {}
+yy4:
+       YYSKIP ();
+       YYBACKUP ();
+       yych = YYPEEK ();
+       yyctx0 = YYDIST();
+       switch (yych) {
+       case 'a':       goto yy8;
+       default:        goto yy11;
+       }
+yy5:
+       YYRESTORECTX (yyctx0);
+       {}
+yy6:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+yy7:
+       switch (yych) {
+       case 'b':       goto yy6;
+       default:        goto yy3;
+       }
+yy8:
+       YYSKIP ();
+       yych = YYPEEK ();
+       yyctx2 = YYDIST();
+       switch (yych) {
+       case 'b':       goto yy12;
+       case 'c':       goto yy15;
+       default:        goto yy9;
+       }
+yy9:
+       YYRESTORE ();
+       goto yy5;
+yy10:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+yy11:
+       switch (yych) {
+       case 'b':       goto yy10;
+       default:        goto yy5;
+       }
+yy12:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'b':       goto yy12;
+       default:        goto yy14;
+       }
+yy14:
+       YYRESTORECTX (yyctx2);
+       {}
+yy15:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'c':       goto yy15;
+       default:        goto yy17;
+       }
+yy17:
+       YYRESTORECTX (yyctx2);
+       {}
+}
+
diff --git a/re2c/test/contexts/dedup1.i--input(custom).re b/re2c/test/contexts/dedup1.i--input(custom).re
new file mode 100644 (file)
index 0000000..7229739
--- /dev/null
@@ -0,0 +1,6 @@
+/*!re2c
+    [a]  / "b"* {}
+    [^a] / "b"* {}
+    "aa" / "b"+ {}
+    "aa" / "c"+ {}
+*/
diff --git a/re2c/test/contexts/dedup1.i.c b/re2c/test/contexts/dedup1.i.c
new file mode 100644 (file)
index 0000000..324fadc
--- /dev/null
@@ -0,0 +1,83 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx2;
+       YYCTXMARKER = YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       yych = *YYCURSOR;
+       goto yy7;
+yy3:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy4:
+       yych = *(YYMARKER = ++YYCURSOR);
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case 'a':       goto yy8;
+       default:        goto yy11;
+       }
+yy5:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy6:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+yy7:
+       switch (yych) {
+       case 'b':       goto yy6;
+       default:        goto yy3;
+       }
+yy8:
+       yych = *++YYCURSOR;
+       yyctx2 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case 'b':       goto yy12;
+       case 'c':       goto yy15;
+       default:        goto yy9;
+       }
+yy9:
+       YYCURSOR = YYMARKER;
+       goto yy5;
+yy10:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+yy11:
+       switch (yych) {
+       case 'b':       goto yy10;
+       default:        goto yy5;
+       }
+yy12:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy12;
+       default:        goto yy14;
+       }
+yy14:
+       YYCURSOR = YYCTXMARKER + yyctx2;
+       {}
+yy15:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy15;
+       default:        goto yy17;
+       }
+yy17:
+       YYCURSOR = YYCTXMARKER + yyctx2;
+       {}
+}
+
diff --git a/re2c/test/contexts/dedup1.i.re b/re2c/test/contexts/dedup1.i.re
new file mode 100644 (file)
index 0000000..7229739
--- /dev/null
@@ -0,0 +1,6 @@
+/*!re2c
+    [a]  / "b"* {}
+    [^a] / "b"* {}
+    "aa" / "b"+ {}
+    "aa" / "c"+ {}
+*/
diff --git a/re2c/test/contexts/dedup2.i--input(custom).c b/re2c/test/contexts/dedup2.i--input(custom).c
new file mode 100644 (file)
index 0000000..53ddde3
--- /dev/null
@@ -0,0 +1,48 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx2;
+       YYBACKUPCTX ();
+       if (YYLESSTHAN (3)) YYFILL(3);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       YYSKIP ();
+       yyctx0 = YYDIST();
+       yych = YYPEEK ();
+       goto yy6;
+       YYRESTORECTX (yyctx0);
+       {}
+yy4:
+       YYSKIP ();
+       yyctx0 = YYDIST();
+       switch ((yych = YYPEEK ())) {
+       case 'a':       goto yy10;
+       default:        goto yy8;
+       }
+       YYRESTORECTX (yyctx0);
+       {}
+yy6:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       goto yy6;
+yy8:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       goto yy8;
+yy10:
+       YYSKIP ();
+       yyctx2 = YYDIST();
+       yych = YYPEEK ();
+       goto yy8;
+}
+
+re2c: warning: line 2: unreachable rule  [-Wunreachable-rules]
+re2c: warning: line 3: unreachable rule  [-Wunreachable-rules]
+re2c: warning: line 4: unreachable rule (shadowed by rule at line 2) [-Wunreachable-rules]
diff --git a/re2c/test/contexts/dedup2.i--input(custom).re b/re2c/test/contexts/dedup2.i--input(custom).re
new file mode 100644 (file)
index 0000000..96b92ae
--- /dev/null
@@ -0,0 +1,5 @@
+/*!re2c
+    [a]  / [^]* {}
+    [^a] / [^]* {}
+    "aa" / "z"+ {}
+*/
diff --git a/re2c/test/contexts/dedup2.i.c b/re2c/test/contexts/dedup2.i.c
new file mode 100644 (file)
index 0000000..9fb4aee
--- /dev/null
@@ -0,0 +1,48 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx2;
+       YYCTXMARKER = YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       yych = *YYCURSOR;
+       goto yy6;
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy4:
+       ++YYCURSOR;
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch ((yych = *YYCURSOR)) {
+       case 'a':       goto yy10;
+       default:        goto yy8;
+       }
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy6:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       goto yy6;
+yy8:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       goto yy8;
+yy10:
+       ++YYCURSOR;
+       yyctx2 = (YYCURSOR - YYCTXMARKER);
+       yych = *YYCURSOR;
+       goto yy8;
+}
+
+re2c: warning: line 2: unreachable rule  [-Wunreachable-rules]
+re2c: warning: line 3: unreachable rule  [-Wunreachable-rules]
+re2c: warning: line 4: unreachable rule (shadowed by rule at line 2) [-Wunreachable-rules]
diff --git a/re2c/test/contexts/dedup2.i.re b/re2c/test/contexts/dedup2.i.re
new file mode 100644 (file)
index 0000000..96b92ae
--- /dev/null
@@ -0,0 +1,5 @@
+/*!re2c
+    [a]  / [^]* {}
+    [^a] / [^]* {}
+    "aa" / "z"+ {}
+*/
diff --git a/re2c/test/contexts/dedup3.i--input(custom).c b/re2c/test/contexts/dedup3.i--input(custom).c
new file mode 100644 (file)
index 0000000..18fbc81
--- /dev/null
@@ -0,0 +1,74 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx2;
+       YYBACKUPCTX ();
+       if (YYLESSTHAN (3)) YYFILL(3);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       YYSKIP ();
+       yyctx0 = YYDIST();
+       yych = YYPEEK ();
+       goto yy7;
+yy3:
+       YYRESTORECTX (yyctx0);
+       {}
+yy4:
+       YYSKIP ();
+       YYBACKUP ();
+       yych = YYPEEK ();
+       yyctx0 = YYDIST();
+       switch (yych) {
+       case 'a':       goto yy8;
+       default:        goto yy11;
+       }
+yy5:
+       YYRESTORECTX (yyctx0);
+       {}
+yy6:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+yy7:
+       switch (yych) {
+       case 'b':       goto yy6;
+       default:        goto yy3;
+       }
+yy8:
+       YYSKIP ();
+       yych = YYPEEK ();
+       yyctx2 = YYDIST();
+       switch (yych) {
+       case 'b':       goto yy12;
+       default:        goto yy9;
+       }
+yy9:
+       YYRESTORE ();
+       goto yy5;
+yy10:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+yy11:
+       switch (yych) {
+       case 'b':       goto yy10;
+       default:        goto yy5;
+       }
+yy12:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'b':       goto yy12;
+       default:        goto yy14;
+       }
+yy14:
+       YYRESTORECTX (yyctx2);
+       {}
+}
+
diff --git a/re2c/test/contexts/dedup3.i--input(custom).re b/re2c/test/contexts/dedup3.i--input(custom).re
new file mode 100644 (file)
index 0000000..df29143
--- /dev/null
@@ -0,0 +1,5 @@
+/*!re2c
+    [a]  / "b"* {}
+    [^a] / "b"* {}
+    "aa" / "b"+ {}
+*/
diff --git a/re2c/test/contexts/dedup3.i.c b/re2c/test/contexts/dedup3.i.c
new file mode 100644 (file)
index 0000000..9751045
--- /dev/null
@@ -0,0 +1,71 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx2;
+       YYCTXMARKER = YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       yych = *YYCURSOR;
+       goto yy7;
+yy3:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy4:
+       yych = *(YYMARKER = ++YYCURSOR);
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case 'a':       goto yy8;
+       default:        goto yy11;
+       }
+yy5:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy6:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+yy7:
+       switch (yych) {
+       case 'b':       goto yy6;
+       default:        goto yy3;
+       }
+yy8:
+       yych = *++YYCURSOR;
+       yyctx2 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case 'b':       goto yy12;
+       default:        goto yy9;
+       }
+yy9:
+       YYCURSOR = YYMARKER;
+       goto yy5;
+yy10:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+yy11:
+       switch (yych) {
+       case 'b':       goto yy10;
+       default:        goto yy5;
+       }
+yy12:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy12;
+       default:        goto yy14;
+       }
+yy14:
+       YYCURSOR = YYCTXMARKER + yyctx2;
+       {}
+}
+
diff --git a/re2c/test/contexts/dedup3.i.re b/re2c/test/contexts/dedup3.i.re
new file mode 100644 (file)
index 0000000..df29143
--- /dev/null
@@ -0,0 +1,5 @@
+/*!re2c
+    [a]  / "b"* {}
+    [^a] / "b"* {}
+    "aa" / "b"+ {}
+*/
diff --git a/re2c/test/contexts/fix2.i--contexts.c b/re2c/test/contexts/fix2.i--contexts.c
new file mode 100644 (file)
index 0000000..3a4d959
--- /dev/null
@@ -0,0 +1,131 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYCTXMARKER = YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case '0':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+yy3:
+       { printf("error\n"); return; }
+yy4:
+       yych = *(YYMARKER = ++YYCURSOR);
+       switch (yych) {
+       case '1':       goto yy5;
+       default:        goto yy3;
+       }
+yy5:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '1':       goto yy7;
+       default:        goto yy6;
+       }
+yy6:
+       YYCURSOR = YYMARKER;
+       goto yy3;
+yy7:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '2':       goto yy8;
+       default:        goto yy6;
+       }
+yy8:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '2':       goto yy9;
+       default:        goto yy6;
+       }
+yy9:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '2':       goto yy10;
+       default:        goto yy6;
+       }
+yy10:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '3':       goto yy11;
+       default:        goto yy6;
+       }
+yy11:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '3':       goto yy12;
+       default:        goto yy6;
+       }
+yy12:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '3':       goto yy13;
+       default:        goto yy6;
+       }
+yy13:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '3':       goto yy14;
+       default:        goto yy6;
+       }
+yy14:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy15;
+       default:        goto yy6;
+       }
+yy15:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy16;
+       default:        goto yy6;
+       }
+yy16:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy17;
+       default:        goto yy6;
+       }
+yy17:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy18;
+       default:        goto yy6;
+       }
+yy18:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy19;
+       default:        goto yy6;
+       }
+yy19:
+       ++YYCURSOR;
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%.*s'\n",
+                (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 14)) - YYCTXMARKER, YYCTXMARKER,
+                (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 12)) - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 14)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 14)),
+                (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)) - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 12)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 12)),
+                (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 5)) - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)),
+                YYCURSOR - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 5)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 5)));
+                return;
+        }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix2.i--contexts.re b/re2c/test/contexts/fix2.i--contexts.re
new file mode 100644 (file)
index 0000000..37df4c0
--- /dev/null
@@ -0,0 +1,35 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0" @p1 "11"
+            @p2 "222"
+            @p3 "3333"
+            @p4 "44444" {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%.*s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                @p4 - @p3, @p3,
+                YYCURSOR - @p4, @p4);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix2_trail.i--contexts--input(custom).c b/re2c/test/contexts/fix2_trail.i--contexts--input(custom).c
new file mode 100644 (file)
index 0000000..8affb1e
--- /dev/null
@@ -0,0 +1,147 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYBACKUPCTX ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '0':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       YYSKIP ();
+yy3:
+       { printf("error\n"); return; }
+yy4:
+       YYSKIP ();
+       YYBACKUP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '1':       goto yy5;
+       default:        goto yy3;
+       }
+yy5:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '1':       goto yy7;
+       default:        goto yy6;
+       }
+yy6:
+       YYRESTORE ();
+       goto yy3;
+yy7:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '2':       goto yy8;
+       default:        goto yy6;
+       }
+yy8:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '2':       goto yy9;
+       default:        goto yy6;
+       }
+yy9:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '2':       goto yy10;
+       default:        goto yy6;
+       }
+yy10:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '3':       goto yy11;
+       default:        goto yy6;
+       }
+yy11:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '3':       goto yy12;
+       default:        goto yy6;
+       }
+yy12:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '3':       goto yy13;
+       default:        goto yy6;
+       }
+yy13:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '3':       goto yy14;
+       default:        goto yy6;
+       }
+yy14:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '4':       goto yy15;
+       default:        goto yy6;
+       }
+yy15:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '4':       goto yy16;
+       default:        goto yy6;
+       }
+yy16:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '4':       goto yy17;
+       default:        goto yy6;
+       }
+yy17:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '4':       goto yy18;
+       default:        goto yy6;
+       }
+yy18:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '4':       goto yy19;
+       default:        goto yy6;
+       }
+yy19:
+       YYSKIP ();
+       YYRESTORECTX (YYDIST() - 5);
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                YYCTX((YYDIST() - 9)) - YYCTXMARKER, YYCTXMARKER,
+                YYCTX((YYDIST() - 7)) - YYCTX((YYDIST() - 9)), YYCTX((YYDIST() - 9)),
+                YYCTX((YYDIST() - 4)) - YYCTX((YYDIST() - 7)), YYCTX((YYDIST() - 7)),
+                YYCURSOR - YYCTX((YYDIST() - 4)), YYCTX((YYDIST() - 4)),
+                YYCURSOR);
+                return;
+        }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix2_trail.i--contexts--input(custom).re b/re2c/test/contexts/fix2_trail.i--contexts--input(custom).re
new file mode 100644 (file)
index 0000000..4ded9c2
--- /dev/null
@@ -0,0 +1,35 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0" @p1 "11"
+            @p2 "222"
+            @p3 "3333"
+            / "44444" {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                YYCURSOR - @p3, @p3,
+                YYCURSOR);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix2_trail.i--contexts.c b/re2c/test/contexts/fix2_trail.i--contexts.c
new file mode 100644 (file)
index 0000000..0b363e3
--- /dev/null
@@ -0,0 +1,132 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYCTXMARKER = YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case '0':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+yy3:
+       { printf("error\n"); return; }
+yy4:
+       yych = *(YYMARKER = ++YYCURSOR);
+       switch (yych) {
+       case '1':       goto yy5;
+       default:        goto yy3;
+       }
+yy5:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '1':       goto yy7;
+       default:        goto yy6;
+       }
+yy6:
+       YYCURSOR = YYMARKER;
+       goto yy3;
+yy7:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '2':       goto yy8;
+       default:        goto yy6;
+       }
+yy8:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '2':       goto yy9;
+       default:        goto yy6;
+       }
+yy9:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '2':       goto yy10;
+       default:        goto yy6;
+       }
+yy10:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '3':       goto yy11;
+       default:        goto yy6;
+       }
+yy11:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '3':       goto yy12;
+       default:        goto yy6;
+       }
+yy12:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '3':       goto yy13;
+       default:        goto yy6;
+       }
+yy13:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '3':       goto yy14;
+       default:        goto yy6;
+       }
+yy14:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy15;
+       default:        goto yy6;
+       }
+yy15:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy16;
+       default:        goto yy6;
+       }
+yy16:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy17;
+       default:        goto yy6;
+       }
+yy17:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy18;
+       default:        goto yy6;
+       }
+yy18:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy19;
+       default:        goto yy6;
+       }
+yy19:
+       ++YYCURSOR;
+       YYCURSOR -= 5;
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)) - YYCTXMARKER, YYCTXMARKER,
+                (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 7)) - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 9)),
+                (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 4)) - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 7)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 7)),
+                YYCURSOR - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 4)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 4)),
+                YYCURSOR);
+                return;
+        }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix2_trail.i--contexts.re b/re2c/test/contexts/fix2_trail.i--contexts.re
new file mode 100644 (file)
index 0000000..4ded9c2
--- /dev/null
@@ -0,0 +1,35 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0" @p1 "11"
+            @p2 "222"
+            @p3 "3333"
+            / "44444" {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                YYCURSOR - @p3, @p3,
+                YYCURSOR);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix3.i--contexts.c b/re2c/test/contexts/fix3.i--contexts.c
new file mode 100644 (file)
index 0000000..34cd5b0
--- /dev/null
@@ -0,0 +1,98 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYDISTTYPE yyctx0p1, yyctx0p2, yyctx0p3, yyctx0p4;
+       YYCTXMARKER = YYCURSOR;
+       yych = *YYCURSOR;
+       yyctx0p1 = yyctx0p2 = yyctx0p3 = yyctx0p4 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '0':       goto yy5;
+       case '1':       goto yy7;
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy3;
+       }
+yy2:
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%.*s'\n",
+                (YYCTXMARKER + yyctx0p1) - YYCTXMARKER, YYCTXMARKER,
+                (YYCTXMARKER + yyctx0p2) - (YYCTXMARKER + yyctx0p1), (YYCTXMARKER + yyctx0p1),
+                (YYCTXMARKER + yyctx0p3) - (YYCTXMARKER + yyctx0p2), (YYCTXMARKER + yyctx0p2),
+                (YYCTXMARKER + yyctx0p4) - (YYCTXMARKER + yyctx0p3), (YYCTXMARKER + yyctx0p3),
+                YYCURSOR - (YYCTXMARKER + yyctx0p4), (YYCTXMARKER + yyctx0p4));
+                return;
+        }
+yy3:
+       ++YYCURSOR;
+       { printf("error\n"); return; }
+yy5:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       yyctx0p1 = yyctx0p2 = yyctx0p3 = yyctx0p4 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '0':       goto yy5;
+       case '1':       goto yy7;
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy7:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       yyctx0p2 = yyctx0p3 = yyctx0p4 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '1':       goto yy7;
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy9:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       yyctx0p3 = yyctx0p4 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy11:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       yyctx0p4 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy13:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
+re2c: warning: line 18: rule matches empty string [-Wmatch-empty-string]
diff --git a/re2c/test/contexts/fix3.i--contexts.re b/re2c/test/contexts/fix3.i--contexts.re
new file mode 100644 (file)
index 0000000..cbb1d97
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0"*
+            @p1 "1"*
+            @p2 "2"*
+            @p3 "3"*
+            @p4 "4"* {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%.*s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                @p4 - @p3, @p3,
+                YYCURSOR - @p4, @p4);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix3_trail.i--contexts--input(custom).c b/re2c/test/contexts/fix3_trail.i--contexts--input(custom).c
new file mode 100644 (file)
index 0000000..60824d3
--- /dev/null
@@ -0,0 +1,99 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYDISTTYPE yyctx0, yyctx0p1, yyctx0p2, yyctx0p3;
+       YYBACKUPCTX ();
+       yych = YYPEEK ();
+       yyctx0p1 = yyctx0p2 = yyctx0p3 = yyctx0 = YYDIST();
+       switch (yych) {
+       case '0':       goto yy5;
+       case '1':       goto yy7;
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy3;
+       }
+yy2:
+       YYRESTORECTX (yyctx0);
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                YYCTX(yyctx0p1) - YYCTXMARKER, YYCTXMARKER,
+                YYCTX(yyctx0p2) - YYCTX(yyctx0p1), YYCTX(yyctx0p1),
+                YYCTX(yyctx0p3) - YYCTX(yyctx0p2), YYCTX(yyctx0p2),
+                YYCURSOR - YYCTX(yyctx0p3), YYCTX(yyctx0p3),
+                YYCURSOR);
+                return;
+        }
+yy3:
+       YYSKIP ();
+       { printf("error\n"); return; }
+yy5:
+       YYSKIP ();
+       yych = YYPEEK ();
+       yyctx0p1 = yyctx0p2 = yyctx0p3 = yyctx0 = YYDIST();
+       switch (yych) {
+       case '0':       goto yy5;
+       case '1':       goto yy7;
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy7:
+       YYSKIP ();
+       yych = YYPEEK ();
+       yyctx0p2 = yyctx0p3 = yyctx0 = YYDIST();
+       switch (yych) {
+       case '1':       goto yy7;
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy9:
+       YYSKIP ();
+       yych = YYPEEK ();
+       yyctx0p3 = yyctx0 = YYDIST();
+       switch (yych) {
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy11:
+       YYSKIP ();
+       yych = YYPEEK ();
+       yyctx0 = YYDIST();
+       switch (yych) {
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy13:
+       YYSKIP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
+re2c: warning: line 18: rule matches empty string [-Wmatch-empty-string]
diff --git a/re2c/test/contexts/fix3_trail.i--contexts--input(custom).re b/re2c/test/contexts/fix3_trail.i--contexts--input(custom).re
new file mode 100644 (file)
index 0000000..106ccc0
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0"*
+            @p1 "1"*
+            @p2 "2"*
+            @p3 "3"*
+            / "4"* {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                YYCURSOR - @p3, @p3,
+                YYCURSOR);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix3_trail.i--contexts.c b/re2c/test/contexts/fix3_trail.i--contexts.c
new file mode 100644 (file)
index 0000000..38315d0
--- /dev/null
@@ -0,0 +1,99 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYDISTTYPE yyctx0, yyctx0p1, yyctx0p2, yyctx0p3;
+       YYCTXMARKER = YYCURSOR;
+       yych = *YYCURSOR;
+       yyctx0p1 = yyctx0p2 = yyctx0p3 = yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '0':       goto yy5;
+       case '1':       goto yy7;
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy3;
+       }
+yy2:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                (YYCTXMARKER + yyctx0p1) - YYCTXMARKER, YYCTXMARKER,
+                (YYCTXMARKER + yyctx0p2) - (YYCTXMARKER + yyctx0p1), (YYCTXMARKER + yyctx0p1),
+                (YYCTXMARKER + yyctx0p3) - (YYCTXMARKER + yyctx0p2), (YYCTXMARKER + yyctx0p2),
+                YYCURSOR - (YYCTXMARKER + yyctx0p3), (YYCTXMARKER + yyctx0p3),
+                YYCURSOR);
+                return;
+        }
+yy3:
+       ++YYCURSOR;
+       { printf("error\n"); return; }
+yy5:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       yyctx0p1 = yyctx0p2 = yyctx0p3 = yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '0':       goto yy5;
+       case '1':       goto yy7;
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy7:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       yyctx0p2 = yyctx0p3 = yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '1':       goto yy7;
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy9:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       yyctx0p3 = yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '2':       goto yy9;
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy11:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '3':       goto yy11;
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+yy13:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case '4':       goto yy13;
+       default:        goto yy2;
+       }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
+re2c: warning: line 18: rule matches empty string [-Wmatch-empty-string]
diff --git a/re2c/test/contexts/fix3_trail.i--contexts.re b/re2c/test/contexts/fix3_trail.i--contexts.re
new file mode 100644 (file)
index 0000000..106ccc0
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0"*
+            @p1 "1"*
+            @p2 "2"*
+            @p3 "3"*
+            / "4"* {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                YYCURSOR - @p3, @p3,
+                YYCURSOR);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix4.i--contexts.c b/re2c/test/contexts/fix4.i--contexts.c
new file mode 100644 (file)
index 0000000..adb134e
--- /dev/null
@@ -0,0 +1,78 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYDISTTYPE yyctx0p1, yyctx0p3;
+       YYCTXMARKER = YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case '0':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+yy3:
+       { printf("error\n"); return; }
+yy4:
+       yych = *(YYMARKER = ++YYCURSOR);
+       yyctx0p1 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '1':
+       case '2':       goto yy6;
+       default:        goto yy3;
+       }
+yy5:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+yy6:
+       switch (yych) {
+       case '1':       goto yy5;
+       case '2':       goto yy8;
+       default:        goto yy7;
+       }
+yy7:
+       YYCURSOR = YYMARKER;
+       goto yy3;
+yy8:
+       yych = *++YYCURSOR;
+       yyctx0p3 = (YYCURSOR - YYCTXMARKER);
+       goto yy10;
+yy9:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+yy10:
+       switch (yych) {
+       case '3':       goto yy9;
+       case '4':       goto yy11;
+       default:        goto yy7;
+       }
+yy11:
+       ++YYCURSOR;
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%.*s'\n",
+                (YYCTXMARKER + yyctx0p1) - YYCTXMARKER, YYCTXMARKER,
+                (YYCTXMARKER + (yyctx0p3 - 1)) - (YYCTXMARKER + yyctx0p1), (YYCTXMARKER + yyctx0p1),
+                (YYCTXMARKER + yyctx0p3) - (YYCTXMARKER + (yyctx0p3 - 1)), (YYCTXMARKER + (yyctx0p3 - 1)),
+                (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 1)) - (YYCTXMARKER + yyctx0p3), (YYCTXMARKER + yyctx0p3),
+                YYCURSOR - (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 1)), (YYCTXMARKER + ((YYCURSOR - YYCTXMARKER) - 1)));
+                return;
+        }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix4.i--contexts.re b/re2c/test/contexts/fix4.i--contexts.re
new file mode 100644 (file)
index 0000000..bde32ab
--- /dev/null
@@ -0,0 +1,35 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0" @p1 "1"*
+            @p2 "2"
+            @p3 "3"*
+            @p4 "4" {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%.*s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                @p4 - @p3, @p3,
+                YYCURSOR - @p4, @p4);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix4_trail.i--contexts--input(custom).c b/re2c/test/contexts/fix4_trail.i--contexts--input(custom).c
new file mode 100644 (file)
index 0000000..5865c07
--- /dev/null
@@ -0,0 +1,82 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYDISTTYPE yyctx0p1, yyctx0p3;
+       YYBACKUPCTX ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '0':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       YYSKIP ();
+yy3:
+       { printf("error\n"); return; }
+yy4:
+       YYSKIP ();
+       YYBACKUP ();
+       yych = YYPEEK ();
+       yyctx0p1 = YYDIST();
+       switch (yych) {
+       case '1':
+       case '2':       goto yy6;
+       default:        goto yy3;
+       }
+yy5:
+       YYSKIP ();
+       yych = YYPEEK ();
+yy6:
+       switch (yych) {
+       case '1':       goto yy5;
+       case '2':       goto yy8;
+       default:        goto yy7;
+       }
+yy7:
+       YYRESTORE ();
+       goto yy3;
+yy8:
+       YYSKIP ();
+       yych = YYPEEK ();
+       yyctx0p3 = YYDIST();
+       goto yy10;
+yy9:
+       YYSKIP ();
+       yych = YYPEEK ();
+yy10:
+       switch (yych) {
+       case '3':       goto yy9;
+       case '4':       goto yy11;
+       default:        goto yy7;
+       }
+yy11:
+       YYSKIP ();
+       YYRESTORECTX (YYDIST() - 1);
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                YYCTX(yyctx0p1) - YYCTXMARKER, YYCTXMARKER,
+                YYCTX((yyctx0p3 - 1)) - YYCTX(yyctx0p1), YYCTX(yyctx0p1),
+                YYCTX(yyctx0p3) - YYCTX((yyctx0p3 - 1)), YYCTX((yyctx0p3 - 1)),
+                YYCURSOR - YYCTX(yyctx0p3), YYCTX(yyctx0p3),
+                YYCURSOR);
+                return;
+        }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix4_trail.i--contexts--input(custom).re b/re2c/test/contexts/fix4_trail.i--contexts--input(custom).re
new file mode 100644 (file)
index 0000000..7487841
--- /dev/null
@@ -0,0 +1,35 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0" @p1 "1"*
+            @p2 "2"
+            @p3 "3"*
+            / "4" {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                YYCURSOR - @p3, @p3,
+                YYCURSOR);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix4_trail.i--contexts.c b/re2c/test/contexts/fix4_trail.i--contexts.c
new file mode 100644 (file)
index 0000000..1d26748
--- /dev/null
@@ -0,0 +1,79 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYDISTTYPE yyctx0p1, yyctx0p3;
+       YYCTXMARKER = YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case '0':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+yy3:
+       { printf("error\n"); return; }
+yy4:
+       yych = *(YYMARKER = ++YYCURSOR);
+       yyctx0p1 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '1':
+       case '2':       goto yy6;
+       default:        goto yy3;
+       }
+yy5:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+yy6:
+       switch (yych) {
+       case '1':       goto yy5;
+       case '2':       goto yy8;
+       default:        goto yy7;
+       }
+yy7:
+       YYCURSOR = YYMARKER;
+       goto yy3;
+yy8:
+       yych = *++YYCURSOR;
+       yyctx0p3 = (YYCURSOR - YYCTXMARKER);
+       goto yy10;
+yy9:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+yy10:
+       switch (yych) {
+       case '3':       goto yy9;
+       case '4':       goto yy11;
+       default:        goto yy7;
+       }
+yy11:
+       ++YYCURSOR;
+       YYCURSOR -= 1;
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                (YYCTXMARKER + yyctx0p1) - YYCTXMARKER, YYCTXMARKER,
+                (YYCTXMARKER + (yyctx0p3 - 1)) - (YYCTXMARKER + yyctx0p1), (YYCTXMARKER + yyctx0p1),
+                (YYCTXMARKER + yyctx0p3) - (YYCTXMARKER + (yyctx0p3 - 1)), (YYCTXMARKER + (yyctx0p3 - 1)),
+                YYCURSOR - (YYCTXMARKER + yyctx0p3), (YYCTXMARKER + yyctx0p3),
+                YYCURSOR);
+                return;
+        }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix4_trail.i--contexts.re b/re2c/test/contexts/fix4_trail.i--contexts.re
new file mode 100644 (file)
index 0000000..7487841
--- /dev/null
@@ -0,0 +1,35 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0" @p1 "1"*
+            @p2 "2"
+            @p3 "3"*
+            / "4" {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                YYCURSOR - @p3, @p3,
+                YYCURSOR);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix5.i--contexts.c b/re2c/test/contexts/fix5.i--contexts.c
new file mode 100644 (file)
index 0000000..af11f61
--- /dev/null
@@ -0,0 +1,98 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYDISTTYPE yyctx0p2, yyctx0p4;
+       YYCTXMARKER = YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case '0':       goto yy4;
+       case '1':       goto yy5;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+yy3:
+       { printf("error\n"); return; }
+yy4:
+       yych = *(YYMARKER = ++YYCURSOR);
+       switch (yych) {
+       case '0':
+       case '1':       goto yy7;
+       default:        goto yy3;
+       }
+yy5:
+       yych = *(YYMARKER = ++YYCURSOR);
+       yyctx0p2 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '2':
+       case '3':       goto yy11;
+       default:        goto yy3;
+       }
+yy6:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+yy7:
+       switch (yych) {
+       case '0':       goto yy6;
+       case '1':       goto yy9;
+       default:        goto yy8;
+       }
+yy8:
+       YYCURSOR = YYMARKER;
+       goto yy3;
+yy9:
+       yych = *++YYCURSOR;
+       yyctx0p2 = (YYCURSOR - YYCTXMARKER);
+       goto yy11;
+yy10:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+yy11:
+       switch (yych) {
+       case '2':       goto yy10;
+       case '3':       goto yy12;
+       default:        goto yy8;
+       }
+yy12:
+       ++YYCURSOR;
+       yyctx0p4 = (YYCURSOR - YYCTXMARKER);
+       yych = *YYCURSOR;
+       goto yy15;
+yy13:
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%.*s'\n",
+                (YYCTXMARKER + (yyctx0p2 - 1)) - YYCTXMARKER, YYCTXMARKER,
+                (YYCTXMARKER + yyctx0p2) - (YYCTXMARKER + (yyctx0p2 - 1)), (YYCTXMARKER + (yyctx0p2 - 1)),
+                (YYCTXMARKER + (yyctx0p4 - 1)) - (YYCTXMARKER + yyctx0p2), (YYCTXMARKER + yyctx0p2),
+                (YYCTXMARKER + yyctx0p4) - (YYCTXMARKER + (yyctx0p4 - 1)), (YYCTXMARKER + (yyctx0p4 - 1)),
+                YYCURSOR - (YYCTXMARKER + yyctx0p4), (YYCTXMARKER + yyctx0p4));
+                return;
+        }
+yy14:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+yy15:
+       switch (yych) {
+       case '4':       goto yy14;
+       default:        goto yy13;
+       }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix5.i--contexts.re b/re2c/test/contexts/fix5.i--contexts.re
new file mode 100644 (file)
index 0000000..a150897
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0"*
+            @p1 "1"
+            @p2 "2"*
+            @p3 "3"
+            @p4 "4"* {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%.*s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                @p4 - @p3, @p3,
+                YYCURSOR - @p4, @p4);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix5_trail.i--contexts--input(custom).c b/re2c/test/contexts/fix5_trail.i--contexts--input(custom).c
new file mode 100644 (file)
index 0000000..09a5184
--- /dev/null
@@ -0,0 +1,104 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYDISTTYPE yyctx0, yyctx0p2;
+       YYBACKUPCTX ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '0':       goto yy4;
+       case '1':       goto yy5;
+       default:        goto yy2;
+       }
+yy2:
+       YYSKIP ();
+yy3:
+       { printf("error\n"); return; }
+yy4:
+       YYSKIP ();
+       YYBACKUP ();
+       yych = YYPEEK ();
+       switch (yych) {
+       case '0':
+       case '1':       goto yy7;
+       default:        goto yy3;
+       }
+yy5:
+       YYSKIP ();
+       YYBACKUP ();
+       yych = YYPEEK ();
+       yyctx0p2 = YYDIST();
+       switch (yych) {
+       case '2':
+       case '3':       goto yy11;
+       default:        goto yy3;
+       }
+yy6:
+       YYSKIP ();
+       yych = YYPEEK ();
+yy7:
+       switch (yych) {
+       case '0':       goto yy6;
+       case '1':       goto yy9;
+       default:        goto yy8;
+       }
+yy8:
+       YYRESTORE ();
+       goto yy3;
+yy9:
+       YYSKIP ();
+       yych = YYPEEK ();
+       yyctx0p2 = YYDIST();
+       goto yy11;
+yy10:
+       YYSKIP ();
+       yych = YYPEEK ();
+yy11:
+       switch (yych) {
+       case '2':       goto yy10;
+       case '3':       goto yy12;
+       default:        goto yy8;
+       }
+yy12:
+       YYSKIP ();
+       yyctx0 = YYDIST();
+       yych = YYPEEK ();
+       goto yy15;
+yy13:
+       YYRESTORECTX (yyctx0);
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                YYCTX((yyctx0p2 - 1)) - YYCTXMARKER, YYCTXMARKER,
+                YYCTX(yyctx0p2) - YYCTX((yyctx0p2 - 1)), YYCTX((yyctx0p2 - 1)),
+                YYCTX((yyctx0 - 1)) - YYCTX(yyctx0p2), YYCTX(yyctx0p2),
+                YYCURSOR - YYCTX((yyctx0 - 1)), YYCTX((yyctx0 - 1)),
+                YYCURSOR);
+                return;
+        }
+yy14:
+       YYSKIP ();
+       yych = YYPEEK ();
+yy15:
+       switch (yych) {
+       case '4':       goto yy14;
+       default:        goto yy13;
+       }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix5_trail.i--contexts--input(custom).re b/re2c/test/contexts/fix5_trail.i--contexts--input(custom).re
new file mode 100644 (file)
index 0000000..5ffcc7b
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0"*
+            @p1 "1"
+            @p2 "2"*
+            @p3 "3"
+            / "4"* {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                YYCURSOR - @p3, @p3,
+                YYCURSOR);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix5_trail.i--contexts.c b/re2c/test/contexts/fix5_trail.i--contexts.c
new file mode 100644 (file)
index 0000000..df09243
--- /dev/null
@@ -0,0 +1,99 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    
+{
+       char yych;
+       YYDISTTYPE yyctx0, yyctx0p2;
+       YYCTXMARKER = YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case '0':       goto yy4;
+       case '1':       goto yy5;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+yy3:
+       { printf("error\n"); return; }
+yy4:
+       yych = *(YYMARKER = ++YYCURSOR);
+       switch (yych) {
+       case '0':
+       case '1':       goto yy7;
+       default:        goto yy3;
+       }
+yy5:
+       yych = *(YYMARKER = ++YYCURSOR);
+       yyctx0p2 = (YYCURSOR - YYCTXMARKER);
+       switch (yych) {
+       case '2':
+       case '3':       goto yy11;
+       default:        goto yy3;
+       }
+yy6:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+yy7:
+       switch (yych) {
+       case '0':       goto yy6;
+       case '1':       goto yy9;
+       default:        goto yy8;
+       }
+yy8:
+       YYCURSOR = YYMARKER;
+       goto yy3;
+yy9:
+       yych = *++YYCURSOR;
+       yyctx0p2 = (YYCURSOR - YYCTXMARKER);
+       goto yy11;
+yy10:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+yy11:
+       switch (yych) {
+       case '2':       goto yy10;
+       case '3':       goto yy12;
+       default:        goto yy8;
+       }
+yy12:
+       ++YYCURSOR;
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       yych = *YYCURSOR;
+       goto yy15;
+yy13:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                (YYCTXMARKER + (yyctx0p2 - 1)) - YYCTXMARKER, YYCTXMARKER,
+                (YYCTXMARKER + yyctx0p2) - (YYCTXMARKER + (yyctx0p2 - 1)), (YYCTXMARKER + (yyctx0p2 - 1)),
+                (YYCTXMARKER + (yyctx0 - 1)) - (YYCTXMARKER + yyctx0p2), (YYCTXMARKER + yyctx0p2),
+                YYCURSOR - (YYCTXMARKER + (yyctx0 - 1)), (YYCTXMARKER + (yyctx0 - 1)),
+                YYCURSOR);
+                return;
+        }
+yy14:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+yy15:
+       switch (yych) {
+       case '4':       goto yy14;
+       default:        goto yy13;
+       }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/fix5_trail.i--contexts.re b/re2c/test/contexts/fix5_trail.i--contexts.re
new file mode 100644 (file)
index 0000000..5ffcc7b
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "0"*
+            @p1 "1"
+            @p2 "2"*
+            @p3 "3"
+            / "4"* {
+            printf("'%.*s', '%.*s', '%.*s', '%.*s', '%s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                @p2 - @p1, @p1,
+                @p3 - @p2, @p2,
+                YYCURSOR - @p3, @p3,
+                YYCURSOR);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/overlap.i--input(custom).c b/re2c/test/contexts/overlap.i--input(custom).c
new file mode 100644 (file)
index 0000000..597fc68
--- /dev/null
@@ -0,0 +1,54 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx1;
+       YYBACKUPCTX ();
+       if (YYLESSTHAN (3)) YYFILL(3);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       YYSKIP ();
+       {}
+yy4:
+       YYSKIP ();
+       yyctx1 = YYDIST();
+       switch ((yych = YYPEEK ())) {
+       case 'b':       goto yy6;
+       default:        goto yy5;
+       }
+yy5:
+       YYRESTORECTX (yyctx1);
+       {}
+yy6:
+       YYSKIP ();
+       yyctx0 = YYDIST();
+       switch ((yych = YYPEEK ())) {
+       case 'b':       goto yy8;
+       case 'c':       goto yy10;
+       default:        goto yy7;
+       }
+yy7:
+       YYRESTORECTX (yyctx0);
+       {}
+yy8:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'b':       goto yy8;
+       default:        goto yy5;
+       }
+yy10:
+       YYSKIP ();
+       if (YYLESSTHAN (1)) YYFILL(1);
+       yych = YYPEEK ();
+       switch (yych) {
+       case 'c':       goto yy10;
+       default:        goto yy7;
+       }
+}
+
diff --git a/re2c/test/contexts/overlap.i--input(custom).re b/re2c/test/contexts/overlap.i--input(custom).re
new file mode 100644 (file)
index 0000000..986fac7
--- /dev/null
@@ -0,0 +1,5 @@
+/*!re2c
+    "ab" / "c"* {}
+    "a"  / "b"* {}
+    *           {}
+*/
diff --git a/re2c/test/contexts/overlap.i.c b/re2c/test/contexts/overlap.i.c
new file mode 100644 (file)
index 0000000..4f023ac
--- /dev/null
@@ -0,0 +1,54 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       YYDISTTYPE yyctx0, yyctx1;
+       YYCTXMARKER = YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+       {}
+yy4:
+       ++YYCURSOR;
+       yyctx1 = (YYCURSOR - YYCTXMARKER);
+       switch ((yych = *YYCURSOR)) {
+       case 'b':       goto yy6;
+       default:        goto yy5;
+       }
+yy5:
+       YYCURSOR = YYCTXMARKER + yyctx1;
+       {}
+yy6:
+       ++YYCURSOR;
+       yyctx0 = (YYCURSOR - YYCTXMARKER);
+       switch ((yych = *YYCURSOR)) {
+       case 'b':       goto yy8;
+       case 'c':       goto yy10;
+       default:        goto yy7;
+       }
+yy7:
+       YYCURSOR = YYCTXMARKER + yyctx0;
+       {}
+yy8:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy8;
+       default:        goto yy5;
+       }
+yy10:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy10;
+       default:        goto yy7;
+       }
+}
+
diff --git a/re2c/test/contexts/overlap.i.re b/re2c/test/contexts/overlap.i.re
new file mode 100644 (file)
index 0000000..986fac7
--- /dev/null
@@ -0,0 +1,5 @@
+/*!re2c
+    "ab" / "c"* {}
+    "a"  / "b"* {}
+    *           {}
+*/
diff --git a/re2c/test/contexts/selfoverlap1.i--contexts.c b/re2c/test/contexts/selfoverlap1.i--contexts.c
new file mode 100644 (file)
index 0000000..79a68ab
--- /dev/null
@@ -0,0 +1 @@
+re2c: error: line 20: context p1 is self-overlapping [-Werror-selfoverlapping-contexts]
diff --git a/re2c/test/contexts/selfoverlap1.i--contexts.re b/re2c/test/contexts/selfoverlap1.i--contexts.re
new file mode 100644 (file)
index 0000000..9145a03
--- /dev/null
@@ -0,0 +1,29 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "a"+ @p1 "a"+ {
+            printf("'%.*s', '%.*s'\n",
+                @p1 - YYCTXMARKER, YYCTXMARKER,
+                YYCURSOR - @p1, @p1);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/selfoverlap1_trail.i--contexts.c b/re2c/test/contexts/selfoverlap1_trail.i--contexts.c
new file mode 100644 (file)
index 0000000..8d0af52
--- /dev/null
@@ -0,0 +1 @@
+re2c: error: line 20: trailing context is self-overlapping [-Werror-selfoverlapping-contexts]
diff --git a/re2c/test/contexts/selfoverlap1_trail.i--contexts.re b/re2c/test/contexts/selfoverlap1_trail.i--contexts.re
new file mode 100644 (file)
index 0000000..f553a5e
--- /dev/null
@@ -0,0 +1,29 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+#define YYDISTTYPE ptrdiff_t
+    const char *YYMARKER;
+    const char *YYCTXMARKER;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "" @p0 "a"+ / "a"+ {
+            printf("'%.*s', '%s'\n",
+                YYCURSOR - @p0, @p0,
+                YYCURSOR);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
diff --git a/re2c/test/contexts/selfoverlap1_trail.i.c b/re2c/test/contexts/selfoverlap1_trail.i.c
new file mode 100644 (file)
index 0000000..9aa2e88
--- /dev/null
@@ -0,0 +1,55 @@
+/* Generated by re2c */
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+    const char *YYCTXMARKER;
+    const char *token = YYCURSOR;
+    
+{
+       char yych;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+yy3:
+       { printf("error\n"); return; }
+yy4:
+       yych = *++YYCURSOR;
+       YYCTXMARKER = YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy5;
+       default:        goto yy3;
+       }
+yy5:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       YYCTXMARKER = YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy5;
+       default:        goto yy7;
+       }
+yy7:
+       YYCURSOR = YYCTXMARKER;
+       {
+            printf("'%.*s', '%s'\n",
+                YYCURSOR - token, token,
+                YYCURSOR);
+                return;
+        }
+}
+
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
+re2c: warning: line 19: trailing context is self-overlapping [-Wselfoverlapping-contexts]
diff --git a/re2c/test/contexts/selfoverlap1_trail.i.re b/re2c/test/contexts/selfoverlap1_trail.i.re
new file mode 100644 (file)
index 0000000..32db9cb
--- /dev/null
@@ -0,0 +1,28 @@
+#include <stddef.h>
+#include <stdio.h>
+
+static void lex(const char *YYCURSOR)
+{
+    const char *YYCTXMARKER;
+    const char *token = YYCURSOR;
+    /*!re2c
+        re2c:define:YYCTYPE = char;
+        re2c:yyfill:enable = 0;
+
+        * { printf("error\n"); return; }
+        "a"+ / "a"+ {
+            printf("'%.*s', '%s'\n",
+                YYCURSOR - token, token,
+                YYCURSOR);
+                return;
+        }
+    */
+}
+
+int main(int argc, char **argv)
+{
+    for (int i = 1; i < argc; ++i) {
+        lex(argv[i]);
+    }
+    return 0;
+}
index a791a5b5ca9836e0a2470deb43cc3ed59be2a723..238c64a8d70d060200247450940a7b4856566ad4 100644 (file)
@@ -7,14 +7,15 @@
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        goto yy3;
+       YYCURSOR -= 0;
 #line 3 "input6.--empty-class(match-empty).re"
        { return 0; }
-#line 13 "input6.--empty-class(match-empty).c"
+#line 14 "input6.--empty-class(match-empty).c"
 yy3:
        ++YYCURSOR;
 #line 4 "input6.--empty-class(match-empty).re"
        { return 1; }
-#line 18 "input6.--empty-class(match-empty).c"
+#line 19 "input6.--empty-class(match-empty).c"
 }
 #line 6 "input6.--empty-class(match-empty).re"
 
index f7c39370d9f0aa0a92bf2a192bec9455a257ac76..410ad5815229a9f5b378d4c1d65c3b38eb424c4e 100644 (file)
@@ -7,14 +7,15 @@
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        goto yy3;
+       YYCURSOR -= 0;
 #line 3 "input6.re"
        { return 0; }
-#line 13 "input6.c"
+#line 14 "input6.c"
 yy3:
        ++YYCURSOR;
 #line 4 "input6.re"
        { return 1; }
-#line 18 "input6.c"
+#line 19 "input6.c"
 }
 #line 6 "input6.re"