From: Ulya Trofimovich Date: Mon, 17 Jul 2017 21:36:02 +0000 (+0100) Subject: Forbid merging of tag variables for tags with and without history. X-Git-Tag: 1.0~39^2~26 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ddb3d8507872f9e98f8df8e4929631b88ff31862;p=re2c Forbid merging of tag variables for tags with and without history. --- diff --git a/re2c/src/adfa/adfa.cc b/re2c/src/adfa/adfa.cc index e5267700..48981f42 100644 --- a/re2c/src/adfa/adfa.cc +++ b/re2c/src/adfa/adfa.cc @@ -37,6 +37,7 @@ DFA::DFA , charset(dfa.charset) , rules(dfa.rules) , tags(dfa.tags) + , listvers(dfa.listvers) , finvers(dfa.finvers) , tcpool(dfa.tcpool) , max_fill (0) @@ -105,6 +106,7 @@ DFA::~DFA() delete &charset; delete &rules; delete &tags; + delete &listvers; delete[] finvers; delete &tcpool; } diff --git a/re2c/src/adfa/adfa.h b/re2c/src/adfa/adfa.h index 05c3b524..50e3c1d3 100644 --- a/re2c/src/adfa/adfa.h +++ b/re2c/src/adfa/adfa.h @@ -70,6 +70,7 @@ struct DFA std::vector &charset; std::valarray &rules; std::vector &tags; + std::set &listvers; const tagver_t *finvers; tcpool_t &tcpool; size_t max_fill; diff --git a/re2c/src/code/emit_dfa.cc b/re2c/src/code/emit_dfa.cc index 00ccca3b..93600359 100644 --- a/re2c/src/code/emit_dfa.cc +++ b/re2c/src/code/emit_dfa.cc @@ -121,50 +121,6 @@ void DFA::emit_dot(OutputFile &o, bool last_cond) const } } -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; @@ -181,17 +137,14 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra 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()); } diff --git a/re2c/src/dfa/cfg/interfere.cc b/re2c/src/dfa/cfg/interfere.cc index 8562e76e..e2d91b92 100644 --- a/re2c/src/dfa/cfg/interfere.cc +++ b/re2c/src/dfa/cfg/interfere.cc @@ -10,7 +10,8 @@ static void interfere(const tcmd_t *cmd, const bool *live, bool *interf, bool *b void cfg_t::interference(const cfg_t &cfg, const bool *live, bool *interf) { - const size_t nver = static_cast(cfg.dfa.maxtagver) + 1; + const tagver_t maxver = cfg.dfa.maxtagver + 1; + const size_t nver = static_cast(maxver); bool *buf = new bool[nver]; vals_t *vals = new vals_t[nver](); const cfg_bb_t *b = cfg.bblocks, *e = b + cfg.nbbfin; @@ -20,6 +21,16 @@ void cfg_t::interference(const cfg_t &cfg, const bool *live, bool *interf) interfere(b->cmd, live, interf, buf, vals, nver); } + // versions of tags with/without history interfere + std::set &lvs = cfg.dfa.listvers; + for (std::set::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; } diff --git a/re2c/src/dfa/cfg/rename.cc b/re2c/src/dfa/cfg/rename.cc index 64f5fc4b..5b660ecd 100644 --- a/re2c/src/dfa/cfg/rename.cc +++ b/re2c/src/dfa/cfg/rename.cc @@ -35,6 +35,13 @@ void cfg_t::renaming(cfg_t &cfg, const tagver_t *ver2new, tagver_t maxver) f = ver2new[f]; } } + + // versions of tags with history + std::set newlvs, &oldlvs = cfg.dfa.listvers; + for (std::set::iterator i = oldlvs.begin(); i != oldlvs.end(); ++i) { + newlvs.insert(ver2new[*i]); + } + oldlvs.swap(newlvs); } } // namespace re2c diff --git a/re2c/src/dfa/determinization.cc b/re2c/src/dfa/determinization.cc index 70a1f83a..6efbf292 100644 --- a/re2c/src/dfa/determinization.cc +++ b/re2c/src/dfa/determinization.cc @@ -56,6 +56,7 @@ dfa_t::dfa_t(const nfa_t &nfa, const opt_t *opts, , charset(nfa.charset) , rules(nfa.rules) , tags(nfa.tags) + , listvers(*new std::set) , finvers(NULL) , tcpool(*new tcpool_t) , maxtagver(0) @@ -84,6 +85,15 @@ dfa_t::dfa_t(const nfa_t &nfa, const opt_t *opts, 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(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 @@ -100,6 +110,10 @@ dfa_t::dfa_t(const nfa_t &nfa, const opt_t *opts, 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) { diff --git a/re2c/src/dfa/dfa.h b/re2c/src/dfa/dfa.h index 85db8d6c..78e04f72 100644 --- a/re2c/src/dfa/dfa.h +++ b/re2c/src/dfa/dfa.h @@ -54,6 +54,7 @@ struct dfa_t std::vector &charset; std::valarray &rules; std::vector &tags; + std::set &listvers; tagver_t *finvers; tcpool_t &tcpool; tagver_t maxtagver;