From 573c077962c96ffd3ff4cb1e3445eb18e637803b Mon Sep 17 00:00:00 2001 From: Ulya Trofimovich Date: Wed, 7 Oct 2015 16:20:38 +0100 Subject: [PATCH] Merge default rules on the fly, assign them the same lowest priority. re2c used to postpone merging default rules because rank counter could only assign consequtive ranks to rules, and default rules must have the lowest priority. Now rank counter has been modified to return special value as defult rule rank. --- re2c/Makefile.am | 1 + re2c/bootstrap/src/parse/parser.cc | 165 ++++++++++----------- re2c/src/ir/bytecode/bytecode.cc | 4 +- re2c/src/ir/bytecode/bytecode.h | 3 +- re2c/src/ir/rule_rank.cc | 17 ++- re2c/src/ir/rule_rank.h | 7 +- re2c/src/parse/parser.h | 3 +- re2c/src/parse/parser.ypp | 143 ++++++++---------- re2c/src/parse/spec.h | 48 ++++++ re2c/test/default_dup.i.c | 1 + re2c/test/default_dup.i.re | 4 + re2c/test/default_dup.ic.c | 1 + re2c/test/default_dup.ic.re | 4 + re2c/test/default_dup_star_1.ic.c | 30 ++++ re2c/test/default_dup_star_1.ic.re | 6 + re2c/test/default_dup_star_2.ic.c | 1 + re2c/test/default_dup_star_2.ic.re | 4 + re2c/test/reuse_conds_default_0.cgir.c | 190 +++++++++++++++++++++++- re2c/test/reuse_conds_default_1.cgir.c | 198 ++++++++++++++++++++++++- 19 files changed, 653 insertions(+), 177 deletions(-) create mode 100644 re2c/src/parse/spec.h create mode 100644 re2c/test/default_dup.i.c create mode 100644 re2c/test/default_dup.i.re create mode 100644 re2c/test/default_dup.ic.c create mode 100644 re2c/test/default_dup.ic.re create mode 100644 re2c/test/default_dup_star_1.ic.c create mode 100644 re2c/test/default_dup_star_1.ic.re create mode 100644 re2c/test/default_dup_star_2.ic.c create mode 100644 re2c/test/default_dup_star_2.ic.re diff --git a/re2c/Makefile.am b/re2c/Makefile.am index 3995d758..9a2f07aa 100644 --- a/re2c/Makefile.am +++ b/re2c/Makefile.am @@ -55,6 +55,7 @@ SRC_HDR = \ src/parse/loc.h \ src/parse/parser.h \ src/parse/scanner.h \ + src/parse/spec.h \ src/parse/unescape.h \ src/util/allocate.h \ src/util/attribute.h \ diff --git a/re2c/bootstrap/src/parse/parser.cc b/re2c/bootstrap/src/parse/parser.cc index 9ce0715d..3b139134 100644 --- a/re2c/bootstrap/src/parse/parser.cc +++ b/re2c/bootstrap/src/parse/parser.cc @@ -104,13 +104,13 @@ void yyerror(const char*); static counter_t rank_counter; static std::vector condnames; static re2c::RegExpMap specMap; -static RegExp *spec = NULL, *specNone = NULL; +static Spec spec; +static RegExp *specNone = NULL; static RuleOpList specStar; +static RuleOp * star_default = NULL; static Scanner *in = NULL; static Scanner::ParseMode parseMode; static SetupMap ruleSetupMap; -static const Code * ruleDefault = NULL; -static DefaultMap ruleDefaultMap; static bool foundRules; static symbol_table_t symbol_table; @@ -152,6 +152,11 @@ void context_rule : RegExp::SHARED; for(CondList::const_iterator it = clist->begin(); it != clist->end(); ++it) { + if (specMap.find(*it) == specMap.end()) + { + condnames.push_back (*it); + } + RuleOp * rule = new RuleOp ( loc , expr @@ -161,19 +166,7 @@ void context_rule , code , newcond ); - - RegExpMap::iterator itRE = specMap.find(*it); - - if (itRE != specMap.end()) - { - itRE->second = mkAlt(itRE->second, rule); - } - else - { - specMap[*it] = rule; - condnames.push_back (*it); - } - + specMap[*it].add (rule); } delete clist; delete newcond; @@ -202,11 +195,19 @@ void default_rule(CondList *clist, const Code * code) context_check(clist); for(CondList::const_iterator it = clist->begin(); it != clist->end(); ++it) { - if (ruleDefaultMap.find(*it) != ruleDefaultMap.end()) + RuleOp * def = new RuleOp + ( code->loc + , in->mkDefault () + , new NullOp + , rule_rank_t::def () + , RegExp::SHARED + , code + , NULL + ); + if (!specMap[*it].add_def (def)) { in->fatalf_at(code->loc.line, "code to default rule '%s' is already defined", it->c_str()); } - ruleDefaultMap[*it] = code; } delete clist; } @@ -674,17 +675,17 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 242, 242, 244, 248, 252, 261, 270, 274, 278, - 283, 288, 293, 298, 303, 308, 316, 321, 326, 331, - 336, 341, 346, 351, 356, 361, 366, 371, 376, 381, - 386, 391, 396, 401, 405, 410, 415, 419, 424, 428, - 432, 437, 441, 446, 459, 464, 472, 477, 482, 487, - 491, 496, 500, 504, 509, 514, 519, 524, 529, 534, - 538, 542, 546, 550, 554, 561, 578, 587, 591, 597, - 602, 608, 612, 627, 644, 649, 655, 661, 679, 699, - 705, 713, 716, 723, 729, 739, 742, 750, 753, 760, - 764, 771, 775, 782, 786, 793, 797, 812, 832, 836, - 840, 844, 851, 861, 865 + 0, 243, 243, 245, 249, 253, 262, 271, 275, 279, + 284, 289, 294, 299, 304, 309, 317, 322, 327, 332, + 337, 342, 347, 352, 357, 362, 367, 372, 377, 382, + 387, 392, 397, 402, 406, 411, 416, 420, 425, 429, + 433, 438, 442, 447, 460, 465, 473, 478, 483, 488, + 492, 497, 501, 505, 510, 515, 520, 525, 530, 535, + 539, 543, 547, 551, 555, 562, 579, 597, 601, 607, + 612, 618, 622, 637, 654, 659, 665, 681, 699, 719, + 725, 733, 736, 743, 749, 759, 762, 770, 773, 780, + 784, 791, 795, 802, 806, 813, 817, 832, 852, 856, + 860, 864, 871, 881, 885 }; #endif @@ -2297,7 +2298,7 @@ yyreduce: , (yyvsp[(3) - (3)].code) , NULL ); - spec = spec? mkAlt(spec, (yyval.regexp)) : (yyval.regexp); + spec.add ((yyval.regexp)); ;} break; @@ -2306,10 +2307,19 @@ yyreduce: { if (opts->cFlag) in->fatal("condition or '<*>' required when using -c switch"); - if (ruleDefault != NULL) + RuleOp * def = new RuleOp + ( (yyvsp[(2) - (2)].code)->loc + , in->mkDefault () + , new NullOp + , rule_rank_t::def () + , RegExp::SHARED + , (yyvsp[(2) - (2)].code) + , NULL + ); + if (!spec.add_def (def)) + { in->fatal("code to default rule is already defined"); - else - ruleDefault = (yyvsp[(2) - (2)].code); + } ;} break; @@ -2411,9 +2421,19 @@ yyreduce: case 76: { - CondList *clist = new CondList(); - clist->insert("*"); - default_rule(clist, (yyvsp[(5) - (5)].code)); + if (star_default) + { + in->fatal ("code to default rule '*' is already defined"); + } + star_default = new RuleOp + ( (yyvsp[(5) - (5)].code)->loc + , in->mkDefault () + , new NullOp + , rule_rank_t::def () + , RegExp::PRIVATE + , (yyvsp[(5) - (5)].code) + , NULL + ); ;} break; @@ -2952,8 +2972,7 @@ void parse(Scanner& i, Output & o) dfa_map.clear(); } rank_counter.reset (); - spec = NULL; - ruleDefault = NULL; + spec.clear (); in->set_in_parse(true); yyparse(); in->set_in_parse(false); @@ -2967,9 +2986,8 @@ void parse(Scanner& i, Output & o) i.reuse(); dfa_map.clear(); parse_cleanup(); - spec = NULL; + spec.clear (); rank_counter.reset (); - ruleDefault = NULL; in->set_in_parse(true); yyparse(); in->set_in_parse(false); @@ -2992,30 +3010,30 @@ void parse(Scanner& i, Output & o) if (parseMode != Scanner::Reuse) { - if (!specStar.empty()) + // <*> rules must have the lowest priority + // now that all rules have been parsed, we can fix it + for (RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp) + { + (*itOp)->rank = rank_counter.next (); + } + // merge <*> rules to all conditions + // note that all conditions use the same regexp for <*> rules, + // but compile it separately because of RegExp::PRIVATE attribute + for (it = specMap.begin(); it != specMap.end(); ++it) { - // <*> rules must have the lowest priority - // now that all rules have been parsed, we can fix it for (RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp) { - (*itOp)->rank = rank_counter.next (); + it->second.addl (*itOp); } - // merge <*> rules to all conditions - // note that all conditions use the same regexp for <*> rules, - // but compile it separately because of RegExp::PRIVATE attribute - for (it = specMap.begin(); it != specMap.end(); ++it) + if (star_default) { - assert(it->second); - for (RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp) - { - it->second = mkAlt(*itOp, it->second); - } + it->second.addl (star_default); } } - + if (specNone) { - specMap["0"] = specNone; + specMap["0"].add (specNone); // Note that "0" inserts first, which is important. condnames.insert (condnames.begin (), "0"); } @@ -3026,8 +3044,6 @@ void parse(Scanner& i, Output & o) for (it = specMap.begin(); it != specMap.end(); ++it) { - assert(it->second); - if (parseMode != Scanner::Reuse) { itRuleSetup = ruleSetupMap.find(it->first); @@ -3048,25 +3064,6 @@ void parse(Scanner& i, Output & o) } } - DefaultMap::const_iterator def = ruleDefaultMap.find (it->first); - if (def == ruleDefaultMap.end ()) - { - def = ruleDefaultMap.find ("*"); - } - if (def != ruleDefaultMap.end ()) - { - RuleOp * def_rule = new RuleOp - ( def->second->loc - , in->mkDefault () - , new NullOp - , rank_counter.next () - , RegExp::SHARED - , def->second - , NULL - ); - it->second = it->second ? mkAlt (def_rule, it->second) : def_rule; - } - dfa_map[it->first] = genCode(it->second, o, it->first, opts->encoding.nCodeUnits ()); } if (parseMode != Scanner::Rules && dfa_map.find(it->first) != dfa_map.end()) @@ -3077,20 +3074,7 @@ void parse(Scanner& i, Output & o) } else { - if (ruleDefault != NULL && parseMode != Scanner::Reuse) - { - RuleOp * def = new RuleOp - ( ruleDefault->loc - , in->mkDefault () - , new NullOp - , rank_counter.next () - , RegExp::SHARED - , ruleDefault - , NULL - ); - spec = spec ? mkAlt(def, spec) : def; - } - if (spec || !dfa_map.empty()) + if (spec.re || !dfa_map.empty()) { if (parseMode != Scanner::Reuse) { @@ -3148,6 +3132,7 @@ void parse_cleanup() condnames.clear (); specMap.clear(); specStar.clear(); + star_default = NULL; specNone = NULL; } diff --git a/re2c/src/ir/bytecode/bytecode.cc b/re2c/src/ir/bytecode/bytecode.cc index 76b66c1b..60d6422c 100644 --- a/re2c/src/ir/bytecode/bytecode.cc +++ b/re2c/src/ir/bytecode/bytecode.cc @@ -8,8 +8,10 @@ namespace re2c { static void optimize (Ins * i); -smart_ptr genCode (RegExp *re, Output & output, const std::string & cond, uint32_t cunits) +smart_ptr genCode (Spec & spec, Output & output, const std::string & cond, uint32_t cunits) { + RegExp * re = spec.re; + CharSet cs (cunits); re->split(cs); diff --git a/re2c/src/ir/bytecode/bytecode.h b/re2c/src/ir/bytecode/bytecode.h index 4e1f296d..6e9ad865 100644 --- a/re2c/src/ir/bytecode/bytecode.h +++ b/re2c/src/ir/bytecode/bytecode.h @@ -4,12 +4,13 @@ #include "src/codegen/output.h" #include "src/ir/dfa/dfa.h" #include "src/ir/regexp/regexp.h" +#include "src/parse/spec.h" #include "src/util/smart_ptr.h" namespace re2c { -smart_ptr genCode (RegExp * re, Output & output, const std::string & cond, uint32_t cunits); +smart_ptr genCode (Spec & spec, Output & output, const std::string & cond, uint32_t cunits); } // namespace re2c diff --git a/re2c/src/ir/rule_rank.cc b/re2c/src/ir/rule_rank.cc index a41a84a9..d8546412 100644 --- a/re2c/src/ir/rule_rank.cc +++ b/re2c/src/ir/rule_rank.cc @@ -1,3 +1,4 @@ +#include #include #include "src/ir/rule_rank.h" @@ -5,7 +6,8 @@ namespace re2c { -const uint32_t rule_rank_t::NONE = 0xFFFFffff; +const uint32_t rule_rank_t::NONE = UINT32_MAX; +const uint32_t rule_rank_t::DEF = rule_rank_t::NONE - 1; rule_rank_t::rule_rank_t () : value (0) @@ -13,6 +15,7 @@ rule_rank_t::rule_rank_t () void rule_rank_t::inc () { + assert (value < DEF - 1); ++value; } @@ -23,11 +26,23 @@ rule_rank_t rule_rank_t::none () return r; } +rule_rank_t rule_rank_t::def () +{ + rule_rank_t r; + r.value = DEF; + return r; +} + bool rule_rank_t::is_none () const { return value == NONE; } +bool rule_rank_t::is_def () const +{ + return value == DEF; +} + bool rule_rank_t::operator < (const rule_rank_t & r) const { return value < r.value; diff --git a/re2c/src/ir/rule_rank.h b/re2c/src/ir/rule_rank.h index 51111ed5..55d97704 100644 --- a/re2c/src/ir/rule_rank.h +++ b/re2c/src/ir/rule_rank.h @@ -10,8 +10,8 @@ namespace re2c { // rule rank public API: -// - get rule rank corresponding to nonexistent rule -// - check if rank corresponds to nonexistent rule +// - get rule rank corresponding to nonexistent/default rule +// - check if rank corresponds to nonexistent/default rule // - compare ranks // - output rank to std::ostream // @@ -21,13 +21,16 @@ namespace re2c class rule_rank_t { static const uint32_t NONE; + static const uint32_t DEF; uint32_t value; rule_rank_t (); void inc (); public: static rule_rank_t none (); + static rule_rank_t def (); bool is_none () const; + bool is_def () const; bool operator < (const rule_rank_t & r) const; friend std::ostream & operator << (std::ostream & o, rule_rank_t r); uint32_t uint32 () const; diff --git a/re2c/src/parse/parser.h b/re2c/src/parse/parser.h index deb74995..0f847577 100644 --- a/re2c/src/parse/parser.h +++ b/re2c/src/parse/parser.h @@ -8,6 +8,7 @@ #include "src/ir/regexp/regexp.h" #include "src/ir/regexp/regexp_rule.h" #include "src/parse/scanner.h" +#include "src/parse/spec.h" namespace re2c { @@ -17,7 +18,7 @@ extern void parse_cleanup(); typedef std::set CondList; typedef std::list RuleOpList; -typedef std::map RegExpMap; +typedef std::map RegExpMap; typedef std::map > SetupMap; typedef std::map DefaultMap; typedef std::map symbol_table_t; diff --git a/re2c/src/parse/parser.ypp b/re2c/src/parse/parser.ypp index 577ee09c..473a06db 100644 --- a/re2c/src/parse/parser.ypp +++ b/re2c/src/parse/parser.ypp @@ -36,13 +36,13 @@ void yyerror(const char*); static counter_t rank_counter; static std::vector condnames; static re2c::RegExpMap specMap; -static RegExp *spec = NULL, *specNone = NULL; +static Spec spec; +static RegExp *specNone = NULL; static RuleOpList specStar; +static RuleOp * star_default = NULL; static Scanner *in = NULL; static Scanner::ParseMode parseMode; static SetupMap ruleSetupMap; -static const Code * ruleDefault = NULL; -static DefaultMap ruleDefaultMap; static bool foundRules; static symbol_table_t symbol_table; @@ -84,6 +84,11 @@ void context_rule : RegExp::SHARED; for(CondList::const_iterator it = clist->begin(); it != clist->end(); ++it) { + if (specMap.find(*it) == specMap.end()) + { + condnames.push_back (*it); + } + RuleOp * rule = new RuleOp ( loc , expr @@ -93,19 +98,7 @@ void context_rule , code , newcond ); - - RegExpMap::iterator itRE = specMap.find(*it); - - if (itRE != specMap.end()) - { - itRE->second = mkAlt(itRE->second, rule); - } - else - { - specMap[*it] = rule; - condnames.push_back (*it); - } - + specMap[*it].add (rule); } delete clist; delete newcond; @@ -134,11 +127,19 @@ void default_rule(CondList *clist, const Code * code) context_check(clist); for(CondList::const_iterator it = clist->begin(); it != clist->end(); ++it) { - if (ruleDefaultMap.find(*it) != ruleDefaultMap.end()) + RuleOp * def = new RuleOp + ( code->loc + , in->mkDefault () + , new NullOp + , rule_rank_t::def () + , RegExp::SHARED + , code + , NULL + ); + if (!specMap[*it].add_def (def)) { in->fatalf_at(code->loc.line, "code to default rule '%s' is already defined", it->c_str()); } - ruleDefaultMap[*it] = code; } delete clist; } @@ -573,16 +574,25 @@ rule: , $3 , NULL ); - spec = spec? mkAlt(spec, $$) : $$; + spec.add ($$); } | STAR CODE /* default rule */ { if (opts->cFlag) in->fatal("condition or '<*>' required when using -c switch"); - if (ruleDefault != NULL) + RuleOp * def = new RuleOp + ( $2->loc + , in->mkDefault () + , new NullOp + , rule_rank_t::def () + , RegExp::SHARED + , $2 + , NULL + ); + if (!spec.add_def (def)) + { in->fatal("code to default rule is already defined"); - else - ruleDefault = $2; + } } | '<' cond '>' expr look newcond CODE { @@ -654,9 +664,19 @@ rule: } | '<' STAR '>' STAR CODE /* default rule for all conditions */ { - CondList *clist = new CondList(); - clist->insert("*"); - default_rule(clist, $5); + if (star_default) + { + in->fatal ("code to default rule '*' is already defined"); + } + star_default = new RuleOp + ( $5->loc + , in->mkDefault () + , new NullOp + , rule_rank_t::def () + , RegExp::PRIVATE + , $5 + , NULL + ); } | NOCOND newcond CODE { @@ -929,8 +949,7 @@ void parse(Scanner& i, Output & o) dfa_map.clear(); } rank_counter.reset (); - spec = NULL; - ruleDefault = NULL; + spec.clear (); in->set_in_parse(true); yyparse(); in->set_in_parse(false); @@ -944,9 +963,8 @@ void parse(Scanner& i, Output & o) i.reuse(); dfa_map.clear(); parse_cleanup(); - spec = NULL; + spec.clear (); rank_counter.reset (); - ruleDefault = NULL; in->set_in_parse(true); yyparse(); in->set_in_parse(false); @@ -969,30 +987,30 @@ void parse(Scanner& i, Output & o) if (parseMode != Scanner::Reuse) { - if (!specStar.empty()) + // <*> rules must have the lowest priority + // now that all rules have been parsed, we can fix it + for (RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp) + { + (*itOp)->rank = rank_counter.next (); + } + // merge <*> rules to all conditions + // note that all conditions use the same regexp for <*> rules, + // but compile it separately because of RegExp::PRIVATE attribute + for (it = specMap.begin(); it != specMap.end(); ++it) { - // <*> rules must have the lowest priority - // now that all rules have been parsed, we can fix it for (RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp) { - (*itOp)->rank = rank_counter.next (); + it->second.addl (*itOp); } - // merge <*> rules to all conditions - // note that all conditions use the same regexp for <*> rules, - // but compile it separately because of RegExp::PRIVATE attribute - for (it = specMap.begin(); it != specMap.end(); ++it) + if (star_default) { - assert(it->second); - for (RuleOpList::const_iterator itOp = specStar.begin(); itOp != specStar.end(); ++itOp) - { - it->second = mkAlt(*itOp, it->second); - } + it->second.addl (star_default); } } - + if (specNone) { - specMap["0"] = specNone; + specMap["0"].add (specNone); // Note that "0" inserts first, which is important. condnames.insert (condnames.begin (), "0"); } @@ -1003,8 +1021,6 @@ void parse(Scanner& i, Output & o) for (it = specMap.begin(); it != specMap.end(); ++it) { - assert(it->second); - if (parseMode != Scanner::Reuse) { itRuleSetup = ruleSetupMap.find(it->first); @@ -1025,25 +1041,6 @@ void parse(Scanner& i, Output & o) } } - DefaultMap::const_iterator def = ruleDefaultMap.find (it->first); - if (def == ruleDefaultMap.end ()) - { - def = ruleDefaultMap.find ("*"); - } - if (def != ruleDefaultMap.end ()) - { - RuleOp * def_rule = new RuleOp - ( def->second->loc - , in->mkDefault () - , new NullOp - , rank_counter.next () - , RegExp::SHARED - , def->second - , NULL - ); - it->second = it->second ? mkAlt (def_rule, it->second) : def_rule; - } - dfa_map[it->first] = genCode(it->second, o, it->first, opts->encoding.nCodeUnits ()); } if (parseMode != Scanner::Rules && dfa_map.find(it->first) != dfa_map.end()) @@ -1054,20 +1051,7 @@ void parse(Scanner& i, Output & o) } else { - if (ruleDefault != NULL && parseMode != Scanner::Reuse) - { - RuleOp * def = new RuleOp - ( ruleDefault->loc - , in->mkDefault () - , new NullOp - , rank_counter.next () - , RegExp::SHARED - , ruleDefault - , NULL - ); - spec = spec ? mkAlt(def, spec) : def; - } - if (spec || !dfa_map.empty()) + if (spec.re || !dfa_map.empty()) { if (parseMode != Scanner::Reuse) { @@ -1125,6 +1109,7 @@ void parse_cleanup() condnames.clear (); specMap.clear(); specStar.clear(); + star_default = NULL; specNone = NULL; } diff --git a/re2c/src/parse/spec.h b/re2c/src/parse/spec.h new file mode 100644 index 00000000..fc853c0a --- /dev/null +++ b/re2c/src/parse/spec.h @@ -0,0 +1,48 @@ +#ifndef _RE2C_PARSE_SPEC_ +#define _RE2C_PARSE_SPEC_ + +#include "src/ir/regexp/regexp.h" + +namespace re2c +{ + +struct Spec +{ + RegExp * re; + bool def; + + Spec () + : re (NULL) + , def (false) + {} + bool add_def (RegExp * r) + { + if (def) + { + return false; + } + else + { + def = true; + addl (r); + return true; + } + } + void add (RegExp * r) + { + re = mkAlt (re, r); + } + void addl (RegExp * r) + { + re = mkAlt (r, re); + } + void clear () + { + re = NULL; + def = false; + } +}; + +} // namespace re2c + +#endif // _RE2C_PARSE_SPEC_ diff --git a/re2c/test/default_dup.i.c b/re2c/test/default_dup.i.c new file mode 100644 index 00000000..df77c5b7 --- /dev/null +++ b/re2c/test/default_dup.i.c @@ -0,0 +1 @@ +re2c: error: line 3, column 4: code to default rule is already defined diff --git a/re2c/test/default_dup.i.re b/re2c/test/default_dup.i.re new file mode 100644 index 00000000..f0c887e0 --- /dev/null +++ b/re2c/test/default_dup.i.re @@ -0,0 +1,4 @@ +/*!re2c + * { return DEFAULT-1; } + * { return DEFAULT-2; } +*/ diff --git a/re2c/test/default_dup.ic.c b/re2c/test/default_dup.ic.c new file mode 100644 index 00000000..548466b5 --- /dev/null +++ b/re2c/test/default_dup.ic.c @@ -0,0 +1 @@ +re2c: error: line 3, column 9: code to default rule 'c1' is already defined diff --git a/re2c/test/default_dup.ic.re b/re2c/test/default_dup.ic.re new file mode 100644 index 00000000..7f51001d --- /dev/null +++ b/re2c/test/default_dup.ic.re @@ -0,0 +1,4 @@ +/*!re2c + * { return DEFAULT-1; } + * { return DEFAULT-2; } +*/ diff --git a/re2c/test/default_dup_star_1.ic.c b/re2c/test/default_dup_star_1.ic.c new file mode 100644 index 00000000..e137fac3 --- /dev/null +++ b/re2c/test/default_dup_star_1.ic.c @@ -0,0 +1,30 @@ +/* Generated by re2c */ + +{ + YYCTYPE yych; + switch (YYGETCONDITION()) { + case yycc3: goto yyc_c3; + } +/* *********************************** */ +yyc_c1: + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + ++YYCURSOR; + { return DEFAULT-1; } +/* *********************************** */ +yyc_c2: + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + ++YYCURSOR; + { return DEFAULT-2; } +/* *********************************** */ +yyc_c3: + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + goto yy12; + { return C3; } +yy12: + ++YYCURSOR; + { return DEFAULT-*; } +} + diff --git a/re2c/test/default_dup_star_1.ic.re b/re2c/test/default_dup_star_1.ic.re new file mode 100644 index 00000000..5c38e27f --- /dev/null +++ b/re2c/test/default_dup_star_1.ic.re @@ -0,0 +1,6 @@ +/*!re2c + * { return DEFAULT-1; } + * { return DEFAULT-2; } + "" { return C3; } + <*> * { return DEFAULT-*; } +*/ diff --git a/re2c/test/default_dup_star_2.ic.c b/re2c/test/default_dup_star_2.ic.c new file mode 100644 index 00000000..79910934 --- /dev/null +++ b/re2c/test/default_dup_star_2.ic.c @@ -0,0 +1 @@ +re2c: error: line 3, column 8: code to default rule '*' is already defined diff --git a/re2c/test/default_dup_star_2.ic.re b/re2c/test/default_dup_star_2.ic.re new file mode 100644 index 00000000..4910a2ce --- /dev/null +++ b/re2c/test/default_dup_star_2.ic.re @@ -0,0 +1,4 @@ +/*!re2c + <*> * { return DEFAULT-1; } + <*> * { return DEFAULT-2; } +*/ diff --git a/re2c/test/reuse_conds_default_0.cgir.c b/re2c/test/reuse_conds_default_0.cgir.c index 932b60ed..4ad2219e 100644 --- a/re2c/test/reuse_conds_default_0.cgir.c +++ b/re2c/test/reuse_conds_default_0.cgir.c @@ -1 +1,189 @@ -re2c: error: line 13, column 9: code to default rule 'r1' is already defined +re2c: warning: line 15: control flow in condition 'r2' is undefined for strings that match '\xA', use default rule '*' [-Wundefined-control-flow] +re2c: warning: line 20: control flow in condition 'r1' is undefined for strings that match '\xA', use default rule '*' [-Wundefined-control-flow] +re2c: warning: line 15: looks like you use hardcoded numbers instead of autogenerated condition names: better add '/*!types:re2c*/' directive or '-t, --type-header' option and don't rely on fixed condition order. [-Wcondition-order] +re2c: warning: line 20: looks like you use hardcoded numbers instead of autogenerated condition names: better add '/*!types:re2c*/' directive or '-t, --type-header' option and don't rely on fixed condition order. [-Wcondition-order] +/* Generated by re2c */ +// This test currently fails with error +// 're2c: error: line 13, column 9: code to default rule 'r1' is already defined' +// This must be fixed later + + + + +{ + YYCTYPE yych; + static void *yyctable[2] = { + &&yyc_r1, + &&yyc_r2, + }; + goto *yyctable[YYGETCONDITION()]; +/* *********************************** */ +yyc_r1: + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + { + static void *yytarget[256] = { + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy13, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy5, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy7, &&yy9, &&yy11, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3 + }; + goto *yytarget[yych]; + } +yy3: + ++YYCURSOR; + { return "."; } +yy5: + ++YYCURSOR; + { return "1"; } +yy7: + ++YYCURSOR; + { return "a"; } +yy9: + ++YYCURSOR; + { return "b"; } +yy11: + ++YYCURSOR; + { return "c"; } +yy13: + ++YYCURSOR; + { return "DEFAULT - r1"; } +/* *********************************** */ +yyc_r2: + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '`') { + if (yych != '\n') goto yy18; + } else { + if (yych <= 'a') goto yy20; + if (yych == 'c') goto yy22; + goto yy18; + } +yy18: + ++YYCURSOR; + { return "."; } +yy20: + ++YYCURSOR; + { return "a"; } +yy22: + ++YYCURSOR; + { return "c"; } +} + + + +{ + YYCTYPE yych; + static void *yyctable[2] = { + &&yyc_r1, + &&yyc_r2, + }; + goto *yyctable[YYGETCONDITION()]; +/* *********************************** */ +yyc_r1: + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + { + static void *yytarget[256] = { + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy3, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy6, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy8, &&yy10, &&yy12, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, + &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4, &&yy4 + }; + goto *yytarget[yych]; + } +yy3: +yy4: + ++YYCURSOR; + { return "."; } +yy6: + ++YYCURSOR; + { return "2"; } +yy8: + ++YYCURSOR; + { return "a"; } +yy10: + ++YYCURSOR; + { return "b"; } +yy12: + ++YYCURSOR; + { return "c"; } +/* *********************************** */ +yyc_r2: + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '`') { + if (yych == '\n') goto yy22; + } else { + if (yych <= 'a') goto yy18; + if (yych == 'c') goto yy20; + } + ++YYCURSOR; + { return "."; } +yy18: + ++YYCURSOR; + { return "a"; } +yy20: + ++YYCURSOR; + { return "c"; } +yy22: + ++YYCURSOR; + { return "DEFAULT - r2"; } +} + diff --git a/re2c/test/reuse_conds_default_1.cgir.c b/re2c/test/reuse_conds_default_1.cgir.c index 87194fd8..91249f45 100644 --- a/re2c/test/reuse_conds_default_1.cgir.c +++ b/re2c/test/reuse_conds_default_1.cgir.c @@ -1 +1,197 @@ -re2c: error: line 11, column 9: code to default rule 'r1' is already defined +re2c: warning: line 32: control flow in condition 'r2' is undefined for strings that match '\xA', use default rule '*' [-Wundefined-control-flow] +/* Generated by re2c */ +// This test currently fails with error +// 're2c: error: line 11, column 9: code to default rule 'r1' is already defined' +// This must be fixed later + + +enum YYCONDTYPE { + yycr2, +}; + + +void scan(unsigned char* in) +{ + +{ + YYCTYPE yych; + static void *yyctable[1] = { + &&yyc_r2, + }; + goto *yyctable[YYGETCONDITION()]; +/* *********************************** */ +yyc_r1: + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + { + static void *yytarget[256] = { + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy13, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy5, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy7, &&yy9, &&yy11, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3 + }; + goto *yytarget[yych]; + } +yy3: + ++YYCURSOR; + { return "."; } +yy5: + ++YYCURSOR; + { return "1"; } +yy7: + ++YYCURSOR; + { return "a"; } +yy9: + ++YYCURSOR; + { return "b"; } +yy11: + ++YYCURSOR; + { return "c"; } +yy13: + ++YYCURSOR; + { return "DEFAULT-r1"; } +/* *********************************** */ +yyc_r2: + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '`') { + if (yych == '\n') goto yy23; + } else { + if (yych <= 'a') goto yy19; + if (yych == 'c') goto yy21; + } + ++YYCURSOR; + { return "."; } +yy19: + ++YYCURSOR; + { return "a"; } +yy21: + ++YYCURSOR; + { return "c"; } +yy23: + ++YYCURSOR; + { return "DEFAULT-r2"; } +} + + +} + +void scan(unsigned short* in) +{ + +{ + YYCTYPE yych; + static void *yyctable[1] = { + &&yyc_r2, + }; + goto *yyctable[YYGETCONDITION()]; +/* *********************************** */ +yyc_r1: + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + { + static void *yytarget[256] = { + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy13, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy5, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy7, &&yy9, &&yy11, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, + &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3, &&yy3 + }; + goto *yytarget[yych]; + } +yy3: + ++YYCURSOR; + { return "."; } +yy5: + ++YYCURSOR; + { return "2"; } +yy7: + ++YYCURSOR; + { return "a"; } +yy9: + ++YYCURSOR; + { return "b"; } +yy11: + ++YYCURSOR; + { return "c"; } +yy13: + ++YYCURSOR; + { return "DEFAULT-r1"; } +/* *********************************** */ +yyc_r2: + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '`') { + if (yych != '\n') goto yy18; + } else { + if (yych <= 'a') goto yy20; + if (yych == 'c') goto yy22; + goto yy18; + } +yy18: + ++YYCURSOR; + { return "."; } +yy20: + ++YYCURSOR; + { return "a"; } +yy22: + ++YYCURSOR; + { return "c"; } +} + +} -- 2.40.0