]> granicus.if.org Git - re2c/commitdiff
Parse character strings in lexer.
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 19 Aug 2015 17:31:04 +0000 (18:31 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 19 Aug 2015 17:31:04 +0000 (18:31 +0100)
This commit is a continuation of e42f271e4b284cd6ed590dc06a5239ce13942fc5:
"Parse character classes in lexer." It makes lexer parse individual code
points instead of barely recognizing string of code points.

Since the contents of case sensitive strings, case insensitive strings
and character classes are lexically the same (except for escaped quotes
or closing bracket), we can parse them all in the same lexer block.

Note that re2c allows any 1-byte code points. Maybe we should report
non-ASCII or non-printables.

re2c/bootstrap/src/parse/scanner_lex.cc
re2c/src/ir/regexp/regexp.cc
re2c/src/parse/scanner.h
re2c/src/parse/scanner_lex.re
re2c/test/input_custom_mjson.--input(custom).c
re2c/test/php20150211_zend_language_scanner.cDF--case-inverted.c
re2c/test/php20150211_zend_language_scanner.igcFd--case-inverted.c

index 1c9b109edfd015e50c6e725c8f76f9080c87699e..f907bfc034036c860fafbe882d6db52634a33b0f 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.14.3 on Tue Aug 18 21:48:49 2015 */
+/* Generated by re2c 0.14.3 on Wed Aug 19 17:56:07 2015 */
 #line 1 "../src/parse/scanner_lex.re"
 #include <stdlib.h>
 #include <string.h>
@@ -32,7 +32,7 @@ namespace re2c
 #line 32 "../src/parse/scanner_lex.re"
 
 
-#line 50 "../src/parse/scanner_lex.re"
+#line 56 "../src/parse/scanner_lex.re"
 
 
 Scanner::ParseMode Scanner::echo()
@@ -107,7 +107,7 @@ echo:
                }
        }
        ++YYCURSOR;
