]> granicus.if.org Git - re2c/commitdiff
Tags can be calculated immediately after closure construction.
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 28 Sep 2016 14:52:11 +0000 (15:52 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 28 Sep 2016 14:52:11 +0000 (15:52 +0100)
re2c/src/ir/dfa/closure.cc
re2c/src/ir/dfa/closure.h
re2c/src/ir/dfa/determinization.cc
re2c/src/ir/tagpool.cc
re2c/src/ir/tagpool.h

index 48f3b3bcd799890c4fae5b00bf871dd5c453f57a..2ef111a26eca270af1f024a738de35e1e775dcbc 100644 (file)
@@ -10,20 +10,34 @@ static void closure_one(closure_t &clos, Tagpool &tagpool, nfa_state_t *n, bool
 static void check_tags(const Tagpool &tagpool, size_t oldidx, size_t newidx, bool *badtags);
 static bool compare_by_rule(const clos_t &c1, const clos_t &c2);
 static void prune_final_items(closure_t &clos, std::valarray<Rule> &rules);
+static void merge_tags_with_mask(bool *oldtags, const bool *newtags, bool *oldmask, const bool *newmask, bool *badtags, size_t ntags);
 
-void closure(const closure_t &clos1, closure_t &clos2,
-       Tagpool &tagpool, std::valarray<Rule> &rules,
-       bool *tags, bool *badtags)
+size_t closure(const closure_t &clos1, closure_t &clos2,
+       Tagpool &tagpool, std::valarray<Rule> &rules, bool *badtags)
 {
+       const size_t ntags = tagpool.ntags;
+       bool *buf1 = tagpool.buffer1,
+               *buf2 = tagpool.buffer2;
+
        clos2.clear();
+       std::fill(buf1, buf1 + ntags, false);
        for (cclositer_t c = clos1.begin(); c != clos1.end(); ++c) {
-               closure_one(clos2, tagpool, c->state, tags, badtags);
+               closure_one(clos2, tagpool, c->state, buf1, badtags);
        }
 
        prune_final_items(clos2, rules);
 
        // sort closure: we need this to compare closures by hash
        std::sort(clos2.begin(), clos2.end(), compare_by_rule);
+
+       // merge tags from different rules
+       std::fill(buf1, buf1 + ntags, false);
+       std::fill(buf2, buf2 + ntags, false);
+       for (cclositer_t c = clos1.begin(); c != clos1.end(); ++c) {
+               merge_tags_with_mask(buf1, tagpool[c->tagidx], buf2,
+                       tagpool[rules[c->state->rule].tags], badtags, ntags);
+       }
+       return tagpool.insert(buf1);
 }
 
 /* note [epsilon-closures in tagged NFA]
@@ -156,4 +170,19 @@ void prune_final_items(closure_t &clos, std::valarray<Rule> &rules)
        }
 }
 
+void merge_tags_with_mask(bool *oldtags, const bool *newtags,
+       bool *oldmask, const bool *newmask,
+       bool *badtags, size_t ntags)
+{
+       for (size_t i = 0; i < ntags; ++i) {
+               const bool bad = oldmask[i] & newmask[i] & (oldtags[i] ^ newtags[i]);
+               // don't merge conflicting tags, only note the conflict
+               if (!bad) {
+                       oldtags[i] |= newtags[i];
+               }
+               badtags[i] |= bad;
+               oldmask[i] |= newmask[i];
+       }
+}
+
 } // namespace re2c
index 9cf566573f8acfe9d460bd28a8d4d955916293da..08b51f1ea1f6d24556cae2afcdf213c3986d2cdf 100644 (file)
@@ -24,9 +24,8 @@ typedef std::vector<clos_t> closure_t;
 typedef closure_t::iterator clositer_t;
 typedef closure_t::const_iterator cclositer_t;
 
-void closure(const closure_t &clos1, closure_t &clos2,
-       Tagpool &tagpool, std::valarray<Rule> &rules,
-       bool *tags, bool *badtags);
+size_t closure(const closure_t &clos1, closure_t &clos2,
+       Tagpool &tagpool, std::valarray<Rule> &rules, bool *badtags);
 
 clos_t::clos_t()
        : state(NULL)
index 6ac38278c8063ddf24926f364b812e77eb07d9ce..a33ec73b0cbf9d5a761a25fc487ce526333c84a9 100644 (file)
@@ -16,6 +16,8 @@ namespace re2c
 
 static nfa_state_t *transition(nfa_state_t *state, uint32_t symbol);
 static void reach(const closure_t &clos1, closure_t &clos2, uint32_t symbol);
+static void warn_bad_tags(const bool *badtags, const std::valarray<Tag> &tags,
+       const std::valarray<Rule> &rules, const std::string &cond);
 
 const size_t dfa_t::NIL = std::numeric_limits<size_t>::max();
 
@@ -45,21 +47,6 @@ void reach(const closure_t &clos1, closure_t &clos2, uint32_t symbol)
        }
 }
 
-static void merge_tags_with_mask(bool *oldtags, const bool *newtags,
-       bool *oldmask, const bool *newmask,
-       bool *badtags, size_t ntags)
-{
-       for (size_t i = 0; i < ntags; ++i) {
-               const bool bad = oldmask[i] & newmask[i] & (oldtags[i] ^ newtags[i]);
-               // don't merge conflicting tags, only note the conflict
-               if (!bad) {
-                       oldtags[i] |= newtags[i];
-               }
-               badtags[i] |= bad;
-               oldmask[i] |= newmask[i];
-       }
-}
-
 dfa_t::dfa_t(const nfa_t &nfa,
        const charset_t &charset,
        const std::string &cond)
@@ -71,14 +58,10 @@ dfa_t::dfa_t(const nfa_t &nfa,
 {
        clospool_t clospool;
        closure_t clos1, clos2;
-       const size_t ntags = tags.size();
-       bool *ktags = new bool[ntags]();
-       bool *badtags = new bool[ntags]();
-       bool *arctags = new bool[ntags];
-       bool *mask = new bool[ntags];
+       bool *badtags = new bool[tags.size()]();
 
        clos1.push_back(clos_t(nfa.root, ZERO_TAGS));
-       closure(clos1, clos2, tagpool, rules, ktags, badtags);
+       closure(clos1, clos2, tagpool, rules, badtags);
        find_state(clos2, clospool);
 
        for (size_t i = 0; i < clospool.size(); ++i) {
@@ -88,16 +71,8 @@ dfa_t::dfa_t(const nfa_t &nfa,
 
                for (size_t c = 0; c < nchars; ++c) {
                        reach(clos0, clos1, charset[c]);
-                       closure(clos1, clos2, tagpool, rules, ktags, badtags);
+                       s->tags[c] = closure(clos1, clos2, tagpool, rules, badtags);
                        s->arcs[c] = find_state(clos2, clospool);
-
-                       memset(arctags, 0, ntags * sizeof(bool));
-                       memset(mask, 0, ntags * sizeof(bool));
-                       for (cclositer_t p = clos1.begin(); p != clos1.end(); ++p) {
-                               merge_tags_with_mask(arctags, tagpool[p->tagidx], mask,
-                                       tagpool[rules[p->state->rule].tags], badtags, ntags);
-                       }
-                       s->tags[c] = tagpool.insert(arctags);
                }
 
                // see note [at most one final item per closure]
@@ -110,17 +85,23 @@ dfa_t::dfa_t(const nfa_t &nfa,
                }
        }
 
+       warn_bad_tags(badtags, tags, rules, cond);
+       delete[] badtags;
+}
+
+void warn_bad_tags(const bool *badtags,
+       const std::valarray<Tag> &tags,
+       const std::valarray<Rule> &rules,
+       const std::string &cond)
+{
+       const size_t ntags = tags.size();
        for (size_t i = 0; i < ntags; ++i) {
                if (badtags[i]) {
-                       warn.nondeterministic_tags(rules[tags[i].rule].info->loc.line,
-                               cond, tags[i].name);
+                       const Tag &tag = tags[i];
+                       const uint32_t line = rules[tag.rule].info->loc.line;
+                       warn.nondeterministic_tags(line, cond, tag.name);
                }
        }
-
-       delete[] ktags;
-       delete[] badtags;
-       delete[] arctags;
-       delete[] mask;
 }
 
 dfa_t::~dfa_t()
index 206d2b8c5f253fd1d227717cc36a058fe7362a6d..ffd0b3e120144923de2e20abc814529820f5ced3 100644 (file)
@@ -7,17 +7,20 @@ namespace re2c
 {
 
 Tagpool::Tagpool(size_t n)
-       : ntags(n)
-       , lookup()
-       , buff(new bool[ntags]())
+       : lookup()
+       , buffer(new bool[n * 3])
+       , ntags(n)
+       , buffer1(&buffer[n * 1])
+       , buffer2(&buffer[n * 2])
 {
        // all-zero tag configuration must have static number zero
-       assert(ZERO_TAGS == insert(buff));
+       std::fill(buffer, buffer + ntags, false);
+       assert(ZERO_TAGS == insert(buffer));
 }
 
 Tagpool::~Tagpool()
 {
-       delete[] buff;
+       delete[] buffer;
        const size_t n = lookup.size();
        for (size_t i = 0; i < n; ++i) {
                free(const_cast<bool*>(lookup[i]));
@@ -56,9 +59,9 @@ size_t Tagpool::orl(size_t t, size_t o)
        const bool *tags = operator[](t);
        const bool *ortags = operator[](o);
        for (size_t i = 0; i < ntags; ++i) {
-               buff[i] = tags[i] | ortags[i];
+               buffer[i] = tags[i] | ortags[i];
        }
-       return insert(buff);
+       return insert(buffer);
 }
 
 size_t Tagpool::andl(size_t t, size_t a)
@@ -72,9 +75,9 @@ size_t Tagpool::andl(size_t t, size_t a)
        const bool *tags = operator[](t);
        const bool *andtags = operator[](a);
        for (size_t i = 0; i < ntags; ++i) {
-               buff[i] = tags[i] & andtags[i];
+               buffer[i] = tags[i] & andtags[i];
        }
-       return insert(buff);
+       return insert(buffer);
 }
 
 size_t Tagpool::andlinv(size_t t, size_t a)
@@ -88,21 +91,21 @@ size_t Tagpool::andlinv(size_t t, size_t a)
        const bool *tags = operator[](t);
        const bool *andinvtags = operator[](a);
        for (size_t i = 0; i < ntags; ++i) {
-               buff[i] = tags[i] & ~andinvtags[i];
+               buffer[i] = tags[i] & ~andinvtags[i];
        }
-       return insert(buff);
+       return insert(buffer);
 }
 
 size_t Tagpool::subst(size_t t, const size_t *represent)
 {
        const bool *tags = operator[](t);
-       memset(buff, 0, ntags * sizeof(bool));
+       memset(buffer, 0, ntags * sizeof(bool));
        for (size_t i = 0; i < ntags; ++i) {
                if (tags[i]) {
-                       buff[represent[i]] = true;
+                       buffer[represent[i]] = true;
                }
        }
-       return insert(buff);
+       return insert(buffer);
 }
 
 } // namespace re2c
index 2a63833d4ddff1cf2b454b2e2a376b946aa6547f..5f032bab1b619f2dbfb5a8fcf8f773f02ea512da 100644 (file)
@@ -25,14 +25,16 @@ struct eqtag_t
 
 struct Tagpool
 {
-       const size_t ntags;
-
 private:
        typedef lookup_t<const bool*> taglookup_t;
        taglookup_t lookup;
-       bool *buff;
+       bool *buffer;
 
 public:
+       const size_t ntags;
+       bool *buffer1;
+       bool *buffer2;
+
        explicit Tagpool(size_t n);
        ~Tagpool();
        size_t insert(const bool *tags);