, charset(dfa.charset)
, rules(dfa.rules)
, tags(dfa.tags)
+ , listvers(dfa.listvers)
, finvers(dfa.finvers)
, tcpool(dfa.tcpool)
, max_fill (0)
delete &charset;
delete &rules;
delete &tags;
+ delete &listvers;
delete[] finvers;
delete &tcpool;
}
std::vector<uint32_t> &charset;
std::valarray<Rule> &rules;
std::vector<Tag> &tags;
+ std::set<tagver_t> &listvers;
const tagver_t *finvers;
tcpool_t &tcpool;
size_t max_fill;
}
}
-static void find_list_tags_cmd(const tcmd_t *p, bool *list)
-{
- for (; p; p = p->next) {
- if (tcmd_t::isadd(p)) {
- list[p->lhs] = list[p->rhs] = true;
- }
- }
-}
-
-static void prop_list_tags_cmd(const tcmd_t *p, bool *list)
-{
- for (; p; p = p->next) {
- if (tcmd_t::iscopy(p)) {
- const tagver_t l = p->lhs, r = p->rhs;
- if (list[l]) list[r] = true;
- if (list[r]) list[l] = true;
- }
- }
-}
-
-static void find_list_tags(const DFA &dfa, bool *list)
-{
- find_list_tags_cmd(dfa.tcpool[dfa.tags0], list);
- for (State *s = dfa.head; s; s = s->next) {
- const Go &go = s->go;
- find_list_tags_cmd(dfa.tcpool[go.tags], list);
- for (uint32_t i = 0; i < go.nSpans; ++i) {
- find_list_tags_cmd(dfa.tcpool[go.span[i].tags], list);
- }
- find_list_tags_cmd(dfa.tcpool[s->rule_tags], list);
- find_list_tags_cmd(dfa.tcpool[s->fall_tags], list);
- }
- prop_list_tags_cmd(dfa.tcpool[dfa.tags0], list);
- for (State *s = dfa.head; s; s = s->next) {
- const Go &go = s->go;
- prop_list_tags_cmd(dfa.tcpool[go.tags], list);
- for (uint32_t i = 0; i < go.nSpans; ++i) {
- prop_list_tags_cmd(dfa.tcpool[go.span[i].tags], list);
- }
- prop_list_tags_cmd(dfa.tcpool[s->rule_tags], list);
- prop_list_tags_cmd(dfa.tcpool[s->fall_tags], list);
- }
-}
-
void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBrace)
{
OutputFile &o = output.source;
tagvars.insert(*tag.name);
}
}
- bool *list = new bool[maxtagver + 1]();
- find_list_tags(*this, list);
for (tagver_t v = 1; v <= maxtagver; ++v) {
const std::string name = vartag_name(v, opts->tags_prefix);
- if (list[v]) {
+ if (listvers.find(v) != listvers.end()) {
taglistnames.insert(name);
} else {
tagnames.insert(name);
}
}
- delete[] list;
ob.tags.insert(tagnames.begin(), tagnames.end());
ob.taglists.insert(taglistnames.begin(), taglistnames.end());
}
void cfg_t::interference(const cfg_t &cfg, const bool *live, bool *interf)
{
- const size_t nver = static_cast<size_t>(cfg.dfa.maxtagver) + 1;
+ const tagver_t maxver = cfg.dfa.maxtagver + 1;
+ const size_t nver = static_cast<size_t>(maxver);
bool *buf = new bool[nver];
vals_t *vals = new vals_t[nver]();
const cfg_bb_t *b = cfg.bblocks, *e = b + cfg.nbbfin;
interfere(b->cmd, live, interf, buf, vals, nver);
}
+ // versions of tags with/without history interfere
+ std::set<tagver_t> &lvs = cfg.dfa.listvers;
+ for (std::set<tagver_t>::iterator i = lvs.begin(); i != lvs.end(); ++i) {
+ for (tagver_t u = *i, v = 0; v < maxver; ++v) {
+ if (lvs.find(v) == lvs.end()) {
+ interf[v * maxver + u] = interf[u * maxver + v] = true;
+ }
+ }
+ }
+
delete[] buf;
delete[] vals;
}
f = ver2new[f];
}
}
+
+ // versions of tags with history
+ std::set<tagver_t> newlvs, &oldlvs = cfg.dfa.listvers;
+ for (std::set<tagver_t>::iterator i = oldlvs.begin(); i != oldlvs.end(); ++i) {
+ newlvs.insert(ver2new[*i]);
+ }
+ oldlvs.swap(newlvs);
}
} // namespace re2c
, charset(nfa.charset)
, rules(nfa.rules)
, tags(nfa.tags)
+ , listvers(*new std::set<tagver_t>)
, finvers(NULL)
, tcpool(*new tcpool_t)
, maxtagver(0)
finvers[i] = fixed(tags[i]) ? TAGVER_ZERO : ++maxtagver;
}
+ // mark tags with history (initial and final)
+ for (size_t i = 0; i < ntag; ++i) {
+ if (history(tags[i])) {
+ tagver_t v = static_cast<tagver_t>(i) + 1, f = finvers[i];
+ if (f != TAGVER_ZERO) listvers.insert(f);
+ listvers.insert(v);
+ }
+ }
+
// iterate while new kernels are added: for each alphabet symbol,
// build tagged epsilon-closure of all reachable NFA states,
// then find identical or mappable DFA state or add a new one
acts = closure(clos1, clos2, tagpool, tcpool, rules, maxtagver, newvers, dump.shadow, tags);
find_state(*this, i, c, kernels, clos2, acts, dump);
}
+ // mark tags with history
+ for (newvers_t::iterator j = newvers.begin(); j != newvers.end(); ++j) {
+ if (history(tags[j->first.tag])) listvers.insert(abs(j->second));
+ }
}
if (!opts->posix_captures) {
std::vector<uint32_t> &charset;
std::valarray<Rule> &rules;
std::vector<Tag> &tags;
+ std::set<tagver_t> &listvers;
tagver_t *finvers;
tcpool_t &tcpool;
tagver_t maxtagver;