-#line 193 "../src/parse/scanner_lex.re"
+#line 199 "../src/parse/scanner_lex.re"
        {
                                        if (!(ignore_eoc || DFlag || flag_skeleton))
                                        {
@@ -123,7 +123,7 @@ echo:
 yy4:
        ++YYCURSOR;
 yy5:
-#line 204 "../src/parse/scanner_lex.re"
+#line 210 "../src/parse/scanner_lex.re"
        {
                                        goto echo;
                                }
@@ -136,7 +136,7 @@ yy6:
        }
        if (yych == '#') goto yy91;
 yy7:
-#line 180 "../src/parse/scanner_lex.re"
+#line 186 "../src/parse/scanner_lex.re"
        {
                                        if (ignore_eoc)
                                        {
@@ -234,7 +234,7 @@ yy21:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 81 "../src/parse/scanner_lex.re"
+#line 87 "../src/parse/scanner_lex.re"
        {
                                        if (rFlag)
                                        {
@@ -253,7 +253,7 @@ yy31:
        if (yych != 'c') goto yy12;
 yy32:
        ++YYCURSOR;
-#line 66 "../src/parse/scanner_lex.re"
+#line 72 "../src/parse/scanner_lex.re"
        {
                                        if (rFlag)
                                        {
@@ -284,7 +284,7 @@ yy34:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 93 "../src/parse/scanner_lex.re"
+#line 99 "../src/parse/scanner_lex.re"
        {
                                        if (!rFlag)
                                        {
@@ -314,7 +314,7 @@ yy42:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 107 "../src/parse/scanner_lex.re"
+#line 113 "../src/parse/scanner_lex.re"
        {
                                        if (!DFlag)
                                        {
@@ -349,7 +349,7 @@ yy50:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 116 "../src/parse/scanner_lex.re"
+#line 122 "../src/parse/scanner_lex.re"
        {
                                        tok = pos = cur;
                                        out.insert_state_goto (topIndent);
@@ -377,7 +377,7 @@ yy63:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 122 "../src/parse/scanner_lex.re"
+#line 128 "../src/parse/scanner_lex.re"
        {
                                        tok = pos = cur;
                                        ignore_eoc = true;
@@ -402,7 +402,7 @@ yy74:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych != 'c') goto yy12;
        ++YYCURSOR;
-#line 127 "../src/parse/scanner_lex.re"
+#line 133 "../src/parse/scanner_lex.re"
        {
                                        tok = pos = cur;
                                        ignore_eoc = true;
@@ -423,7 +423,7 @@ yy84:
        if (yych == '\n') goto yy87;
        if (yych == '\r') goto yy86;
 yy85:
-#line 158 "../src/parse/scanner_lex.re"
+#line 164 "../src/parse/scanner_lex.re"
        {
                                        if (ignore_eoc)
                                        {
@@ -448,7 +448,7 @@ yy86:
        if (yych != '\n') goto yy12;
 yy87:
        ++YYCURSOR;
-#line 140 "../src/parse/scanner_lex.re"
+#line 146 "../src/parse/scanner_lex.re"
        {
                                        cline++;
                                        if (ignore_eoc)
@@ -542,7 +542,7 @@ yy101:
 yy103:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 176 "../src/parse/scanner_lex.re"
+#line 182 "../src/parse/scanner_lex.re"
        {
                                        set_sourceline ();
                                        goto echo;
@@ -572,7 +572,7 @@ yy109:
        if (yych == '\r') goto yy105;
        goto yy12;
 }
-#line 207 "../src/parse/scanner_lex.re"
+#line 213 "../src/parse/scanner_lex.re"
 
 }
 
@@ -580,6 +580,7 @@ int Scanner::scan()
 {
        uint32_t depth;
 
+       char quote;
        bool negated_class = false;
        std::vector<uint32_t> cpoints;
 scan:
@@ -596,43 +597,43 @@ scan:
 
 start:
 
-#line 600 "src/parse/scanner_lex.cc"
+#line 601 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        unsigned int yyaccept = 0;
        static const unsigned char yybm[] = {
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 224,   0, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               224, 192,  64, 192, 192, 192, 192, 128, 
-               192, 192, 192, 192, 192, 192, 192, 192
-               216, 216, 216, 216, 216, 216, 216, 216, 
-               216, 216, 192, 192, 192, 192, 192, 192
-               192, 208, 208, 208, 208, 208, 208, 208
-               208, 208, 208, 208, 208, 208, 208, 208
-               208, 208, 208, 208, 208, 208, 208, 208
-               208, 208, 208, 192,   0, 192, 192, 208
-               192, 208, 208, 208, 208, 208, 208, 208
-               208, 208, 208, 208, 208, 208, 208, 208
-               208, 208, 208, 208, 208, 208, 208, 208
-               208, 208, 208, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
-               192, 192, 192, 192, 192, 192, 192, 192
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 192,   0, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               192, 128,   0, 128, 128, 128, 128, 128, 
+               128, 128, 128, 128, 128, 128, 128, 128
+               176, 176, 176, 176, 176, 176, 176, 176, 
+               176, 176, 128, 128, 128, 128, 128, 128
+               128, 160, 160, 160, 160, 160, 160, 160
+               160, 160, 160, 160, 160, 160, 160, 160
+               160, 160, 160, 160, 160, 160, 160, 160
+               160, 160, 160, 128,   0, 128, 128, 160
+               128, 160, 160, 160, 160, 160, 160, 160
+               160, 160, 160, 160, 160, 160, 160, 160
+               160, 160, 160, 160, 160, 160, 160, 160
+               160, 160, 160, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
+               128, 128, 128, 128, 128, 128, 128, 128
        };
        if ((YYLIMIT - YYCURSOR) < 6) YYFILL(6);
        yych = (YYCTYPE)*YYCURSOR;
@@ -656,16 +657,16 @@ start:
                                        if (yych >= '%') goto yy121;
                                } else {
                                        if (yych <= '&') goto yy112;
-                                       if (yych <= '\'') goto yy122;
-                                       goto yy124;
+                                       if (yych <= '\'') goto yy119;
+                                       goto yy122;
                                }
                        } else {
                                if (yych <= '+') {
-                                       if (yych <= '*') goto yy126;
-                                       goto yy128;
+                                       if (yych <= '*') goto yy124;
+                                       goto yy126;
                                } else {
-                                       if (yych <= ',') goto yy124;
-                                       if (yych >= '.') goto yy130;
+                                       if (yych <= ',') goto yy122;
+                                       if (yych >= '.') goto yy128;
                                }
                        }
                }
@@ -673,37 +674,37 @@ start:
                if (yych <= '[') {
                        if (yych <= '<') {
                                if (yych <= '9') {
-                                       if (yych <= '/') goto yy132;
-                                       goto yy133;
+                                       if (yych <= '/') goto yy130;
+                                       goto yy131;
                                } else {
-                                       if (yych <= ':') goto yy134;
-                                       if (yych <= ';') goto yy124;
-                                       goto yy135;
+                                       if (yych <= ':') goto yy132;
+                                       if (yych <= ';') goto yy122;
+                                       goto yy133;
                                }
                        } else {
                                if (yych <= '?') {
-                                       if (yych <= '>') goto yy124;
-                                       goto yy128;
+                                       if (yych <= '>') goto yy122;
+                                       goto yy126;
                                } else {
                                        if (yych <= '@') goto yy112;
-                                       if (yych <= 'Z') goto yy133;
-                                       goto yy136;
+                                       if (yych <= 'Z') goto yy131;
+                                       goto yy134;
                                }
                        }
                } else {
                        if (yych <= 'q') {
                                if (yych <= '^') {
-                                       if (yych <= '\\') goto yy124;
+                                       if (yych <= '\\') goto yy122;
                                } else {
-                                       if (yych != '`') goto yy133;
+                                       if (yych != '`') goto yy131;
                                }
                        } else {
                                if (yych <= 'z') {
-                                       if (yych <= 'r') goto yy138;
-                                       goto yy133;
+                                       if (yych <= 'r') goto yy136;
+                                       goto yy131;
                                } else {
-                                       if (yych <= '{') goto yy139;
-                                       if (yych <= '|') goto yy124;
+                                       if (yych <= '{') goto yy137;
+                                       if (yych <= '|') goto yy122;
                                }
                        }
                }
@@ -711,224 +712,201 @@ start:
 yy112:
        ++YYCURSOR;
 yy113:
-#line 422 "../src/parse/scanner_lex.re"
+#line 397 "../src/parse/scanner_lex.re"
        {
                                        fatalf("unexpected character: '%c'", *tok);
                                        goto scan;
                                }
-#line 720 "src/parse/scanner_lex.cc"
+#line 721 "src/parse/scanner_lex.cc"
 yy114:
        ++YYCURSOR;
        yych = (YYCTYPE)*YYCURSOR;
-       goto yy236;
+       goto yy224;
 yy115:
-#line 406 "../src/parse/scanner_lex.re"
+#line 381 "../src/parse/scanner_lex.re"
        {
                                        goto scan;
                                }
-#line 730 "src/parse/scanner_lex.cc"
+#line 731 "src/parse/scanner_lex.cc"
 yy116:
        yyaccept = 0;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy214;
+               if (yych == '\t') goto yy202;
        } else {
-               if (yych <= ' ') goto yy214;
-               if (yych == '#') goto yy216;
+               if (yych <= ' ') goto yy202;
+               if (yych == '#') goto yy204;
        }
 yy117:
-#line 415 "../src/parse/scanner_lex.re"
+#line 390 "../src/parse/scanner_lex.re"
        {
                                        if (cur == eof) return 0;
                                        pos = cur;
                                        cline++;
                                        goto scan;
                                }
-#line 748 "src/parse/scanner_lex.cc"
+#line 749 "src/parse/scanner_lex.cc"
 yy118:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy213;
+       if (yych == '\n') goto yy201;
        goto yy113;
 yy119:
-       yyaccept = 1;
-       yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych != '\n') goto yy209;
-yy120:
-#line 285 "../src/parse/scanner_lex.re"
-       {
-                                       fatal("unterminated string constant (missing \")");
-                               }
-#line 762 "src/parse/scanner_lex.cc"
+       ++YYCURSOR;
+#line 266 "../src/parse/scanner_lex.re"
+       { quote = tok[0];                    goto cpoints; }
+#line 758 "src/parse/scanner_lex.cc"
 yy121:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '}') goto yy201;
+       if (yych == '}') goto yy199;
        goto yy113;
 yy122:
-       yyaccept = 2;
-       yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych != '\n') goto yy204;
-yy123:
-#line 288 "../src/parse/scanner_lex.re"
-       {
-                                       fatal("unterminated string constant (missing ')");
-                               }
-#line 776 "src/parse/scanner_lex.cc"
-yy124:
        ++YYCURSOR;
-yy125:
-#line 301 "../src/parse/scanner_lex.re"
+yy123:
+#line 276 "../src/parse/scanner_lex.re"
        {
                                        return *tok;
                                }
-#line 784 "src/parse/scanner_lex.cc"
-yy126:
+#line 770 "src/parse/scanner_lex.cc"
+yy124:
        ++YYCURSOR;
-       if ((yych = (YYCTYPE)*YYCURSOR) == '/') goto yy201;
-#line 305 "../src/parse/scanner_lex.re"
+       if ((yych = (YYCTYPE)*YYCURSOR) == '/') goto yy199;
+#line 280 "../src/parse/scanner_lex.re"
        {
                                        yylval.op = *tok;
                                        return STAR;
                                }
-#line 793 "src/parse/scanner_lex.cc"
-yy128:
+#line 779 "src/parse/scanner_lex.cc"
+yy126:
        ++YYCURSOR;
-#line 309 "../src/parse/scanner_lex.re"
+#line 284 "../src/parse/scanner_lex.re"
        {
                                        yylval.op = *tok;
                                        return CLOSE;
                                }
-#line 801 "src/parse/scanner_lex.cc"
-yy130:
+#line 787 "src/parse/scanner_lex.cc"
+yy128:
        ++YYCURSOR;
-#line 401 "../src/parse/scanner_lex.re"
+#line 376 "../src/parse/scanner_lex.re"
        {
                                        yylval.regexp = mkDot();
                                        return RANGE;
                                }
-#line 809 "src/parse/scanner_lex.cc"
-yy132:
+#line 795 "src/parse/scanner_lex.cc"
+yy130:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '*') goto yy197;
-       if (yych == '/') goto yy199;
-       goto yy125;
-yy133:
+       if (yych == '*') goto yy195;
+       if (yych == '/') goto yy197;
+       goto yy123;
+yy131:
        YYCTXMARKER = YYCURSOR + 1;
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy165;
-yy134:
+       goto yy163;
+yy132:
        YYCTXMARKER = YYCURSOR + 1;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '=') goto yy193;
+       if (yych == '=') goto yy191;
        goto yy113;
-yy135:
-       yyaccept = 3;
+yy133:
+       yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == '!') goto yy184;
-       if (yych == '>') goto yy186;
-       goto yy125;
-yy136:
+       if (yych == '!') goto yy182;
+       if (yych == '>') goto yy184;
+       goto yy123;
+yy134:
        ++YYCURSOR;
-       if ((yych = (YYCTYPE)*YYCURSOR) == '^') goto yy182;
-#line 292 "../src/parse/scanner_lex.re"
-       {                       goto cpoint_class; }
-#line 835 "src/parse/scanner_lex.cc"
-yy138:
+       if ((yych = (YYCTYPE)*YYCURSOR) == '^') goto yy180;
+#line 267 "../src/parse/scanner_lex.re"
+       { quote = ']';                       goto cpoints; }
+#line 821 "src/parse/scanner_lex.cc"
+yy136:
        YYCTXMARKER = YYCURSOR + 1;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == 'e') goto yy166;
-       goto yy165;
-yy139:
-       yyaccept = 4;
+       if (yych == 'e') goto yy164;
+       goto yy163;
+yy137:
+       yyaccept = 2;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yybm[0+yych] & 8) {
-               goto yy141;
+       if (yybm[0+yych] & 16) {
+               goto yy139;
        }
        if (yych <= 'Z') {
-               if (yych == ',') goto yy146;
-               if (yych >= 'A') goto yy144;
+               if (yych == ',') goto yy144;
+               if (yych >= 'A') goto yy142;
        } else {
                if (yych <= '_') {
-                       if (yych >= '_') goto yy144;
+                       if (yych >= '_') goto yy142;
                } else {
-                       if (yych <= '`') goto yy140;
-                       if (yych <= 'z') goto yy144;
+                       if (yych <= '`') goto yy138;
+                       if (yych <= 'z') goto yy142;
                }
        }
-yy140:
-#line 230 "../src/parse/scanner_lex.re"
+yy138:
+#line 237 "../src/parse/scanner_lex.re"
        {
                                        depth = 1;
                                        goto code;
                                }
-#line 864 "src/parse/scanner_lex.cc"
-yy141:
+#line 850 "src/parse/scanner_lex.cc"
+yy139:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yybm[0+yych] & 8) {
-               goto yy141;
+       if (yybm[0+yych] & 16) {
+               goto yy139;
        }
        if (yych <= '^') {
                if (yych <= ',') {
-                       if (yych >= ',') goto yy152;
+                       if (yych >= ',') goto yy150;
                } else {
-                       if (yych <= '@') goto yy143;
-                       if (yych <= 'Z') goto yy144;
+                       if (yych <= '@') goto yy141;
+                       if (yych <= 'Z') goto yy142;
                }
        } else {
                if (yych <= 'z') {
-                       if (yych != '`') goto yy144;
+                       if (yych != '`') goto yy142;
                } else {
-                       if (yych == '}') goto yy150;
+                       if (yych == '}') goto yy148;
                }
        }
-yy143:
+yy141:
        YYCURSOR = YYMARKER;
-       if (yyaccept <= 3) {
+       if (yyaccept <= 2) {
                if (yyaccept <= 1) {
                        if (yyaccept == 0) {
                                goto yy117;
                        } else {
-                               goto yy120;
-                       }
-               } else {
-                       if (yyaccept == 2) {
                                goto yy123;
-                       } else {
-                               goto yy125;
                        }
+               } else {
+                       goto yy138;
                }
        } else {
-               if (yyaccept <= 5) {
-                       if (yyaccept == 4) {
-                               goto yy140;
-                       } else {
-                               goto yy147;
-                       }
+               if (yyaccept == 3) {
+                       goto yy145;
                } else {
-                       goto yy172;
+                       goto yy170;
                }
        }
-yy144:
+yy142:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yybm[0+yych] & 16) {
-               goto yy144;
+       if (yybm[0+yych] & 32) {
+               goto yy142;
        }
-       if (yych == '}') goto yy148;
-       goto yy143;
-yy146:
+       if (yych == '}') goto yy146;
+       goto yy141;
+yy144:
        ++YYCURSOR;
-yy147:
-#line 345 "../src/parse/scanner_lex.re"
+yy145:
+#line 320 "../src/parse/scanner_lex.re"
        {
                                        fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers");
                                }
-#line 929 "src/parse/scanner_lex.cc"
-yy148:
+#line 907 "src/parse/scanner_lex.cc"
+yy146:
        ++YYCURSOR;
-#line 349 "../src/parse/scanner_lex.re"
+#line 324 "../src/parse/scanner_lex.re"
        {
                                        if (!FFlag) {
                                                fatal("curly braces for names only allowed with -F switch");
@@ -936,10 +914,10 @@ yy148:
                                        yylval.str = new std::string (tok + 1, tok_len () - 2); // -2 to omit braces
                                        return ID;
                                }
-#line 940 "src/parse/scanner_lex.cc"
-yy150:
+#line 918 "src/parse/scanner_lex.cc"
+yy148:
        ++YYCURSOR;
-#line 314 "../src/parse/scanner_lex.re"
+#line 289 "../src/parse/scanner_lex.re"
        {
                                        if (!s_to_u32_unsafe (tok + 1, cur - 1, yylval.extop.min))
                                        {
@@ -948,15 +926,15 @@ yy150:
                                        yylval.extop.max = yylval.extop.min;
                                        return CLOSESIZE;
                                }
-#line 952 "src/parse/scanner_lex.cc"
-yy152:
-       yyaccept = 5;
+#line 930 "src/parse/scanner_lex.cc"
+yy150:
+       yyaccept = 3;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych <= '/') goto yy147;
-       if (yych <= '9') goto yy155;
-       if (yych != '}') goto yy147;
+       if (yych <= '/') goto yy145;
+       if (yych <= '9') goto yy153;
+       if (yych != '}') goto yy145;
        ++YYCURSOR;
-#line 336 "../src/parse/scanner_lex.re"
+#line 311 "../src/parse/scanner_lex.re"
        {
                                        if (!s_to_u32_unsafe (tok + 1, cur - 2, yylval.extop.min))
                                        {
@@ -965,16 +943,16 @@ yy152:
                                        yylval.extop.max = UINT32_MAX;
                                        return CLOSESIZE;
                                }
-#line 969 "src/parse/scanner_lex.cc"
-yy155:
+#line 947 "src/parse/scanner_lex.cc"
+yy153:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych <= '/') goto yy143;
-       if (yych <= '9') goto yy155;
-       if (yych != '}') goto yy143;
+       if (yych <= '/') goto yy141;
+       if (yych <= '9') goto yy153;
+       if (yych != '}') goto yy141;
        ++YYCURSOR;
-#line 323 "../src/parse/scanner_lex.re"
+#line 298 "../src/parse/scanner_lex.re"
        {
                                        const char * p = strchr (tok, ',');
                                        if (!s_to_u32_unsafe (tok + 1, p, yylval.extop.min))
@@ -987,12 +965,12 @@ yy155:
                                        }
                                        return CLOSESIZE;
                                }
-#line 991 "src/parse/scanner_lex.cc"
-yy159:
+#line 969 "src/parse/scanner_lex.cc"
+yy157:
        ++YYCURSOR;
-yy160:
+yy158:
        YYCURSOR = YYCTXMARKER;
-#line 382 "../src/parse/scanner_lex.re"
+#line 357 "../src/parse/scanner_lex.re"
        {
                                        if (!FFlag) {
                                                yylval.str = new std::string (tok, tok_len ());
@@ -1011,165 +989,165 @@ yy160:
                                                return STRING;
                                        }
                                }
-#line 1015 "src/parse/scanner_lex.cc"
-yy161:
+#line 993 "src/parse/scanner_lex.cc"
+yy159:
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy180;
-yy162:
+       goto yy178;
+yy160:
        ++YYCURSOR;
-yy163:
+yy161:
        YYCURSOR = YYCTXMARKER;
-#line 377 "../src/parse/scanner_lex.re"
+#line 352 "../src/parse/scanner_lex.re"
        {
                                        yylval.str = new std::string (tok, tok_len ());
                                        return ID;
                                }
-#line 1028 "src/parse/scanner_lex.cc"
-yy164:
+#line 1006 "src/parse/scanner_lex.cc"
+yy162:
        YYCTXMARKER = YYCURSOR + 1;
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
-yy165:
+yy163:
        if (yych <= '9') {
                if (yych <= ' ') {
-                       if (yych == '\t') goto yy161;
-                       if (yych <= 0x1F) goto yy159;
-                       goto yy161;
+                       if (yych == '\t') goto yy159;
+                       if (yych <= 0x1F) goto yy157;
+                       goto yy159;
                } else {
-                       if (yych == ',') goto yy162;
-                       if (yych <= '/') goto yy159;
-                       goto yy164;
+                       if (yych == ',') goto yy160;
+                       if (yych <= '/') goto yy157;
+                       goto yy162;
                }
        } else {
                if (yych <= 'Z') {
-                       if (yych <= '<') goto yy159;
-                       if (yych <= '>') goto yy162;
-                       if (yych <= '@') goto yy159;
-                       goto yy164;
+                       if (yych <= '<') goto yy157;
+                       if (yych <= '>') goto yy160;
+                       if (yych <= '@') goto yy157;
+                       goto yy162;
                } else {
                        if (yych <= '_') {
-                               if (yych <= '^') goto yy159;
-                               goto yy164;
+                               if (yych <= '^') goto yy157;
+                               goto yy162;
                        } else {
-                               if (yych <= '`') goto yy159;
-                               if (yych <= 'z') goto yy164;
-                               goto yy159;
+                               if (yych <= '`') goto yy157;
+                               if (yych <= 'z') goto yy162;
+                               goto yy157;
                        }
                }
        }
-yy166:
+yy164:
        YYCTXMARKER = YYCURSOR + 1;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != '2') goto yy165;
+       if (yych != '2') goto yy163;
        YYCTXMARKER = YYCURSOR + 1;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'c') goto yy165;
+       if (yych != 'c') goto yy163;
        YYCTXMARKER = YYCURSOR + 1;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != ':') goto yy165;
+       if (yych != ':') goto yy163;
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= 'Z') {
-               if (yych <= '/') goto yy160;
-               if (yych <= '9') goto yy170;
-               if (yych <= '@') goto yy160;
+               if (yych <= '/') goto yy158;
+               if (yych <= '9') goto yy168;
+               if (yych <= '@') goto yy158;
        } else {
                if (yych <= '_') {
-                       if (yych <= '^') goto yy160;
+                       if (yych <= '^') goto yy158;
                } else {
-                       if (yych <= '`') goto yy160;
-                       if (yych >= '{') goto yy160;
+                       if (yych <= '`') goto yy158;
+                       if (yych >= '{') goto yy158;
                }
        }
-yy170:
-       yyaccept = 6;
+yy168:
+       yyaccept = 4;
        YYMARKER = ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '@') {
                if (yych <= '9') {
-                       if (yych >= '0') goto yy170;
+                       if (yych >= '0') goto yy168;
                } else {
-                       if (yych <= ':') goto yy174;
-                       if (yych >= '@') goto yy173;
+                       if (yych <= ':') goto yy172;
+                       if (yych >= '@') goto yy171;
                }
        } else {
                if (yych <= '_') {
-                       if (yych <= 'Z') goto yy170;
-                       if (yych >= '_') goto yy170;
+                       if (yych <= 'Z') goto yy168;
+                       if (yych >= '_') goto yy168;
                } else {
-                       if (yych <= '`') goto yy172;
-                       if (yych <= 'z') goto yy170;
+                       if (yych <= '`') goto yy170;
+                       if (yych <= 'z') goto yy168;
                }
        }
-yy172:
-#line 357 "../src/parse/scanner_lex.re"
+yy170:
+#line 332 "../src/parse/scanner_lex.re"
        {
                                        tok += 5; /* skip "re2c:" */
                                        lexer_state = LEX_CONFIG;
                                        yylval.str = new std::string (tok, tok_len ());
                                        return CONFIG;
                                }
-#line 1114 "src/parse/scanner_lex.cc"
-yy173:
+#line 1092 "src/parse/scanner_lex.cc"
+yy171:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= 'Z') {
-               if (yych <= '/') goto yy143;
-               if (yych <= '9') goto yy175;
-               if (yych <= '@') goto yy143;
-               goto yy175;
+               if (yych <= '/') goto yy141;
+               if (yych <= '9') goto yy173;
+               if (yych <= '@') goto yy141;
+               goto yy173;
        } else {
                if (yych <= '_') {
-                       if (yych <= '^') goto yy143;
-                       goto yy175;
+                       if (yych <= '^') goto yy141;
+                       goto yy173;
                } else {
-                       if (yych <= '`') goto yy143;
-                       if (yych <= 'z') goto yy175;
-                       goto yy143;
+                       if (yych <= '`') goto yy141;
+                       if (yych <= 'z') goto yy173;
+                       goto yy141;
                }
        }
-yy174:
+yy172:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 'Z') {
-               if (yych <= '/') goto yy143;
-               if (yych <= '9') goto yy170;
-               if (yych <= '@') goto yy143;
-               goto yy170;
+               if (yych <= '/') goto yy141;
+               if (yych <= '9') goto yy168;
+               if (yych <= '@') goto yy141;
+               goto yy168;
        } else {
                if (yych <= '_') {
-                       if (yych <= '^') goto yy143;
-                       goto yy170;
+                       if (yych <= '^') goto yy141;
+                       goto yy168;
                } else {
-                       if (yych <= '`') goto yy143;
-                       if (yych <= 'z') goto yy170;
-                       goto yy143;
+                       if (yych <= '`') goto yy141;
+                       if (yych <= 'z') goto yy168;
+                       goto yy141;
                }
        }
