From: helly
Date: Tue, 12 Feb 2008 22:02:59 +0000 (+0000)
Subject: - Added support for \ to enable rule setup.
X-Git-Tag: 0.13.6~98
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f5c9177a6167ec535d9b16120ff6354b17761694;p=re2c
- Added support for \ to enable rule setup.
---
diff --git a/re2c/CHANGELOG b/re2c/CHANGELOG
index a9bfea50..8b78aee7 100644
--- a/re2c/CHANGELOG
+++ b/re2c/CHANGELOG
@@ -1,5 +1,6 @@
Version 0.13.2 (2007-??-??)
---------------------------
+- Added support for '' to enable rule setup.
- Added support for '=>' style rules.
- Added support for ':=' style rules.
- Added support for ':=>' style rules.
diff --git a/re2c/bootstrap/parser.cc b/re2c/bootstrap/parser.cc
index ec61cc73..20abb6f8 100644
--- a/re2c/bootstrap/parser.cc
+++ b/re2c/bootstrap/parser.cc
@@ -76,7 +76,8 @@
STRING = 265,
CONFIG = 266,
VALUE = 267,
- NUMBER = 268
+ NUMBER = 268,
+ SETUP = 269
};
#endif
/* Tokens. */
@@ -91,6 +92,7 @@
#define CONFIG 266
#define VALUE 267
#define NUMBER 268
+#define SETUP 269
@@ -109,6 +111,7 @@
#include
#include
#include
+#include
#include "globals.h"
#include "parser.h"
@@ -130,6 +133,7 @@ static re2c::RegExpMap specMap;
static RegExp *spec, *specNone = NULL;
static RuleOpList specStar;
static Scanner *in = NULL;
+static StringMap ruleSetupMap;
/* Bison version 1.875 emits a definition that is not working
* with several g++ version. Hence we disable it here.
@@ -198,6 +202,25 @@ void context_rule(CondList *clist, RegExp *expr, RegExp *look, Str *newcond, Tok
delete code;
}
+void setup_rule(CondList *clist, Token *code)
+{
+ assert(clist);
+ assert(code);
+ context_check(clist);
+ if (bFirstPass) {
+ for(CondList::const_iterator it = clist->begin(); it != clist->end(); ++it)
+ {
+ if (ruleSetupMap.find(*it) != ruleSetupMap.end())
+ {
+ in->fatalf("code to setup rule '%s' is already defined", it->c_str());
+ }
+ ruleSetupMap[*it] = code->text.to_string();
+ }
+ }
+ delete clist;
+ delete code;
+}
+
/* Enabling traces. */
@@ -220,7 +243,7 @@ void context_rule(CondList *clist, RegExp *expr, RegExp *look, Str *newcond, Tok
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 106 "parser.y"
+#line 127 "parser.y"
{
re2c::Symbol *symbol;
re2c::RegExp *regexp;
@@ -232,7 +255,7 @@ typedef union YYSTYPE
re2c::CondList *clist;
}
/* Line 187 of yacc.c. */
-#line 236 "parser.cc"
+#line 259 "parser.cc"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -245,7 +268,7 @@ typedef union YYSTYPE
/* Line 216 of yacc.c. */
-#line 249 "parser.cc"
+#line 272 "parser.cc"
#ifdef short
# undef short
@@ -460,20 +483,20 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 89
+#define YYLAST 92
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 25
+#define YYNTOKENS 26
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 14
/* YYNRULES -- Number of rules. */
-#define YYNRULES 44
+#define YYNRULES 46
/* YYNRULES -- Number of states. */
-#define YYNSTATES 81
+#define YYNSTATES 88
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 268
+#define YYMAXUTOK 269
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -485,15 +508,15 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 23, 24, 2, 2, 20, 2, 2, 16, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 19, 15,
- 17, 14, 18, 2, 2, 2, 2, 2, 2, 2,
+ 24, 25, 2, 2, 21, 2, 2, 17, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 20, 16,
+ 18, 15, 19, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 22, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 23, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 21, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 22, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -507,7 +530,7 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
};
#if YYDEBUG
@@ -517,41 +540,42 @@ static const yytype_uint8 yyprhs[] =
{
0, 0, 3, 4, 7, 10, 15, 20, 25, 30,
34, 42, 50, 57, 64, 72, 80, 87, 94, 98,
- 102, 103, 105, 107, 111, 112, 116, 117, 120, 122,
- 126, 128, 132, 134, 137, 139, 142, 145, 147, 149,
- 152, 155, 157, 159, 161
+ 102, 107, 112, 113, 115, 117, 121, 122, 126, 127,
+ 130, 132, 136, 138, 142, 144, 147, 149, 152, 155,
+ 157, 159, 162, 165, 167, 169, 171
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] =
{
- 26, 0, -1, -1, 26, 28, -1, 26, 27, -1,
- 7, 14, 33, 15, -1, 7, 14, 33, 16, -1,
- 11, 14, 12, 15, -1, 11, 14, 13, 15, -1,
- 33, 32, 8, -1, 17, 29, 18, 33, 32, 31,
- 8, -1, 17, 29, 18, 33, 32, 19, 31, -1,
- 17, 29, 18, 32, 31, 8, -1, 17, 29, 18,
- 32, 19, 31, -1, 17, 5, 18, 33, 32, 31,
- 8, -1, 17, 5, 18, 33, 32, 19, 31, -1,
- 17, 5, 18, 32, 31, 8, -1, 17, 5, 18,
- 32, 19, 31, -1, 6, 31, 8, -1, 6, 19,
- 31, -1, -1, 30, -1, 7, -1, 30, 20, 7,
- -1, -1, 14, 18, 7, -1, -1, 16, 33, -1,
- 34, -1, 33, 21, 34, -1, 35, -1, 34, 22,
- 35, -1, 36, -1, 35, 36, -1, 38, -1, 38,
- 37, -1, 38, 3, -1, 4, -1, 5, -1, 37,
- 4, -1, 37, 5, -1, 7, -1, 9, -1, 10,
- -1, 23, 33, 24, -1
+ 27, 0, -1, -1, 27, 29, -1, 27, 28, -1,
+ 7, 15, 34, 16, -1, 7, 15, 34, 17, -1,
+ 11, 15, 12, 16, -1, 11, 15, 13, 16, -1,
+ 34, 33, 8, -1, 18, 30, 19, 34, 33, 32,
+ 8, -1, 18, 30, 19, 34, 33, 20, 32, -1,
+ 18, 30, 19, 33, 32, 8, -1, 18, 30, 19,
+ 33, 20, 32, -1, 18, 5, 19, 34, 33, 32,
+ 8, -1, 18, 5, 19, 34, 33, 20, 32, -1,
+ 18, 5, 19, 33, 32, 8, -1, 18, 5, 19,
+ 33, 20, 32, -1, 6, 32, 8, -1, 6, 20,
+ 32, -1, 14, 5, 19, 8, -1, 14, 30, 19,
+ 8, -1, -1, 31, -1, 7, -1, 31, 21, 7,
+ -1, -1, 15, 19, 7, -1, -1, 17, 34, -1,
+ 35, -1, 34, 22, 35, -1, 36, -1, 35, 23,
+ 36, -1, 37, -1, 36, 37, -1, 39, -1, 39,
+ 38, -1, 39, 3, -1, 4, -1, 5, -1, 38,
+ 4, -1, 38, 5, -1, 7, -1, 9, -1, 10,
+ -1, 24, 34, 25, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 135, 135, 139, 140, 144, 152, 156, 162, 170,
- 179, 183, 188, 193, 199, 207, 215, 220, 226, 238,
- 254, 257, 264, 269, 278, 281, 289, 292, 299, 303,
- 310, 314, 325, 329, 336, 340, 355, 362, 366, 370,
- 374, 381, 389, 393, 397
+ 0, 156, 156, 160, 161, 165, 173, 177, 183, 191,
+ 200, 204, 209, 214, 220, 228, 236, 241, 247, 259,
+ 271, 277, 285, 288, 295, 300, 309, 312, 320, 323,
+ 330, 334, 341, 345, 356, 360, 367, 371, 386, 393,
+ 397, 401, 405, 412, 420, 424, 428
};
#endif
@@ -561,10 +585,10 @@ static const yytype_uint16 yyrline[] =
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", "newcond", "look",
- "expr", "diff", "term", "factor", "close", "primary", 0
+ "ID", "CODE", "RANGE", "STRING", "CONFIG", "VALUE", "NUMBER", "SETUP",
+ "'='", "';'", "'/'", "'<'", "'>'", "':'", "','", "'|'", "'\\\\'", "'('",
+ "')'", "$accept", "spec", "decl", "rule", "cond", "clist", "newcond",
+ "look", "expr", "diff", "term", "factor", "close", "primary", 0
};
#endif
@@ -574,19 +598,19 @@ static const char *const yytname[] =
static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 61, 59, 47, 60, 62, 58,
- 44, 124, 92, 40, 41
+ 265, 266, 267, 268, 269, 61, 59, 47, 60, 62,
+ 58, 44, 124, 92, 40, 41
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 25, 26, 26, 26, 27, 27, 27, 27, 28,
- 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 0, 26, 27, 27, 27, 28, 28, 28, 28, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
- 34, 34, 35, 35, 36, 36, 36, 37, 37, 37,
- 37, 38, 38, 38, 38
+ 34, 34, 35, 35, 36, 36, 37, 37, 37, 38,
+ 38, 38, 38, 39, 39, 39, 39
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
@@ -594,9 +618,9 @@ static const yytype_uint8 yyr2[] =
{
0, 2, 0, 2, 2, 4, 4, 4, 4, 3,
7, 7, 6, 6, 7, 7, 6, 6, 3, 3,
- 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
+ 4, 4, 0, 1, 1, 3, 0, 3, 0, 2,
+ 1, 3, 1, 3, 1, 2, 1, 2, 2, 1,
+ 1, 2, 2, 1, 1, 1, 3
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -604,45 +628,45 @@ static const yytype_uint8 yyr2[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 2, 0, 1, 24, 41, 42, 43, 0, 20, 0,
- 4, 3, 26, 28, 30, 32, 34, 0, 24, 0,
- 0, 0, 0, 22, 0, 21, 41, 0, 0, 0,
- 0, 0, 33, 36, 37, 38, 35, 0, 19, 18,
- 0, 0, 0, 26, 26, 0, 44, 27, 29, 9,
- 31, 39, 40, 25, 5, 6, 7, 8, 24, 26,
- 24, 26, 23, 24, 0, 24, 24, 0, 24, 17,
- 16, 24, 0, 13, 12, 24, 0, 15, 14, 11,
- 10
+ 2, 0, 1, 26, 43, 44, 45, 0, 22, 22,
+ 0, 4, 3, 28, 30, 32, 34, 36, 0, 26,
+ 0, 0, 0, 0, 24, 0, 23, 0, 0, 43,
+ 0, 0, 0, 0, 0, 35, 38, 39, 40, 37,
+ 0, 19, 18, 0, 0, 0, 0, 0, 0, 28,
+ 28, 46, 29, 31, 9, 33, 41, 42, 27, 5,
+ 6, 7, 8, 20, 21, 25, 26, 28, 26, 28,
+ 26, 0, 26, 26, 0, 26, 17, 16, 26, 0,
+ 13, 12, 26, 0, 15, 14, 11, 10
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 1, 10, 11, 24, 25, 19, 30, 12, 13,
- 14, 15, 36, 16
+ -1, 1, 11, 12, 25, 26, 20, 33, 13, 14,
+ 15, 16, 39, 17
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -38
+#define YYPACT_NINF -42
static const yytype_int8 yypact[] =
{
- -38, 2, -38, -9, -11, -38, -38, 29, 51, 7,
- -38, -38, 10, 33, 7, -38, 57, 34, 49, 60,
- 7, 52, 53, -38, 54, 50, -38, 8, 7, 7,
- 61, 7, -38, -38, -38, -38, 62, 66, -38, -38,
- 20, 59, 63, 11, 11, 68, -38, 55, 33, -38,
- 7, -38, -38, -38, -38, -38, -38, -38, 14, 10,
- 30, 10, -38, 49, 69, 32, 49, 71, 40, -38,
- -38, 49, 72, -38, -38, 49, 73, -38, -38, -38,
- -38
+ -42, 7, -42, -5, -11, -42, -42, 8, 59, 60,
+ -4, -42, -42, 2, -12, -4, -42, 57, 27, 55,
+ 63, -4, 23, 53, -42, 54, 56, 61, 62, -42,
+ 33, -4, -4, 66, -4, -42, -42, -42, -42, 64,
+ 68, -42, -42, 16, 67, 69, 70, 71, 75, 20,
+ 20, -42, 65, -12, -42, -4, -42, -42, -42, -42,
+ -42, -42, -42, -42, -42, -42, 19, 2, 28, 2,
+ 55, 76, 30, 55, 78, 37, -42, -42, 55, 80,
+ -42, -42, 55, 81, -42, -42, -42, -42
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -38, -38, -38, -38, -38, -38, -18, -37, -5, 56,
- 58, -13, -38, -38
+ -42, -42, -42, -42, 82, -42, -19, -41, -9, 44,
+ 58, -13, -42, -42
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
@@ -652,43 +676,45 @@ static const yytype_int8 yypgoto[] =
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
- 38, 32, 2, 20, 27, 17, 58, 60, 3, 4,
- 18, 5, 6, 7, 26, 40, 5, 6, 26, 8,
- 5, 6, 65, 47, 68, 9, 28, 28, 17, 29,
- 9, 29, 46, 63, 9, 54, 55, 32, 59, 61,
- 64, 29, 67, 21, 17, 69, 17, 72, 73, 66,
- 76, 71, 37, 77, 17, 31, 22, 79, 23, 75,
- 33, 34, 35, 17, 41, 42, 51, 52, 39, 49,
- 45, 43, 44, 53, 56, 62, 29, 70, 57, 74,
- 78, 80, 0, 0, 0, 48, 0, 0, 0, 50
+ 41, 30, 35, 29, 21, 5, 6, 2, 66, 68,
+ 18, 34, 43, 3, 4, 19, 5, 6, 7, 31,
+ 10, 8, 52, 22, 32, 9, 72, 29, 75, 5,
+ 6, 10, 59, 60, 18, 44, 45, 31, 32, 70,
+ 67, 69, 35, 18, 10, 18, 40, 71, 73, 74,
+ 78, 76, 18, 79, 80, 32, 83, 82, 51, 84,
+ 36, 37, 38, 86, 23, 27, 24, 24, 56, 57,
+ 18, 42, 46, 47, 54, 58, 53, 48, 63, 64,
+ 49, 50, 65, 61, 77, 62, 81, 32, 85, 87,
+ 0, 28, 55
};
static const yytype_int8 yycheck[] =
{
- 18, 14, 0, 14, 9, 14, 43, 44, 6, 7,
- 19, 9, 10, 11, 7, 20, 9, 10, 7, 17,
- 9, 10, 59, 28, 61, 23, 16, 16, 14, 21,
- 23, 21, 24, 19, 23, 15, 16, 50, 43, 44,
- 58, 21, 60, 14, 14, 63, 14, 65, 66, 19,
- 68, 19, 18, 71, 14, 22, 5, 75, 7, 19,
- 3, 4, 5, 14, 12, 13, 4, 5, 8, 8,
- 20, 18, 18, 7, 15, 7, 21, 8, 15, 8,
- 8, 8, -1, -1, -1, 29, -1, -1, -1, 31
+ 19, 10, 15, 7, 15, 9, 10, 0, 49, 50,
+ 15, 23, 21, 6, 7, 20, 9, 10, 11, 17,
+ 24, 14, 31, 15, 22, 18, 67, 7, 69, 9,
+ 10, 24, 16, 17, 15, 12, 13, 17, 22, 20,
+ 49, 50, 55, 15, 24, 15, 19, 66, 20, 68,
+ 20, 70, 15, 72, 73, 22, 75, 20, 25, 78,
+ 3, 4, 5, 82, 5, 5, 7, 7, 4, 5,
+ 15, 8, 19, 19, 8, 7, 32, 21, 8, 8,
+ 19, 19, 7, 16, 8, 16, 8, 22, 8, 8,
+ -1, 9, 34
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 26, 0, 6, 7, 9, 10, 11, 17, 23,
- 27, 28, 33, 34, 35, 36, 38, 14, 19, 31,
- 14, 14, 5, 7, 29, 30, 7, 33, 16, 21,
- 32, 22, 36, 3, 4, 5, 37, 18, 31, 8,
- 33, 12, 13, 18, 18, 20, 24, 33, 34, 8,
- 35, 4, 5, 7, 15, 16, 15, 15, 32, 33,
- 32, 33, 7, 19, 31, 32, 19, 31, 32, 31,
- 8, 19, 31, 31, 8, 19, 31, 31, 8, 31,
- 8
+ 0, 27, 0, 6, 7, 9, 10, 11, 14, 18,
+ 24, 28, 29, 34, 35, 36, 37, 39, 15, 20,
+ 32, 15, 15, 5, 7, 30, 31, 5, 30, 7,
+ 34, 17, 22, 33, 23, 37, 3, 4, 5, 38,
+ 19, 32, 8, 34, 12, 13, 19, 19, 21, 19,
+ 19, 25, 34, 35, 8, 36, 4, 5, 7, 16,
+ 17, 16, 16, 8, 8, 7, 33, 34, 33, 34,
+ 20, 32, 33, 20, 32, 33, 32, 8, 20, 32,
+ 32, 8, 20, 32, 32, 8, 32, 8
};
#define yyerrok (yyerrstatus = 0)
@@ -1503,7 +1529,7 @@ yyreduce:
switch (yyn)
{
case 2:
-#line 135 "parser.y"
+#line 156 "parser.y"
{
accept = 0;
spec = NULL;
@@ -1511,7 +1537,7 @@ yyreduce:
break;
case 5:
-#line 145 "parser.y"
+#line 166 "parser.y"
{
if((yyvsp[(1) - (4)].symbol)->re)
{
@@ -1522,14 +1548,14 @@ yyreduce:
break;
case 6:
-#line 153 "parser.y"
+#line 174 "parser.y"
{
in->fatal("trailing contexts are not allowed in named definitions");
}
break;
case 7:
-#line 157 "parser.y"
+#line 178 "parser.y"
{
in->config(*(yyvsp[(1) - (4)].str), *(yyvsp[(3) - (4)].str));
delete (yyvsp[(1) - (4)].str);
@@ -1538,7 +1564,7 @@ yyreduce:
break;
case 8:
-#line 163 "parser.y"
+#line 184 "parser.y"
{
in->config(*(yyvsp[(1) - (4)].str), (yyvsp[(3) - (4)].number));
delete (yyvsp[(1) - (4)].str);
@@ -1546,7 +1572,7 @@ yyreduce:
break;
case 9:
-#line 171 "parser.y"
+#line 192 "parser.y"
{
if (cFlag)
{
@@ -1558,14 +1584,14 @@ yyreduce:
break;
case 10:
-#line 180 "parser.y"
+#line 201 "parser.y"
{
context_rule((yyvsp[(2) - (7)].clist), (yyvsp[(4) - (7)].regexp), (yyvsp[(5) - (7)].regexp), (yyvsp[(6) - (7)].str), (yyvsp[(7) - (7)].token));
}
break;
case 11:
-#line 184 "parser.y"
+#line 205 "parser.y"
{
assert((yyvsp[(7) - (7)].str));
context_rule((yyvsp[(2) - (7)].clist), (yyvsp[(4) - (7)].regexp), (yyvsp[(5) - (7)].regexp), (yyvsp[(7) - (7)].str), NULL);
@@ -1573,7 +1599,7 @@ yyreduce:
break;
case 12:
-#line 189 "parser.y"
+#line 210 "parser.y"
{
context_none((yyvsp[(2) - (6)].clist));
delete (yyvsp[(5) - (6)].str);
@@ -1581,7 +1607,7 @@ yyreduce:
break;
case 13:
-#line 194 "parser.y"
+#line 215 "parser.y"
{
assert((yyvsp[(6) - (6)].str));
context_none((yyvsp[(2) - (6)].clist));
@@ -1590,7 +1616,7 @@ yyreduce:
break;
case 14:
-#line 200 "parser.y"
+#line 221 "parser.y"
{
context_check(NULL);
Token *token = new Token((yyvsp[(7) - (7)].token), (yyvsp[(7) - (7)].token)->line, (yyvsp[(6) - (7)].str));
@@ -1601,7 +1627,7 @@ yyreduce:
break;
case 15:
-#line 208 "parser.y"
+#line 229 "parser.y"
{
assert((yyvsp[(7) - (7)].str));
context_check(NULL);
@@ -1612,7 +1638,7 @@ yyreduce:
break;
case 16:
-#line 216 "parser.y"
+#line 237 "parser.y"
{
context_none(NULL);
delete (yyvsp[(5) - (6)].str);
@@ -1620,7 +1646,7 @@ yyreduce:
break;
case 17:
-#line 221 "parser.y"
+#line 242 "parser.y"
{
assert((yyvsp[(6) - (6)].str));
context_none(NULL);
@@ -1629,7 +1655,7 @@ yyreduce:
break;
case 18:
-#line 227 "parser.y"
+#line 248 "parser.y"
{
context_check(NULL);
if (specNone)
@@ -1644,7 +1670,7 @@ yyreduce:
break;
case 19:
-#line 239 "parser.y"
+#line 260 "parser.y"
{
assert((yyvsp[(3) - (3)].str));
context_check(NULL);
@@ -1659,86 +1685,102 @@ yyreduce:
break;
case 20:
-#line 254 "parser.y"
+#line 272 "parser.y"
{
- in->fatal("unnamed condition not supported");
+ CondList *clist = new CondList();
+ clist->insert("*");
+ setup_rule(clist, (yyvsp[(4) - (4)].token));
}
break;
case 21:
-#line 258 "parser.y"
+#line 278 "parser.y"
{
- (yyval.clist) = (yyvsp[(1) - (1)].clist);
+ setup_rule((yyvsp[(2) - (4)].clist), (yyvsp[(4) - (4)].token));
}
break;
case 22:
-#line 265 "parser.y"
+#line 285 "parser.y"
+ {
+ in->fatal("unnamed condition not supported");
+ }
+ break;
+
+ case 23:
+#line 289 "parser.y"
+ {
+ (yyval.clist) = (yyvsp[(1) - (1)].clist);
+ }
+ break;
+
+ case 24:
+#line 296 "parser.y"
{
(yyval.clist) = new CondList();
(yyval.clist)->insert((yyvsp[(1) - (1)].symbol)->GetName().to_string());
}
break;
- case 23:
-#line 270 "parser.y"
+ case 25:
+#line 301 "parser.y"
{
(yyvsp[(1) - (3)].clist)->insert((yyvsp[(3) - (3)].symbol)->GetName().to_string());
(yyval.clist) = (yyvsp[(1) - (3)].clist);
}
break;
- case 24:
-#line 278 "parser.y"
+ case 26:
+#line 309 "parser.y"
{
(yyval.str) = NULL;
}
break;
- case 25:
-#line 282 "parser.y"
+ case 27:
+#line 313 "parser.y"
{
(yyval.str) = new Str((yyvsp[(3) - (3)].symbol)->GetName().to_string().c_str());
}
break;
- case 26:
-#line 289 "parser.y"
+ case 28:
+#line 320 "parser.y"
{
(yyval.regexp) = new NullOp;
}
break;
- case 27:
-#line 293 "parser.y"
+ case 29:
+#line 324 "parser.y"
{
(yyval.regexp) = (yyvsp[(2) - (2)].regexp);
}
break;
- case 28:
-#line 300 "parser.y"
+ case 30:
+#line 331 "parser.y"
{
(yyval.regexp) = (yyvsp[(1) - (1)].regexp);
}
break;
- case 29:
-#line 304 "parser.y"
+ case 31:
+#line 335 "parser.y"
{
(yyval.regexp) = mkAlt((yyvsp[(1) - (3)].regexp), (yyvsp[(3) - (3)].regexp));
}
break;
- case 30:
-#line 311 "parser.y"
+ case 32:
+#line 342 "parser.y"
{
(yyval.regexp) = (yyvsp[(1) - (1)].regexp);
}
break;
- case 31:
-#line 315 "parser.y"
+ case 33:
+#line 346 "parser.y"
{
(yyval.regexp) = mkDiff((yyvsp[(1) - (3)].regexp), (yyvsp[(3) - (3)].regexp));
if(!(yyval.regexp))
@@ -1748,29 +1790,29 @@ yyreduce:
}
break;
- case 32:
-#line 326 "parser.y"
+ case 34:
+#line 357 "parser.y"
{
(yyval.regexp) = (yyvsp[(1) - (1)].regexp);
}
break;
- case 33:
-#line 330 "parser.y"
+ case 35:
+#line 361 "parser.y"
{
(yyval.regexp) = new CatOp((yyvsp[(1) - (2)].regexp), (yyvsp[(2) - (2)].regexp));
}
break;
- case 34:
-#line 337 "parser.y"
+ case 36:
+#line 368 "parser.y"
{
(yyval.regexp) = (yyvsp[(1) - (1)].regexp);
}
break;
- case 35:
-#line 341 "parser.y"
+ case 37:
+#line 372 "parser.y"
{
switch((yyvsp[(2) - (2)].op))
{
@@ -1787,43 +1829,43 @@ yyreduce:
}
break;
- case 36:
-#line 356 "parser.y"
+ case 38:
+#line 387 "parser.y"
{
(yyval.regexp) = new CloseVOp((yyvsp[(1) - (2)].regexp), (yyvsp[(2) - (2)].extop).minsize, (yyvsp[(2) - (2)].extop).maxsize);
}
break;
- case 37:
-#line 363 "parser.y"
+ case 39:
+#line 394 "parser.y"
{
(yyval.op) = (yyvsp[(1) - (1)].op);
}
break;
- case 38:
-#line 367 "parser.y"
+ case 40:
+#line 398 "parser.y"
{
(yyval.op) = (yyvsp[(1) - (1)].op);
}
break;
- case 39:
-#line 371 "parser.y"
+ case 41:
+#line 402 "parser.y"
{
(yyval.op) = ((yyvsp[(1) - (2)].op) == (yyvsp[(2) - (2)].op)) ? (yyvsp[(1) - (2)].op) : '*';
}
break;
- case 40:
-#line 375 "parser.y"
+ case 42:
+#line 406 "parser.y"
{
(yyval.op) = ((yyvsp[(1) - (2)].op) == (yyvsp[(2) - (2)].op)) ? (yyvsp[(1) - (2)].op) : '*';
}
break;
- case 41:
-#line 382 "parser.y"
+ case 43:
+#line 413 "parser.y"
{
if(!(yyvsp[(1) - (1)].symbol)->re)
{
@@ -1833,22 +1875,22 @@ yyreduce:
}
break;
- case 42:
-#line 390 "parser.y"
+ case 44:
+#line 421 "parser.y"
{
(yyval.regexp) = (yyvsp[(1) - (1)].regexp);
}
break;
- case 43:
-#line 394 "parser.y"
+ case 45:
+#line 425 "parser.y"
{
(yyval.regexp) = (yyvsp[(1) - (1)].regexp);
}
break;
- case 44:
-#line 398 "parser.y"
+ case 46:
+#line 429 "parser.y"
{
(yyval.regexp) = (yyvsp[(2) - (3)].regexp);
}
@@ -1856,7 +1898,7 @@ yyreduce:
/* Line 1267 of yacc.c. */
-#line 1860 "parser.cc"
+#line 1902 "parser.cc"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -2070,7 +2112,7 @@ yyreturn:
}
-#line 403 "parser.y"
+#line 434 "parser.y"
extern "C" {
@@ -2101,20 +2143,21 @@ void parse(Scanner& i, std::ostream& o, std::ostream* h)
o << " */\n";
o << sourceFileInfo;
- while(i.echo())
+ while (i.echo())
{
bool bPrologBrace = false;
yyparse();
if (cFlag)
{
RegExpMap::iterator it;
+ StringMap::const_iterator itRuleSetup;
if (!specStar.empty())
{
- for(it = specMap.begin(); it != specMap.end(); ++it)
+ for (it = specMap.begin(); it != specMap.end(); ++it)
{
assert(it->second.second);
- for(RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp)
+ for (RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp)
{
it->second.second = mkAlt((*itOp)->copy(accept++), it->second.second);
}
@@ -2132,16 +2175,46 @@ void parse(Scanner& i, std::ostream& o, std::ostream* h)
{
// We reserved 0 for specNone but it is not present,
// so we can decrease all specs.
- for(it = specMap.begin(); it != specMap.end(); ++it)
+ for (it = specMap.begin(); it != specMap.end(); ++it)
{
it->second.first--;
}
}
size_t nCount = specMap.size();
- for(it = specMap.begin(); it != specMap.end(); ++it)
+
+ for (itRuleSetup = ruleSetupMap.begin(); itRuleSetup != ruleSetupMap.end(); ++itRuleSetup)
+ {
+ if (itRuleSetup->first != "*" && specMap.find(itRuleSetup->first) == specMap.end())
+ {
+ in->fatalf("Setup for non existing rule '%s' found", itRuleSetup->first.c_str());
+ }
+ }
+ if (nCount < (ruleSetupMap.find("*") == ruleSetupMap.end() ? ruleSetupMap.size() : ruleSetupMap.size()))
+ {
+ in->fatalf("Setup for all rules with '*' not possible when all rules are setup explicitly");
+ }
+ for (it = specMap.begin(); it != specMap.end(); ++it)
{
assert(it->second.second);
+
+ itRuleSetup = ruleSetupMap.find(it->first);
+ if (itRuleSetup != ruleSetupMap.end())
+ {
+ yySetupRule = itRuleSetup->second;
+ }
+ else
+ {
+ itRuleSetup = ruleSetupMap.find("*");
+ if (itRuleSetup != ruleSetupMap.end())
+ {
+ yySetupRule = itRuleSetup->second;
+ }
+ else
+ {
+ yySetupRule = "";
+ }
+ }
genCode(o, topIndent, it->second.second, &specMap, it->first, !--nCount, bPrologBrace);
}
if (h)
@@ -2153,7 +2226,7 @@ void parse(Scanner& i, std::ostream& o, std::ostream* h)
genTypes(typesInline, 0, specMap);
}
}
- else if(spec)
+ else if (spec)
{
genCode(o, topIndent, spec, NULL, "", 0, bPrologBrace);
}
diff --git a/re2c/bootstrap/scanner.cc b/re2c/bootstrap/scanner.cc
index 4a1bcfcc..38beb3cc 100644
--- a/re2c/bootstrap/scanner.cc
+++ b/re2c/bootstrap/scanner.cc
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.2.dev on Tue Jan 22 17:06:50 2008 */
+/* Generated by re2c 0.13.2.dev on Tue Feb 12 22:20:54 2008 */
/* $Id$ */
#include
#include
@@ -206,7 +206,7 @@ yy16:
yych = *++YYCURSOR;
if (yych != '!') goto yy13;
yych = *++YYCURSOR;
- switch(yych) {
+ switch (yych) {
case 'g': goto yy20;
case 'i': goto yy19;
case 'm': goto yy21;
@@ -500,10 +500,10 @@ yy71:
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= '/') {
- if (yych == ',') goto yy154;
+ if (yych == ',') goto yy156;
} else {
- if (yych <= '0') goto yy151;
- if (yych <= '9') goto yy152;
+ if (yych <= '0') goto yy153;
+ if (yych <= '9') goto yy154;
}
yy72:
{
@@ -513,7 +513,7 @@ yy72:
yy73:
YYCTXMARKER = YYCURSOR + 1;
++YYCURSOR;
- if ((yych = *YYCURSOR) == '=') goto yy147;
+ if ((yych = *YYCURSOR) == '=') goto yy149;
yy74:
{
std::ostringstream msg;
@@ -524,14 +524,14 @@ yy74:
}
yy75:
++YYCURSOR;
- if ((yych = *YYCURSOR) == '*') goto yy145;
+ if ((yych = *YYCURSOR) == '*') goto yy147;
yy76:
{
RETURN(*tok);
}
yy77:
++YYCURSOR;
- if ((yych = *YYCURSOR) == '/') goto yy143;
+ if ((yych = *YYCURSOR) == '/') goto yy145;
{
yylval.op = *tok;
RETURN(STAR);
@@ -539,7 +539,7 @@ yy77:
yy79:
yyaccept = 1;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych != 0x0A) goto yy139;
+ if (yych != 0x0A) goto yy141;
yy80:
{
fatal("unterminated string constant (missing \")");
@@ -547,7 +547,7 @@ yy80:
yy81:
yyaccept = 2;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych != 0x0A) goto yy134;
+ if (yych != 0x0A) goto yy136;
yy82:
{
fatal("unterminated string constant (missing ')");
@@ -556,8 +556,8 @@ yy83:
yyaccept = 3;
yych = *(YYMARKER = ++YYCURSOR);
if (yych == 0x0A) goto yy84;
- if (yych == '^') goto yy125;
- goto yy124;
+ if (yych == '^') goto yy127;
+ goto yy126;
yy84:
{
fatal("unterminated range (missing ])");
@@ -565,7 +565,8 @@ yy84:
yy85:
yyaccept = 4;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == '>') goto yy116;
+ if (yych == '!') goto yy116;
+ if (yych == '>') goto yy118;
goto yy76;
yy86:
yych = *++YYCURSOR;
@@ -687,7 +688,7 @@ yy109:
if (yyaccept <= 6) {
goto yy112;
} else {
- goto yy155;
+ goto yy157;
}
}
}
@@ -749,204 +750,209 @@ yy114:
}
}
yy116:
+ ++YYCURSOR;
+ {
+ RETURN(SETUP);
+ }
+yy118:
YYCTXMARKER = YYCURSOR + 1;
yych = *++YYCURSOR;
- goto yy118;
-yy117:
+ goto yy120;
+yy119:
++YYCURSOR;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
-yy118:
+yy120:
if (yybm[0+yych] & 8) {
- goto yy117;
+ goto yy119;
}
if (yych <= '<') {
- if (yych == ':') goto yy122;
+ if (yych == ':') goto yy124;
goto yy109;
} else {
- if (yych <= '=') goto yy121;
+ if (yych <= '=') goto yy123;
if (yych != '{') goto yy109;
}
-yy119:
+yy121:
++YYCURSOR;
YYCURSOR = YYCTXMARKER;
{
RETURN(NOCOND);
}
-yy121:
+yy123:
yych = *++YYCURSOR;
- if (yych == '>') goto yy119;
+ if (yych == '>') goto yy121;
goto yy109;
-yy122:
+yy124:
yych = *++YYCURSOR;
- if (yych == '=') goto yy119;
+ if (yych == '=') goto yy121;
goto yy109;
-yy123:
+yy125:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy124:
+yy126:
if (yybm[0+yych] & 16) {
- goto yy123;
+ goto yy125;
}
if (yych <= '[') goto yy109;
- if (yych <= '\\') goto yy127;
- goto yy128;
-yy125:
+ if (yych <= '\\') goto yy129;
+ goto yy130;
+yy127:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych <= '[') {
if (yych == 0x0A) goto yy109;
- goto yy125;
+ goto yy127;
} else {
- if (yych <= '\\') goto yy130;
- if (yych <= ']') goto yy131;
- goto yy125;
+ if (yych <= '\\') goto yy132;
+ if (yych <= ']') goto yy133;
+ goto yy127;
}
-yy127:
+yy129:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych == 0x0A) goto yy109;
- goto yy123;
-yy128:
+ goto yy125;
+yy130:
++YYCURSOR;
{
cur = cursor;
yylval.regexp = ranToRE(token());
return RANGE;
}
-yy130:
+yy132:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych == 0x0A) goto yy109;
- goto yy125;
-yy131:
+ goto yy127;
+yy133:
++YYCURSOR;
{
cur = cursor;
yylval.regexp = invToRE(token());
return RANGE;
}
-yy133:
+yy135:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy134:
+yy136:
if (yybm[0+yych] & 32) {
- goto yy133;
+ goto yy135;
}
if (yych <= '&') goto yy109;
- if (yych <= '\'') goto yy136;
+ if (yych <= '\'') goto yy138;
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych == 0x0A) goto yy109;
- goto yy133;
-yy136:
+ goto yy135;
+yy138:
++YYCURSOR;
{
cur = cursor;
yylval.regexp = strToCaseInsensitiveRE(token());
return STRING;
}
-yy138:
+yy140:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy139:
+yy141:
if (yybm[0+yych] & 64) {
- goto yy138;
+ goto yy140;
}
if (yych <= '!') goto yy109;
- if (yych <= '"') goto yy141;
+ if (yych <= '"') goto yy143;
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych == 0x0A) goto yy109;
- goto yy138;
-yy141:
+ goto yy140;
+yy143:
++YYCURSOR;
{
cur = cursor;
yylval.regexp = strToRE(token());
return STRING;
}
-yy143:
+yy145:
++YYCURSOR;
{
tok = cursor;
RETURN(0);
}
-yy145:
+yy147:
++YYCURSOR;
{
depth = 1;
goto comment;
}
-yy147:
+yy149:
++YYCURSOR;
- if ((yych = *YYCURSOR) == '>') goto yy149;
+ if ((yych = *YYCURSOR) == '>') goto yy151;
{
cur = cursor;
tok+= 2; /* skip ":=" */
depth = 0;
goto code;
}
-yy149:
+yy151:
++YYCURSOR;
YYCURSOR = YYCTXMARKER;
{
RETURN(*tok);
}
-yy151:
+yy153:
yych = *++YYCURSOR;
- if (yych == ',') goto yy165;
- goto yy153;
-yy152:
+ if (yych == ',') goto yy167;
+ goto yy155;
+yy154:
++YYCURSOR;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
-yy153:
+yy155:
if (yybm[0+yych] & 128) {
- goto yy152;
+ goto yy154;
}
- if (yych == ',') goto yy158;
- if (yych == '}') goto yy156;
+ if (yych == ',') goto yy160;
+ if (yych == '}') goto yy158;
goto yy109;
-yy154:
+yy156:
++YYCURSOR;
-yy155:
+yy157:
{
fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers");
}
-yy156:
+yy158:
++YYCURSOR;
{
yylval.extop.minsize = atoi((char *)tok+1);
yylval.extop.maxsize = atoi((char *)tok+1);
RETURN(CLOSESIZE);
}
-yy158:
+yy160:
yyaccept = 7;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych <= '/') goto yy155;
- if (yych <= '9') goto yy161;
- if (yych != '}') goto yy155;
+ if (yych <= '/') goto yy157;
+ if (yych <= '9') goto yy163;
+ if (yych != '}') goto yy157;
++YYCURSOR;
{
yylval.extop.minsize = atoi((char *)tok+1);
yylval.extop.maxsize = -1;
RETURN(CLOSESIZE);
}
-yy161:
+yy163:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych <= '/') goto yy109;
- if (yych <= '9') goto yy161;
+ if (yych <= '9') goto yy163;
if (yych != '}') goto yy109;
++YYCURSOR;
{
@@ -954,12 +960,12 @@ yy161:
yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
RETURN(CLOSESIZE);
}
-yy165:
+yy167:
yyaccept = 7;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych <= '/') goto yy155;
- if (yych <= '9') goto yy161;
- if (yych != '}') goto yy155;
+ if (yych <= '/') goto yy157;
+ if (yych <= '9') goto yy163;
+ if (yych != '}') goto yy157;
++YYCURSOR;
{
yylval.op = '*';
@@ -1010,20 +1016,20 @@ code:
yych = *YYCURSOR;
if (yych <= '&') {
if (yych <= 0x0A) {
- if (yych <= 0x00) goto yy176;
- if (yych <= 0x09) goto yy178;
- goto yy174;
+ if (yych <= 0x00) goto yy178;
+ if (yych <= 0x09) goto yy180;
+ goto yy176;
} else {
- if (yych == '"') goto yy180;
- goto yy178;
+ if (yych == '"') goto yy182;
+ goto yy180;
}
} else {
if (yych <= '{') {
- if (yych <= '\'') goto yy181;
- if (yych <= 'z') goto yy178;
- goto yy172;
+ if (yych <= '\'') goto yy183;
+ if (yych <= 'z') goto yy180;
+ goto yy174;
} else {
- if (yych != '}') goto yy178;
+ if (yych != '}') goto yy180;
}
}
++YYCURSOR;
@@ -1040,7 +1046,7 @@ code:
}
goto code;
}
-yy172:
+yy174:
++YYCURSOR;
{
if (depth == 0)
@@ -1053,17 +1059,17 @@ yy172:
}
goto code;
}
-yy174:
+yy176:
YYCTXMARKER = YYCURSOR + 1;
++YYCURSOR;
if ((yych = *YYCURSOR) <= 0x0C) {
- if (yych <= 0x08) goto yy175;
- if (yych <= 0x0A) goto yy189;
+ if (yych <= 0x08) goto yy177;
+ if (yych <= 0x0A) goto yy191;
} else {
- if (yych <= 0x0D) goto yy189;
- if (yych == ' ') goto yy189;
+ if (yych <= 0x0D) goto yy191;
+ if (yych == ' ') goto yy191;
}
-yy175:
+yy177:
{
if (depth == 0)
{
@@ -1084,7 +1090,7 @@ yy175:
cline++;
goto code;
}
-yy176:
+yy178:
++YYCURSOR;
{
if (cursor == eof)
@@ -1097,56 +1103,56 @@ yy176:
}
goto code;
}
-yy178:
+yy180:
++YYCURSOR;
-yy179:
+yy181:
{
goto code;
}
-yy180:
+yy182:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 0x0A) goto yy179;
- goto yy187;
-yy181:
+ if (yych == 0x0A) goto yy181;
+ goto yy189;
+yy183:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 0x0A) goto yy179;
- goto yy183;
-yy182:
+ if (yych == 0x0A) goto yy181;
+ goto yy185;
+yy184:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy183:
+yy185:
if (yybm[0+yych] & 64) {
- goto yy182;
+ goto yy184;
}
- if (yych <= '&') goto yy184;
- if (yych <= '\'') goto yy178;
- goto yy185;
-yy184:
+ if (yych <= '&') goto yy186;
+ if (yych <= '\'') goto yy180;
+ goto yy187;
+yy186:
YYCURSOR = YYMARKER;
- goto yy179;
-yy185:
+ goto yy181;
+yy187:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- if (yych == 0x0A) goto yy184;
- goto yy182;
-yy186:
+ if (yych == 0x0A) goto yy186;
+ goto yy184;
+yy188:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy187:
+yy189:
if (yybm[0+yych] & 128) {
- goto yy186;
+ goto yy188;
}
- if (yych <= '!') goto yy184;
- if (yych <= '"') goto yy178;
+ if (yych <= '!') goto yy186;
+ if (yych <= '"') goto yy180;
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- if (yych == 0x0A) goto yy184;
- goto yy186;
-yy189:
+ if (yych == 0x0A) goto yy186;
+ goto yy188;
+yy191:
++YYCURSOR;
YYCURSOR = YYCTXMARKER;
{
@@ -1172,17 +1178,17 @@ comment:
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych <= ')') {
- if (yych == 0x0A) goto yy196;
- goto yy198;
+ if (yych == 0x0A) goto yy198;
+ goto yy200;
} else {
- if (yych <= '*') goto yy193;
- if (yych == '/') goto yy195;
- goto yy198;
+ if (yych <= '*') goto yy195;
+ if (yych == '/') goto yy197;
+ goto yy200;
}
-yy193:
+yy195:
++YYCURSOR;
- if ((yych = *YYCURSOR) == '/') goto yy201;
-yy194:
+ if ((yych = *YYCURSOR) == '/') goto yy203;
+yy196:
{
if(cursor == eof)
{
@@ -1190,11 +1196,11 @@ yy194:
}
goto comment;
}
-yy195:
+yy197:
yych = *++YYCURSOR;
- if (yych == '*') goto yy199;
- goto yy194;
-yy196:
+ if (yych == '*') goto yy201;
+ goto yy196;
+yy198:
++YYCURSOR;
{
if(cursor == eof)
@@ -1205,17 +1211,17 @@ yy196:
cline++;
goto comment;
}
-yy198:
+yy200:
yych = *++YYCURSOR;
- goto yy194;
-yy199:
+ goto yy196;
+yy201:
++YYCURSOR;
{
++depth;
fatal("ambiguous /* found");
goto comment;
}
-yy201:
+yy203:
++YYCURSOR;
{
if(--depth == 0)
@@ -1271,52 +1277,52 @@ config:
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych <= 0x1F) {
- if (yych != 0x09) goto yy209;
+ if (yych != 0x09) goto yy211;
} else {
- if (yych <= ' ') goto yy205;
- if (yych == '=') goto yy207;
- goto yy209;
+ if (yych <= ' ') goto yy207;
+ if (yych == '=') goto yy209;
+ goto yy211;
}
-yy205:
+yy207:
++YYCURSOR;
yych = *YYCURSOR;
- goto yy214;
-yy206:
+ goto yy216;
+yy208:
{
goto config;
}
-yy207:
+yy209:
++YYCURSOR;
yych = *YYCURSOR;
- goto yy212;
-yy208:
+ goto yy214;
+yy210:
{
iscfg = 2;
cur = cursor;
RETURN('=');
}
-yy209:
+yy211:
++YYCURSOR;
{
fatal("missing '='");
}
-yy211:
+yy213:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy212:
+yy214:
if (yybm[0+yych] & 128) {
- goto yy211;
+ goto yy213;
}
- goto yy208;
-yy213:
+ goto yy210;
+yy215:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy214:
- if (yych == 0x09) goto yy213;
- if (yych == ' ') goto yy213;
- goto yy206;
+yy216:
+ if (yych == 0x09) goto yy215;
+ if (yych == ' ') goto yy215;
+ goto yy208;
}
@@ -1362,191 +1368,191 @@ value:
yych = *YYCURSOR;
if (yych <= '&') {
if (yych <= 0x0D) {
- if (yych <= 0x08) goto yy223;
- if (yych <= 0x0A) goto yy217;
- if (yych <= 0x0C) goto yy223;
+ if (yych <= 0x08) goto yy225;
+ if (yych <= 0x0A) goto yy219;
+ if (yych <= 0x0C) goto yy225;
} else {
if (yych <= ' ') {
- if (yych <= 0x1F) goto yy223;
+ if (yych <= 0x1F) goto yy225;
} else {
- if (yych == '"') goto yy225;
- goto yy223;
+ if (yych == '"') goto yy227;
+ goto yy225;
}
}
} else {
if (yych <= '/') {
- if (yych <= '\'') goto yy227;
- if (yych == '-') goto yy220;
- goto yy223;
+ if (yych <= '\'') goto yy229;
+ if (yych == '-') goto yy222;
+ goto yy225;
} else {
if (yych <= '9') {
- if (yych <= '0') goto yy218;
- goto yy221;
+ if (yych <= '0') goto yy220;
+ goto yy223;
} else {
- if (yych != ';') goto yy223;
+ if (yych != ';') goto yy225;
}
}
}
-yy217:
+yy219:
{
cur = cursor;
yylval.str = new Str(token());
iscfg = 0;
return VALUE;
}
-yy218:
+yy220:
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 8) {
- goto yy223;
+ goto yy225;
}
-yy219:
+yy221:
{
cur = cursor;
yylval.number = atoi(token().to_string().c_str());
iscfg = 0;
return NUMBER;
}
-yy220:
+yy222:
yych = *++YYCURSOR;
- if (yych <= '0') goto yy224;
- if (yych >= ':') goto yy224;
-yy221:
+ if (yych <= '0') goto yy226;
+ if (yych >= ':') goto yy226;
+yy223:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 4) {
- goto yy221;
+ goto yy223;
}
if (yych <= 0x0D) {
- if (yych <= 0x08) goto yy223;
- if (yych <= 0x0A) goto yy219;
- if (yych >= 0x0D) goto yy219;
+ if (yych <= 0x08) goto yy225;
+ if (yych <= 0x0A) goto yy221;
+ if (yych >= 0x0D) goto yy221;
} else {
if (yych <= ' ') {
- if (yych >= ' ') goto yy219;
+ if (yych >= ' ') goto yy221;
} else {
- if (yych == ';') goto yy219;
+ if (yych == ';') goto yy221;
}
}
-yy223:
+yy225:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy224:
+yy226:
if (yybm[0+yych] & 8) {
- goto yy223;
+ goto yy225;
}
- goto yy217;
-yy225:
+ goto yy219;
+yy227:
YYMARKER = ++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 16) {
- goto yy225;
+ goto yy227;
}
if (yych <= '!') {
- if (yych == 0x0A) goto yy217;
- goto yy235;
- } else {
- if (yych <= '"') goto yy223;
- if (yych <= '[') goto yy235;
+ if (yych == 0x0A) goto yy219;
goto yy237;
+ } else {
+ if (yych <= '"') goto yy225;
+ if (yych <= '[') goto yy237;
+ goto yy239;
}
-yy227:
+yy229:
YYMARKER = ++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 32) {
- goto yy227;
+ goto yy229;
}
if (yych <= '&') {
- if (yych == 0x0A) goto yy217;
+ if (yych == 0x0A) goto yy219;
} else {
- if (yych <= '\'') goto yy223;
- if (yych >= '\\') goto yy232;
+ if (yych <= '\'') goto yy225;
+ if (yych >= '\\') goto yy234;
}
-yy229:
+yy231:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 64) {
- goto yy229;
+ goto yy231;
}
- if (yych <= '&') goto yy231;
- if (yych <= '\'') goto yy233;
- goto yy234;
-yy231:
+ if (yych <= '&') goto yy233;
+ if (yych <= '\'') goto yy235;
+ goto yy236;
+yy233:
YYCURSOR = YYMARKER;
- goto yy217;
-yy232:
+ goto yy219;
+yy234:
YYMARKER = ++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych <= 0x0D) {
if (yych <= 0x09) {
- if (yych <= 0x08) goto yy227;
- goto yy229;
+ if (yych <= 0x08) goto yy229;
+ goto yy231;
} else {
- if (yych <= 0x0A) goto yy217;
- if (yych <= 0x0C) goto yy227;
- goto yy229;
+ if (yych <= 0x0A) goto yy219;
+ if (yych <= 0x0C) goto yy229;
+ goto yy231;
}
} else {
if (yych <= ' ') {
- if (yych <= 0x1F) goto yy227;
- goto yy229;
+ if (yych <= 0x1F) goto yy229;
+ goto yy231;
} else {
- if (yych == ';') goto yy229;
- goto yy227;
+ if (yych == ';') goto yy231;
+ goto yy229;
}
}
-yy233:
+yy235:
yych = *++YYCURSOR;
- goto yy217;
-yy234:
+ goto yy219;
+yy236:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- if (yych == 0x0A) goto yy231;
- goto yy229;
-yy235:
+ if (yych == 0x0A) goto yy233;
+ goto yy231;
+yy237:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy235;
+ goto yy237;
}
- if (yych <= '!') goto yy231;
- if (yych <= '"') goto yy233;
- goto yy238;
-yy237:
+ if (yych <= '!') goto yy233;
+ if (yych <= '"') goto yy235;
+ goto yy240;
+yy239:
YYMARKER = ++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych <= 0x0D) {
if (yych <= 0x09) {
- if (yych <= 0x08) goto yy225;
- goto yy235;
+ if (yych <= 0x08) goto yy227;
+ goto yy237;
} else {
- if (yych <= 0x0A) goto yy217;
- if (yych <= 0x0C) goto yy225;
- goto yy235;
+ if (yych <= 0x0A) goto yy219;
+ if (yych <= 0x0C) goto yy227;
+ goto yy237;
}
} else {
if (yych <= ' ') {
- if (yych <= 0x1F) goto yy225;
- goto yy235;
+ if (yych <= 0x1F) goto yy227;
+ goto yy237;
} else {
- if (yych == ';') goto yy235;
- goto yy225;
+ if (yych == ';') goto yy237;
+ goto yy227;
}
}
-yy238:
+yy240:
++YYCURSOR;
if (YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- if (yych == 0x0A) goto yy231;
- goto yy235;
+ if (yych == 0x0A) goto yy233;
+ goto yy237;
}
}
diff --git a/re2c/bootstrap/y.tab.h b/re2c/bootstrap/y.tab.h
index 4d3b909a..54548369 100644
--- a/re2c/bootstrap/y.tab.h
+++ b/re2c/bootstrap/y.tab.h
@@ -49,7 +49,8 @@
STRING = 265,
CONFIG = 266,
VALUE = 267,
- NUMBER = 268
+ NUMBER = 268,
+ SETUP = 269
};
#endif
/* Tokens. */
@@ -64,13 +65,14 @@
#define CONFIG 266
#define VALUE 267
#define NUMBER 268
+#define SETUP 269
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 106 "parser.y"
+#line 127 "parser.y"
{
re2c::Symbol *symbol;
re2c::RegExp *regexp;
@@ -82,7 +84,7 @@ typedef union YYSTYPE
re2c::CondList *clist;
}
/* Line 1489 of yacc.c. */
-#line 86 "y.tab.h"
+#line 88 "y.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
diff --git a/re2c/code.cc b/re2c/code.cc
index 8fbc0948..aebe97d3 100644
--- a/re2c/code.cc
+++ b/re2c/code.cc
@@ -684,6 +684,11 @@ void Rule::emit(std::ostream &o, uint ind, bool &, const std::string& condName)
RuleLine rl(*rule);
+ if (!yySetupRule.empty() && !rule->code->autogen)
+ {
+ o << indent(ind) << yySetupRule << "\n";
+ }
+
o << file_info(sourceFileInfo, &rl);
o << indent(ind);
if (rule->code->autogen)
diff --git a/re2c/globals.h b/re2c/globals.h
index fd04656d..4f825ac4 100644
--- a/re2c/globals.h
+++ b/re2c/globals.h
@@ -51,6 +51,7 @@ extern std::string yychConversion;
extern std::string yyFillLength;
extern std::string yySetConditionParam;
extern std::string yySetStateParam;
+extern std::string yySetupRule;
extern uint maxFill;
extern uint next_label;
extern uint cGotoThreshold;
diff --git a/re2c/htdocs/index.html b/re2c/htdocs/index.html
index 53184426..70294dc8 100755
--- a/re2c/htdocs/index.html
+++ b/re2c/htdocs/index.html
@@ -81,9 +81,10 @@ fixes which were incorporated.
Changelog
2007-??-??: 0.13.2
-Added support for '=>' style rules.
+Added support for '<!...>' to enable rule setup.
+Added support for '=>' style rules.
Added support for ':=' style rules.
-Added support for ':=>' style rules.
+Added support for ':=>' style rules.
Added re2c:cond:divider and re2c:con:goto inplace configuration.
Fixed code generation to emit space after 'if'.
diff --git a/re2c/htdocs/manual.html b/re2c/htdocs/manual.html
index 8ab6bd2a..e8b1091a 100755
--- a/re2c/htdocs/manual.html
+++ b/re2c/htdocs/manual.html
@@ -313,7 +313,8 @@ rules can use ':=>' as a shortcut to automatically generate code that not only
sets the new condition state but also continues execution with the new state. A
shortcut rule should not be used in a loop where there is code between the start
of the loop and the re2c block unless re2c:cond:goto is changed
-to 'continue;'.
+to 'continue;'. If code is necessary before all rule (though not simple
+jumps) you can doso by using <! pseudo-rules.
- <condition-list> regular-expression { C/C++ code }
@@ -331,6 +332,10 @@ to 'continue;'.
- <> => condition { C/C++ code }
- <> => condition := C/C++ code
- <> :=> condition
+- <!condition-list> { C/C++ code }
+- <!condition-list> := C/C++ code
+- <!*> { C/C++ code }
+- <!*> := C/C++ code
Named definitions are of the form:
diff --git a/re2c/main.cc b/re2c/main.cc
index 9842d7e9..c7554516 100644
--- a/re2c/main.cc
+++ b/re2c/main.cc
@@ -67,6 +67,7 @@ std::string yychConversion("");
std::string yyFillLength("@@");
std::string yySetConditionParam("@@");
std::string yySetStateParam("@@");
+std::string yySetupRule("");
uint maxFill = 1;
uint next_label = 0;
uint cGotoThreshold = 9;
diff --git a/re2c/parser.y b/re2c/parser.y
index fae174f7..aecc9bbc 100644
--- a/re2c/parser.y
+++ b/re2c/parser.y
@@ -10,6 +10,7 @@
#include
#include
#include
+#include
#include "globals.h"
#include "parser.h"
@@ -31,6 +32,7 @@ static re2c::RegExpMap specMap;
static RegExp *spec, *specNone = NULL;
static RuleOpList specStar;
static Scanner *in = NULL;
+static StringMap ruleSetupMap;
/* Bison version 1.875 emits a definition that is not working
* with several g++ version. Hence we disable it here.
@@ -99,6 +101,25 @@ void context_rule(CondList *clist, RegExp *expr, RegExp *look, Str *newcond, Tok
delete code;
}
+void setup_rule(CondList *clist, Token *code)
+{
+ assert(clist);
+ assert(code);
+ context_check(clist);
+ if (bFirstPass) {
+ for(CondList::const_iterator it = clist->begin(); it != clist->end(); ++it)
+ {
+ if (ruleSetupMap.find(*it) != ruleSetupMap.end())
+ {
+ in->fatalf("code to setup rule '%s' is already defined", it->c_str());
+ }
+ ruleSetupMap[*it] = code->text.to_string();
+ }
+ }
+ delete clist;
+ delete code;
+}
+
%}
%start spec
@@ -115,9 +136,9 @@ void context_rule(CondList *clist, RegExp *expr, RegExp *look, Str *newcond, Tok
};
%token CLOSESIZE CLOSE STAR NOCOND ID CODE RANGE STRING
-%token CONFIG VALUE NUMBER
+%token CONFIG VALUE NUMBER SETUP
-%type CLOSE STAR
+%type CLOSE STAR SETUP
%type close
%type CLOSESIZE
%type ID
@@ -247,6 +268,16 @@ rule:
delete $3;
$$ = specNone = new RuleOp(new NullOp(), new NullOp(), token, accept++);
}
+ | SETUP STAR '>' CODE
+ {
+ CondList *clist = new CondList();
+ clist->insert("*");
+ setup_rule(clist, $4);
+ }
+ | SETUP cond '>' CODE
+ {
+ setup_rule($2, $4);
+ }
;
cond:
@@ -430,20 +461,21 @@ void parse(Scanner& i, std::ostream& o, std::ostream* h)
o << " */\n";
o << sourceFileInfo;
- while(i.echo())
+ while (i.echo())
{
bool bPrologBrace = false;
yyparse();
if (cFlag)
{
RegExpMap::iterator it;
+ StringMap::const_iterator itRuleSetup;
if (!specStar.empty())
{
- for(it = specMap.begin(); it != specMap.end(); ++it)
+ for (it = specMap.begin(); it != specMap.end(); ++it)
{
assert(it->second.second);
- for(RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp)
+ for (RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp)
{
it->second.second = mkAlt((*itOp)->copy(accept++), it->second.second);
}
@@ -461,16 +493,46 @@ void parse(Scanner& i, std::ostream& o, std::ostream* h)
{
// We reserved 0 for specNone but it is not present,
// so we can decrease all specs.
- for(it = specMap.begin(); it != specMap.end(); ++it)
+ for (it = specMap.begin(); it != specMap.end(); ++it)
{
it->second.first--;
}
}
size_t nCount = specMap.size();
- for(it = specMap.begin(); it != specMap.end(); ++it)
+
+ for (itRuleSetup = ruleSetupMap.begin(); itRuleSetup != ruleSetupMap.end(); ++itRuleSetup)
+ {
+ if (itRuleSetup->first != "*" && specMap.find(itRuleSetup->first) == specMap.end())
+ {
+ in->fatalf("Setup for non existing rule '%s' found", itRuleSetup->first.c_str());
+ }
+ }
+ if (nCount < (ruleSetupMap.find("*") == ruleSetupMap.end() ? ruleSetupMap.size() : ruleSetupMap.size()))
+ {
+ in->fatalf("Setup for all rules with '*' not possible when all rules are setup explicitly");
+ }
+ for (it = specMap.begin(); it != specMap.end(); ++it)
{
assert(it->second.second);
+
+ itRuleSetup = ruleSetupMap.find(it->first);
+ if (itRuleSetup != ruleSetupMap.end())
+ {
+ yySetupRule = itRuleSetup->second;
+ }
+ else
+ {
+ itRuleSetup = ruleSetupMap.find("*");
+ if (itRuleSetup != ruleSetupMap.end())
+ {
+ yySetupRule = itRuleSetup->second;
+ }
+ else
+ {
+ yySetupRule = "";
+ }
+ }
genCode(o, topIndent, it->second.second, &specMap, it->first, !--nCount, bPrologBrace);
}
if (h)
@@ -482,7 +544,7 @@ void parse(Scanner& i, std::ostream& o, std::ostream* h)
genTypes(typesInline, 0, specMap);
}
}
- else if(spec)
+ else if (spec)
{
genCode(o, topIndent, spec, NULL, "", 0, bPrologBrace);
}
diff --git a/re2c/re.h b/re2c/re.h
index a8361879..8bfd3297 100644
--- a/re2c/re.h
+++ b/re2c/re.h
@@ -496,6 +496,7 @@ typedef std::pair NRegExp;
typedef std::map RegExpMap;
typedef std::vector RegExpIndices;
typedef std::list RuleOpList;
+typedef std::map StringMap;
extern void genCode(std::ostream&, uint&, RegExp*, const RegExpMap*, const std::string&, bool, bool&);
extern void genGetStateGoto(std::ostream&, uint&, uint);
diff --git a/re2c/re2c.1.in b/re2c/re2c.1.in
index d386f8dd..d05bad07 100644
--- a/re2c/re2c.1.in
+++ b/re2c/re2c.1.in
@@ -355,7 +355,8 @@ rules can use ':=>' as a shortcut to automatically generate code that not only
sets the new condition state but also continues execution with the new state. A
shortcut rule should not be used in a loop where there is code between the start
of the loop and the \*(re block unless \fIre2c:cond:goto\fP is changed
-to '\fIcontinue;\fP'.
+to '\fIcontinue;\fP'. If code is necessary before all rule (though not simple
+jumps) you can doso by using \fP \fI\*(rx\fP \fC{\fP \fIC/C++ code\fP \fC}\fP
@@ -387,6 +388,14 @@ to '\fIcontinue;\fP'.
\fC<>\fP \fC=>\fP \fP\fIcondition\fP \fC:=\fP \fIC/C++ code\fP
.P
\fC<>\fP \fC:=>\fP \fP\fIcondition\fP
+.P
+\fC\fP \fC{\fP \fIC/C++ code\fP \fC}\fP
+.P
+\fC\fP \fC:=\fP \fIC/C++ code\fP
+.P
+\fC\fP \fC{\fP \fIC/C++ code\fP \fC}\fP
+.P
+\fC\fP \fC:=\fP \fIC/C++ code\fP
.RE
.LP
Named definitions are of the form:
diff --git a/re2c/scanner.re b/re2c/scanner.re
index 07f6b599..4745f71c 100644
--- a/re2c/scanner.re
+++ b/re2c/scanner.re
@@ -307,6 +307,9 @@ scan:
"<>" / (ws* ("{" | "=>" | ":=")) {
RETURN(NOCOND);
}
+ ",()|=;/\\] {
RETURN(*tok);
}
diff --git a/re2c/test/cond_error_09.c.c b/re2c/test/cond_error_09.c.c
new file mode 100755
index 00000000..dde066b3
--- /dev/null
+++ b/re2c/test/cond_error_09.c.c
@@ -0,0 +1 @@
+re2c: error: line 6, column 6: code to setup rule 'a' is already defined
diff --git a/re2c/test/cond_error_09.c.re b/re2c/test/cond_error_09.c.re
new file mode 100755
index 00000000..e54f7cbb
--- /dev/null
+++ b/re2c/test/cond_error_09.c.re
@@ -0,0 +1,8 @@
+/*!re2c
+
+"a" { return 1; }
+"b" { return 2; }
+ { printf("foo"); }
+ := printf("bar");
+
+*/
diff --git a/re2c/test/cond_error_10.c.c b/re2c/test/cond_error_10.c.c
new file mode 100755
index 00000000..1cb5763d
--- /dev/null
+++ b/re2c/test/cond_error_10.c.c
@@ -0,0 +1 @@
+re2c: error: line 8, column 1: Setup for non existing rule 'c' found
diff --git a/re2c/test/cond_error_10.c.re b/re2c/test/cond_error_10.c.re
new file mode 100755
index 00000000..32af77ba
--- /dev/null
+++ b/re2c/test/cond_error_10.c.re
@@ -0,0 +1,8 @@
+/*!re2c
+
+"a" { return 1; }
+"b" { return 2; }
+ { printf("foo"); }
+ := printf("bar");
+
+*/
diff --git a/re2c/test/cond_error_11.c.c b/re2c/test/cond_error_11.c.c
new file mode 100755
index 00000000..45a51bb7
--- /dev/null
+++ b/re2c/test/cond_error_11.c.c
@@ -0,0 +1 @@
+re2c: error: line 9, column 1: Setup for all rules with '*' not possible when all rules are setup explicitly
diff --git a/re2c/test/cond_error_11.c.re b/re2c/test/cond_error_11.c.re
new file mode 100755
index 00000000..1f99cd4f
--- /dev/null
+++ b/re2c/test/cond_error_11.c.re
@@ -0,0 +1,9 @@
+/*!re2c
+
+"a" { return 1; }
+"b" { return 2; }
+ { printf("foo"); }
+ := printf("bar");
+ := printf("baz");
+
+*/
diff --git a/re2c/test/condition_15.csif.c b/re2c/test/condition_15.csif.c
new file mode 100755
index 00000000..acaf5fa5
--- /dev/null
+++ b/re2c/test/condition_15.csif.c
@@ -0,0 +1,383 @@
+/* Generated by re2c */
+#include
+#include
+#include
+
+#define BSIZE 8192
+
+
+enum ScanContition {
+ EStateNormal,
+ EStateComment,
+ 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;
+
+size_t fill(Scanner *s, size_t len)
+{
+ size_t got = ~0, cnt;
+
+ if (!s->eof && s->lim - s->tok < len)
+ {
+ if (s->tok > s->buffer)
+ {
+ cnt = s->tok - s->buffer;
+ memcpy(s->buffer, s->tok, s->lim - s->tok);
+ s->tok -= cnt;
+ s->cur -= cnt;
+ s->lim -= cnt;
+ cnt = &s->buffer[BSIZE] - s->lim;
+ }
+ else
+ {
+ cnt = BSIZE;
+ }
+ if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+ {
+ s->eof = &s->lim[got];
+ }
+ s->lim += got;
+ }
+ if (s->eof && s->cur + len > s->eof)
+ {
+ return ~0; /* not enough input data */
+ }
+ return got;
+}
+
+size_t init(Scanner *s)
+{
+ s->cur = s->tok = s->lim = s->buffer;
+ s->eof = 0;
+ s->cond = EStateNormal;
+ s->state = -1;
+
+ return fill(s, 0);
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+ while(len-- > 0)
+ {
+ fputc(*s++, stream);
+ }
+}
+
+void scan(Scanner *s)
+{
+ 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;
+ }
+ for(;;)
+ {
+ s->tok = s->cur;
+
+
+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:
+ continue;
+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:
+ fprintf(stderr, "Normal\n");
+ fputc(s->cur[-1], 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;
+ fprintf(stderr, "Normal\n");
+ fputc(s->cur[-1], 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;
+ fprintf(stderr, "Normal\n");
+ fputl("'\"'", 3, stdout);
+ continue;
+yy22:
+ ++s->cur;
+ s->cond = EStateSkiptoeol;
+ continue;
+yy24:
+ ++s->cur;
+ s->cond = EStateComment;
+ continue;
+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;
+ fprintf(stderr, "Normal\n");
+ fputc('[', stdout);
+ continue;
+yy29:
+ ++s->cur;
+ fprintf(stderr, "Normal\n");
+ fputc(']', stdout);
+ continue;
+yy31:
+ ++s->cur;
+ fprintf(stderr, "Normal\n");
+ fputc('{', stdout);
+ continue;
+yy33:
+ ++s->cur;
+ fprintf(stderr, "Normal\n");
+ fputc('}', stdout);
+ continue;
+yy35:
+ ++s->cur;
+ fprintf(stderr, "Normal\n");
+ fputc('#', stdout);
+ continue;
+yy37:
+ ++s->cur;
+ fprintf(stderr, "Normal\n");
+ fputc('\\', stdout);
+ continue;
+yy39:
+ ++s->cur;
+ fprintf(stderr, "Normal\n");
+ fputc('^', stdout);
+ continue;
+yy41:
+ ++s->cur;
+ fprintf(stderr, "Normal\n");
+ fputc('|', stdout);
+ continue;
+yy43:
+ ++s->cur;
+ fprintf(stderr, "Normal\n");
+ 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 <= 0x0D) {
+ if (s->yych == 0x0A) goto yy51;
+ if (s->yych <= 0x0C) goto yy53;
+ goto yy50;
+ } else {
+ if (s->yych <= '?') {
+ if (s->yych <= '>') goto yy53;
+ } else {
+ if (s->yych == '\\') goto yy49;
+ goto yy53;
+ }
+ }
+ s->yych = *(s->tok = ++s->cur);
+ if (s->yych == '?') goto yy60;
+yy48:
+ continue;
+yy49:
+ s->yych = *(s->tok = ++s->cur);
+ if (s->yych == 0x0A) goto yy58;
+ if (s->yych == 0x0D) goto yy56;
+ goto yy48;
+yy50:
+ s->yych = *++s->cur;
+ if (s->yych == 0x0A) goto yy54;
+ goto yy48;
+yy51:
+ ++s->cur;
+ s->cond = EStateNormal;
+ fprintf(stderr, "Comment\n");
+ fputc('\n', stdout);
+ continue;
+yy53:
+ s->yych = *++s->cur;
+ goto yy48;
+yy54:
+ ++s->cur;
+ s->cond = EStateNormal;
+ fprintf(stderr, "Comment\n");
+ fputc('\r', stdout);
+ fputc('\n', stdout);
+ continue;
+yy56:
+ s->yych = *++s->cur;
+ if (s->yych == 0x0A) goto yy58;
+yy57:
+ s->cur = s->tok;
+ goto yy48;
+yy58:
+ ++s->cur;
+ continue;
+yy60:
+ s->yych = *++s->cur;
+ if (s->yych != '/') goto yy57;
+ s->yych = *++s->cur;
+ if (s->yych == 0x0A) goto yy63;
+ if (s->yych != 0x0D) goto yy57;
+ s->yych = *++s->cur;
+ if (s->yych != 0x0A) goto yy57;
+yy63:
+ ++s->cur;
+ continue;
+/* *********************************** */
+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 yy69;
+ if (s->yych != '\\') goto yy71;
+ ++s->cur;
+ if ((s->yych = *s->cur) != 0x0A) goto yy72;
+yy68:
+ fprintf(stderr, "Normal\n");
+ fputc(s->cur[-1], stdout);
+ continue;
+yy69:
+ ++s->cur;
+ s->cond = EStateNormal;
+ fprintf(stderr, "Normal\n");
+ fputc(s->cur[-1], stdout);
+ continue;
+yy71:
+ s->yych = *++s->cur;
+ goto yy68;
+yy72:
+ ++s->cur;
+ fprintf(stderr, "Normal\n");
+ fputl((const char*)s->cur-2, 2, stdout);
+ continue;
+
+ }
+}
+
+int main(int argc, char **argv)
+{
+ Scanner in;
+
+ if (argc != 2)
+ {
+ fprintf(stderr, "%s \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;
+ }
+
+ if (init(&in) > 0)
+ {
+ scan(&in);
+ }
+
+ if (in.fp != stdin)
+ {
+ fclose(in.fp);
+ }
+ return 0;
+}
diff --git a/re2c/test/condition_15.csif.re b/re2c/test/condition_15.csif.re
new file mode 100755
index 00000000..323b3e8c
--- /dev/null
+++ b/re2c/test/condition_15.csif.re
@@ -0,0 +1,200 @@
+#include
+#include
+#include
+
+#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;
+
+size_t fill(Scanner *s, size_t len)
+{
+ size_t got = ~0, cnt;
+
+ if (!s->eof && s->lim - s->tok < len)
+ {
+ if (s->tok > s->buffer)
+ {
+ cnt = s->tok - s->buffer;
+ memcpy(s->buffer, s->tok, s->lim - s->tok);
+ s->tok -= cnt;
+ s->cur -= cnt;
+ s->lim -= cnt;
+ cnt = &s->buffer[BSIZE] - s->lim;
+ }
+ else
+ {
+ cnt = BSIZE;
+ }
+ if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+ {
+ s->eof = &s->lim[got];
+ }
+ s->lim += got;
+ }
+ if (s->eof && s->cur + len > s->eof)
+ {
+ return ~0; /* not enough input data */
+ }
+ return got;
+}
+
+size_t init(Scanner *s)
+{
+ s->cur = s->tok = s->lim = s->buffer;
+ s->eof = 0;
+ s->cond = EStateNormal;
+ s->state = -1;
+
+ return fill(s, 0);
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+ while(len-- > 0)
+ {
+ fputc(*s++, stream);
+ }
+}
+
+void scan(Scanner *s)
+{
+ s->tok = s->cur;
+/*!re2c
+re2c:define:YYGETSTATE = "s->state";
+re2c:define:YYGETSTATE:naked = 1;
+re2c:define:YYCONDTYPE = ScanContition;
+re2c:indent:top = 1;
+re2c:cond:goto = "continue;";
+*/
+/*!getstate:re2c */
+ 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:naked = 1;
+re2c:define:YYFILL = "if (fill(s, #) == ~0) break;";
+re2c:define:YYSETSTATE@state = #;
+re2c:define:YYSETSTATE = "s->state = #;";
+re2c:define:YYSETCONDITION = "s->cond = #;";
+re2c:define:YYSETCONDITION@cond = #;
+re2c:define:YYGETCONDITION = s->cond;
+re2c:define:YYGETCONDITION:naked = 1;
+re2c:variable:yych = s->yych;
+re2c:yych:emit = 0;
+re2c:indent:top = 2;
+re2c:condenumprefix = EState;
+
+ "??(" :=
+ fputc('[', stdout);
+ continue;
+ "??)" :=
+ fputc(']', stdout);
+ continue;
+ "??<" :=
+ fputc('{', stdout);
+ continue;
+ "??>" :=
+ fputc('}', stdout);
+ continue;
+ "??=" :=
+ fputc('#', stdout);
+ continue;
+ "??/" :=
+ fputc('\\', stdout);
+ continue;
+ "??'" :=
+ fputc('^', stdout);
+ continue;
+ "??!" :=
+ fputc('|', stdout);
+ continue;
+ "??-" :=
+ fputc('~', stdout);
+ continue;
+ "/*" :=> Comment
+ "//" :=> Skiptoeol
+ "'\\\"'"|"'\"'" :=
+ fputl("'\"'", 3, stdout);
+ continue;
+ '"' => String :=
+ fputc(s->cur[-1], stdout);
+ continue;
+ [^] :=
+ fputc(s->cur[-1], stdout);
+ continue;
+ "*" "/" :=> Normal
+ [^] :=> Comment
+ "??/" "\r"? "\n" :=> Skiptoeol
+ "\\" "\r"? "\n" :=> Skiptoeol
+ "\r" "\n" => Normal :=
+ fputc('\r', stdout);
+ fputc('\n', stdout);
+ continue;
+ "\n" => Normal :=
+ fputc('\n', stdout);
+ continue;
+ [^] :=> Skiptoeol
+ '\\' . :=
+ fputl((const char*)s->cur-2, 2, stdout);
+ continue;
+ '"' => Normal :=
+ fputc(s->cur[-1], stdout);
+ continue;
+ [^] :=
+ fputc(s->cur[-1], stdout);
+ continue;
+ := fprintf(stderr, "Normal\n");
+ := fprintf(stderr, "Comment\n");
+*/
+ }
+}
+
+int main(int argc, char **argv)
+{
+ Scanner in;
+
+ if (argc != 2)
+ {
+ fprintf(stderr, "%s \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;
+ }
+
+ if (init(&in) > 0)
+ {
+ scan(&in);
+ }
+
+ if (in.fp != stdin)
+ {
+ fclose(in.fp);
+ }
+ return 0;
+}