case nfa_state_t::TAG:
if (q->arcidx == 0) {
x.state = q->tag.out;
- x.tlook = tagpool.history.push(x.tlook, q->tag.info,
- q->tag.bottom ? TAGVER_BOTTOM : TAGVER_CURSOR);
+ x.tlook = tagpool.history.push(x.tlook, q->tag.info);
p = relax(x, done, shadow, tagpool, tags);
++q->arcidx;
}
break;
case nfa_state_t::TAG:
x.state = n->tag.out;
- x.tlook = tagpool.history.push(x.tlook, n->tag.info,
- n->tag.bottom ? TAGVER_BOTTOM : TAGVER_CURSOR);
+ x.tlook = tagpool.history.push(x.tlook, n->tag.info);
todo.push(x);
break;
case nfa_state_t::RAN:
tagtree_t::tagtree_t(): nodes(), path1(), path2() {}
-tagver_t tagtree_t::elem(hidx_t i) const { return nodes[i].elem; }
+tagver_t tagtree_t::elem(hidx_t i) const { return nodes[i].info.neg ? TAGVER_BOTTOM : TAGVER_CURSOR; }
hidx_t tagtree_t::pred(hidx_t i) const { return nodes[i].pred; }
-size_t tagtree_t::tag(hidx_t i) const { return nodes[i].tag; }
+size_t tagtree_t::tag(hidx_t i) const { return nodes[i].info.idx; }
-hidx_t tagtree_t::push(hidx_t i, size_t t, tagver_t v)
+hidx_t tagtree_t::push(hidx_t idx, tag_info_t info)
{
- node_t x = {i, v, t};
+ node_t x = {idx, info};
nodes.push_back(x);
return static_cast<hidx_t>(nodes.size() - 1);
}
// (a bunch of separate subtrees for each tag with common root)
struct node_t {
hidx_t pred;
- tagver_t elem;
- size_t tag;
+ tag_info_t info;
};
std::vector<node_t> nodes;
hidx_t pred(hidx_t i) const;
tagver_t elem(hidx_t i) const;
size_t tag(hidx_t i) const;
- hidx_t push(hidx_t i, size_t t, tagver_t v);
+ hidx_t push(hidx_t idx, tag_info_t info);
int32_t compare_plain(hidx_t x, hidx_t y, size_t t);
int32_t compare_histories(hidx_t x, hidx_t y, tagver_t ox, tagver_t oy, size_t t);
int32_t compare_last_subhistories(hidx_t x, hidx_t y, tagver_t ox, tagver_t oy, size_t t);
break;
}
case nfa_state_t::TAG: {
- const Tag &tag = nfa.tags[n->tag.info];
+ const Tag &tag = nfa.tags[n->tag.info.idx];
fprintf(stderr, " n%u -> n%u [label=\"/", i, index(nfa, n->tag.out));
if (capture(tag)) {
fprintf(stderr, "%u", (uint32_t)tag.ncap);
} else if (!trailing(tag)) {
fprintf(stderr, "%s", tag.name->c_str());
}
- if (n->tag.bottom) {
+ if (n->tag.info.neg) {
fprintf(stderr, "↓");
} else {
fprintf(stderr, "↑");
struct
{
nfa_state_t *out;
- size_t info;
- bool bottom;
+ tag_info_t info;
} tag;
struct
{
ran.ran = p;
init(r);
}
- void make_tag(size_t r, nfa_state_t *s, size_t i, bool bottom)
+ void make_tag(size_t r, nfa_state_t *s, tag_info_t info)
{
type = TAG;
tag.out = s;
- tag.info = i;
- tag.bottom = bottom;
+ tag.info = info;
init(r);
}
void make_fin(size_t r)
s = t;
} else {
s = &nfa.states[nfa.size++];
- s->make_tag(nrule, t, re->tag.idx, re->tag.bottom);
+ s->make_tag(nrule, t, re->tag);
}
break;
}
uint32_t min;
uint32_t max;
} iter;
- struct {
- size_t idx;
- bool bottom;
- } tag;
+ tag_info_t tag;
};
};
return y;
}
-inline RE *re_tag(RE::alc_t &alc, size_t i, bool b)
+inline RE *re_tag(RE::alc_t &alc, size_t idx, bool neg)
{
RE *x = alc.alloct<RE>(1);
x->type = RE::TAG;
- x->tag.idx = i;
- x->tag.bottom = b;
+ x->tag.idx = idx & 0x7FFFffff;
+ assert(idx == x->tag.idx);
+ x->tag.neg = neg;
return x;
}
static const tagver_t TAGVER_CURSOR = std::numeric_limits<tagver_t>::max(); // current position, highest priority
+struct tag_info_t
+{
+ uint32_t idx : 31;
+ uint32_t neg : 1;
+};
+
+
struct Tag
{
static const size_t RIGHTMOST;