-yy175:
+yy173:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 'Z') {
-               if (yych <= '/') goto yy172;
-               if (yych <= '9') goto yy175;
-               if (yych <= '@') goto yy172;
-               goto yy175;
+               if (yych <= '/') goto yy170;
+               if (yych <= '9') goto yy173;
+               if (yych <= '@') goto yy170;
+               goto yy173;
        } else {
                if (yych <= '_') {
-                       if (yych <= '^') goto yy172;
-                       goto yy175;
+                       if (yych <= '^') goto yy170;
+                       goto yy173;
                } else {
-                       if (yych <= '`') goto yy172;
-                       if (yych <= 'z') goto yy175;
-                       goto yy172;
+                       if (yych <= '`') goto yy170;
+                       if (yych <= 'z') goto yy173;
+                       goto yy170;
                }
        }
-yy177:
+yy175:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 364 "../src/parse/scanner_lex.re"
+#line 339 "../src/parse/scanner_lex.re"
        {
                                        yylval.str = new std::string (tok, tok_len ());
                                        if (FFlag)
@@ -1182,645 +1160,578 @@ yy177:
                                                return ID;
                                        }
                                }
-#line 1186 "src/parse/scanner_lex.cc"
-yy179:
+#line 1164 "src/parse/scanner_lex.cc"
+yy177:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy180:
-       if (yybm[0+yych] & 32) {
-               goto yy179;
+yy178:
+       if (yybm[0+yych] & 64) {
+               goto yy177;
        }
-       if (yych == ',') goto yy181;
-       if (yych <= '<') goto yy177;
-       if (yych >= '?') goto yy177;
-yy181:
+       if (yych == ',') goto yy179;
+       if (yych <= '<') goto yy175;
+       if (yych >= '?') goto yy175;
+yy179:
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy163;
-yy182:
+       goto yy161;
+yy180:
        ++YYCURSOR;
-#line 293 "../src/parse/scanner_lex.re"
-       { negated_class = true; goto cpoint_class; }
-#line 1205 "src/parse/scanner_lex.cc"
-yy184:
+#line 268 "../src/parse/scanner_lex.re"
+       { quote = ']'; negated_class = true; goto cpoints; }
+#line 1183 "src/parse/scanner_lex.cc"
+yy182:
        ++YYCURSOR;
-#line 298 "../src/parse/scanner_lex.re"
+#line 273 "../src/parse/scanner_lex.re"
        {
                                        return SETUP;
                                }
-#line 1212 "src/parse/scanner_lex.cc"
-yy186:
+#line 1190 "src/parse/scanner_lex.cc"
+yy184:
        YYCTXMARKER = YYCURSOR + 1;
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy188;
-yy187:
+       goto yy186;
+yy185:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
-yy188:
+yy186:
        if (yych <= '9') {
                if (yych <= '\t') {
-                       if (yych <= 0x08) goto yy143;
-                       goto yy187;
+                       if (yych <= 0x08) goto yy141;
+                       goto yy185;
                } else {
-                       if (yych == ' ') goto yy187;
-                       goto yy143;
+                       if (yych == ' ') goto yy185;
+                       goto yy141;
                }
        } else {
                if (yych <= '=') {
-                       if (yych <= ':') goto yy192;
-                       if (yych <= '<') goto yy143;
-                       goto yy191;
+                       if (yych <= ':') goto yy190;
+                       if (yych <= '<') goto yy141;
+                       goto yy189;
                } else {
-                       if (yych != '{') goto yy143;
+                       if (yych != '{') goto yy141;
                }
        }
-yy189:
+yy187:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 295 "../src/parse/scanner_lex.re"
+#line 270 "../src/parse/scanner_lex.re"
        {
                                        return NOCOND;
                                }
-#line 1246 "src/parse/scanner_lex.cc"
-yy191:
+#line 1224 "src/parse/scanner_lex.cc"
+yy189:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '>') goto yy189;
-       goto yy143;
-yy192:
+       if (yych == '>') goto yy187;
+       goto yy141;
+yy190:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '=') goto yy189;
-       goto yy143;
-yy193:
+       if (yych == '=') goto yy187;
+       goto yy141;
+yy191:
        ++YYCURSOR;
-       if ((yych = (YYCTYPE)*YYCURSOR) == '>') goto yy195;
-#line 239 "../src/parse/scanner_lex.re"
+       if ((yych = (YYCTYPE)*YYCURSOR) == '>') goto yy193;
+#line 246 "../src/parse/scanner_lex.re"
        {
                                        tok += 2; /* skip ":=" */
                                        depth = 0;
                                        goto code;
                                }
-#line 1264 "src/parse/scanner_lex.cc"
-yy195:
+#line 1242 "src/parse/scanner_lex.cc"
+yy193:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 235 "../src/parse/scanner_lex.re"
+#line 242 "../src/parse/scanner_lex.re"
        {
                                        return *tok;
                                }
-#line 1272 "src/parse/scanner_lex.cc"
-yy197:
+#line 1250 "src/parse/scanner_lex.cc"
+yy195:
        ++YYCURSOR;
-#line 248 "../src/parse/scanner_lex.re"
+#line 255 "../src/parse/scanner_lex.re"
        {
                                        depth = 1;
                                        goto comment;
                                }
-#line 1280 "src/parse/scanner_lex.cc"
-yy199:
+#line 1258 "src/parse/scanner_lex.cc"
+yy197:
        ++YYCURSOR;
-#line 245 "../src/parse/scanner_lex.re"
+#line 252 "../src/parse/scanner_lex.re"
        {
                                goto nextLine;
                        }
-#line 1287 "src/parse/scanner_lex.cc"
-yy201:
+#line 1265 "src/parse/scanner_lex.cc"
+yy199:
        ++YYCURSOR;
-#line 254 "../src/parse/scanner_lex.re"
+#line 261 "../src/parse/scanner_lex.re"
        {
                                        tok = cur;
                                        return 0;
                                }
-#line 1295 "src/parse/scanner_lex.cc"
-yy203:
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = (YYCTYPE)*YYCURSOR;
-yy204:
-       if (yybm[0+yych] & 64) {
-               goto yy203;
-       }
-       if (yych <= '\n') goto yy143;
-       if (yych <= '\'') goto yy206;
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy143;
-       goto yy203;
-yy206:
-       ++YYCURSOR;
-#line 272 "../src/parse/scanner_lex.re"
-       {
-                                       SubStr s (tok + 1, tok_len () - 2); // -2 to omit quotes
-                                       if (bCaseInverted)
-                                       {
-                                               yylval.regexp = strToRE (s);
-                                       }
-                                       else
-                                       {
-                                               yylval.regexp = strToCaseInsensitiveRE (s);
-                                       }
-                                       return STRING;
-                               }
-#line 1326 "src/parse/scanner_lex.cc"
-yy208:
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = (YYCTYPE)*YYCURSOR;
-yy209:
-       if (yybm[0+yych] & 128) {
-               goto yy208;
-       }
-       if (yych <= '\n') goto yy143;
-       if (yych <= '"') goto yy211;
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy143;
-       goto yy208;
-yy211:
-       ++YYCURSOR;
-#line 259 "../src/parse/scanner_lex.re"
-       {
-                                       SubStr s (tok + 1, tok_len () - 2); // -2 to omit quotes
-                                       if (bCaseInsensitive || bCaseInverted)
-                                       {
-                                               yylval.regexp = strToCaseInsensitiveRE (s);
-                                       }
-                                       else
-                                       {
-                                               yylval.regexp = strToRE (s);
-                                       }
-                                       return STRING;
-                               }
-#line 1357 "src/parse/scanner_lex.cc"
-yy213:
+#line 1273 "src/parse/scanner_lex.cc"
+yy201:
        yyaccept = 0;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= 0x1F) {
                if (yych != '\t') goto yy117;
        } else {
-               if (yych <= ' ') goto yy214;
-               if (yych == '#') goto yy216;
+               if (yych <= ' ') goto yy202;
+               if (yych == '#') goto yy204;
                goto yy117;
        }
-yy214:
+yy202:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy214;
-               goto yy143;
+               if (yych == '\t') goto yy202;
+               goto yy141;
        } else {
-               if (yych <= ' ') goto yy214;
-               if (yych != '#') goto yy143;
+               if (yych <= ' ') goto yy202;
+               if (yych != '#') goto yy141;
        }
