]> granicus.if.org Git - re2c/commitdiff
- Add <> to support code in case no condition is being met
authorhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Tue, 17 Apr 2007 00:14:12 +0000 (00:14 +0000)
committerhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Tue, 17 Apr 2007 00:14:12 +0000 (00:14 +0000)
- Merge <*> rules to all other rules
- Configurable code
- In -g mode generate a computed goto jump table

13 files changed:
re2c/actions.cc
re2c/bootstrap/parser.cc
re2c/bootstrap/scanner.cc
re2c/bootstrap/y.tab.h
re2c/code.cc
re2c/globals.h
re2c/main.cc
re2c/parser.h
re2c/parser.y
re2c/re.h
re2c/scanner.h
re2c/scanner.re
re2c/test/cond_error_04.c.re

index e0bacb4458f3b7e009bc0989a2ba83271fcc772f..6d18f6868d9a1314a475b4ea6732a969d0ac470c 100644 (file)
@@ -900,6 +900,11 @@ RuleOp::RuleOp(RegExp *e, RegExp *c, Token *t, uint a)
        ;
 }
 
+RuleOp* RuleOp::copy(uint a) const
+{
+       return new RuleOp(exp, ctx, new Token(code->text, code->line), a);
+}
+
 void RuleOp::calcSize(Char *rep)
 {
        exp->calcSize(rep);
index 9baa0ff10c60c09961343047d90993179c15ce43..4b503fa5324c4e1b49028b44bab4e25eedc033d8 100644 (file)
      CLOSESIZE = 258,
      CLOSE = 259,
      STAR = 260,
-     ID = 261,
-     CODE = 262,
-     RANGE = 263,
-     STRING = 264,
-     CONFIG = 265,
-     VALUE = 266,
-     NUMBER = 267
+     NOCOND = 261,
+     ID = 262,
+     CODE = 263,
+     RANGE = 264,
+     STRING = 265,
+     CONFIG = 266,
+     VALUE = 267,
+     NUMBER = 268
    };
 #endif
 /* Tokens.  */
 #define CLOSESIZE 258
 #define CLOSE 259
 #define STAR 260
-#define ID 261
-#define CODE 262
-#define RANGE 263
-#define STRING 264
-#define CONFIG 265
-#define VALUE 266
-#define NUMBER 267
+#define NOCOND 261
+#define ID 262
+#define CODE 263
+#define RANGE 264
+#define STRING 265
+#define CONFIG 266
+#define VALUE 267
+#define NUMBER 268
 
 
 
@@ -114,8 +116,9 @@ void yyerror(const char*);
 }
 
 static re2c::uint       accept;
-static re2c::RegExpMap  specmap;
-static RegExp           *spec;
+static re2c::RegExpMap  specMap;
+static RegExp           *spec, *specNone = NULL;
+static RuleOpList       specStar;
 static Scanner          *in = NULL;
 
 /* Bison version 1.875 emits a definition that is not working
@@ -163,7 +166,7 @@ static char* strdup(const char* s)
 #endif
 
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 62 "parser.y"
+#line 63 "parser.y"
 typedef union YYSTYPE {
        re2c::Symbol    *symbol;
        re2c::RegExp    *regexp;
@@ -175,7 +178,7 @@ typedef union YYSTYPE {
        re2c::CondList  *clist;
 } YYSTYPE;
 /* Line 196 of yacc.c.  */
-#line 179 "parser.cc"
+#line 182 "parser.cc"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
@@ -187,7 +190,7 @@ typedef union YYSTYPE {
 
 
 /* Line 219 of yacc.c.  */
-#line 191 "parser.cc"
+#line 194 "parser.cc"
 
 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
 # define YYSIZE_T __SIZE_TYPE__
@@ -338,20 +341,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state. */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   56
+#define YYLAST   63
 
 /* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS  23
+#define YYNTOKENS  24
 /* YYNNTS -- Number of nonterminals. */
 #define YYNNTS  13
 /* YYNRULES -- Number of rules. */
-#define YYNRULES  35
+#define YYNRULES  37
 /* YYNRULES -- Number of states. */
-#define YYNSTATES  55
+#define YYNSTATES  63
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   267
+#define YYMAXUTOK   268
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -363,15 +366,15 @@ static const unsigned char yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      21,    22,     2,     2,    18,     2,     2,    15,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,    14,
-      16,    13,    17,     2,     2,     2,     2,     2,     2,     2,
+      22,    23,     2,     2,    19,     2,     2,    16,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,    15,
+      17,    14,    18,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,    20,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,    21,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,    19,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,    20,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -385,7 +388,7 @@ static const unsigned char yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12
+       5,     6,     7,     8,     9,    10,    11,    12,    13
 };
 
 #if YYDEBUG
