From: Ulya Trofimovich Date: Tue, 27 Sep 2016 14:48:27 +0000 (+0100) Subject: Don't merge conflicting tags, choose arbitrary configuration. X-Git-Tag: 1.0~39^2~275 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2ead99e4f9e2628faf35f424d57e740b47c6d5cd;p=re2c Don't merge conflicting tags, choose arbitrary configuration. Merging conflicting tags doesn't make sense: information is lost anyway. --- diff --git a/re2c/src/ir/dfa/closure.cc b/re2c/src/ir/dfa/closure.cc index 540246e2..1cb052c4 100644 --- a/re2c/src/ir/dfa/closure.cc +++ b/re2c/src/ir/dfa/closure.cc @@ -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 diff --git a/re2c/src/ir/dfa/determinization.cc b/re2c/src/ir/dfa/determinization.cc index 548ac58c..fe6f12a9 100644 --- a/re2c/src/ir/dfa/determinization.cc +++ b/re2c/src/ir/dfa/determinization.cc @@ -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]; } }