-yy216:
+yy204:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy216;
-               goto yy143;
+               if (yych == '\t') goto yy204;
+               goto yy141;
        } else {
-               if (yych <= ' ') goto yy216;
-               if (yych != 'l') goto yy143;
+               if (yych <= ' ') goto yy204;
+               if (yych != 'l') goto yy141;
        }
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'i') goto yy143;
+       if (yych != 'i') goto yy141;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'n') goto yy143;
+       if (yych != 'n') goto yy141;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'e') goto yy143;
+       if (yych != 'e') goto yy141;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= '0') goto yy223;
-       if (yych <= '9') goto yy143;
-       goto yy223;
-yy222:
+       if (yych <= '0') goto yy211;
+       if (yych <= '9') goto yy141;
+       goto yy211;
+yy210:
        YYCTXMARKER = YYCURSOR + 1;
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy223:
+yy211:
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy222;
-               goto yy143;
+               if (yych == '\t') goto yy210;
+               goto yy141;
        } else {
-               if (yych <= ' ') goto yy222;
-               if (yych <= '0') goto yy143;
-               if (yych >= ':') goto yy143;
+               if (yych <= ' ') goto yy210;
+               if (yych <= '0') goto yy141;
+               if (yych >= ':') goto yy141;
        }
-yy224:
+yy212:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '\r') {
                if (yych <= '\t') {
-                       if (yych <= 0x08) goto yy143;
+                       if (yych <= 0x08) goto yy141;
                } else {
-                       if (yych <= '\n') goto yy228;
-                       if (yych <= '\f') goto yy143;
-                       goto yy230;
+                       if (yych <= '\n') goto yy216;
+                       if (yych <= '\f') goto yy141;
+                       goto yy218;
                }
        } else {
                if (yych <= ' ') {
-                       if (yych <= 0x1F) goto yy143;
+                       if (yych <= 0x1F) goto yy141;
                } else {
-                       if (yych <= '/') goto yy143;
-                       if (yych <= '9') goto yy224;
-                       goto yy143;
+                       if (yych <= '/') goto yy141;
+                       if (yych <= '9') goto yy212;
+                       goto yy141;
                }
        }
-yy226:
+yy214:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy226;
-               goto yy143;
+               if (yych == '\t') goto yy214;
+               goto yy141;
        } else {
-               if (yych <= ' ') goto yy226;
-               if (yych == '"') goto yy231;
-               goto yy143;
+               if (yych <= ' ') goto yy214;
+               if (yych == '"') goto yy219;
+               goto yy141;
        }
-yy228:
+yy216:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 410 "../src/parse/scanner_lex.re"
+#line 385 "../src/parse/scanner_lex.re"
        {
                                        set_sourceline ();
                                        goto scan;
                                }
-#line 1455 "src/parse/scanner_lex.cc"
-yy230:
+#line 1371 "src/parse/scanner_lex.cc"
+yy218:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy228;
-       goto yy143;
-yy231:
+       if (yych == '\n') goto yy216;
+       goto yy141;
+yy219:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych <= '!') {
-               if (yych == '\n') goto yy143;
-               goto yy231;
-       } else {
-               if (yych <= '"') goto yy234;
-               if (yych != '\\') goto yy231;
+       if (yybm[0+yych] & 128) {
+               goto yy219;
        }
+       if (yych <= '\n') goto yy141;
+       if (yych <= '"') goto yy222;
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy143;
-       goto yy231;
-yy234:
+       if (yych == '\n') goto yy141;
+       goto yy219;
+yy222:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy228;
-       if (yych == '\r') goto yy230;
-       goto yy143;
-yy235:
+       if (yych == '\n') goto yy216;
+       if (yych == '\r') goto yy218;
+       goto yy141;
+yy223:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy236:
-       if (yych == '\t') goto yy235;
-       if (yych == ' ') goto yy235;
+yy224:
+       if (yych == '\t') goto yy223;
+       if (yych == ' ') goto yy223;
        goto yy115;
 }
-#line 426 "../src/parse/scanner_lex.re"
+#line 401 "../src/parse/scanner_lex.re"
 
 
 flex_name:
 
-#line 1495 "src/parse/scanner_lex.cc"
+#line 1409 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy241;
-       if (yych == '\r') goto yy243;
+       if (yych == '\n') goto yy229;
+       if (yych == '\r') goto yy231;
        ++YYCURSOR;
-yy240:
-#line 437 "../src/parse/scanner_lex.re"
+yy228:
+#line 412 "../src/parse/scanner_lex.re"
        {
                YYCURSOR = tok;
                goto start;
        }
-#line 1509 "src/parse/scanner_lex.cc"
-yy241:
+#line 1423 "src/parse/scanner_lex.cc"
+yy229:
        ++YYCURSOR;
-yy242:
-#line 431 "../src/parse/scanner_lex.re"
+yy230:
+#line 406 "../src/parse/scanner_lex.re"
        {
                YYCURSOR = tok;
                lexer_state = LEX_NORMAL;
                return FID_END;
        }
-#line 1519 "src/parse/scanner_lex.cc"
-yy243:
+#line 1433 "src/parse/scanner_lex.cc"
+yy231:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != '\n') goto yy240;
+       if (yych != '\n') goto yy228;
        ++YYCURSOR;
        yych = (YYCTYPE)*YYCURSOR;
-       goto yy242;
+       goto yy230;
 }
-#line 441 "../src/parse/scanner_lex.re"
+#line 416 "../src/parse/scanner_lex.re"
 
 
-cpoint_class:
+cpoints:
        tok = cur;
 
-#line 1533 "src/parse/scanner_lex.cc"
+#line 1447 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        unsigned int yyaccept = 0;
        if ((YYLIMIT - YYCURSOR) < 10) YYFILL(10);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych <= '\\') {
-               if (yych <= 0x1F) goto yy247;
-               if (yych <= '[') goto yy249;
-               goto yy251;
-       } else {
-               if (yych <= ']') goto yy253;
-               if (yych <= '~') goto yy249;
-       }
-yy247:
+       if (yych != '\\') goto yy237;
        ++YYCURSOR;
-#line 453 "../src/parse/scanner_lex.re"
-       { fatal ((tok - pos) - tchar, "syntax error in character range"); }
-#line 1551 "src/parse/scanner_lex.cc"
-yy249:
-       ++YYCURSOR;
-#line 462 "../src/parse/scanner_lex.re"
-       { cpoints.push_back (static_cast<uint32_t> (tok[0])); goto cpoint_class; }
-#line 1556 "src/parse/scanner_lex.cc"
-yy251:
-       ++YYCURSOR;
-       if ((yych = (YYCTYPE)*YYCURSOR) <= 'b') {
-               if (yych <= 'U') {
-                       if (yych <= '3') {
-                               if (yych <= 0x1F) goto yy252;
-                               if (yych <= '/') goto yy255;
-                               goto yy257;
+       if ((yych = (YYCTYPE)*YYCURSOR) <= 'e') {
+               if (yych <= 'W') {
+                       if (yych <= '7') {
+                               if (yych <= '/') goto yy239;
+                               if (yych <= '3') goto yy241;
+                               goto yy243;
                        } else {
-                               if (yych <= '7') goto yy259;
-                               if (yych <= 'T') goto yy255;
-                               goto yy260;
+                               if (yych == 'U') goto yy244;
+                               goto yy239;
                        }
                } else {
-                       if (yych <= '[') {
-                               if (yych == 'X') goto yy262;
-                               goto yy255;
+                       if (yych <= '\\') {
+                               if (yych <= 'X') goto yy246;
+                               if (yych <= '[') goto yy239;
+                               goto yy247;
                        } else {
-                               if (yych <= '\\') goto yy263;
-                               if (yych <= ']') goto yy265;
-                               if (yych <= '`') goto yy255;
-                               goto yy263;
+                               if (yych <= '`') goto yy239;
+                               if (yych <= 'b') goto yy247;
+                               goto yy239;
                        }
                }
        } else {
                if (yych <= 's') {
-                       if (yych <= 'm') {
-                               if (yych == 'f') goto yy263;
-                               goto yy255;
+                       if (yych <= 'n') {
+                               if (yych <= 'f') goto yy247;
+                               if (yych <= 'm') goto yy239;
+                               goto yy247;
                        } else {
-                               if (yych <= 'n') goto yy263;
-                               if (yych == 'r') goto yy263;
-                               goto yy255;
+                               if (yych == 'r') goto yy247;
+                               goto yy239;
                        }
                } else {
                        if (yych <= 'v') {
-                               if (yych == 'u') goto yy262;
-                               goto yy263;
+                               if (yych == 'u') goto yy246;
+                               goto yy247;
                        } else {
-                               if (yych == 'x') goto yy267;
-                               if (yych <= '~') goto yy255;
+                               if (yych == 'x') goto yy249;
+                               goto yy239;
                        }
                }
        }
-yy252:
-#line 456 "../src/parse/scanner_lex.re"
+#line 423 "../src/parse/scanner_lex.re"
        { fatal ((tok - pos) - tchar, "syntax error in escape sequence"); }
-#line 1604 "src/parse/scanner_lex.cc"
-yy253:
+#line 1498 "src/parse/scanner_lex.cc"
+yy237:
        ++YYCURSOR;
-#line 471 "../src/parse/scanner_lex.re"
+#line 439 "../src/parse/scanner_lex.re"
        {
-               yylval.regexp = cpoint_class (cpoints, negated_class);
-               return RANGE;
+               const char c = tok[0];
+               if (c == quote)
+               {
+                       switch (quote)
+                       {
+                               case ']':
+                                       yylval.regexp = cpoint_class (cpoints, negated_class);
+                                       return RANGE;
+                               case '\'':
+                                       yylval.regexp = cpoint_string (cpoints, bCaseInsensitive || !bCaseInverted);
+                                       return STRING;
+                               case '"':
+                                       yylval.regexp = cpoint_string (cpoints, bCaseInsensitive || bCaseInverted);
+                                       return STRING;
+                       }
+               }
+               else
+               {
+                       cpoints.push_back (static_cast<uint32_t> (c));
+                       goto cpoints;
+               }
        }
-#line 1612 "src/parse/scanner_lex.cc"
-yy255:
+#line 1525 "src/parse/scanner_lex.cc"
+yy239:
        ++YYCURSOR;
-#line 464 "../src/parse/scanner_lex.re"
+#line 429 "../src/parse/scanner_lex.re"
        {
                const char c = tok[1];
-               warn.useless_escape (tline, tok - pos, c);
+               if (c != quote)
+               {
+                       warn.useless_escape (tline, tok - pos, c);
+               }
                cpoints.push_back (static_cast<uint32_t> (c));
-               goto cpoint_class;
+               goto cpoints;
        }
-#line 1622 "src/parse/scanner_lex.cc"
-yy257:
+#line 1538 "src/parse/scanner_lex.cc"
+yy241:
        yyaccept = 0;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych <= '/') goto yy258;
-       if (yych <= '7') goto yy282;
-yy258:
-#line 455 "../src/parse/scanner_lex.re"
+       if (yych <= '/') goto yy242;
+       if (yych <= '7') goto yy264;
+yy242:
+#line 422 "../src/parse/scanner_lex.re"
        { fatal ((tok - pos) - tchar, "syntax error in octal escape sequence"); }
-#line 1631 "src/parse/scanner_lex.cc"
-yy259:
+#line 1547 "src/parse/scanner_lex.cc"
+yy243:
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy258;
-yy260:
+       goto yy242;
+yy244:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= '@') {
-               if (yych <= '/') goto yy261;
-               if (yych <= '9') goto yy275;
+               if (yych <= '/') goto yy245;
+               if (yych <= '9') goto yy257;
        } else {
-               if (yych <= 'F') goto yy275;
-               if (yych <= '`') goto yy261;
-               if (yych <= 'f') goto yy275;
+               if (yych <= 'F') goto yy257;
+               if (yych <= '`') goto yy245;
+               if (yych <= 'f') goto yy257;
        }
-yy261:
-#line 454 "../src/parse/scanner_lex.re"
+yy245:
+#line 421 "../src/parse/scanner_lex.re"
        { fatal ((tok - pos) - tchar, "syntax error in hexadecimal escape sequence"); }
-#line 1649 "src/parse/scanner_lex.cc"
-yy262:
+#line 1565 "src/parse/scanner_lex.cc"
+yy246:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= '@') {
-               if (yych <= '/') goto yy261;
-               if (yych <= '9') goto yy272;
-               goto yy261;
+               if (yych <= '/') goto yy245;
+               if (yych <= '9') goto yy254;
+               goto yy245;
        } else {
-               if (yych <= 'F') goto yy272;
-               if (yych <= '`') goto yy261;
-               if (yych <= 'f') goto yy272;
-               goto yy261;
+               if (yych <= 'F') goto yy254;
+               if (yych <= '`') goto yy245;
+               if (yych <= 'f') goto yy254;
+               goto yy245;
        }
-yy263:
-       ++YYCURSOR;
-#line 460 "../src/parse/scanner_lex.re"
-       { cpoints.push_back (unesc_escapable (tok));          goto cpoint_class; }
-#line 1667 "src/parse/scanner_lex.cc"
-yy265:
+yy247:
        ++YYCURSOR;
-#line 461 "../src/parse/scanner_lex.re"
-       { cpoints.push_back (']');                            goto cpoint_class; }
-#line 1672 "src/parse/scanner_lex.cc"
-yy267:
+#line 427 "../src/parse/scanner_lex.re"
+       { cpoints.push_back (unesc_escapable (tok)); goto cpoints; }
+#line 1583 "src/parse/scanner_lex.cc"
+yy249:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= '@') {
-               if (yych <= '/') goto yy261;
-               if (yych >= ':') goto yy261;
+               if (yych <= '/') goto yy245;
+               if (yych >= ':') goto yy245;
        } else {
-               if (yych <= 'F') goto yy268;
-               if (yych <= '`') goto yy261;
-               if (yych >= 'g') goto yy261;
+               if (yych <= 'F') goto yy250;
+               if (yych <= '`') goto yy245;
+               if (yych >= 'g') goto yy245;
        }
-yy268:
+yy250:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy269;
-               if (yych <= '9') goto yy270;
+               if (yych <= '/') goto yy251;
+               if (yych <= '9') goto yy252;
        } else {
-               if (yych <= 'F') goto yy270;
-               if (yych <= '`') goto yy269;
-               if (yych <= 'f') goto yy270;
+               if (yych <= 'F') goto yy252;
+               if (yych <= '`') goto yy251;
+               if (yych <= 'f') goto yy252;
        }
