]> granicus.if.org Git - re2c/commitdiff
Simplified parsing of startup code '<>'.
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 21 Dec 2016 22:31:34 +0000 (22:31 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 21 Dec 2016 22:31:34 +0000 (22:31 +0000)
re2c/bootstrap/src/parse/lex.cc
re2c/bootstrap/src/parse/parser.cc
re2c/src/parse/parser.ypp
re2c/test/cond_error_08.c.c

index e2fb6a2e37ca0bb2b053b7e3a1f3be01bafb8569..8e83ed28f148c34dfcb4c939532c3214ca7fe4df 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.16 on Wed Dec 21 18:43:25 2016 */
+/* Generated by re2c 0.16 on Wed Dec 21 22:10:36 2016 */
 #line 1 "../src/parse/lex.re"
 #include "src/util/c99_stdint.h"
 #include <stddef.h>
index 339243e2d52421860bae58f729c49f320f4e7385..721188e921561a76c85339904f4ad690df2f53d8 100644 (file)
@@ -112,7 +112,6 @@ void yyerror(Scanner &in, const char*);
 static std::vector<std::string> condnames;
 static re2c::SpecMap  specMap;
 static Spec spec;
-static RegExpRule *specNone = NULL;
 static SetupMap            ruleSetupMap;
 static bool                foundRules;
 static symbol_table_t symbol_table;
@@ -124,13 +123,13 @@ static symbol_table_t symbol_table;
 #define __attribute__(x)
 #endif
 
-static void check_default(const Spec &spec, const std::string &cond)
+static void check(const Spec &spec, const std::string &cond)
 {
-       Spec::const_iterator
-               b = spec.begin(),
-               e = spec.end(),
-               i = std::find_if(b, e, RegExpRule::is_def),
-               j = std::find_if(i + 1, e, RegExpRule::is_def);
+       Spec::const_iterator b = spec.begin(), e = spec.end(), i, j;
+
+       // no multiple default rules per condition
+       i = std::find_if(b, e, RegExpRule::is_def);
+       j = std::find_if(i + 1, e, RegExpRule::is_def);
        if (j != e) {
                const uint32_t
                        l1 = (*i)->info->loc.line,
@@ -139,6 +138,18 @@ static void check_default(const Spec &spec, const std::string &cond)
                        l2, incond(cond).c_str(), l1);
                exit(1);
        }
+
+       // no multiple startup code definitions
+       if (cond == "0" && e - b > 1) {
+               fprintf(stderr, "re2c: error: multiple definitions of startup code (lines ");
+               for (i = b;;) {
+                       fprintf(stderr, "%u", (*i)->info->loc.line);
+                       if (++i == e) break;
+                       fprintf(stderr, ", ");
+               }
+               fprintf(stderr, ")\n");
+               exit(1);
+       }
 }
 
 static void delay_default(Spec &spec)
@@ -571,11 +582,11 @@ static const yytype_int8 yyrhs[] =
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   179,   179,   181,   182,   183,   188,   195,   200,   203,
-     207,   207,   210,   218,   222,   227,   237,   248,   253,   259,
-     266,   267,   272,   275,   282,   286,   291,   296,   300,   307,
-     311,   318,   322,   329,   333,   350,   369,   373,   377,   381,
-     388,   398,   402
+       0,   190,   190,   192,   193,   194,   199,   206,   211,   214,
+     218,   218,   221,   229,   233,   238,   245,   253,   258,   264,
+     271,   272,   277,   280,   287,   291,   296,   301,   305,   312,
+     316,   323,   327,   334,   338,   355,   374,   378,   382,   386,
+     393,   403,   407
 };
 #endif
 