@@ -394,34 +397,36 @@ static const unsigned char yytranslate[] =
 static const unsigned char yyprhs[] =
 {
        0,     0,     3,     4,     7,    10,    15,    20,    25,    30,
-      34,    41,    47,    48,    50,    52,    54,    58,    59,    62,
-      64,    68,    70,    74,    76,    79,    81,    84,    87,    89,
-      91,    94,    97,    99,   101,   103
+      34,    41,    47,    54,    60,    63,    64,    66,    68,    72,
+      73,    76,    78,    82,    84,    88,    90,    93,    95,    98,
+     101,   103,   105,   108,   111,   113,   115,   117
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
 static const yysigned_char yyrhs[] =
 {
-      24,     0,    -1,    -1,    24,    26,    -1,    24,    25,    -1,
-       6,    13,    30,    14,    -1,     6,    13,    30,    15,    -1,
-      10,    13,    11,    14,    -1,    10,    13,    12,    14,    -1,
-      30,    29,     7,    -1,    16,    27,    17,    30,    29,     7,
-      -1,    16,    27,    17,    29,     7,    -1,    -1,     5,    -1,
-      28,    -1,     6,    -1,    28,    18,     6,    -1,    -1,    15,
-      30,    -1,    31,    -1,    30,    19,    31,    -1,    32,    -1,
-      31,    20,    32,    -1,    33,    -1,    32,    33,    -1,    35,
-      -1,    35,    34,    -1,    35,     3,    -1,     4,    -1,     5,
-      -1,    34,     4,    -1,    34,     5,    -1,     6,    -1,     8,
-      -1,     9,    -1,    21,    30,    22,    -1
+      25,     0,    -1,    -1,    25,    27,    -1,    25,    26,    -1,
+       7,    14,    31,    15,    -1,     7,    14,    31,    16,    -1,
+      11,    14,    12,    15,    -1,    11,    14,    13,    15,    -1,
+      31,    30,     8,    -1,    17,    28,    18,    31,    30,     8,
+      -1,    17,    28,    18,    30,     8,    -1,    17,     5,    18,
+      31,    30,     8,    -1,    17,     5,    18,    30,     8,    -1,
+       6,     8,    -1,    -1,    29,    -1,     7,    -1,    29,    19,
+       7,    -1,    -1,    16,    31,    -1,    32,    -1,    31,    20,
+      32,    -1,    33,    -1,    32,    21,    33,    -1,    34,    -1,
+      33,    34,    -1,    36,    -1,    36,    35,    -1,    36,     3,
+      -1,     4,    -1,     5,    -1,    35,     4,    -1,    35,     5,
+      -1,     7,    -1,     9,    -1,    10,    -1,    22,    31,    23,
+      -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const unsigned short int yyrline[] =
 {
-       0,    91,    91,    95,    96,   100,   108,   112,   118,   126,
-     135,   158,   171,   174,   179,   186,   191,   200,   203,   210,
-     214,   221,   225,   236,   240,   247,   251,   266,   273,   277,
-     281,   285,   292,   300,   304,   308
+       0,    92,    92,    96,    97,   101,   109,   113,   119,   127,
+     136,   159,   168,   176,   184,   200,   203,   210,   215,   224,
+     227,   234,   238,   245,   249,   260,   264,   271,   275,   290,
+     297,   301,   305,   309,   316,   324,   328,   332
 };
 #endif
 
@@ -430,11 +435,11 @@ static const unsigned short int yyrline[] =
    First, the terminals, then, starting at YYNTOKENS, nonterminals. */
 static const char *const yytname[] =
 {
-  "$end", "error", "$undefined", "CLOSESIZE", "CLOSE", "STAR", "ID",
-  "CODE", "RANGE", "STRING", "CONFIG", "VALUE", "NUMBER", "'='", "';'",
-  "'/'", "'<'", "'>'", "','", "'|'", "'\\\\'", "'('", "')'", "$accept",
-  "spec", "decl", "rule", "cond", "clist", "look", "expr", "diff", "term",
-  "factor", "close", "primary", 0
+  "$end", "error", "$undefined", "CLOSESIZE", "CLOSE", "STAR", "NOCOND",
+  "ID", "CODE", "RANGE", "STRING", "CONFIG", "VALUE", "NUMBER", "'='",
+  "';'", "'/'", "'<'", "'>'", "','", "'|'", "'\\\\'", "'('", "')'",
+  "$accept", "spec", "decl", "rule", "cond", "clist", "look", "expr",
+  "diff", "term", "factor", "close", "primary", 0
 };
 #endif
 
@@ -444,27 +449,27 @@ static const char *const yytname[] =
 static const unsigned short int yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
-     265,   266,   267,    61,    59,    47,    60,    62,    44,   124,
-      92,    40,    41
+     265,   266,   267,   268,    61,    59,    47,    60,    62,    44,
+     124,    92,    40,    41
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const unsigned char yyr1[] =
 {
-       0,    23,    24,    24,    24,    25,    25,    25,    25,    26,
-      26,    26,    27,    27,    27,    28,    28,    29,    29,    30,
-      30,    31,    31,    32,    32,    33,    33,    33,    34,    34,
-      34,    34,    35,    35,    35,    35
+       0,    24,    25,    25,    25,    26,    26,    26,    26,    27,
+      27,    27,    27,    27,    27,    28,    28,    29,    29,    30,
+      30,    31,    31,    32,    32,    33,    33,    34,    34,    34,
+      35,    35,    35,    35,    36,    36,    36,    36
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const unsigned char yyr2[] =
 {
        0,     2,     0,     2,     2,     4,     4,     4,     4,     3,
-       6,     5,     0,     1,     1,     1,     3,     0,     2,     1,
-       3,     1,     3,     1,     2,     1,     2,     2,     1,     1,
-       2,     2,     1,     1,     1,     3
+       6,     5,     6,     5,     2,     0,     1,     1,     3,     0,
+       2,     1,     3,     1,     3,     1,     2,     1,     2,     2,
+       1,     1,     2,     2,     1,     1,     1,     3
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -472,39 +477,41 @@ static const unsigned char yyr2[] =
    means the default is an error.  */
 static const unsigned char yydefact[] =
 {
-       2,     0,     1,    32,    33,    34,     0,    12,     0,     4,
-       3,    17,    19,    21,    23,    25,     0,     0,    13,    15,
-       0,    14,    32,     0,     0,     0,     0,     0,    24,    27,
-      28,    29,    26,     0,     0,     0,    17,     0,    35,    18,
-      20,     9,    22,    30,    31,     5,     6,     7,     8,     0,
-      17,    16,    11,     0,    10
+       2,     0,     1,     0,    34,    35,    36,     0,    15,     0,
+       4,     3,    19,    21,    23,    25,    27,    14,     0,     0,
+       0,    17,     0,    16,    34,     0,     0,     0,     0,     0,
+      26,    29,    30,    31,    28,     0,     0,     0,    19,    19,
+       0,    37,    20,    22,     9,    24,    32,    33,     5,     6,
+       7,     8,     0,    19,     0,    19,    18,    13,     0,    11,
+       0,    12,    10
 };
 
 /* YYDEFGOTO[NTERM-NUM]. */
 static const yysigned_char yydefgoto[] =
 {
-      -1,     1,     9,    10,    20,    21,    26,    11,    12,    13,
-      14,    32,    15
+      -1,     1,    10,    11,    22,    23,    28,    12,    13,    14,
+      15,    34,    16
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -36
+#define YYPACT_NINF -38
 static const yysigned_char yypact[] =
 {
-     -36,     3,   -36,    -9,   -36,   -36,    -7,    28,    17,   -36,
-     -36,    12,     8,    17,   -36,    36,    17,    25,   -36,   -36,
-       5,    26,   -36,    13,    17,    17,    39,    17,   -36,   -36,
-     -36,   -36,    38,     2,    31,    33,    -1,    42,   -36,    30,
-       8,   -36,    17,   -36,   -36,   -36,   -36,   -36,   -36,    43,
-      12,   -36,   -36,    44,   -36
+     -38,     4,   -38,     9,    22,   -38,   -38,    30,    38,    28,
+     -38,   -38,   -11,    27,    28,   -38,     3,   -38,    28,    11,
+      21,   -38,    29,    32,   -38,    -1,    28,    28,    41,    28,
+     -38,   -38,   -38,   -38,    25,    26,    37,    39,    18,    18,
+      46,   -38,    35,    27,   -38,    28,   -38,   -38,   -38,   -38,
+     -38,   -38,    48,   -11,    49,   -11,   -38,   -38,    50,   -38,
+      51,   -38,   -38
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yysigned_char yypgoto[] =
 {
-     -36,   -36,   -36,   -36,   -36,   -36,   -35,    -6,    27,    29,
-     -13,   -36,   -36
+     -38,   -38,   -38,   -38,   -38,   -38,   -37,    -6,    33,    34,
+     -14,   -38,   -38
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
@@ -514,34 +521,37 @@ static const yysigned_char yypgoto[] =
 #define YYTABLE_NINF -1
 static const unsigned char yytable[] =
 {
-      28,    49,    23,     2,    16,    22,    17,     4,     5,     3,
-      33,     4,     5,     6,    24,    53,    45,    46,    39,     7,
-       8,    25,    36,    22,     8,     4,     5,    24,    27,    28,
-      50,    25,    25,    18,    19,    38,    34,    35,     8,    29,
-      30,    31,    43,    44,    37,    47,    41,    48,    51,    25,
-      52,    54,    40,     0,     0,     0,    42
+      30,    52,    54,    25,     2,    26,    31,    32,    33,    27,
+       3,     4,    35,     5,     6,     7,    58,    17,    60,    27,
+      42,     8,    41,    36,    37,    24,     9,     5,     6,    46,
+      47,    30,    53,    55,    26,    24,    18,     5,     6,    38,
+       9,    48,    49,    20,    19,    21,    27,    39,    29,    44,
+       9,    40,    50,    56,    51,    27,    57,    59,    61,    62,
+      43,     0,     0,    45
 };
 
 static const yysigned_char yycheck[] =
 {
-      13,    36,     8,     0,    13,     6,    13,     8,     9,     6,
-      16,     8,     9,    10,    15,    50,    14,    15,    24,    16,
-      21,    19,    17,     6,    21,     8,     9,    15,    20,    42,
-      36,    19,    19,     5,     6,    22,    11,    12,    21,     3,
-       4,     5,     4,     5,    18,    14,     7,    14,     6,    19,
-       7,     7,    25,    -1,    -1,    -1,    27
+      14,    38,    39,     9,     0,    16,     3,     4,     5,    20,
+       6,     7,    18,     9,    10,    11,    53,     8,    55,    20,
+      26,    17,    23,    12,    13,     7,    22,     9,    10,     4,
+       5,    45,    38,    39,    16,     7,    14,     9,    10,    18,
+      22,    15,    16,     5,    14,     7,    20,    18,    21,     8,
+      22,    19,    15,     7,    15,    20,     8,     8,     8,     8,
+      27,    -1,    -1,    29
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const unsigned char yystos[] =
 {
-       0,    24,     0,     6,     8,     9,    10,    16,    21,    25,
-      26,    30,    31,    32,    33,    35,    13,    13,     5,     6,
-      27,    28,     6,    30,    15,    19,    29,    20,    33,     3,
-       4,     5,    34,    30,    11,    12,    17,    18,    22,    30,
-      31,     7,    32,     4,     5,    14,    15,    14,    14,    29,
-      30,     6,     7,    29,     7
+       0,    25,     0,     6,     7,     9,    10,    11,    17,    22,
+      26,    27,    31,    32,    33,    34,    36,     8,    14,    14,
+       5,     7,    28,    29,     7,    31,    16,    20,    30,    21,
+      34,     3,     4,     5,    35,    31,    12,    13,    18,    18,
+      19,    23,    31,    32,     8,    33,     4,     5,    15,    16,
+      15,    15,    30,    31,    30,    31,     7,     8,    30,     8,
+      30,     8,     8
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1211,7 +1221,7 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 91 "parser.y"
+#line 92 "parser.y"
     {
                        accept = 0;
                        spec = NULL;
@@ -1219,7 +1229,7 @@ yyreduce:
     break;
 
   case 5:
-#line 101 "parser.y"
+#line 102 "parser.y"
     {
                        if((yyvsp[-3].symbol)->re)
                        {
@@ -1230,14 +1240,14 @@ yyreduce:
     break;
 
   case 6:
-#line 109 "parser.y"
+#line 110 "parser.y"
     {
                        in->fatal("trailing contexts are not allowed in named definitions");
                }
     break;
 
   case 7:
-#line 113 "parser.y"
+#line 114 "parser.y"
     {
                        in->config(*(yyvsp[-3].str), *(yyvsp[-1].str));
                        delete (yyvsp[-3].str);
@@ -1246,7 +1256,7 @@ yyreduce:
     break;
 
   case 8:
-#line 119 "parser.y"
+#line 120 "parser.y"
     {
                        in->config(*(yyvsp[-3].str), (yyvsp[-1].number));
                        delete (yyvsp[-3].str);
@@ -1254,7 +1264,7 @@ yyreduce:
     break;
 
   case 9:
-#line 127 "parser.y"
+#line 128 "parser.y"
     {
                        if (cFlag)
                        {
@@ -1266,7 +1276,7 @@ yyreduce:
     break;
 
   case 10:
-#line 136 "parser.y"
+#line 137 "parser.y"
     {
                        if (!cFlag)
                        {
@@ -1278,13 +1288,13 @@ yyreduce:
                                // Duplicating stuff, slow but safe
                                (yyval.regexp) = new RuleOp((yyvsp[-2].regexp), (yyvsp[-1].regexp), new Token(*(yyvsp[0].token)), accept++);
                                
-                               RegExpMap::iterator itRE = specmap.find(*it);
+                               RegExpMap::iterator itRE = specMap.find(*it);
                                
-                               if (itRE != specmap.end())
+                               if (itRE != specMap.end())
                                {
                                        (yyval.regexp) = mkAlt(itRE->second, (yyval.regexp));
                                }
-                               specmap[*it] = (yyval.regexp);
+                               specMap[*it] = (yyval.regexp);
                        }
                        delete (yyvsp[-4].clist);
                        delete (yyvsp[0].token);
@@ -1292,7 +1302,7 @@ yyreduce:
     break;
 
   case 11:
-#line 159 "parser.y"
+#line 160 "parser.y"
     {
                        delete (yyvsp[-3].clist);
                        if (!cFlag)
@@ -1304,80 +1314,109 @@ yyreduce:
     break;
 
   case 12:
-#line 171 "parser.y"
+#line 169 "parser.y"
     {
-                       in->fatal("unnamed condition not supported");
+                       if (!cFlag)
+                       {
+                               in->fatal("conditions are only allowed when using -c switch");
+                       }
+                       specStar.push_back(new RuleOp((yyvsp[-2].regexp), (yyvsp[-1].regexp), (yyvsp[0].token), accept++));
                }
     break;
 
   case 13:
-#line 175 "parser.y"
+#line 177 "parser.y"
     {
-                       (yyval.clist) = new CondList();
-                       (yyval.clist)->insert("*");
+                       if (!cFlag)
+                       {
+                               in->fatal("conditions are only allowed when using -c switch");
+                       }
+                       in->fatal("no expression specified");
                }
     break;
 
   case 14:
-#line 180 "parser.y"
+#line 185 "parser.y"
     {
-                       (yyval.clist) = (yyvsp[0].clist);
+                       if (!cFlag)
+                       {
+                               in->fatal("conditions are only allowed when using -c switch");
+                       }
+                       if (specNone)
+                       {
+                               in->fatal("code to handle illegal condition already defined");
+                       }
+                       (yyval.regexp) = specNone = new RuleOp(new NullOp(), new NullOp(), (yyvsp[0].token), accept++);
                }
     break;
 
   case 15:
-#line 187 "parser.y"
+#line 200 "parser.y"
+    {
+                       in->fatal("unnamed condition not supported");
+               }
+    break;
+
+  case 16:
+#line 204 "parser.y"
+    {
+                       (yyval.clist) = (yyvsp[0].clist);
+               }
+    break;
+
+  case 17:
+#line 211 "parser.y"
     {
                        (yyval.clist) = new CondList();
                        (yyval.clist)->insert((yyvsp[0].symbol)->GetName().to_string());
                }
     break;
 
-  case 16:
-#line 192 "parser.y"
+  case 18:
+#line 216 "parser.y"
     {
                        (yyvsp[-2].clist)->insert((yyvsp[0].symbol)->GetName().to_string());
                        (yyval.clist) = (yyvsp[-2].clist);
                }
     break;
 
-  case 17:
-#line 200 "parser.y"
+  case 19:
+#line 224 "parser.y"
     {
                        (yyval.regexp) = new NullOp;
                }
     break;
 
-  case 18:
-#line 204 "parser.y"
+  case 20:
+#line 228 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
-  case 19:
-#line 211 "parser.y"
+  case 21:
+#line 235 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
-  case 20:
-#line 215 "parser.y"
+  case 22:
+#line 239 "parser.y"
     {
                        (yyval.regexp) = mkAlt((yyvsp[-2].regexp), (yyvsp[0].regexp));
                }
     break;
 
-  case 21:
-#line 222 "parser.y"
+  case 23:
+#line 246 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
-  case 22:
-#line 226 "parser.y"
+  case 24:
+#line 250 "parser.y"
     {
                        (yyval.regexp) = mkDiff((yyvsp[-2].regexp), (yyvsp[0].regexp));
                        if(!(yyval.regexp))
@@ -1387,29 +1426,29 @@ yyreduce:
                }
     break;
 
-  case 23:
-#line 237 "parser.y"
+  case 25:
+#line 261 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
-  case 24:
-#line 241 "parser.y"
+  case 26:
+#line 265 "parser.y"
     {
                        (yyval.regexp) = new CatOp((yyvsp[-1].regexp), (yyvsp[0].regexp));
                }
     break;
 
-  case 25:
-#line 248 "parser.y"
+  case 27:
+#line 272 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
-  case 26:
-#line 252 "parser.y"
+  case 28:
+#line 276 "parser.y"
     {
                        switch((yyvsp[0].op))
                        {
@@ -1426,43 +1465,43 @@ yyreduce:
                }
     break;
 
-  case 27:
-#line 267 "parser.y"
+  case 29:
+#line 291 "parser.y"
     {
                        (yyval.regexp) = new CloseVOp((yyvsp[-1].regexp), (yyvsp[0].extop).minsize, (yyvsp[0].extop).maxsize);
                }
     break;
 
-  case 28:
-#line 274 "parser.y"
+  case 30:
+#line 298 "parser.y"
     {
                        (yyval.op) = (yyvsp[0].op);
                }
     break;
 
-  case 29:
-#line 278 "parser.y"
+  case 31:
+#line 302 "parser.y"
     {
                        (yyval.op) = (yyvsp[0].op);
                }
     break;
 
-  case 30:
-#line 282 "parser.y"
+  case 32:
+#line 306 "parser.y"
     {
                        (yyval.op) = ((yyvsp[-1].op) == (yyvsp[0].op)) ? (yyvsp[-1].op) : '*';
                }
     break;
 
-  case 31:
-#line 286 "parser.y"
+  case 33:
+#line 310 "parser.y"
     {
                        (yyval.op) = ((yyvsp[-1].op) == (yyvsp[0].op)) ? (yyvsp[-1].op) : '*';
                }
     break;
 
-  case 32:
-#line 293 "parser.y"
+  case 34:
+#line 317 "parser.y"
     {
                        if(!(yyvsp[0].symbol)->re)
                        {
@@ -1472,22 +1511,22 @@ yyreduce:
                }
     break;
 
-  case 33:
-#line 301 "parser.y"
+  case 35:
+#line 325 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
-  case 34:
-#line 305 "parser.y"
+  case 36:
+#line 329 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
-  case 35:
-#line 309 "parser.y"
+  case 37:
+#line 333 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[-1].regexp);
                }
@@ -1498,7 +1537,7 @@ yyreduce:
     }
 
 /* Line 1126 of yacc.c.  */
-#line 1502 "parser.cc"
+#line 1541 "parser.cc"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -1766,7 +1805,7 @@ yyreturn:
 }
 
 
-#line 314 "parser.y"
+#line 338 "parser.y"
 
 
 extern "C" {
@@ -1802,14 +1841,43 @@ void parse(Scanner& i, std::ostream& o)
                yyparse();
                if (cFlag)
                {
-                       for(RegExpMap::const_iterator it = specmap.begin(); it != specmap.end(); ++it)
+                       RegExpMap::iterator it;
+
+                       if (!specStar.empty())
                        {
-                               if (it->second)
+                               for(it = specMap.begin(); it != specMap.end(); ++it)
                                {
-                                       o << "yyc_" << it->first << ":\n";
-                                       spec = it->second;
-                                       genCode(o, topIndent, spec);
+                                       assert(it->second);
+                                       for(RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp)
+                                       {
+                                               it->second = mkAlt((*itOp)->copy(accept++), it->second);
+                                       }
                                }
+                               if (!specNone)
+                               {
+                                       RuleOpList::const_iterator itOp = specStar.begin();
+
+                                       specNone = (*itOp)->copy(accept++);
+                                       while(++itOp != specStar.end())
+                                       {
+                                               specNone = mkAlt((*itOp)->copy(accept++), specNone);
+                                       }
+                               }
+                       }
+
+                       genCondCheck(o, topIndent, specMap);
+
+                       if (specNone)
+                       {
+                               genCode(o, topIndent, specNone);
+                       }
+
+                       for(it = specMap.begin(); it != specMap.end(); ++it)
+                       {
+                               assert(it->second);
+                               o << condPrefix << it->first << ":\n";
+                               spec = it->second;
+                               genCode(o, topIndent, spec);
                        }
                }
                else if(spec)
@@ -1822,7 +1890,9 @@ void parse(Scanner& i, std::ostream& o)
        RegExp::vFreeList.clear();
        Range::vFreeList.clear();
        Symbol::ClearTable();
-       specmap.clear();
+       specMap.clear();
+       specStar.clear();
+       specNone = NULL;
        in = NULL;
 }
 
index d72e92ada0b5dabac9e11701520cedb817a91cb7..773b074a6959b0e8f5ccda36a87ab269ef9abc73 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.0.dev on Mon Apr 16 17:43:24 2007 */
+/* Generated by re2c 0.13.0.dev on Mon Apr 16 18:34:28 2007 */
 #line 1 "scanner.re"
 /* $Id$ */
 #include <stdlib.h>
@@ -23,6 +23,7 @@ extern YYSTYPE yylval;
 #define        YYCURSOR        cursor
 #define        YYLIMIT         lim
 #define        YYMARKER        ptr
+#define YYCTXMARKER ctx
 #define        YYFILL(n)       {cursor = fill(cursor);}
 
 #define        RETURN(i)       {cur = cursor; return i;}
@@ -34,7 +35,7 @@ Scanner::Scanner(std::istream& i, std::ostream& o)
        : in(i)
        , out(o)
        , bot(NULL), tok(NULL), ptr(NULL), cur(NULL), pos(NULL), lim(NULL)
-       , top(NULL), eof(NULL), tchar(0), tline(0), cline(1), iscfg(0)
+       , top(NULL), eof(NULL), ctx(NULL), tchar(0), tline(0), cline(1), iscfg(0)
 {
        ;
 }
@@ -77,7 +78,7 @@ char *Scanner::fill(char *cursor)
        return cursor;
 }
 
-#line 96 "scanner.re"
+#line 98 "scanner.re"
 
 
 int Scanner::echo()
@@ -95,7 +96,7 @@ int Scanner::echo()
 echo:
 {
 
-#line 99 "scanner.cc"
+#line 100 "scanner.cc"
        {
                YYCTYPE yych;
                unsigned int yyaccept = 0;
@@ -114,18 +115,18 @@ echo:
                yych = *(YYMARKER = ++YYCURSOR);
                if(yych == '*') goto yy16;
 yy3:
-#line 202 "scanner.re"
+#line 204 "scanner.re"
                {
                                        goto echo;
                                }
-#line 122 "scanner.cc"
+#line 123 "scanner.cc"
 yy4:
                yych = *++YYCURSOR;
                if(yych == '/') goto yy10;
                goto yy3;
 yy5:
                ++YYCURSOR;
-#line 178 "scanner.re"
+#line 180 "scanner.re"
                {
                                        if (ignore_eoc)
                                        {
@@ -139,10 +140,10 @@ yy5:
                                        cline++;
                                        goto echo;
                                }
-#line 143 "scanner.cc"
+#line 144 "scanner.cc"
 yy7:
                ++YYCURSOR;
-#line 191 "scanner.re"
+#line 193 "scanner.re"
                {
                                        if (!ignore_eoc)
                                        {
@@ -154,7 +155,7 @@ yy7:
                                                RETURN(0);
                                        }
                                }
-#line 158 "scanner.cc"
+#line 159 "scanner.cc"
 yy9:
                yych = *++YYCURSOR;
                goto yy3;
@@ -164,7 +165,7 @@ yy10:
                if(yych == 0x0A) goto yy14;
                if(yych == 0x0D) goto yy12;
 yy11:
-#line 161 "scanner.re"
+#line 163 "scanner.re"
                {
                                        if (ignore_eoc)
                                        {
@@ -182,7 +183,7 @@ yy11:
                                        tok = pos = cursor;
                                        goto echo;
                                }
-#line 186 "scanner.cc"
+#line 187 "scanner.cc"
 yy12:
                yych = *++YYCURSOR;
                if(yych == 0x0A) goto yy14;
@@ -195,7 +196,7 @@ yy13:
                }
 yy14:
                ++YYCURSOR;
-#line 143 "scanner.re"
+#line 145 "scanner.re"
                {
                                        cline++;
                                        if (ignore_eoc)
@@ -214,7 +215,7 @@ yy14:
                                        tok = pos = cursor;
                                        goto echo;
                                }
-#line 218 "scanner.cc"
+#line 219 "scanner.cc"
 yy16:
                yych = *++YYCURSOR;
                if(yych != '!') goto yy13;
@@ -246,7 +247,7 @@ yy21:
                yych = *++YYCURSOR;
                if(yych != 'c') goto yy13;
                ++YYCURSOR;
-#line 112 "scanner.re"
+#line 114 "scanner.re"
                {
                                        if (bUsedYYMaxFill && bSinglePass)
                                        {
@@ -256,7 +257,7 @@ yy21:
                                        tok = cursor;
                                        RETURN(1);
                                }
-#line 260 "scanner.cc"
+#line 261 "scanner.cc"
 yy26:
                yych = *++YYCURSOR;
                if(yych != 'x') goto yy13;
@@ -271,7 +272,7 @@ yy26:
                yych = *++YYCURSOR;
                if(yych != 'c') goto yy13;
                ++YYCURSOR;
-#line 121 "scanner.re"
+#line 123 "scanner.re"
                {
                                        if (bUsedYYMaxFill)
                                        {
@@ -283,7 +284,7 @@ yy26:
                                        bUsedYYMaxFill = true;
                                        goto echo;
                                }
-#line 287 "scanner.cc"
+#line 288 "scanner.cc"
 yy34:
                yych = *++YYCURSOR;
                if(yych != 't') goto yy13;
@@ -308,14 +309,14 @@ yy34:
                yych = *++YYCURSOR;
                if(yych != 'c') goto yy13;
                ++YYCURSOR;
-#line 132 "scanner.re"
+#line 134 "scanner.re"
                {
                                        tok = pos = cursor;
                                        genGetState(out, topIndent, 0);
                                        ignore_eoc = true;
                                        goto echo;
                                }
-#line 319 "scanner.cc"
+#line 320 "scanner.cc"
 yy47:
                yych = *++YYCURSOR;
                if(yych != 'n') goto yy13;
@@ -336,16 +337,16 @@ yy47:
                yych = *++YYCURSOR;
                if(yych != 'c') goto yy13;
                ++YYCURSOR;
-#line 138 "scanner.re"
+#line 140 "scanner.re"
                {
                                        tok = pos = cursor;
                                        ignore_eoc = true;
                                        goto echo;
                                }
-#line 346 "scanner.cc"
+#line 347 "scanner.cc"
        }
 }
-#line 205 "scanner.re"
+#line 207 "scanner.re"
 
 }
 
@@ -370,21 +371,21 @@ scan:
 {
        static const unsigned char yybm[] = {
                112, 112, 112, 112, 112, 112, 112, 112, 
-               112, 116,   0, 112, 112, 112, 112, 112, 
+               112, 122,   8, 112, 112, 120, 112, 112, 
                112, 112, 112, 112, 112, 112, 112, 112, 
                112, 112, 112, 112, 112, 112, 112, 112, 
-               116, 112,  48, 112, 112, 112, 112,  80, 
+               122, 112,  48, 112, 112, 112, 112,  80, 
                112, 112, 112, 112, 112, 112, 112, 112, 
-               248, 248, 248, 248, 248, 248, 248, 248
-               248, 248, 112, 112, 112, 112, 112, 112, 
-               112, 120, 120, 120, 120, 120, 120, 120
-               120, 120, 120, 120, 120, 120, 120, 120
-               120, 120, 120, 120, 120, 120, 120, 120
-               120, 120, 120, 112,   0,  96, 112, 120
-               112, 120, 120, 120, 120, 120, 120, 120
-               120, 120, 120, 120, 120, 120, 120, 120
-               120, 120, 120, 120, 120, 120, 120, 120
-               120, 120, 120, 112, 112, 112, 112, 112, 
+               244, 244, 244, 244, 244, 244, 244, 244
+               244, 244, 112, 112, 112, 112, 112, 112, 
+               112, 116, 116, 116, 116, 116, 116, 116
+               116, 116, 116, 116, 116, 116, 116, 116
+               116, 116, 116, 116, 116, 116, 116, 116
+               116, 116, 116, 112,   0,  96, 112, 116
+               112, 116, 116, 116, 116, 116, 116, 116
+               116, 116, 116, 116, 116, 116, 116, 116
+               116, 116, 116, 116, 116, 116, 116, 116
+               116, 116, 116, 112, 112, 112, 112, 112, 
                112, 112, 112, 112, 112, 112, 112, 112, 
                112, 112, 112, 112, 112, 112, 112, 112, 
                112, 112, 112, 112, 112, 112, 112, 112, 
@@ -403,67 +404,75 @@ scan:
                112, 112, 112, 112, 112, 112, 112, 112, 
        };
 
-#line 407 "scanner.cc"
+#line 408 "scanner.cc"
        {
                YYCTYPE yych;
                unsigned int yyaccept = 0;
                if((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
                yych = *YYCURSOR;
-               if(yych <= '.') {
-                       if(yych <= '!') {
+               if(yych <= '/') {
+                       if(yych <= '"') {
                                if(yych <= 0x0C) {
-                                       if(yych <= 0x08) goto yy86;
-                                       if(yych <= 0x09) goto yy80;
-                                       if(yych <= 0x0A) goto yy82;
-                                       goto yy86;
+                                       if(yych <= 0x08) goto yy87;
+                                       if(yych <= 0x09) goto yy81;
+                                       if(yych <= 0x0A) goto yy83;
+                                       goto yy87;
                                } else {
-                                       if(yych <= 0x0D) goto yy84;
-                                       if(yych == ' ') goto yy80;
-                                       goto yy86;
+                                       if(yych <= 0x1F) {
+                                               if(yych <= 0x0D) goto yy85;
+                                               goto yy87;
+                                       } else {
+                                               if(yych <= ' ') goto yy81;
+                                               if(yych <= '!') goto yy87;
+                                               goto yy66;
+                                       }
                                }
                        } else {
-                               if(yych <= ')') {
-                                       if(yych <= '"') goto yy66;
-                                       if(yych <= '&') goto yy86;
+                               if(yych <= '*') {
+                                       if(yych <= '&') goto yy87;
                                        if(yych <= '\'') goto yy68;
-                                       goto yy72;
+                                       if(yych <= ')') goto yy73;
+                                       goto yy64;
                                } else {
-                                       if(yych <= '+') {
-                                               if(yych <= '*') goto yy64;
+                                       if(yych <= ',') {
+                                               if(yych <= '+') goto yy74;
                                                goto yy73;
                                        } else {
-                                               if(yych <= ',') goto yy72;
-                                               if(yych <= '-') goto yy86;
-                                               goto yy78;
+                                               if(yych <= '-') goto yy87;
+                                               if(yych <= '.') goto yy79;
+                                               goto yy62;
                                        }
                                }
                        }
                } else {
                        if(yych <= '\\') {
-                               if(yych <= '?') {
-                                       if(yych <= '/') goto yy62;
-                                       if(yych <= ':') goto yy86;
-                                       if(yych <= '>') goto yy72;
+                               if(yych <= '>') {
+                                       if(yych <= ':') goto yy87;
+                                       if(yych == '<') goto yy72;
                                        goto yy73;
                                } else {
-                                       if(yych <= '@') goto yy86;
-                                       if(yych <= 'Z') goto yy77;
-                                       if(yych <= '[') goto yy70;
-                                       goto yy72;
+                                       if(yych <= '@') {
+                                               if(yych <= '?') goto yy74;
+                                               goto yy87;
+                                       } else {
+                                               if(yych <= 'Z') goto yy78;
+                                               if(yych <= '[') goto yy70;
+                                               goto yy73;
+                                       }
                                }
                        } else {
                                if(yych <= 'q') {
-                                       if(yych == '_') goto yy77;
-                                       if(yych <= '`') goto yy86;
-                                       goto yy77;
+                                       if(yych == '_') goto yy78;
+                                       if(yych <= '`') goto yy87;
+                                       goto yy78;
                                } else {
                                        if(yych <= 'z') {
-                                               if(yych <= 'r') goto yy75;
-                                               goto yy77;
+                                               if(yych <= 'r') goto yy76;
+                                               goto yy78;
                                        } else {
                                                if(yych <= '{') goto yy60;
-                                               if(yych <= '|') goto yy72;
-                                               goto yy86;
+                                               if(yych <= '|') goto yy73;
+                                               goto yy87;
                                        }
                                }
                        }
@@ -472,129 +481,134 @@ yy60:
                yyaccept = 0;
                yych = *(YYMARKER = ++YYCURSOR);
                if(yych <= '/') {
-                       if(yych == ',') goto yy127;
+                       if(yych == ',') goto yy133;
                } else {
-                       if(yych <= '0') goto yy124;
-                       if(yych <= '9') goto yy125;
+                       if(yych <= '0') goto yy130;
+                       if(yych <= '9') goto yy131;
                }
 yy61:
-#line 227 "scanner.re"
+#line 229 "scanner.re"
                {
                                        depth = 1;
                                        goto code;
                                }
-#line 487 "scanner.cc"
+#line 496 "scanner.cc"
 yy62:
                ++YYCURSOR;
-               if((yych = *YYCURSOR) == '*') goto yy122;
+               if((yych = *YYCURSOR) == '*') goto yy128;
 yy63:
-#line 277 "scanner.re"
+#line 282 "scanner.re"
                {
                                        RETURN(*tok);
                                }
-#line 496 "scanner.cc"
+#line 505 "scanner.cc"
 yy64:
                ++YYCURSOR;
-               if((yych = *YYCURSOR) == '/') goto yy120;
-#line 281 "scanner.re"
+               if((yych = *YYCURSOR) == '/') goto yy126;
+#line 286 "scanner.re"
                {
                                        yylval.op = *tok;
                                        RETURN(STAR);
                                }
-#line 505 "scanner.cc"
+#line 514 "scanner.cc"
 yy66:
                yyaccept = 1;
                yych = *(YYMARKER = ++YYCURSOR);
-               if(yych != 0x0A) goto yy116;
+               if(yych != 0x0A) goto yy122;
 yy67:
-#line 254 "scanner.re"
+#line 256 "scanner.re"
                {
                                        fatal("unterminated string constant (missing \")");
                                }
-#line 515 "scanner.cc"
+#line 524 "scanner.cc"
 yy68:
                yyaccept = 2;
                yych = *(YYMARKER = ++YYCURSOR);
-               if(yych != 0x0A) goto yy111;
+               if(yych != 0x0A) goto yy117;
 yy69:
-#line 257 "scanner.re"
+#line 259 "scanner.re"
                {
                                        fatal("unterminated string constant (missing ')");
                                }
-#line 525 "scanner.cc"
+#line 534 "scanner.cc"
 yy70:
                yyaccept = 3;
                yych = *(YYMARKER = ++YYCURSOR);
                if(yych == 0x0A) goto yy71;
-               if(yych == '^') goto yy102;
-               goto yy101;
+               if(yych == '^') goto yy108;
+               goto yy107;
 yy71:
-#line 273 "scanner.re"
+#line 275 "scanner.re"
                {
                                        fatal("unterminated range (missing ])");
                                }
-#line 537 "scanner.cc"
+#line 546 "scanner.cc"
 yy72:
-               yych = *++YYCURSOR;
+               yyaccept = 4;
+               yych = *(YYMARKER = ++YYCURSOR);
+               if(yych == '>') goto yy101;
                goto yy63;
 yy73:
+               yych = *++YYCURSOR;
+               goto yy63;
+yy74:
                ++YYCURSOR;
-#line 285 "scanner.re"
+#line 290 "scanner.re"
                {
                                        yylval.op = *tok;
                                        RETURN(CLOSE);
                                }
-#line 548 "scanner.cc"
-yy75:
-               ++YYCURSOR;
-               if((yych = *YYCURSOR) == 'e') goto yy92;
-               goto yy91;
+#line 562 "scanner.cc"
 yy76:
-#line 325 "scanner.re"
+               ++YYCURSOR;
+               if((yych = *YYCURSOR) == 'e') goto yy93;
+               goto yy92;
+yy77:
+#line 330 "scanner.re"
                {
                                        cur = cursor;
                                        yylval.symbol = Symbol::find(token());
                                        return ID;
                                }
-#line 560 "scanner.cc"
-yy77:
-               yych = *++YYCURSOR;
-               goto yy91;
+#line 574 "scanner.cc"
 yy78:
+               yych = *++YYCURSOR;
+               goto yy92;
+yy79:
                ++YYCURSOR;
-#line 331 "scanner.re"
+#line 336 "scanner.re"
                {
                                        cur = cursor;
                                        yylval.regexp = mkDot();
                                        return RANGE;
                                }
-#line 572 "scanner.cc"
-yy80:
+#line 586 "scanner.cc"
+yy81:
                ++YYCURSOR;
                yych = *YYCURSOR;
-               goto yy89;
-yy81:
-#line 337 "scanner.re"
+               goto yy90;
+yy82:
+#line 342 "scanner.re"
                {
                                        goto scan;
                                }
-#line 582 "scanner.cc"
-yy82:
-               ++YYCURSOR;
+#line 596 "scanner.cc"
 yy83:
-#line 341 "scanner.re"
+               ++YYCURSOR;
+yy84:
+#line 346 "scanner.re"
                {
                                        if(cursor == eof) RETURN(0);
                                        pos = cursor;
                                        cline++;
                                        goto scan;
                                }
-#line 593 "scanner.cc"
-yy84:
-               ++YYCURSOR;
-               if((yych = *YYCURSOR) == 0x0A) goto yy87;
+#line 607 "scanner.cc"
 yy85:
-#line 348 "scanner.re"
+               ++YYCURSOR;
+               if((yych = *YYCURSOR) == 0x0A) goto yy88;
+yy86:
+#line 353 "scanner.re"
                {
                                        std::ostringstream msg;
                                        msg << "unexpected character: ";
@@ -602,51 +616,51 @@ yy85:
                                        fatal(msg.str().c_str());
                                        goto scan;
                                }
-#line 606 "scanner.cc"
-yy86:
-               yych = *++YYCURSOR;
-               goto yy85;
+#line 620 "scanner.cc"
 yy87:
                yych = *++YYCURSOR;
-               goto yy83;
+               goto yy86;
 yy88:
+               yych = *++YYCURSOR;
+               goto yy84;
+yy89:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-yy89:
-               if(yybm[0+yych] & 4) {
-                       goto yy88;
-               }
-               goto yy81;
 yy90:
+               if(yybm[0+yych] & 2) {
+                       goto yy89;
+               }
+               goto yy82;
+yy91:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-yy91:
-               if(yybm[0+yych] & 8) {
-                       goto yy90;
-               }
-               goto yy76;
 yy92:
+               if(yybm[0+yych] & 4) {
+                       goto yy91;
+               }
+               goto yy77;
+yy93:
                yych = *++YYCURSOR;
-               if(yych != '2') goto yy91;
+               if(yych != '2') goto yy92;
                yych = *++YYCURSOR;
-               if(yych != 'c') goto yy91;
-               yyaccept = 4;
+               if(yych != 'c') goto yy92;
+               yyaccept = 5;
                yych = *(YYMARKER = ++YYCURSOR);
-               if(yych != ':') goto yy91;
-yy95:
+               if(yych != ':') goto yy92;
+yy96:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
                if(yych <= '^') {
-                       if(yych <= '@') goto yy96;
-                       if(yych <= 'Z') goto yy97;
+                       if(yych <= '@') goto yy97;
+                       if(yych <= 'Z') goto yy98;
                } else {
-                       if(yych == '`') goto yy96;
-                       if(yych <= 'z') goto yy97;
+                       if(yych == '`') goto yy97;
+                       if(yych <= 'z') goto yy98;
                }
-yy96:
+yy97:
                YYCURSOR = YYMARKER;
                if(yyaccept <= 3) {
                        if(yyaccept <= 1) {
@@ -665,36 +679,40 @@ yy96:
                } else {
                        if(yyaccept <= 5) {
                                if(yyaccept <= 4) {
-                                       goto yy76;
+                                       goto yy63;
                                } else {
-                                       goto yy99;
+                                       goto yy77;
                                }
                        } else {
-                               goto yy128;
+                               if(yyaccept <= 6) {
+                                       goto yy100;
+                               } else {
+                                       goto yy134;
+                               }
                        }
                }
-yy97:
-               yyaccept = 5;
+yy98:
+               yyaccept = 6;
                YYMARKER = ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
                if(yych <= 'Z') {
                        if(yych <= '9') {
-                               if(yych >= '0') goto yy97;
+                               if(yych >= '0') goto yy98;
                        } else {
-                               if(yych <= ':') goto yy95;
-                               if(yych >= 'A') goto yy97;
+                               if(yych <= ':') goto yy96;
+                               if(yych >= 'A') goto yy98;
                        }
                } else {
                        if(yych <= '_') {
-                               if(yych >= '_') goto yy97;
+                               if(yych >= '_') goto yy98;
                        } else {
-                               if(yych <= '`') goto yy99;
-                               if(yych <= 'z') goto yy97;
+                               if(yych <= '`') goto yy100;
+                               if(yych <= 'z') goto yy98;
                        }
                }
-yy99:
-#line 317 "scanner.re"
+yy100:
+#line 322 "scanner.re"
                {
                                        cur = cursor;
                                        tok+= 5; /* skip "re2c:" */
@@ -702,201 +720,221 @@ yy99:
                                        yylval.str = new Str(token());
                                        return CONFIG;
                                }
-#line 706 "scanner.cc"
-yy100:
+#line 724 "scanner.cc"
+yy101:
+               YYCTXMARKER = YYCURSOR + 1;
+               yych = *++YYCURSOR;
+               goto yy103;
+yy102:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-yy101:
+yy103:
+               if(yybm[0+yych] & 8) {
+                       goto yy102;
+               }
+               if(yych != '{') goto yy97;
+               ++YYCURSOR;
+               YYCURSOR = YYCTXMARKER;
+#line 279 "scanner.re"
+               {
+                                       RETURN(NOCOND);
+                               }
+#line 744 "scanner.cc"
+yy106:
+               ++YYCURSOR;
+               if(YYLIMIT == YYCURSOR) YYFILL(1);
+               yych = *YYCURSOR;
+yy107:
                if(yybm[0+yych] & 16) {
-                       goto yy100;
+                       goto yy106;
                }
-               if(yych <= '[') goto yy96;
-               if(yych <= '\\') goto yy104;
-               goto yy105;
-yy102:
+               if(yych <= '[') goto yy97;
+               if(yych <= '\\') goto yy110;
+               goto yy111;
+yy108:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
                if(yych <= '[') {
-                       if(yych == 0x0A) goto yy96;
-                       goto yy102;
+                       if(yych == 0x0A) goto yy97;
+                       goto yy108;
                } else {
-                       if(yych <= '\\') goto yy107;
-                       if(yych <= ']') goto yy108;
-                       goto yy102;
+                       if(yych <= '\\') goto yy113;
+                       if(yych <= ']') goto yy114;
+                       goto yy108;
                }
-yy104:
+yy110:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-               if(yych == 0x0A) goto yy96;
-               goto yy100;
-yy105:
+               if(yych == 0x0A) goto yy97;
+               goto yy106;
+yy111:
                ++YYCURSOR;
-#line 267 "scanner.re"
+#line 269 "scanner.re"
                {
                                        cur = cursor;
                                        yylval.regexp = ranToRE(token());
                                        return RANGE;
                                }
-#line 744 "scanner.cc"
-yy107:
+#line 782 "scanner.cc"
+yy113:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-               if(yych == 0x0A) goto yy96;
-               goto yy102;
-yy108:
+               if(yych == 0x0A) goto yy97;
+               goto yy108;
+yy114:
                ++YYCURSOR;
-#line 261 "scanner.re"
+#line 263 "scanner.re"
                {
                                        cur = cursor;
                                        yylval.regexp = invToRE(token());
                                        return RANGE;
                                }
-#line 759 "scanner.cc"
-yy110:
+#line 797 "scanner.cc"
+yy116:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-yy111:
+yy117:
                if(yybm[0+yych] & 32) {
-                       goto yy110;
+                       goto yy116;
                }
-               if(yych <= '&') goto yy96;
-               if(yych <= '\'') goto yy113;
+               if(yych <= '&') goto yy97;
+               if(yych <= '\'') goto yy119;
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-               if(yych == 0x0A) goto yy96;
-               goto yy110;
-yy113:
+               if(yych == 0x0A) goto yy97;
+               goto yy116;
+yy119:
                ++YYCURSOR;
-#line 248 "scanner.re"
+#line 250 "scanner.re"
                {
                                        cur = cursor;
                                        yylval.regexp = strToCaseInsensitiveRE(token());
                                        return STRING;
                                }
-#line 783 "scanner.cc"
-yy115:
+#line 821 "scanner.cc"
+yy121:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-yy116:
+yy122:
                if(yybm[0+yych] & 64) {
-                       goto yy115;
+                       goto yy121;
                }
-               if(yych <= '!') goto yy96;
-               if(yych <= '"') goto yy118;
+               if(yych <= '!') goto yy97;
+               if(yych <= '"') goto yy124;
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-               if(yych == 0x0A) goto yy96;
-               goto yy115;
-yy118:
+               if(yych == 0x0A) goto yy97;
+               goto yy121;
+yy124:
                ++YYCURSOR;
-#line 242 "scanner.re"
+#line 244 "scanner.re"
                {
                                        cur = cursor;
                                        yylval.regexp = strToRE(token());
                                        return STRING;
                                }
-#line 807 "scanner.cc"
-yy120:
+#line 845 "scanner.cc"
+yy126:
                ++YYCURSOR;
-#line 237 "scanner.re"
+#line 239 "scanner.re"
                {
                                        tok = cursor;
                                        RETURN(0);
                                }
-#line 815 "scanner.cc"
-yy122:
+#line 853 "scanner.cc"
+yy128:
                ++YYCURSOR;
-#line 232 "scanner.re"
+#line 234 "scanner.re"
                {
                                        depth = 1;
                                        goto comment;
                                }
-#line 823 "scanner.cc"
-yy124:
+#line 861 "scanner.cc"
+yy130:
                yych = *++YYCURSOR;
-               if(yych == ',') goto yy138;
-               goto yy126;
-yy125:
+               if(yych == ',') goto yy144;
+               goto yy132;
+yy131:
                ++YYCURSOR;
                if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
                yych = *YYCURSOR;
-yy126:
+yy132:
                if(yybm[0+yych] & 128) {
-                       goto yy125;
+                       goto yy131;
                }
-               if(yych == ',') goto yy131;
-               if(yych == '}') goto yy129;
-               goto yy96;
-yy127:
+               if(yych == ',') goto yy137;
+               if(yych == '}') goto yy135;
+               goto yy97;
+yy133:
                ++YYCURSOR;
-yy128:
-#line 313 "scanner.re"
+yy134:
+#line 318 "scanner.re"
                {
                                        fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers");
                                }
-#line 846 "scanner.cc"
-yy129:
+#line 884 "scanner.cc"
+yy135:
                ++YYCURSOR;
-#line 295 "scanner.re"
+#line 300 "scanner.re"
                {
                                        yylval.extop.minsize = atoi((char *)tok+1);
                                        yylval.extop.maxsize = atoi((char *)tok+1);
                                        RETURN(CLOSESIZE);
                                }
-#line 855 "scanner.cc"
-yy131:
-               yyaccept = 6;
+#line 893 "scanner.cc"
+yy137:
+               yyaccept = 7;
                yych = *(YYMARKER = ++YYCURSOR);
-               if(yych <= '/') goto yy128;
-               if(yych <= '9') goto yy134;
-               if(yych != '}') goto yy128;
+               if(yych <= '/') goto yy134;
+               if(yych <= '9') goto yy140;
+               if(yych != '}') goto yy134;
                ++YYCURSOR;
-#line 307 "scanner.re"
+#line 312 "scanner.re"
                {
                                        yylval.extop.minsize = atoi((char *)tok+1);
                                        yylval.extop.maxsize = -1;
                                        RETURN(CLOSESIZE);
                                }
-#line 869 "scanner.cc"
-yy134:
+#line 907 "scanner.cc"
+yy140:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-               if(yych <= '/') goto yy96;
-               if(yych <= '9') goto yy134;
-               if(yych != '}') goto yy96;
+               if(yych <= '/') goto yy97;
+               if(yych <= '9') goto yy140;
+               if(yych != '}') goto yy97;
                ++YYCURSOR;
-#line 301 "scanner.re"
+#line 306 "scanner.re"
                {
                                        yylval.extop.minsize = atoi((char *)tok+1);
                                        yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
                                        RETURN(CLOSESIZE);
                                }
-#line 884 "scanner.cc"
-yy138:
-               yyaccept = 6;
+#line 922 "scanner.cc"
+yy144:
+               yyaccept = 7;
                yych = *(YYMARKER = ++YYCURSOR);
-               if(yych <= '/') goto yy128;
-               if(yych <= '9') goto yy134;
-               if(yych != '}') goto yy128;
+               if(yych <= '/') goto yy134;
+               if(yych <= '9') goto yy140;
+               if(yych != '}') goto yy134;
                ++YYCURSOR;
-#line 290 "scanner.re"
+#line 295 "scanner.re"
                {
                                        yylval.op = '*';
                                        RETURN(CLOSE);
                                }
-#line 897 "scanner.cc"
+#line 935 "scanner.cc"
        }
 }
-#line 355 "scanner.re"
+#line 360 "scanner.re"
 
 
 code:
@@ -936,31 +974,31 @@ code:
                192, 192, 192, 192, 192, 192, 192, 192, 
        };
 
-#line 940 "scanner.cc"
+#line 978 "scanner.cc"
        {
                YYCTYPE yych;
                if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
                yych = *YYCURSOR;
                if(yych <= '&') {
                        if(yych <= 0x0A) {
-                               if(yych <= 0x00) goto yy149;
-                               if(yych <= 0x09) goto yy151;
-                               goto yy147;
+                               if(yych <= 0x00) goto yy155;
+                               if(yych <= 0x09) goto yy157;
+                               goto yy153;
                        } else {
-                               if(yych == '"') goto yy153;
-                               goto yy151;
+                               if(yych == '"') goto yy159;
+                               goto yy157;
                        }
                } else {
                        if(yych <= '{') {
-                               if(yych <= '\'') goto yy154;
-                               if(yych <= 'z') goto yy151;
-                               goto yy145;
+                               if(yych <= '\'') goto yy160;
+                               if(yych <= 'z') goto yy157;
+                               goto yy151;
                        } else {
-                               if(yych != '}') goto yy151;
+                               if(yych != '}') goto yy157;
                        }
                }
                ++YYCURSOR;
-#line 359 "scanner.re"
+#line 364 "scanner.re"
                {
                                        if(--depth == 0)
                                        {
@@ -970,18 +1008,18 @@ code:
                                        }
                                        goto code;
                                }
-#line 974 "scanner.cc"
-yy145:
+#line 1012 "scanner.cc"
+yy151:
                ++YYCURSOR;
-#line 368 "scanner.re"
+#line 373 "scanner.re"
                {
                                        ++depth;
                                        goto code;
                                }
-#line 982 "scanner.cc"
-yy147:
+#line 1020 "scanner.cc"
+yy153:
                ++YYCURSOR;
-#line 372 "scanner.re"
+#line 377 "scanner.re"
                {
                                        if(cursor == eof)
                                        {
@@ -991,10 +1029,10 @@ yy147:
                                        cline++;
                                        goto code;
                                }
-#line 995 "scanner.cc"
-yy149:
+#line 1033 "scanner.cc"
+yy155:
                ++YYCURSOR;
-#line 381 "scanner.re"
+#line 386 "scanner.re"
                {
                                        if(cursor == eof)
                                        {
@@ -1006,84 +1044,84 @@ yy149:
                                        }
                                        goto code;
                                }
-#line 1010 "scanner.cc"
-yy151:
+#line 1048 "scanner.cc"
+yy157:
                ++YYCURSOR;
-yy152:
-#line 392 "scanner.re"
+yy158:
+#line 397 "scanner.re"
                {
                                        goto code;
                                }
-#line 1018 "scanner.cc"
-yy153:
+#line 1056 "scanner.cc"
+yy159:
                yych = *(YYMARKER = ++YYCURSOR);
-               if(yych == 0x0A) goto yy152;
-               goto yy160;
-yy154:
+               if(yych == 0x0A) goto yy158;
+               goto yy166;
+yy160:
                yych = *(YYMARKER = ++YYCURSOR);
-               if(yych == 0x0A) goto yy152;
-               goto yy156;
-yy155:
+               if(yych == 0x0A) goto yy158;
+               goto yy162;
+yy161:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-yy156:
+yy162:
                if(yybm[0+yych] & 64) {
-                       goto yy155;
+                       goto yy161;
                }
-               if(yych <= '&') goto yy157;
-               if(yych <= '\'') goto yy151;
-               goto yy158;
-yy157:
+               if(yych <= '&') goto yy163;
+               if(yych <= '\'') goto yy157;
+               goto yy164;
+yy163:
                YYCURSOR = YYMARKER;
-               goto yy152;
-yy158:
+               goto yy158;
+yy164:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-               if(yych == 0x0A) goto yy157;
-               goto yy155;
-yy159:
+               if(yych == 0x0A) goto yy163;
+               goto yy161;
+yy165:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-yy160:
+yy166:
                if(yybm[0+yych] & 128) {
-                       goto yy159;
+                       goto yy165;
                }
-               if(yych <= '!') goto yy157;
-               if(yych <= '"') goto yy151;
+               if(yych <= '!') goto yy163;
+               if(yych <= '"') goto yy157;
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-               if(yych == 0x0A) goto yy157;
-               goto yy159;
+               if(yych == 0x0A) goto yy163;
+               goto yy165;
        }
 }
-#line 395 "scanner.re"
+#line 400 "scanner.re"
 
 
 comment:
 {
 
-#line 1070 "scanner.cc"
+#line 1108 "scanner.cc"
        {
                YYCTYPE yych;
                if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
                yych = *YYCURSOR;
                if(yych <= ')') {
-                       if(yych == 0x0A) goto yy167;
-                       goto yy169;
+                       if(yych == 0x0A) goto yy173;
+                       goto yy175;
                } else {
-                       if(yych <= '*') goto yy164;
-                       if(yych == '/') goto yy166;
-                       goto yy169;
+                       if(yych <= '*') goto yy170;
+                       if(yych == '/') goto yy172;
+                       goto yy175;
                }
-yy164:
+yy170:
                ++YYCURSOR;
-               if((yych = *YYCURSOR) == '/') goto yy172;
-yy165:
-#line 423 "scanner.re"
+               if((yych = *YYCURSOR) == '/') goto yy178;
+yy171:
+#line 428 "scanner.re"
                {
                                        if(cursor == eof)
                                        {
@@ -1091,14 +1129,14 @@ yy165:
                                        }
                                        goto comment;
                                }
-#line 1095 "scanner.cc"
-yy166:
+#line 1133 "scanner.cc"
+yy172:
                yych = *++YYCURSOR;
-               if(yych == '*') goto yy170;
-               goto yy165;
-yy167:
+               if(yych == '*') goto yy176;
+               goto yy171;
+yy173:
                ++YYCURSOR;
-#line 414 "scanner.re"
+#line 419 "scanner.re"
                {
                                        if(cursor == eof)
                                        {
@@ -1108,22 +1146,22 @@ yy167:
                                        cline++;
                                        goto comment;
                                }
-#line 1112 "scanner.cc"
-yy169:
+#line 1150 "scanner.cc"
+yy175:
                yych = *++YYCURSOR;
-               goto yy165;
-yy170:
+               goto yy171;
+yy176:
                ++YYCURSOR;
-#line 409 "scanner.re"
+#line 414 "scanner.re"
                {
                                        ++depth;
                                        fatal("ambiguous /* found");
                                        goto comment;
                                }
-#line 1124 "scanner.cc"
-yy172:
+#line 1162 "scanner.cc"
+yy178:
                ++YYCURSOR;
-#line 399 "scanner.re"
+#line 404 "scanner.re"
                {
                                        if(--depth == 0)
                                        {
@@ -1134,10 +1172,10 @@ yy172:
                                                goto comment;
                                        }
                                }
-#line 1138 "scanner.cc"
+#line 1176 "scanner.cc"
        }
 }
-#line 430 "scanner.re"
+#line 435 "scanner.re"
 
 
 config:
@@ -1177,67 +1215,67 @@ config:
                  0,   0,   0,   0,   0,   0,   0,   0, 
        };
 
-#line 1181 "scanner.cc"
+#line 1219 "scanner.cc"
        {
                YYCTYPE yych;
                if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
                yych = *YYCURSOR;
                if(yych <= 0x1F) {
-                       if(yych != 0x09) goto yy180;
+                       if(yych != 0x09) goto yy186;
                } else {
-                       if(yych <= ' ') goto yy176;
-                       if(yych == '=') goto yy178;
-                       goto yy180;
+                       if(yych <= ' ') goto yy182;
+                       if(yych == '=') goto yy184;
+                       goto yy186;
                }
-yy176:
+yy182:
                ++YYCURSOR;
                yych = *YYCURSOR;
-               goto yy185;
-yy177:
-#line 434 "scanner.re"
+               goto yy191;
+yy183:
+#line 439 "scanner.re"
                {
                                        goto config;
                                }
-#line 1202 "scanner.cc"
-yy178:
+#line 1240 "scanner.cc"
+yy184:
                ++YYCURSOR;
                yych = *YYCURSOR;
-               goto yy183;
-yy179:
-#line 437 "scanner.re"
+               goto yy189;
+yy185:
+#line 442 "scanner.re"
                {
                                        iscfg = 2;
                                        cur = cursor;
                                        RETURN('=');
                                }
-#line 1214 "scanner.cc"
-yy180:
+#line 1252 "scanner.cc"
+yy186:
                ++YYCURSOR;
-#line 442 "scanner.re"
+#line 447 "scanner.re"
                {
                                        fatal("missing '='");
                                }
-#line 1221 "scanner.cc"
-yy182:
+#line 1259 "scanner.cc"
+yy188:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-yy183:
+yy189:
                if(yybm[0+yych] & 128) {
-                       goto yy182;
+                       goto yy188;
                }
-               goto yy179;
-yy184:
+               goto yy185;
+yy190:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-yy185:
-               if(yych == 0x09) goto yy184;
-               if(yych == ' ') goto yy184;
-               goto yy177;
+yy191:
+               if(yych == 0x09) goto yy190;
+               if(yych == ' ') goto yy190;
+               goto yy183;
        }
 }
-#line 445 "scanner.re"
+#line 450 "scanner.re"
 
 
 value:
@@ -1277,205 +1315,205 @@ value:
                248, 248, 248, 248, 248, 248, 248, 248, 
        };
 
-#line 1281 "scanner.cc"
+#line 1319 "scanner.cc"
        {
                YYCTYPE yych;
                if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
                yych = *YYCURSOR;
                if(yych <= '&') {
                        if(yych <= 0x0D) {
-                               if(yych <= 0x08) goto yy194;
-                               if(yych <= 0x0A) goto yy188;
-                               if(yych <= 0x0C) goto yy194;
+                               if(yych <= 0x08) goto yy200;
+                               if(yych <= 0x0A) goto yy194;
+                               if(yych <= 0x0C) goto yy200;
                        } else {
                                if(yych <= ' ') {
-                                       if(yych <= 0x1F) goto yy194;
+                                       if(yych <= 0x1F) goto yy200;
                                } else {
-                                       if(yych == '"') goto yy196;
-                                       goto yy194;
+                                       if(yych == '"') goto yy202;
+                                       goto yy200;
                                }
                        }
                } else {
                        if(yych <= '/') {
-                               if(yych <= '\'') goto yy198;
-                               if(yych == '-') goto yy191;
-                               goto yy194;
+                               if(yych <= '\'') goto yy204;
+                               if(yych == '-') goto yy197;
+                               goto yy200;
                        } else {
                                if(yych <= '9') {
-                                       if(yych <= '0') goto yy189;
-                                       goto yy192;
+                                       if(yych <= '0') goto yy195;
+                                       goto yy198;
                                } else {
-                                       if(yych != ';') goto yy194;
+                                       if(yych != ';') goto yy200;
                                }
                        }
                }
-yy188:
-#line 455 "scanner.re"
+yy194:
+#line 460 "scanner.re"
                {
                                        cur = cursor;
                                        yylval.str = new Str(token());
                                        iscfg = 0;
                                        return VALUE;
                                }
-#line 1321 "scanner.cc"
-yy189:
+#line 1359 "scanner.cc"
+yy195:
                ++YYCURSOR;
                if(yybm[0+(yych = *YYCURSOR)] & 8) {
-                       goto yy194;
+                       goto yy200;
                }
-yy190:
-#line 449 "scanner.re"
+yy196:
+#line 454 "scanner.re"
                {
                                        cur = cursor;
                                        yylval.number = atoi(token().to_string().c_str());
                                        iscfg = 0;
                                        return NUMBER;
                                }
-#line 1335 "scanner.cc"
-yy191:
+#line 1373 "scanner.cc"
+yy197:
                yych = *++YYCURSOR;
-               if(yych <= '0') goto yy195;
-               if(yych >= ':') goto yy195;
-yy192:
+               if(yych <= '0') goto yy201;
+               if(yych >= ':') goto yy201;
+yy198:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
                if(yybm[0+yych] & 4) {
-                       goto yy192;
+                       goto yy198;
                }
                if(yych <= 0x0D) {
-                       if(yych <= 0x08) goto yy194;
-                       if(yych <= 0x0A) goto yy190;
-                       if(yych >= 0x0D) goto yy190;
+                       if(yych <= 0x08) goto yy200;
+                       if(yych <= 0x0A) goto yy196;
+                       if(yych >= 0x0D) goto yy196;
                } else {
                        if(yych <= ' ') {
-                               if(yych >= ' ') goto yy190;
+                               if(yych >= ' ') goto yy196;
                        } else {
-                               if(yych == ';') goto yy190;
+                               if(yych == ';') goto yy196;
                        }
                }
-yy194:
+yy200:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-yy195:
+yy201:
                if(yybm[0+yych] & 8) {
-                       goto yy194;
+                       goto yy200;
                }
-               goto yy188;
-yy196:
+               goto yy194;
+yy202:
                YYMARKER = ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
                if(yybm[0+yych] & 16) {
-                       goto yy196;
+                       goto yy202;
                }
                if(yych <= '!') {
-                       if(yych == 0x0A) goto yy188;
-                       goto yy206;
+                       if(yych == 0x0A) goto yy194;
+                       goto yy212;
                } else {
-                       if(yych <= '"') goto yy194;
-                       if(yych <= '[') goto yy206;
-                       goto yy208;
+                       if(yych <= '"') goto yy200;
+                       if(yych <= '[') goto yy212;
+                       goto yy214;
                }
-yy198:
+yy204:
                YYMARKER = ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
                if(yybm[0+yych] & 32) {
-                       goto yy198;
+                       goto yy204;
                }
                if(yych <= '&') {
-                       if(yych == 0x0A) goto yy188;
+                       if(yych == 0x0A) goto yy194;
                } else {
-                       if(yych <= '\'') goto yy194;
-                       if(yych >= '\\') goto yy203;
+                       if(yych <= '\'') goto yy200;
+                       if(yych >= '\\') goto yy209;
                }
-yy200:
+yy206:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
                if(yybm[0+yych] & 64) {
-                       goto yy200;
+                       goto yy206;
                }
-               if(yych <= '&') goto yy202;
-               if(yych <= '\'') goto yy204;
-               goto yy205;
-yy202:
+               if(yych <= '&') goto yy208;
+               if(yych <= '\'') goto yy210;
+               goto yy211;
+yy208:
                YYCURSOR = YYMARKER;
-               goto yy188;
-yy203:
+               goto yy194;
+yy209:
                YYMARKER = ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
                if(yych <= 0x0D) {
                        if(yych <= 0x09) {
-                               if(yych <= 0x08) goto yy198;
-                               goto yy200;
+                               if(yych <= 0x08) goto yy204;
+                               goto yy206;
                        } else {
-                               if(yych <= 0x0A) goto yy188;
-                               if(yych <= 0x0C) goto yy198;
-                               goto yy200;
+                               if(yych <= 0x0A) goto yy194;
+                               if(yych <= 0x0C) goto yy204;
+                               goto yy206;
                        }
                } else {
                        if(yych <= ' ') {
-                               if(yych <= 0x1F) goto yy198;
-                               goto yy200;
+                               if(yych <= 0x1F) goto yy204;
+                               goto yy206;
                        } else {
-                               if(yych == ';') goto yy200;
-                               goto yy198;
+                               if(yych == ';') goto yy206;
+                               goto yy204;
                        }
                }
-yy204:
+yy210:
                yych = *++YYCURSOR;
-               goto yy188;
-yy205:
+               goto yy194;
+yy211:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-               if(yych == 0x0A) goto yy202;
-               goto yy200;
-yy206:
+               if(yych == 0x0A) goto yy208;
+               goto yy206;
+yy212:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
                if(yybm[0+yych] & 128) {
-                       goto yy206;
+                       goto yy212;
                }
-               if(yych <= '!') goto yy202;
-               if(yych <= '"') goto yy204;
-               goto yy209;
-yy208:
+               if(yych <= '!') goto yy208;
+               if(yych <= '"') goto yy210;
+               goto yy215;
+yy214:
                YYMARKER = ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
                if(yych <= 0x0D) {
                        if(yych <= 0x09) {
-                               if(yych <= 0x08) goto yy196;
-                               goto yy206;
+                               if(yych <= 0x08) goto yy202;
+                               goto yy212;
                        } else {
-                               if(yych <= 0x0A) goto yy188;
-                               if(yych <= 0x0C) goto yy196;
-                               goto yy206;
+                               if(yych <= 0x0A) goto yy194;
+                               if(yych <= 0x0C) goto yy202;
+                               goto yy212;
                        }
                } else {
                        if(yych <= ' ') {
-                               if(yych <= 0x1F) goto yy196;
-                               goto yy206;
+                               if(yych <= 0x1F) goto yy202;
+                               goto yy212;
                        } else {
-                               if(yych == ';') goto yy206;
-                               goto yy196;
+                               if(yych == ';') goto yy212;
+                               goto yy202;
                        }
                }
-yy209:
+yy215:
                ++YYCURSOR;
                if(YYLIMIT == YYCURSOR) YYFILL(1);
                yych = *YYCURSOR;
-               if(yych == 0x0A) goto yy202;
-               goto yy206;
+               if(yych == 0x0A) goto yy208;
+               goto yy212;
        }
 }
-#line 461 "scanner.re"
+#line 466 "scanner.re"
 
 }
 
index 49e44d85c58ed7edcfd04dec13404c74c9c0bee6..562f2a6534a624308ad6435e7923109c6ad46bb6 100644 (file)
      CLOSESIZE = 258,
      CLOSE = 259,
      STAR = 260,
-     ID = 261,
-     CODE = 262,
-     RANGE = 263,
-     STRING = 264,
-     CONFIG = 265,
-     VALUE = 266,
-     NUMBER = 267
+     NOCOND = 261,
+     ID = 262,
+     CODE = 263,
+     RANGE = 264,
+     STRING = 265,
+     CONFIG = 266,
+     VALUE = 267,
+     NUMBER = 268
    };
 #endif
 /* Tokens.  */
 #define CLOSESIZE 258
 #define CLOSE 259
 #define STAR 260
-#define ID 261
-#define CODE 262
-#define RANGE 263
-#define STRING 264
-#define CONFIG 265
-#define VALUE 266
-#define NUMBER 267
+#define NOCOND 261
+#define ID 262
+#define CODE 263
+#define RANGE 264
+#define STRING 265
+#define CONFIG 266
+#define VALUE 267
+#define NUMBER 268
 
 
 
 
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 62 "parser.y"
+#line 63 "parser.y"
 typedef union YYSTYPE {
        re2c::Symbol    *symbol;
        re2c::RegExp    *regexp;
@@ -69,7 +71,7 @@ typedef union YYSTYPE {
        re2c::CondList  *clist;
 } YYSTYPE;
 /* Line 1447 of yacc.c.  */
-#line 73 "y.tab.h"
+#line 75 "y.tab.h"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
index d47d1c6b7c791a9d6926abfd5aa23df3ea626aba..4edce0cd2f17663d77d013371ea8d77c8adf8aea 100644 (file)
@@ -1647,6 +1647,33 @@ void genGetState(std::ostream &o, uint& ind, uint start_label)
        }
 }
 
+void genCondCheck(std::ostream &o, uint& ind, const RegExpMap& specMap)
+{
+       if (gFlag)
+       {
+               o << indent(ind++) << "{\n";
+               o << indent(ind++) << "static void *" << mapCodeName["yycond"] << "[" << specMap.size() << "] = {\n";
+       }
+       for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it)
+       {
+               if (gFlag)
+               {
+                       o << indent(ind) << "&&" << condPrefix << it->first << ",\n";
+               }
+               else
+               {
+                       o << indent(ind) << "if(" << mapCodeName["YYCOND"] << " == " << it->first << ")";
+                       o << " goto " << condPrefix << it->first << ";\n";
+               }
+       }
+       if (gFlag)
+       {
+               o << indent(--ind) << "};\n";
+               o << indent(ind) << "goto *" << mapCodeName["yycond"] << "[" << mapCodeName["YYCOND"] << "];\n";
+               o << indent(--ind) << "}\n";
+       }
+}
+
 std::ostream& operator << (std::ostream& o, const file_info& li)
 {
        if (li.ln && !iFlag)
@@ -1770,6 +1797,10 @@ void Scanner::config(const Str& cfg, const Str& val)
        {
                labelPrefix = strVal;
        }
+       else if (cfg.to_string() == "condprefix")
+       {
+               condPrefix = strVal;
+       }
        else if (cfg.to_string() == "yych:conversion")
        {
                yychConversion = mapCodeName["YYCTYPE"];
index 12d7bc9fb4d9e9c04e5129755303b8f70faa32ca..cab8540abff482f373e1383f12a8d7f2a8125cc4 100644 (file)
@@ -39,6 +39,7 @@ extern bool bUsedYYMarker;
 extern bool bUseStartLabel;
 extern std::string startLabelName;
 extern std::string labelPrefix;
+extern std::string condPrefix;
 extern std::string yychConversion;
 extern uint maxFill;
 extern uint next_label;
index ec1bdb50d6f0eeba2f6bf45c0c6782fdcaae1387..98bd3c9f2ef241ee07e8671eb78bf35129f5abbf 100644 (file)
@@ -49,6 +49,7 @@ bool bUseYYFillParam = true;
 
 std::string startLabelName;
 std::string labelPrefix("yy");
+std::string condPrefix("yyc_");
 std::string yychConversion("");
 uint maxFill = 1;
 uint next_label = 0;
index 5f2b80f61615cfe02600220e33c2e8bbd6ccfbe7..210fa6766b0c59e7d79f57cbaf332c4e846c3498 100644 (file)
@@ -5,8 +5,6 @@
 #include "scanner.h"
 #include "re.h"
 #include <iosfwd>
-#include <map>
-#include <set>
 
 namespace re2c
 {
@@ -55,9 +53,6 @@ private:
 #endif
 };
 
-typedef std::set<std::string>           CondList;
-typedef std::map<std::string, RegExp*>  RegExpMap;
-
 void parse(Scanner&, std::ostream&);
 
 } // end namespace re2c
index 3fba68ea9bfd364a881b050336bf1233b24bb57d..6b09a0de150f19e7335aa5be5fde3e7aa6bb3158 100644 (file)
@@ -27,8 +27,9 @@ void yyerror(const char*);
 }
 
 static re2c::uint       accept;
-static re2c::RegExpMap  specmap;
-static RegExp           *spec;
+static re2c::RegExpMap  specMap;
+static RegExp           *spec, *specNone = NULL;
+static RuleOpList       specStar;
 static Scanner          *in = NULL;
 
 /* Bison version 1.875 emits a definition that is not working
@@ -70,7 +71,7 @@ static char* strdup(const char* s)
        re2c::CondList  *clist;
 };
 
-%token         CLOSESIZE       CLOSE   STAR    ID      CODE    RANGE   STRING
+%token         CLOSESIZE       CLOSE   STAR    NOCOND  ID      CODE    RANGE   STRING
 %token         CONFIG  VALUE   NUMBER
 
 %type  <op>            CLOSE   STAR
@@ -144,13 +145,13 @@ rule:
                                // Duplicating stuff, slow but safe
                                $$ = new RuleOp($4, $5, new Token(*$6), accept++);
                                
-                               RegExpMap::iterator itRE = specmap.find(*it);
+                               RegExpMap::iterator itRE = specMap.find(*it);
                                
-                               if (itRE != specmap.end())
+                               if (itRE != specMap.end())
                                {
                                        $$ = mkAlt(itRE->second, $$);
                                }
-                               specmap[*it] = $$;
+                               specMap[*it] = $$;
                        }
                        delete $2;
                        delete $6;
@@ -164,6 +165,34 @@ rule:
                        }
                        in->fatal("no expression specified");
                }
+       |       '<' STAR '>' expr look CODE
+               {
+                       if (!cFlag)
+                       {
+                               in->fatal("conditions are only allowed when using -c switch");
+                       }
+                       specStar.push_back(new RuleOp($4, $5, $6, accept++));
+               }
+       |       '<' STAR '>' look CODE
+               {
+                       if (!cFlag)
+                       {
+                               in->fatal("conditions are only allowed when using -c switch");
+                       }
+                       in->fatal("no expression specified");
+               }
+       |       NOCOND CODE
+               {
+                       if (!cFlag)
+                       {
+                               in->fatal("conditions are only allowed when using -c switch");
+                       }
+                       if (specNone)
+                       {
+                               in->fatal("code to handle illegal condition already defined");
+                       }
+                       $$ = specNone = new RuleOp(new NullOp(), new NullOp(), $2, accept++);
+               }
 ;
 
 cond:
@@ -171,11 +200,6 @@ cond:
                {
                        in->fatal("unnamed condition not supported");
                }
-       |       STAR
-               {
-                       $$ = new CondList();
-                       $$->insert("*");
-               }
        |       clist
                {
                        $$ = $1;
@@ -346,15 +370,44 @@ void parse(Scanner& i, std::ostream& o)
                yyparse();
                if (cFlag)
                {
-                       for(RegExpMap::const_iterator it = specmap.begin(); it != specmap.end(); ++it)
+                       RegExpMap::iterator it;
+
+                       if (!specStar.empty())
                        {
-                               if (it->second)
+                               for(it = specMap.begin(); it != specMap.end(); ++it)
+                               {
+                                       assert(it->second);
+                                       for(RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp)
+                                       {
+                                               it->second = mkAlt((*itOp)->copy(accept++), it->second);
+                                       }
+                               }
+                               if (!specNone)
                                {
-                                       o << "yyc_" << it->first << ":\n";
-                                       spec = it->second;
-                                       genCode(o, topIndent, spec);
+                                       RuleOpList::const_iterator itOp = specStar.begin();
+
+                                       specNone = (*itOp)->copy(accept++);
+                                       while(++itOp != specStar.end())
+                                       {
+                                               specNone = mkAlt((*itOp)->copy(accept++), specNone);
+                                       }
                                }
                        }
+
+                       genCondCheck(o, topIndent, specMap);
+
+                       if (specNone)
+                       {
+                               genCode(o, topIndent, specNone);
+                       }
+
+                       for(it = specMap.begin(); it != specMap.end(); ++it)
+                       {
+                               assert(it->second);
+                               o << condPrefix << it->first << ":\n";
+                               spec = it->second;
+                               genCode(o, topIndent, spec);
+                       }
                }
                else if(spec)
                {
@@ -366,7 +419,9 @@ void parse(Scanner& i, std::ostream& o)
        RegExp::vFreeList.clear();
        Range::vFreeList.clear();
        Symbol::ClearTable();
-       specmap.clear();
+       specMap.clear();
+       specStar.clear();
+       specNone = NULL;
        in = NULL;
 }
 
index 7b48570d51a5ec0a842ab3fc2a978dca0e392560..59b427e6ef60e8f904ba4a03cf5891b6887d6bc9 100644 (file)
--- a/re2c/re.h
+++ b/re2c/re.h
@@ -4,6 +4,8 @@
 
 #include <iostream>
 #include <set>
+#include <map>
+#include <list>
 #include "token.h"
 #include "ins.h"
 #include "globals.h"
@@ -260,6 +262,7 @@ public:
        {
                o << exp << "/" << ctx << ";";
        }
+       RuleOp* copy(uint) const;
 
 #ifdef PEDANTIC
 private:
@@ -483,9 +486,15 @@ private:
 #endif
 };
 
+typedef std::set<std::string>           CondList;
+typedef std::map<std::string, RegExp*>  RegExpMap;
+typedef std::list<RuleOp*>              RuleOpList;
+
 extern void genCode(std::ostream&, RegExp*);
 extern void genCode(std::ostream&, uint, RegExp*);
 extern void genGetState(std::ostream&, uint&, uint);
+extern void genCondCheck(std::ostream &o, uint& ind, const RegExpMap& specmap);
+
 extern RegExp *mkDiff(RegExp*, RegExp*);
 extern RegExp *mkAlt(RegExp*, RegExp*);
 
index 8de61e76f9c7cc00fa774c2e42468a82e2570893..cb43e8dc5fe1297b7e6041a7cd6766e8c67c2091 100644 (file)
@@ -17,7 +17,7 @@ class Scanner:
 private:
        std::istream&   in;
        std::ostream&   out;
-       char    *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
+       char    *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof, *ctx;
        uint    tchar, tline, cline, iscfg;
 
 private:
index aebab1a387667b290589a76475fd5a16c2ec8281..38843f3c3ca60eb0c3fbac8144c89c80347624c0 100644 (file)
@@ -21,6 +21,7 @@ extern YYSTYPE yylval;
 #define        YYCURSOR        cursor
 #define        YYLIMIT         lim
 #define        YYMARKER        ptr
+#define YYCTXMARKER ctx
 #define        YYFILL(n)       {cursor = fill(cursor);}
 
 #define        RETURN(i)       {cur = cursor; return i;}
@@ -32,7 +33,7 @@ Scanner::Scanner(std::istream& i, std::ostream& o)
        : in(i)
        , out(o)
        , bot(NULL), tok(NULL), ptr(NULL), cur(NULL), pos(NULL), lim(NULL)
-       , top(NULL), eof(NULL), tchar(0), tline(0), cline(1), iscfg(0)
+       , top(NULL), eof(NULL), ctx(NULL), tchar(0), tline(0), cline(1), iscfg(0)
 {
        ;
 }
@@ -90,6 +91,7 @@ number  = "0" | ("-"? [1-9] digit*);
 name    = (letter|"_") (letter|digit|"_")*;
 cname   = ":" name;
 space   = [ \t];
+ws      = (space | [\r\n]);
 eol     = ("\r\n" | "\n");
 config  = "re2c" cname+;
 value   = [^\r\n; \t]* | dstring | sstring;
@@ -274,6 +276,9 @@ scan:
                                        fatal("unterminated range (missing ])");
                                }
 
+       "<>" / (ws* "{") {
+                                       RETURN(NOCOND);
+                               }
        [<>,()|=;/\\]   {
                                        RETURN(*tok);
                                }
index 352a7f37acaa6cceb00e072bb8aab126d3555fce..33e9fff424ab493ca4001fd755569b65038e121d 100755 (executable)
@@ -1,5 +1,5 @@
 /*!re2c
 
-<,>    { }
+<,>    "a" { }
 
 */