-yy269:
+yy251:
        YYCURSOR = YYMARKER;
        if (yyaccept == 0) {
-               goto yy258;
+               goto yy242;
        } else {
-               goto yy261;
+               goto yy245;
        }
-yy270:
+yy252:
        ++YYCURSOR;
-#line 458 "../src/parse/scanner_lex.re"
-       { cpoints.push_back (unesc_hex (tok, cur));           goto cpoint_class; }
-#line 1705 "src/parse/scanner_lex.cc"
-yy272:
+#line 425 "../src/parse/scanner_lex.re"
+       { cpoints.push_back (unesc_hex (tok, cur));  goto cpoints; }
+#line 1616 "src/parse/scanner_lex.cc"
+yy254:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy269;
-               if (yych >= ':') goto yy269;
+               if (yych <= '/') goto yy251;
+               if (yych >= ':') goto yy251;
        } else {
-               if (yych <= 'F') goto yy273;
-               if (yych <= '`') goto yy269;
-               if (yych >= 'g') goto yy269;
+               if (yych <= 'F') goto yy255;
+               if (yych <= '`') goto yy251;
+               if (yych >= 'g') goto yy251;
        }
-yy273:
+yy255:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy269;
-               if (yych >= ':') goto yy269;
+               if (yych <= '/') goto yy251;
+               if (yych >= ':') goto yy251;
        } else {
-               if (yych <= 'F') goto yy274;
-               if (yych <= '`') goto yy269;
-               if (yych >= 'g') goto yy269;
+               if (yych <= 'F') goto yy256;
+               if (yych <= '`') goto yy251;
+               if (yych >= 'g') goto yy251;
        }
-yy274:
+yy256:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy269;
-               if (yych <= '9') goto yy270;
-               goto yy269;
+               if (yych <= '/') goto yy251;
+               if (yych <= '9') goto yy252;
+               goto yy251;
        } else {
-               if (yych <= 'F') goto yy270;
-               if (yych <= '`') goto yy269;
-               if (yych <= 'f') goto yy270;
-               goto yy269;
+               if (yych <= 'F') goto yy252;
+               if (yych <= '`') goto yy251;
+               if (yych <= 'f') goto yy252;
+               goto yy251;
        }
-yy275:
+yy257:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy269;
-               if (yych >= ':') goto yy269;
+               if (yych <= '/') goto yy251;
+               if (yych >= ':') goto yy251;
        } else {
-               if (yych <= 'F') goto yy276;
-               if (yych <= '`') goto yy269;
-               if (yych >= 'g') goto yy269;
+               if (yych <= 'F') goto yy258;
+               if (yych <= '`') goto yy251;
+               if (yych >= 'g') goto yy251;
        }
-yy276:
+yy258:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy269;
-               if (yych >= ':') goto yy269;
+               if (yych <= '/') goto yy251;
+               if (yych >= ':') goto yy251;
        } else {
-               if (yych <= 'F') goto yy277;
-               if (yych <= '`') goto yy269;
-               if (yych >= 'g') goto yy269;
+               if (yych <= 'F') goto yy259;
+               if (yych <= '`') goto yy251;
+               if (yych >= 'g') goto yy251;
        }
-yy277:
+yy259:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy269;
-               if (yych >= ':') goto yy269;
+               if (yych <= '/') goto yy251;
+               if (yych >= ':') goto yy251;
        } else {
-               if (yych <= 'F') goto yy278;
-               if (yych <= '`') goto yy269;
-               if (yych >= 'g') goto yy269;
+               if (yych <= 'F') goto yy260;
+               if (yych <= '`') goto yy251;
+               if (yych >= 'g') goto yy251;
        }
-yy278:
+yy260:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy269;
-               if (yych >= ':') goto yy269;
+               if (yych <= '/') goto yy251;
+               if (yych >= ':') goto yy251;
        } else {
-               if (yych <= 'F') goto yy279;
-               if (yych <= '`') goto yy269;
-               if (yych >= 'g') goto yy269;
+               if (yych <= 'F') goto yy261;
+               if (yych <= '`') goto yy251;
+               if (yych >= 'g') goto yy251;
        }
-yy279:
+yy261:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy269;
-               if (yych >= ':') goto yy269;
+               if (yych <= '/') goto yy251;
+               if (yych >= ':') goto yy251;
        } else {
-               if (yych <= 'F') goto yy280;
-               if (yych <= '`') goto yy269;
-               if (yych >= 'g') goto yy269;
+               if (yych <= 'F') goto yy262;
+               if (yych <= '`') goto yy251;
+               if (yych >= 'g') goto yy251;
        }
-yy280:
+yy262:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy269;
-               if (yych >= ':') goto yy269;
+               if (yych <= '/') goto yy251;
+               if (yych >= ':') goto yy251;
        } else {
-               if (yych <= 'F') goto yy281;
-               if (yych <= '`') goto yy269;
-               if (yych >= 'g') goto yy269;
+               if (yych <= 'F') goto yy263;
+               if (yych <= '`') goto yy251;
+               if (yych >= 'g') goto yy251;
        }
-yy281:
+yy263:
        yych = (YYCTYPE)*++YYCURSOR;
        if (yych <= '@') {
-               if (yych <= '/') goto yy269;
-               if (yych <= '9') goto yy270;
-               goto yy269;
+               if (yych <= '/') goto yy251;
+               if (yych <= '9') goto yy252;
+               goto yy251;
        } else {
-               if (yych <= 'F') goto yy270;
-               if (yych <= '`') goto yy269;
-               if (yych <= 'f') goto yy270;
-               goto yy269;
+               if (yych <= 'F') goto yy252;
+               if (yych <= '`') goto yy251;
+               if (yych <= 'f') goto yy252;
+               goto yy251;
        }
-yy282:
+yy264:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= '/') goto yy269;
-       if (yych >= '8') goto yy269;
+       if (yych <= '/') goto yy251;
+       if (yych >= '8') goto yy251;
        ++YYCURSOR;
-#line 459 "../src/parse/scanner_lex.re"
-       { cpoints.push_back (unesc_oct (tok, cur));           goto cpoint_class; }
-#line 1817 "src/parse/scanner_lex.cc"
+#line 426 "../src/parse/scanner_lex.re"
+       { cpoints.push_back (unesc_oct (tok, cur));  goto cpoints; }
+#line 1728 "src/parse/scanner_lex.cc"
 }
-#line 475 "../src/parse/scanner_lex.re"
+#line 462 "../src/parse/scanner_lex.re"
 
 
 code:
 
-#line 1824 "src/parse/scanner_lex.cc"
+#line 1735 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        unsigned int yyaccept = 0;
@@ -1862,26 +1773,26 @@ code:
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '&') {
                if (yych <= '\n') {
-                       if (yych <= 0x00) goto yy287;
-                       if (yych <= '\t') goto yy289;
-                       goto yy291;
+                       if (yych <= 0x00) goto yy269;
+                       if (yych <= '\t') goto yy271;
+                       goto yy273;
                } else {
-                       if (yych == '"') goto yy293;
-                       goto yy289;
+                       if (yych == '"') goto yy275;
+                       goto yy271;
                }
        } else {
                if (yych <= '{') {
-                       if (yych <= '\'') goto yy294;
-                       if (yych <= 'z') goto yy289;
-                       goto yy295;
+                       if (yych <= '\'') goto yy276;
+                       if (yych <= 'z') goto yy271;
+                       goto yy277;
                } else {
-                       if (yych == '}') goto yy297;
-                       goto yy289;
+                       if (yych == '}') goto yy279;
+                       goto yy271;
                }
        }
-yy287:
+yy269:
        ++YYCURSOR;
-#line 538 "../src/parse/scanner_lex.re"
+#line 525 "../src/parse/scanner_lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -1893,35 +1804,35 @@ yy287:
                                        }
                                        goto code;
                                }
-#line 1897 "src/parse/scanner_lex.cc"
-yy289:
+#line 1808 "src/parse/scanner_lex.cc"
+yy271:
        ++YYCURSOR;
-yy290:
-#line 552 "../src/parse/scanner_lex.re"
+yy272:
+#line 539 "../src/parse/scanner_lex.re"
        {
                                        goto code;
                                }
-#line 1905 "src/parse/scanner_lex.cc"
-yy291:
+#line 1816 "src/parse/scanner_lex.cc"
+yy273:
        YYCTXMARKER = YYCURSOR + 1;
        yyaccept = 0;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= '\r') {
                if (yych <= '\t') {
-                       if (yych >= '\t') goto yy308;
+                       if (yych >= '\t') goto yy290;
                } else {
-                       if (yych <= '\n') goto yy310;
-                       if (yych >= '\r') goto yy310;
+                       if (yych <= '\n') goto yy292;
+                       if (yych >= '\r') goto yy292;
                }
        } else {
                if (yych <= ' ') {
-                       if (yych >= ' ') goto yy308;
+                       if (yych >= ' ') goto yy290;
                } else {
-                       if (yych == '#') goto yy311;
+                       if (yych == '#') goto yy293;
                }
        }
-yy292:
-#line 519 "../src/parse/scanner_lex.re"
+yy274:
+#line 506 "../src/parse/scanner_lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -1941,20 +1852,20 @@ yy292:
                                        cline++;
                                        goto code;
                                }
-#line 1945 "src/parse/scanner_lex.cc"
-yy293:
+#line 1856 "src/parse/scanner_lex.cc"
+yy275:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == '\n') goto yy290;
-       goto yy306;
-yy294:
+       if (yych == '\n') goto yy272;
+       goto yy288;
+yy276:
        yyaccept = 1;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == '\n') goto yy290;
-       goto yy300;
-yy295:
+       if (yych == '\n') goto yy272;
+       goto yy282;
+yy277:
        ++YYCURSOR;
-#line 491 "../src/parse/scanner_lex.re"
+#line 478 "../src/parse/scanner_lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -1966,10 +1877,10 @@ yy295:
                                        }
                                        goto code;
                                }
-#line 1970 "src/parse/scanner_lex.cc"
-yy297:
+#line 1881 "src/parse/scanner_lex.cc"
+yy279:
        ++YYCURSOR;
