namespace re2c
{
-static void reconstruct_history(const tag_history_t &, tag_path_t &, hidx_t);
-
-int32_t precedence(determ_context_t &ctx,
- const clos_t &x, const clos_t &y, int32_t &rhox, int32_t &rhoy)
+int32_t precedence(determ_context_t &ctx, const clos_t &x, const clos_t &y
+ , int32_t &prec1, int32_t &prec2)
{
- const hidx_t xl = x.tlook, yl = y.tlook;
- const uint32_t xo = x.origin, yo = y.origin;
- const std::vector<Tag> &tags = ctx.dc_dfa.tags;
- const kernel_t *k = NULL;
+ const int32_t idx1 = x.tlook, idx2 = y.tlook;
+ const uint32_t orig1 = x.origin, orig2 = y.origin;
+ int prec = 0;
- if (xl == yl && xo == yo) {
- rhox = rhoy = MAX_RHO;
- return 0;
+ if (idx1 == idx2 && orig1 == orig2) {
+ prec1 = prec2 = MAX_RHO;
+ return prec;
}
- tag_history_t &thist = ctx.dc_taghistory;
- tag_path_t &p1 = ctx.dc_path1, &p2 = ctx.dc_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;
-
- DINCCOUNT_CLPREC(ctx);
- DINCCOUNT_CLLENGTH(ctx, p1.size() + p2.size());
-
- const bool fork_frame = xo == yo;
+ const std::vector<Tag> &tags = ctx.dc_dfa.tags;
+ tag_history_t &hist = ctx.dc_taghistory;
- // longest precedence
+ const bool fork_frame = orig1 == orig2;
if (fork_frame) {
- // find fork
- for (; j1 != e1 && j2 != e2 && *j1 == *j2; ++j1, ++j2);
- rhox = rhoy = j1 > i1
- ? tags[(j1 - 1)->idx].height : MAX_RHO;
+ prec1 = prec2 = MAX_RHO;
}
else {
- // get precedence table and size of the origin state
- k = ctx.dc_kernels[ctx.dc_origin];
- rhox = unpack_longest(k->prectbl[xo * k->size + yo]);
- rhoy = unpack_longest(k->prectbl[yo * k->size + xo]);
+ const kernel_t *k = ctx.dc_kernels[ctx.dc_origin];
+ prec = unpack_leftmost(k->prectbl[orig1 * k->size + orig2]);
+ prec1 = unpack_longest(k->prectbl[orig1 * k->size + orig2]);
+ prec2 = unpack_longest(k->prectbl[orig2 * k->size + orig1]);
}
- for (g1 = j1; g1 != e1; ++g1) {
- rhox = std::min(rhox, tags[g1->idx].height);
+
+ tag_info_t info1, info2;
+ int32_t i1 = idx1, i2 = idx2;
+ for (; i1 != i2; ) {
+ if (i1 > i2) {
+ info1 = hist.info(i1);
+ prec1 = std::min(prec1, tags[info1.idx].height);
+ i1 = hist.pred(i1);
+ }
+ else {
+ info2 = hist.info(i2);
+ prec2 = std::min(prec2, tags[info2.idx].height);
+ i2 = hist.pred(i2);
+ }
+ DINCCOUNT_CLLENGTH(ctx, 1);
}
- for (g2 = j2; g2 != e2; ++g2) {
- rhoy = std::min(rhoy, tags[g2->idx].height);
+ if (i1 != HROOT) {
+ DASSERT(fork_frame);
+ const int32_t h = tags[hist.info(i1).idx].height;
+ prec1 = std::min(prec1, h);
+ prec2 = std::min(prec2, h);
}
- if (rhox > rhoy) return -1;
- if (rhox < rhoy) return 1;
+ DINCCOUNT_CLPREC(ctx);
+
+ // longest precedence
+ if (prec1 > prec2) return -1;
+ if (prec1 < prec2) return 1;
// leftmost precedence
if (fork_frame) {
// equal => not less
- if (j1 == e1 && j2 == e2) return 0;
+ if (i1 == idx1 && i2 == idx2) return 0;
// shorter => less
- if (j1 == e1) return -1;
- if (j2 == e2) return 1;
+ if (i1 == idx1) return -1;
+ if (i2 == idx2) return 1;
- const uint32_t idx1 = j1->idx, idx2 = j2->idx;
- const bool neg1 = j1->neg, neg2 = j2->neg;
+ const uint32_t tag1 = info1.idx, tag2 = info2.idx;
+ const bool neg1 = info1.neg, neg2 = info2.neg;
// can't be both closing
- DASSERT(!(idx1 % 2 == 1 && idx2 % 2 == 1));
+ DASSERT(!(tag1 % 2 == 1 && tag2 % 2 == 1));
// closing vs opening: closing wins
- if (idx1 % 2 == 1) return -1;
- if (idx2 % 2 == 1) return 1;
+ if (tag1 % 2 == 1) return -1;
+ if (tag2 % 2 == 1) return 1;
// can't be both negative
DASSERT(!(neg1 && neg2));
// positive vs negative: positive wins
- if (neg1) return 1;
+ 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;
- }
- else {
- return unpack_leftmost(k->prectbl[xo * k->size + yo]);
- }
-
- // unreachable
- DASSERT(false);
- return 0;
-}
+ if (tag1 < tag2) return -1;
+ if (tag1 > tag2) return 1;
-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));
+ DASSERT(false); // unreachable
}
+ return prec;
}
int32_t unpack_longest(int32_t packed)
}
debug/closure_stats.i--posix-captures--posix-closure(gor1)--dump-closure-stats.re:1:32: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 47 prec: 3 length: 36
+scans: 47 prec: 3 length: 24
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gor1)--dump-closure-stats.re:2:32: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 133 prec: 14 length: 282
+scans: 133 prec: 14 length: 66
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gor1)--dump-closure-stats.re:3:32: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 617 prec: 84 length: 3420
+scans: 617 prec: 84 length: 432
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gor1)--dump-closure-stats.re:4:32: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 3841 prec: 584 length: 49176
+scans: 3841 prec: 584 length: 4980
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gor1)--dump-closure-stats.re:5:35: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 27377 prec: 4368 length: 751536
+scans: 27377 prec: 4368 length: 71004
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gor1)--dump-closure-stats.re:6:35: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 207313 prec: 33824 length: 11771232
+scans: 207313 prec: 33824 length: 1086636
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gor1)--dump-closure-stats.re:7:35: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 1614737 prec: 266304 length: 186413760
+scans: 1614737 prec: 266304 length: 17060172
scans: 0 prec: 0 length: 0
}
debug/closure_stats.i--posix-captures--posix-closure(gtop)--dump-closure-stats.re:1:32: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 24 prec: 3 length: 36
+scans: 24 prec: 3 length: 24
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gtop)--dump-closure-stats.re:2:32: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 67 prec: 14 length: 282
+scans: 67 prec: 14 length: 66
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gtop)--dump-closure-stats.re:3:32: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 309 prec: 84 length: 3420
+scans: 309 prec: 84 length: 432
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gtop)--dump-closure-stats.re:4:32: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 1921 prec: 584 length: 49176
+scans: 1921 prec: 584 length: 4980
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gtop)--dump-closure-stats.re:5:35: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 13689 prec: 4368 length: 751536
+scans: 13689 prec: 4368 length: 71004
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gtop)--dump-closure-stats.re:6:35: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 103657 prec: 33824 length: 11771232
+scans: 103657 prec: 33824 length: 1086636
scans: 0 prec: 0 length: 0
debug/closure_stats.i--posix-captures--posix-closure(gtop)--dump-closure-stats.re:7:35: warning: rule matches empty string [-Wmatch-empty-string]
-scans: 807369 prec: 266304 length: 186413760
+scans: 807369 prec: 266304 length: 17060172
scans: 0 prec: 0 length: 0