]> granicus.if.org Git - re2c/commitdiff
- Allow full replacement of YYGETSTATE/YYSETSTAE by inplace-configuration
authorhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Mon, 30 Apr 2007 17:59:07 +0000 (17:59 +0000)
committerhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Mon, 30 Apr 2007 17:59:07 +0000 (17:59 +0000)
- Add ability to specify new condition via '=> condition' prior to code block
- Fix order of states in -cs
- Add support for -cf
- Add new tests

21 files changed:
re2c/bootstrap/parser.cc
re2c/code.cc
re2c/globals.h
re2c/main.cc
re2c/parser.y
re2c/test/condition_05.cg.c
re2c/test/condition_05.cgitcondition_05.cgit.h.c
re2c/test/condition_05.cgtcondition_05.cgt.h.c
re2c/test/condition_05.cs.c
re2c/test/condition_06.cs.c
re2c/test/condition_07.cbi.c
re2c/test/condition_08.cbi.c [new file with mode: 0755]
re2c/test/condition_08.cbi.re [new file with mode: 0755]
re2c/test/condition_08.cbif.c [new file with mode: 0755]
re2c/test/condition_08.cbif.re [new file with mode: 0755]
re2c/test/condition_09.cbif.c [new file with mode: 0755]
re2c/test/condition_09.cbif.re [new file with mode: 0755]
re2c/test/condition_09.cgif.c [new file with mode: 0755]
re2c/test/condition_09.cgif.re [new file with mode: 0755]
re2c/test/config10.re
re2c/token.h

index 7b90c02d46c35d8c416edbc56d68e11126c7bd20..e14e31a7b6f6a6373dd163d63e2be9dc31d0d78e 100644 (file)
@@ -341,16 +341,16 @@ union yyalloc
 /* YYFINAL -- State number of the termination state. */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   63
+#define YYLAST   69
 
 /* YYNTOKENS -- Number of terminals. */
 #define YYNTOKENS  24
 /* YYNNTS -- Number of nonterminals. */
-#define YYNNTS  13
+#define YYNNTS  14
 /* YYNRULES -- Number of rules. */
-#define YYNRULES  37
+#define YYNRULES  39
 /* YYNRULES -- Number of states. */
-#define YYNSTATES  63
+#define YYNSTATES  68
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -397,36 +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,    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
+      34,    42,    48,    56,    62,    65,    66,    68,    70,    74,
+      75,    79,    80,    83,    85,    89,    91,    95,    97,   100,
+     102,   105,   108,   110,   112,   115,   118,   120,   122,   124
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
 static const yysigned_char yyrhs[] =
 {
       25,     0,    -1,    -1,    25,    27,    -1,    25,    26,    -1,
-       7,    14,    31,    15,    -1,     7,    14,    31,    16,    -1,
+       7,    14,    32,    15,    -1,     7,    14,    32,    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
+      32,    31,     8,    -1,    17,    28,    18,    32,    31,    30,
+       8,    -1,    17,    28,    18,    31,     8,    -1,    17,     5,
+      18,    32,    31,    30,     8,    -1,    17,     5,    18,    31,
+       8,    -1,     6,     8,    -1,    -1,    29,    -1,     7,    -1,
+      29,    19,     7,    -1,    -1,    14,    18,     7,    -1,    -1,
+      16,    32,    -1,    33,    -1,    32,    20,    33,    -1,    34,
+      -1,    33,    21,    34,    -1,    35,    -1,    34,    35,    -1,
+      37,    -1,    37,    36,    -1,    37,     3,    -1,     4,    -1,
+       5,    -1,    36,     4,    -1,    36,     5,    -1,     7,    -1,
+       9,    -1,    10,    -1,    22,    32,    23,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const unsigned short int yyrline[] =
 {
        0,    92,    92,    96,    97,   101,   109,   113,   119,   127,
-     136,   164,   173,   181,   189,   205,   208,   215,   220,   229,
-     232,   239,   243,   250,   254,   265,   269,   276,   280,   295,
-     302,   306,   310,   314,   321,   329,   333,   337
+     136,   165,   174,   183,   191,   207,   210,   217,   222,   231,
+     234,   242,   245,   252,   256,   263,   267,   278,   282,   289,
+     293,   308,   315,   319,   323,   327,   334,   342,   346,   350
 };
 #endif
 
@@ -438,8 +438,8 @@ static const char *const yytname[] =
   "$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
+  "$accept", "spec", "decl", "rule", "cond", "clist", "newcond", "look",
+  "expr", "diff", "term", "factor", "close", "primary", 0
 };
 #endif
 
@@ -459,17 +459,17 @@ static const unsigned char yyr1[] =
 {
        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
+      30,    31,    31,    32,    32,    33,    33,    34,    34,    35,
+      35,    35,    36,    36,    36,    36,    37,    37,    37,    37
 };
 
 /* 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,     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
+       7,     5,     7,     5,     2,     0,     1,     1,     3,     0,
+       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
@@ -477,20 +477,20 @@ static const unsigned char yyr2[] =
    means the default is an error.  */
 static const unsigned char yydefact[] =
 {
-       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
+       2,     0,     1,     0,    36,    37,    38,     0,    15,     0,
+       4,     3,    21,    23,    25,    27,    29,    14,     0,     0,
+       0,    17,     0,    16,    36,     0,     0,     0,     0,     0,
+      28,    31,    32,    33,    30,     0,     0,     0,    21,    21,
+       0,    39,    22,    24,     9,    26,    34,    35,     5,     6,
+       7,     8,     0,    21,     0,    21,    18,    13,    19,    11,
+      19,     0,     0,     0,     0,    12,    10,    20
 };
 
 /* YYDEFGOTO[NTERM-NUM]. */
 static const yysigned_char yydefgoto[] =
 {
-      -1,     1,    10,    11,    22,    23,    28,    12,    13,    14,
-      15,    34,    16
+      -1,     1,    10,    11,    22,    23,    62,    28,    12,    13,
+      14,    15,    34,    16
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
@@ -503,15 +503,15 @@ static const yysigned_char yypact[] =
       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
+     -38,   -38,    48,   -11,    49,   -11,   -38,   -38,    44,   -38,
+      44,    42,    51,    53,    55,   -38,   -38,   -38
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yysigned_char yypgoto[] =
 {
-     -38,   -38,   -38,   -38,   -38,   -38,   -37,    -6,    33,    34,
-     -14,   -38,   -38
+     -38,   -38,   -38,   -38,   -38,   -38,     5,   -37,    -6,    36,
+      40,   -14,   -38,   -38
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
@@ -526,8 +526,8 @@ static const unsigned char yytable[] =
       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
+       9,    40,    50,    56,    51,    27,    57,    59,    61,    65,
+      64,    66,    67,    43,     0,    63,     0,     0,     0,    45
 };
 
 static const yysigned_char yycheck[] =
@@ -537,8 +537,8 @@ static const yysigned_char yycheck[] =
       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
+      22,    19,    15,     7,    15,    20,     8,     8,    14,     8,
+      18,     8,     7,    27,    -1,    60,    -1,    -1,    -1,    29
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -546,12 +546,12 @@ static const yysigned_char yycheck[] =
 static const unsigned char yystos[] =
 {
        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
+      26,    27,    32,    33,    34,    35,    37,     8,    14,    14,
+       5,     7,    28,    29,     7,    32,    16,    20,    31,    21,
+      35,     3,     4,     5,    36,    32,    12,    13,    18,    18,
+      19,    23,    32,    33,     8,    34,     4,     5,    15,    16,
+      15,    15,    31,    32,    31,    32,     7,     8,    31,     8,
+      31,    14,    30,    30,    18,     8,     8,     7
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1280,13 +1280,14 @@ yyreduce:
     {
                        if (!cFlag)
                        {
-                               delete (yyvsp[-4].clist);
+                               delete (yyvsp[-5].clist);
                                in->fatal("conditions are only allowed when using -c switch");
                        }
-                       for(CondList::const_iterator it = (yyvsp[-4].clist)->begin(); it != (yyvsp[-4].clist)->end(); ++it)
+                       (yyvsp[0].token)->newcond = (yyvsp[-1].str);
+                       for(CondList::const_iterator it = (yyvsp[-5].clist)->begin(); it != (yyvsp[-5].clist)->end(); ++it)
                        {
                                // Duplicating stuff, slow but safe
-                               (yyval.regexp) = new RuleOp((yyvsp[-2].regexp), (yyvsp[-1].regexp), new Token(*(yyvsp[0].token)), accept++);
+                               (yyval.regexp) = new RuleOp((yyvsp[-3].regexp), (yyvsp[-2].regexp), new Token(*(yyvsp[0].token)), accept++);
 
                                RegExpMap::iterator itRE = specMap.find(*it);
 
@@ -1301,13 +1302,13 @@ yyreduce:
                                }
                                
                        }
-                       delete (yyvsp[-4].clist);
+                       delete (yyvsp[-5].clist);
                        delete (yyvsp[0].token);
                }
     break;
 
   case 11:
-#line 165 "parser.y"
+#line 166 "parser.y"
     {
                        delete (yyvsp[-3].clist);
                        if (!cFlag)
@@ -1319,18 +1320,19 @@ yyreduce:
     break;
 
   case 12:
-#line 174 "parser.y"
+#line 175 "parser.y"
     {
                        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++));
+                       (yyvsp[0].token)->newcond = (yyvsp[-1].str);
+                       specStar.push_back(new RuleOp((yyvsp[-3].regexp), (yyvsp[-2].regexp), (yyvsp[0].token), accept++));
                }
     break;
 
   case 13:
-#line 182 "parser.y"
+#line 184 "parser.y"
     {
                        if (!cFlag)
                        {
@@ -1341,7 +1343,7 @@ yyreduce:
     break;
 
   case 14:
-#line 190 "parser.y"
+#line 192 "parser.y"
     {
                        if (!cFlag)
                        {
@@ -1356,21 +1358,21 @@ yyreduce:
     break;
 
   case 15:
-#line 205 "parser.y"
+#line 207 "parser.y"
     {
                        in->fatal("unnamed condition not supported");
                }
     break;
 
   case 16:
-#line 209 "parser.y"
+#line 211 "parser.y"
     {
                        (yyval.clist) = (yyvsp[0].clist);
                }
     break;
 
   case 17:
-#line 216 "parser.y"
+#line 218 "parser.y"
     {
                        (yyval.clist) = new CondList();
                        (yyval.clist)->insert((yyvsp[0].symbol)->GetName().to_string());
@@ -1378,7 +1380,7 @@ yyreduce:
     break;
 
   case 18:
-#line 221 "parser.y"
+#line 223 "parser.y"
     {
                        (yyvsp[-2].clist)->insert((yyvsp[0].symbol)->GetName().to_string());
                        (yyval.clist) = (yyvsp[-2].clist);
@@ -1386,42 +1388,56 @@ yyreduce:
     break;
 
   case 19:
-#line 229 "parser.y"
+#line 231 "parser.y"
     {
-                       (yyval.regexp) = new NullOp;
+                       (yyval.str) = NULL;
                }
     break;
 
   case 20:
-#line 233 "parser.y"
+#line 235 "parser.y"
     {
-                       (yyval.regexp) = (yyvsp[0].regexp);
+                       (yyval.str) = new Str((yyvsp[0].symbol)->GetName().to_string().c_str());
                }
     break;
 
   case 21:
-#line 240 "parser.y"
+#line 242 "parser.y"
     {
-                       (yyval.regexp) = (yyvsp[0].regexp);
+                       (yyval.regexp) = new NullOp;
                }
     break;
 
   case 22:
-#line 244 "parser.y"
+#line 246 "parser.y"
     {
-                       (yyval.regexp) = mkAlt((yyvsp[-2].regexp), (yyvsp[0].regexp));
+                       (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
   case 23:
-#line 251 "parser.y"
+#line 253 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
   case 24:
-#line 255 "parser.y"
+#line 257 "parser.y"
+    {
+                       (yyval.regexp) = mkAlt((yyvsp[-2].regexp), (yyvsp[0].regexp));
+               }
+    break;
+
+  case 25:
+#line 264 "parser.y"
+    {
+                       (yyval.regexp) = (yyvsp[0].regexp);
+               }
+    break;
+
+  case 26:
+#line 268 "parser.y"
     {
                        (yyval.regexp) = mkDiff((yyvsp[-2].regexp), (yyvsp[0].regexp));
                        if(!(yyval.regexp))
@@ -1431,29 +1447,29 @@ yyreduce:
                }
     break;
 
-  case 25:
-#line 266 "parser.y"
+  case 27:
+#line 279 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
-  case 26:
-#line 270 "parser.y"
+  case 28:
+#line 283 "parser.y"
     {
                        (yyval.regexp) = new CatOp((yyvsp[-1].regexp), (yyvsp[0].regexp));
                }
     break;
 
-  case 27:
-#line 277 "parser.y"
+  case 29:
+#line 290 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
-  case 28:
-#line 281 "parser.y"
+  case 30:
+#line 294 "parser.y"
     {
                        switch((yyvsp[0].op))
                        {
@@ -1470,43 +1486,43 @@ yyreduce:
                }
     break;
 
-  case 29:
-#line 296 "parser.y"
+  case 31:
+#line 309 "parser.y"
     {
                        (yyval.regexp) = new CloseVOp((yyvsp[-1].regexp), (yyvsp[0].extop).minsize, (yyvsp[0].extop).maxsize);
                }
     break;
 
-  case 30:
-#line 303 "parser.y"
+  case 32:
+#line 316 "parser.y"
     {
                        (yyval.op) = (yyvsp[0].op);
                }
     break;
 
-  case 31:
-#line 307 "parser.y"
+  case 33:
+#line 320 "parser.y"
     {
                        (yyval.op) = (yyvsp[0].op);
                }
     break;
 
-  case 32:
-#line 311 "parser.y"
+  case 34:
+#line 324 "parser.y"
     {
                        (yyval.op) = ((yyvsp[-1].op) == (yyvsp[0].op)) ? (yyvsp[-1].op) : '*';
                }
     break;
 
-  case 33:
-#line 315 "parser.y"
+  case 35:
+#line 328 "parser.y"
     {
                        (yyval.op) = ((yyvsp[-1].op) == (yyvsp[0].op)) ? (yyvsp[-1].op) : '*';
                }
     break;
 
-  case 34:
-#line 322 "parser.y"
+  case 36:
+#line 335 "parser.y"
     {
                        if(!(yyvsp[0].symbol)->re)
                        {
@@ -1516,22 +1532,22 @@ yyreduce:
                }
     break;
 
-  case 35:
-#line 330 "parser.y"
+  case 37:
+#line 343 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
-  case 36:
-#line 334 "parser.y"
+  case 38:
+#line 347 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[0].regexp);
                }
     break;
 
-  case 37:
-#line 338 "parser.y"
+  case 39:
+#line 351 "parser.y"
     {
                        (yyval.regexp) = (yyvsp[-1].regexp);
                }
@@ -1542,7 +1558,7 @@ yyreduce:
     }
 
 /* Line 1126 of yacc.c.  */
-#line 1546 "parser.cc"
+#line 1562 "parser.cc"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -1810,7 +1826,7 @@ yyreturn:
 }
 
 
-#line 343 "parser.y"
+#line 356 "parser.y"
 
 
 extern "C" {
index 4f1488ab31a20c52198d33cbe1a1aaac790623fe..fc43e13343b1f1509364634df1217c55688b9ffd 100644 (file)
@@ -313,25 +313,30 @@ void genIf(std::ostream &o, uint ind, const char *cmp, uint v, bool &readCh)
        o << ") ";
 }
 
+static std::string replaceParam(std::string str, const std::string& param, int value)
+{
+       std::string::size_type pos;
+       char tmp[16];
+
+       sprintf(tmp, "%d", value);
+
+       while((pos = str.find(param)) != std::string::npos)
+       {
+               str.replace(pos, param.length(), tmp);
+       }
+
+       return str;
+}
+
 static void genYyfill(std::ostream &o, uint ind, uint need)
 {
        if (bUseYYFillParam)
        {
-               o << mapCodeName["YYFILL"] << "(" << need << ")";
+               o << mapCodeName["YYFILL"] << "(" << need << ");\n";
        }
        else
        {
-               std::string yyfill(mapCodeName["YYFILL"]);
-               std::string::size_type pos;
-               char cnt[16];
-
-               sprintf(cnt, "%d", need);
-
-               while((pos = yyfill.find(yyfillLength)) != std::string::npos)
-               {
-                       yyfill.replace(pos, yyfillLength.length(), cnt);
-               }
-               o << yyfill;
+               o << replaceParam(mapCodeName["YYFILL"], yyFillLength, need) << "\n";
        }
 }
 
@@ -342,7 +347,14 @@ static void need(std::ostream &o, uint ind, uint n, bool & readCh, bool bSetMark
        if (fFlag)
        {
                next_fill_index++;
-               o << indent(ind) << mapCodeName["YYSETSTATE"] << "(" << fillIndex << ");\n";
+               if (bUseYYSetStateParam)
+               {
+                       o << indent(ind) << mapCodeName["YYSETSTATE"] << "(" << fillIndex << ");\n";
+               }
+               else
+               {
+                       o << indent(ind) << replaceParam(mapCodeName["YYSETSTATE"], yySetStateParam, fillIndex) << "\n";
+               }
        }
 
        if (bUseYYFill && n > 0)
@@ -357,7 +369,6 @@ static void need(std::ostream &o, uint ind, uint n, bool & readCh, bool bSetMark
                        o << indent(ind) << "if((" << mapCodeName["YYLIMIT"] << " - " << mapCodeName["YYCURSOR"] << ") < " << n << ") ";
                        genYyfill(o, ind, n);
                }
-               o << ";\n";
        }
 
        if (fFlag)
@@ -428,7 +439,7 @@ void Enter::emit(std::ostream &o, uint ind, bool &readCh) const
 
 void Initial::emit(std::ostream &o, uint ind, bool &readCh) const
 {
-       if (!startLabelName.empty())
+       if (!cFlag && !startLabelName.empty())
        {
                o << startLabelName << ":\n";
        }
@@ -445,7 +456,7 @@ void Initial::emit(std::ostream &o, uint ind, bool &readCh) const
                }
        }
 
-       if (vUsedLabels.count(label))
+       if (!cFlag && vUsedLabels.count(label))
        {
                o << labelPrefix << label << ":\n";
        }
@@ -616,6 +627,11 @@ void Rule::emit(std::ostream &o, uint ind, bool &) const
                o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYCTXMARKER"] << ";\n";
        }
 
+       if (rule->code->newcond)
+       {
+               o << indent(ind) << mapCodeName["YYCONDITION"] << " = " << condEnumPrefix << rule->code->newcond << ";\n";
+       }
+
        RuleLine rl(*rule);
 
        o << file_info(sourceFileInfo, &rl);
@@ -1589,7 +1605,10 @@ void DFA::emit(std::ostream &o, uint& ind, const RegExpMap* specMap, const std::
        
                if (!fFlag)
                {
-                       o << indent(ind) << mapCodeName["YYCTYPE"] << " " << mapCodeName["yych"] << ";\n";
+                       if (bEmitYYCh)
+                       {
+                               o << indent(ind) << mapCodeName["YYCTYPE"] << " " << mapCodeName["yych"] << ";\n";
+                       }
                        if (bUsedYYAccept)
                        {
                                o << indent(ind) << "unsigned int "<< mapCodeName["yyaccept"] << " = 0;\n";
@@ -1608,6 +1627,17 @@ void DFA::emit(std::ostream &o, uint& ind, const RegExpMap* specMap, const std::
        {
                genCondTable(o, ind, *specMap);
                genGetState(o, ind, start_label);
+               if (cFlag)
+               {
+                       if (vUsedLabels.count(start_label))
+                       {
+                               o << labelPrefix << start_label << ":\n";
+                       }
+                       if (!startLabelName.empty())
+                       {
+                               o << startLabelName << ":\n";
+                       }
+               }
                genCondGoto(o, ind, *specMap);
        }
 
@@ -1669,7 +1699,12 @@ void genGetState(std::ostream &o, uint& ind, uint start_label)
        if (fFlag && !bWroteGetState)
        {
                vUsedLabels.insert(start_label);
-               o << indent(ind) << "switch(" << mapCodeName["YYGETSTATE"] << "()) {\n";
+               o << indent(ind) << "switch(" << mapCodeName["YYGETSTATE"];
+               if (bUseYYGetStateFunc)
+               {
+                       o << "()";
+               }
+               o << ") {\n";
                if (bUseStateAbort)
                {
                        o << indent(ind) << "default: abort();\n";
@@ -1739,11 +1774,10 @@ void genCondGoto(std::ostream &o, uint ind, const RegExpMap& specMap)
                        if (sFlag)
                        {
                                RegExpIndices  vCondList(specMap.size());
-                               size_t nCnt = 0;
                        
                                for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it)
                                {
-                                       vCondList[nCnt++] = it->first;
+                                       vCondList[it->second.first] = it->first;
                                }
                                genCondGotoSub(o, ind, vCondList, 0, vCondList.size() - 1);
                        }
@@ -1857,6 +1891,14 @@ void Scanner::config(const Str& cfg, int num)
                        yychConversion  = "";
                }
        }
+       else if (cfg.to_string() == "yych:emit")
+       {
+               bEmitYYCh = num != 0;
+       }
+       else if (cfg.to_string() == "define:YYGETSTATE:func")
+       {
+               bUseYYGetStateFunc = num != 0;
+       }
        else
        {
                fatal("unrecognized configuration name or illegal integer value");
@@ -1927,7 +1969,13 @@ void Scanner::config(const Str& cfg, const Str& val)
        }
        else if (cfg.to_string() == "define:YYFILL:len")
        {
-               yyfillLength = strVal;
+               yyFillLength = strVal;
+               bUseYYFillParam = false;
+       }
+       else if (cfg.to_string() == "define:YYSETSTATE:state")
+       {
+               yySetStateParam = strVal;
+               bUseYYSetStateParam = false;
        }
        else if (mapVariableKeys.find(cfg.to_string()) != mapVariableKeys.end())
     {
index fea02d4b0595c720f809cfcaca1a141ec7a64c6c..809cdb63b9fffb478910802796746b57af1aa419 100644 (file)
@@ -43,7 +43,8 @@ extern std::string labelPrefix;
 extern std::string condPrefix;
 extern std::string condEnumPrefix;
 extern std::string yychConversion;
-extern std::string yyfillLength;
+extern std::string yyFillLength;
+extern std::string yySetStateParam;
 extern uint maxFill;
 extern uint next_label;
 extern uint cGotoThreshold;
@@ -52,10 +53,13 @@ extern uint cGotoThreshold;
 extern uint topIndent;
 extern std::string indString;
 extern bool yybmHexTable;
+extern bool bEmitYYCh;
 extern bool bUseStateAbort;
 extern bool bUseStateNext;
 extern bool bUseYYFill;
 extern bool bUseYYFillParam;
+extern bool bUseYYSetStateParam;
+extern bool bUseYYGetStateFunc;
 extern bool bWroteGetState;
 extern bool bWroteCondCheck;
 
index bced4c9d0a8a71fc99abc1a4c306aac51bae05d3..f8de35d02bc37f632fd190bae0725dc2c79fa00a 100644 (file)
@@ -43,17 +43,21 @@ bool bUsedYYAccept  = false;
 bool bUsedYYMaxFill = false;
 bool bUsedYYMarker  = true;
 
+bool bEmitYYCh       = true;
 bool bUseStartLabel  = false;
 bool bUseStateNext   = false;
 bool bUseYYFill      = true;
 bool bUseYYFillParam = true;
+bool bUseYYSetStateParam = true;
+bool bUseYYGetStateFunc  = true;
 
 std::string startLabelName;
 std::string labelPrefix("yy");
 std::string condPrefix("yyc_");
 std::string condEnumPrefix("yyc");
 std::string yychConversion("");
-std::string yyfillLength("@@");
+std::string yyFillLength("@@");
+std::string yySetStateParam("@@");
 uint maxFill = 1;
 uint next_label = 0;
 uint cGotoThreshold = 9;
index 2ea0175a0b4bddaff5524595a03b45cf20e08467..bc7cbd4ef554b0f9b5aed5e050c93055f3189f88 100644 (file)
@@ -81,7 +81,7 @@ static char* strdup(const char* s)
 %type  <token>         CODE
 %type  <regexp>        RANGE   STRING
 %type  <regexp>        rule    look    expr    diff    term    factor  primary
-%type  <str>           CONFIG  VALUE
+%type  <str>           CONFIG  VALUE   newcond
 %type  <clist>         cond    clist
 %type  <number>        NUMBER
 
@@ -133,17 +133,18 @@ rule:
                        $$ = new RuleOp($1, $2, $3, accept++);
                        spec = spec? mkAlt(spec, $$) : $$;
                }
-       |       '<' cond '>' expr look CODE
+       |       '<' cond '>' expr look newcond CODE
                {
                        if (!cFlag)
                        {
                                delete $2;
                                in->fatal("conditions are only allowed when using -c switch");
                        }
+                       $7->newcond = $6;
                        for(CondList::const_iterator it = $2->begin(); it != $2->end(); ++it)
                        {
                                // Duplicating stuff, slow but safe
-                               $$ = new RuleOp($4, $5, new Token(*$6), accept++);
+                               $$ = new RuleOp($4, $5, new Token(*$7), accept++);
 
                                RegExpMap::iterator itRE = specMap.find(*it);
 
@@ -159,7 +160,7 @@ rule:
                                
                        }
                        delete $2;
-                       delete $6;
+                       delete $7;
                }
        |       '<' cond '>' look CODE
                {
@@ -170,13 +171,14 @@ rule:
                        }
                        in->fatal("no expression specified");
                }
-       |       '<' STAR '>' expr look CODE
+       |       '<' STAR '>' expr look newcond CODE
                {
                        if (!cFlag)
                        {
                                in->fatal("conditions are only allowed when using -c switch");
                        }
-                       specStar.push_back(new RuleOp($4, $5, $6, accept++));
+                       $7->newcond = $6;
+                       specStar.push_back(new RuleOp($4, $5, $7, accept++));
                }
        |       '<' STAR '>' look CODE
                {
@@ -224,6 +226,17 @@ clist:
                }
 ;
 
+newcond:
+               /* empty */
+               {
+                       $$ = NULL;
+               }
+       |       '=' '>' ID
+               {
+                       $$ = new Str($3->GetName().to_string().c_str());
+               }
+;
+
 look:
                /* empty */
                {
index b32c5187ba4558b97b59c08d1e27261ca61f2c29..c276d5763d37d353b1bde14cc4bd4942fbe2cc94 100755 (executable)
@@ -66,7 +66,7 @@ char scan(Scanner *s)
 /* *********************************** */
 yyc_comment:
 
-                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                        yych = *s->cur;
                        if(yych != '*') goto yy4;
                        ++s->cur;
@@ -89,7 +89,7 @@ yy5:
 #line 90 "<stdout>"
 /* *********************************** */
 yyc_normal:
-                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                        yych = *s->cur;
                        if(yych != '/') goto yy11;
                        ++s->cur;
index de63c6e35e489451a19692cf9267776a162abd03..41b51fe4cc9f4e61193bc6cff8b4c055802e4a38 100755 (executable)
@@ -64,7 +64,7 @@ char scan(Scanner *s)
 /* *********************************** */
 yyc_comment:
 
-                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                        yych = *s->cur;
                        if(yych != '*') goto yy4;
                        ++s->cur;
@@ -83,7 +83,7 @@ yy5:
                        }
 /* *********************************** */
 yyc_normal:
-                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                        yych = *s->cur;
                        if(yych != '/') goto yy11;
                        ++s->cur;
index cd13ece07662fac8831038eabf37d93766b6a35a..aa5a92a29131006af3fb19abe111b45db4cee0fe 100755 (executable)
@@ -66,7 +66,7 @@ char scan(Scanner *s)
 /* *********************************** */
 yyc_comment:
 
-                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                        yych = *s->cur;
                        if(yych != '*') goto yy4;
                        ++s->cur;
@@ -89,7 +89,7 @@ yy5:
 #line 90 "<stdout>"
 /* *********************************** */
 yyc_normal:
-                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                        yych = *s->cur;
                        if(yych != '/') goto yy11;
                        ++s->cur;
index 930b4129f1851be7b452dcb5f5955dec65342a3d..cf142102520a39728aa8833b869019bc8f50c1da 100755 (executable)
@@ -59,14 +59,14 @@ char scan(Scanner *s)
                {
                        unsigned char yych;
                        if (state < 1) {
-                               goto yyc_comment;
-                       } else {
                                goto yyc_normal;
+                       } else {
+                               goto yyc_comment;
                        }
 /* *********************************** */
 yyc_comment:
 
-                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                        yych = *s->cur;
                        if(yych != '*') goto yy4;
                        ++s->cur;
@@ -89,7 +89,7 @@ yy5:
 #line 90 "<stdout>"
 /* *********************************** */
 yyc_normal:
-                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                        yych = *s->cur;
                        if(yych != '/') goto yy11;
                        ++s->cur;
index 9eef88dab33f3f3d95ddd4836fd4b1870bb57a66..c4b2ba09f3c20a84d4cc95cb20cba1f3b7ba937a 100755 (executable)
@@ -79,9 +79,9 @@ void scan(Scanner *s)
                        unsigned char yych;
                        if (state < 2) {
                                if (state < 1) {
-                                       goto yyc_Comment;
-                               } else {
                                        goto yyc_Normal;
+                               } else {
+                                       goto yyc_Comment;
                                }
                        } else {
                                if (state < 3) {
@@ -93,7 +93,7 @@ void scan(Scanner *s)
 /* *********************************** */
 yyc_Comment:
 
-                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                        yych = *s->cur;
                        if(yych != '*') goto yy4;
                        ++s->cur;
@@ -116,7 +116,7 @@ yy5:
 #line 117 "<stdout>"
 /* *********************************** */
 yyc_Normal:
-                       if((s->lim - s->cur) < 3) { if(fill(s, 3) >= 0) break; };
+                       if((s->lim - s->cur) < 3) { if(fill(s, 3) >= 0) break; }
                        yych = *s->cur;
                        if(yych <= '.') {
                                if(yych == '"') goto yy12;
@@ -256,7 +256,7 @@ yy37:
 #line 257 "<stdout>"
 /* *********************************** */
 yyc_Skiptoeol:
-                       if((s->lim - s->cur) < 5) { if(fill(s, 5) >= 0) break; };
+                       if((s->lim - s->cur) < 5) { if(fill(s, 5) >= 0) break; }
                        yych = *s->cur;
                        if(yych <= '>') {
                                if(yych == 0x0A) goto yy44;
@@ -320,7 +320,7 @@ yy54:
 #line 321 "<stdout>"
 /* *********************************** */
 yyc_String:
-                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                       if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                        yych = *s->cur;
                        if(yych == '"') goto yy60;
                        if(yych != '\\') goto yy62;
index 90b404f2fbdbb87454fbcbcf86ec0c3125088d58..5d8096bb66391f985efd75783ab19eec67558b0f 100755 (executable)
@@ -114,7 +114,7 @@ yyc_R1:
                                          0,   0,   0,   0,   0,   0,   0,   0, 
                                };
 
-                               if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                               if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                                yych = *s->cur;
                                if(yych <= '@') {
                                        if(yych <= '/') goto yy4;
@@ -139,7 +139,7 @@ yy4:
                                }
 yy6:
                                ++s->cur;
-                               if(s->lim == s->cur) { if(fill(s, 1) >= 0) break; };
+                               if(s->lim == s->cur) { if(fill(s, 1) >= 0) break; }
                                yych = *s->cur;
 yy7:
                                if(yybm[0+yych] & 128) {
@@ -184,7 +184,7 @@ yyc_R2:
                                          0,   0,   0,   0,   0,   0,   0,   0, 
                                          0,   0,   0,   0,   0,   0,   0,   0, 
                                };
-                               if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; };
+                               if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }
                                yych = *s->cur;
                                if(yych <= '@') {
                                        if(yych <= '/') goto yy12;
@@ -209,7 +209,7 @@ yy12:
                                }
 yy14:
                                ++s->cur;
-                               if(s->lim == s->cur) { if(fill(s, 1) >= 0) break; };
+                               if(s->lim == s->cur) { if(fill(s, 1) >= 0) break; }
                                yych = *s->cur;
 yy15:
                                if(yybm[0+yych] & 128) {
diff --git a/re2c/test/condition_08.cbi.c b/re2c/test/condition_08.cbi.c
new file mode 100755 (executable)
index 0000000..e2ab76a
--- /dev/null
@@ -0,0 +1,372 @@
+/* Generated by re2c */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define        BSIZE   8192
+
+
+enum ScanContition {
+       EStateComment,
+       EStateNormal,
+       EStateSkiptoeol,
+       EStateString,
+};
+
+
+typedef struct Scanner
+{
+       FILE                        *fp;
+       unsigned char       *cur, *tok, *lim, *eof;
+       unsigned char       buffer[BSIZE];
+       unsigned char       yych;
+       enum ScanContition  cond;
+       int                 state;
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+       if (!len)
+       {
+               s->cur = s->tok = s->lim = s->buffer;
+               s->eof = 0;
+       }
+       if (!s->eof)
+       {
+               int got, cnt = s->tok - s->buffer;
+
+               if (cnt > 0)
+               {
+                       memcpy(s->buffer, s->tok, s->lim - s->tok);
+                       s->tok -= cnt;
+                       s->cur -= cnt;
+                       s->lim -= cnt;
+               }
+               cnt = BSIZE - cnt;
+               if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+               {
+                       s->eof = &s->lim[got];
+               }
+               s->lim += got;
+       }
+       else if (s->cur + len > s->eof)
+       {
+               return 0; /* not enough input data */
+       }
+       return -1;
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+       while(len-- > 0)
+       {
+               fputc(*s++, stream);
+       }
+}
+
+void scan(Scanner *s)
+{
+       fill(s, 0);
+
+       for(;;)
+       {
+               s->tok = s->cur;
+
+               {
+                       if (s->cond < 2) {
+                               if (s->cond < 1) {
+                                       goto yyc_Normal;
+                               } else {
+                                       goto yyc_Comment;
+                               }
+                       } else {
+                               if (s->cond < 3) {
+                                       goto yyc_Skiptoeol;
+                               } else {
+                                       goto yyc_String;
+                               }
+                       }
+/* *********************************** */
+yyc_Comment:
+
+                       if((s->lim - s->cur) < 2) if(fill(s, 2) >= 0) break;
+                       s->yych = *s->cur;
+                       if(s->yych != '*') goto yy4;
+                       ++s->cur;
+                       if((s->yych = *s->cur) == '/') goto yy5;
+yy3:
+                       {
+                               goto yyc_Comment;
+                       }
+yy4:
+                       s->yych = *++s->cur;
+                       goto yy3;
+yy5:
+                       ++s->cur;
+                       {
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+/* *********************************** */
+yyc_Normal:
+                       if((s->lim - s->cur) < 4) if(fill(s, 4) >= 0) break;
+                       s->yych = *s->cur;
+                       if(s->yych <= '\'') {
+                               if(s->yych == '"') goto yy13;
+                               if(s->yych <= '&') goto yy15;
+                               goto yy12;
+                       } else {
+                               if(s->yych <= '/') {
+                                       if(s->yych <= '.') goto yy15;
+                                       goto yy11;
+                               } else {
+                                       if(s->yych != '?') goto yy15;
+                               }
+                       }
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '?') goto yy26;
+yy10:
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy11:
+                       s->yych = *++s->cur;
+                       if(s->yych == '*') goto yy24;
+                       if(s->yych == '/') goto yy22;
+                       goto yy10;
+yy12:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '"') goto yy16;
+                       if(s->yych == '\\') goto yy18;
+                       goto yy10;
+yy13:
+                       ++s->cur;
+                       {
+                               fputc(*s->tok, stdout);
+                               s->state = EStateString;
+                               continue;
+                       }
+yy15:
+                       s->yych = *++s->cur;
+                       goto yy10;
+yy16:
+                       s->yych = *++s->cur;
+                       if(s->yych == '\'') goto yy20;
+yy17:
+                       s->cur = s->tok;
+                       goto yy10;
+yy18:
+                       s->yych = *++s->cur;
+                       if(s->yych != '"') goto yy17;
+                       s->yych = *++s->cur;
+                       if(s->yych != '\'') goto yy17;
+yy20:
+                       ++s->cur;
+                       {
+                               fputl("'\"'", 3, stdout);
+                               continue;
+                       }
+yy22:
+                       ++s->cur;
+                       {
+                               s->cond = EStateSkiptoeol;
+                               goto yyc_Skiptoeol;
+                       }
+yy24:
+                       ++s->cur;
+                       {
+                               s->cond = EStateComment;
+                               goto yyc_Comment;
+                       }
+yy26:
+                       s->yych = *++s->cur;
+                       switch(s->yych) {
+                       case '!':       goto yy41;
+                       case '\'':      goto yy39;
+                       case '(':       goto yy27;
+                       case ')':       goto yy29;
+                       case '-':       goto yy43;
+                       case '/':       goto yy37;
+                       case '<':       goto yy31;
+                       case '=':       goto yy35;
+                       case '>':       goto yy33;
+                       default:        goto yy17;
+                       }
+yy27:
+                       ++s->cur;
+                       {
+                               fputc('[', stdout);
+                               continue;
+                       }
+yy29:
+                       ++s->cur;
+                       {
+                               fputc(']', stdout);
+                               continue;
+                       }
+yy31:
+                       ++s->cur;
+                       {
+                               fputc('{', stdout);
+                               continue;
+                       }
+yy33:
+                       ++s->cur;
+                       {
+                               fputc('}', stdout);
+                               continue;
+                       }
+yy35:
+                       ++s->cur;
+                       {
+                               fputc('#', stdout);
+                               continue;
+                       }
+yy37:
+                       ++s->cur;
+                       {
+                               fputc('\\', stdout);
+                               continue;
+                       }
+yy39:
+                       ++s->cur;
+                       {
+                               fputc('^', stdout);
+                               continue;
+                       }
+yy41:
+                       ++s->cur;
+                       {
+                               fputc('|', stdout);
+                               continue;
+                       }
+yy43:
+                       ++s->cur;
+                       {
+                               fputc('~', stdout);
+                               continue;
+                       }
+/* *********************************** */
+yyc_Skiptoeol:
+                       if((s->lim - s->cur) < 5) if(fill(s, 5) >= 0) break;
+                       s->yych = *s->cur;
+                       if(s->yych <= '>') {
+                               if(s->yych == 0x0A) goto yy50;
+                               goto yy52;
+                       } else {
+                               if(s->yych <= '?') goto yy47;
+                               if(s->yych == '\\') goto yy49;
+                               goto yy52;
+                       }
+yy47:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '?') goto yy57;
+yy48:
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+yy49:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == 0x0A) goto yy55;
+                       if(s->yych == 0x0D) goto yy53;
+                       goto yy48;
+yy50:
+                       ++s->cur;
+                       {
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+yy52:
+                       s->yych = *++s->cur;
+                       goto yy48;
+yy53:
+                       s->yych = *++s->cur;
+                       if(s->yych == 0x0A) goto yy55;
+yy54:
+                       s->cur = s->tok;
+                       goto yy48;
+yy55:
+                       ++s->cur;
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+yy57:
+                       s->yych = *++s->cur;
+                       if(s->yych != '/') goto yy54;
+                       s->yych = *++s->cur;
+                       if(s->yych == 0x0A) goto yy60;
+                       if(s->yych != 0x0D) goto yy54;
+                       s->yych = *++s->cur;
+                       if(s->yych != 0x0A) goto yy54;
+yy60:
+                       ++s->cur;
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+/* *********************************** */
+yyc_String:
+                       if((s->lim - s->cur) < 2) if(fill(s, 2) >= 0) break;
+                       s->yych = *s->cur;
+                       if(s->yych == '"') goto yy66;
+                       if(s->yych != '\\') goto yy68;
+                       ++s->cur;
+                       if((s->yych = *s->cur) != 0x0A) goto yy69;
+yy65:
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy66:
+                       ++s->cur;
+                       {
+                               fputc(*s->tok, stdout);
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+yy68:
+                       s->yych = *++s->cur;
+                       goto yy65;
+yy69:
+                       ++s->cur;
+                       {
+                               fputl((const char*)s->tok, 2, stdout);
+                               continue;
+                       }
+               }
+
+       }
+}
+
+int main(int argc, char **argv)
+{
+       Scanner in;
+       char c;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "%s <file>\n", argv[0]);
+               return 1;;
+       }
+
+       memset((char*) &in, 0, sizeof(in));
+
+       if (!strcmp(argv[1], "-"))
+       {
+               in.fp = stdin;
+       }
+       else if ((in.fp = fopen(argv[1], "r")) == NULL)
+       {
+               fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+               return 1;
+       }
+
+       in.cond = EStateNormal;
+       scan(&in);
+
+       if (in.fp != stdin)
+       {
+               fclose(in.fp);
+       }
+       return 0;
+}
diff --git a/re2c/test/condition_08.cbi.re b/re2c/test/condition_08.cbi.re
new file mode 100755 (executable)
index 0000000..148d9c6
--- /dev/null
@@ -0,0 +1,233 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define        BSIZE   8192
+
+/*!types:re2c */
+
+typedef struct Scanner
+{
+       FILE                        *fp;
+       unsigned char       *cur, *tok, *lim, *eof;
+       unsigned char       buffer[BSIZE];
+       unsigned char       yych;
+       enum ScanContition  cond;
+       int                 state;
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+       if (!len)
+       {
+               s->cur = s->tok = s->lim = s->buffer;
+               s->eof = 0;
+       }
+       if (!s->eof)
+       {
+               int got, cnt = s->tok - s->buffer;
+
+               if (cnt > 0)
+               {
+                       memcpy(s->buffer, s->tok, s->lim - s->tok);
+                       s->tok -= cnt;
+                       s->cur -= cnt;
+                       s->lim -= cnt;
+               }
+               cnt = BSIZE - cnt;
+               if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+               {
+                       s->eof = &s->lim[got];
+               }
+               s->lim += got;
+       }
+       else if (s->cur + len > s->eof)
+       {
+               return 0; /* not enough input data */
+       }
+       return -1;
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+       while(len-- > 0)
+       {
+               fputc(*s++, stream);
+       }
+}
+
+void scan(Scanner *s)
+{
+       fill(s, 0);
+
+       for(;;)
+       {
+               s->tok = s->cur;
+/*!re2c
+
+re2c:define:YYCTYPE          = "unsigned char";
+re2c:define:YYCURSOR         = s->cur;
+re2c:define:YYLIMIT          = s->lim;
+re2c:define:YYMARKER         = s->tok;
+re2c:define:YYFILL:len       = #;
+re2c:define:YYFILL           = "if(fill(s, #) >= 0) break;";
+re2c:define:YYSETSTATE:state = #;
+re2c:define:YYSETSTATE       = "s->state = #;";
+re2c:define:YYGETSTATE       = "s->state";
+re2c:define:YYGETSTATE:func  = 0;
+re2c:define:YYCONDITION      = s->cond;
+re2c:define:YYCONDTYPE       = ScanContition;
+re2c:variable:yych           = s->yych;
+re2c:yych:emit               = 0;
+re2c:indent:top              = 2;
+re2c:condenumprefix          = EState;
+
+<Normal>       "??("
+                       {
+                               fputc('[', stdout);
+                               continue;
+                       }
+<Normal>       "??)"
+                       {
+                               fputc(']', stdout);
+                               continue;
+                       }
+<Normal>       "??<"
+                       {
+                               fputc('{', stdout);
+                               continue;
+                       }
+<Normal>       "??>"
+                       {
+                               fputc('}', stdout);
+                               continue;
+                       }
+<Normal>       "??="
+                       {
+                               fputc('#', stdout);
+                               continue;
+                       }
+<Normal>       "??/"
+                       {
+                               fputc('\\', stdout);
+                               continue;
+                       }
+<Normal>       "??'"
+                       {
+                               fputc('^', stdout);
+                               continue;
+                       }
+<Normal>       "??!"
+                       {
+                               fputc('|', stdout);
+                               continue;
+                       }
+<Normal>       "??-"
+                       {
+                               fputc('~', stdout);
+                               continue;
+                       }
+<Normal>       "/*"
+                       {
+                               s->cond = EStateComment;
+                               goto yyc_Comment;
+                       }
+<Normal>       "//"
+                       {
+                               s->cond = EStateSkiptoeol;
+                               goto yyc_Skiptoeol;
+                       }
+<Normal>       "'\\\"'"|"'\"'"
+                       {
+                               fputl("'\"'", 3, stdout);
+                               continue;
+                       }
+<Normal>       '"'
+                       {
+                               fputc(*s->tok, stdout);
+                               s->state = EStateString;
+                               continue;
+                       }
+<Normal>       [^]
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+<Comment>      "*" "/"
+                       {
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+<Comment>      [^]
+                       {
+                               goto yyc_Comment;
+                       }
+<Skiptoeol>    "??/" "\r"? "\n"
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<Skiptoeol>    "\\" "\r"? "\n"
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<Skiptoeol>    "\n"
+                       {
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+<Skiptoeol> [^]
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<String>       '\\' .
+                       {
+                               fputl((const char*)s->tok, 2, stdout);
+                               continue;
+                       }
+<String>       '"'
+                       {
+                               fputc(*s->tok, stdout);
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+<String>       [^]
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+*/
+       }
+}
+
+int main(int argc, char **argv)
+{
+       Scanner in;
+       char c;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "%s <file>\n", argv[0]);
+               return 1;;
+       }
+
+       memset((char*) &in, 0, sizeof(in));
+
+       if (!strcmp(argv[1], "-"))
+       {
+               in.fp = stdin;
+       }
+       else if ((in.fp = fopen(argv[1], "r")) == NULL)
+       {
+               fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+               return 1;
+       }
+
+       in.cond = EStateNormal;
+       scan(&in);
+
+       if (in.fp != stdin)
+       {
+               fclose(in.fp);
+       }
+       return 0;
+}
diff --git a/re2c/test/condition_08.cbif.c b/re2c/test/condition_08.cbif.c
new file mode 100755 (executable)
index 0000000..c546c45
--- /dev/null
@@ -0,0 +1,389 @@
+/* Generated by re2c */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define        BSIZE   8192
+
+
+enum ScanContition {
+       EStateComment,
+       EStateNormal,
+       EStateSkiptoeol,
+       EStateString,
+};
+
+
+typedef struct Scanner
+{
+       FILE                        *fp;
+       unsigned char       *cur, *tok, *lim, *eof;
+       unsigned char       buffer[BSIZE];
+       unsigned char       yych;
+       enum ScanContition  cond;
+       int                 state;
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+       if (!len)
+       {
+               s->cur = s->tok = s->lim = s->buffer;
+               s->eof = 0;
+       }
+       if (!s->eof)
+       {
+               int got, cnt = s->tok - s->buffer;
+
+               if (cnt > 0)
+               {
+                       memcpy(s->buffer, s->tok, s->lim - s->tok);
+                       s->tok -= cnt;
+                       s->cur -= cnt;
+                       s->lim -= cnt;
+               }
+               cnt = BSIZE - cnt;
+               if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+               {
+                       s->eof = &s->lim[got];
+               }
+               s->lim += got;
+       }
+       else if (s->cur + len > s->eof)
+       {
+               return 0; /* not enough input data */
+       }
+       return -1;
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+       while(len-- > 0)
+       {
+               fputc(*s++, stream);
+       }
+}
+
+void scan(Scanner *s)
+{
+       fill(s, 0);
+
+       for(;;)
+       {
+               s->tok = s->cur;
+
+               {
+
+                       switch(s->state) {
+                       default: goto yy0;
+                       case 0: goto yyFillLabel0;
+                       case 1: goto yyFillLabel1;
+                       case 2: goto yyFillLabel2;
+                       case 3: goto yyFillLabel3;
+                       }
+yy0:
+                       if (s->cond < 2) {
+                               if (s->cond < 1) {
+                                       goto yyc_Normal;
+                               } else {
+                                       goto yyc_Comment;
+                               }
+                       } else {
+                               if (s->cond < 3) {
+                                       goto yyc_Skiptoeol;
+                               } else {
+                                       goto yyc_String;
+                               }
+                       }
+/* *********************************** */
+yyc_Comment:
+
+                       s->state = 0;
+                       if((s->lim - s->cur) < 2) if(fill(s, 2) >= 0) break;
+yyFillLabel0:
+                       s->yych = *s->cur;
+                       if(s->yych != '*') goto yy4;
+                       ++s->cur;
+                       if((s->yych = *s->cur) == '/') goto yy5;
+yy3:
+                       {
+                               goto yyc_Comment;
+                       }
+yy4:
+                       s->yych = *++s->cur;
+                       goto yy3;
+yy5:
+                       ++s->cur;
+                       {
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+/* *********************************** */
+yyc_Normal:
+                       s->state = 1;
+                       if((s->lim - s->cur) < 4) if(fill(s, 4) >= 0) break;
+yyFillLabel1:
+                       s->yych = *s->cur;
+                       if(s->yych <= '\'') {
+                               if(s->yych == '"') goto yy13;
+                               if(s->yych <= '&') goto yy15;
+                               goto yy12;
+                       } else {
+                               if(s->yych <= '/') {
+                                       if(s->yych <= '.') goto yy15;
+                                       goto yy11;
+                               } else {
+                                       if(s->yych != '?') goto yy15;
+                               }
+                       }
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '?') goto yy26;
+yy10:
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy11:
+                       s->yych = *++s->cur;
+                       if(s->yych == '*') goto yy24;
+                       if(s->yych == '/') goto yy22;
+                       goto yy10;
+yy12:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '"') goto yy16;
+                       if(s->yych == '\\') goto yy18;
+                       goto yy10;
+yy13:
+                       ++s->cur;
+                       {
+                               fputc(*s->tok, stdout);
+                               s->state = EStateString;
+                               continue;
+                       }
+yy15:
+                       s->yych = *++s->cur;
+                       goto yy10;
+yy16:
+                       s->yych = *++s->cur;
+                       if(s->yych == '\'') goto yy20;
+yy17:
+                       s->cur = s->tok;
+                       goto yy10;
+yy18:
+                       s->yych = *++s->cur;
+                       if(s->yych != '"') goto yy17;
+                       s->yych = *++s->cur;
+                       if(s->yych != '\'') goto yy17;
+yy20:
+                       ++s->cur;
+                       {
+                               fputl("'\"'", 3, stdout);
+                               continue;
+                       }
+yy22:
+                       ++s->cur;
+                       {
+                               s->cond = EStateSkiptoeol;
+                               goto yyc_Skiptoeol;
+                       }
+yy24:
+                       ++s->cur;
+                       {
+                               s->cond = EStateComment;
+                               goto yyc_Comment;
+                       }
+yy26:
+                       s->yych = *++s->cur;
+                       switch(s->yych) {
+                       case '!':       goto yy41;
+                       case '\'':      goto yy39;
+                       case '(':       goto yy27;
+                       case ')':       goto yy29;
+                       case '-':       goto yy43;
+                       case '/':       goto yy37;
+                       case '<':       goto yy31;
+                       case '=':       goto yy35;
+                       case '>':       goto yy33;
+                       default:        goto yy17;
+                       }
+yy27:
+                       ++s->cur;
+                       {
+                               fputc('[', stdout);
+                               continue;
+                       }
+yy29:
+                       ++s->cur;
+                       {
+                               fputc(']', stdout);
+                               continue;
+                       }
+yy31:
+                       ++s->cur;
+                       {
+                               fputc('{', stdout);
+                               continue;
+                       }
+yy33:
+                       ++s->cur;
+                       {
+                               fputc('}', stdout);
+                               continue;
+                       }
+yy35:
+                       ++s->cur;
+                       {
+                               fputc('#', stdout);
+                               continue;
+                       }
+yy37:
+                       ++s->cur;
+                       {
+                               fputc('\\', stdout);
+                               continue;
+                       }
+yy39:
+                       ++s->cur;
+                       {
+                               fputc('^', stdout);
+                               continue;
+                       }
+yy41:
+                       ++s->cur;
+                       {
+                               fputc('|', stdout);
+                               continue;
+                       }
+yy43:
+                       ++s->cur;
+                       {
+                               fputc('~', stdout);
+                               continue;
+                       }
+/* *********************************** */
+yyc_Skiptoeol:
+                       s->state = 2;
+                       if((s->lim - s->cur) < 5) if(fill(s, 5) >= 0) break;
+yyFillLabel2:
+                       s->yych = *s->cur;
+                       if(s->yych <= '>') {
+                               if(s->yych == 0x0A) goto yy50;
+                               goto yy52;
+                       } else {
+                               if(s->yych <= '?') goto yy47;
+                               if(s->yych == '\\') goto yy49;
+                               goto yy52;
+                       }
+yy47:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '?') goto yy57;
+yy48:
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+yy49:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == 0x0A) goto yy55;
+                       if(s->yych == 0x0D) goto yy53;
+                       goto yy48;
+yy50:
+                       ++s->cur;
+                       {
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+yy52:
+                       s->yych = *++s->cur;
+                       goto yy48;
+yy53:
+                       s->yych = *++s->cur;
+                       if(s->yych == 0x0A) goto yy55;
+yy54:
+                       s->cur = s->tok;
+                       goto yy48;
+yy55:
+                       ++s->cur;
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+yy57:
+                       s->yych = *++s->cur;
+                       if(s->yych != '/') goto yy54;
+                       s->yych = *++s->cur;
+                       if(s->yych == 0x0A) goto yy60;
+                       if(s->yych != 0x0D) goto yy54;
+                       s->yych = *++s->cur;
+                       if(s->yych != 0x0A) goto yy54;
+yy60:
+                       ++s->cur;
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+/* *********************************** */
+yyc_String:
+                       s->state = 3;
+                       if((s->lim - s->cur) < 2) if(fill(s, 2) >= 0) break;
+yyFillLabel3:
+                       s->yych = *s->cur;
+                       if(s->yych == '"') goto yy66;
+                       if(s->yych != '\\') goto yy68;
+                       ++s->cur;
+                       if((s->yych = *s->cur) != 0x0A) goto yy69;
+yy65:
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy66:
+                       ++s->cur;
+                       {
+                               fputc(*s->tok, stdout);
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+yy68:
+                       s->yych = *++s->cur;
+                       goto yy65;
+yy69:
+                       ++s->cur;
+                       {
+                               fputl((const char*)s->tok, 2, stdout);
+                               continue;
+                       }
+               }
+
+       }
+}
+
+int main(int argc, char **argv)
+{
+       Scanner in;
+       char c;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "%s <file>\n", argv[0]);
+               return 1;;
+       }
+
+       memset((char*) &in, 0, sizeof(in));
+
+       if (!strcmp(argv[1], "-"))
+       {
+               in.fp = stdin;
+       }
+       else if ((in.fp = fopen(argv[1], "r")) == NULL)
+       {
+               fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+               return 1;
+       }
+
+       in.cond = EStateNormal;
+       scan(&in);
+
+       if (in.fp != stdin)
+       {
+               fclose(in.fp);
+       }
+       return 0;
+}
diff --git a/re2c/test/condition_08.cbif.re b/re2c/test/condition_08.cbif.re
new file mode 100755 (executable)
index 0000000..148d9c6
--- /dev/null
@@ -0,0 +1,233 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define        BSIZE   8192
+
+/*!types:re2c */
+
+typedef struct Scanner
+{
+       FILE                        *fp;
+       unsigned char       *cur, *tok, *lim, *eof;
+       unsigned char       buffer[BSIZE];
+       unsigned char       yych;
+       enum ScanContition  cond;
+       int                 state;
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+       if (!len)
+       {
+               s->cur = s->tok = s->lim = s->buffer;
+               s->eof = 0;
+       }
+       if (!s->eof)
+       {
+               int got, cnt = s->tok - s->buffer;
+
+               if (cnt > 0)
+               {
+                       memcpy(s->buffer, s->tok, s->lim - s->tok);
+                       s->tok -= cnt;
+                       s->cur -= cnt;
+                       s->lim -= cnt;
+               }
+               cnt = BSIZE - cnt;
+               if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+               {
+                       s->eof = &s->lim[got];
+               }
+               s->lim += got;
+       }
+       else if (s->cur + len > s->eof)
+       {
+               return 0; /* not enough input data */
+       }
+       return -1;
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+       while(len-- > 0)
+       {
+               fputc(*s++, stream);
+       }
+}
+
+void scan(Scanner *s)
+{
+       fill(s, 0);
+
+       for(;;)
+       {
+               s->tok = s->cur;
+/*!re2c
+
+re2c:define:YYCTYPE          = "unsigned char";
+re2c:define:YYCURSOR         = s->cur;
+re2c:define:YYLIMIT          = s->lim;
+re2c:define:YYMARKER         = s->tok;
+re2c:define:YYFILL:len       = #;
+re2c:define:YYFILL           = "if(fill(s, #) >= 0) break;";
+re2c:define:YYSETSTATE:state = #;
+re2c:define:YYSETSTATE       = "s->state = #;";
+re2c:define:YYGETSTATE       = "s->state";
+re2c:define:YYGETSTATE:func  = 0;
+re2c:define:YYCONDITION      = s->cond;
+re2c:define:YYCONDTYPE       = ScanContition;
+re2c:variable:yych           = s->yych;
+re2c:yych:emit               = 0;
+re2c:indent:top              = 2;
+re2c:condenumprefix          = EState;
+
+<Normal>       "??("
+                       {
+                               fputc('[', stdout);
+                               continue;
+                       }
+<Normal>       "??)"
+                       {
+                               fputc(']', stdout);
+                               continue;
+                       }
+<Normal>       "??<"
+                       {
+                               fputc('{', stdout);
+                               continue;
+                       }
+<Normal>       "??>"
+                       {
+                               fputc('}', stdout);
+                               continue;
+                       }
+<Normal>       "??="
+                       {
+                               fputc('#', stdout);
+                               continue;
+                       }
+<Normal>       "??/"
+                       {
+                               fputc('\\', stdout);
+                               continue;
+                       }
+<Normal>       "??'"
+                       {
+                               fputc('^', stdout);
+                               continue;
+                       }
+<Normal>       "??!"
+                       {
+                               fputc('|', stdout);
+                               continue;
+                       }
+<Normal>       "??-"
+                       {
+                               fputc('~', stdout);
+                               continue;
+                       }
+<Normal>       "/*"
+                       {
+                               s->cond = EStateComment;
+                               goto yyc_Comment;
+                       }
+<Normal>       "//"
+                       {
+                               s->cond = EStateSkiptoeol;
+                               goto yyc_Skiptoeol;
+                       }
+<Normal>       "'\\\"'"|"'\"'"
+                       {
+                               fputl("'\"'", 3, stdout);
+                               continue;
+                       }
+<Normal>       '"'
+                       {
+                               fputc(*s->tok, stdout);
+                               s->state = EStateString;
+                               continue;
+                       }
+<Normal>       [^]
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+<Comment>      "*" "/"
+                       {
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+<Comment>      [^]
+                       {
+                               goto yyc_Comment;
+                       }
+<Skiptoeol>    "??/" "\r"? "\n"
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<Skiptoeol>    "\\" "\r"? "\n"
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<Skiptoeol>    "\n"
+                       {
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+<Skiptoeol> [^]
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<String>       '\\' .
+                       {
+                               fputl((const char*)s->tok, 2, stdout);
+                               continue;
+                       }
+<String>       '"'
+                       {
+                               fputc(*s->tok, stdout);
+                               s->cond = EStateNormal;
+                               continue;
+                       }
+<String>       [^]
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+*/
+       }
+}
+
+int main(int argc, char **argv)
+{
+       Scanner in;
+       char c;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "%s <file>\n", argv[0]);
+               return 1;;
+       }
+
+       memset((char*) &in, 0, sizeof(in));
+
+       if (!strcmp(argv[1], "-"))
+       {
+               in.fp = stdin;
+       }
+       else if ((in.fp = fopen(argv[1], "r")) == NULL)
+       {
+               fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+               return 1;
+       }
+
+       in.cond = EStateNormal;
+       scan(&in);
+
+       if (in.fp != stdin)
+       {
+               fclose(in.fp);
+       }
+       return 0;
+}
diff --git a/re2c/test/condition_09.cbif.c b/re2c/test/condition_09.cbif.c
new file mode 100755 (executable)
index 0000000..62ce8ef
--- /dev/null
@@ -0,0 +1,389 @@
+/* Generated by re2c */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define        BSIZE   8192
+
+
+enum ScanContition {
+       EStateComment,
+       EStateNormal,
+       EStateSkiptoeol,
+       EStateString,
+};
+
+
+typedef struct Scanner
+{
+       FILE                        *fp;
+       unsigned char       *cur, *tok, *lim, *eof;
+       unsigned char       buffer[BSIZE];
+       unsigned char       yych;
+       enum ScanContition  cond;
+       int                 state;
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+       if (!len)
+       {
+               s->cur = s->tok = s->lim = s->buffer;
+               s->eof = 0;
+       }
+       if (!s->eof)
+       {
+               int got, cnt = s->tok - s->buffer;
+
+               if (cnt > 0)
+               {
+                       memcpy(s->buffer, s->tok, s->lim - s->tok);
+                       s->tok -= cnt;
+                       s->cur -= cnt;
+                       s->lim -= cnt;
+               }
+               cnt = BSIZE - cnt;
+               if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+               {
+                       s->eof = &s->lim[got];
+               }
+               s->lim += got;
+       }
+       else if (s->cur + len > s->eof)
+       {
+               return 0; /* not enough input data */
+       }
+       return -1;
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+       while(len-- > 0)
+       {
+               fputc(*s++, stream);
+       }
+}
+
+void scan(Scanner *s)
+{
+       fill(s, 0);
+
+       for(;;)
+       {
+               s->tok = s->cur;
+
+               {
+
+                       switch(s->state) {
+                       default: goto yy0;
+                       case 0: goto yyFillLabel0;
+                       case 1: goto yyFillLabel1;
+                       case 2: goto yyFillLabel2;
+                       case 3: goto yyFillLabel3;
+                       }
+yy0:
+                       if (s->cond < 2) {
+                               if (s->cond < 1) {
+                                       goto yyc_Normal;
+                               } else {
+                                       goto yyc_Comment;
+                               }
+                       } else {
+                               if (s->cond < 3) {
+                                       goto yyc_Skiptoeol;
+                               } else {
+                                       goto yyc_String;
+                               }
+                       }
+/* *********************************** */
+yyc_Comment:
+
+                       s->state = 0;
+                       if((s->lim - s->cur) < 2) if(fill(s, 2) >= 0) break;
+yyFillLabel0:
+                       s->yych = *s->cur;
+                       if(s->yych != '*') goto yy4;
+                       ++s->cur;
+                       if((s->yych = *s->cur) == '/') goto yy5;
+yy3:
+                       {
+                               goto yyc_Comment;
+                       }
+yy4:
+                       s->yych = *++s->cur;
+                       goto yy3;
+yy5:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       {
+                               continue;
+                       }
+/* *********************************** */
+yyc_Normal:
+                       s->state = 1;
+                       if((s->lim - s->cur) < 4) if(fill(s, 4) >= 0) break;
+yyFillLabel1:
+                       s->yych = *s->cur;
+                       if(s->yych <= '\'') {
+                               if(s->yych == '"') goto yy13;
+                               if(s->yych <= '&') goto yy15;
+                               goto yy12;
+                       } else {
+                               if(s->yych <= '/') {
+                                       if(s->yych <= '.') goto yy15;
+                                       goto yy11;
+                               } else {
+                                       if(s->yych != '?') goto yy15;
+                               }
+                       }
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '?') goto yy26;
+yy10:
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy11:
+                       s->yych = *++s->cur;
+                       if(s->yych == '*') goto yy24;
+                       if(s->yych == '/') goto yy22;
+                       goto yy10;
+yy12:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '"') goto yy16;
+                       if(s->yych == '\\') goto yy18;
+                       goto yy10;
+yy13:
+                       ++s->cur;
+                       s->cond = EStateString;
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy15:
+                       s->yych = *++s->cur;
+                       goto yy10;
+yy16:
+                       s->yych = *++s->cur;
+                       if(s->yych == '\'') goto yy20;
+yy17:
+                       s->cur = s->tok;
+                       goto yy10;
+yy18:
+                       s->yych = *++s->cur;
+                       if(s->yych != '"') goto yy17;
+                       s->yych = *++s->cur;
+                       if(s->yych != '\'') goto yy17;
+yy20:
+                       ++s->cur;
+                       {
+                               fputl("'\"'", 3, stdout);
+                               continue;
+                       }
+yy22:
+                       ++s->cur;
+                       s->cond = EStateSkiptoeol;
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+yy24:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       {
+                               goto yyc_Comment;
+                       }
+yy26:
+                       s->yych = *++s->cur;
+                       switch(s->yych) {
+                       case '!':       goto yy41;
+                       case '\'':      goto yy39;
+                       case '(':       goto yy27;
+                       case ')':       goto yy29;
+                       case '-':       goto yy43;
+                       case '/':       goto yy37;
+                       case '<':       goto yy31;
+                       case '=':       goto yy35;
+                       case '>':       goto yy33;
+                       default:        goto yy17;
+                       }
+yy27:
+                       ++s->cur;
+                       {
+                               fputc('[', stdout);
+                               continue;
+                       }
+yy29:
+                       ++s->cur;
+                       {
+                               fputc(']', stdout);
+                               continue;
+                       }
+yy31:
+                       ++s->cur;
+                       {
+                               fputc('{', stdout);
+                               continue;
+                       }
+yy33:
+                       ++s->cur;
+                       {
+                               fputc('}', stdout);
+                               continue;
+                       }
+yy35:
+                       ++s->cur;
+                       {
+                               fputc('#', stdout);
+                               continue;
+                       }
+yy37:
+                       ++s->cur;
+                       {
+                               fputc('\\', stdout);
+                               continue;
+                       }
+yy39:
+                       ++s->cur;
+                       {
+                               fputc('^', stdout);
+                               continue;
+                       }
+yy41:
+                       ++s->cur;
+                       {
+                               fputc('|', stdout);
+                               continue;
+                       }
+yy43:
+                       ++s->cur;
+                       {
+                               fputc('~', stdout);
+                               continue;
+                       }
+/* *********************************** */
+yyc_Skiptoeol:
+                       s->state = 2;
+                       if((s->lim - s->cur) < 5) if(fill(s, 5) >= 0) break;
+yyFillLabel2:
+                       s->yych = *s->cur;
+                       if(s->yych <= '>') {
+                               if(s->yych == 0x0A) goto yy50;
+                               goto yy52;
+                       } else {
+                               if(s->yych <= '?') goto yy47;
+                               if(s->yych == '\\') goto yy49;
+                               goto yy52;
+                       }
+yy47:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '?') goto yy57;
+yy48:
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+yy49:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == 0x0A) goto yy55;
+                       if(s->yych == 0x0D) goto yy53;
+                       goto yy48;
+yy50:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       {
+                               continue;
+                       }
+yy52:
+                       s->yych = *++s->cur;
+                       goto yy48;
+yy53:
+                       s->yych = *++s->cur;
+                       if(s->yych == 0x0A) goto yy55;
+yy54:
+                       s->cur = s->tok;
+                       goto yy48;
+yy55:
+                       ++s->cur;
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+yy57:
+                       s->yych = *++s->cur;
+                       if(s->yych != '/') goto yy54;
+                       s->yych = *++s->cur;
+                       if(s->yych == 0x0A) goto yy60;
+                       if(s->yych != 0x0D) goto yy54;
+                       s->yych = *++s->cur;
+                       if(s->yych != 0x0A) goto yy54;
+yy60:
+                       ++s->cur;
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+/* *********************************** */
+yyc_String:
+                       s->state = 3;
+                       if((s->lim - s->cur) < 2) if(fill(s, 2) >= 0) break;
+yyFillLabel3:
+                       s->yych = *s->cur;
+                       if(s->yych == '"') goto yy66;
+                       if(s->yych != '\\') goto yy68;
+                       ++s->cur;
+                       if((s->yych = *s->cur) != 0x0A) goto yy69;
+yy65:
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy66:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy68:
+                       s->yych = *++s->cur;
+                       goto yy65;
+yy69:
+                       ++s->cur;
+                       {
+                               fputl((const char*)s->tok, 2, stdout);
+                               continue;
+                       }
+               }
+
+       }
+}
+
+int main(int argc, char **argv)
+{
+       Scanner in;
+       char c;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "%s <file>\n", argv[0]);
+               return 1;;
+       }
+
+       memset((char*) &in, 0, sizeof(in));
+
+       if (!strcmp(argv[1], "-"))
+       {
+               in.fp = stdin;
+       }
+       else if ((in.fp = fopen(argv[1], "r")) == NULL)
+       {
+               fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+               return 1;
+       }
+
+       in.cond = EStateNormal;
+       scan(&in);
+
+       if (in.fp != stdin)
+       {
+               fclose(in.fp);
+       }
+       return 0;
+}
diff --git a/re2c/test/condition_09.cbif.re b/re2c/test/condition_09.cbif.re
new file mode 100755 (executable)
index 0000000..432a0cc
--- /dev/null
@@ -0,0 +1,227 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define        BSIZE   8192
+
+/*!types:re2c */
+
+typedef struct Scanner
+{
+       FILE                        *fp;
+       unsigned char       *cur, *tok, *lim, *eof;
+       unsigned char       buffer[BSIZE];
+       unsigned char       yych;
+       enum ScanContition  cond;
+       int                 state;
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+       if (!len)
+       {
+               s->cur = s->tok = s->lim = s->buffer;
+               s->eof = 0;
+       }
+       if (!s->eof)
+       {
+               int got, cnt = s->tok - s->buffer;
+
+               if (cnt > 0)
+               {
+                       memcpy(s->buffer, s->tok, s->lim - s->tok);
+                       s->tok -= cnt;
+                       s->cur -= cnt;
+                       s->lim -= cnt;
+               }
+               cnt = BSIZE - cnt;
+               if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+               {
+                       s->eof = &s->lim[got];
+               }
+               s->lim += got;
+       }
+       else if (s->cur + len > s->eof)
+       {
+               return 0; /* not enough input data */
+       }
+       return -1;
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+       while(len-- > 0)
+       {
+               fputc(*s++, stream);
+       }
+}
+
+void scan(Scanner *s)
+{
+       fill(s, 0);
+
+       for(;;)
+       {
+               s->tok = s->cur;
+/*!re2c
+
+re2c:define:YYCTYPE          = "unsigned char";
+re2c:define:YYCURSOR         = s->cur;
+re2c:define:YYLIMIT          = s->lim;
+re2c:define:YYMARKER         = s->tok;
+re2c:define:YYFILL:len       = #;
+re2c:define:YYFILL           = "if(fill(s, #) >= 0) break;";
+re2c:define:YYSETSTATE:state = #;
+re2c:define:YYSETSTATE       = "s->state = #;";
+re2c:define:YYGETSTATE       = "s->state";
+re2c:define:YYGETSTATE:func  = 0;
+re2c:define:YYCONDITION      = s->cond;
+re2c:define:YYCONDTYPE       = ScanContition;
+re2c:variable:yych           = s->yych;
+re2c:yych:emit               = 0;
+re2c:indent:top              = 2;
+re2c:condenumprefix          = EState;
+
+<Normal>       "??("
+                       {
+                               fputc('[', stdout);
+                               continue;
+                       }
+<Normal>       "??)"
+                       {
+                               fputc(']', stdout);
+                               continue;
+                       }
+<Normal>       "??<"
+                       {
+                               fputc('{', stdout);
+                               continue;
+                       }
+<Normal>       "??>"
+                       {
+                               fputc('}', stdout);
+                               continue;
+                       }
+<Normal>       "??="
+                       {
+                               fputc('#', stdout);
+                               continue;
+                       }
+<Normal>       "??/"
+                       {
+                               fputc('\\', stdout);
+                               continue;
+                       }
+<Normal>       "??'"
+                       {
+                               fputc('^', stdout);
+                               continue;
+                       }
+<Normal>       "??!"
+                       {
+                               fputc('|', stdout);
+                               continue;
+                       }
+<Normal>       "??-"
+                       {
+                               fputc('~', stdout);
+                               continue;
+                       }
+<Normal>       "/*" => Normal
+                       {
+                               goto yyc_Comment;
+                       }
+<Normal>       "//" => Skiptoeol
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<Normal>       "'\\\"'"|"'\"'"
+                       {
+                               fputl("'\"'", 3, stdout);
+                               continue;
+                       }
+<Normal>       '"' => String
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+<Normal>       [^]
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+<Comment>      "*" "/" => Normal
+                       {
+                               continue;
+                       }
+<Comment>      [^]
+                       {
+                               goto yyc_Comment;
+                       }
+<Skiptoeol>    "??/" "\r"? "\n"
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<Skiptoeol>    "\\" "\r"? "\n"
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<Skiptoeol>    "\n" => Normal
+                       {
+                               continue;
+                       }
+<Skiptoeol> [^]
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<String>       '\\' .
+                       {
+                               fputl((const char*)s->tok, 2, stdout);
+                               continue;
+                       }
+<String>       '"' => Normal
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+<String>       [^]
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+*/
+       }
+}
+
+int main(int argc, char **argv)
+{
+       Scanner in;
+       char c;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "%s <file>\n", argv[0]);
+               return 1;;
+       }
+
+       memset((char*) &in, 0, sizeof(in));
+
+       if (!strcmp(argv[1], "-"))
+       {
+               in.fp = stdin;
+       }
+       else if ((in.fp = fopen(argv[1], "r")) == NULL)
+       {
+               fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+               return 1;
+       }
+
+       in.cond = EStateNormal;
+       scan(&in);
+
+       if (in.fp != stdin)
+       {
+               fclose(in.fp);
+       }
+       return 0;
+}
diff --git a/re2c/test/condition_09.cgif.c b/re2c/test/condition_09.cgif.c
new file mode 100755 (executable)
index 0000000..826810a
--- /dev/null
@@ -0,0 +1,434 @@
+/* Generated by re2c */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define        BSIZE   8192
+
+
+enum ScanContition {
+       EStateComment,
+       EStateNormal,
+       EStateSkiptoeol,
+       EStateString,
+};
+
+
+typedef struct Scanner
+{
+       FILE                        *fp;
+       unsigned char       *cur, *tok, *lim, *eof;
+       unsigned char       buffer[BSIZE];
+       unsigned char       yych;
+       enum ScanContition  cond;
+       int                 state;
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+       if (!len)
+       {
+               s->cur = s->tok = s->lim = s->buffer;
+               s->eof = 0;
+       }
+       if (!s->eof)
+       {
+               int got, cnt = s->tok - s->buffer;
+
+               if (cnt > 0)
+               {
+                       memcpy(s->buffer, s->tok, s->lim - s->tok);
+                       s->tok -= cnt;
+                       s->cur -= cnt;
+                       s->lim -= cnt;
+               }
+               cnt = BSIZE - cnt;
+               if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+               {
+                       s->eof = &s->lim[got];
+               }
+               s->lim += got;
+       }
+       else if (s->cur + len > s->eof)
+       {
+               return 0; /* not enough input data */
+       }
+       return -1;
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+       while(len-- > 0)
+       {
+               fputc(*s++, stream);
+       }
+}
+
+void scan(Scanner *s)
+{
+       fill(s, 0);
+
+       for(;;)
+       {
+               s->tok = s->cur;
+
+               {
+
+                       static void *yyctable[4] = {
+                               &&yyc_Comment,
+                               &&yyc_Normal,
+                               &&yyc_Skiptoeol,
+                               &&yyc_String,
+                       };
+                       switch(s->state) {
+                       default: goto yy0;
+                       case 0: goto yyFillLabel0;
+                       case 1: goto yyFillLabel1;
+                       case 2: goto yyFillLabel2;
+                       case 3: goto yyFillLabel3;
+                       }
+yy0:
+                       goto *yyctable[s->cond];
+/* *********************************** */
+yyc_Comment:
+
+                       s->state = 0;
+                       if((s->lim - s->cur) < 2) if(fill(s, 2) >= 0) break;
+yyFillLabel0:
+                       s->yych = *s->cur;
+                       if(s->yych != '*') goto yy4;
+                       ++s->cur;
+                       if((s->yych = *s->cur) == '/') goto yy5;
+yy3:
+                       {
+                               goto yyc_Comment;
+                       }
+yy4:
+                       s->yych = *++s->cur;
+                       goto yy3;
+yy5:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       {
+                               continue;
+                       }
+/* *********************************** */
+yyc_Normal:
+                       s->state = 1;
+                       if((s->lim - s->cur) < 4) if(fill(s, 4) >= 0) break;
+yyFillLabel1:
+                       s->yych = *s->cur;
+                       {
+                               static void *yytarget[256] = {
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy13, &&yy15, &&yy15, &&yy15, &&yy15, &&yy12,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy11,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy9,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15
+                               };
+                               goto *yytarget[s->yych];
+                       }
+yy9:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '?') goto yy26;
+yy10:
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy11:
+                       s->yych = *++s->cur;
+                       if(s->yych == '*') goto yy24;
+                       if(s->yych == '/') goto yy22;
+                       goto yy10;
+yy12:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '"') goto yy16;
+                       if(s->yych == '\\') goto yy18;
+                       goto yy10;
+yy13:
+                       ++s->cur;
+                       s->cond = EStateString;
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy15:
+                       s->yych = *++s->cur;
+                       goto yy10;
+yy16:
+                       s->yych = *++s->cur;
+                       if(s->yych == '\'') goto yy20;
+yy17:
+                       s->cur = s->tok;
+                       goto yy10;
+yy18:
+                       s->yych = *++s->cur;
+                       if(s->yych != '"') goto yy17;
+                       s->yych = *++s->cur;
+                       if(s->yych != '\'') goto yy17;
+yy20:
+                       ++s->cur;
+                       {
+                               fputl("'\"'", 3, stdout);
+                               continue;
+                       }
+yy22:
+                       ++s->cur;
+                       s->cond = EStateSkiptoeol;
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+yy24:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       {
+                               goto yyc_Comment;
+                       }
+yy26:
+                       s->yych = *++s->cur;
+                       {
+                               static void *yytarget[256] = {
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy41, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy39,
+                                       &&yy27, &&yy29, &&yy17, &&yy17, &&yy17, &&yy43, &&yy17, &&yy37,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy31, &&yy35, &&yy33, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17
+                               };
+                               goto *yytarget[s->yych];
+                       }
+yy27:
+                       ++s->cur;
+                       {
+                               fputc('[', stdout);
+                               continue;
+                       }
+yy29:
+                       ++s->cur;
+                       {
+                               fputc(']', stdout);
+                               continue;
+                       }
+yy31:
+                       ++s->cur;
+                       {
+                               fputc('{', stdout);
+                               continue;
+                       }
+yy33:
+                       ++s->cur;
+                       {
+                               fputc('}', stdout);
+                               continue;
+                       }
+yy35:
+                       ++s->cur;
+                       {
+                               fputc('#', stdout);
+                               continue;
+                       }
+yy37:
+                       ++s->cur;
+                       {
+                               fputc('\\', stdout);
+                               continue;
+                       }
+yy39:
+                       ++s->cur;
+                       {
+                               fputc('^', stdout);
+                               continue;
+                       }
+yy41:
+                       ++s->cur;
+                       {
+                               fputc('|', stdout);
+                               continue;
+                       }
+yy43:
+                       ++s->cur;
+                       {
+                               fputc('~', stdout);
+                               continue;
+                       }
+/* *********************************** */
+yyc_Skiptoeol:
+                       s->state = 2;
+                       if((s->lim - s->cur) < 5) if(fill(s, 5) >= 0) break;
+yyFillLabel2:
+                       s->yych = *s->cur;
+                       if(s->yych <= '>') {
+                               if(s->yych == 0x0A) goto yy50;
+                               goto yy52;
+                       } else {
+                               if(s->yych <= '?') goto yy47;
+                               if(s->yych == '\\') goto yy49;
+                               goto yy52;
+                       }
+yy47:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '?') goto yy57;
+yy48:
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+yy49:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == 0x0A) goto yy55;
+                       if(s->yych == 0x0D) goto yy53;
+                       goto yy48;
+yy50:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       {
+                               continue;
+                       }
+yy52:
+                       s->yych = *++s->cur;
+                       goto yy48;
+yy53:
+                       s->yych = *++s->cur;
+                       if(s->yych == 0x0A) goto yy55;
+yy54:
+                       s->cur = s->tok;
+                       goto yy48;
+yy55:
+                       ++s->cur;
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+yy57:
+                       s->yych = *++s->cur;
+                       if(s->yych != '/') goto yy54;
+                       s->yych = *++s->cur;
+                       if(s->yych == 0x0A) goto yy60;
+                       if(s->yych != 0x0D) goto yy54;
+                       s->yych = *++s->cur;
+                       if(s->yych != 0x0A) goto yy54;
+yy60:
+                       ++s->cur;
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+/* *********************************** */
+yyc_String:
+                       s->state = 3;
+                       if((s->lim - s->cur) < 2) if(fill(s, 2) >= 0) break;
+yyFillLabel3:
+                       s->yych = *s->cur;
+                       if(s->yych == '"') goto yy66;
+                       if(s->yych != '\\') goto yy68;
+                       ++s->cur;
+                       if((s->yych = *s->cur) != 0x0A) goto yy69;
+yy65:
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy66:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+yy68:
+                       s->yych = *++s->cur;
+                       goto yy65;
+yy69:
+                       ++s->cur;
+                       {
+                               fputl((const char*)s->tok, 2, stdout);
+                               continue;
+                       }
+               }
+
+       }
+}
+
+int main(int argc, char **argv)
+{
+       Scanner in;
+       char c;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "%s <file>\n", argv[0]);
+               return 1;;
+       }
+
+       memset((char*) &in, 0, sizeof(in));
+
+       if (!strcmp(argv[1], "-"))
+       {
+               in.fp = stdin;
+       }
+       else if ((in.fp = fopen(argv[1], "r")) == NULL)
+       {
+               fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+               return 1;
+       }
+
+       in.cond = EStateNormal;
+       scan(&in);
+
+       if (in.fp != stdin)
+       {
+               fclose(in.fp);
+       }
+       return 0;
+}
diff --git a/re2c/test/condition_09.cgif.re b/re2c/test/condition_09.cgif.re
new file mode 100755 (executable)
index 0000000..432a0cc
--- /dev/null
@@ -0,0 +1,227 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define        BSIZE   8192
+
+/*!types:re2c */
+
+typedef struct Scanner
+{
+       FILE                        *fp;
+       unsigned char       *cur, *tok, *lim, *eof;
+       unsigned char       buffer[BSIZE];
+       unsigned char       yych;
+       enum ScanContition  cond;
+       int                 state;
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+       if (!len)
+       {
+               s->cur = s->tok = s->lim = s->buffer;
+               s->eof = 0;
+       }
+       if (!s->eof)
+       {
+               int got, cnt = s->tok - s->buffer;
+
+               if (cnt > 0)
+               {
+                       memcpy(s->buffer, s->tok, s->lim - s->tok);
+                       s->tok -= cnt;
+                       s->cur -= cnt;
+                       s->lim -= cnt;
+               }
+               cnt = BSIZE - cnt;
+               if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+               {
+                       s->eof = &s->lim[got];
+               }
+               s->lim += got;
+       }
+       else if (s->cur + len > s->eof)
+       {
+               return 0; /* not enough input data */
+       }
+       return -1;
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+       while(len-- > 0)
+       {
+               fputc(*s++, stream);
+       }
+}
+
+void scan(Scanner *s)
+{
+       fill(s, 0);
+
+       for(;;)
+       {
+               s->tok = s->cur;
+/*!re2c
+
+re2c:define:YYCTYPE          = "unsigned char";
+re2c:define:YYCURSOR         = s->cur;
+re2c:define:YYLIMIT          = s->lim;
+re2c:define:YYMARKER         = s->tok;
+re2c:define:YYFILL:len       = #;
+re2c:define:YYFILL           = "if(fill(s, #) >= 0) break;";
+re2c:define:YYSETSTATE:state = #;
+re2c:define:YYSETSTATE       = "s->state = #;";
+re2c:define:YYGETSTATE       = "s->state";
+re2c:define:YYGETSTATE:func  = 0;
+re2c:define:YYCONDITION      = s->cond;
+re2c:define:YYCONDTYPE       = ScanContition;
+re2c:variable:yych           = s->yych;
+re2c:yych:emit               = 0;
+re2c:indent:top              = 2;
+re2c:condenumprefix          = EState;
+
+<Normal>       "??("
+                       {
+                               fputc('[', stdout);
+                               continue;
+                       }
+<Normal>       "??)"
+                       {
+                               fputc(']', stdout);
+                               continue;
+                       }
+<Normal>       "??<"
+                       {
+                               fputc('{', stdout);
+                               continue;
+                       }
+<Normal>       "??>"
+                       {
+                               fputc('}', stdout);
+                               continue;
+                       }
+<Normal>       "??="
+                       {
+                               fputc('#', stdout);
+                               continue;
+                       }
+<Normal>       "??/"
+                       {
+                               fputc('\\', stdout);
+                               continue;
+                       }
+<Normal>       "??'"
+                       {
+                               fputc('^', stdout);
+                               continue;
+                       }
+<Normal>       "??!"
+                       {
+                               fputc('|', stdout);
+                               continue;
+                       }
+<Normal>       "??-"
+                       {
+                               fputc('~', stdout);
+                               continue;
+                       }
+<Normal>       "/*" => Normal
+                       {
+                               goto yyc_Comment;
+                       }
+<Normal>       "//" => Skiptoeol
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<Normal>       "'\\\"'"|"'\"'"
+                       {
+                               fputl("'\"'", 3, stdout);
+                               continue;
+                       }
+<Normal>       '"' => String
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+<Normal>       [^]
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+<Comment>      "*" "/" => Normal
+                       {
+                               continue;
+                       }
+<Comment>      [^]
+                       {
+                               goto yyc_Comment;
+                       }
+<Skiptoeol>    "??/" "\r"? "\n"
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<Skiptoeol>    "\\" "\r"? "\n"
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<Skiptoeol>    "\n" => Normal
+                       {
+                               continue;
+                       }
+<Skiptoeol> [^]
+                       {
+                               goto yyc_Skiptoeol;
+                       }
+<String>       '\\' .
+                       {
+                               fputl((const char*)s->tok, 2, stdout);
+                               continue;
+                       }
+<String>       '"' => Normal
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+<String>       [^]
+                       {
+                               fputc(*s->tok, stdout);
+                               continue;
+                       }
+*/
+       }
+}
+
+int main(int argc, char **argv)
+{
+       Scanner in;
+       char c;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "%s <file>\n", argv[0]);
+               return 1;;
+       }
+
+       memset((char*) &in, 0, sizeof(in));
+
+       if (!strcmp(argv[1], "-"))
+       {
+               in.fp = stdin;
+       }
+       else if ((in.fp = fopen(argv[1], "r")) == NULL)
+       {
+               fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+               return 1;
+       }
+
+       in.cond = EStateNormal;
+       scan(&in);
+
+       if (in.fp != stdin)
+       {
+               fclose(in.fp);
+       }
+       return 0;
+}
index 3c3fafcb2f83592e8eacdf0e2d1e1551a1c31fd9..4724b92dbd34c82fe739897b028a2c9c1361db2e 100755 (executable)
@@ -46,7 +46,7 @@ re2c:define:YYCURSOR  = s.cur;
 re2c:define:YYLIMIT            = s.lim;
 re2c:define:YYMARKER   = s.ptr;
 re2c:define:YYCTXMARKER        = s.ctx;
-re2c:define:YYFILL      = "fill()";
+re2c:define:YYFILL      = "fill();";
 
 re2c:yyfill:parameter   = 0;
 re2c:variable:yych      = curr;
index 19a6442052edd9ec69811cc6a2e2bda64acac13a..6fc3989589bce7c6d020df15f52ddeaeae8a72f8 100644 (file)
@@ -11,23 +11,36 @@ class Token
 {
 public:
        Str     text;
+       Str*    newcond;
        uint    line;
 
 public:
        Token(const SubStr&, uint);
        Token(const Token& oth);
+       ~Token();
 };
 
-inline Token::Token(const SubStr& t, uint l) : text(t), line(l)
+inline Token::Token(const SubStr& t, uint l) : text(t), newcond(NULL), line(l)
 {
        ;
 }
 
-inline Token::Token(const Token& oth) : text(oth.text), line(oth.line)
+inline Token::Token(const Token& oth)
+       : text(oth.text)
+       , newcond(oth.newcond ? new Str(*oth.newcond) : NULL)
+       , line(oth.line)
 {
        ;
 }
 
+inline Token::~Token()
+{
+       if (newcond)
+       {
+               delete newcond;
+       }
+}
+
 } // end namespace re2c
 
 #endif