-#line 479 "../src/parse/scanner_lex.re"
+#line 466 "../src/parse/scanner_lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -1982,69 +1893,69 @@ yy297:
                                        }
                                        goto code;
                                }
-#line 1986 "src/parse/scanner_lex.cc"
-yy299:
+#line 1897 "src/parse/scanner_lex.cc"
+yy281:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy300:
+yy282:
        if (yybm[0+yych] & 16) {
-               goto yy299;
+               goto yy281;
        }
-       if (yych <= '\n') goto yy301;
-       if (yych <= '\'') goto yy303;
-       goto yy302;
-yy301:
+       if (yych <= '\n') goto yy283;
+       if (yych <= '\'') goto yy285;
+       goto yy284;
+yy283:
        YYCURSOR = YYMARKER;
        if (yyaccept <= 1) {
                if (yyaccept == 0) {
-                       goto yy292;
+                       goto yy274;
                } else {
-                       goto yy290;
+                       goto yy272;
                }
        } else {
-               goto yy309;
+               goto yy291;
        }
-yy302:
+yy284:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy301;
-       goto yy299;
-yy303:
+       if (yych == '\n') goto yy283;
+       goto yy281;
+yy285:
        ++YYCURSOR;
-#line 549 "../src/parse/scanner_lex.re"
+#line 536 "../src/parse/scanner_lex.re"
        {
                                        goto code;
                                }
-#line 2021 "src/parse/scanner_lex.cc"
-yy305:
+#line 1932 "src/parse/scanner_lex.cc"
+yy287:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy306:
+yy288:
        if (yybm[0+yych] & 32) {
-               goto yy305;
+               goto yy287;
        }
-       if (yych <= '\n') goto yy301;
-       if (yych <= '"') goto yy303;
+       if (yych <= '\n') goto yy283;
+       if (yych <= '"') goto yy285;
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy301;
-       goto yy305;
-yy308:
+       if (yych == '\n') goto yy283;
+       goto yy287;
+yy290:
        yyaccept = 2;
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy330;
+               if (yych == '\t') goto yy312;
        } else {
-               if (yych <= ' ') goto yy330;
-               if (yych == '#') goto yy311;
+               if (yych <= ' ') goto yy312;
+               if (yych == '#') goto yy293;
        }
-yy309:
+yy291:
        YYCURSOR = YYCTXMARKER;
-#line 506 "../src/parse/scanner_lex.re"
+#line 493 "../src/parse/scanner_lex.re"
        {
                                        if (depth == 0)
                                        {
@@ -2058,123 +1969,123 @@ yy309:
                                        cline++;
                                        goto code;
                                }
-#line 2062 "src/parse/scanner_lex.cc"
-yy310:
+#line 1973 "src/parse/scanner_lex.cc"
+yy292:
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy309;
-yy311:
+       goto yy291;
+yy293:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 64) {
-               goto yy311;
+               goto yy293;
        }
-       if (yych != 'l') goto yy301;
+       if (yych != 'l') goto yy283;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'i') goto yy301;
+       if (yych != 'i') goto yy283;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'n') goto yy301;
+       if (yych != 'n') goto yy283;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'e') goto yy301;
+       if (yych != 'e') goto yy283;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= '0') goto yy318;
-       if (yych <= '9') goto yy301;
-       goto yy318;
-yy317:
+       if (yych <= '0') goto yy300;
+       if (yych <= '9') goto yy283;
+       goto yy300;
+yy299:
        YYCTXMARKER = YYCURSOR + 1;
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy318:
+yy300:
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy317;
-               goto yy301;
+               if (yych == '\t') goto yy299;
+               goto yy283;
        } else {
-               if (yych <= ' ') goto yy317;
-               if (yych <= '0') goto yy301;
-               if (yych >= ':') goto yy301;
+               if (yych <= ' ') goto yy299;
+               if (yych <= '0') goto yy283;
+               if (yych >= ':') goto yy283;
        }
-yy319:
+yy301:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 128) {
-               goto yy319;
+               goto yy301;
        }
        if (yych <= '\f') {
-               if (yych <= 0x08) goto yy301;
-               if (yych <= '\t') goto yy321;
-               if (yych <= '\n') goto yy323;
-               goto yy301;
+               if (yych <= 0x08) goto yy283;
+               if (yych <= '\t') goto yy303;
+               if (yych <= '\n') goto yy305;
+               goto yy283;
        } else {
-               if (yych <= '\r') goto yy325;
-               if (yych != ' ') goto yy301;
+               if (yych <= '\r') goto yy307;
+               if (yych != ' ') goto yy283;
        }
-yy321:
+yy303:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy321;
-               goto yy301;
+               if (yych == '\t') goto yy303;
+               goto yy283;
        } else {
-               if (yych <= ' ') goto yy321;
-               if (yych == '"') goto yy326;
-               goto yy301;
+               if (yych <= ' ') goto yy303;
+               if (yych == '"') goto yy308;
+               goto yy283;
        }
-yy323:
+yy305:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 502 "../src/parse/scanner_lex.re"
+#line 489 "../src/parse/scanner_lex.re"
        {
                                        set_sourceline ();
                                        goto code;
                                }
-#line 2134 "src/parse/scanner_lex.cc"
-yy325:
+#line 2045 "src/parse/scanner_lex.cc"
+yy307:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy323;
-       goto yy301;
-yy326:
+       if (yych == '\n') goto yy305;
+       goto yy283;
+yy308:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '!') {
-               if (yych == '\n') goto yy301;
-               goto yy326;
+               if (yych == '\n') goto yy283;
+               goto yy308;
        } else {
-               if (yych <= '"') goto yy329;
-               if (yych != '\\') goto yy326;
+               if (yych <= '"') goto yy311;
+               if (yych != '\\') goto yy308;
        }
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy301;
-       goto yy326;
-yy329:
+       if (yych == '\n') goto yy283;
+       goto yy308;
+yy311:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy323;
-       if (yych == '\r') goto yy325;
-       goto yy301;
-yy330:
+       if (yych == '\n') goto yy305;
+       if (yych == '\r') goto yy307;
+       goto yy283;
+yy312:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy330;
-               goto yy301;
+               if (yych == '\t') goto yy312;
+               goto yy283;
        } else {
-               if (yych <= ' ') goto yy330;
-               if (yych == '#') goto yy311;
-               goto yy301;
+               if (yych <= ' ') goto yy312;
+               if (yych == '#') goto yy293;
+               goto yy283;
        }
 }
-#line 555 "../src/parse/scanner_lex.re"
+#line 542 "../src/parse/scanner_lex.re"
 
 
 comment:
 
-#line 2178 "src/parse/scanner_lex.cc"
+#line 2089 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -2214,14 +2125,14 @@ comment:
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= ')') {
-               if (yych == '\n') goto yy336;
+               if (yych == '\n') goto yy318;
        } else {
-               if (yych <= '*') goto yy338;
-               if (yych == '/') goto yy339;
+               if (yych <= '*') goto yy320;
+               if (yych == '/') goto yy321;
        }
        ++YYCURSOR;
-yy335:
-#line 587 "../src/parse/scanner_lex.re"
+yy317:
+#line 574 "../src/parse/scanner_lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -2229,15 +2140,15 @@ yy335:
                                        }
                                        goto comment;
                                }
-#line 2233 "src/parse/scanner_lex.cc"
-yy336:
+#line 2144 "src/parse/scanner_lex.cc"
+yy318:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
        if (yybm[0+yych] & 32) {
-               goto yy344;
+               goto yy326;
        }
-       if (yych == '#') goto yy347;
-yy337:
-#line 578 "../src/parse/scanner_lex.re"
+       if (yych == '#') goto yy329;
+yy319:
+#line 565 "../src/parse/scanner_lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -2247,25 +2158,25 @@ yy337:
                                        cline++;
                                        goto comment;
                                }
-#line 2251 "src/parse/scanner_lex.cc"
-yy338:
+#line 2162 "src/parse/scanner_lex.cc"
+yy320:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '/') goto yy342;
-       goto yy335;
-yy339:
+       if (yych == '/') goto yy324;
+       goto yy317;
+yy321:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != '*') goto yy335;
+       if (yych != '*') goto yy317;
        ++YYCURSOR;
-#line 569 "../src/parse/scanner_lex.re"
+#line 556 "../src/parse/scanner_lex.re"
        {
                                        ++depth;
                                        fatal("ambiguous /* found");
                                        goto comment;
                                }
-#line 2266 "src/parse/scanner_lex.cc"
-yy342:
+#line 2177 "src/parse/scanner_lex.cc"
+yy324:
        ++YYCURSOR;
-#line 559 "../src/parse/scanner_lex.re"
+#line 546 "../src/parse/scanner_lex.re"
        {
                                        if (--depth == 0)
                                        {
@@ -2276,136 +2187,136 @@ yy342:
                                                goto comment;
                                        }
                                }
-#line 2280 "src/parse/scanner_lex.cc"
-yy344:
+#line 2191 "src/parse/scanner_lex.cc"
+yy326:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 32) {
-               goto yy344;
+               goto yy326;
        }
-       if (yych == '#') goto yy347;
-yy346:
+       if (yych == '#') goto yy329;
+yy328:
        YYCURSOR = YYMARKER;
-       goto yy337;
-yy347:
+       goto yy319;
+yy329:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy347;
-               goto yy346;
+               if (yych == '\t') goto yy329;
+               goto yy328;
        } else {
-               if (yych <= ' ') goto yy347;
-               if (yych != 'l') goto yy346;
+               if (yych <= ' ') goto yy329;
+               if (yych != 'l') goto yy328;
        }
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'i') goto yy346;
+       if (yych != 'i') goto yy328;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'n') goto yy346;
+       if (yych != 'n') goto yy328;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych != 'e') goto yy346;
+       if (yych != 'e') goto yy328;
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= '0') goto yy354;
-       if (yych <= '9') goto yy346;
-       goto yy354;
-yy353:
+       if (yych <= '0') goto yy336;
+       if (yych <= '9') goto yy328;
+       goto yy336;
+yy335:
        YYCTXMARKER = YYCURSOR + 1;
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy354:
+yy336:
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy353;
-               goto yy346;
+               if (yych == '\t') goto yy335;
+               goto yy328;
        } else {
-               if (yych <= ' ') goto yy353;
-               if (yych <= '0') goto yy346;
-               if (yych >= ':') goto yy346;
+               if (yych <= ' ') goto yy335;
+               if (yych <= '0') goto yy328;
+               if (yych >= ':') goto yy328;
        }
-yy355:
+yy337:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 64) {
-               goto yy355;
+               goto yy337;
        }
        if (yych <= '\f') {
-               if (yych <= 0x08) goto yy346;
-               if (yych <= '\t') goto yy357;
-               if (yych <= '\n') goto yy359;
-               goto yy346;
+               if (yych <= 0x08) goto yy328;
+               if (yych <= '\t') goto yy339;
+               if (yych <= '\n') goto yy341;
+               goto yy328;
        } else {
-               if (yych <= '\r') goto yy361;
-               if (yych != ' ') goto yy346;
+               if (yych <= '\r') goto yy343;
+               if (yych != ' ') goto yy328;
        }
-yy357:
+yy339:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy357;
-               goto yy346;
+               if (yych == '\t') goto yy339;
+               goto yy328;
        } else {
-               if (yych <= ' ') goto yy357;
-               if (yych == '"') goto yy362;
-               goto yy346;
+               if (yych <= ' ') goto yy339;
+               if (yych == '"') goto yy344;
+               goto yy328;
        }
-yy359:
+yy341:
        ++YYCURSOR;
        YYCURSOR = YYCTXMARKER;
-#line 574 "../src/parse/scanner_lex.re"
+#line 561 "../src/parse/scanner_lex.re"
        {
                                        set_sourceline ();
                                        goto comment;
                                }
-#line 2363 "src/parse/scanner_lex.cc"
-yy361:
+#line 2274 "src/parse/scanner_lex.cc"
+yy343:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych == '\n') goto yy359;
-       goto yy346;
-yy362:
+       if (yych == '\n') goto yy341;
+       goto yy328;
+yy344:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 128) {
-               goto yy362;
+               goto yy344;
        }
