assert(v1[t] == v2[t]);
// open/close capture tag: maximize (on lookahead and versions);
- // if either one is bottom, fallback to leftmost disambiguation
+ // if one is bottom and the other is not, fallback to leftmost
+ // if both are bottoms, relay comparison to less prioritized tags
// we don't use orders for minimize/maximize, because they are
// already used for leftmost
} else if (capture(tag)) {
x = tagtree.last(l1, t);
y = tagtree.last(l2, t);
- if (x < 0 || y < 0) goto leftmost;
+ if (x == TAGVER_BOTTOM && y == TAGVER_BOTTOM) continue;
+ if (x == TAGVER_BOTTOM || y == TAGVER_BOTTOM) goto leftmost;
if (x > y) return false;
if (x < y) return true;
x = tagtree.last(t1, t);
y = tagtree.last(t2, t);
- if (x < 0 || y < 0) goto leftmost;
+ if (x == TAGVER_BOTTOM && y == TAGVER_BOTTOM) continue;
+ if (x == TAGVER_BOTTOM || y == TAGVER_BOTTOM) goto leftmost;
if (x > y) return false;
if (x < y) return true;
x = v1[t]; y = v2[t];
+ if (x < 0 && y < 0) continue;
if (x < 0 || y < 0) goto leftmost;
if (x > y) return false;
if (x < y) return true;
--- /dev/null
+/* Generated by re2c */
+// if two histories are both bottoms (default) for the given tag,
+// they are uncomparable from this tag's point of view: decision
+// should be relayed on less prioritized tags
+
+
+{
+ YYCTYPE yych;
+ if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ switch (yych) {
+ case 'a':
+ yyt1 = yyt5 = YYCURSOR;
+ goto yy3;
+ case 'b':
+ yyt2 = yyt5 = NULL;
+ yyt1 = yyt4 = YYCURSOR;
+ goto yy4;
+ default:
+ yyt2 = yyt3 = yyt4 = yyt5 = NULL;
+ yyt1 = YYCURSOR;
+ goto yy2;
+ }
+yy2:
+ {
+ const size_t yynmatch = 3;
+ const YYCTYPE *yypmatch[yynmatch * 2];
+ yypmatch[0] = yyt1;
+ yypmatch[2] = yyt5;
+ yypmatch[3] = yyt2;
+ yypmatch[5] = yyt3;
+ yypmatch[1] = YYCURSOR;
+ yypmatch[4] = yyt4;
+ {}
+ }
+yy3:
+ yych = *++YYCURSOR;
+ switch (yych) {
+ case 'b':
+ yyt2 = yyt4 = YYCURSOR;
+ goto yy4;
+ default:
+ yyt3 = yyt4 = NULL;
+ yyt2 = YYCURSOR;
+ goto yy2;
+ }
+yy4:
+ ++YYCURSOR;
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ switch (yych) {
+ case 'b': goto yy5;
+ default:
+ yyt3 = YYCURSOR;
+ goto yy2;
+ }
+yy5:
+ ++YYCURSOR;
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ switch (yych) {
+ case 'b':
+ yyt4 = YYCURSOR;
+ goto yy4;
+ default:
+ yyt3 = YYCURSOR;
+ goto yy2;
+ }
+}
+
+re2c: warning: line 6: rule matches empty string [-Wmatch-empty-string]
+re2c: warning: line 6: trailing context is non-deterministic and induces 2 parallel instances [-Wnondeterministic-tags]
--- /dev/null
+// if two histories are both bottoms (default) for the given tag,
+// they are uncomparable from this tag's point of view: decision
+// should be relayed on less prioritized tags
+
+/*!re2c
+ ("a")? ("b" | "bb")* {}
+*/