@@ -1598,27 +1609,21 @@ yyreduce:
   case 15:
 
     {
-               context_check(in, NULL);
-               if (specNone) {
-                       in.fatal("code to handle illegal condition already defined");
-               }
-               specNone = new RegExpRule(RegExp::make_nil(), false);
-               specNone->info = new RuleInfo((yyvsp[(4) - (4)].code)->loc, (yyvsp[(4) - (4)].code), (yyvsp[(3) - (4)].str));
-               delete (yyvsp[(3) - (4)].str);
+               CondList *cl = new CondList;
+               cl->insert("0");
+               RegExpRule *r = new RegExpRule(RegExp::make_nil(), false);
+               context_rule(in, cl, (yyvsp[(4) - (4)].code)->loc, r, (yyvsp[(4) - (4)].code), (yyvsp[(3) - (4)].str));
        ;}
     break;
 
   case 16:
 
     {
-               context_check(in, NULL);
-               if (specNone) {
-                       in.fatal("code to handle illegal condition already defined");
-               }
+               CondList *cl = new CondList;
+               cl->insert("0");
+               RegExpRule *r = new RegExpRule(RegExp::make_nil(), false);
                Loc loc(in.get_fname(), in.get_cline());
-               specNone = new RegExpRule(RegExp::make_nil(), false);
-               specNone->info = new RuleInfo(loc, NULL, (yyvsp[(4) - (4)].str));
-               delete (yyvsp[(4) - (4)].str);
+               context_rule(in, cl, loc, r, NULL, (yyvsp[(4) - (4)].str));
        ;}
     break;
 
@@ -2138,7 +2143,7 @@ void parse(Scanner &in, Output & o)
                        SpecMap::iterator it;
 
                        for (it = specMap.begin(); it != specMap.end(); ++it) {
-                               check_default(it->second, it->first);
+                               check(it->second, it->first);
                        }
 
                        Spec star;
@@ -2149,19 +2154,13 @@ void parse(Scanner &in, Output & o)
 
                        if (mode != Scanner::Reuse)
                        {
-                               // merge <*> rules to all conditions with lowest priority
+                               // merge <*> rules to all conditions except "0" with lowest priority
                                for (it = specMap.begin(); it != specMap.end(); ++it) {
+                                       if (it->first == "0") continue;
                                        for (size_t j = 0; j < star.size(); ++j) {
                                                it->second.push_back(star[j]);
                                        }
                                }
-
-                               if (specNone)
-                               {
-                                       specMap["0"].push_back(specNone);
-                                       // Note that "0" inserts first, which is important.
-                                       condnames.insert (condnames.begin (), "0");
-                               }
                        }
                        o.source.block().types = condnames;
 
@@ -2183,7 +2182,7 @@ void parse(Scanner &in, Output & o)
                }
                else
                {
-                       check_default(spec, "");
+                       check(spec, "");
                        delay_default(spec);
                        if (!spec.empty() || !dfa_map.empty())
                        {
@@ -2241,7 +2240,6 @@ void parse_cleanup()
        symbol_table.clear ();
        condnames.clear ();
        specMap.clear();
-       specNone = NULL;
 }
 
 } // end namespace re2c
index fbd91875df3cfc86e9db569cba5427d4f7b1ebd9..4739ad11e21e13535a4d78624dcf51d5e76dcba4 100644 (file)
@@ -44,7 +44,6 @@ void yyerror(Scanner &in, const char*);
 static std::vector<std::string> condnames;
 static re2c::SpecMap  specMap;
 static Spec spec;
-static RegExpRule *specNone = NULL;
 static SetupMap            ruleSetupMap;
 static bool                foundRules;
 static symbol_table_t symbol_table;
@@ -56,13 +55,13 @@ static symbol_table_t symbol_table;
 #define __attribute__(x)
 #endif
 
-static void check_default(const Spec &spec, const std::string &cond)
+static void check(const Spec &spec, const std::string &cond)
 {
-       Spec::const_iterator
-               b = spec.begin(),
-               e = spec.end(),
-               i = std::find_if(b, e, RegExpRule::is_def),
-               j = std::find_if(i + 1, e, RegExpRule::is_def);
+       Spec::const_iterator b = spec.begin(), e = spec.end(), i, j;
+
+       // no multiple default rules per condition
+       i = std::find_if(b, e, RegExpRule::is_def);
+       j = std::find_if(i + 1, e, RegExpRule::is_def);
        if (j != e) {
                const uint32_t
                        l1 = (*i)->info->loc.line,
@@ -71,6 +70,18 @@ static void check_default(const Spec &spec, const std::string &cond)
                        l2, incond(cond).c_str(), l1);
                exit(1);
        }