-       if (yych <= '\n') goto yy346;
-       if (yych <= '"') goto yy365;
+       if (yych <= '\n') goto yy328;
+       if (yych <= '"') goto yy347;
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy346;
-       goto yy362;
-yy365:
+       if (yych == '\n') goto yy328;
+       goto yy344;
+yy347:
        ++YYCURSOR;
-       if ((yych = (YYCTYPE)*YYCURSOR) == '\n') goto yy359;
-       if (yych == '\r') goto yy361;
-       goto yy346;
+       if ((yych = (YYCTYPE)*YYCURSOR) == '\n') goto yy341;
+       if (yych == '\r') goto yy343;
+       goto yy328;
 }
-#line 594 "../src/parse/scanner_lex.re"
+#line 581 "../src/parse/scanner_lex.re"
 
 
 nextLine:
 
-#line 2393 "src/parse/scanner_lex.cc"
+#line 2304 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy370;
+       if (yych == '\n') goto yy352;
        ++YYCURSOR;
-#line 605 "../src/parse/scanner_lex.re"
+#line 592 "../src/parse/scanner_lex.re"
        {  if(cur == eof) {
                   return 0;
                }
                goto nextLine;
             }
-#line 2406 "src/parse/scanner_lex.cc"
-yy370:
+#line 2317 "src/parse/scanner_lex.cc"
+yy352:
        ++YYCURSOR;
-#line 598 "../src/parse/scanner_lex.re"
+#line 585 "../src/parse/scanner_lex.re"
        { if(cur == eof) {
                   return 0;
                }
@@ -2413,14 +2324,14 @@ yy370:
                cline++;
                goto scan;
             }
-#line 2417 "src/parse/scanner_lex.cc"
+#line 2328 "src/parse/scanner_lex.cc"
 }
-#line 610 "../src/parse/scanner_lex.re"
+#line 597 "../src/parse/scanner_lex.re"
 
 
 config:
 
-#line 2424 "src/parse/scanner_lex.cc"
+#line 2335 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -2460,62 +2371,62 @@ config:
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= 0x1F) {
-               if (yych == '\t') goto yy376;
+               if (yych == '\t') goto yy358;
        } else {
-               if (yych <= ' ') goto yy376;
-               if (yych == '=') goto yy378;
+               if (yych <= ' ') goto yy358;
+               if (yych == '=') goto yy360;
        }
        ++YYCURSOR;
-#line 621 "../src/parse/scanner_lex.re"
+#line 608 "../src/parse/scanner_lex.re"
        {
                                        fatal("missing '='");
                                }
-#line 2474 "src/parse/scanner_lex.cc"
-yy376:
+#line 2385 "src/parse/scanner_lex.cc"
+yy358:
        ++YYCURSOR;
        yych = (YYCTYPE)*YYCURSOR;
-       goto yy383;
-yy377:
-#line 614 "../src/parse/scanner_lex.re"
+       goto yy365;
+yy359:
+#line 601 "../src/parse/scanner_lex.re"
        {
                                        goto config;
                                }
-#line 2484 "src/parse/scanner_lex.cc"
-yy378:
+#line 2395 "src/parse/scanner_lex.cc"
+yy360:
        ++YYCURSOR;
        yych = (YYCTYPE)*YYCURSOR;
-       goto yy381;
-yy379:
-#line 617 "../src/parse/scanner_lex.re"
+       goto yy363;
+yy361:
+#line 604 "../src/parse/scanner_lex.re"
        {
                                        lexer_state = LEX_CONFIG_VALUE;
                                        return '=';
                                }
-#line 2495 "src/parse/scanner_lex.cc"
-yy380:
+#line 2406 "src/parse/scanner_lex.cc"
+yy362:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy381:
+yy363:
        if (yybm[0+yych] & 128) {
-               goto yy380;
+               goto yy362;
        }
-       goto yy379;
-yy382:
+       goto yy361;
+yy364:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy383:
-       if (yych == '\t') goto yy382;
-       if (yych == ' ') goto yy382;
-       goto yy377;
+yy365:
+       if (yych == '\t') goto yy364;
+       if (yych == ' ') goto yy364;
+       goto yy359;
 }
-#line 624 "../src/parse/scanner_lex.re"
+#line 611 "../src/parse/scanner_lex.re"
 
 
 value:
 
-#line 2519 "src/parse/scanner_lex.cc"
+#line 2430 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -2556,46 +2467,46 @@ value:
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '&') {
                if (yych <= '\r') {
-                       if (yych <= 0x08) goto yy392;
-                       if (yych <= '\n') goto yy386;
-                       if (yych <= '\f') goto yy392;
+                       if (yych <= 0x08) goto yy374;
+                       if (yych <= '\n') goto yy368;
+                       if (yych <= '\f') goto yy374;
                } else {
                        if (yych <= ' ') {
-                               if (yych <= 0x1F) goto yy392;
+                               if (yych <= 0x1F) goto yy374;
                        } else {
-                               if (yych == '"') goto yy394;
-                               goto yy392;
+                               if (yych == '"') goto yy376;
+                               goto yy374;
                        }
                }
        } else {
                if (yych <= '/') {
-                       if (yych <= '\'') goto yy396;
-                       if (yych == '-') goto yy389;
-                       goto yy392;
+                       if (yych <= '\'') goto yy378;
+                       if (yych == '-') goto yy371;
+                       goto yy374;
                } else {
                        if (yych <= '9') {
-                               if (yych <= '0') goto yy387;
-                               goto yy390;
+                               if (yych <= '0') goto yy369;
+                               goto yy372;
                        } else {
-                               if (yych != ';') goto yy392;
+                               if (yych != ';') goto yy374;
                        }
                }
        }
-yy386:
-#line 636 "../src/parse/scanner_lex.re"
+yy368:
+#line 623 "../src/parse/scanner_lex.re"
        {
                                        yylval.str = new std::string (tok, tok_len ());
                                        lexer_state = LEX_NORMAL;
                                        return VALUE;
                                }
-#line 2592 "src/parse/scanner_lex.cc"
-yy387:
+#line 2503 "src/parse/scanner_lex.cc"
+yy369:
        ++YYCURSOR;
        if (yybm[0+(yych = (YYCTYPE)*YYCURSOR)] & 8) {
-               goto yy392;
+               goto yy374;
        }
-yy388:
-#line 628 "../src/parse/scanner_lex.re"
+yy370:
+#line 615 "../src/parse/scanner_lex.re"
        {
                                        if (!s_to_i32_unsafe (tok, cur, yylval.number))
                                        {
@@ -2604,150 +2515,150 @@ yy388:
                                        lexer_state = LEX_NORMAL;
                                        return NUMBER;
                                }
-#line 2608 "src/parse/scanner_lex.cc"
-yy389:
+#line 2519 "src/parse/scanner_lex.cc"
+yy371:
        yych = (YYCTYPE)*++YYCURSOR;
-       if (yych <= '0') goto yy393;
-       if (yych >= ':') goto yy393;
-yy390:
+       if (yych <= '0') goto yy375;
+       if (yych >= ':') goto yy375;
+yy372:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 4) {
-               goto yy390;
+               goto yy372;
        }
        if (yych <= '\r') {
-               if (yych <= 0x08) goto yy392;
-               if (yych <= '\n') goto yy388;
-               if (yych >= '\r') goto yy388;
+               if (yych <= 0x08) goto yy374;
+               if (yych <= '\n') goto yy370;
+               if (yych >= '\r') goto yy370;
        } else {
                if (yych <= ' ') {
-                       if (yych >= ' ') goto yy388;
+                       if (yych >= ' ') goto yy370;
                } else {
-                       if (yych == ';') goto yy388;
+                       if (yych == ';') goto yy370;
                }
        }
-yy392:
+yy374:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy393:
+yy375:
        if (yybm[0+yych] & 8) {
-               goto yy392;
+               goto yy374;
        }
-       goto yy386;
-yy394:
+       goto yy368;
+yy376:
        YYMARKER = ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 16) {
-               goto yy394;
+               goto yy376;
        }
        if (yych <= ' ') {
-               if (yych == '\n') goto yy386;
-               goto yy404;
+               if (yych == '\n') goto yy368;
+               goto yy386;
        } else {
-               if (yych <= '"') goto yy392;
-               if (yych <= ';') goto yy404;
-               goto yy406;
+               if (yych <= '"') goto yy374;
+               if (yych <= ';') goto yy386;
+               goto yy388;
        }
-yy396:
+yy378:
        YYMARKER = ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 32) {
-               goto yy396;
+               goto yy378;
        }
        if (yych <= ' ') {
-               if (yych == '\n') goto yy386;
+               if (yych == '\n') goto yy368;
        } else {
-               if (yych <= '\'') goto yy392;
-               if (yych >= '<') goto yy401;
+               if (yych <= '\'') goto yy374;
+               if (yych >= '<') goto yy383;
        }
-yy398:
+yy380:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 64) {
-               goto yy398;
+               goto yy380;
        }
-       if (yych <= '\n') goto yy400;
-       if (yych <= '\'') goto yy402;
-       goto yy403;
-yy400:
+       if (yych <= '\n') goto yy382;
+       if (yych <= '\'') goto yy384;
+       goto yy385;
+yy382:
        YYCURSOR = YYMARKER;
-       goto yy386;
-yy401:
+       goto yy368;
+yy383:
        YYMARKER = ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '\r') {
                if (yych <= '\t') {
-                       if (yych <= 0x08) goto yy396;
-                       goto yy398;
+                       if (yych <= 0x08) goto yy378;
+                       goto yy380;
                } else {
-                       if (yych <= '\n') goto yy386;
-                       if (yych <= '\f') goto yy396;
-                       goto yy398;
+                       if (yych <= '\n') goto yy368;
+                       if (yych <= '\f') goto yy378;
+                       goto yy380;
                }
        } else {
                if (yych <= ' ') {
-                       if (yych <= 0x1F) goto yy396;
-                       goto yy398;
+                       if (yych <= 0x1F) goto yy378;
+                       goto yy380;
                } else {
-                       if (yych == ';') goto yy398;
-                       goto yy396;
+                       if (yych == ';') goto yy380;
+                       goto yy378;
                }
        }
-yy402:
+yy384:
        yych = (YYCTYPE)*++YYCURSOR;
-       goto yy386;
-yy403:
+       goto yy368;
+yy385:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy400;
-       goto yy398;
-yy404:
+       if (yych == '\n') goto yy382;
+       goto yy380;
+yy386:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yybm[0+yych] & 128) {
-               goto yy404;
+               goto yy386;
        }
-       if (yych <= '\n') goto yy400;
-       if (yych <= '"') goto yy402;
-       goto yy407;
-yy406:
+       if (yych <= '\n') goto yy382;
+       if (yych <= '"') goto yy384;
+       goto yy389;
+yy388:
        YYMARKER = ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '\r') {
                if (yych <= '\t') {
-                       if (yych <= 0x08) goto yy394;
-                       goto yy404;
+                       if (yych <= 0x08) goto yy376;
+                       goto yy386;
                } else {
-                       if (yych <= '\n') goto yy386;
-                       if (yych <= '\f') goto yy394;
-                       goto yy404;
+                       if (yych <= '\n') goto yy368;
+                       if (yych <= '\f') goto yy376;
+                       goto yy386;
                }
        } else {
                if (yych <= ' ') {
-                       if (yych <= 0x1F) goto yy394;
-                       goto yy404;
+                       if (yych <= 0x1F) goto yy376;
+                       goto yy386;
                } else {
-                       if (yych == ';') goto yy404;
-                       goto yy394;
+                       if (yych == ';') goto yy386;
+                       goto yy376;
                }
        }
-yy407:
+yy389:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy400;
-       goto yy404;
+       if (yych == '\n') goto yy382;
+       goto yy386;
 }
-#line 641 "../src/parse/scanner_lex.re"
+#line 628 "../src/parse/scanner_lex.re"
 
 }
 
@@ -2770,7 +2681,7 @@ void Scanner::set_sourceline ()
 sourceline:
        tok = cur;
 
