]> granicus.if.org Git - re2c/commitdiff
Make sure that default rule is handled together with other rules.
authorUlya Trofimovich <skvadrik@gmail.com>
Mon, 28 Mar 2016 14:14:37 +0000 (15:14 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Mon, 28 Mar 2016 14:41:22 +0000 (15:41 +0100)
re2c/src/ir/compile.cc
re2c/src/ir/compile.h
re2c/src/ir/nfa/nfa.cc
re2c/src/ir/nfa/nfa.h
re2c/src/ir/skeleton/generate_data.cc
re2c/src/ir/skeleton/skeleton.cc
re2c/src/ir/skeleton/skeleton.h

index 5b24892c69af02eb3775d6935c12d9f1fba71cde..44ca9d7584010332a1dba2b7a56bed8f979e3200 100644 (file)
@@ -28,7 +28,12 @@ static std::string make_name(const std::string &cond, uint32_t line)
        return name;
 }
 
-smart_ptr<DFA> compile (Spec & spec, Output & output, const std::string & cond, uint32_t cunits)
+static smart_ptr<DFA> compile_rules(
+       const std::vector<const RegExpRule*> &rules,
+       size_t defrule,
+       Output &output,
+       const std::string &cond,
+       uint32_t cunits)
 {
        const uint32_t line = output.source.get_block_line();
        const std::string name = make_name(cond, line);
@@ -40,7 +45,7 @@ smart_ptr<DFA> compile (Spec & spec, Output & output, const std::string & cond,
        // Don't forget to include zero and upper bound, even if they
        // do not explicitely apper in ranges.
        std::set<uint32_t> bounds;
-       split(spec.res, bounds);
+       split(rules, bounds);
        bounds.insert(0);
        bounds.insert(cunits);
        charset_t cs;
@@ -49,15 +54,12 @@ smart_ptr<DFA> compile (Spec & spec, Output & output, const std::string & cond,
                cs.push_back(*i);
        }
 
-       nfa_t nfa(spec);
+       nfa_t nfa(rules);
 
        dfa_t dfa(nfa, cs, line, cond);
 
        // skeleton must be constructed after DFA construction
        // but prior to any other DFA transformations
-       const size_t defrule = spec.def
-               ? dfa.rules.size() - 1
-               : Rule::NONE;
        Skeleton *skeleton = new Skeleton(dfa, cs, defrule, name, cond, line);
 
        minimization(dfa);
@@ -109,4 +111,20 @@ smart_ptr<DFA> compile (Spec & spec, Output & output, const std::string & cond,
        return make_smart_ptr(adfa);
 }
 
+// small wrapper that makes sure default rule is not forgotten
+smart_ptr<DFA> compile(
+       const Spec &spec,
+       Output &output,
+       const std::string &cond,
+       uint32_t cunits)
+{
+       size_t defrule = Rule::NONE;
+       std::vector<const RegExpRule*> rules(spec.res);
+       if (spec.def) {
+               defrule = spec.res.size();
+               rules.push_back(spec.def);
+       }
+       return compile_rules(rules, defrule, output, cond, cunits);
+}
+
 } // namespace re2c
index 6883c1c3f5bcb7bd6ac51e4eaafcdb929786c40f..833f0d1aae6ef8272716553d34e22028251e8613 100644 (file)
@@ -13,7 +13,8 @@ class DFA;
 struct Output;
 struct Spec;
 
-smart_ptr<DFA> compile (Spec & spec, Output & output, const std::string & cond, uint32_t cunits);
+smart_ptr<DFA> compile(const Spec &spec, Output &output,
+       const std::string &cond, uint32_t cunits);
 
 } // namespace re2c
 
index 7ad638c485f03c8ecadaa5250e3c8f74c78fdc04..cb4500a9811fa45ca6c3ae3c2f5355513d761683 100644 (file)
@@ -27,20 +27,11 @@ static size_t calc_size(const RegExp *re)
        }
 }
 