+
+       // no multiple startup code definitions
+       if (cond == "0" && e - b > 1) {
+               fprintf(stderr, "re2c: error: multiple definitions of startup code (lines ");
+               for (i = b;;) {
+                       fprintf(stderr, "%u", (*i)->info->loc.line);
+                       if (++i == e) break;
+                       fprintf(stderr, ", ");
+               }
+               fprintf(stderr, ")\n");
+               exit(1);
+       }
 }
 
 static void delay_default(Spec &spec)
@@ -225,24 +236,18 @@ rule
        }
 
        | '<' '>' newcond TOKEN_CODE {
-               context_check(in, NULL);
-               if (specNone) {
-                       in.fatal("code to handle illegal condition already defined");
-               }
-               specNone = new RegExpRule(RegExp::make_nil(), false);
-               specNone->info = new RuleInfo($4->loc, $4, $3);
-               delete $3;
+               CondList *cl = new CondList;
+               cl->insert("0");
+               RegExpRule *r = new RegExpRule(RegExp::make_nil(), false);
+               context_rule(in, cl, $4->loc, r, $4, $3);
        }
 
        | '<' '>' ':' newcond {
-               context_check(in, NULL);
-               if (specNone) {
-                       in.fatal("code to handle illegal condition already defined");
-               }
+               CondList *cl = new CondList;
+               cl->insert("0");
+               RegExpRule *r = new RegExpRule(RegExp::make_nil(), false);
                Loc loc(in.get_fname(), in.get_cline());
-               specNone = new RegExpRule(RegExp::make_nil(), false);
-               specNone->info = new RuleInfo(loc, NULL, $4);
-               delete $4;
+               context_rule(in, cl, loc, r, NULL, $4);
        }
 
        | '<' '!' clist '>' TOKEN_CODE {
@@ -500,7 +505,7 @@ void parse(Scanner &in, Output & o)
                        SpecMap::iterator it;
 
                        for (it = specMap.begin(); it != specMap.end(); ++it) {
-                               check_default(it->second, it->first);
+                               check(it->second, it->first);
                        }
 
                        Spec star;
@@ -511,19 +516,13 @@ void parse(Scanner &in, Output & o)
 
                        if (mode != Scanner::Reuse)
                        {
-                               // merge <*> rules to all conditions with lowest priority
+                               // merge <*> rules to all conditions except "0" with lowest priority
                                for (it = specMap.begin(); it != specMap.end(); ++it) {
+                                       if (it->first == "0") continue;
                                        for (size_t j = 0; j < star.size(); ++j) {
                                                it->second.push_back(star[j]);
                                        }
                                }
-
-                               if (specNone)
-                               {
-                                       specMap["0"].push_back(specNone);
-                                       // Note that "0" inserts first, which is important.
-                                       condnames.insert (condnames.begin (), "0");
-                               }
                        }
                        o.source.block().types = condnames;
 
@@ -545,7 +544,7 @@ void parse(Scanner &in, Output & o)
                }
                else
                {
-                       check_default(spec, "");
+                       check(spec, "");
                        delay_default(spec);
                        if (!spec.empty() || !dfa_map.empty())
                        {
@@ -603,7 +602,6 @@ void parse_cleanup()
        symbol_table.clear ();
        condnames.clear ();
        specMap.clear();
-       specNone = NULL;
 }
 
 } // end namespace re2c
index 3d6d32dd96a66ad87cbf6dfdcde66a7697c663ba..f3d73f256a84331b9209d200b7fbde859e225672 100644 (file)
@@ -1 +1 @@
-re2c: error: line 4, column 4: code to handle illegal condition already defined
+re2c: error: multiple definitions of startup code (lines 3, 4)