]> granicus.if.org Git - re2c/commitdiff
Cleaned up code that merges arcs while tunneling DFA.
authorUlya Trofimovich <skvadrik@gmail.com>
Sat, 30 Apr 2016 15:18:54 +0000 (16:18 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Sat, 30 Apr 2016 15:18:54 +0000 (16:18 +0100)
Behaviour should be unchanged.

re2c/src/ir/adfa/prepare.cc

index 9e69f69fc3865f4d75fa9436709dbbc64918a022..050fd2abd1b29fd53ff4d71c0f123f484807fc48 100644 (file)
@@ -26,79 +26,37 @@ void DFA::split(State *s)
        s->go.span[0].to = move;
 }
 
-static uint32_t merge(Span *x0, State *fg, State *bg)
+static uint32_t merge(Span *x, State *fg, State *bg)
 {
-       Span *x = x0, *f = fg->go.span, *b = bg->go.span;
-       uint32_t nf = fg->go.nSpans, nb = bg->go.nSpans;
-       State *prev = NULL, *to;
-       // NB: we assume both spans are for same range
-
-       for (;;)
-       {
-               if (f->ub == b->ub)
-               {
-                       to = f->to == b->to ? bg : f->to;
-
-                       if (to == prev)
-                       {
-                               --x;
-                       }
-                       else
-                       {
-                               x->to = prev = to;
-                       }
-
-                       x->ub = f->ub;
-                       ++x;
-                       ++f;
-                       --nf;
-                       ++b;
-                       --nb;
-
-                       if (nf == 0 && nb == 0)
-                       {
-                               return static_cast<uint32_t> (x - x0);
-                       }
+       Span *f = fg->go.span;
+       Span *b = bg->go.span;
+       Span *const fe = f + fg->go.nSpans;
+       Span *const be = b + bg->go.nSpans;
+       Span *const x0 = x;
+
+       for (;!(f == fe && b == be);) {
+               if (f->to == b->to) {
+                       x->to = bg;
+               } else {
+                       x->to = f->to;
                }
-
-               while (f->ub < b->ub)
-               {
-                       to = f->to == b->to ? bg : f->to;
-
-                       if (to == prev)
-                       {
-                               --x;
-                       }
-                       else
-                       {
-                               x->to = prev = to;
-                       }
-
-                       x->ub = f->ub;
+               if (x == x0
+                       || x[-1].to != x->to) {
                        ++x;
-                       ++f;
-                       --nf;
                }
+               x[-1].ub = std::min(f->ub, b->ub);
 
-               while (b->ub < f->ub)
-               {
-                       to = b->to == f->to ? bg : f->to;
-
-                       if (to == prev)
-                       {
-                               --x;
-                       }
-                       else
-                       {
-                               x->to = prev = to;
-                       }
-
-                       x->ub = b->ub;
-                       ++x;
+               if (f->ub < b->ub) {
+                       ++f;
+               } else if (f->ub > b->ub) {
+                       ++b;
+               } else {
+                       ++f;
                        ++b;
-                       --nb;
                }
        }
+
+       return static_cast<uint32_t>(x - x0);
 }
 
 void DFA::findBaseState()