]> granicus.if.org Git - re2c/commitdiff
Mark rules as nullable rather than keep a separate collection of nullable rules.
authorUlya Trofimovich <skvadrik@gmail.com>
Mon, 22 Feb 2016 13:51:57 +0000 (13:51 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Mon, 22 Feb 2016 13:51:57 +0000 (13:51 +0000)
re2c/Makefile.am
re2c/src/ir/compile.cc
re2c/src/ir/regexp/nullable.cc [deleted file]
re2c/src/ir/regexp/regexp.cc
re2c/src/ir/regexp/regexp.h
re2c/src/ir/skeleton/skeleton.cc
re2c/src/ir/skeleton/skeleton.h
re2c/src/ir/skeleton/unreachable_nullable.cc
re2c/src/parse/rules.h

index 563983b8108196009aa7b11d63a6df01cc8aa3ce..311c885ef9c75cd2f97685a8c381f5dcd5f944f1 100644 (file)
@@ -93,7 +93,6 @@ SRC = \
        src/ir/regexp/encoding/utf16/utf16_regexp.cc \
        src/ir/regexp/encoding/utf16/utf16.cc \
        src/ir/regexp/encoding/utf16/utf16_range.cc \
-       src/ir/regexp/nullable.cc \
        src/ir/regexp/regexp.cc \
        src/ir/regexp/split_charset.cc \
        src/ir/compile.cc \
index 6826cd8c3eb6adbd31e66e4cf78979640f3cd6be..3516df254975d93b93ceca7621b247e47c7832eb 100644 (file)
@@ -54,7 +54,6 @@ smart_ptr<DFA> compile (Spec & spec, Output & output, const std::string & cond,
        // skeleton must be constructed after DFA construction
        // but prior to any other DFA transformations
        Skeleton *skeleton = new Skeleton(dfa, cs, spec.rules, name, cond, line);
-       nullable_rules(spec.re, skeleton->nullable_rules);
 
        minimization(dfa);
 
diff --git a/re2c/src/ir/regexp/nullable.cc b/re2c/src/ir/regexp/nullable.cc
deleted file mode 100644 (file)
index e58096f..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "src/ir/regexp/regexp.h"
-
-namespace re2c
-{
-
-static bool nullable(const RegExp *re)
-{
-       switch (re->tag) {
-               default:
-               case RegExp::NIL:
-                       return true;
-               case RegExp::SYM:
-                       return false;
-               case RegExp::ALT:
-                       return nullable(re->pld.alt.re1)
-                               || nullable(re->pld.alt.re2);
-               case RegExp::CAT:
-                       return nullable(re->pld.cat.re1)
-                               && nullable(re->pld.cat.re2);
-               case RegExp::ITER:
-                       return true;
-               case RegExp::RULE:
-                       return nullable(re->pld.rule.re);
-       }
-}
-
-void nullable_rules(const RegExp *re, std::vector<RuleInfo*> &rs)
-{
-       switch (re->tag) {
-               case RegExp::ALT:
-                       nullable_rules(re->pld.alt.re1, rs);
-                       nullable_rules(re->pld.alt.re2, rs);
-                       break;
-               case RegExp::RULE:
-                       if (nullable(re->pld.rule.re)) {
-                               rs.push_back(re->pld.rule.info);
-                       }
-                       break;
-               default:
-                       break;
-       }
-}
-
-} // end namespace re2c
-
index b260ff390162e8853825161d8a698d4fb65ba500..d3a44154af44f2a4d5aff02ebf16e2acbeddde57 100644 (file)
@@ -16,6 +16,7 @@ namespace re2c
 {
 
 static uint32_t fixlen(const RegExp *re);
+static bool nullable(const RegExp *re);
 
 free_list<RegExp*> RegExp::flist;
 
@@ -225,7 +226,7 @@ const RegExp* RegExp::rule(const Loc &loc, const RegExp *r1, const RegExp *r2,
                ctx_len = ~0u;
        }
 
-       re->pld.rule.info = new RuleInfo(loc, rank, code, newcond, ctx_len);
+       re->pld.rule.info = new RuleInfo(loc, rank, code, newcond, ctx_len, nullable(r1));
        return re;
 }
 
@@ -237,8 +238,8 @@ const RegExp* RegExp::rule_copy(const RegExp *rule, rule_rank_t rank)
        re->pld.rule.re = rule->pld.rule.re;
        re->pld.rule.ctx = rule->pld.rule.ctx;
        const RuleInfo *info = rule->pld.rule.info;
-       re->pld.rule.info = new RuleInfo(info->loc, rank,
-               info->code, &info->newcond, info->ctx_len);
+       re->pld.rule.info = new RuleInfo(info->loc, rank, info->code,
+               &info->newcond, info->ctx_len, info->nullable);
        return re;
 }
 
@@ -274,4 +275,25 @@ uint32_t fixlen(const RegExp *re)
        }
 }
 