-#line 2774 "src/parse/scanner_lex.cc"
+#line 2685 "src/parse/scanner_lex.cc"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -2810,23 +2721,23 @@ sourceline:
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = (YYCTYPE)*YYCURSOR;
        if (yych <= '!') {
-               if (yych == '\n') goto yy412;
+               if (yych == '\n') goto yy394;
        } else {
-               if (yych <= '"') goto yy414;
-               if (yych <= '0') goto yy410;
-               if (yych <= '9') goto yy415;
+               if (yych <= '"') goto yy396;
+               if (yych <= '0') goto yy392;
+               if (yych <= '9') goto yy397;
        }
-yy410:
+yy392:
        ++YYCURSOR;
-yy411:
-#line 686 "../src/parse/scanner_lex.re"
+yy393:
+#line 673 "../src/parse/scanner_lex.re"
        {
                                        goto sourceline;
                                }
-#line 2827 "src/parse/scanner_lex.cc"
-yy412:
+#line 2738 "src/parse/scanner_lex.cc"
+yy394:
        ++YYCURSOR;
-#line 674 "../src/parse/scanner_lex.re"
+#line 661 "../src/parse/scanner_lex.re"
        {
                                        if (cur == eof)
                                        {
@@ -2839,17 +2750,17 @@ yy412:
                                        tok = cur;
                                        return; 
                                }
-#line 2843 "src/parse/scanner_lex.cc"
-yy414:
+#line 2754 "src/parse/scanner_lex.cc"
+yy396:
        yych = (YYCTYPE)*(YYMARKER = ++YYCURSOR);
-       if (yych == '\n') goto yy411;
-       goto yy420;
-yy415:
+       if (yych == '\n') goto yy393;
+       goto yy402;
+yy397:
        ++YYCURSOR;
        yych = (YYCTYPE)*YYCURSOR;
-       goto yy418;
-yy416:
-#line 663 "../src/parse/scanner_lex.re"
+       goto yy400;
+yy398:
+#line 650 "../src/parse/scanner_lex.re"
        {
                                        if (!s_to_u32_unsafe (tok, cur, cline))
                                        {
@@ -2857,46 +2768,46 @@ yy416:
                                        }
                                        goto sourceline; 
                                }
-#line 2861 "src/parse/scanner_lex.cc"
-yy417:
+#line 2772 "src/parse/scanner_lex.cc"
+yy399:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy418:
+yy400:
        if (yybm[0+yych] & 64) {
-               goto yy417;
+               goto yy399;
        }
-       goto yy416;
-yy419:
+       goto yy398;
+yy401:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-yy420:
+yy402:
        if (yybm[0+yych] & 128) {
-               goto yy419;
+               goto yy401;
        }
-       if (yych <= '\n') goto yy421;
-       if (yych <= '"') goto yy423;
-       goto yy422;
-yy421:
+       if (yych <= '\n') goto yy403;
+       if (yych <= '"') goto yy405;
+       goto yy404;
+yy403:
        YYCURSOR = YYMARKER;
-       goto yy411;
-yy422:
+       goto yy393;
+yy404:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = (YYCTYPE)*YYCURSOR;
-       if (yych == '\n') goto yy421;
-       goto yy419;
-yy423:
+       if (yych == '\n') goto yy403;
+       goto yy401;
+yy405:
        ++YYCURSOR;
-#line 670 "../src/parse/scanner_lex.re"
+#line 657 "../src/parse/scanner_lex.re"
        {
                                        escape (in.file_name, std::string (tok + 1, tok_len () - 2)); // -2 to omit quotes
                                        goto sourceline; 
                                }
-#line 2898 "src/parse/scanner_lex.cc"
+#line 2809 "src/parse/scanner_lex.cc"
 }
-#line 689 "../src/parse/scanner_lex.re"
+#line 676 "../src/parse/scanner_lex.re"
 
 }
 
index cd4bf81b07ee7c2faa36bd0d13ac51ab74f661a8..22e9ed97258603d41d7cec0cff0ec5134b6ba448 100644 (file)
@@ -182,6 +182,27 @@ RegExp * Scanner::matchSymbolRange(Range * r) const
                return new MatchOp(r);
 }
 
+RegExp * Scanner::cpoint_string (const std::vector<uint32_t> & cs, bool case_insensitive) const
+{
+       RegExp * r = NULL;
+       const size_t count = cs.size ();
+       for (size_t i = 0; i < count; ++i)
+       {
+               const uint32_t c = cs[i];
+               if (case_insensitive && is_alpha (c))
+               {
+                       RegExp * rl = matchSymbol (to_lower_unsafe (c));
+                       RegExp * ru = matchSymbol (to_upper_unsafe (c));
+                       r = doCat (r, mkAlt (rl, ru));
+               }
+               else
+               {
+                       r = doCat (r, matchSymbol (c));
+               }
+       }
+       return r ? r : new NullOp;
+}
+
 RegExp * Scanner::cpoint_class (const std::vector<uint32_t> & cs, bool neg) const
 {
        Range * r = NULL;
index 35d7e492a58b950116ecd1e7f2295805e93f83b7..7deba777350851abb55d4b8282a47e9cfbe5be08 100644 (file)
@@ -103,6 +103,7 @@ public:
        RegExp * mkDiff (RegExp * e1, RegExp * e2) const;
        RegExp * mkDot () const;
        RegExp * mkDefault () const;
+       RegExp * cpoint_string (const std::vector<uint32_t> & cs, bool case_sensitive) const;
        RegExp * cpoint_class (const std::vector<uint32_t> & cs, bool neg) const;
 
        FORBID_COPY (Scanner);
index 2ae89ce49459b1980c38affb461ebea66e2ac7cb..f1966730bd02ec55f273765887a909530f7d8932 100644 (file)
@@ -47,6 +47,12 @@ eol     = ("\r\n" | "\n");
 config  = "re2c" cname+ ("@" name)?;
 value   = [^\r\n; \t]* | dstring | sstring;
 lineinf = lineno (space+ dstring)? eol;
+
+       escapable = [abfnrtv\\];
+       esc = "\\";
+       hex_digit = [0-9a-fA-F];
+       hex = "x" hex_digit{2} | [uX] hex_digit{4} | "U" hex_digit{8};
+       oct = [0-3] [0-7]{2}; // max 1-byte octal value is '\377'
 */
 
 Scanner::ParseMode Scanner::echo()
@@ -211,6 +217,7 @@ int Scanner::scan()
 {
        uint32_t depth;
 
+       char quote;
        bool negated_class = false;
        std::vector<uint32_t> cpoints;
 scan:
@@ -256,41 +263,9 @@ start:
                                        return 0;
                                }
 
-       dstring         {
-                                       SubStr s (tok + 1, tok_len () - 2); // -2 to omit quotes
-                                       if (bCaseInsensitive || bCaseInverted)
-                                       {
-                                               yylval.regexp = strToCaseInsensitiveRE (s);
-                                       }
-                                       else
-                                       {
-                                               yylval.regexp = strToRE (s);
-                                       }
-                                       return STRING;
-                               }
-
-       sstring         {
-                                       SubStr s (tok + 1, tok_len () - 2); // -2 to omit quotes
-                                       if (bCaseInverted)
-                                       {
-                                               yylval.regexp = strToRE (s);
-                                       }
-                                       else
-                                       {
-                                               yylval.regexp = strToCaseInsensitiveRE (s);
-                                       }
-                                       return STRING;
-                               }
-
-       "\""            {
-                                       fatal("unterminated string constant (missing \")");
-                               }
-       "'"                     {
-                                       fatal("unterminated string constant (missing ')");
-                               }
-
-       "["  {                       goto cpoint_class; }
-       "[^" { negated_class = true; goto cpoint_class; }
+       ['"] { quote = tok[0];                    goto cpoints; }
+       "["  { quote = ']';                       goto cpoints; }
+       "[^" { quote = ']'; negated_class = true; goto cpoints; }
 
        "<>" / (space* ("{" | "=>" | ":=")) {
                                        return NOCOND;
@@ -440,37 +415,49 @@ flex_name:
        }
 */
 
-cpoint_class:
+cpoints:
        tok = cur;
 /*!re2c
-       printable = [\x20-\x7E];
-       escapable = [abfnrtv\\];
-       esc = "\\";
-       hex_digit = [0-9a-fA-F];
-       hex = "x" hex_digit{2} | [uX] hex_digit{4} | "U" hex_digit{8};
-       oct = [0-3] [0-7]{2}; // max 1-byte octal value is '\377'
-
-       *          { fatal ((tok - pos) - tchar, "syntax error in character range"); }
        esc [xXuU] { fatal ((tok - pos) - tchar, "syntax error in hexadecimal escape sequence"); }
        esc [0-7]  { fatal ((tok - pos) - tchar, "syntax error in octal escape sequence"); }
        esc        { fatal ((tok - pos) - tchar, "syntax error in escape sequence"); }
 
-       esc hex                 { cpoints.push_back (unesc_hex (tok, cur));           goto cpoint_class; }
-       esc oct                 { cpoints.push_back (unesc_oct (tok, cur));           goto cpoint_class; }
-       esc escapable           { cpoints.push_back (unesc_escapable (tok));          goto cpoint_class; }
-       esc "]"                 { cpoints.push_back (']');                            goto cpoint_class; }
-       printable \ (esc | "]") { cpoints.push_back (static_cast<uint32_t> (tok[0])); goto cpoint_class; }
-       esc printable
+       esc hex       { cpoints.push_back (unesc_hex (tok, cur));  goto cpoints; }
+       esc oct       { cpoints.push_back (unesc_oct (tok, cur));  goto cpoints; }
+       esc escapable { cpoints.push_back (unesc_escapable (tok)); goto cpoints; }
+       esc [^]
        {
                const char c = tok[1];
-               warn.useless_escape (tline, tok - pos, c);
+               if (c != quote)
+               {
+                       warn.useless_escape (tline, tok - pos, c);
+               }
                cpoints.push_back (static_cast<uint32_t> (c));
-               goto cpoint_class;
+               goto cpoints;
        }
-       "]"
+       [^] \ esc
        {
-               yylval.regexp = cpoint_class (cpoints, negated_class);
-               return RANGE;
+               const char c = tok[0];
+               if (c == quote)
+               {
+                       switch (quote)
+                       {
+                               case ']':
+                                       yylval.regexp = cpoint_class (cpoints, negated_class);
+                                       return RANGE;
+                               case '\'':
+                                       yylval.regexp = cpoint_string (cpoints, bCaseInsensitive || !bCaseInverted);
+                                       return STRING;
+                               case '"':
+                                       yylval.regexp = cpoint_string (cpoints, bCaseInsensitive || bCaseInverted);
+                                       return STRING;
+                       }
+               }
+               else
+               {
+                       cpoints.push_back (static_cast<uint32_t> (c));
+                       goto cpoints;
+               }
        }
 */
 
index 82b930fed8a0f1b8aee53c7d901df82a93eac367..e0a2728c3e32046e42c03b8bdb66557d26a0069d 100644 (file)
@@ -1,4 +1,6 @@
+re2c: warning: line 490: column 26: escape has no effect: '\/' [-Wuseless-escape]
 re2c: warning: line 490: column 50: escape has no effect: '\/' [-Wuseless-escape]
+re2c: warning: line 490: column 77: escape has no effect: '\/' [-Wuseless-escape]
 /* Generated by re2c */
 #line 1 "input_custom_mjson.--input(custom).re"
 #include <assert.h>
index 8d97f57e39a5feada9c859b58fc1d0bbc5101c50..dfed811d25cc028804d0064aaaa7148c6aab365c 100644 (file)
@@ -1,4 +1,6 @@
 re2c: warning: line 1095: column 12: escape has no effect: '\[' [-Wuseless-escape]
+re2c: warning: line 1476: column 19: escape has no effect: '\*' [-Wuseless-escape]
+re2c: warning: line 1480: column 19: escape has no effect: '\*' [-Wuseless-escape]
 /* Generated by re2c */
 
 digraph re2c {
index 3b2b0b93ac3cf09fe7afe719cc3afca1d5646cc0..1936b8f434468519213c6e7f77922680a23a3743 100644 (file)
@@ -1,4 +1,6 @@
 re2c: warning: line 1095: column 12: escape has no effect: '\[' [-Wuseless-escape]
+re2c: warning: line 1476: column 19: escape has no effect: '\*' [-Wuseless-escape]
+re2c: warning: line 1480: column 19: escape has no effect: '\*' [-Wuseless-escape]
 /* Generated by re2c */
 /*
    +----------------------------------------------------------------------+