]> granicus.if.org Git - re2c/commitdiff
'save' commands also need topological sorting: they may depend on history.
authorUlya Trofimovich <skvadrik@gmail.com>
Sat, 8 Apr 2017 10:35:14 +0000 (11:35 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Sat, 8 Apr 2017 10:35:14 +0000 (11:35 +0100)
re2c/src/dfa/find_state.cc
re2c/src/dfa/tcmd.cc
re2c/src/dfa/tcmd.h

index 95a854237435ac89586e2d5c290d1cabe33a0347..9a36b21734ff2a0c704e2eb59cf40f42c950c234 100644 (file)
@@ -292,7 +292,7 @@ tcmd_t *kernels_t::actions(tcmd_t *acts)
        *pa = acts;
 
        // see note [topological ordering of copy commands]
-       tcmd_t::topsort(&copy, indeg);
+       tcmd_t::topsort1(&copy, indeg);
 
        return copy;
 }
index 9fa77fd3dc65609987d818d0c019abbd012d984c..2ea2f4d8546cb3fe446677cc0f770eb2902660ce 100644 (file)
@@ -134,6 +134,49 @@ tcmd_t **topsort_(tcmd_t **phead, uint32_t *indeg)
        return py;
 }
 
+static tagver_t depend(const tcmd_t *x)
+{
+       const tagver_t r = x->rhs, h = x->pred;
+       return tcmd_t::iscopy(r) ? r : h;
+}
+
+void tcmd_t::topsort1(tcmd_t **phead, uint32_t *indeg)
+{
+       tcmd_t
+               *x0 = *phead, **px, *x,
+               *y0 = NULL, **py, **py1;
+
+       // initialize in-degree
+       for (x = x0; x; x = x->next) {
+               ++indeg[depend(x)];
+       }
+
+       for (py = &y0;;) {
+               // reached end of list
+               if (!x0) break;
+
+               px = &x0;
+               py1 = py;
+               for (x = x0; x; x = x->next) {
+                       if (indeg[x->lhs] == 0) {
+                               --indeg[depend(x)];
+                               *py = x;
+                               py = &x->next;
+                       } else {
+                               *px = x;
+                               px = &x->next;
+                       }
+               }
+               *px = NULL;
+
+               // only cycles left
+               if (py == py1) break;
+       }
+       *py = x0;
+
+       *phead = y0;
+}
+
 tcpool_t::tcpool_t()
        : alc()
        , index()
index 1dbd3f8098e9fb0db1258316bfe7c7065e9aefed..93aa63341539d8877aa99788bb03bb7a46ce39a9 100644 (file)
@@ -21,6 +21,7 @@ struct tcmd_t
        static void swap(tcmd_t &x, tcmd_t &y);
        static bool equal(const tcmd_t &x, const tcmd_t &y);
        static void topsort(tcmd_t **phead, uint32_t *indeg);
+       static void topsort1(tcmd_t **phead, uint32_t *indeg);
        static bool iscopy(tagver_t rhs);
        static bool isset(const tcmd_t *cmd);
        static bool isadd(const tcmd_t *cmd);