From: Ulya Trofimovich Date: Wed, 11 May 2016 13:48:25 +0000 (+0100) Subject: Don't loose tags on epsilon-loops in NFA. X-Git-Tag: 1.0~39^2~305 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=12f748758d0fb4c74cd872a01f96dd48e8242944;p=re2c Don't loose tags on epsilon-loops in NFA. --- diff --git a/re2c/src/ir/dfa/determinization.cc b/re2c/src/ir/dfa/determinization.cc index db4d2582..ba9c85d4 100644 --- a/re2c/src/ir/dfa/determinization.cc +++ b/re2c/src/ir/dfa/determinization.cc @@ -66,11 +66,13 @@ struct kitem_t static void closure(kitem_t *const kernel, kitem_t *&kend, nfa_state_t *n, bool *tags, bool *badtags, size_t ntags) { - if (n->mark) { + // trace the first iteration of each loop: + // epsilon-loops may add ney tags and reveal conflicts + if (n->loop > 1) { return; } - n->mark = true; + ++n->loop; switch (n->type) { case nfa_state_t::ALT: closure(kernel, kend, n->alt.out2, tags, badtags, ntags); @@ -101,7 +103,7 @@ static void closure(kitem_t *const kernel, kitem_t *&kend, break; } } - n->mark = false; + --n->loop; } static size_t find_state(kitem_t *kernel, kitem_t *kend, diff --git a/re2c/src/ir/nfa/nfa.h b/re2c/src/ir/nfa/nfa.h index f93d4438..b3e60187 100644 --- a/re2c/src/ir/nfa/nfa.h +++ b/re2c/src/ir/nfa/nfa.h @@ -35,7 +35,7 @@ struct nfa_state_t } tag; }; size_t rule; - bool mark; + uint8_t loop; void make_alt(size_t r, nfa_state_t *s1, nfa_state_t *s2) { @@ -43,7 +43,7 @@ struct nfa_state_t alt.out1 = s1; alt.out2 = s2; rule = r; - mark = false; + loop = 0; } void make_ran(size_t r, nfa_state_t *s, const Range *p) { @@ -51,7 +51,7 @@ struct nfa_state_t ran.out = s; ran.ran = p; rule = r; - mark = false; + loop = 0; } void make_tag(size_t r, nfa_state_t *s, size_t i) { @@ -59,13 +59,13 @@ struct nfa_state_t tag.out = s; tag.info = i; rule = r; - mark = false; + loop = 0; } void make_fin(size_t r) { type = FIN; rule = r; - mark = false; + loop = 0; } }; diff --git a/re2c/test/tags/nondet_iter.--tags.c b/re2c/test/tags/nondet_iter.--tags.c new file mode 100644 index 00000000..759a4fc6 --- /dev/null +++ b/re2c/test/tags/nondet_iter.--tags.c @@ -0,0 +1,10 @@ +re2c: error: line 5: tag 'b' is nondeterministic [-Werror-nondeterministic-tags] +re2c: error: line 6: tag 'e' is nondeterministic [-Werror-nondeterministic-tags] +re2c: error: line 8: tag 'c' is nondeterministic [-Werror-nondeterministic-tags] +re2c: error: line 9: tag 'f' is nondeterministic [-Werror-nondeterministic-tags] +re2c: warning: line 2: rule matches empty string [-Wmatch-empty-string] +re2c: warning: line 3: rule matches empty string [-Wmatch-empty-string] +re2c: warning: line 5: rule matches empty string [-Wmatch-empty-string] +re2c: warning: line 6: rule matches empty string [-Wmatch-empty-string] +re2c: warning: line 8: rule matches empty string [-Wmatch-empty-string] +re2c: warning: line 9: rule matches empty string [-Wmatch-empty-string] diff --git a/re2c/test/tags/nondet_iter.--tags.re b/re2c/test/tags/nondet_iter.--tags.re new file mode 100644 index 00000000..6943d58f --- /dev/null +++ b/re2c/test/tags/nondet_iter.--tags.re @@ -0,0 +1,10 @@ +/*!re2c + ((@a "a")*)* { @a } + (("d" @d)*)* { @d } + + (@b "b"*)* { @b } + ("e"* @e)* { @e } + + (@c "c"+)* { @c } + ("f"+ @f)* { @f } +*/