From: Ulya Trofimovich Date: Mon, 13 Aug 2018 22:02:01 +0000 (+0100) Subject: Moved POSIX disambiguation algorithm to a separate file. X-Git-Tag: 1.1~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b267cb922c57973cf963a9922cc9861e9f192ba9;p=re2c Moved POSIX disambiguation algorithm to a separate file. --- diff --git a/re2c/Makefile.am b/re2c/Makefile.am index 6a2f2dbd..b2d26f5f 100644 --- a/re2c/Makefile.am +++ b/re2c/Makefile.am @@ -109,6 +109,7 @@ SRC = \ src/dfa/fillpoints.cc \ src/dfa/find_state.cc \ src/dfa/minimization.cc \ + src/dfa/posix_precedence.cc \ src/dfa/tag_history.cc \ src/dfa/tagver_table.cc \ src/dfa/tcmd.cc \ diff --git a/re2c/src/dfa/posix_precedence.cc b/re2c/src/dfa/posix_precedence.cc new file mode 100644 index 00000000..1bcdf5f8 --- /dev/null +++ b/re2c/src/dfa/posix_precedence.cc @@ -0,0 +1,136 @@ +#include +#include + +#include "src/dfa/determinization.h" +#include "src/dfa/tag_history.h" + + +namespace re2c +{ + +static void reconstruct_history(const tag_history_t &, tag_path_t &, hidx_t); +static int32_t unpack_longest(int32_t); +static int32_t unpack_leftmost(int32_t); + + +int32_t precedence(determ_context_t &ctx, + const clos_t &x, const clos_t &y, int32_t &rhox, int32_t &rhoy) +{ + const hidx_t xl = x.tlook, yl = y.tlook; + const uint32_t xo = x.origin, yo = y.origin; + + if (xl == yl && xo == yo) { + rhox = rhoy = -1; + return 0; + } + + tag_history_t &thist = ctx.dc_taghistory; + tag_path_t &p1 = thist.path1, &p2 = thist.path2; + + reconstruct_history(thist, p1, xl); + reconstruct_history(thist, p2, yl); + + tag_path_t::const_reverse_iterator + i1 = p1.rbegin(), e1 = p1.rend(), j1 = i1, g1, + i2 = p2.rbegin(), e2 = p2.rend(), j2 = i2, g2; + + const std::vector &tags = ctx.dc_dfa.tags; + size_t nclos = 0; + const prectable_t *prectbl = NULL; + const bool fork_frame = xo == yo; + + if (fork_frame) { + // find fork + for (; j1 != e1 && j2 != e2 && *j1 == *j2; ++j1, ++j2); + } + else { + // get precedence table and size of the origin state + const kernel_t *k = ctx.dc_kernels[ctx.dc_origin]; + nclos = k->size; + prectbl = k->prectbl; + } + + // longest precedence + if (!fork_frame) { + rhox = unpack_longest(prectbl[xo * nclos + yo]); + rhoy = unpack_longest(prectbl[yo * nclos + xo]); + } + else { + rhox = rhoy = std::numeric_limits::max(); + if (j1 > i1) rhox = rhoy = tags[(j1 - 1)->idx].height; + } + for (g1 = j1; g1 != e1; ++g1) { + rhox = std::min(rhox, tags[g1->idx].height); + } + for (g2 = j2; g2 != e2; ++g2) { + rhoy = std::min(rhoy, tags[g2->idx].height); + } + if (rhox > rhoy) return -1; + if (rhox < rhoy) return 1; + + // leftmost precedence + if (!fork_frame) { + return unpack_leftmost(prectbl[xo * nclos + yo]); + } + else { + // equal => not less + if (j1 == e1 && j2 == e2) return 0; + + // shorter => less + if (j1 == e1) return -1; + if (j2 == e2) return 1; + + const uint32_t idx1 = j1->idx, idx2 = j2->idx; + const bool neg1 = j1->neg, neg2 = j2->neg; + + // can't be both closing + assert(!(idx1 % 2 == 1 && idx2 % 2 == 1)); + + // closing vs opening: closing wins + if (idx1 % 2 == 1) return -1; + if (idx2 % 2 == 1) return 1; + + // can't be both negative + assert(!(neg1 && neg2)); + + // positive vs negative: positive wins + if (neg1) return 1; + if (neg2) return -1; + + // positive vs positive: smaller wins + // (this case is only possible because multiple + // top-level RE don't have proper negative tags) + if (idx1 < idx2) return -1; + if (idx1 > idx2) return 1; + } + + // unreachable + assert(false); + return 0; +} + + +void reconstruct_history(const tag_history_t &history, + tag_path_t &path, hidx_t idx) +{ + path.clear(); + for (; idx != HROOT; idx = history.pred(idx)) { + path.push_back(history.info(idx)); + } +} + + +int32_t unpack_longest(int32_t value) +{ + // lower 30 bits + return value & 0x3fffFFFF; +} + + +int32_t unpack_leftmost(int32_t value) +{ + // higher 2 bits + return value >> 30u; +} + +} // namespace re2c diff --git a/re2c/src/dfa/tag_history.cc b/re2c/src/dfa/tag_history.cc index fbaeadb2..f3acdee4 100644 --- a/re2c/src/dfa/tag_history.cc +++ b/re2c/src/dfa/tag_history.cc @@ -1,31 +1,9 @@ -#include -#include - -#include "src/dfa/determinization.h" #include "src/dfa/tag_history.h" namespace re2c { -static const tagver_t DELIM = TAGVER_CURSOR - 1; - - -tag_history_t::tag_history_t(): nodes(), path1(), path2() {} - - -hidx_t tag_history_t::pred(hidx_t i) const { return nodes[i].pred; } - - -tag_info_t tag_history_t::info(hidx_t i) const { return nodes[i].info; } - - -tagver_t tag_history_t::elem(hidx_t i) const { return nodes[i].info.neg ? TAGVER_BOTTOM : TAGVER_CURSOR; } - - -size_t tag_history_t::tag(hidx_t i) const { return nodes[i].info.idx; } - - hidx_t tag_history_t::push(hidx_t idx, tag_info_t info) { node_t x = {idx, info}; @@ -60,123 +38,4 @@ int32_t tag_history_t::compare_reversed(hidx_t x, hidx_t y, size_t t) const } } - -static void reconstruct_history(const tag_history_t &history, - tag_path_t &path, hidx_t idx) -{ - path.clear(); - for (; idx != HROOT; idx = history.pred(idx)) { - path.push_back(history.info(idx)); - } -} - - -static inline int32_t unpack_longest(int32_t value) -{ - // lower 30 bits - return value & 0x3fffFFFF; -} - - -static inline int32_t unpack_leftmost(int32_t value) -{ - // higher 2 bits - return value >> 30u; -} - - -int32_t precedence(determ_context_t &ctx, - const clos_t &x, const clos_t &y, int32_t &rhox, int32_t &rhoy) -{ - const hidx_t xl = x.tlook, yl = y.tlook; - const uint32_t xo = x.origin, yo = y.origin; - - if (xl == yl && xo == yo) { - rhox = rhoy = -1; - return 0; - } - - tag_history_t &thist = ctx.dc_taghistory; - tag_path_t &p1 = thist.path1, &p2 = thist.path2; - reconstruct_history(thist, p1, xl); - reconstruct_history(thist, p2, yl); - tag_path_t::const_reverse_iterator - i1 = p1.rbegin(), e1 = p1.rend(), j1 = i1, g1, - i2 = p2.rbegin(), e2 = p2.rend(), j2 = i2, g2; - - const std::vector &tags = ctx.dc_dfa.tags; - size_t nclos = 0; - const prectable_t *prectbl = NULL; - const bool fork_frame = xo == yo; - - if (fork_frame) { - // find fork - for (; j1 != e1 && j2 != e2 && *j1 == *j2; ++j1, ++j2); - } - else { - // get precedence table and size of the origin state - const kernel_t *k = ctx.dc_kernels[ctx.dc_origin]; - nclos = k->size; - prectbl = k->prectbl; - } - - // longest precedence - if (!fork_frame) { - rhox = unpack_longest(prectbl[xo * nclos + yo]); - rhoy = unpack_longest(prectbl[yo * nclos + xo]); - } - else { - rhox = rhoy = std::numeric_limits::max(); - if (j1 > i1) rhox = rhoy = tags[(j1 - 1)->idx].height; - } - for (g1 = j1; g1 != e1; ++g1) { - rhox = std::min(rhox, tags[g1->idx].height); - } - for (g2 = j2; g2 != e2; ++g2) { - rhoy = std::min(rhoy, tags[g2->idx].height); - } - if (rhox > rhoy) return -1; - if (rhox < rhoy) return 1; - - // leftmost precedence - if (!fork_frame) { - return unpack_leftmost(prectbl[xo * nclos + yo]); - } - else { - // equal => not less - if (j1 == e1 && j2 == e2) return 0; - - // shorter => less - if (j1 == e1) return -1; - if (j2 == e2) return 1; - - const uint32_t idx1 = j1->idx, idx2 = j2->idx; - const bool neg1 = j1->neg, neg2 = j2->neg; - - // can't be both closing - assert(!(idx1 % 2 == 1 && idx2 % 2 == 1)); - - // closing vs opening: closing wins - if (idx1 % 2 == 1) return -1; - if (idx2 % 2 == 1) return 1; - - // can't be both negative - assert(!(neg1 && neg2)); - - // positive vs negative: positive wins - if (neg1) return 1; - if (neg2) return -1; - - // positive vs positive: smaller wins - // (this case is only possible because multiple - // top-level RE don't have proper negative tags) - if (idx1 < idx2) return -1; - if (idx1 > idx2) return 1; - } - - // unreachable - assert(false); - return 0; -} - } // namespace re2c diff --git a/re2c/src/dfa/tag_history.h b/re2c/src/dfa/tag_history.h index 9b907578..a0f2d37b 100644 --- a/re2c/src/dfa/tag_history.h +++ b/re2c/src/dfa/tag_history.h @@ -34,15 +34,14 @@ struct tag_history_t tag_path_t path1; tag_path_t path2; - tag_history_t(); - hidx_t pred(hidx_t i) const; - tag_info_t info(hidx_t i) const; - tagver_t elem(hidx_t i) const; - size_t tag(hidx_t i) const; + tag_history_t(): nodes(), path1(), path2() {} + hidx_t pred(hidx_t i) const { return nodes[i].pred; } + tag_info_t info(hidx_t i) const { return nodes[i].info; } + tagver_t elem(hidx_t i) const { return nodes[i].info.neg ? TAGVER_BOTTOM : TAGVER_CURSOR; } + size_t tag(hidx_t i) const { return nodes[i].info.idx; } hidx_t push(hidx_t i, tag_info_t info); tagver_t last(hidx_t i, size_t t) const; int32_t compare_reversed(hidx_t x, hidx_t y, size_t t) const; - FORBID_COPY(tag_history_t); };