From: Ulya Trofimovich Date: Sat, 8 Apr 2017 10:35:14 +0000 (+0100) Subject: 'save' commands also need topological sorting: they may depend on history. X-Git-Tag: 1.0~39^2~69 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9cfa0ca3c93545ffaef500834a2e2406b00b0e21;p=re2c 'save' commands also need topological sorting: they may depend on history. --- diff --git a/re2c/src/dfa/find_state.cc b/re2c/src/dfa/find_state.cc index 95a85423..9a36b217 100644 --- a/re2c/src/dfa/find_state.cc +++ b/re2c/src/dfa/find_state.cc @@ -292,7 +292,7 @@ tcmd_t *kernels_t::actions(tcmd_t *acts) *pa = acts; // see note [topological ordering of copy commands] - tcmd_t::topsort(©, indeg); + tcmd_t::topsort1(©, indeg); return copy; } diff --git a/re2c/src/dfa/tcmd.cc b/re2c/src/dfa/tcmd.cc index 9fa77fd3..2ea2f4d8 100644 --- a/re2c/src/dfa/tcmd.cc +++ b/re2c/src/dfa/tcmd.cc @@ -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() diff --git a/re2c/src/dfa/tcmd.h b/re2c/src/dfa/tcmd.h index 1dbd3f80..93aa6334 100644 --- a/re2c/src/dfa/tcmd.h +++ b/re2c/src/dfa/tcmd.h @@ -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);