]> granicus.if.org Git - re2c/commitdiff
Forbid merging of tag variables for tags with and without history.
authorUlya Trofimovich <skvadrik@gmail.com>
Mon, 17 Jul 2017 21:36:02 +0000 (22:36 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Mon, 17 Jul 2017 21:36:02 +0000 (22:36 +0100)
re2c/src/adfa/adfa.cc
re2c/src/adfa/adfa.h
re2c/src/code/emit_dfa.cc
re2c/src/dfa/cfg/interfere.cc
re2c/src/dfa/cfg/rename.cc
re2c/src/dfa/determinization.cc
re2c/src/dfa/dfa.h

index e5267700a2afb07cd64e8cf91478fe8e816b2ce2..48981f42feab599e05d605436b75af31c24f1136 100644 (file)
@@ -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;
 }
index 05c3b524e1ae6e78137b1c4811f64e225def985a..50e3c1d3e6ea57362ecdaec2337215c4d0d04fc9 100644 (file)
@@ -70,6 +70,7 @@ struct DFA
        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;
index 00ccca3bde0005a4bf12a034d04cbd306aa6bdb1..93600359a8ba98e0080bb644a273818190d0a692 100644 (file)
@@ -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());
        }
index 8562e76e49f7132fb27632097be8573001e8d706..e2d91b920002d20f9a03f4800093dc02c3b4bb68 100644 (file)
@@ -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<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;
@@ -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<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;
 }
index 64f5fc4bfa412f1a21b56e355fc6d152690ddf91..5b660ecd63a5d57e7396a0c1e50577a4b41aeed0 100644 (file)
@@ -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<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
index 70a1f83a9fe1563040fd0730de514cade4893c0d..6efbf292a590ca6013f88c6de611ab0be90a62ad 100644 (file)
@@ -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<tagver_t>)
        , 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<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
@@ -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) {
index 85db8d6ce7416612e129a7177d39965eb3d5b094..78e04f727ef872f7c626d3df130a9c8760ca4525 100644 (file)
@@ -54,6 +54,7 @@ struct dfa_t
        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;