From a0573b83148ae7722bb98aa9f31df798aa473b9f Mon Sep 17 00:00:00 2001 From: Ulya Trofimovich Date: Mon, 28 Mar 2016 15:14:37 +0100 Subject: [PATCH] Make sure that default rule is handled together with other rules. --- re2c/src/ir/compile.cc | 30 +++++++++++++---- re2c/src/ir/compile.h | 3 +- re2c/src/ir/nfa/nfa.cc | 47 ++++++++------------------- re2c/src/ir/nfa/nfa.h | 3 +- re2c/src/ir/skeleton/generate_data.cc | 2 +- re2c/src/ir/skeleton/skeleton.cc | 8 ++--- re2c/src/ir/skeleton/skeleton.h | 6 ++-- 7 files changed, 48 insertions(+), 51 deletions(-) diff --git a/re2c/src/ir/compile.cc b/re2c/src/ir/compile.cc index 5b24892c..44ca9d75 100644 --- a/re2c/src/ir/compile.cc +++ b/re2c/src/ir/compile.cc @@ -28,7 +28,12 @@ static std::string make_name(const std::string &cond, uint32_t line) return name; } -smart_ptr compile (Spec & spec, Output & output, const std::string & cond, uint32_t cunits) +static smart_ptr compile_rules( + const std::vector &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 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 bounds; - split(spec.res, bounds); + split(rules, bounds); bounds.insert(0); bounds.insert(cunits); charset_t cs; @@ -49,15 +54,12 @@ smart_ptr 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 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 compile( + const Spec &spec, + Output &output, + const std::string &cond, + uint32_t cunits) +{ + size_t defrule = Rule::NONE; + std::vector 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 diff --git a/re2c/src/ir/compile.h b/re2c/src/ir/compile.h index 6883c1c3..833f0d1a 100644 --- a/re2c/src/ir/compile.h +++ b/re2c/src/ir/compile.h @@ -13,7 +13,8 @@ class DFA; struct Output; struct Spec; -smart_ptr compile (Spec & spec, Output & output, const std::string & cond, uint32_t cunits); +smart_ptr compile(const Spec &spec, Output &output, + const std::string &cond, uint32_t cunits); } // namespace re2c diff --git a/re2c/src/ir/nfa/nfa.cc b/re2c/src/ir/nfa/nfa.cc index 7ad638c4..cb4500a9 100644 --- a/re2c/src/ir/nfa/nfa.cc +++ b/re2c/src/ir/nfa/nfa.cc @@ -27,20 +27,11 @@ static size_t calc_size(const RegExp *re) } } -static size_t calc_size_all( - const std::vector &rules, - const RegExpRule *def) +static size_t calc_size_all(const std::vector &rs) { - size_t size = rules.size() - 1 + (def ? 1 : 0); - for (size_t i = 0; i < rules.size(); ++i) { - const std::vector ®exps = 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 ®exps = def->regexps; + size_t size = rs.size() - 1; + for (size_t i = 0; i < rs.size(); ++i) { + const std::vector ®exps = 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 &rules, - const RegExpRule* defrule, + const std::vector &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 &rs) + : max_size(calc_size_all(rs)) , size(0) , states(new nfa_state_t[max_size]) , rules(*new std::vector) , contexts(*new std::vector) - , root(compile_rules(spec.res, spec.def, *this)) + , root(compile_rules(rs, *this)) {} diff --git a/re2c/src/ir/nfa/nfa.h b/re2c/src/ir/nfa/nfa.h index 7dc35590..916a4c80 100644 --- a/re2c/src/ir/nfa/nfa.h +++ b/re2c/src/ir/nfa/nfa.h @@ -6,7 +6,6 @@ #include #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 &contexts; nfa_state_t *root; - nfa_t(Spec &spec); + nfa_t(const std::vector &rs); ~nfa_t(); FORBID_COPY(nfa_t); diff --git a/re2c/src/ir/skeleton/generate_data.cc b/re2c/src/ir/skeleton/generate_data.cc index 84170476..e16f71bd 100644 --- a/re2c/src/ir/skeleton/generate_data.cc +++ b/re2c/src/ir/skeleton/generate_data.cc @@ -118,7 +118,7 @@ template static cover_size_t cover_one( delete[] buffer; // keys - const key_t match = skel.rule2key(path.match(skel)); + const key_t match = skel.rule2key(path.match(skel), skel.defrule); keygen(cover.keys, count, len, path.len_matching(skel), match); } diff --git a/re2c/src/ir/skeleton/skeleton.cc b/re2c/src/ir/skeleton/skeleton.cc index 7177c045..42cdaf4a 100644 --- a/re2c/src/ir/skeleton/skeleton.cc +++ b/re2c/src/ir/skeleton/skeleton.cc @@ -111,10 +111,10 @@ size_t Skeleton::rule2key(size_t r) const { switch (sizeof_key) { default: // shouldn't happen - case 8: return rule2key(r); - case 4: return rule2key(r); - case 2: return rule2key(r); - case 1: return rule2key(r); + case 8: return rule2key(r, defrule); + case 4: return rule2key(r, defrule); + case 2: return rule2key(r, defrule); + case 1: return rule2key(r, defrule); } } diff --git a/re2c/src/ir/skeleton/skeleton.h b/re2c/src/ir/skeleton/skeleton.h index 4fc444f1..cd840081 100644 --- a/re2c/src/ir/skeleton/skeleton.h +++ b/re2c/src/ir/skeleton/skeleton.h @@ -64,16 +64,16 @@ struct Skeleton uint32_t dfa_line); ~Skeleton (); size_t rule2key(size_t r) const; - template key_t rule2key(size_t r) const; + template key_t rule2key(size_t r, size_t def) const; FORBID_COPY(Skeleton); }; -template key_t Skeleton::rule2key(size_t r) const +template key_t Skeleton::rule2key(size_t r, size_t def) const { if (r == Rule::NONE) { return std::numeric_limits::max(); - } else if (r == defrule) { + } else if (r == def) { key_t k = std::numeric_limits::max(); return --k; } else { -- 2.40.0