+bool nullable(const RegExp *re)
+{
+       switch (re->tag) {
+               default:
+               case RegExp::NIL:
+                       return true;
+               case RegExp::SYM:
+                       return false;
+               case RegExp::ALT:
+                       return nullable(re->pld.alt.re1)
+                               || nullable(re->pld.alt.re2);
+               case RegExp::CAT:
+                       return nullable(re->pld.cat.re1)
+                               && nullable(re->pld.cat.re2);
+               case RegExp::ITER:
+                       return true;
+               case RegExp::RULE:
+                       return nullable(re->pld.rule.re);
+       }
+}
+
 } // namespace re2c
index 0cdef9e31dab50ae2129c5bff8f9867d268ffc2f..9e1a3feee026adb6e2621b494b2b574cc9c7c442 100644 (file)
@@ -110,8 +110,6 @@ private:
 };
 
 void split(const RegExp *re, std::set<uint32_t> &cs);
-void nullable_rules(const RegExp *re, std::vector<RuleInfo*> &rs);
-
 const RegExp *mkAlt(const RegExp *re1, const RegExp *re2);
 const RegExp *doAlt(const RegExp *re1, const RegExp *re2);
 const RegExp *doCat(const RegExp *re1, const RegExp *re2);
index a678246efd2aa4d7e06067cec682d0a7fa78ef42..cbc3c7f0371cf66f5a09ababfe134883edc1c48e 100644 (file)
@@ -82,7 +82,6 @@ Skeleton::Skeleton
        , nodes (new Node [nodes_count + 1]) // +1 for default state
        , sizeof_key (4)
        , rules (rs)
-       , nullable_rules ()
 {
        const size_t nc = cs.size() - 1;
 
index bbda6b235880cb74c6fe175405830fcf8a91037a..f89135dce787fc90f746c66e4cb677e079cc320a 100644 (file)
@@ -114,7 +114,6 @@ struct Skeleton
        Node * nodes;
        size_t sizeof_key;
        rules_t rules;
-       std::vector<RuleInfo*> nullable_rules;
 
        Skeleton
                ( const dfa_t &dfa
index a46c51b6d8d32aef7e8ed97366202a8c1ed09a2f..7dbfd3ddf92a266aa76e0bde95826dfee247cf14 100644 (file)
@@ -78,13 +78,12 @@ void Skeleton::warn_unreachable_nullable_rules ()
        //    - rules that match empty strins with nonempty trailing context
        // false positives on partially shadowed (yet reachable) rules, e.g.:
        //     [^]?
-       for (std::vector<RuleInfo*>::const_iterator i = nullable_rules.begin();
-               i != nullable_rules.end(); ++i)
+       for (rules_t::const_iterator i = rules.begin(); i != rules.end(); ++i)
        {
-               const RuleInfo *ri = *i;
-               if (ri->reachable)
+               const RuleInfo *r = *i;
+               if (r->nullable && r->reachable)
                {
-                       warn.match_empty_string(ri->loc.line);
+                       warn.match_empty_string(r->loc.line);
                }
        }
 }
index 952e732121b2026ae145b9e81b75311dac2a0f4f..ce6f69f10c56103b2384b655a32ca9046cd71193 100644 (file)
@@ -29,6 +29,7 @@ struct RuleInfo
 
        std::set<uint32_t> shadow;
        bool reachable;
+       bool nullable;
 
        RuleInfo
                ( const Loc & l
@@ -36,6 +37,7 @@ struct RuleInfo
                , const Code * c
                , const std::string * cond
                , uint32_t cl
+               , bool nl
                )
                : loc (l)
                , ctx_len (cl)
@@ -44,6 +46,7 @@ struct RuleInfo
                , newcond (cond ? *cond : "")
                , shadow ()
                , reachable (false)
+               , nullable (nl)
        {}
 
        FORBID_COPY(RuleInfo);