]> granicus.if.org Git - re2c/commitdiff
Don't merge conflicting tags, choose arbitrary configuration.
authorUlya Trofimovich <skvadrik@gmail.com>
Tue, 27 Sep 2016 14:48:27 +0000 (15:48 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Tue, 27 Sep 2016 14:48:27 +0000 (15:48 +0100)
Merging conflicting tags doesn't make sense: information is lost
anyway.

re2c/src/ir/dfa/closure.cc
re2c/src/ir/dfa/determinization.cc

index 540246e2aab0595636a570caac247b38d243c3a5..1cb052c41dc9f7d6d79b0127a9cba4872a637b6d 100644 (file)
@@ -7,7 +7,7 @@ namespace re2c
 {
 
 static void closure_one(closure_t &clos, nfa_state_t *n, bool *tags, bool *badtags, size_t ntags);
-static void merge_tags(bool *oldtags, const bool *newtags, bool *badtags, size_t ntags);
+static void check_tags(const bool *oldtags, const bool *newtags, bool *badtags, size_t ntags);
 
 void closure(const closure_t &clos1, closure_t &clos2, bool *tags, bool *badtags, size_t ntags)
 {
@@ -17,15 +17,6 @@ void closure(const closure_t &clos1, closure_t &clos2, bool *tags, bool *badtags
        }
 }
 
-void merge_tags(bool *oldtags, const bool *newtags,
-       bool *badtags, size_t ntags)
-{
-       for (size_t i = 0; i < ntags; ++i) {
-               badtags[i] |= oldtags[i] ^ newtags[i];
-               oldtags[i] |= newtags[i];
-       }
-}
-
 /* note [epsilon-closures in tagged NFA]
  *
  * DFA state is a set of NFA states.
@@ -72,9 +63,7 @@ void closure_one(closure_t &clos, nfa_state_t *n, bool *tags, bool *badtags, siz
                                memcpy(tagptr, tags, ntags * sizeof(bool));
                                clos.push_back(clos_t(n, tagptr));
                        } else {
-                               // it is impossible to reach the same NFA state from
-                               // different rules, so no need to mess with masks here
-                               merge_tags(c->tagptr, tags, badtags, ntags);
+                               check_tags(c->tagptr, tags, badtags, ntags);
                        }
                        break;
                }
@@ -82,4 +71,19 @@ void closure_one(closure_t &clos, nfa_state_t *n, bool *tags, bool *badtags, siz
        --n->loop;
 }
 
+/*
+ * Check configurations for possible conflicts.
+ * In case of conflict choose random configuration (e.g. the first one)
+ * and don't merge: merging only makes sense for tags from different
+ * rules, and it is impossible to reach the same NFA state from different
+ * rules (hence no need to mess with masks here).
+ */
+void check_tags(const bool *oldtags, const bool *newtags,
+       bool *badtags, size_t ntags)
+{
+       for (size_t i = 0; i < ntags; ++i) {
+               badtags[i] |= oldtags[i] ^ newtags[i];
+       }
+}
+
 } // namespace re2c
index 548ac58c3f6854790f4f21457d87fff4b3143194..fe6f12a9f6570501fc300c376e553635719523f1 100644 (file)
@@ -50,8 +50,12 @@ static void merge_tags_with_mask(bool *oldtags, const bool *newtags,
        bool *badtags, size_t ntags)
 {
        for (size_t i = 0; i < ntags; ++i) {
-               badtags[i] |= oldmask[i] & newmask[i] & (oldtags[i] ^ newtags[i]);
-               oldtags[i] |= newtags[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];
        }
 }