]> granicus.if.org Git - re2c/commitdiff
Compact DFA states after minimization.
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 13 Jan 2016 09:12:14 +0000 (09:12 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 13 Jan 2016 09:12:14 +0000 (09:12 +0000)
re2c/src/ir/adfa/adfa.cc
re2c/src/ir/dfa/minimization.cc

index 897d708ef2c31c3f8b4c28b132f94981ea1f15a2..0219690d5f20348f7da4298ea76c4a98b9884c41 100644 (file)
@@ -43,35 +43,32 @@ DFA::DFA
        State **i2s = new State*[nstates];
        for (size_t i = 0; i < nstates; ++i)
        {
-               i2s[i] = dfa.states[i] ? new State : NULL;
+               i2s[i] = new State;
        }
 
        State **p = &head;
        for (size_t i = 0; i < nstates; ++i)
        {
+               dfa_state_t *t = dfa.states[i];
                State *s = i2s[i];
-               if (s)
+
+               ++nStates;
+               *p = s;
+               p = &s->next;
+
+               s->isPreCtxt = t->ctx;
+               s->rule = t->rule;
+               s->fill = fill[i];
+               s->go.span = allocate<Span>(nchars);
+               uint32_t j = 0;
+               for (uint32_t c = 0; c < nchars; ++j)
                {
-                       ++nStates;
-
-                       *p = s;
-                       p = &s->next;
-
-                       dfa_state_t *t = dfa.states[i];
-                       s->isPreCtxt = t->ctx;
-                       s->rule = t->rule;
-                       s->fill = fill[i];
-                       s->go.span = allocate<Span>(nchars);
-                       uint32_t j = 0;
-                       for (uint32_t c = 0; c < nchars; ++j)
-                       {
-                               const size_t to = t->arcs[c];
-                               for (;++c < nchars && t->arcs[c] == to;);
-                               s->go.span[j].to = to == dfa_t::NIL ? NULL : i2s[to];
-                               s->go.span[j].ub = charset[c];
-                       }
-                       s->go.nSpans = j;
+                       const size_t to = t->arcs[c];
+                       for (;++c < nchars && t->arcs[c] == to;);
+                       s->go.span[j].to = to == dfa_t::NIL ? NULL : i2s[to];
+                       s->go.span[j].ub = charset[c];
                }
+               s->go.nSpans = j;
        }
        *p = NULL;
 
index 0854d04e0f2ed6d7afc36aefde051131de66c107..4b73c152dffea3a976a2b56769a73ffe2d8491d7 100644 (file)
@@ -210,26 +210,39 @@ void minimization(dfa_t &dfa)
                        break;
        }
 
+       size_t *compact = new size_t[count];
+       for (size_t i = 0, j = 0; i < count; ++i)
+       {
+               if (i == part[i])
+               {
+                       compact[i] = j++;
+               }
+       }
+
+       size_t new_count = 0;
        for (size_t i = 0; i < count; ++i)
        {
+               dfa_state_t *s = dfa.states[i];
                if (i == part[i])
                {
-                       size_t *arcs = dfa.states[i]->arcs;
+                       size_t *arcs = s->arcs;
                        for (size_t c = 0; c < dfa.nchars; ++c)
                        {
                                if (arcs[c] != dfa_t::NIL)
                                {
-                                       arcs[c] = part[arcs[c]];
+                                       arcs[c] = compact[part[arcs[c]]];
                                }
                        }
+                       dfa.states[new_count++] = s;
                }
                else
                {
-                       delete dfa.states[i];
-                       dfa.states[i] = NULL;
+                       delete s;
                }
        }
+       dfa.states.resize(new_count);
 
+       delete[] compact;
        delete[] part;
 }