From: helly Date: Mon, 30 Apr 2007 17:59:07 +0000 (+0000) Subject: - Allow full replacement of YYGETSTATE/YYSETSTAE by inplace-configuration X-Git-Tag: 0.13.6~167 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=75c4f5167ee3727904a275c0a0c01b8654f85740;p=re2c - Allow full replacement of YYGETSTATE/YYSETSTAE by inplace-configuration - 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 --- diff --git a/re2c/bootstrap/parser.cc b/re2c/bootstrap/parser.cc index 7b90c02d..e14e31a7 100644 --- a/re2c/bootstrap/parser.cc +++ b/re2c/bootstrap/parser.cc @@ -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" yyvsp -= yylen; yyssp -= yylen; @@ -1810,7 +1826,7 @@ yyreturn: } -#line 343 "parser.y" +#line 356 "parser.y" extern "C" { diff --git a/re2c/code.cc b/re2c/code.cc index 4f1488ab..fc43e133 100644 --- a/re2c/code.cc +++ b/re2c/code.cc @@ -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()) { diff --git a/re2c/globals.h b/re2c/globals.h index fea02d4b..809cdb63 100644 --- a/re2c/globals.h +++ b/re2c/globals.h @@ -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; diff --git a/re2c/main.cc b/re2c/main.cc index bced4c9d..f8de35d0 100644 --- a/re2c/main.cc +++ b/re2c/main.cc @@ -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; diff --git a/re2c/parser.y b/re2c/parser.y index 2ea0175a..bc7cbd4e 100644 --- a/re2c/parser.y +++ b/re2c/parser.y @@ -81,7 +81,7 @@ static char* strdup(const char* s) %type CODE %type RANGE STRING %type rule look expr diff term factor primary -%type CONFIG VALUE +%type CONFIG VALUE newcond %type cond clist %type 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 */ { diff --git a/re2c/test/condition_05.cg.c b/re2c/test/condition_05.cg.c index b32c5187..c276d576 100755 --- a/re2c/test/condition_05.cg.c +++ b/re2c/test/condition_05.cg.c @@ -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 "" /* *********************************** */ 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; diff --git a/re2c/test/condition_05.cgitcondition_05.cgit.h.c b/re2c/test/condition_05.cgitcondition_05.cgit.h.c index de63c6e3..41b51fe4 100755 --- a/re2c/test/condition_05.cgitcondition_05.cgit.h.c +++ b/re2c/test/condition_05.cgitcondition_05.cgit.h.c @@ -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; diff --git a/re2c/test/condition_05.cgtcondition_05.cgt.h.c b/re2c/test/condition_05.cgtcondition_05.cgt.h.c index cd13ece0..aa5a92a2 100755 --- a/re2c/test/condition_05.cgtcondition_05.cgt.h.c +++ b/re2c/test/condition_05.cgtcondition_05.cgt.h.c @@ -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 "" /* *********************************** */ 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; diff --git a/re2c/test/condition_05.cs.c b/re2c/test/condition_05.cs.c index 930b4129..cf142102 100755 --- a/re2c/test/condition_05.cs.c +++ b/re2c/test/condition_05.cs.c @@ -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 "" /* *********************************** */ 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; diff --git a/re2c/test/condition_06.cs.c b/re2c/test/condition_06.cs.c index 9eef88da..c4b2ba09 100755 --- a/re2c/test/condition_06.cs.c +++ b/re2c/test/condition_06.cs.c @@ -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 "" /* *********************************** */ 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 "" /* *********************************** */ 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 "" /* *********************************** */ 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; diff --git a/re2c/test/condition_07.cbi.c b/re2c/test/condition_07.cbi.c index 90b404f2..5d8096bb 100755 --- a/re2c/test/condition_07.cbi.c +++ b/re2c/test/condition_07.cbi.c @@ -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 index 00000000..e2ab76a6 --- /dev/null +++ b/re2c/test/condition_08.cbi.c @@ -0,0 +1,372 @@ +/* Generated by re2c */ +#include +#include +#include + +#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 \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 index 00000000..148d9c69 --- /dev/null +++ b/re2c/test/condition_08.cbi.re @@ -0,0 +1,233 @@ +#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; + +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; + + "??(" + { + 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; + } + "/*" + { + s->cond = EStateComment; + goto yyc_Comment; + } + "//" + { + s->cond = EStateSkiptoeol; + goto yyc_Skiptoeol; + } + "'\\\"'"|"'\"'" + { + fputl("'\"'", 3, stdout); + continue; + } + '"' + { + fputc(*s->tok, stdout); + s->state = EStateString; + continue; + } + [^] + { + fputc(*s->tok, stdout); + continue; + } + "*" "/" + { + s->cond = EStateNormal; + continue; + } + [^] + { + goto yyc_Comment; + } + "??/" "\r"? "\n" + { + goto yyc_Skiptoeol; + } + "\\" "\r"? "\n" + { + goto yyc_Skiptoeol; + } + "\n" + { + s->cond = EStateNormal; + continue; + } + [^] + { + goto yyc_Skiptoeol; + } + '\\' . + { + fputl((const char*)s->tok, 2, stdout); + continue; + } + '"' + { + fputc(*s->tok, stdout); + s->cond = EStateNormal; + continue; + } + [^] + { + fputc(*s->tok, stdout); + continue; + } +*/ + } +} + +int main(int argc, char **argv) +{ + Scanner in; + char c; + + 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; + } + + 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 index 00000000..c546c452 --- /dev/null +++ b/re2c/test/condition_08.cbif.c @@ -0,0 +1,389 @@ +/* Generated by re2c */ +#include +#include +#include + +#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 \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 index 00000000..148d9c69 --- /dev/null +++ b/re2c/test/condition_08.cbif.re @@ -0,0 +1,233 @@ +#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; + +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; + + "??(" + { + 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; + } + "/*" + { + s->cond = EStateComment; + goto yyc_Comment; + } + "//" + { + s->cond = EStateSkiptoeol; + goto yyc_Skiptoeol; + } + "'\\\"'"|"'\"'" + { + fputl("'\"'", 3, stdout); + continue; + } + '"' + { + fputc(*s->tok, stdout); + s->state = EStateString; + continue; + } + [^] + { + fputc(*s->tok, stdout); + continue; + } + "*" "/" + { + s->cond = EStateNormal; + continue; + } + [^] + { + goto yyc_Comment; + } + "??/" "\r"? "\n" + { + goto yyc_Skiptoeol; + } + "\\" "\r"? "\n" + { + goto yyc_Skiptoeol; + } + "\n" + { + s->cond = EStateNormal; + continue; + } + [^] + { + goto yyc_Skiptoeol; + } + '\\' . + { + fputl((const char*)s->tok, 2, stdout); + continue; + } + '"' + { + fputc(*s->tok, stdout); + s->cond = EStateNormal; + continue; + } + [^] + { + fputc(*s->tok, stdout); + continue; + } +*/ + } +} + +int main(int argc, char **argv) +{ + Scanner in; + char c; + + 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; + } + + 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 index 00000000..62ce8efe --- /dev/null +++ b/re2c/test/condition_09.cbif.c @@ -0,0 +1,389 @@ +/* Generated by re2c */ +#include +#include +#include + +#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 \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 index 00000000..432a0cc5 --- /dev/null +++ b/re2c/test/condition_09.cbif.re @@ -0,0 +1,227 @@ +#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; + +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; + + "??(" + { + 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; + } + "/*" => Normal + { + goto yyc_Comment; + } + "//" => Skiptoeol + { + goto yyc_Skiptoeol; + } + "'\\\"'"|"'\"'" + { + fputl("'\"'", 3, stdout); + continue; + } + '"' => String + { + fputc(*s->tok, stdout); + continue; + } + [^] + { + fputc(*s->tok, stdout); + continue; + } + "*" "/" => Normal + { + continue; + } + [^] + { + goto yyc_Comment; + } + "??/" "\r"? "\n" + { + goto yyc_Skiptoeol; + } + "\\" "\r"? "\n" + { + goto yyc_Skiptoeol; + } + "\n" => Normal + { + continue; + } + [^] + { + goto yyc_Skiptoeol; + } + '\\' . + { + fputl((const char*)s->tok, 2, stdout); + continue; + } + '"' => Normal + { + fputc(*s->tok, stdout); + continue; + } + [^] + { + fputc(*s->tok, stdout); + continue; + } +*/ + } +} + +int main(int argc, char **argv) +{ + Scanner in; + char c; + + 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; + } + + 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 index 00000000..826810a0 --- /dev/null +++ b/re2c/test/condition_09.cgif.c @@ -0,0 +1,434 @@ +/* Generated by re2c */ +#include +#include +#include + +#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 \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 index 00000000..432a0cc5 --- /dev/null +++ b/re2c/test/condition_09.cgif.re @@ -0,0 +1,227 @@ +#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; + +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; + + "??(" + { + 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; + } + "/*" => Normal + { + goto yyc_Comment; + } + "//" => Skiptoeol + { + goto yyc_Skiptoeol; + } + "'\\\"'"|"'\"'" + { + fputl("'\"'", 3, stdout); + continue; + } + '"' => String + { + fputc(*s->tok, stdout); + continue; + } + [^] + { + fputc(*s->tok, stdout); + continue; + } + "*" "/" => Normal + { + continue; + } + [^] + { + goto yyc_Comment; + } + "??/" "\r"? "\n" + { + goto yyc_Skiptoeol; + } + "\\" "\r"? "\n" + { + goto yyc_Skiptoeol; + } + "\n" => Normal + { + continue; + } + [^] + { + goto yyc_Skiptoeol; + } + '\\' . + { + fputl((const char*)s->tok, 2, stdout); + continue; + } + '"' => Normal + { + fputc(*s->tok, stdout); + continue; + } + [^] + { + fputc(*s->tok, stdout); + continue; + } +*/ + } +} + +int main(int argc, char **argv) +{ + Scanner in; + char c; + + 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; + } + + in.cond = EStateNormal; + scan(&in); + + if (in.fp != stdin) + { + fclose(in.fp); + } + return 0; +} diff --git a/re2c/test/config10.re b/re2c/test/config10.re index 3c3fafcb..4724b92d 100755 --- a/re2c/test/config10.re +++ b/re2c/test/config10.re @@ -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; diff --git a/re2c/token.h b/re2c/token.h index 19a64420..6fc39895 100644 --- a/re2c/token.h +++ b/re2c/token.h @@ -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