-static size_t calc_size_all(
-       const std::vector<const RegExpRule*> &rules,
-       const RegExpRule *def)
+static size_t calc_size_all(const std::vector<const RegExpRule*> &rs)
 {
-       size_t size = rules.size() - 1 + (def ? 1 : 0);
-       for (size_t i = 0; i < rules.size(); ++i) {
-               const std::vector<const RegExp*> &regexps = rules[i]->regexps;
-               for (size_t j = 0; j < regexps.size(); ++j) {
-                       size += calc_size(regexps[j]);
-               }
-               size += regexps.size();
-       }
-       if (def != NULL) {
-               const std::vector<const RegExp*> &regexps = def->regexps;
+       size_t size = rs.size() - 1;
+       for (size_t i = 0; i < rs.size(); ++i) {
+               const std::vector<const RegExp*> &regexps = rs[i]->regexps;
                for (size_t j = 0; j < regexps.size(); ++j) {
                        size += calc_size(regexps[j]);
                }
@@ -206,41 +197,29 @@ static nfa_state_t *compile_rule(
 }
 
 static nfa_state_t *compile_rules(
-       const std::vector<const RegExpRule*> &rules,
-       const RegExpRule* defrule,
+       const std::vector<const RegExpRule*> &rs,
        nfa_t &nfa)
 {
        nfa_state_t *s = NULL;
-
-       if (!rules.empty()) {
-               s = compile_rule(rules[0], nfa);
-               for (size_t i = 1; i < rules.size(); ++i) {
+       const size_t nrs = rs.size();
+       if (nrs > 0) {
+               s = compile_rule(rs[0], nfa);
+               for (size_t i = 1; i < nrs; ++i) {
                        nfa_state_t *q = &nfa.states[nfa.size++];
-                       q->alt(s, compile_rule(rules[i], nfa));
+                       q->alt(s, compile_rule(rs[i], nfa));
                        s = q;
                }
        }
-       // default rule goes last
-       if (defrule) {
-               if (s) {
-                       nfa_state_t *q = &nfa.states[nfa.size++];
-                       q->alt(s, compile_rule(defrule, nfa));
-                       s = q;
-               } else {
-                       s = compile_rule(defrule, nfa);
-               }
-       }
-
        return s;
 }
 
-nfa_t::nfa_t(Spec &spec)
-       : max_size(calc_size_all(spec.res, spec.def))
+nfa_t::nfa_t(const std::vector<const RegExpRule*> &rs)
+       : max_size(calc_size_all(rs))
        , size(0)
        , states(new nfa_state_t[max_size])
        , rules(*new std::vector<Rule>)
        , contexts(*new std::vector<CtxVar>)
-       , root(compile_rules(spec.res, spec.def, *this))
+       , root(compile_rules(rs, *this))
 {}
 
 
index 7dc355905d8009c9a79ecb8a49d5c50c336e8beb..916a4c808c3c2d0ea2fd7221b4b79d4ec27e43ef 100644 (file)
@@ -6,7 +6,6 @@
 #include <vector>
 
 #include "src/ir/rule.h"
-#include "src/parse/spec.h"
 #include "src/util/forbid_copy.h"
 
 namespace re2c
@@ -87,7 +86,7 @@ struct nfa_t
        std::vector<CtxVar> &contexts;
        nfa_state_t *root;
 
-       nfa_t(Spec &spec);
+       nfa_t(const std::vector<const RegExpRule*> &rs);
        ~nfa_t();
 
        FORBID_COPY(nfa_t);
index 84170476119ab2ee9c585f0f6cd6a96af6a5477a..e16f71bd8bdb6b9ecdd741ad4072481681dd08f5 100644 (file)
@@ -118,7 +118,7 @@ template<typename cunit_t, typename key_t> static cover_size_t cover_one(
                delete[] buffer;
 
                // keys
-               const key_t match = skel.rule2key<key_t>(path.match(skel));
+               const key_t match = skel.rule2key<key_t>(path.match(skel), skel.defrule);
                keygen<key_t>(cover.keys, count, len,
                        path.len_matching(skel), match);
        }
index 7177c045ba1ade87aa1173643e71a5e18752376e..42cdaf4aa658dc380dad8d811dd9d4e2bdd247e1 100644 (file)
@@ -111,10 +111,10 @@ size_t Skeleton::rule2key(size_t r) const
 {
        switch (sizeof_key) {
                default: // shouldn't happen
-               case 8: return rule2key<uint64_t>(r);
-               case 4: return rule2key<uint32_t>(r);
-               case 2: return rule2key<uint16_t>(r);
-               case 1: return rule2key<uint8_t>(r);
+               case 8: return rule2key<uint64_t>(r, defrule);
+               case 4: return rule2key<uint32_t>(r, defrule);
+               case 2: return rule2key<uint16_t>(r, defrule);
+               case 1: return rule2key<uint8_t>(r, defrule);
        }
 }
 
index 4fc444f12391513a785ce21733a4b158fcd85685..cd84008196680f98f15eedc472638098461758d9 100644 (file)
@@ -64,16 +64,16 @@ struct Skeleton
                uint32_t dfa_line);
        ~Skeleton ();
        size_t rule2key(size_t r) const;
-       template<typename key_t> key_t rule2key(size_t r) const;
+       template<typename key_t> key_t rule2key(size_t r, size_t def) const;
 
        FORBID_COPY(Skeleton);
 };
 
-template<typename key_t> key_t Skeleton::rule2key(size_t r) const
+template<typename key_t> key_t Skeleton::rule2key(size_t r, size_t def) const
 {
        if (r == Rule::NONE) {
                return std::numeric_limits<key_t>::max();
-       } else if (r == defrule) {
+       } else if (r == def) {
                key_t k = std::numeric_limits<key_t>::max();
                return --k;
        } else {