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);
// 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;
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);
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
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
}
}
-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*> ®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<const RegExp*> ®exps = def->regexps;
+ size_t size = rs.size() - 1;
+ for (size_t i = 0; i < rs.size(); ++i) {
+ const std::vector<const RegExp*> ®exps = rs[i]->regexps;
for (size_t j = 0; j < regexps.size(); ++j) {
size += calc_size(regexps[j]);
}
}
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))
{}
#include <vector>
#include "src/ir/rule.h"
-#include "src/parse/spec.h"
#include "src/util/forbid_copy.h"
namespace re2c
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);
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);
}
{
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);
}
}
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 {