parseman 0.57.0 → 0.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/diagnostics.js +1799 -962
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +1928 -1091
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts +11 -1
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +69 -16
- package/dist/compiler/token-capability.js.map +2 -2
- package/dist/cst/capture-buffer.d.ts +6 -0
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.js +1016 -177
- package/dist/index.js.map +3 -3
- package/dist/plugin/index.d.ts +25 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1209 -236
- package/dist/plugin/index.js.map +3 -3
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +1 -1
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/factor-choice.d.ts +42 -0
- package/dist/table/factor-choice.d.ts.map +1 -0
- package/dist/table/fail-clean.d.ts +3 -0
- package/dist/table/fail-clean.d.ts.map +1 -0
- package/dist/table/hold-gap.d.ts +8 -0
- package/dist/table/hold-gap.d.ts.map +1 -0
- package/dist/table/index.js +1369 -259
- package/dist/table/index.js.map +3 -3
- package/dist/table/lex-program.d.ts +7 -3
- package/dist/table/lex-program.d.ts.map +1 -1
- package/dist/table/ops.d.ts +8 -0
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/run-support.d.ts +19 -0
- package/dist/table/run-support.d.ts.map +1 -1
- package/dist/table/scalar-terminal.d.ts +2 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -1
- package/dist/table/site-labels.d.ts +66 -0
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/combinators/dispatch.ts +12 -3
- package/src/compiler/token-alphabet.ts +57 -17
- package/src/cst/capture-buffer.ts +25 -0
- package/src/plugin/index.ts +230 -35
- package/src/table/assemble.ts +252 -62
- package/src/table/child-slots.ts +2 -2
- package/src/table/compile-rule-map.ts +14 -5
- package/src/table/emit-assembly.ts +112 -23
- package/src/table/emit.ts +3 -1
- package/src/table/encode.ts +80 -14
- package/src/table/exec.ts +27 -8
- package/src/table/factor-choice.ts +173 -0
- package/src/table/fail-clean.ts +130 -0
- package/src/table/hold-gap.ts +68 -0
- package/src/table/lex-program.ts +197 -43
- package/src/table/ops.ts +9 -1
- package/src/table/run-support.ts +35 -0
- package/src/table/scalar-terminal.ts +8 -0
- package/src/table/site-labels.ts +135 -4
- package/src/version.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -465,6 +465,31 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
465
465
|
else if (ctx._cstLeaves) ctx._cstLeaves.push(built);
|
|
466
466
|
if (ctx._cstRawChildren) ctx._cstRawChildren.push(rawEntry2);
|
|
467
467
|
}
|
|
468
|
+
function popCstChild(ctx) {
|
|
469
|
+
const b = ctx._cstBuf;
|
|
470
|
+
if (b) {
|
|
471
|
+
const ch2 = b.ch;
|
|
472
|
+
if (b.rawOnly !== true && ch2) {
|
|
473
|
+
ch2.pop();
|
|
474
|
+
if (ch2.length === 1) {
|
|
475
|
+
b.single = ch2[0];
|
|
476
|
+
b.ch = void 0;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (b.noRaw === true) b.rawLen = (b.rawLen ?? 1) - 1;
|
|
480
|
+
else if (b.raw) {
|
|
481
|
+
b.raw.pop();
|
|
482
|
+
if (b.raw.length === 1) {
|
|
483
|
+
b.rawSingle = b.raw[0];
|
|
484
|
+
b.raw = void 0;
|
|
485
|
+
}
|
|
486
|
+
} else b.rawSingle = void 0;
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
if (ctx._cstChildren) ctx._cstChildren.pop();
|
|
490
|
+
else if (ctx._cstLeaves) ctx._cstLeaves.pop();
|
|
491
|
+
if (ctx._cstRawChildren) ctx._cstRawChildren.pop();
|
|
492
|
+
}
|
|
468
493
|
function cstRawLen(ctx) {
|
|
469
494
|
const b = ctx._cstBuf;
|
|
470
495
|
if (b) {
|
|
@@ -3398,10 +3423,16 @@ function branchUsesRouted(branch) {
|
|
|
3398
3423
|
return branch.usesRouted === true || parserUsesRouted(branch.parser);
|
|
3399
3424
|
}
|
|
3400
3425
|
function asciiFoldKey(key) {
|
|
3401
|
-
let
|
|
3402
|
-
for (
|
|
3426
|
+
let i = 0;
|
|
3427
|
+
for (; i < key.length; i++) {
|
|
3428
|
+
const c = key.charCodeAt(i);
|
|
3429
|
+
if (c >= 65 && c <= 90) break;
|
|
3430
|
+
}
|
|
3431
|
+
if (i === key.length) return key;
|
|
3432
|
+
let out = key.slice(0, i);
|
|
3433
|
+
for (; i < key.length; i++) {
|
|
3403
3434
|
const c = key.charCodeAt(i);
|
|
3404
|
-
out +=
|
|
3435
|
+
out += c >= 65 && c <= 90 ? String.fromCharCode(c + 32) : key[i];
|
|
3405
3436
|
}
|
|
3406
3437
|
return out;
|
|
3407
3438
|
}
|
|
@@ -5388,17 +5419,59 @@ function buildLexBodyRecognizer(spec, constants) {
|
|
|
5388
5419
|
};
|
|
5389
5420
|
}
|
|
5390
5421
|
|
|
5422
|
+
// src/table/run-support.ts
|
|
5423
|
+
function lineCol(ctx, offset) {
|
|
5424
|
+
const starts = ctx._lineStarts ?? [0];
|
|
5425
|
+
let lo = 0, hi = starts.length - 1;
|
|
5426
|
+
while (lo < hi) {
|
|
5427
|
+
const mid = lo + hi + 1 >> 1;
|
|
5428
|
+
if (starts[mid] <= offset) lo = mid;
|
|
5429
|
+
else hi = mid - 1;
|
|
5430
|
+
}
|
|
5431
|
+
return [lo + 1, offset - starts[lo] + 1];
|
|
5432
|
+
}
|
|
5433
|
+
function spanLines(ctx, start, end) {
|
|
5434
|
+
const s = lineCol(ctx, start), e = lineCol(ctx, end);
|
|
5435
|
+
return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] };
|
|
5436
|
+
}
|
|
5437
|
+
function rawEntry(v, input, s, e) {
|
|
5438
|
+
if (typeof v === "object" && v !== null) {
|
|
5439
|
+
const tg = v._tag;
|
|
5440
|
+
if (tg === "node" || tg === "leaf" || tg === "parseError") return v;
|
|
5441
|
+
}
|
|
5442
|
+
return {
|
|
5443
|
+
_tag: "leaf",
|
|
5444
|
+
value: typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "",
|
|
5445
|
+
span: { start: s, end: e }
|
|
5446
|
+
};
|
|
5447
|
+
}
|
|
5448
|
+
function lead(input, pos) {
|
|
5449
|
+
if (pos >= input.length) return -1;
|
|
5450
|
+
const c = input.charCodeAt(pos);
|
|
5451
|
+
if (c < 55296 || c > 56319) return c;
|
|
5452
|
+
return input.codePointAt(pos) ?? c;
|
|
5453
|
+
}
|
|
5454
|
+
var EMPTY_KIDS = Object.freeze([]);
|
|
5455
|
+
var EMPTY_TRIVIA = Object.freeze([]);
|
|
5456
|
+
function collapseEmpty(ctx, build, input, pos, end, readsRaw) {
|
|
5457
|
+
const collected = ctx._cstBuf !== void 0 || ctx._cstChildren !== void 0;
|
|
5458
|
+
if (collected) popCstChild(ctx);
|
|
5459
|
+
const raw = readsRaw ? [rawEntry(void 0, input, pos, end)] : EMPTY_KIDS;
|
|
5460
|
+
const nd = build(EMPTY_KIDS, void 0, { start: pos, end }, raw, EMPTY_TRIVIA, void 0);
|
|
5461
|
+
if (collected) pushCstChild(ctx, nd, ctx._cstBuf?.noRaw === true ? void 0 : rawEntry(nd, input, pos, end));
|
|
5462
|
+
return nd;
|
|
5463
|
+
}
|
|
5464
|
+
|
|
5391
5465
|
// src/table/lex-program.ts
|
|
5392
5466
|
var LEX_NODE_TERMINAL = 0;
|
|
5393
5467
|
var LEX_NODE_SEQUENCE2 = 1;
|
|
5394
5468
|
var LEX_NODE_SEQUENCE3 = 2;
|
|
5395
5469
|
var LEX_NODE_SEQUENCE4 = 3;
|
|
5396
5470
|
var LEX_NODE_SEQUENCE5 = 4;
|
|
5397
|
-
var
|
|
5398
|
-
var LEX_NODE_CHOICE4 = 6;
|
|
5399
|
-
var LEX_NODE_CHOICE8 = 7;
|
|
5471
|
+
var LEX_NODE_CHOICE = 5;
|
|
5400
5472
|
var LEX_NODE_NOT = 8;
|
|
5401
5473
|
var LEX_NODE_OPTIONAL = 9;
|
|
5474
|
+
var LEX_NODE_REPEAT = 10;
|
|
5402
5475
|
function lexProgramDigest(words) {
|
|
5403
5476
|
let hash = 2166136261;
|
|
5404
5477
|
for (const word2 of words) {
|
|
@@ -5427,85 +5500,114 @@ function trackLexLines(ctx, input, end) {
|
|
|
5427
5500
|
ctx._lineScannedTo = end;
|
|
5428
5501
|
}
|
|
5429
5502
|
function terminalNode(matcher, failure, tracksLines) {
|
|
5430
|
-
const match = (input, pos) => {
|
|
5431
|
-
const result = matcher(input, pos);
|
|
5432
|
-
return result < 0 ? -1 : result / 2;
|
|
5433
|
-
};
|
|
5434
5503
|
return {
|
|
5435
|
-
match,
|
|
5504
|
+
match: (input, pos) => {
|
|
5505
|
+
const result = matcher(input, pos);
|
|
5506
|
+
return result < 0 ? -1 : result / 2;
|
|
5507
|
+
},
|
|
5436
5508
|
run: (input, pos, ctx) => {
|
|
5437
|
-
const
|
|
5438
|
-
if (
|
|
5509
|
+
const result = matcher(input, pos);
|
|
5510
|
+
if (result < 0) {
|
|
5439
5511
|
ctx._fe = pos;
|
|
5440
5512
|
ctx._fx = failure;
|
|
5441
5513
|
if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
|
|
5442
5514
|
return -1;
|
|
5443
5515
|
}
|
|
5516
|
+
const end = result / 2;
|
|
5444
5517
|
if (tracksLines) trackLexLines(ctx, input, end);
|
|
5445
5518
|
return end;
|
|
5446
5519
|
}
|
|
5447
5520
|
};
|
|
5448
5521
|
}
|
|
5449
5522
|
function sequence2(a, b) {
|
|
5523
|
+
const am = a.match, bm = b.match, ar = a.run, br = b.run;
|
|
5450
5524
|
return {
|
|
5451
5525
|
match: (input, pos) => {
|
|
5452
|
-
const e0 =
|
|
5453
|
-
return e0 < 0 ? -1 :
|
|
5526
|
+
const e0 = am(input, pos);
|
|
5527
|
+
return e0 < 0 ? -1 : bm(input, e0);
|
|
5454
5528
|
},
|
|
5455
5529
|
run: (input, pos, ctx) => {
|
|
5456
|
-
const e0 =
|
|
5530
|
+
const e0 = ar(input, pos, ctx);
|
|
5457
5531
|
if (e0 < 0) return -1;
|
|
5458
5532
|
ctx._fc = false;
|
|
5459
|
-
return
|
|
5533
|
+
return br(input, e0, ctx);
|
|
5460
5534
|
}
|
|
5461
5535
|
};
|
|
5462
5536
|
}
|
|
5463
5537
|
function sequence3(a, b, c) {
|
|
5538
|
+
const am = a.match, bm = b.match, cm = c.match, ar = a.run, br = b.run, cr = c.run;
|
|
5464
5539
|
return {
|
|
5465
5540
|
match: (input, pos) => {
|
|
5466
|
-
const e0 =
|
|
5541
|
+
const e0 = am(input, pos);
|
|
5467
5542
|
if (e0 < 0) return -1;
|
|
5468
|
-
const e1 =
|
|
5469
|
-
return e1 < 0 ? -1 :
|
|
5543
|
+
const e1 = bm(input, e0);
|
|
5544
|
+
return e1 < 0 ? -1 : cm(input, e1);
|
|
5470
5545
|
},
|
|
5471
5546
|
run: (input, pos, ctx) => {
|
|
5472
|
-
const e0 =
|
|
5547
|
+
const e0 = ar(input, pos, ctx);
|
|
5473
5548
|
if (e0 < 0) return -1;
|
|
5474
5549
|
ctx._fc = false;
|
|
5475
|
-
const e1 =
|
|
5550
|
+
const e1 = br(input, e0, ctx);
|
|
5476
5551
|
if (e1 < 0) return -1;
|
|
5477
5552
|
ctx._fc = false;
|
|
5478
|
-
return
|
|
5553
|
+
return cr(input, e1, ctx);
|
|
5479
5554
|
}
|
|
5480
5555
|
};
|
|
5481
5556
|
}
|
|
5482
5557
|
function sequence4(a, b, c, d) {
|
|
5483
|
-
const
|
|
5558
|
+
const am = a.match, bm = b.match, cm = c.match, dm = d.match;
|
|
5559
|
+
const ar = a.run, br = b.run, cr = c.run, dr = d.run;
|
|
5484
5560
|
return {
|
|
5485
5561
|
match: (input, pos) => {
|
|
5486
|
-
const
|
|
5487
|
-
|
|
5562
|
+
const e0 = am(input, pos);
|
|
5563
|
+
if (e0 < 0) return -1;
|
|
5564
|
+
const e1 = bm(input, e0);
|
|
5565
|
+
if (e1 < 0) return -1;
|
|
5566
|
+
const e2 = cm(input, e1);
|
|
5567
|
+
return e2 < 0 ? -1 : dm(input, e2);
|
|
5488
5568
|
},
|
|
5489
5569
|
run: (input, pos, ctx) => {
|
|
5490
|
-
const
|
|
5491
|
-
if (
|
|
5570
|
+
const e0 = ar(input, pos, ctx);
|
|
5571
|
+
if (e0 < 0) return -1;
|
|
5572
|
+
ctx._fc = false;
|
|
5573
|
+
const e1 = br(input, e0, ctx);
|
|
5574
|
+
if (e1 < 0) return -1;
|
|
5575
|
+
ctx._fc = false;
|
|
5576
|
+
const e2 = cr(input, e1, ctx);
|
|
5577
|
+
if (e2 < 0) return -1;
|
|
5492
5578
|
ctx._fc = false;
|
|
5493
|
-
return
|
|
5579
|
+
return dr(input, e2, ctx);
|
|
5494
5580
|
}
|
|
5495
5581
|
};
|
|
5496
5582
|
}
|
|
5497
5583
|
function sequence5(a, b, c, d, e) {
|
|
5498
|
-
const
|
|
5584
|
+
const am = a.match, bm = b.match, cm = c.match, dm = d.match, em = e.match;
|
|
5585
|
+
const ar = a.run, br = b.run, cr = c.run, dr = d.run, er = e.run;
|
|
5499
5586
|
return {
|
|
5500
5587
|
match: (input, pos) => {
|
|
5501
|
-
const
|
|
5502
|
-
|
|
5588
|
+
const e0 = am(input, pos);
|
|
5589
|
+
if (e0 < 0) return -1;
|
|
5590
|
+
const e1 = bm(input, e0);
|
|
5591
|
+
if (e1 < 0) return -1;
|
|
5592
|
+
const e2 = cm(input, e1);
|
|
5593
|
+
if (e2 < 0) return -1;
|
|
5594
|
+
const e3 = dm(input, e2);
|
|
5595
|
+
return e3 < 0 ? -1 : em(input, e3);
|
|
5503
5596
|
},
|
|
5504
5597
|
run: (input, pos, ctx) => {
|
|
5505
|
-
const
|
|
5506
|
-
if (
|
|
5598
|
+
const e0 = ar(input, pos, ctx);
|
|
5599
|
+
if (e0 < 0) return -1;
|
|
5600
|
+
ctx._fc = false;
|
|
5601
|
+
const e1 = br(input, e0, ctx);
|
|
5602
|
+
if (e1 < 0) return -1;
|
|
5603
|
+
ctx._fc = false;
|
|
5604
|
+
const e2 = cr(input, e1, ctx);
|
|
5605
|
+
if (e2 < 0) return -1;
|
|
5507
5606
|
ctx._fc = false;
|
|
5508
|
-
|
|
5607
|
+
const e3 = dr(input, e2, ctx);
|
|
5608
|
+
if (e3 < 0) return -1;
|
|
5609
|
+
ctx._fc = false;
|
|
5610
|
+
return er(input, e3, ctx);
|
|
5509
5611
|
}
|
|
5510
5612
|
};
|
|
5511
5613
|
}
|
|
@@ -5518,9 +5620,9 @@ function appendExpected(acc, values) {
|
|
|
5518
5620
|
function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
5519
5621
|
let matchTail = () => -1;
|
|
5520
5622
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5521
|
-
const
|
|
5623
|
+
const armMatch = arms[i].match, next = matchTail;
|
|
5522
5624
|
matchTail = (input, pos) => {
|
|
5523
|
-
const end =
|
|
5625
|
+
const end = armMatch(input, pos);
|
|
5524
5626
|
return end < 0 ? next(input, pos) : end;
|
|
5525
5627
|
};
|
|
5526
5628
|
}
|
|
@@ -5530,7 +5632,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5530
5632
|
return -1;
|
|
5531
5633
|
};
|
|
5532
5634
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5533
|
-
const
|
|
5635
|
+
const armRun = arms[i].run, cls = classes[i], staticExpected = armExpected[i], next = tail;
|
|
5534
5636
|
tail = (input, pos, ctx, lead2, acc, best) => {
|
|
5535
5637
|
if (cls !== void 0 && !classHas(cls, lead2)) {
|
|
5536
5638
|
return next(
|
|
@@ -5543,7 +5645,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5543
5645
|
);
|
|
5544
5646
|
}
|
|
5545
5647
|
ctx._fc = false;
|
|
5546
|
-
const end =
|
|
5648
|
+
const end = armRun(input, pos, ctx);
|
|
5547
5649
|
if (end >= 0) return end;
|
|
5548
5650
|
const at = ctx._fe ?? pos;
|
|
5549
5651
|
if (at > best) {
|
|
@@ -5570,11 +5672,58 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5570
5672
|
)
|
|
5571
5673
|
};
|
|
5572
5674
|
}
|
|
5675
|
+
function exclusiveChoiceNode(arms, classes, choiceFx) {
|
|
5676
|
+
const ascii = (classes.length <= 128 ? new Int8Array(128) : new Int32Array(128)).fill(-1);
|
|
5677
|
+
const hi = [];
|
|
5678
|
+
for (let i = 0; i < classes.length; i++) {
|
|
5679
|
+
const cls = classes[i];
|
|
5680
|
+
for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) ascii[c] = i;
|
|
5681
|
+
for (let r = 0; r < cls.hi.length; r += 2) hi.push(cls.hi[r], cls.hi[r + 1], i);
|
|
5682
|
+
}
|
|
5683
|
+
const select = (code) => {
|
|
5684
|
+
if (code < 0) return -1;
|
|
5685
|
+
if (code < 128) return ascii[code];
|
|
5686
|
+
for (let r = 0; r < hi.length; r += 3) if (code >= hi[r] && code <= hi[r + 1]) return hi[r + 2];
|
|
5687
|
+
return -1;
|
|
5688
|
+
};
|
|
5689
|
+
let matchArm = () => -1;
|
|
5690
|
+
let selectRun = () => -1;
|
|
5691
|
+
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5692
|
+
const armMatch = arms[i].match, armRun = arms[i].run, nextMatch = matchArm, nextRun = selectRun;
|
|
5693
|
+
matchArm = (selected, input, pos) => selected === i ? armMatch(input, pos) : nextMatch(selected, input, pos);
|
|
5694
|
+
selectRun = (selected, input, pos, ctx) => selected === i ? armRun(input, pos, ctx) : nextRun(selected, input, pos, ctx);
|
|
5695
|
+
}
|
|
5696
|
+
const runArm = (input, pos, ctx) => {
|
|
5697
|
+
const arm = select(lead(input, pos));
|
|
5698
|
+
if (arm >= 0) {
|
|
5699
|
+
ctx._fc = false;
|
|
5700
|
+
const end = selectRun(arm, input, pos, ctx);
|
|
5701
|
+
if (end >= 0) return end;
|
|
5702
|
+
if (committed(ctx)) return -1;
|
|
5703
|
+
const failed = ctx._fx;
|
|
5704
|
+
if (failed !== void 0 && failed.length > 0) {
|
|
5705
|
+
ctx._fe = pos;
|
|
5706
|
+
return -1;
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
ctx._fe = pos;
|
|
5710
|
+
ctx._fx = choiceFx;
|
|
5711
|
+
return -1;
|
|
5712
|
+
};
|
|
5713
|
+
return {
|
|
5714
|
+
match: (input, pos) => {
|
|
5715
|
+
const arm = select(lead(input, pos));
|
|
5716
|
+
return arm < 0 ? -1 : matchArm(arm, input, pos);
|
|
5717
|
+
},
|
|
5718
|
+
run: runArm
|
|
5719
|
+
};
|
|
5720
|
+
}
|
|
5573
5721
|
function notNode(body, failure) {
|
|
5722
|
+
const bodyMatch = body.match;
|
|
5574
5723
|
return {
|
|
5575
|
-
match: (input, pos) =>
|
|
5724
|
+
match: (input, pos) => bodyMatch(input, pos) < 0 ? pos : -1,
|
|
5576
5725
|
run: (input, pos, ctx) => {
|
|
5577
|
-
if (
|
|
5726
|
+
if (bodyMatch(input, pos) < 0) return pos;
|
|
5578
5727
|
ctx._fe = pos;
|
|
5579
5728
|
ctx._fx = failure;
|
|
5580
5729
|
return -1;
|
|
@@ -5582,18 +5731,57 @@ function notNode(body, failure) {
|
|
|
5582
5731
|
};
|
|
5583
5732
|
}
|
|
5584
5733
|
function optionalNode(body) {
|
|
5734
|
+
const bodyMatch = body.match, bodyRun = body.run;
|
|
5585
5735
|
return {
|
|
5586
5736
|
match: (input, pos) => {
|
|
5587
|
-
const end =
|
|
5737
|
+
const end = bodyMatch(input, pos);
|
|
5588
5738
|
return end < 0 ? pos : end;
|
|
5589
5739
|
},
|
|
5590
5740
|
run: (input, pos, ctx) => {
|
|
5591
5741
|
ctx._fc = false;
|
|
5592
|
-
const end =
|
|
5742
|
+
const end = bodyRun(input, pos, ctx);
|
|
5593
5743
|
return end < 0 && !committed(ctx) ? pos : end;
|
|
5594
5744
|
}
|
|
5595
5745
|
};
|
|
5596
5746
|
}
|
|
5747
|
+
function repeatNode(item, min, max) {
|
|
5748
|
+
const itemMatch = item.match, itemRun = item.run;
|
|
5749
|
+
return {
|
|
5750
|
+
match: (input, pos) => {
|
|
5751
|
+
let cur = pos;
|
|
5752
|
+
let count = 0;
|
|
5753
|
+
for (; ; ) {
|
|
5754
|
+
if (max >= 0 && count >= max) break;
|
|
5755
|
+
const optional2 = count >= min && (count > 0 || min === 0);
|
|
5756
|
+
if (optional2 && cur >= input.length) break;
|
|
5757
|
+
const end = itemMatch(input, cur);
|
|
5758
|
+
if (end < 0 || optional2 && end === cur) break;
|
|
5759
|
+
cur = end;
|
|
5760
|
+
count++;
|
|
5761
|
+
}
|
|
5762
|
+
return count < min ? -1 : cur;
|
|
5763
|
+
},
|
|
5764
|
+
run: (input, pos, ctx) => {
|
|
5765
|
+
let cur = pos;
|
|
5766
|
+
let count = 0;
|
|
5767
|
+
for (; ; ) {
|
|
5768
|
+
if (max >= 0 && count >= max) break;
|
|
5769
|
+
const optional2 = count >= min && (count > 0 || min === 0);
|
|
5770
|
+
if (optional2 && cur >= input.length) break;
|
|
5771
|
+
ctx._fc = false;
|
|
5772
|
+
const end = itemRun(input, cur, ctx);
|
|
5773
|
+
if (end < 0) {
|
|
5774
|
+
if (committed(ctx)) return -1;
|
|
5775
|
+
break;
|
|
5776
|
+
}
|
|
5777
|
+
if (optional2 && end === cur) break;
|
|
5778
|
+
cur = end;
|
|
5779
|
+
count++;
|
|
5780
|
+
}
|
|
5781
|
+
return count < min ? -1 : cur;
|
|
5782
|
+
}
|
|
5783
|
+
};
|
|
5784
|
+
}
|
|
5597
5785
|
function fixedTreeRunner(words, matchers, classes, expected) {
|
|
5598
5786
|
const stack = [];
|
|
5599
5787
|
const pop = () => {
|
|
@@ -5621,9 +5809,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5621
5809
|
else stack.push(sequence5(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4]));
|
|
5622
5810
|
continue;
|
|
5623
5811
|
}
|
|
5624
|
-
if (op
|
|
5625
|
-
const count =
|
|
5812
|
+
if (op === LEX_NODE_CHOICE) {
|
|
5813
|
+
const count = words[at++];
|
|
5814
|
+
const exclusive = words[at++];
|
|
5815
|
+
if (exclusive !== 0 && exclusive !== 1) throw new TypeError("table lexical tree choice has an invalid dispatch mode");
|
|
5626
5816
|
const choiceFx = expected[words[at++]];
|
|
5817
|
+
if (!Number.isInteger(count) || count < 2 || count > stack.length) {
|
|
5818
|
+
throw new TypeError("table lexical tree choice has an invalid arm count");
|
|
5819
|
+
}
|
|
5627
5820
|
if (choiceFx === void 0) throw new TypeError("table lexical tree choice has an invalid expected set");
|
|
5628
5821
|
const armClasses = [];
|
|
5629
5822
|
const armFx = [];
|
|
@@ -5636,7 +5829,7 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5636
5829
|
armFx.push(fx);
|
|
5637
5830
|
}
|
|
5638
5831
|
const arms = Array.from({ length: count }, pop).reverse();
|
|
5639
|
-
stack.push(choiceNode(arms, armClasses, armFx, choiceFx));
|
|
5832
|
+
stack.push(exclusive === 1 ? exclusiveChoiceNode(arms, armClasses, choiceFx) : choiceNode(arms, armClasses, armFx, choiceFx));
|
|
5640
5833
|
continue;
|
|
5641
5834
|
}
|
|
5642
5835
|
if (op === LEX_NODE_NOT) {
|
|
@@ -5649,6 +5842,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5649
5842
|
stack.push(optionalNode(pop()));
|
|
5650
5843
|
continue;
|
|
5651
5844
|
}
|
|
5845
|
+
if (op === LEX_NODE_REPEAT) {
|
|
5846
|
+
const min = words[at++], max = words[at++];
|
|
5847
|
+
if (!Number.isInteger(min) || min < 0 || !Number.isInteger(max) || max >= 0 && max < min) {
|
|
5848
|
+
throw new TypeError("table lexical tree repeat has invalid bounds");
|
|
5849
|
+
}
|
|
5850
|
+
stack.push(repeatNode(pop(), min, max));
|
|
5851
|
+
continue;
|
|
5852
|
+
}
|
|
5652
5853
|
throw new TypeError("table lexical tree has an unknown fixed body");
|
|
5653
5854
|
}
|
|
5654
5855
|
if (stack.length !== 1) throw new TypeError("table lexical tree does not resolve to one root body");
|
|
@@ -6914,6 +7115,111 @@ function classifyRuleMap(ruleMap) {
|
|
|
6914
7115
|
};
|
|
6915
7116
|
}
|
|
6916
7117
|
|
|
7118
|
+
// src/table/factor-choice.ts
|
|
7119
|
+
var DERIVED = /* @__PURE__ */ new Set(["_tag", "_meta", "_def", "_parseScalar", "_stickyRegex", "parse"]);
|
|
7120
|
+
function isCombinator(v) {
|
|
7121
|
+
return typeof v === "object" && v !== null && "_def" in v && "_meta" in v;
|
|
7122
|
+
}
|
|
7123
|
+
function sameComb(a, b, depth) {
|
|
7124
|
+
if (a === b) return true;
|
|
7125
|
+
if (depth > 32 || a._tag !== b._tag) return false;
|
|
7126
|
+
for (const k of Object.keys(a)) if (!DERIVED.has(k)) return false;
|
|
7127
|
+
for (const k of Object.keys(b)) if (!DERIVED.has(k)) return false;
|
|
7128
|
+
return sameFields(a._def, b._def, depth, void 0);
|
|
7129
|
+
}
|
|
7130
|
+
function sameValue(u, v, depth) {
|
|
7131
|
+
if (u === v) return true;
|
|
7132
|
+
if (isCombinator(u) && isCombinator(v)) return sameComb(u, v, depth + 1);
|
|
7133
|
+
if (Array.isArray(u) && Array.isArray(v)) return u.length === v.length && u.every((x, i) => sameValue(x, v[i], depth));
|
|
7134
|
+
if (typeof u === "object" && u !== null && typeof v === "object" && v !== null && Object.getPrototypeOf(u) === Object.prototype && Object.getPrototypeOf(v) === Object.prototype) {
|
|
7135
|
+
return sameFields(u, v, depth, void 0);
|
|
7136
|
+
}
|
|
7137
|
+
return false;
|
|
7138
|
+
}
|
|
7139
|
+
function sameFields(x, y, depth, skip) {
|
|
7140
|
+
const kx = Object.keys(x).filter((k) => k !== skip && x[k] !== void 0);
|
|
7141
|
+
const ky = Object.keys(y).filter((k) => k !== skip && y[k] !== void 0);
|
|
7142
|
+
if (kx.length !== ky.length) return false;
|
|
7143
|
+
for (const k of kx) {
|
|
7144
|
+
if (!(k in y)) return false;
|
|
7145
|
+
const u = x[k];
|
|
7146
|
+
const v = y[k];
|
|
7147
|
+
if (k === "fn" && typeof u === "function" && typeof v === "function" && u !== v) {
|
|
7148
|
+
if (typeof x.fnSrc !== "string" || x.fnSrc === "" || x.fnSrc !== y.fnSrc) return false;
|
|
7149
|
+
continue;
|
|
7150
|
+
}
|
|
7151
|
+
if (!sameValue(u, v, depth)) return false;
|
|
7152
|
+
}
|
|
7153
|
+
return true;
|
|
7154
|
+
}
|
|
7155
|
+
function rewrap(w, body) {
|
|
7156
|
+
const d = w._def;
|
|
7157
|
+
let out;
|
|
7158
|
+
if (d.tag === "leaf") {
|
|
7159
|
+
out = d.cstValue === "source" ? sourceLeaf(body, d.fn) : leaf(body, d.fn);
|
|
7160
|
+
if (d.fnSrc !== void 0) out._def.fnSrc = d.fnSrc;
|
|
7161
|
+
} else if (d.tag === "grammar") {
|
|
7162
|
+
out = d.clearTrivia === true ? noTrivia(body) : parser({ trivia: d.triviaParser ?? null }, body);
|
|
7163
|
+
} else return void 0;
|
|
7164
|
+
return sameFields(d, out._def, 0, "parser") ? out : void 0;
|
|
7165
|
+
}
|
|
7166
|
+
function unusedOf(seq) {
|
|
7167
|
+
return seq._def.tag === "sequence" && seq._def.valueUnused === true;
|
|
7168
|
+
}
|
|
7169
|
+
function never(c) {
|
|
7170
|
+
const t = c._def.tag;
|
|
7171
|
+
return t === "optional" || t === "many";
|
|
7172
|
+
}
|
|
7173
|
+
function factorSharedEnds(d) {
|
|
7174
|
+
const arms = d.parsers;
|
|
7175
|
+
if (arms.length < 2) return void 0;
|
|
7176
|
+
if (d.strategy.tag !== "firstMatch" && d.strategy.tag !== "sharedPrefix") return void 0;
|
|
7177
|
+
if (d.gates.some((g) => g !== null) || d.autoNot.some((a) => a !== null)) return void 0;
|
|
7178
|
+
const shapes = [];
|
|
7179
|
+
for (const arm of arms) {
|
|
7180
|
+
const wrappers = [];
|
|
7181
|
+
let c = arm;
|
|
7182
|
+
while ((c._def.tag === "leaf" || c._def.tag === "grammar") && wrappers.length < 4) {
|
|
7183
|
+
wrappers.push(c);
|
|
7184
|
+
c = c._def.parser;
|
|
7185
|
+
}
|
|
7186
|
+
if (c._def.tag !== "sequence" || c._def.parsers.length < 2) return void 0;
|
|
7187
|
+
shapes.push({ wrappers, terms: c._def.parsers, seq: c });
|
|
7188
|
+
}
|
|
7189
|
+
const first = shapes[0];
|
|
7190
|
+
const n = first.terms.length;
|
|
7191
|
+
for (const s of shapes) {
|
|
7192
|
+
if (s.wrappers.length !== first.wrappers.length || s.terms.length !== n) return void 0;
|
|
7193
|
+
if (unusedOf(s.seq) !== unusedOf(first.seq)) return void 0;
|
|
7194
|
+
for (let j = 0; j < s.wrappers.length; j++) {
|
|
7195
|
+
const a = first.wrappers[j]._def;
|
|
7196
|
+
const b = s.wrappers[j]._def;
|
|
7197
|
+
if (a.tag !== b.tag || !sameFields(a, b, 0, "parser")) return void 0;
|
|
7198
|
+
}
|
|
7199
|
+
}
|
|
7200
|
+
let at = -1;
|
|
7201
|
+
for (let i = 0; i < n; i++) {
|
|
7202
|
+
if (shapes.every((s) => sameComb(s.terms[i], first.terms[i], 0))) continue;
|
|
7203
|
+
if (at >= 0) return void 0;
|
|
7204
|
+
at = i;
|
|
7205
|
+
}
|
|
7206
|
+
if (at < 0) return void 0;
|
|
7207
|
+
for (let i = at + 1; i < n; i++) if (!never(first.terms[i])) return void 0;
|
|
7208
|
+
if (arms.some((a) => mayCommitFailure(a))) return void 0;
|
|
7209
|
+
const middle = choice(...shapes.map((s) => s.terms[at]));
|
|
7210
|
+
if (middle._def.tag === "choice" && middle._def.autoNot.some((a) => a !== null)) return void 0;
|
|
7211
|
+
const st = middle._def.tag === "choice" ? middle._def.strategy : void 0;
|
|
7212
|
+
if (st === void 0 || st.tag !== "firstMatch" && st.tag !== "sharedPrefix" && !(st.tag === "literalsLongestFirst" && st.sortedIndices.every((x, i) => x === i))) return void 0;
|
|
7213
|
+
let out = sequence(
|
|
7214
|
+
...[...first.terms.slice(0, at), middle, ...first.terms.slice(at + 1)]
|
|
7215
|
+
);
|
|
7216
|
+
if (unusedOf(first.seq)) {
|
|
7217
|
+
out._def.valueUnused = true;
|
|
7218
|
+
}
|
|
7219
|
+
for (let j = first.wrappers.length - 1; j >= 0 && out !== void 0; j--) out = rewrap(first.wrappers[j], out);
|
|
7220
|
+
return out === void 0 ? void 0 : attempt(out);
|
|
7221
|
+
}
|
|
7222
|
+
|
|
6917
7223
|
// src/table/ops.ts
|
|
6918
7224
|
var OP_LIT = 1;
|
|
6919
7225
|
var OP_RX = 2;
|
|
@@ -6957,6 +7263,7 @@ var OP_SCOPE_PLAIN = 41;
|
|
|
6957
7263
|
var OP_LEX_BODY = 42;
|
|
6958
7264
|
var OP_LEX_PROGRAM = 43;
|
|
6959
7265
|
var OP_SOURCE_LEAF = 44;
|
|
7266
|
+
var OP_RGATE = 45;
|
|
6960
7267
|
var OP_DISPATCH = 25;
|
|
6961
7268
|
var OP_ROUTED = 26;
|
|
6962
7269
|
var OP_NAMES = {
|
|
@@ -6976,6 +7283,7 @@ var OP_NAMES = {
|
|
|
6976
7283
|
[OP_PEEK]: "PEEK",
|
|
6977
7284
|
[OP_LEAF]: "LEAF",
|
|
6978
7285
|
[OP_SOURCE_LEAF]: "SOURCE_LEAF",
|
|
7286
|
+
[OP_RGATE]: "RGATE",
|
|
6979
7287
|
[OP_EMPTY]: "EMPTY",
|
|
6980
7288
|
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
6981
7289
|
[OP_RX_TRACK]: "RX_TRACK",
|
|
@@ -7056,7 +7364,10 @@ function selectOptionalSuffixLexBody(ir) {
|
|
|
7056
7364
|
const token2 = { strategy: "token", estimatedOps: 2, body };
|
|
7057
7365
|
return token2.estimatedOps < character.estimatedOps ? token2 : character;
|
|
7058
7366
|
}
|
|
7059
|
-
function
|
|
7367
|
+
function reinstallsRuleTrivia(reference, target) {
|
|
7368
|
+
return (reference._meta.grammarTrivia ?? target._meta.grammarTrivia) !== void 0 && hasOwnTriviaBoundary(target);
|
|
7369
|
+
}
|
|
7370
|
+
function directTokenBodyParser(parser2, resolve, scope) {
|
|
7060
7371
|
const outer = parser2._def;
|
|
7061
7372
|
if (outer.tag !== "token") return void 0;
|
|
7062
7373
|
let body = outer.parser;
|
|
@@ -7066,12 +7377,13 @@ function directTokenBodyParser(parser2, resolve) {
|
|
|
7066
7377
|
const wrapper = body._def;
|
|
7067
7378
|
if (wrapper.tag === "grammar") {
|
|
7068
7379
|
if (wrapper.clearTrivia !== true || wrapper.triviaParser !== void 0 || wrapper.captureTrivia === true || wrapper.rootCapture === "opaque" || wrapper.constructionTrackLines !== "inherit" || wrapper.constructionCaptureTriviaKinds !== void 0) return void 0;
|
|
7380
|
+
if (scope !== void 0) scope.cleared = true;
|
|
7069
7381
|
body = wrapper.parser;
|
|
7070
7382
|
continue;
|
|
7071
7383
|
}
|
|
7072
7384
|
if (wrapper.tag === "lazy") {
|
|
7073
7385
|
const target = resolvedLazyTarget(body, resolve);
|
|
7074
|
-
if (target === void 0) return void 0;
|
|
7386
|
+
if (target === void 0 || reinstallsRuleTrivia(body, target)) return void 0;
|
|
7075
7387
|
body = target;
|
|
7076
7388
|
continue;
|
|
7077
7389
|
}
|
|
@@ -7243,7 +7555,7 @@ function directNot2TokenBody(parser2, resolve) {
|
|
|
7243
7555
|
terminal
|
|
7244
7556
|
};
|
|
7245
7557
|
}
|
|
7246
|
-
function directFixedLexNode(parser2, resolve, active, pureOnly = false) {
|
|
7558
|
+
function directFixedLexNode(parser2, resolve, active, pureOnly = false, cleared = false) {
|
|
7247
7559
|
let current = parser2;
|
|
7248
7560
|
const wrappers = /* @__PURE__ */ new Set();
|
|
7249
7561
|
while (!wrappers.has(current)) {
|
|
@@ -7251,7 +7563,7 @@ function directFixedLexNode(parser2, resolve, active, pureOnly = false) {
|
|
|
7251
7563
|
const def = current._def;
|
|
7252
7564
|
if (def.tag === "lazy") {
|
|
7253
7565
|
const target = resolvedLazyTarget(current, resolve);
|
|
7254
|
-
if (target === void 0) return void 0;
|
|
7566
|
+
if (target === void 0 || reinstallsRuleTrivia(current, target)) return void 0;
|
|
7255
7567
|
current = target;
|
|
7256
7568
|
continue;
|
|
7257
7569
|
}
|
|
@@ -7269,30 +7581,33 @@ function directFixedLexNode(parser2, resolve, active, pureOnly = false) {
|
|
|
7269
7581
|
if (terminal !== void 0) return { kind: "terminal", terminal };
|
|
7270
7582
|
const def = current._def;
|
|
7271
7583
|
if (def.tag === "grammar") {
|
|
7584
|
+
if (def.triviaParser === void 0 && def.captureTrivia !== true && def.rootCapture !== "opaque" && def.constructionCaptureTriviaKinds === void 0) {
|
|
7585
|
+
return directFixedLexNode(def.parser, resolve, active, pureOnly, cleared || def.clearTrivia === true);
|
|
7586
|
+
}
|
|
7272
7587
|
if (!pureOnly || def.parser._def.tag !== "token" && (def.clearTrivia !== true || def.triviaParser !== void 0 || def.captureTrivia === true || def.rootCapture === "opaque")) return void 0;
|
|
7273
|
-
return directFixedLexNode(def.parser, resolve, active, true);
|
|
7588
|
+
return directFixedLexNode(def.parser, resolve, active, true, cleared);
|
|
7274
7589
|
}
|
|
7275
7590
|
if (def.tag === "sequence") {
|
|
7276
7591
|
if (def.parsers.length < 2 || def.parsers.length > 5) return void 0;
|
|
7277
|
-
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve, active, pureOnly));
|
|
7592
|
+
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve, active, pureOnly, cleared));
|
|
7278
7593
|
if (parts.some((part) => part === void 0)) return void 0;
|
|
7279
7594
|
return { kind: "sequence", parts };
|
|
7280
7595
|
}
|
|
7281
7596
|
if (def.tag === "choice") {
|
|
7282
|
-
if (def.parsers.length
|
|
7283
|
-
const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve, active, pureOnly));
|
|
7597
|
+
if (def.parsers.length < 2 || def.strategy.tag !== "firstMatch" || def.gates.some((gate2) => gate2 !== null) || def.autoNot.some((check) => check !== null)) return void 0;
|
|
7598
|
+
const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve, active, pureOnly, cleared));
|
|
7284
7599
|
if (arms.some((arm) => arm === void 0)) return void 0;
|
|
7285
|
-
const final = classifyFinalChoice(def.parsers, resolve);
|
|
7286
7600
|
return {
|
|
7287
7601
|
kind: "choice",
|
|
7288
7602
|
arms,
|
|
7289
|
-
|
|
7603
|
+
parsers: def.parsers,
|
|
7604
|
+
cleared,
|
|
7290
7605
|
armExpected: def.parsers.map(deriveExpected),
|
|
7291
7606
|
expected: def.parsers.flatMap(deriveExpected)
|
|
7292
7607
|
};
|
|
7293
7608
|
}
|
|
7294
7609
|
if (def.tag === "not") {
|
|
7295
|
-
const body = directFixedLexNode(def.parser, resolve, active, true);
|
|
7610
|
+
const body = directFixedLexNode(def.parser, resolve, active, true, cleared);
|
|
7296
7611
|
return body === void 0 ? void 0 : {
|
|
7297
7612
|
kind: "not",
|
|
7298
7613
|
body,
|
|
@@ -7300,18 +7615,28 @@ function directFixedLexNode(parser2, resolve, active, pureOnly = false) {
|
|
|
7300
7615
|
};
|
|
7301
7616
|
}
|
|
7302
7617
|
if (def.tag === "optional") {
|
|
7303
|
-
const body = directFixedLexNode(def.parser, resolve, active, pureOnly);
|
|
7618
|
+
const body = directFixedLexNode(def.parser, resolve, active, pureOnly, cleared);
|
|
7304
7619
|
return body === void 0 ? void 0 : { kind: "optional", body };
|
|
7305
7620
|
}
|
|
7621
|
+
if (def.tag === "many" || def.tag === "oneOrMore") {
|
|
7622
|
+
const body = directFixedLexNode(def.parser, resolve, active, pureOnly, cleared);
|
|
7623
|
+
return body === void 0 ? void 0 : {
|
|
7624
|
+
kind: "repeat",
|
|
7625
|
+
body,
|
|
7626
|
+
min: def.tag === "many" ? 0 : def.min,
|
|
7627
|
+
max: def.max ?? -1
|
|
7628
|
+
};
|
|
7629
|
+
}
|
|
7306
7630
|
return void 0;
|
|
7307
7631
|
} finally {
|
|
7308
7632
|
active.delete(current);
|
|
7309
7633
|
}
|
|
7310
7634
|
}
|
|
7311
7635
|
function directFixedTokenBody(parser2, resolve) {
|
|
7312
|
-
const
|
|
7636
|
+
const scope = { cleared: false };
|
|
7637
|
+
const body = directTokenBodyParser(parser2, resolve, scope);
|
|
7313
7638
|
if (body === void 0) return void 0;
|
|
7314
|
-
const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set());
|
|
7639
|
+
const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set(), false, scope.cleared);
|
|
7315
7640
|
return root === void 0 ? void 0 : { kind: "fixed-tree", root };
|
|
7316
7641
|
}
|
|
7317
7642
|
function directBalancedTokenBody(parser2, resolve) {
|
|
@@ -7558,13 +7883,16 @@ var Encoder = class {
|
|
|
7558
7883
|
}
|
|
7559
7884
|
case "choice": {
|
|
7560
7885
|
for (const arm of node2.arms) if (!emitNode(arm)) return false;
|
|
7561
|
-
const
|
|
7562
|
-
|
|
7563
|
-
|
|
7886
|
+
const final = classifyFinalChoice(
|
|
7887
|
+
node2.parsers,
|
|
7888
|
+
this.refResolver(),
|
|
7889
|
+
node2.cleared ? void 0 : this.activeTrivia
|
|
7890
|
+
);
|
|
7891
|
+
const classes = final.firstSets.map((first, i) => final.nullable[i] ? -1 : this.charClass(first));
|
|
7892
|
+
const exclusive = final.exclusive && classes.every((cls) => cls >= 0);
|
|
7893
|
+
words.push(LEX_NODE_CHOICE, node2.arms.length, exclusive ? 1 : 0, this.expected(node2.expected));
|
|
7564
7894
|
for (let i = 0; i < node2.arms.length; i++) {
|
|
7565
|
-
|
|
7566
|
-
words.push(first.kind === "ranges" ? this.charClass(first) : -1);
|
|
7567
|
-
words.push(this.expected(node2.armExpected[i]));
|
|
7895
|
+
words.push(classes[i], this.expected(node2.armExpected[i]));
|
|
7568
7896
|
}
|
|
7569
7897
|
return true;
|
|
7570
7898
|
}
|
|
@@ -7576,6 +7904,10 @@ var Encoder = class {
|
|
|
7576
7904
|
if (!emitNode(node2.body)) return false;
|
|
7577
7905
|
words.push(LEX_NODE_OPTIONAL);
|
|
7578
7906
|
return true;
|
|
7907
|
+
case "repeat":
|
|
7908
|
+
if (!emitNode(node2.body)) return false;
|
|
7909
|
+
words.push(LEX_NODE_REPEAT, node2.min, node2.max);
|
|
7910
|
+
return true;
|
|
7579
7911
|
}
|
|
7580
7912
|
};
|
|
7581
7913
|
if (!emitNode(body.root)) return void 0;
|
|
@@ -8081,6 +8413,50 @@ var Encoder = class {
|
|
|
8081
8413
|
if (!hasOwnTriviaBoundary(target)) return ip;
|
|
8082
8414
|
return this.emit(OP_SCOPE_PLAIN, this.triviaSlot(amb), ip);
|
|
8083
8415
|
}
|
|
8416
|
+
/**
|
|
8417
|
+
* The `OP_RGATE` operands of a choice arm that opens with `routed()`, or
|
|
8418
|
+
* `undefined`. Through `node()`/scope wrappers and first sequence terms, the
|
|
8419
|
+
* arm's next term after the routed token is found; the gate is that term's
|
|
8420
|
+
* first characters, with the trivia in force at the boundary before it, so
|
|
8421
|
+
* the arm is entered only where it can get past the token. The term must be
|
|
8422
|
+
* unable to match empty or to commit, so a miss is exactly that term failing
|
|
8423
|
+
* at the token's end with its own set.
|
|
8424
|
+
*/
|
|
8425
|
+
routedArmGate(arm) {
|
|
8426
|
+
const walk = (p, trivia2, depth) => {
|
|
8427
|
+
if (depth > 16) return void 0;
|
|
8428
|
+
const d = p._def;
|
|
8429
|
+
switch (d.tag) {
|
|
8430
|
+
case "routed":
|
|
8431
|
+
return "end";
|
|
8432
|
+
case "node":
|
|
8433
|
+
return walk(d.parser, trivia2, depth + 1);
|
|
8434
|
+
case "grammar":
|
|
8435
|
+
return walk(d.parser, d.clearTrivia === true ? void 0 : d.triviaParser ?? trivia2, depth + 1);
|
|
8436
|
+
case "sequence": {
|
|
8437
|
+
const head = d.parsers[0];
|
|
8438
|
+
if (head === void 0) return void 0;
|
|
8439
|
+
const r = walk(head, trivia2, depth + 1);
|
|
8440
|
+
if (r !== "end") return r;
|
|
8441
|
+
const next2 = d.parsers[1];
|
|
8442
|
+
return next2 === void 0 ? "end" : { next: next2, boundary: trivia2 };
|
|
8443
|
+
}
|
|
8444
|
+
default:
|
|
8445
|
+
return void 0;
|
|
8446
|
+
}
|
|
8447
|
+
};
|
|
8448
|
+
const follow = walk(arm, this.activeTrivia, 0);
|
|
8449
|
+
if (follow === void 0 || follow === "end") return void 0;
|
|
8450
|
+
const rr = this.refResolver();
|
|
8451
|
+
const { next, boundary } = follow;
|
|
8452
|
+
if (matchesEmpty(next, /* @__PURE__ */ new Set(), rr) || mayCommitFailure(next, rr, this.commitFailureMemo)) return void 0;
|
|
8453
|
+
const nextTag = next._def.tag;
|
|
8454
|
+
if (nextTag !== "literal" && nextTag !== "regex" && nextTag !== "keywords" && nextTag !== "label") return void 0;
|
|
8455
|
+
const first = firstSetOf(next, /* @__PURE__ */ new Set(), rr, boundary);
|
|
8456
|
+
const cls = this.charClass(boundary === void 0 ? first : union(first, firstSetOf(boundary, /* @__PURE__ */ new Set(), rr)));
|
|
8457
|
+
if (cls < 0) return void 0;
|
|
8458
|
+
return { cls, fx: this.expected(deriveExpected(next)) };
|
|
8459
|
+
}
|
|
8084
8460
|
node(p) {
|
|
8085
8461
|
const lazyRef = p._def.tag === "lazy";
|
|
8086
8462
|
const scopeKey = lazyRef ? this.activeTrivia : void 0;
|
|
@@ -8205,6 +8581,10 @@ var Encoder = class {
|
|
|
8205
8581
|
return head;
|
|
8206
8582
|
}
|
|
8207
8583
|
case "choice": {
|
|
8584
|
+
if (this.plan === void 0) {
|
|
8585
|
+
const factored = factorSharedEnds(d);
|
|
8586
|
+
if (factored !== void 0) return this.node(factored).ip;
|
|
8587
|
+
}
|
|
8208
8588
|
if (d.strategy.tag === "greedyClassify") {
|
|
8209
8589
|
const superIndex = d.strategy.superIndex;
|
|
8210
8590
|
const sup = this.node(d.parsers[superIndex]).ip;
|
|
@@ -8228,9 +8608,12 @@ var Encoder = class {
|
|
|
8228
8608
|
const kids = arms.map((c, k) => {
|
|
8229
8609
|
const src = order[k];
|
|
8230
8610
|
const checks = d.autoNot[src];
|
|
8231
|
-
const inner = this.node(c).ip;
|
|
8232
|
-
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
8233
8611
|
const gate2 = d.gates[src];
|
|
8612
|
+
const plain = (checks === null || checks === void 0 || checks.length === 0) && (gate2 === null || gate2 === void 0);
|
|
8613
|
+
const routedGate = plain ? this.routedArmGate(c) : void 0;
|
|
8614
|
+
const body = this.node(c).ip;
|
|
8615
|
+
const inner = routedGate === void 0 ? body : this.emit(OP_RGATE, routedGate.cls, body, routedGate.fx);
|
|
8616
|
+
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
8234
8617
|
const gated = gate2 === null || gate2 === void 0 ? ip : this.emit(OP_ARMGATE, this.fn(gate2, d.gateSrcs?.[src] ?? null), ip, this.expected(deriveExpected(c)));
|
|
8235
8618
|
return this.covWrap(gated, armCovIds?.[src], 1);
|
|
8236
8619
|
});
|
|
@@ -8554,6 +8937,7 @@ var Encoder = class {
|
|
|
8554
8937
|
const slots = (ip) => {
|
|
8555
8938
|
switch (this.code[ip]) {
|
|
8556
8939
|
case OP_GATE:
|
|
8940
|
+
case OP_RGATE:
|
|
8557
8941
|
return [ip + 2];
|
|
8558
8942
|
case OP_RULE:
|
|
8559
8943
|
case OP_OPT:
|
|
@@ -9784,6 +10168,7 @@ function childSlots(code, ip, out) {
|
|
|
9784
10168
|
case OP_LEAF:
|
|
9785
10169
|
case OP_SOURCE_LEAF:
|
|
9786
10170
|
case OP_ARMGATE:
|
|
10171
|
+
case OP_RGATE:
|
|
9787
10172
|
out.push(code[ip + 2]);
|
|
9788
10173
|
return true;
|
|
9789
10174
|
// `ROUTED fallback` — the operand is an offset or −1. The routed token itself is
|
|
@@ -9867,6 +10252,42 @@ function reachableSites(code, roots) {
|
|
|
9867
10252
|
}
|
|
9868
10253
|
return seen;
|
|
9869
10254
|
}
|
|
10255
|
+
function passCollapse(code, ip, hostCst) {
|
|
10256
|
+
const flags = code[ip + 3];
|
|
10257
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return false;
|
|
10258
|
+
if (flags !== 32 && flags !== 34) return false;
|
|
10259
|
+
let at = code[ip + 2];
|
|
10260
|
+
for (let n = 0; n < 8; n++) {
|
|
10261
|
+
const op = code[at];
|
|
10262
|
+
if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[at + 3] === 0) at = code[at + 2];
|
|
10263
|
+
else if (op === OP_RULE) at = code[at + 1];
|
|
10264
|
+
else break;
|
|
10265
|
+
}
|
|
10266
|
+
return code[at] === OP_NODE;
|
|
10267
|
+
}
|
|
10268
|
+
function gatedPassCollapse(code, ip, hostCst) {
|
|
10269
|
+
const flags = code[ip + 3];
|
|
10270
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return void 0;
|
|
10271
|
+
if (flags !== 32 && flags !== 34) return void 0;
|
|
10272
|
+
const seq = code[ip + 2];
|
|
10273
|
+
if (code[seq] !== OP_SEQ && code[seq] !== OP_SEQV) return void 0;
|
|
10274
|
+
const n = code[seq + 1];
|
|
10275
|
+
if (n < 2) return void 0;
|
|
10276
|
+
const leads = [];
|
|
10277
|
+
const lits = [];
|
|
10278
|
+
for (let i = 0; i < n - 1; i++) {
|
|
10279
|
+
const t = code[seq + 2 + i];
|
|
10280
|
+
if (code[t] !== OP_OPT && code[t] !== OP_NOT) return void 0;
|
|
10281
|
+
const g = code[t + 1];
|
|
10282
|
+
if (code[g] === OP_GATE) leads.push(g);
|
|
10283
|
+
else if (code[g] === OP_LIT) lits.push(code[g + 1]);
|
|
10284
|
+
else return void 0;
|
|
10285
|
+
}
|
|
10286
|
+
const last = code[seq + 2 + n - 1];
|
|
10287
|
+
let at = last;
|
|
10288
|
+
for (let k = 0; k < 8 && (code[at] === OP_GATE || code[at] === OP_RULE); k++) at = code[at] === OP_RULE ? code[at + 1] : code[at + 2];
|
|
10289
|
+
return code[at] === OP_NODE ? { leads, lits, last } : void 0;
|
|
10290
|
+
}
|
|
9870
10291
|
function transfer(code, ip, at, hostCst) {
|
|
9871
10292
|
const op = code[ip];
|
|
9872
10293
|
if (op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN) {
|
|
@@ -9878,14 +10299,18 @@ function transfer(code, ip, at, hostCst) {
|
|
|
9878
10299
|
}
|
|
9879
10300
|
if (op === OP_NODE || op === OP_NODE_TRACK) {
|
|
9880
10301
|
const flags = code[ip + 3];
|
|
10302
|
+
if (passCollapse(code, ip, hostCst)) return at;
|
|
10303
|
+
const gated = gatedPassCollapse(code, ip, hostCst) !== void 0;
|
|
9881
10304
|
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && ((flags & ~128) === 2 || flags === 18 || flags === 34);
|
|
9882
10305
|
if (directChildren) {
|
|
9883
|
-
|
|
10306
|
+
const framed2 = { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
|
|
10307
|
+
return gated ? meet(at, framed2) : framed2;
|
|
9884
10308
|
}
|
|
9885
10309
|
const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
|
|
9886
10310
|
const raw = !hostCst && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags & 2) !== 0 ? RAW_OMIT : RAW_CAPTURE;
|
|
9887
10311
|
if (at.buf && raw === at.raw && cap === at.cap) return at;
|
|
9888
|
-
|
|
10312
|
+
const framed = { tri: at.tri, buf: true, raw, cap };
|
|
10313
|
+
return gated ? meet(at, framed) : framed;
|
|
9889
10314
|
}
|
|
9890
10315
|
if (op === OP_TOKEN) {
|
|
9891
10316
|
if (at.tri === TRI_NONE && !at.buf) return at;
|
|
@@ -9923,6 +10348,40 @@ function computeSiteLabels(code, roots, hostCst) {
|
|
|
9923
10348
|
}
|
|
9924
10349
|
return { at: (ip) => labels.get(ip) ?? TOP };
|
|
9925
10350
|
}
|
|
10351
|
+
function scopeIsIdentity(code, ip, at) {
|
|
10352
|
+
const op = code[ip];
|
|
10353
|
+
if (op !== OP_SCOPE_PLAIN && !(op === OP_SCOPE && code[ip + 3] === 0)) return false;
|
|
10354
|
+
const ki = code[ip + 1];
|
|
10355
|
+
return at.tri === (ki < 0 ? TRI_NONE : ki);
|
|
10356
|
+
}
|
|
10357
|
+
function scanHandoffNeeded(code, ip, labels) {
|
|
10358
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10359
|
+
const stack = [ip];
|
|
10360
|
+
const kids = [];
|
|
10361
|
+
while (stack.length > 0) {
|
|
10362
|
+
const at = stack.pop();
|
|
10363
|
+
if (seen.has(at)) continue;
|
|
10364
|
+
seen.add(at);
|
|
10365
|
+
const l = labels.at(at);
|
|
10366
|
+
if (l.tri === TRI_UNKNOWN) return true;
|
|
10367
|
+
const op = code[at];
|
|
10368
|
+
if (op === OP_SCAN) return true;
|
|
10369
|
+
if (op === OP_TOKEN || op === OP_SCOPE_CAP) continue;
|
|
10370
|
+
if ((op === OP_SCOPE_PLAIN || op === OP_SCOPE) && !(code[at + 1] >= 0 && l.tri === code[at + 1] && (op === OP_SCOPE_PLAIN || code[at + 3] === 0))) continue;
|
|
10371
|
+
kids.length = 0;
|
|
10372
|
+
if (!childSlots(code, at, kids)) return true;
|
|
10373
|
+
for (const c of kids) stack.push(c);
|
|
10374
|
+
}
|
|
10375
|
+
return false;
|
|
10376
|
+
}
|
|
10377
|
+
function triviaLeadRanges(tri, trivia2) {
|
|
10378
|
+
if (tri === TRI_NONE) return [];
|
|
10379
|
+
if (tri < 0) return void 0;
|
|
10380
|
+
const fs = trivia2[tri]?._meta.firstSet;
|
|
10381
|
+
if (fs === void 0) return void 0;
|
|
10382
|
+
if (fs.kind === "empty") return [];
|
|
10383
|
+
return fs.kind === "ranges" && fs.ranges !== void 0 ? fs.ranges : void 0;
|
|
10384
|
+
}
|
|
9926
10385
|
|
|
9927
10386
|
// src/table/scalar-terminal.ts
|
|
9928
10387
|
function makeScalarRecognizer(op, spec) {
|
|
@@ -9960,6 +10419,12 @@ function scalarTerminalNotChild(code, ip) {
|
|
|
9960
10419
|
const op = code[child];
|
|
9961
10420
|
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
9962
10421
|
}
|
|
10422
|
+
function scalarTerminalPeekChild(code, ip) {
|
|
10423
|
+
if (code[ip] !== OP_PEEK) return -1;
|
|
10424
|
+
const child = code[ip + 1];
|
|
10425
|
+
const op = code[child];
|
|
10426
|
+
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
10427
|
+
}
|
|
9963
10428
|
function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, throughPeek = false) {
|
|
9964
10429
|
const seen = /* @__PURE__ */ new Set();
|
|
9965
10430
|
let at = ip;
|
|
@@ -10137,6 +10602,59 @@ function leadingTriviaFieldAt(code, k, ip) {
|
|
|
10137
10602
|
return code[ip] === OP_FIELD && (fieldSpec(k[code[ip + 1]]).bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
10138
10603
|
}
|
|
10139
10604
|
|
|
10605
|
+
// src/table/hold-gap.ts
|
|
10606
|
+
var WRAPPERS = /* @__PURE__ */ new Set([
|
|
10607
|
+
OP_NODE,
|
|
10608
|
+
OP_XFORM,
|
|
10609
|
+
OP_LEAF,
|
|
10610
|
+
OP_SOURCE_LEAF,
|
|
10611
|
+
OP_TOKEN,
|
|
10612
|
+
OP_SCOPE,
|
|
10613
|
+
OP_SCOPE_CAP,
|
|
10614
|
+
OP_SCOPE_PLAIN,
|
|
10615
|
+
OP_FIELD,
|
|
10616
|
+
OP_LABEL,
|
|
10617
|
+
OP_EXPECT,
|
|
10618
|
+
OP_WITHCTX,
|
|
10619
|
+
OP_RULE,
|
|
10620
|
+
OP_ATTEMPT,
|
|
10621
|
+
OP_COV
|
|
10622
|
+
]);
|
|
10623
|
+
function rowNullable(code, k, ip, memo) {
|
|
10624
|
+
const hit = memo.get(ip);
|
|
10625
|
+
if (hit !== void 0) return hit;
|
|
10626
|
+
memo.set(ip, true);
|
|
10627
|
+
const op = code[ip];
|
|
10628
|
+
const kids = [];
|
|
10629
|
+
let out = true;
|
|
10630
|
+
if (op === OP_GATE) out = false;
|
|
10631
|
+
else if (op === OP_LIT || op === OP_LIT_CI) out = k[code[ip + 1]].length === 0;
|
|
10632
|
+
else if (op === OP_RX) {
|
|
10633
|
+
const re = k[code[ip + 1]];
|
|
10634
|
+
out = !(re instanceof RegExp) || regexCanMatchEmpty(re.source);
|
|
10635
|
+
} else if (op === OP_SEQ || op === OP_SEQV || op === OP_SEQX) {
|
|
10636
|
+
childSlots(code, ip, kids);
|
|
10637
|
+
out = kids.every((c) => rowNullable(code, k, c, memo));
|
|
10638
|
+
} else if (op === OP_CHOICE) {
|
|
10639
|
+
childSlots(code, ip, kids);
|
|
10640
|
+
out = kids.length === 0 || kids.some((c) => rowNullable(code, k, c, memo));
|
|
10641
|
+
} else if (op === OP_REP || op === OP_REPV) {
|
|
10642
|
+
out = code[ip + 2] === 0 || rowNullable(code, k, code[ip + 1], memo);
|
|
10643
|
+
} else if (WRAPPERS.has(op)) {
|
|
10644
|
+
if (childSlots(code, ip, kids) && kids.length === 1) out = rowNullable(code, k, kids[0], memo);
|
|
10645
|
+
}
|
|
10646
|
+
memo.set(ip, out);
|
|
10647
|
+
return out;
|
|
10648
|
+
}
|
|
10649
|
+
function holdsGap(code, k, base, n, i, memo) {
|
|
10650
|
+
if (i < 1 || i + 1 >= n) return false;
|
|
10651
|
+
const term = code[base + i];
|
|
10652
|
+
if (code[term] !== OP_NOT && code[term] !== OP_PEEK) return false;
|
|
10653
|
+
const next = code[base + i + 1];
|
|
10654
|
+
if (code[next] === OP_ADJ || leadingTriviaFieldAt(code, k, next)) return false;
|
|
10655
|
+
return !rowNullable(code, k, next, memo);
|
|
10656
|
+
}
|
|
10657
|
+
|
|
10140
10658
|
// src/table/emit-assembly.ts
|
|
10141
10659
|
var Unemittable = class extends Error {
|
|
10142
10660
|
construct;
|
|
@@ -10217,7 +10735,10 @@ var EMITTED_PARAMS = [
|
|
|
10217
10735
|
"triviaFieldCapture",
|
|
10218
10736
|
// Appended for the deferred-commit trivia skip (`trivia-gap.ts`); old
|
|
10219
10737
|
// factories ignore it.
|
|
10220
|
-
"skipDeferredTrivia"
|
|
10738
|
+
"skipDeferredTrivia",
|
|
10739
|
+
// Appended for the pass-through collapse (`run-support.ts`); old factories
|
|
10740
|
+
// ignore it.
|
|
10741
|
+
"collapseEmpty"
|
|
10221
10742
|
];
|
|
10222
10743
|
var RUNTIME_PRELUDE = `
|
|
10223
10744
|
let _pfScan=null
|
|
@@ -10414,6 +10935,24 @@ ${fast}
|
|
|
10414
10935
|
${scanned}
|
|
10415
10936
|
}`;
|
|
10416
10937
|
}
|
|
10938
|
+
function emitHoldTerm(callee, dst, t, l, skip) {
|
|
10939
|
+
const fast = `const ${t}v=${callee}(input,cur,ctx)
|
|
10940
|
+
if(${t}v===FAIL)return FAIL
|
|
10941
|
+
${dst}=${t}v
|
|
10942
|
+
cur=EC.e`;
|
|
10943
|
+
if (l.tri === TRI_NONE) return fast;
|
|
10944
|
+
const held = `const ${t}s=${skip}(input,cur,ctx)
|
|
10945
|
+
const ${t}v=${callee}(input,${t}s,ctx)
|
|
10946
|
+
if(${t}v===FAIL)return FAIL
|
|
10947
|
+
${dst}=${t}v
|
|
10948
|
+
cur=${t}s`;
|
|
10949
|
+
if (l.tri !== TRI_UNKNOWN) return held;
|
|
10950
|
+
return `if(ctx.trivia===undefined){
|
|
10951
|
+
${fast}
|
|
10952
|
+
}else{
|
|
10953
|
+
${held}
|
|
10954
|
+
}`;
|
|
10955
|
+
}
|
|
10417
10956
|
function leadSkip(hasTrivia, leadTrivia, skip) {
|
|
10418
10957
|
if (hasTrivia === "false") return "{}";
|
|
10419
10958
|
const call = `itemStart=${skip}(input,itemStart,ctx)`;
|
|
@@ -10455,6 +10994,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, se
|
|
|
10455
10994
|
const reachable = [...reachableSites(code, roots)];
|
|
10456
10995
|
const labels = computeSiteLabels(code, roots, hostCst);
|
|
10457
10996
|
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
10997
|
+
const nullable2 = /* @__PURE__ */ new Map();
|
|
10458
10998
|
const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
|
|
10459
10999
|
const largeChoiceLiteralFamilies = /* @__PURE__ */ new Map();
|
|
10460
11000
|
const largeChoiceScalarSequences = /* @__PURE__ */ new Map();
|
|
@@ -10779,9 +11319,7 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
10779
11319
|
const op = code[ip];
|
|
10780
11320
|
if (op === OP_GATE && (cfg.tolerant || cfg.probe)) return code[ip + 2];
|
|
10781
11321
|
if (op === OP_RULE) return code[ip + 1];
|
|
10782
|
-
if ((
|
|
10783
|
-
return code[ip + 2];
|
|
10784
|
-
}
|
|
11322
|
+
if (scopeIsIdentity(code, ip, labels.at(ip))) return code[ip + 2];
|
|
10785
11323
|
return void 0;
|
|
10786
11324
|
}
|
|
10787
11325
|
function lower(ip, fname) {
|
|
@@ -10903,6 +11441,22 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
10903
11441
|
return `${head}
|
|
10904
11442
|
if(${gateMissTest(ip)}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
10905
11443
|
return ${child}(input,pos,ctx)
|
|
11444
|
+
}`;
|
|
11445
|
+
}
|
|
11446
|
+
case OP_RGATE: {
|
|
11447
|
+
const child = link(code[ip + 2]);
|
|
11448
|
+
if (cfg.tolerant || cfg.probe) return `${head}
|
|
11449
|
+
return ${child}(input,pos,ctx)
|
|
11450
|
+
}`;
|
|
11451
|
+
const resolved = t.cc[code[ip + 1]];
|
|
11452
|
+
const ci = classes.push([resolved]) - 1;
|
|
11453
|
+
classPlan.push([code[ip + 1]]);
|
|
11454
|
+
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
11455
|
+
const xf = fxRef(code[ip + 3]);
|
|
11456
|
+
return `${head}
|
|
11457
|
+
const it=ctx._routed
|
|
11458
|
+
if(it!==undefined&&it.span.start===pos&&!classHas(${cls},lead(input,it.span.end))){ctx._fe=it.span.end;ctx._fx=${xf};return FAIL}
|
|
11459
|
+
return ${child}(input,pos,ctx)
|
|
10906
11460
|
}`;
|
|
10907
11461
|
}
|
|
10908
11462
|
case OP_ARMGATE: {
|
|
@@ -11177,23 +11731,33 @@ return FAIL
|
|
|
11177
11731
|
const p = tmp();
|
|
11178
11732
|
return `${head}
|
|
11179
11733
|
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${emitMark(p, L.buf, L.raw, sinks)}
|
|
11180
|
-
const v=${child}(input,pos,ctx)
|
|
11734
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
11181
11735
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
11182
|
-
if(v===FAIL){EC.e=pos;return null}
|
|
11736
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){EC.e=pos;return null}
|
|
11183
11737
|
ctx._fe=pos
|
|
11184
11738
|
ctx._fx=${xf}
|
|
11185
11739
|
return FAIL
|
|
11186
11740
|
}`;
|
|
11187
11741
|
}
|
|
11188
11742
|
case OP_PEEK: {
|
|
11743
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
11744
|
+
if (scalarChild >= 0) {
|
|
11745
|
+
const recognize = recognizerRef(code[scalarChild + 1]);
|
|
11746
|
+
const xf2 = fxRef(code[ip + 2]);
|
|
11747
|
+
return `${head}
|
|
11748
|
+
if(${recognize}(input,pos)<0){ctx._fe=pos;ctx._fx=${xf2};return FAIL}
|
|
11749
|
+
EC.e=pos
|
|
11750
|
+
return null
|
|
11751
|
+
}`;
|
|
11752
|
+
}
|
|
11189
11753
|
const child = link(code[ip + 1]);
|
|
11190
11754
|
const xf = fxRef(code[ip + 2]);
|
|
11191
11755
|
const p = tmp();
|
|
11192
11756
|
return `${head}
|
|
11193
11757
|
${lookaheadMiss(code[ip + 1], `ctx._fe=pos;ctx._fx=${xf};return FAIL`)}${emitMark(p, L.buf, L.raw, sinks)}
|
|
11194
|
-
const v=${child}(input,pos,ctx)
|
|
11758
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
11195
11759
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
11196
|
-
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
11760
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
11197
11761
|
EC.e=pos
|
|
11198
11762
|
return null
|
|
11199
11763
|
}`;
|
|
@@ -11264,7 +11828,7 @@ return v
|
|
|
11264
11828
|
);
|
|
11265
11829
|
} else {
|
|
11266
11830
|
const callee = leadingTriviaFieldAt(code, k, childIp) ? `(LEAD.at=cur,${kids[i]})` : kids[i];
|
|
11267
|
-
parts.push(emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
11831
|
+
parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
11268
11832
|
}
|
|
11269
11833
|
names.push(vn);
|
|
11270
11834
|
}
|
|
@@ -11747,6 +12311,26 @@ return nd
|
|
|
11747
12311
|
const trailingTrivia = (flags & 128) !== 0;
|
|
11748
12312
|
const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
|
|
11749
12313
|
const leanFlags = flags & ~128;
|
|
12314
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
12315
|
+
return `${head}
|
|
12316
|
+
const v=${child}(input,pos,ctx)
|
|
12317
|
+
if(v!==undefined)return v
|
|
12318
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
12319
|
+
}`;
|
|
12320
|
+
}
|
|
12321
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
12322
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(labels.at(code[ip + 2]).tri, t.trivia);
|
|
12323
|
+
const gp = gated !== void 0 && triviaLead !== void 0 && triviaLead.length <= 16 ? `const gc=lead(input,pos)
|
|
12324
|
+
if(!(${[
|
|
12325
|
+
...gated.leads.map((g) => `!(${gateMissTest(g)})`),
|
|
12326
|
+
...gated.lits.map((i) => `gc===${k[i].codePointAt(0)}`),
|
|
12327
|
+
...triviaLead.map((r) => r.lo === r.hi ? `gc===${r.lo}` : `(gc>=${r.lo}&&gc<=${r.hi})`)
|
|
12328
|
+
].join("||") || "false"})){
|
|
12329
|
+
const gv=${link(gated.last)}(input,pos,ctx)
|
|
12330
|
+
if(gv!==undefined)return gv
|
|
12331
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
12332
|
+
}
|
|
12333
|
+
` : "";
|
|
11750
12334
|
if (!hostCst && !tracked && build !== void 0 && proj < 0 && (leanFlags === 2 || (flags === 18 || flags === 34))) {
|
|
11751
12335
|
const fields = flags === 18;
|
|
11752
12336
|
const collapseChildren = flags === 34;
|
|
@@ -11781,7 +12365,7 @@ sCh.push(nd)
|
|
|
11781
12365
|
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
11782
12366
|
}`;
|
|
11783
12367
|
return `${head}
|
|
11784
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
12368
|
+
${gp}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
11785
12369
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf,sFields=ctx._fields
|
|
11786
12370
|
const flat=[]
|
|
11787
12371
|
ctx._cstBuf=undefined
|
|
@@ -11856,7 +12440,7 @@ const hostKids=kids
|
|
|
11856
12440
|
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
11857
12441
|
const tlog=buf.tl??EMPTY_TLOG`;
|
|
11858
12442
|
return `${head}
|
|
11859
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
12443
|
+
${!hostCst && !tracked ? gp : ""}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
11860
12444
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
11861
12445
|
${openCapture}
|
|
11862
12446
|
ctx.captureTrivia=${captureWide}
|
|
@@ -11926,9 +12510,15 @@ ext:[${externals.join(",")}],
|
|
|
11926
12510
|
bind:function(xs,ps){_xScan=xs
|
|
11927
12511
|
${externals.map((ip, i) => `_xp${ip}=ps[${i}]`).join("\n")}},
|
|
11928
12512
|
scan:function(s){const o=_pfScan;_pfScan=s;return o}`;
|
|
12513
|
+
const scannerFor = (ip) => {
|
|
12514
|
+
const ki = labels.at(ip).tri;
|
|
12515
|
+
if (ki === TRI_UNKNOWN) return "_pfScan";
|
|
12516
|
+
if (ki === TRI_NONE) return "null";
|
|
12517
|
+
return swapLegal && !triviaLabelled[ki] && t.triviaScan[ki] != null ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
12518
|
+
};
|
|
11929
12519
|
const externalDefs = select === void 0 ? "" : `let _xScan
|
|
11930
12520
|
${externals.map((ip) => `let _xp${ip}
|
|
11931
|
-
function _px${ip}(input,pos,ctx){const o=_xScan(
|
|
12521
|
+
function _px${ip}(input,pos,ctx){const o=_xScan(${scannerFor(ip)});const v=_xp${ip}(input,pos,ctx);_xScan(o);return v}`).join("\n")}
|
|
11932
12522
|
`;
|
|
11933
12523
|
const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
|
|
11934
12524
|
${prelude.join("\n")}
|
|
@@ -12465,37 +13055,120 @@ function clearOf(ranges, input, from, to) {
|
|
|
12465
13055
|
return true;
|
|
12466
13056
|
}
|
|
12467
13057
|
|
|
12468
|
-
// src/table/
|
|
12469
|
-
function
|
|
12470
|
-
|
|
12471
|
-
|
|
12472
|
-
|
|
12473
|
-
|
|
12474
|
-
|
|
12475
|
-
|
|
13058
|
+
// src/table/fail-clean.ts
|
|
13059
|
+
function passChild(code, ip) {
|
|
13060
|
+
switch (code[ip]) {
|
|
13061
|
+
case OP_RULE:
|
|
13062
|
+
case OP_LABEL:
|
|
13063
|
+
case OP_COV:
|
|
13064
|
+
case OP_TOKEN:
|
|
13065
|
+
return code[ip + 1];
|
|
13066
|
+
case OP_GATE:
|
|
13067
|
+
case OP_NODE:
|
|
13068
|
+
case OP_NODE_TRACK:
|
|
13069
|
+
case OP_XFORM:
|
|
13070
|
+
case OP_FIELD:
|
|
13071
|
+
case OP_SCOPE:
|
|
13072
|
+
case OP_SCOPE_CAP:
|
|
13073
|
+
case OP_SCOPE_PLAIN:
|
|
13074
|
+
case OP_WITHCTX:
|
|
13075
|
+
case OP_LEAF:
|
|
13076
|
+
case OP_SOURCE_LEAF:
|
|
13077
|
+
return code[ip + 2];
|
|
13078
|
+
default:
|
|
13079
|
+
return -1;
|
|
12476
13080
|
}
|
|
12477
|
-
return [lo + 1, offset - starts[lo] + 1];
|
|
12478
|
-
}
|
|
12479
|
-
function spanLines(ctx, start, end) {
|
|
12480
|
-
const s = lineCol(ctx, start), e = lineCol(ctx, end);
|
|
12481
|
-
return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] };
|
|
12482
13081
|
}
|
|
12483
|
-
function
|
|
12484
|
-
|
|
12485
|
-
|
|
12486
|
-
|
|
12487
|
-
|
|
12488
|
-
|
|
12489
|
-
|
|
12490
|
-
|
|
12491
|
-
|
|
13082
|
+
function seqCount(code, ip) {
|
|
13083
|
+
const op = code[ip];
|
|
13084
|
+
return op === OP_SEQ || op === OP_SEQV ? ip + 1 : op === OP_SEQX ? ip + 2 : -1;
|
|
13085
|
+
}
|
|
13086
|
+
function failCleanAnalysis(code) {
|
|
13087
|
+
const cleanAt = new Uint8Array(code.length);
|
|
13088
|
+
const neverAt = new Uint8Array(code.length);
|
|
13089
|
+
const neverFails = (ip) => {
|
|
13090
|
+
const hit = neverAt[ip];
|
|
13091
|
+
if (hit !== 0) return hit === 1;
|
|
13092
|
+
neverAt[ip] = 3;
|
|
13093
|
+
let out = false;
|
|
13094
|
+
const op = code[ip];
|
|
13095
|
+
if (op === OP_OPT || op === OP_EMPTY || op === OP_EXPECT) out = true;
|
|
13096
|
+
else if (op === OP_REP || op === OP_REPV) out = code[ip + 2] === 0;
|
|
13097
|
+
else {
|
|
13098
|
+
const at = seqCount(code, ip);
|
|
13099
|
+
if (at >= 0) {
|
|
13100
|
+
out = true;
|
|
13101
|
+
for (let i = 1, n = code[at]; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
13102
|
+
} else if (op !== OP_GATE) {
|
|
13103
|
+
const c = passChild(code, ip);
|
|
13104
|
+
out = c >= 0 && neverFails(c);
|
|
13105
|
+
}
|
|
13106
|
+
}
|
|
13107
|
+
neverAt[ip] = out ? 1 : 2;
|
|
13108
|
+
return out;
|
|
12492
13109
|
};
|
|
12493
|
-
|
|
12494
|
-
|
|
12495
|
-
|
|
12496
|
-
|
|
12497
|
-
|
|
12498
|
-
|
|
13110
|
+
const clean = (ip) => {
|
|
13111
|
+
const hit = cleanAt[ip];
|
|
13112
|
+
if (hit !== 0) return hit === 1;
|
|
13113
|
+
cleanAt[ip] = 3;
|
|
13114
|
+
let out = false;
|
|
13115
|
+
switch (code[ip]) {
|
|
13116
|
+
// A terminal pushes its leaf only on a match; NOT/PEEK/ATTEMPT restore
|
|
13117
|
+
// their own mark; OPT, EMPTY and EXPECT do not fail uncommitted.
|
|
13118
|
+
case OP_LIT:
|
|
13119
|
+
case OP_RX:
|
|
13120
|
+
case OP_LIT_TRACK:
|
|
13121
|
+
case OP_RX_TRACK:
|
|
13122
|
+
case OP_LIT_CI:
|
|
13123
|
+
case OP_LIT_CI_TRACK:
|
|
13124
|
+
case OP_GUARD:
|
|
13125
|
+
case OP_NOT:
|
|
13126
|
+
case OP_PEEK:
|
|
13127
|
+
case OP_ATTEMPT:
|
|
13128
|
+
case OP_EMPTY:
|
|
13129
|
+
case OP_OPT:
|
|
13130
|
+
case OP_EXPECT:
|
|
13131
|
+
out = true;
|
|
13132
|
+
break;
|
|
13133
|
+
// Min 0 does not fail uncommitted; min 1 fails only with no item kept, and
|
|
13134
|
+
// restores the failed item itself.
|
|
13135
|
+
case OP_REP:
|
|
13136
|
+
case OP_REPV:
|
|
13137
|
+
out = code[ip + 2] <= 1;
|
|
13138
|
+
break;
|
|
13139
|
+
// Only the first term may fail: a later one fails after the terms before it
|
|
13140
|
+
// wrote, and after the trivia scanned in front of it.
|
|
13141
|
+
case OP_SEQ:
|
|
13142
|
+
case OP_SEQV:
|
|
13143
|
+
case OP_SEQX: {
|
|
13144
|
+
const at = seqCount(code, ip);
|
|
13145
|
+
const n = code[at];
|
|
13146
|
+
out = n > 0 && clean(code[at + 1]);
|
|
13147
|
+
for (let i = 2; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
13148
|
+
break;
|
|
13149
|
+
}
|
|
13150
|
+
case OP_CHOICE: {
|
|
13151
|
+
out = true;
|
|
13152
|
+
for (let i = 0, n = code[ip + 2]; out && i < n; i++) out = clean(code[ip + 4 + i]);
|
|
13153
|
+
break;
|
|
13154
|
+
}
|
|
13155
|
+
case OP_ROUTED:
|
|
13156
|
+
out = code[ip + 1] < 0 || clean(code[ip + 1]);
|
|
13157
|
+
break;
|
|
13158
|
+
// An arm's failure and the fallback's are committed; only the selector's is
|
|
13159
|
+
// not, and without a fallback an unknown key fails after the selector wrote.
|
|
13160
|
+
case OP_DISPATCH:
|
|
13161
|
+
out = code[ip + 3] >= 0 && clean(code[ip + 1]);
|
|
13162
|
+
break;
|
|
13163
|
+
default: {
|
|
13164
|
+
const c = passChild(code, ip);
|
|
13165
|
+
out = c >= 0 && clean(c);
|
|
13166
|
+
}
|
|
13167
|
+
}
|
|
13168
|
+
cleanAt[ip] = out ? 1 : 2;
|
|
13169
|
+
return out;
|
|
13170
|
+
};
|
|
13171
|
+
return clean;
|
|
12499
13172
|
}
|
|
12500
13173
|
|
|
12501
13174
|
// src/cst/host-mode.ts
|
|
@@ -12660,6 +13333,7 @@ function assemble(t, prog, cfg) {
|
|
|
12660
13333
|
const swapLegal = !cfg.trackLines;
|
|
12661
13334
|
const hostCst = cfg.hostCst;
|
|
12662
13335
|
const REC2 = prog.rec === 1 && cfg.tolerant;
|
|
13336
|
+
const PROBE = cfg.probe;
|
|
12663
13337
|
const sentinels = /* @__PURE__ */ new Map();
|
|
12664
13338
|
function sentinelFor(cls) {
|
|
12665
13339
|
if (cls < 0) return void 0;
|
|
@@ -12705,6 +13379,8 @@ function assemble(t, prog, cfg) {
|
|
|
12705
13379
|
}
|
|
12706
13380
|
const memo = /* @__PURE__ */ new Map();
|
|
12707
13381
|
const reached = /* @__PURE__ */ new Set();
|
|
13382
|
+
const NULLABLE = /* @__PURE__ */ new Map();
|
|
13383
|
+
const CLEAN = REC2 ? () => false : failCleanAnalysis(code);
|
|
12708
13384
|
function pushLeaf(ctx, value, s, e) {
|
|
12709
13385
|
const lf = { _tag: "leaf", value, span: { start: s, end: e } };
|
|
12710
13386
|
pushCstLeaf(ctx, lf);
|
|
@@ -12903,6 +13579,22 @@ function assemble(t, prog, cfg) {
|
|
|
12903
13579
|
return node2;
|
|
12904
13580
|
};
|
|
12905
13581
|
}
|
|
13582
|
+
function passCollapseNode(child, build, readsRaw) {
|
|
13583
|
+
return (input, pos, ctx) => {
|
|
13584
|
+
const v = child(input, pos, ctx);
|
|
13585
|
+
if (v !== void 0) return v;
|
|
13586
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
13587
|
+
};
|
|
13588
|
+
}
|
|
13589
|
+
function gatedPassCollapseNode(blockers, last, classic, build, readsRaw) {
|
|
13590
|
+
return (input, pos, ctx) => {
|
|
13591
|
+
const c = lead(input, pos);
|
|
13592
|
+
for (let i = 0; i < blockers.length; i++) if (classHas2(blockers[i], c)) return classic(input, pos, ctx);
|
|
13593
|
+
const v = last(input, pos, ctx);
|
|
13594
|
+
if (v !== void 0) return v;
|
|
13595
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
13596
|
+
};
|
|
13597
|
+
}
|
|
12906
13598
|
function plainProjectNode(child, projection, type) {
|
|
12907
13599
|
return (input, pos, ctx) => {
|
|
12908
13600
|
const sCh = ctx._cstChildren;
|
|
@@ -13273,21 +13965,27 @@ function assemble(t, prog, cfg) {
|
|
|
13273
13965
|
}
|
|
13274
13966
|
function dispatchBranch(child, usesRouted) {
|
|
13275
13967
|
if (!usesRouted) {
|
|
13276
|
-
return (input, _pos, selEnd, key,
|
|
13277
|
-
const
|
|
13968
|
+
return (input, _pos, selEnd, key, ctx) => {
|
|
13969
|
+
const need = markCst(ctx);
|
|
13970
|
+
const mRaw = MRAW;
|
|
13971
|
+
const mTl = MTL;
|
|
13972
|
+
const mLv = MLV;
|
|
13973
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
13974
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13975
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13976
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
13278
13977
|
const v = child(input, selEnd, ctx);
|
|
13279
13978
|
if (v === FAIL) {
|
|
13280
|
-
|
|
13979
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13281
13980
|
ctx._fc = true;
|
|
13282
13981
|
return FAIL;
|
|
13283
13982
|
}
|
|
13284
13983
|
return [key, v];
|
|
13285
13984
|
};
|
|
13286
13985
|
}
|
|
13287
|
-
return (input, pos, selEnd, key,
|
|
13986
|
+
return (input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
13288
13987
|
const savedRouted = ctx._routed;
|
|
13289
|
-
|
|
13290
|
-
const mark = saveTriviaMark(ctx);
|
|
13988
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13291
13989
|
ctx._routed = { value: key, span: { start: pos, end: selEnd } };
|
|
13292
13990
|
let v;
|
|
13293
13991
|
try {
|
|
@@ -13296,7 +13994,7 @@ function assemble(t, prog, cfg) {
|
|
|
13296
13994
|
ctx._routed = savedRouted;
|
|
13297
13995
|
}
|
|
13298
13996
|
if (v === FAIL) {
|
|
13299
|
-
|
|
13997
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13300
13998
|
ctx._fc = true;
|
|
13301
13999
|
return FAIL;
|
|
13302
14000
|
}
|
|
@@ -13304,12 +14002,12 @@ function assemble(t, prog, cfg) {
|
|
|
13304
14002
|
};
|
|
13305
14003
|
}
|
|
13306
14004
|
function dispatchArmBlock(start, a0, a1, a2, a3, next) {
|
|
13307
|
-
return (arm, input, pos, selEnd, key,
|
|
13308
|
-
if (arm === start) return a0(input, pos, selEnd, key,
|
|
13309
|
-
if (arm === start + 1) return a1(input, pos, selEnd, key,
|
|
13310
|
-
if (arm === start + 2) return a2(input, pos, selEnd, key,
|
|
13311
|
-
if (arm === start + 3) return a3(input, pos, selEnd, key,
|
|
13312
|
-
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key,
|
|
14005
|
+
return (arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
14006
|
+
if (arm === start) return a0(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14007
|
+
if (arm === start + 1) return a1(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14008
|
+
if (arm === start + 2) return a2(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14009
|
+
if (arm === start + 3) return a3(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14010
|
+
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13313
14011
|
};
|
|
13314
14012
|
}
|
|
13315
14013
|
function trackLinesInto(ctx, input, end) {
|
|
@@ -13328,7 +14026,7 @@ function assemble(t, prog, cfg) {
|
|
|
13328
14026
|
if (flight !== void 0) return flight.fwd;
|
|
13329
14027
|
const selected = HYBRID?.byIp[ip];
|
|
13330
14028
|
if (selected !== void 0) {
|
|
13331
|
-
const piece2 = hybridPiece(selected);
|
|
14029
|
+
const piece2 = scanHandoffNeeded(code, ip, closureLabels) ? hybridPiece(selected) : selected;
|
|
13332
14030
|
memo.set(ip, piece2);
|
|
13333
14031
|
reached.add(ip);
|
|
13334
14032
|
return piece2;
|
|
@@ -13339,14 +14037,55 @@ function assemble(t, prog, cfg) {
|
|
|
13339
14037
|
target = p;
|
|
13340
14038
|
} };
|
|
13341
14039
|
inFlight.set(ip, holder);
|
|
13342
|
-
const
|
|
13343
|
-
const piece = (op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[ip + 3] === 0) && code[ip + 1] >= 0 && closureLabels.at(ip).tri === code[ip + 1] ? link(code[ip + 2]) : countedPiece(lower(ip), ip);
|
|
14040
|
+
const piece = scopeIsIdentity(code, ip, closureLabels.at(ip)) ? link(code[ip + 2]) : countedPiece(lookaheadLedNode(ip) ?? lower(ip), ip);
|
|
13344
14041
|
inFlight.delete(ip);
|
|
13345
14042
|
holder.set(piece);
|
|
13346
14043
|
memo.set(ip, piece);
|
|
13347
14044
|
reached.add(ip);
|
|
13348
14045
|
return piece;
|
|
13349
14046
|
}
|
|
14047
|
+
let FIRST_DECIDED;
|
|
14048
|
+
let NODE_BODY;
|
|
14049
|
+
const DECIDED = (_input, pos) => {
|
|
14050
|
+
EC.e = pos;
|
|
14051
|
+
return null;
|
|
14052
|
+
};
|
|
14053
|
+
function lookaheadLedNode(ip) {
|
|
14054
|
+
const op = code[ip];
|
|
14055
|
+
if (op !== OP_NODE && op !== OP_NODE_TRACK || hostCst || REC2 || cfg.probe || cfg.coverage || cfg.trackLines) return void 0;
|
|
14056
|
+
if (passCollapse(code, ip, hostCst) || gatedPassCollapse(code, ip, hostCst) !== void 0) return void 0;
|
|
14057
|
+
const body = code[ip + 2];
|
|
14058
|
+
const bop = code[body];
|
|
14059
|
+
if (bop !== OP_SEQ && bop !== OP_SEQV && bop !== OP_SEQX) return void 0;
|
|
14060
|
+
const base = bop === OP_SEQX ? body + 3 : body + 2;
|
|
14061
|
+
if (code[bop === OP_SEQX ? body + 2 : body + 1] < 2) return void 0;
|
|
14062
|
+
const first = code[base];
|
|
14063
|
+
const negative = code[first] === OP_NOT;
|
|
14064
|
+
const terminal = negative ? scalarTerminalNotChild(code, first) : code[first] === OP_PEEK ? scalarTerminalPeekChild(code, first) : -1;
|
|
14065
|
+
if (terminal < 0) return void 0;
|
|
14066
|
+
const recognize = scalarFor(terminal);
|
|
14067
|
+
const xf = fx[code[first + 2]];
|
|
14068
|
+
FIRST_DECIDED = DECIDED;
|
|
14069
|
+
NODE_BODY = lower(body);
|
|
14070
|
+
const node2 = lower(ip);
|
|
14071
|
+
NODE_BODY = void 0;
|
|
14072
|
+
return negative ? (input, pos, ctx) => {
|
|
14073
|
+
if (recognize(input, pos) >= 0) {
|
|
14074
|
+
ctx._fe = pos;
|
|
14075
|
+
ctx._fx = xf;
|
|
14076
|
+
EC.e = pos;
|
|
14077
|
+
return FAIL;
|
|
14078
|
+
}
|
|
14079
|
+
return node2(input, pos, ctx);
|
|
14080
|
+
} : (input, pos, ctx) => {
|
|
14081
|
+
if (recognize(input, pos) < 0) {
|
|
14082
|
+
ctx._fe = pos;
|
|
14083
|
+
ctx._fx = xf;
|
|
14084
|
+
return FAIL;
|
|
14085
|
+
}
|
|
14086
|
+
return node2(input, pos, ctx);
|
|
14087
|
+
};
|
|
14088
|
+
}
|
|
13350
14089
|
function lower(ip) {
|
|
13351
14090
|
const op = code[ip];
|
|
13352
14091
|
switch (op) {
|
|
@@ -13891,8 +14630,10 @@ function assemble(t, prog, cfg) {
|
|
|
13891
14630
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13892
14631
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13893
14632
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14633
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
13894
14634
|
const v = child(input, pos, ctx);
|
|
13895
14635
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14636
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
13896
14637
|
if (v === FAIL) {
|
|
13897
14638
|
EC.e = pos;
|
|
13898
14639
|
return null;
|
|
@@ -13903,6 +14644,20 @@ function assemble(t, prog, cfg) {
|
|
|
13903
14644
|
};
|
|
13904
14645
|
}
|
|
13905
14646
|
case OP_PEEK: {
|
|
14647
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
14648
|
+
if (scalarChild >= 0) {
|
|
14649
|
+
const recognize = scalarFor(scalarChild);
|
|
14650
|
+
const xf2 = fx[code[ip + 2]];
|
|
14651
|
+
return (input, pos, ctx) => {
|
|
14652
|
+
if (recognize(input, pos) < 0) {
|
|
14653
|
+
ctx._fe = pos;
|
|
14654
|
+
ctx._fx = xf2;
|
|
14655
|
+
return FAIL;
|
|
14656
|
+
}
|
|
14657
|
+
EC.e = pos;
|
|
14658
|
+
return null;
|
|
14659
|
+
};
|
|
14660
|
+
}
|
|
13906
14661
|
const child = link(code[ip + 1]);
|
|
13907
14662
|
const xf = fx[code[ip + 2]];
|
|
13908
14663
|
const gate2 = lookaheadClass(code[ip + 1]);
|
|
@@ -13920,8 +14675,10 @@ function assemble(t, prog, cfg) {
|
|
|
13920
14675
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13921
14676
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13922
14677
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14678
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
13923
14679
|
const v = child(input, pos, ctx);
|
|
13924
14680
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14681
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
13925
14682
|
if (v === FAIL) {
|
|
13926
14683
|
ctx._fe = pos;
|
|
13927
14684
|
ctx._fx = xf;
|
|
@@ -13934,12 +14691,13 @@ function assemble(t, prog, cfg) {
|
|
|
13934
14691
|
case OP_OPT: {
|
|
13935
14692
|
const child = link(code[ip + 1]);
|
|
13936
14693
|
const gate2 = lookaheadClass(code[ip + 1]);
|
|
14694
|
+
const childClean = CLEAN(code[ip + 1]);
|
|
13937
14695
|
return (input, pos, ctx) => {
|
|
13938
14696
|
if (gate2 !== null && !classHas2(gate2, lead(input, pos))) {
|
|
13939
14697
|
EC.e = pos;
|
|
13940
14698
|
return null;
|
|
13941
14699
|
}
|
|
13942
|
-
const need = markCst(ctx);
|
|
14700
|
+
const need = !childClean && markCst(ctx);
|
|
13943
14701
|
const mRaw = MRAW;
|
|
13944
14702
|
const mTl = MTL;
|
|
13945
14703
|
const mLv = MLV;
|
|
@@ -14137,6 +14895,9 @@ function assemble(t, prog, cfg) {
|
|
|
14137
14895
|
const projection = reducer < 0 ? ~reducer : -1;
|
|
14138
14896
|
const fn = fused && projection < 0 ? fns[reducer] : void 0;
|
|
14139
14897
|
const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm;
|
|
14898
|
+
const decided = FIRST_DECIDED;
|
|
14899
|
+
FIRST_DECIDED = void 0;
|
|
14900
|
+
const linkFirst = () => decided ?? link(code[base]);
|
|
14140
14901
|
const runnerBlock = (count, r0, r1, r2, r3, next) => {
|
|
14141
14902
|
if (count === 1) return (input, cur, ctx, values, inherited) => {
|
|
14142
14903
|
cur = r0(input, cur, ctx, inherited);
|
|
@@ -14182,7 +14943,7 @@ function assemble(t, prog, cfg) {
|
|
|
14182
14943
|
};
|
|
14183
14944
|
};
|
|
14184
14945
|
if (REC2) {
|
|
14185
|
-
const first2 =
|
|
14946
|
+
const first2 = linkFirst();
|
|
14186
14947
|
const firstSync = sentinelFor(code[base + n]);
|
|
14187
14948
|
const runnerAt = (i) => {
|
|
14188
14949
|
const sync = sentinelFor(code[base + n + i]);
|
|
@@ -14218,13 +14979,13 @@ function assemble(t, prog, cfg) {
|
|
|
14218
14979
|
const bindRunners = (start) => {
|
|
14219
14980
|
const count = Math.min(4, n - start);
|
|
14220
14981
|
const at = (offset) => runnerAt(start + offset);
|
|
14221
|
-
const
|
|
14982
|
+
const never2 = () => -1;
|
|
14222
14983
|
return runnerBlock(
|
|
14223
14984
|
count,
|
|
14224
14985
|
at(0),
|
|
14225
|
-
count > 1 ? at(1) :
|
|
14226
|
-
count > 2 ? at(2) :
|
|
14227
|
-
count > 3 ? at(3) :
|
|
14986
|
+
count > 1 ? at(1) : never2,
|
|
14987
|
+
count > 2 ? at(2) : never2,
|
|
14988
|
+
count > 3 ? at(3) : never2,
|
|
14228
14989
|
start + count < n ? bindRunners(start + count) : void 0
|
|
14229
14990
|
);
|
|
14230
14991
|
};
|
|
@@ -14274,15 +15035,31 @@ function assemble(t, prog, cfg) {
|
|
|
14274
15035
|
let hasAdj = false;
|
|
14275
15036
|
for (let i = 1; i < n; i++) {
|
|
14276
15037
|
const kidIp = code[base + i];
|
|
14277
|
-
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp)) {
|
|
15038
|
+
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp) || holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
14278
15039
|
hasAdj = true;
|
|
14279
15040
|
break;
|
|
14280
15041
|
}
|
|
14281
15042
|
}
|
|
14282
15043
|
if (hasAdj) {
|
|
14283
|
-
const first2 =
|
|
15044
|
+
const first2 = linkFirst();
|
|
14284
15045
|
const runnerAt = (i) => {
|
|
14285
15046
|
const kidIp = code[base + i];
|
|
15047
|
+
if (holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
15048
|
+
const kid = link(kidIp);
|
|
15049
|
+
return (input, cur, ctx) => {
|
|
15050
|
+
if (ctx.trivia === void 0) {
|
|
15051
|
+
const v2 = kid(input, cur, ctx);
|
|
15052
|
+
if (v2 === FAIL) return -1;
|
|
15053
|
+
TERMV = v2;
|
|
15054
|
+
return EC.e;
|
|
15055
|
+
}
|
|
15056
|
+
const scanEnd = skipTrivia(input, cur, ctx);
|
|
15057
|
+
const v = kid(input, scanEnd, ctx);
|
|
15058
|
+
if (v === FAIL) return -1;
|
|
15059
|
+
TERMV = v;
|
|
15060
|
+
return scanEnd;
|
|
15061
|
+
};
|
|
15062
|
+
}
|
|
14286
15063
|
if (code[kidIp] !== OP_ADJ) {
|
|
14287
15064
|
const kid = link(kidIp);
|
|
14288
15065
|
if (leadingTriviaFieldAt(code, k, kidIp)) {
|
|
@@ -14307,13 +15084,13 @@ function assemble(t, prog, cfg) {
|
|
|
14307
15084
|
const bindRunners = (start) => {
|
|
14308
15085
|
const count = Math.min(4, n - start);
|
|
14309
15086
|
const at = (offset) => runnerAt(start + offset);
|
|
14310
|
-
const
|
|
15087
|
+
const never2 = () => -1;
|
|
14311
15088
|
return runnerBlock(
|
|
14312
15089
|
count,
|
|
14313
15090
|
at(0),
|
|
14314
|
-
count > 1 ? at(1) :
|
|
14315
|
-
count > 2 ? at(2) :
|
|
14316
|
-
count > 3 ? at(3) :
|
|
15091
|
+
count > 1 ? at(1) : never2,
|
|
15092
|
+
count > 2 ? at(2) : never2,
|
|
15093
|
+
count > 3 ? at(3) : never2,
|
|
14317
15094
|
start + count < n ? bindRunners(start + count) : void 0
|
|
14318
15095
|
);
|
|
14319
15096
|
};
|
|
@@ -14350,7 +15127,7 @@ function assemble(t, prog, cfg) {
|
|
|
14350
15127
|
};
|
|
14351
15128
|
}
|
|
14352
15129
|
if (n === 1) {
|
|
14353
|
-
const k0 =
|
|
15130
|
+
const k0 = linkFirst();
|
|
14354
15131
|
if (fused) {
|
|
14355
15132
|
return (input, pos, ctx) => {
|
|
14356
15133
|
const v = k0(input, pos, ctx);
|
|
@@ -14372,7 +15149,7 @@ function assemble(t, prog, cfg) {
|
|
|
14372
15149
|
};
|
|
14373
15150
|
}
|
|
14374
15151
|
if (n === 2) {
|
|
14375
|
-
const k0 =
|
|
15152
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]);
|
|
14376
15153
|
if (fused) {
|
|
14377
15154
|
return (input, pos, ctx) => {
|
|
14378
15155
|
const v0 = k0(input, pos, ctx);
|
|
@@ -14403,7 +15180,7 @@ function assemble(t, prog, cfg) {
|
|
|
14403
15180
|
};
|
|
14404
15181
|
}
|
|
14405
15182
|
if (n === 3) {
|
|
14406
|
-
const k0 =
|
|
15183
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]), k2 = link(code[base + 2]);
|
|
14407
15184
|
if (fused) {
|
|
14408
15185
|
return (input, pos, ctx) => {
|
|
14409
15186
|
const v0 = k0(input, pos, ctx);
|
|
@@ -14497,7 +15274,7 @@ function assemble(t, prog, cfg) {
|
|
|
14497
15274
|
start + count < n ? bind(start + count) : void 0
|
|
14498
15275
|
);
|
|
14499
15276
|
};
|
|
14500
|
-
const first =
|
|
15277
|
+
const first = linkFirst();
|
|
14501
15278
|
const tail = bind(1);
|
|
14502
15279
|
const runDirectTerms = (input, pos, ctx, values) => {
|
|
14503
15280
|
const v0 = first(input, pos, ctx);
|
|
@@ -14536,6 +15313,8 @@ function assemble(t, prog, cfg) {
|
|
|
14536
15313
|
const n = code[ip + 2];
|
|
14537
15314
|
const choiceFx = fx[code[ip + 3]];
|
|
14538
15315
|
const base = ip + 4;
|
|
15316
|
+
for (let i = 0; i < n; i++) link(code[base + i]);
|
|
15317
|
+
const armsClean = CLEAN(ip);
|
|
14539
15318
|
if (table.exclusive) {
|
|
14540
15319
|
const ascii = table.ascii;
|
|
14541
15320
|
const hi = table.hi;
|
|
@@ -14675,7 +15454,7 @@ function assemble(t, prog, cfg) {
|
|
|
14675
15454
|
if (n === 3) addGate(g2, 4);
|
|
14676
15455
|
return (input, pos, ctx) => {
|
|
14677
15456
|
const c = lead(input, pos);
|
|
14678
|
-
const need = markCst(ctx);
|
|
15457
|
+
const need = !armsClean && markCst(ctx);
|
|
14679
15458
|
const mRaw = MRAW;
|
|
14680
15459
|
const mTl = MTL;
|
|
14681
15460
|
const mLv = MLV;
|
|
@@ -14892,7 +15671,7 @@ function assemble(t, prog, cfg) {
|
|
|
14892
15671
|
if (pn !== 0) {
|
|
14893
15672
|
return (input, pos, ctx) => {
|
|
14894
15673
|
const c = lead(input, pos);
|
|
14895
|
-
const need = markCst(ctx);
|
|
15674
|
+
const need = !armsClean && markCst(ctx);
|
|
14896
15675
|
const mRaw = MRAW;
|
|
14897
15676
|
const mTl = MTL;
|
|
14898
15677
|
const mLv = MLV;
|
|
@@ -14949,7 +15728,7 @@ function assemble(t, prog, cfg) {
|
|
|
14949
15728
|
}
|
|
14950
15729
|
return (input, pos, ctx) => {
|
|
14951
15730
|
const c = lead(input, pos);
|
|
14952
|
-
const need = markCst(ctx);
|
|
15731
|
+
const need = !armsClean && markCst(ctx);
|
|
14953
15732
|
const mRaw = MRAW;
|
|
14954
15733
|
const mTl = MTL;
|
|
14955
15734
|
const mLv = MLV;
|
|
@@ -14997,7 +15776,7 @@ function assemble(t, prog, cfg) {
|
|
|
14997
15776
|
}
|
|
14998
15777
|
return (input, pos, ctx) => {
|
|
14999
15778
|
const c = lead(input, pos);
|
|
15000
|
-
const need = markCst(ctx);
|
|
15779
|
+
const need = !armsClean && markCst(ctx);
|
|
15001
15780
|
const mRaw = MRAW;
|
|
15002
15781
|
const mTl = MTL;
|
|
15003
15782
|
const mLv = MLV;
|
|
@@ -15051,6 +15830,21 @@ function assemble(t, prog, cfg) {
|
|
|
15051
15830
|
return lit(input, pos, ctx);
|
|
15052
15831
|
};
|
|
15053
15832
|
}
|
|
15833
|
+
case OP_RGATE: {
|
|
15834
|
+
const cls = cc[code[ip + 1]];
|
|
15835
|
+
const xf = fx[code[ip + 3]];
|
|
15836
|
+
const child = link(code[ip + 2]);
|
|
15837
|
+
if (cfg.tolerant || cfg.probe) return child;
|
|
15838
|
+
return (input, pos, ctx) => {
|
|
15839
|
+
const item = ctx._routed;
|
|
15840
|
+
if (item !== void 0 && item.span.start === pos && !classHas2(cls, lead(input, item.span.end))) {
|
|
15841
|
+
ctx._fe = item.span.end;
|
|
15842
|
+
ctx._fx = xf;
|
|
15843
|
+
return FAIL;
|
|
15844
|
+
}
|
|
15845
|
+
return child(input, pos, ctx);
|
|
15846
|
+
};
|
|
15847
|
+
}
|
|
15054
15848
|
case OP_ARMGATE: {
|
|
15055
15849
|
const pred = fns[code[ip + 1]];
|
|
15056
15850
|
const child = link(code[ip + 2]);
|
|
@@ -15119,6 +15913,7 @@ function assemble(t, prog, cfg) {
|
|
|
15119
15913
|
const itemClass = !REC2 && itemClassIndex >= 0 ? cc[itemClassIndex] : void 0;
|
|
15120
15914
|
const itemMayStart = itemClass === void 0 ? void 0 : (input, pos) => classHas2(itemClass, lead(input, pos));
|
|
15121
15915
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
15916
|
+
const itemClean = sepIp < 0 && CLEAN(code[ip + 1]) && !rowNullable(code, k, code[ip + 1], NULLABLE);
|
|
15122
15917
|
if (REC2) {
|
|
15123
15918
|
const itemFx2 = fx[code[ip + 6]];
|
|
15124
15919
|
const sepSent = sentinelFor(code[ip + 7]);
|
|
@@ -15215,6 +16010,8 @@ function assemble(t, prog, cfg) {
|
|
|
15215
16010
|
const out = collect ? [] : void 0;
|
|
15216
16011
|
const hasTrivia = ctx.trivia !== void 0;
|
|
15217
16012
|
const needMark = rollbackNeeded(ctx);
|
|
16013
|
+
const markLater = needMark && (!itemClean || hasTrivia);
|
|
16014
|
+
const markFirst = needMark && (!itemClean || hasTrivia && skipBeforeFirst);
|
|
15218
16015
|
const gateItems = itemMayStart !== void 0 && ctx._probe === void 0;
|
|
15219
16016
|
let cur = pos;
|
|
15220
16017
|
let count = 0;
|
|
@@ -15222,14 +16019,15 @@ function assemble(t, prog, cfg) {
|
|
|
15222
16019
|
if (max >= 0 && count >= max) break;
|
|
15223
16020
|
if (sep !== void 0 && count > 0 && count >= min && cur >= input.length) break;
|
|
15224
16021
|
if (count >= min && sep === void 0 && !hasTrivia && gateItems && !itemMayStart(input, cur)) break;
|
|
15225
|
-
|
|
15226
|
-
|
|
15227
|
-
const
|
|
15228
|
-
const
|
|
15229
|
-
const
|
|
15230
|
-
const
|
|
15231
|
-
const
|
|
15232
|
-
const
|
|
16022
|
+
const markIt = count > 0 ? markLater : markFirst;
|
|
16023
|
+
if (markIt) markCst(ctx);
|
|
16024
|
+
const mRaw = markIt ? MRAW : 0;
|
|
16025
|
+
const mTl = markIt ? MTL : 0;
|
|
16026
|
+
const mLv = markIt ? MLV : 0;
|
|
16027
|
+
const mFl = markIt ? ctx._fields?.length ?? 0 : 0;
|
|
16028
|
+
const mEr = markIt ? ctx._errors?.length ?? 0 : 0;
|
|
16029
|
+
const mLog = markIt ? ctx._triviaLog?.length ?? 0 : 0;
|
|
16030
|
+
const mRoot = markIt ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
15233
16031
|
let itemStart = cur;
|
|
15234
16032
|
let sepEnd = -1;
|
|
15235
16033
|
const viaRepItem = sep === void 0 && count >= min && (count > 0 || skipBeforeFirst);
|
|
@@ -15241,7 +16039,7 @@ function assemble(t, prog, cfg) {
|
|
|
15241
16039
|
if (sepLeads) LEAD.at = cur;
|
|
15242
16040
|
const sv = sep(input, sp, ctx);
|
|
15243
16041
|
if (sv === FAIL) {
|
|
15244
|
-
if (
|
|
16042
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
15245
16043
|
if (committed3(ctx)) return FAIL;
|
|
15246
16044
|
break;
|
|
15247
16045
|
}
|
|
@@ -15252,25 +16050,25 @@ function assemble(t, prog, cfg) {
|
|
|
15252
16050
|
itemStart = skipTrivia(input, itemStart, ctx);
|
|
15253
16051
|
}
|
|
15254
16052
|
if (itemStart >= input.length && viaRepItem) {
|
|
15255
|
-
if (
|
|
16053
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
15256
16054
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
15257
16055
|
break;
|
|
15258
16056
|
}
|
|
15259
16057
|
if (count >= min && gateItems && !itemMayStart(input, itemStart)) {
|
|
15260
|
-
if (
|
|
16058
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
15261
16059
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
15262
16060
|
break;
|
|
15263
16061
|
}
|
|
15264
16062
|
ctx._fc = false;
|
|
15265
16063
|
const v = child(input, itemStart, ctx);
|
|
15266
16064
|
if (v === FAIL) {
|
|
15267
|
-
if (
|
|
16065
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
15268
16066
|
if (committed3(ctx)) return FAIL;
|
|
15269
16067
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
15270
16068
|
break;
|
|
15271
16069
|
}
|
|
15272
16070
|
if (EC.e === itemStart && viaRepItem) {
|
|
15273
|
-
if (
|
|
16071
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
15274
16072
|
break;
|
|
15275
16073
|
}
|
|
15276
16074
|
if (out !== void 0) out.push(v);
|
|
@@ -15344,7 +16142,14 @@ function assemble(t, prog, cfg) {
|
|
|
15344
16142
|
const runArm = n === 0 ? void 0 : bindArms(0);
|
|
15345
16143
|
const runOther = other === void 0 ? void 0 : dispatchBranch(other, otherRouted);
|
|
15346
16144
|
return (input, pos, ctx) => {
|
|
15347
|
-
const
|
|
16145
|
+
const need = markCst(ctx);
|
|
16146
|
+
const mRaw = MRAW;
|
|
16147
|
+
const mTl = MTL;
|
|
16148
|
+
const mLv = MLV;
|
|
16149
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
16150
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
16151
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
16152
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
15348
16153
|
const selVal = selector(input, pos, ctx);
|
|
15349
16154
|
if (selVal === FAIL) return FAIL;
|
|
15350
16155
|
const selEnd = EC.e;
|
|
@@ -15356,9 +16161,9 @@ function assemble(t, prog, cfg) {
|
|
|
15356
16161
|
ctx._fx = expected;
|
|
15357
16162
|
return FAIL;
|
|
15358
16163
|
}
|
|
15359
|
-
return runOther(input, pos, selEnd, key,
|
|
16164
|
+
return runOther(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
15360
16165
|
}
|
|
15361
|
-
return runArm(arm, input, pos, selEnd, key,
|
|
16166
|
+
return runArm(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
15362
16167
|
};
|
|
15363
16168
|
}
|
|
15364
16169
|
/* ── node ────────────────────────────────────────────────────────────── */
|
|
@@ -15394,7 +16199,8 @@ function assemble(t, prog, cfg) {
|
|
|
15394
16199
|
return nd;
|
|
15395
16200
|
};
|
|
15396
16201
|
}
|
|
15397
|
-
const child = link(code[ip + 2]);
|
|
16202
|
+
const child = NODE_BODY ?? link(code[ip + 2]);
|
|
16203
|
+
NODE_BODY = void 0;
|
|
15398
16204
|
const proj = code[ip + 4];
|
|
15399
16205
|
const buildIdx = code[ip + 1];
|
|
15400
16206
|
const type = k[code[ip + 5]];
|
|
@@ -15418,6 +16224,30 @@ function assemble(t, prog, cfg) {
|
|
|
15418
16224
|
if (build !== void 0 && proj < 0 && flags === 18) {
|
|
15419
16225
|
return childrenOnlyFieldsBuildNode(child, build);
|
|
15420
16226
|
}
|
|
16227
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
16228
|
+
return passCollapseNode(child, build, flags === 32);
|
|
16229
|
+
}
|
|
16230
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
16231
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(closureLabels.at(code[ip + 2]).tri, trivia2);
|
|
16232
|
+
if (build !== void 0 && gated !== void 0 && triviaLead !== void 0) {
|
|
16233
|
+
const classic = flags === 32 ? collapseBuildNode(child, build) : childrenOnlyCollapseBuildNode(child, build);
|
|
16234
|
+
return gatedPassCollapseNode(
|
|
16235
|
+
[
|
|
16236
|
+
...gated.leads.map((g) => cc[code[g + 1]]),
|
|
16237
|
+
resolveClass(encodeClassSpec([
|
|
16238
|
+
...triviaLead,
|
|
16239
|
+
...gated.lits.map((i) => {
|
|
16240
|
+
const c = k[i].codePointAt(0);
|
|
16241
|
+
return { lo: c, hi: c };
|
|
16242
|
+
})
|
|
16243
|
+
]))
|
|
16244
|
+
],
|
|
16245
|
+
link(gated.last),
|
|
16246
|
+
classic,
|
|
16247
|
+
build,
|
|
16248
|
+
flags === 32
|
|
16249
|
+
);
|
|
16250
|
+
}
|
|
15421
16251
|
if (build !== void 0 && proj < 0 && flags === 32) {
|
|
15422
16252
|
return collapseBuildNode(child, build);
|
|
15423
16253
|
}
|
|
@@ -15566,6 +16396,8 @@ function assemble(t, prog, cfg) {
|
|
|
15566
16396
|
}
|
|
15567
16397
|
const notChild = scalarTerminalNotChild(code, ip);
|
|
15568
16398
|
if (notChild >= 0) scalarFor(notChild);
|
|
16399
|
+
const peekChild = scalarTerminalPeekChild(code, ip);
|
|
16400
|
+
if (peekChild >= 0) scalarFor(peekChild);
|
|
15569
16401
|
}
|
|
15570
16402
|
const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
|
|
15571
16403
|
if (pre !== void 0) {
|
|
@@ -15625,7 +16457,8 @@ function assemble(t, prog, cfg) {
|
|
|
15625
16457
|
t.lexPrograms,
|
|
15626
16458
|
LEAD,
|
|
15627
16459
|
triviaFieldCapture,
|
|
15628
|
-
skipDeferredTrivia
|
|
16460
|
+
skipDeferredTrivia,
|
|
16461
|
+
collapseEmpty
|
|
15629
16462
|
);
|
|
15630
16463
|
emitReached = new Set(pre.reached);
|
|
15631
16464
|
if (emitted.ext !== void 0) HYBRID = emitted;
|
|
@@ -15711,7 +16544,8 @@ function assemble(t, prog, cfg) {
|
|
|
15711
16544
|
t.lexPrograms,
|
|
15712
16545
|
LEAD,
|
|
15713
16546
|
triviaFieldCapture,
|
|
15714
|
-
skipDeferredTrivia
|
|
16547
|
+
skipDeferredTrivia,
|
|
16548
|
+
collapseEmpty
|
|
15715
16549
|
);
|
|
15716
16550
|
emitReached = em.reached;
|
|
15717
16551
|
} catch (e) {
|
|
@@ -15978,7 +16812,7 @@ function emitClassPool(classes) {
|
|
|
15978
16812
|
if (classes.length < 2) return array;
|
|
15979
16813
|
const delimiter = "|/~?^`".split("").find((ch2) => classes.every((spec) => !spec.includes(ch2)));
|
|
15980
16814
|
if (delimiter === void 0) return array;
|
|
15981
|
-
const split =
|
|
16815
|
+
const split = `/* @__PURE__ */ ${jsString(classes.join(delimiter))}.split(${jsString(delimiter)})`;
|
|
15982
16816
|
return split.length < array.length ? split : array;
|
|
15983
16817
|
}
|
|
15984
16818
|
function emitConst(v) {
|
|
@@ -17761,15 +18595,20 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
17761
18595
|
throw e;
|
|
17762
18596
|
}
|
|
17763
18597
|
const ceiling = budget / SUPERCOMPILE_GROWTH;
|
|
18598
|
+
if (ceiling <= fixed) return none;
|
|
17764
18599
|
let target = ceiling;
|
|
17765
|
-
for (
|
|
18600
|
+
for (; ; ) {
|
|
17766
18601
|
const sites = selectHotSites(artifact.code, Object.values(artifact.rules), siteBytes, target - fixed, profile);
|
|
17767
|
-
if (sites.size === 0)
|
|
18602
|
+
if (sites.size === 0) {
|
|
18603
|
+
return {
|
|
18604
|
+
...none,
|
|
18605
|
+
refusal: `a site within its ${Math.floor(ceiling)} B selection ceiling (the prelude alone is ${fixed} B)`
|
|
18606
|
+
};
|
|
18607
|
+
}
|
|
17768
18608
|
const bytes2 = emitAssemblySource(table, artifact, cfg, roots, true, sites).source.length;
|
|
17769
18609
|
if (bytes2 <= ceiling) return { sites, bytes: Math.ceil(bytes2 * SUPERCOMPILE_GROWTH) };
|
|
17770
18610
|
target *= Math.min(ceiling / bytes2, 0.99);
|
|
17771
18611
|
}
|
|
17772
|
-
return none;
|
|
17773
18612
|
};
|
|
17774
18613
|
return {
|
|
17775
18614
|
keys: ruleMap.map(([key]) => key),
|
|
@@ -17857,16 +18696,16 @@ function ownSource(fn) {
|
|
|
17857
18696
|
return typeof name === "string" && name.length > 0 && globalThis[name] === fn ? name : null;
|
|
17858
18697
|
}
|
|
17859
18698
|
function compile(target, second, third) {
|
|
17860
|
-
if (!
|
|
18699
|
+
if (!isCombinator2(target)) return compileMap(target, second);
|
|
17861
18700
|
return compileRoot(target, second, third);
|
|
17862
18701
|
}
|
|
17863
|
-
function
|
|
18702
|
+
function isCombinator2(x) {
|
|
17864
18703
|
return typeof x === "object" && x !== null && typeof x.parse === "function" && "_def" in x;
|
|
17865
18704
|
}
|
|
17866
18705
|
function compileMap(grammar, opts = {}) {
|
|
17867
18706
|
const entries = [];
|
|
17868
18707
|
for (const [key, value] of Object.entries(grammar)) {
|
|
17869
|
-
if (!
|
|
18708
|
+
if (!isCombinator2(value)) throw new TypeError(`compile: grammar entry "${key}" is not a parser`);
|
|
17870
18709
|
if (value._def.tag === "lazy") {
|
|
17871
18710
|
try {
|
|
17872
18711
|
value._def.thunk();
|
|
@@ -18408,7 +19247,7 @@ function fieldOptionsSrc(def) {
|
|
|
18408
19247
|
}
|
|
18409
19248
|
|
|
18410
19249
|
// src/version.ts
|
|
18411
|
-
var PARSEMAN_VERSION = "0.
|
|
19250
|
+
var PARSEMAN_VERSION = "0.58.0";
|
|
18412
19251
|
|
|
18413
19252
|
// src/compiler/compile-linkable-table.ts
|
|
18414
19253
|
function isLocal(rule) {
|
|
@@ -18677,7 +19516,7 @@ function analyzeGrammarGating(grammar, opts) {
|
|
|
18677
19516
|
}
|
|
18678
19517
|
|
|
18679
19518
|
// src/analysis/diagnose.ts
|
|
18680
|
-
var
|
|
19519
|
+
var isCombinator3 = (g) => typeof g === "object" && g !== null && "_def" in g;
|
|
18681
19520
|
var isRuleEntries = (g) => Array.isArray(g);
|
|
18682
19521
|
function diagnoseGrammar(grammar, opts) {
|
|
18683
19522
|
const depth = degradationCaptureDepth();
|
|
@@ -18721,7 +19560,7 @@ function formatGrammarDiagnosis(d) {
|
|
|
18721
19560
|
return lines2;
|
|
18722
19561
|
}
|
|
18723
19562
|
function runAnalysis(grammar, opts) {
|
|
18724
|
-
if (
|
|
19563
|
+
if (isCombinator3(grammar)) return analyzeGating(grammar, opts);
|
|
18725
19564
|
if (isRuleEntries(grammar)) return analyzeGatingRules(grammar, opts);
|
|
18726
19565
|
return analyzeGrammarGating(grammar, opts);
|
|
18727
19566
|
}
|
|
@@ -21028,13 +21867,13 @@ function buildTriviaIndex(root, input = "", opts) {
|
|
|
21028
21867
|
}
|
|
21029
21868
|
|
|
21030
21869
|
// src/cst/walk.ts
|
|
21031
|
-
function
|
|
21870
|
+
function isCombinator4(value) {
|
|
21032
21871
|
return !!value && typeof value === "object" && "_def" in value && "_meta" in value && typeof value.parse === "function";
|
|
21033
21872
|
}
|
|
21034
21873
|
function reflectionFor(grammar) {
|
|
21035
21874
|
const stamped = grammarReflectionOf(grammar);
|
|
21036
21875
|
if (stamped) return stamped;
|
|
21037
|
-
const entries = Object.entries(grammar).filter((entry) =>
|
|
21876
|
+
const entries = Object.entries(grammar).filter((entry) => isCombinator4(entry[1]));
|
|
21038
21877
|
return collectGrammarReflection(entries);
|
|
21039
21878
|
}
|
|
21040
21879
|
function createVisitor(grammar, spec) {
|