parseman 0.56.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 +2232 -1088
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +2247 -1103
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/combinators/node.d.ts +1 -1
- package/dist/compiler/build-arity.d.ts +1 -1
- package/dist/compiler/build-arity.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/cst/trivia-kinds.d.ts +9 -1
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/index.js +1446 -236
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +1 -0
- package/dist/language-service/index.js.map +1 -1
- package/dist/parse-context.d.ts.map +1 -1
- package/dist/plugin/entry-supercompiler.d.ts +1 -1
- package/dist/plugin/entry-supercompiler.d.ts.map +1 -1
- package/dist/plugin/index.d.ts +51 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +2126 -380
- package/dist/plugin/index.js.map +3 -3
- package/dist/plugin/ir-eval.d.ts +2 -0
- package/dist/plugin/ir-eval.d.ts.map +1 -1
- package/dist/regex/classes.d.ts.map +1 -1
- package/dist/run/index.js +1 -0
- package/dist/run/index.js.map +1 -1
- package/dist/table/assemble.d.ts +9 -0
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/child-slots.d.ts +4 -6
- package/dist/table/child-slots.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +14 -2
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +17 -2
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts +5 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec-baseline.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 +1798 -316
- 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 +17 -6
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +13 -0
- package/dist/table/program.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/select-hot.d.ts +6 -0
- package/dist/table/select-hot.d.ts.map +1 -0
- package/dist/table/site-labels.d.ts +66 -0
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/table/trivia-gap.d.ts +31 -0
- package/dist/table/trivia-gap.d.ts.map +1 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +4 -1
- package/src/combinators/dispatch.ts +12 -3
- package/src/combinators/node.ts +6 -13
- package/src/combinators/trivia-skip.ts +44 -1
- package/src/compiler/build-arity.ts +3 -3
- package/src/compiler/token-alphabet.ts +57 -17
- package/src/cst/capture-buffer.ts +25 -0
- package/src/cst/trivia-kinds.ts +12 -1
- package/src/parse-context.ts +1 -0
- package/src/plugin/entry-supercompiler.ts +8 -9
- package/src/plugin/index.ts +362 -42
- package/src/plugin/ir-eval.ts +7 -1
- package/src/regex/classes.ts +3 -0
- package/src/table/assemble.ts +371 -83
- package/src/table/child-slots.ts +6 -8
- package/src/table/compile-rule-map.ts +64 -15
- package/src/table/emit-assembly.ts +244 -42
- package/src/table/emit.ts +11 -8
- package/src/table/encode.ts +149 -35
- package/src/table/exec-baseline.ts +1 -3
- package/src/table/exec.ts +34 -14
- 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 +18 -7
- package/src/table/program.ts +24 -0
- package/src/table/run-support.ts +35 -0
- package/src/table/scalar-terminal.ts +8 -0
- package/src/table/select-hot.ts +70 -0
- package/src/table/site-labels.ts +135 -4
- package/src/table/trivia-gap.ts +109 -0
- package/src/types.ts +18 -0
- package/src/version.ts +1 -1
package/dist/table/index.js
CHANGED
|
@@ -329,6 +329,7 @@ function createParseContext() {
|
|
|
329
329
|
_rootTriviaKindIndex: void 0,
|
|
330
330
|
_rootTriviaStrictScopes: void 0,
|
|
331
331
|
_rootTriviaCapture: void 0,
|
|
332
|
+
_gap: void 0,
|
|
332
333
|
_cstTriviaLog: void 0,
|
|
333
334
|
_fields: void 0,
|
|
334
335
|
_cstBuf: void 0,
|
|
@@ -348,6 +349,9 @@ function createDetachedParseContext(trackLines, state) {
|
|
|
348
349
|
}
|
|
349
350
|
|
|
350
351
|
// src/line-index.ts
|
|
352
|
+
function createLineIndex() {
|
|
353
|
+
return { lineStarts: [0] };
|
|
354
|
+
}
|
|
351
355
|
function recordLineRange(index, input, start, end) {
|
|
352
356
|
const lineStarts = index.lineStarts;
|
|
353
357
|
for (let i = start; i < end; i++) {
|
|
@@ -363,6 +367,18 @@ function recordLineRangeFromContext(ctx, input, _startHint, end) {
|
|
|
363
367
|
recordLineRange(index, input, from, end);
|
|
364
368
|
ctx._lineScannedTo = end;
|
|
365
369
|
}
|
|
370
|
+
function normalizeLineIndex(index) {
|
|
371
|
+
const starts = index.lineStarts;
|
|
372
|
+
starts.sort((a, b) => a - b);
|
|
373
|
+
let write = 0;
|
|
374
|
+
for (let read = 0; read < starts.length; read++) {
|
|
375
|
+
const value = starts[read];
|
|
376
|
+
if (write === 0 || starts[write - 1] !== value) starts[write++] = value;
|
|
377
|
+
}
|
|
378
|
+
starts.length = write;
|
|
379
|
+
if (starts.length === 0 || starts[0] !== 0) starts.unshift(0);
|
|
380
|
+
return index;
|
|
381
|
+
}
|
|
366
382
|
function offsetToLineCol(index, offset) {
|
|
367
383
|
const { lineStarts } = index;
|
|
368
384
|
let lo = 0;
|
|
@@ -592,12 +608,12 @@ function rebuildLineScan(s, subtree) {
|
|
|
592
608
|
function cstCaptureActive(ctx) {
|
|
593
609
|
return ctx._cstBuf !== void 0 || ctx._cstLeaves !== void 0;
|
|
594
610
|
}
|
|
595
|
-
function pushCstLeaf(ctx,
|
|
611
|
+
function pushCstLeaf(ctx, leaf2) {
|
|
596
612
|
if (!ctx.trackLines) {
|
|
597
|
-
pushCstChild(ctx,
|
|
613
|
+
pushCstChild(ctx, leaf2, leaf2);
|
|
598
614
|
return;
|
|
599
615
|
}
|
|
600
|
-
const annotated =
|
|
616
|
+
const annotated = leaf2 && typeof leaf2 === "object" && leaf2.span ? { ...leaf2, span: annotateSpanFromLineContext(leaf2.span, ctx) } : leaf2;
|
|
601
617
|
pushCstChild(ctx, annotated, annotated);
|
|
602
618
|
}
|
|
603
619
|
function pushCstChild(ctx, built, rawEntry2) {
|
|
@@ -622,6 +638,31 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
622
638
|
else if (ctx._cstLeaves) ctx._cstLeaves.push(built);
|
|
623
639
|
if (ctx._cstRawChildren) ctx._cstRawChildren.push(rawEntry2);
|
|
624
640
|
}
|
|
641
|
+
function popCstChild(ctx) {
|
|
642
|
+
const b = ctx._cstBuf;
|
|
643
|
+
if (b) {
|
|
644
|
+
const ch2 = b.ch;
|
|
645
|
+
if (b.rawOnly !== true && ch2) {
|
|
646
|
+
ch2.pop();
|
|
647
|
+
if (ch2.length === 1) {
|
|
648
|
+
b.single = ch2[0];
|
|
649
|
+
b.ch = void 0;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
if (b.noRaw === true) b.rawLen = (b.rawLen ?? 1) - 1;
|
|
653
|
+
else if (b.raw) {
|
|
654
|
+
b.raw.pop();
|
|
655
|
+
if (b.raw.length === 1) {
|
|
656
|
+
b.rawSingle = b.raw[0];
|
|
657
|
+
b.raw = void 0;
|
|
658
|
+
}
|
|
659
|
+
} else b.rawSingle = void 0;
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
if (ctx._cstChildren) ctx._cstChildren.pop();
|
|
663
|
+
else if (ctx._cstLeaves) ctx._cstLeaves.pop();
|
|
664
|
+
if (ctx._cstRawChildren) ctx._cstRawChildren.pop();
|
|
665
|
+
}
|
|
625
666
|
function cstRawLen(ctx) {
|
|
626
667
|
const b = ctx._cstBuf;
|
|
627
668
|
if (b) {
|
|
@@ -780,6 +821,7 @@ function literalCodePoints(frag) {
|
|
|
780
821
|
if (ch2 === "\\") {
|
|
781
822
|
const e = frag[i + 1];
|
|
782
823
|
if (e === void 0) return null;
|
|
824
|
+
if (!(e in CLASS_ESCAPES) && /\w/.test(e)) return null;
|
|
783
825
|
out.push(e in CLASS_ESCAPES ? CLASS_ESCAPES[e] : e.codePointAt(0));
|
|
784
826
|
i += 2;
|
|
785
827
|
continue;
|
|
@@ -1326,7 +1368,10 @@ function labeledTriviaSpec(arms, minRepeats) {
|
|
|
1326
1368
|
arms,
|
|
1327
1369
|
minRepeats,
|
|
1328
1370
|
visitor: commonLabeledTriviaVisitor({ arms, minRepeats }),
|
|
1329
|
-
charArms: charArmsFor({ arms, minRepeats })
|
|
1371
|
+
charArms: charArmsFor({ arms, minRepeats }),
|
|
1372
|
+
rootKinds: void 0,
|
|
1373
|
+
rootLeaders: [],
|
|
1374
|
+
rootScan: null
|
|
1330
1375
|
};
|
|
1331
1376
|
}
|
|
1332
1377
|
function matchArmAt(input, pos, arm, state) {
|
|
@@ -1463,6 +1508,15 @@ function triviaKindMaskAt(input, pos, spec, state) {
|
|
|
1463
1508
|
}
|
|
1464
1509
|
return mask;
|
|
1465
1510
|
}
|
|
1511
|
+
function triviaKindMask(labels, keep) {
|
|
1512
|
+
if (!labels) return void 0;
|
|
1513
|
+
let mask = 0;
|
|
1514
|
+
for (const name of keep) {
|
|
1515
|
+
const idx = labels.indexOf(name);
|
|
1516
|
+
if (idx >= 0) mask |= 1 << idx;
|
|
1517
|
+
}
|
|
1518
|
+
return mask;
|
|
1519
|
+
}
|
|
1466
1520
|
|
|
1467
1521
|
// src/recovery/scan.ts
|
|
1468
1522
|
function probeAt(sentinel, input, pos, ctx) {
|
|
@@ -1964,8 +2018,8 @@ function buildFastTriviaScanner(trivia2) {
|
|
|
1964
2018
|
if (arms.some((s) => s === null)) return null;
|
|
1965
2019
|
return loopScanner(arms);
|
|
1966
2020
|
}
|
|
1967
|
-
function triviaRegexSource(
|
|
1968
|
-
const d =
|
|
2021
|
+
function triviaRegexSource(parser2) {
|
|
2022
|
+
const d = parser2._def.tag === "label" ? parser2._def.parser._def : parser2._def;
|
|
1969
2023
|
return d.tag === "regex" && d.flags === "" ? d.source : null;
|
|
1970
2024
|
}
|
|
1971
2025
|
function loopScanner(arms) {
|
|
@@ -1984,11 +2038,53 @@ function loopScanner(arms) {
|
|
|
1984
2038
|
return pos;
|
|
1985
2039
|
};
|
|
1986
2040
|
}
|
|
1987
|
-
function regexTriviaScanner(
|
|
1988
|
-
const d =
|
|
2041
|
+
function regexTriviaScanner(parser2) {
|
|
2042
|
+
const d = parser2._def.tag === "label" ? parser2._def.parser._def : parser2._def;
|
|
1989
2043
|
if (d.tag !== "regex" || d.flags) return null;
|
|
1990
|
-
|
|
1991
|
-
|
|
2044
|
+
return sourceScanner(d.source);
|
|
2045
|
+
}
|
|
2046
|
+
function sourceScanner(source) {
|
|
2047
|
+
return classRunSource(source) ?? altStarSource(source) ?? prefixRunSource(source) ?? delimitedSource(source) ?? sharedPrefixAltSource(source);
|
|
2048
|
+
}
|
|
2049
|
+
function sharedPrefixAltSource(source) {
|
|
2050
|
+
const m = /^((?:\\.|[^\\[\]()*+?|^$.{}])+)\(\?:(.*)\)$/.exec(source);
|
|
2051
|
+
if (!m) return null;
|
|
2052
|
+
const alts = [];
|
|
2053
|
+
const body = m[2];
|
|
2054
|
+
let depth = 0;
|
|
2055
|
+
let start = 0;
|
|
2056
|
+
for (let i = 0; i < body.length; i++) {
|
|
2057
|
+
const c = body[i];
|
|
2058
|
+
if (c === "\\") {
|
|
2059
|
+
i++;
|
|
2060
|
+
continue;
|
|
2061
|
+
}
|
|
2062
|
+
if (c === "[") {
|
|
2063
|
+
while (i < body.length && body[i] !== "]") i += body[i] === "\\" ? 2 : 1;
|
|
2064
|
+
continue;
|
|
2065
|
+
}
|
|
2066
|
+
if (c === "(") depth++;
|
|
2067
|
+
else if (c === ")" && --depth < 0) return null;
|
|
2068
|
+
else if (c === "|" && depth === 0) {
|
|
2069
|
+
alts.push(body.slice(start, i));
|
|
2070
|
+
start = i + 1;
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
if (depth !== 0 || alts.length === 0) return null;
|
|
2074
|
+
alts.push(body.slice(start));
|
|
2075
|
+
const scanners = [];
|
|
2076
|
+
for (const alt of alts) {
|
|
2077
|
+
const scanner = sourceScanner(m[1] + alt);
|
|
2078
|
+
if (scanner === null) return null;
|
|
2079
|
+
scanners.push(scanner);
|
|
2080
|
+
}
|
|
2081
|
+
return (input, cur) => {
|
|
2082
|
+
for (const scanner of scanners) {
|
|
2083
|
+
const end = scanner(input, cur);
|
|
2084
|
+
if (end > cur) return end;
|
|
2085
|
+
}
|
|
2086
|
+
return cur;
|
|
2087
|
+
};
|
|
1992
2088
|
}
|
|
1993
2089
|
function bmpString(cps) {
|
|
1994
2090
|
if (!cps) return null;
|
|
@@ -2251,9 +2347,26 @@ function altStarSource(source) {
|
|
|
2251
2347
|
}
|
|
2252
2348
|
|
|
2253
2349
|
// src/combinators/scalar.ts
|
|
2350
|
+
var SCALAR_TAG = /^(?:literal|regex|keywords|sequence|choice|many|oneOrMore|optional|transform|trivia|grammar|sepBy|lazy)$/;
|
|
2254
2351
|
function scalarOf(combinator) {
|
|
2255
2352
|
return combinator._parseScalar;
|
|
2256
2353
|
}
|
|
2354
|
+
function scalarTree(parser2, seen) {
|
|
2355
|
+
if (seen.has(parser2)) return true;
|
|
2356
|
+
if (parser2._parseScalar === void 0) return false;
|
|
2357
|
+
seen.add(parser2);
|
|
2358
|
+
const def = parser2._def;
|
|
2359
|
+
if (!SCALAR_TAG.test(def.tag)) return false;
|
|
2360
|
+
if ("parsers" in def && !def.parsers.every((child) => scalarTree(child, seen))) return false;
|
|
2361
|
+
if ("parser" in def && !scalarTree(def.parser, seen)) return false;
|
|
2362
|
+
if ("separator" in def && !scalarTree(def.separator, seen)) return false;
|
|
2363
|
+
return def.tag !== "lazy" || scalarTree(def.thunk(), seen);
|
|
2364
|
+
}
|
|
2365
|
+
function scalarRootOf(combinator) {
|
|
2366
|
+
const scalar = combinator._parseScalar;
|
|
2367
|
+
const def = combinator._def;
|
|
2368
|
+
return scalar !== void 0 && def.tag === "grammar" && scalarTree(def.parser, /* @__PURE__ */ new Set()) ? scalar : void 0;
|
|
2369
|
+
}
|
|
2257
2370
|
|
|
2258
2371
|
// src/combinators/choice.ts
|
|
2259
2372
|
function choice(...args) {
|
|
@@ -2401,7 +2514,7 @@ function choice(...args) {
|
|
|
2401
2514
|
return result;
|
|
2402
2515
|
}
|
|
2403
2516
|
if (expected.length === 0) {
|
|
2404
|
-
for (const
|
|
2517
|
+
for (const parser2 of parsers) expected.push(...deriveExpected(parser2));
|
|
2405
2518
|
}
|
|
2406
2519
|
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
2407
2520
|
}
|
|
@@ -3292,17 +3405,59 @@ function buildLexBodyRecognizer(spec, constants) {
|
|
|
3292
3405
|
};
|
|
3293
3406
|
}
|
|
3294
3407
|
|
|
3408
|
+
// src/table/run-support.ts
|
|
3409
|
+
function lineCol(ctx, offset) {
|
|
3410
|
+
const starts = ctx._lineStarts ?? [0];
|
|
3411
|
+
let lo = 0, hi = starts.length - 1;
|
|
3412
|
+
while (lo < hi) {
|
|
3413
|
+
const mid = lo + hi + 1 >> 1;
|
|
3414
|
+
if (starts[mid] <= offset) lo = mid;
|
|
3415
|
+
else hi = mid - 1;
|
|
3416
|
+
}
|
|
3417
|
+
return [lo + 1, offset - starts[lo] + 1];
|
|
3418
|
+
}
|
|
3419
|
+
function spanLines(ctx, start, end) {
|
|
3420
|
+
const s = lineCol(ctx, start), e = lineCol(ctx, end);
|
|
3421
|
+
return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] };
|
|
3422
|
+
}
|
|
3423
|
+
function rawEntry(v, input, s, e) {
|
|
3424
|
+
if (typeof v === "object" && v !== null) {
|
|
3425
|
+
const tg = v._tag;
|
|
3426
|
+
if (tg === "node" || tg === "leaf" || tg === "parseError") return v;
|
|
3427
|
+
}
|
|
3428
|
+
return {
|
|
3429
|
+
_tag: "leaf",
|
|
3430
|
+
value: typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "",
|
|
3431
|
+
span: { start: s, end: e }
|
|
3432
|
+
};
|
|
3433
|
+
}
|
|
3434
|
+
function lead(input, pos) {
|
|
3435
|
+
if (pos >= input.length) return -1;
|
|
3436
|
+
const c = input.charCodeAt(pos);
|
|
3437
|
+
if (c < 55296 || c > 56319) return c;
|
|
3438
|
+
return input.codePointAt(pos) ?? c;
|
|
3439
|
+
}
|
|
3440
|
+
var EMPTY_KIDS = Object.freeze([]);
|
|
3441
|
+
var EMPTY_TRIVIA = Object.freeze([]);
|
|
3442
|
+
function collapseEmpty(ctx, build, input, pos, end, readsRaw) {
|
|
3443
|
+
const collected = ctx._cstBuf !== void 0 || ctx._cstChildren !== void 0;
|
|
3444
|
+
if (collected) popCstChild(ctx);
|
|
3445
|
+
const raw = readsRaw ? [rawEntry(void 0, input, pos, end)] : EMPTY_KIDS;
|
|
3446
|
+
const nd = build(EMPTY_KIDS, void 0, { start: pos, end }, raw, EMPTY_TRIVIA, void 0);
|
|
3447
|
+
if (collected) pushCstChild(ctx, nd, ctx._cstBuf?.noRaw === true ? void 0 : rawEntry(nd, input, pos, end));
|
|
3448
|
+
return nd;
|
|
3449
|
+
}
|
|
3450
|
+
|
|
3295
3451
|
// src/table/lex-program.ts
|
|
3296
3452
|
var LEX_NODE_TERMINAL = 0;
|
|
3297
3453
|
var LEX_NODE_SEQUENCE2 = 1;
|
|
3298
3454
|
var LEX_NODE_SEQUENCE3 = 2;
|
|
3299
3455
|
var LEX_NODE_SEQUENCE4 = 3;
|
|
3300
3456
|
var LEX_NODE_SEQUENCE5 = 4;
|
|
3301
|
-
var
|
|
3302
|
-
var LEX_NODE_CHOICE4 = 6;
|
|
3303
|
-
var LEX_NODE_CHOICE8 = 7;
|
|
3457
|
+
var LEX_NODE_CHOICE = 5;
|
|
3304
3458
|
var LEX_NODE_NOT = 8;
|
|
3305
3459
|
var LEX_NODE_OPTIONAL = 9;
|
|
3460
|
+
var LEX_NODE_REPEAT = 10;
|
|
3306
3461
|
function lexProgramDigest(words) {
|
|
3307
3462
|
let hash = 2166136261;
|
|
3308
3463
|
for (const word of words) {
|
|
@@ -3331,85 +3486,114 @@ function trackLexLines(ctx, input, end) {
|
|
|
3331
3486
|
ctx._lineScannedTo = end;
|
|
3332
3487
|
}
|
|
3333
3488
|
function terminalNode(matcher, failure, tracksLines) {
|
|
3334
|
-
const match = (input, pos) => {
|
|
3335
|
-
const result = matcher(input, pos);
|
|
3336
|
-
return result < 0 ? -1 : result / 2;
|
|
3337
|
-
};
|
|
3338
3489
|
return {
|
|
3339
|
-
match,
|
|
3490
|
+
match: (input, pos) => {
|
|
3491
|
+
const result = matcher(input, pos);
|
|
3492
|
+
return result < 0 ? -1 : result / 2;
|
|
3493
|
+
},
|
|
3340
3494
|
run: (input, pos, ctx) => {
|
|
3341
|
-
const
|
|
3342
|
-
if (
|
|
3495
|
+
const result = matcher(input, pos);
|
|
3496
|
+
if (result < 0) {
|
|
3343
3497
|
ctx._fe = pos;
|
|
3344
3498
|
ctx._fx = failure;
|
|
3345
3499
|
if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
|
|
3346
3500
|
return -1;
|
|
3347
3501
|
}
|
|
3502
|
+
const end = result / 2;
|
|
3348
3503
|
if (tracksLines) trackLexLines(ctx, input, end);
|
|
3349
3504
|
return end;
|
|
3350
3505
|
}
|
|
3351
3506
|
};
|
|
3352
3507
|
}
|
|
3353
3508
|
function sequence2(a, b) {
|
|
3509
|
+
const am = a.match, bm = b.match, ar = a.run, br = b.run;
|
|
3354
3510
|
return {
|
|
3355
3511
|
match: (input, pos) => {
|
|
3356
|
-
const e0 =
|
|
3357
|
-
return e0 < 0 ? -1 :
|
|
3512
|
+
const e0 = am(input, pos);
|
|
3513
|
+
return e0 < 0 ? -1 : bm(input, e0);
|
|
3358
3514
|
},
|
|
3359
3515
|
run: (input, pos, ctx) => {
|
|
3360
|
-
const e0 =
|
|
3516
|
+
const e0 = ar(input, pos, ctx);
|
|
3361
3517
|
if (e0 < 0) return -1;
|
|
3362
3518
|
ctx._fc = false;
|
|
3363
|
-
return
|
|
3519
|
+
return br(input, e0, ctx);
|
|
3364
3520
|
}
|
|
3365
3521
|
};
|
|
3366
3522
|
}
|
|
3367
3523
|
function sequence3(a, b, c) {
|
|
3524
|
+
const am = a.match, bm = b.match, cm = c.match, ar = a.run, br = b.run, cr = c.run;
|
|
3368
3525
|
return {
|
|
3369
3526
|
match: (input, pos) => {
|
|
3370
|
-
const e0 =
|
|
3527
|
+
const e0 = am(input, pos);
|
|
3371
3528
|
if (e0 < 0) return -1;
|
|
3372
|
-
const e1 =
|
|
3373
|
-
return e1 < 0 ? -1 :
|
|
3529
|
+
const e1 = bm(input, e0);
|
|
3530
|
+
return e1 < 0 ? -1 : cm(input, e1);
|
|
3374
3531
|
},
|
|
3375
3532
|
run: (input, pos, ctx) => {
|
|
3376
|
-
const e0 =
|
|
3533
|
+
const e0 = ar(input, pos, ctx);
|
|
3377
3534
|
if (e0 < 0) return -1;
|
|
3378
3535
|
ctx._fc = false;
|
|
3379
|
-
const e1 =
|
|
3536
|
+
const e1 = br(input, e0, ctx);
|
|
3380
3537
|
if (e1 < 0) return -1;
|
|
3381
3538
|
ctx._fc = false;
|
|
3382
|
-
return
|
|
3539
|
+
return cr(input, e1, ctx);
|
|
3383
3540
|
}
|
|
3384
3541
|
};
|
|
3385
3542
|
}
|
|
3386
3543
|
function sequence4(a, b, c, d) {
|
|
3387
|
-
const
|
|
3544
|
+
const am = a.match, bm = b.match, cm = c.match, dm = d.match;
|
|
3545
|
+
const ar = a.run, br = b.run, cr = c.run, dr = d.run;
|
|
3388
3546
|
return {
|
|
3389
3547
|
match: (input, pos) => {
|
|
3390
|
-
const
|
|
3391
|
-
|
|
3548
|
+
const e0 = am(input, pos);
|
|
3549
|
+
if (e0 < 0) return -1;
|
|
3550
|
+
const e1 = bm(input, e0);
|
|
3551
|
+
if (e1 < 0) return -1;
|
|
3552
|
+
const e2 = cm(input, e1);
|
|
3553
|
+
return e2 < 0 ? -1 : dm(input, e2);
|
|
3392
3554
|
},
|
|
3393
3555
|
run: (input, pos, ctx) => {
|
|
3394
|
-
const
|
|
3395
|
-
if (
|
|
3556
|
+
const e0 = ar(input, pos, ctx);
|
|
3557
|
+
if (e0 < 0) return -1;
|
|
3558
|
+
ctx._fc = false;
|
|
3559
|
+
const e1 = br(input, e0, ctx);
|
|
3560
|
+
if (e1 < 0) return -1;
|
|
3561
|
+
ctx._fc = false;
|
|
3562
|
+
const e2 = cr(input, e1, ctx);
|
|
3563
|
+
if (e2 < 0) return -1;
|
|
3396
3564
|
ctx._fc = false;
|
|
3397
|
-
return
|
|
3565
|
+
return dr(input, e2, ctx);
|
|
3398
3566
|
}
|
|
3399
3567
|
};
|
|
3400
3568
|
}
|
|
3401
3569
|
function sequence5(a, b, c, d, e) {
|
|
3402
|
-
const
|
|
3570
|
+
const am = a.match, bm = b.match, cm = c.match, dm = d.match, em = e.match;
|
|
3571
|
+
const ar = a.run, br = b.run, cr = c.run, dr = d.run, er = e.run;
|
|
3403
3572
|
return {
|
|
3404
3573
|
match: (input, pos) => {
|
|
3405
|
-
const
|
|
3406
|
-
|
|
3574
|
+
const e0 = am(input, pos);
|
|
3575
|
+
if (e0 < 0) return -1;
|
|
3576
|
+
const e1 = bm(input, e0);
|
|
3577
|
+
if (e1 < 0) return -1;
|
|
3578
|
+
const e2 = cm(input, e1);
|
|
3579
|
+
if (e2 < 0) return -1;
|
|
3580
|
+
const e3 = dm(input, e2);
|
|
3581
|
+
return e3 < 0 ? -1 : em(input, e3);
|
|
3407
3582
|
},
|
|
3408
3583
|
run: (input, pos, ctx) => {
|
|
3409
|
-
const
|
|
3410
|
-
if (
|
|
3584
|
+
const e0 = ar(input, pos, ctx);
|
|
3585
|
+
if (e0 < 0) return -1;
|
|
3586
|
+
ctx._fc = false;
|
|
3587
|
+
const e1 = br(input, e0, ctx);
|
|
3588
|
+
if (e1 < 0) return -1;
|
|
3411
3589
|
ctx._fc = false;
|
|
3412
|
-
|
|
3590
|
+
const e2 = cr(input, e1, ctx);
|
|
3591
|
+
if (e2 < 0) return -1;
|
|
3592
|
+
ctx._fc = false;
|
|
3593
|
+
const e3 = dr(input, e2, ctx);
|
|
3594
|
+
if (e3 < 0) return -1;
|
|
3595
|
+
ctx._fc = false;
|
|
3596
|
+
return er(input, e3, ctx);
|
|
3413
3597
|
}
|
|
3414
3598
|
};
|
|
3415
3599
|
}
|
|
@@ -3422,9 +3606,9 @@ function appendExpected(acc, values) {
|
|
|
3422
3606
|
function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
3423
3607
|
let matchTail = () => -1;
|
|
3424
3608
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
3425
|
-
const
|
|
3609
|
+
const armMatch = arms[i].match, next = matchTail;
|
|
3426
3610
|
matchTail = (input, pos) => {
|
|
3427
|
-
const end =
|
|
3611
|
+
const end = armMatch(input, pos);
|
|
3428
3612
|
return end < 0 ? next(input, pos) : end;
|
|
3429
3613
|
};
|
|
3430
3614
|
}
|
|
@@ -3434,7 +3618,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
3434
3618
|
return -1;
|
|
3435
3619
|
};
|
|
3436
3620
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
3437
|
-
const
|
|
3621
|
+
const armRun = arms[i].run, cls = classes[i], staticExpected = armExpected[i], next = tail;
|
|
3438
3622
|
tail = (input, pos, ctx, lead2, acc, best) => {
|
|
3439
3623
|
if (cls !== void 0 && !classHas(cls, lead2)) {
|
|
3440
3624
|
return next(
|
|
@@ -3447,7 +3631,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
3447
3631
|
);
|
|
3448
3632
|
}
|
|
3449
3633
|
ctx._fc = false;
|
|
3450
|
-
const end =
|
|
3634
|
+
const end = armRun(input, pos, ctx);
|
|
3451
3635
|
if (end >= 0) return end;
|
|
3452
3636
|
const at = ctx._fe ?? pos;
|
|
3453
3637
|
if (at > best) {
|
|
@@ -3474,11 +3658,58 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
3474
3658
|
)
|
|
3475
3659
|
};
|
|
3476
3660
|
}
|
|
3661
|
+
function exclusiveChoiceNode(arms, classes, choiceFx) {
|
|
3662
|
+
const ascii = (classes.length <= 128 ? new Int8Array(128) : new Int32Array(128)).fill(-1);
|
|
3663
|
+
const hi = [];
|
|
3664
|
+
for (let i = 0; i < classes.length; i++) {
|
|
3665
|
+
const cls = classes[i];
|
|
3666
|
+
for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) ascii[c] = i;
|
|
3667
|
+
for (let r = 0; r < cls.hi.length; r += 2) hi.push(cls.hi[r], cls.hi[r + 1], i);
|
|
3668
|
+
}
|
|
3669
|
+
const select = (code) => {
|
|
3670
|
+
if (code < 0) return -1;
|
|
3671
|
+
if (code < 128) return ascii[code];
|
|
3672
|
+
for (let r = 0; r < hi.length; r += 3) if (code >= hi[r] && code <= hi[r + 1]) return hi[r + 2];
|
|
3673
|
+
return -1;
|
|
3674
|
+
};
|
|
3675
|
+
let matchArm = () => -1;
|
|
3676
|
+
let selectRun = () => -1;
|
|
3677
|
+
for (let i = arms.length - 1; i >= 0; i--) {
|
|
3678
|
+
const armMatch = arms[i].match, armRun = arms[i].run, nextMatch = matchArm, nextRun = selectRun;
|
|
3679
|
+
matchArm = (selected, input, pos) => selected === i ? armMatch(input, pos) : nextMatch(selected, input, pos);
|
|
3680
|
+
selectRun = (selected, input, pos, ctx) => selected === i ? armRun(input, pos, ctx) : nextRun(selected, input, pos, ctx);
|
|
3681
|
+
}
|
|
3682
|
+
const runArm = (input, pos, ctx) => {
|
|
3683
|
+
const arm = select(lead(input, pos));
|
|
3684
|
+
if (arm >= 0) {
|
|
3685
|
+
ctx._fc = false;
|
|
3686
|
+
const end = selectRun(arm, input, pos, ctx);
|
|
3687
|
+
if (end >= 0) return end;
|
|
3688
|
+
if (committed(ctx)) return -1;
|
|
3689
|
+
const failed = ctx._fx;
|
|
3690
|
+
if (failed !== void 0 && failed.length > 0) {
|
|
3691
|
+
ctx._fe = pos;
|
|
3692
|
+
return -1;
|
|
3693
|
+
}
|
|
3694
|
+
}
|
|
3695
|
+
ctx._fe = pos;
|
|
3696
|
+
ctx._fx = choiceFx;
|
|
3697
|
+
return -1;
|
|
3698
|
+
};
|
|
3699
|
+
return {
|
|
3700
|
+
match: (input, pos) => {
|
|
3701
|
+
const arm = select(lead(input, pos));
|
|
3702
|
+
return arm < 0 ? -1 : matchArm(arm, input, pos);
|
|
3703
|
+
},
|
|
3704
|
+
run: runArm
|
|
3705
|
+
};
|
|
3706
|
+
}
|
|
3477
3707
|
function notNode(body, failure) {
|
|
3708
|
+
const bodyMatch = body.match;
|
|
3478
3709
|
return {
|
|
3479
|
-
match: (input, pos) =>
|
|
3710
|
+
match: (input, pos) => bodyMatch(input, pos) < 0 ? pos : -1,
|
|
3480
3711
|
run: (input, pos, ctx) => {
|
|
3481
|
-
if (
|
|
3712
|
+
if (bodyMatch(input, pos) < 0) return pos;
|
|
3482
3713
|
ctx._fe = pos;
|
|
3483
3714
|
ctx._fx = failure;
|
|
3484
3715
|
return -1;
|
|
@@ -3486,18 +3717,57 @@ function notNode(body, failure) {
|
|
|
3486
3717
|
};
|
|
3487
3718
|
}
|
|
3488
3719
|
function optionalNode(body) {
|
|
3720
|
+
const bodyMatch = body.match, bodyRun = body.run;
|
|
3489
3721
|
return {
|
|
3490
3722
|
match: (input, pos) => {
|
|
3491
|
-
const end =
|
|
3723
|
+
const end = bodyMatch(input, pos);
|
|
3492
3724
|
return end < 0 ? pos : end;
|
|
3493
3725
|
},
|
|
3494
3726
|
run: (input, pos, ctx) => {
|
|
3495
3727
|
ctx._fc = false;
|
|
3496
|
-
const end =
|
|
3728
|
+
const end = bodyRun(input, pos, ctx);
|
|
3497
3729
|
return end < 0 && !committed(ctx) ? pos : end;
|
|
3498
3730
|
}
|
|
3499
3731
|
};
|
|
3500
3732
|
}
|
|
3733
|
+
function repeatNode(item, min, max) {
|
|
3734
|
+
const itemMatch = item.match, itemRun = item.run;
|
|
3735
|
+
return {
|
|
3736
|
+
match: (input, pos) => {
|
|
3737
|
+
let cur = pos;
|
|
3738
|
+
let count = 0;
|
|
3739
|
+
for (; ; ) {
|
|
3740
|
+
if (max >= 0 && count >= max) break;
|
|
3741
|
+
const optional = count >= min && (count > 0 || min === 0);
|
|
3742
|
+
if (optional && cur >= input.length) break;
|
|
3743
|
+
const end = itemMatch(input, cur);
|
|
3744
|
+
if (end < 0 || optional && end === cur) break;
|
|
3745
|
+
cur = end;
|
|
3746
|
+
count++;
|
|
3747
|
+
}
|
|
3748
|
+
return count < min ? -1 : cur;
|
|
3749
|
+
},
|
|
3750
|
+
run: (input, pos, ctx) => {
|
|
3751
|
+
let cur = pos;
|
|
3752
|
+
let count = 0;
|
|
3753
|
+
for (; ; ) {
|
|
3754
|
+
if (max >= 0 && count >= max) break;
|
|
3755
|
+
const optional = count >= min && (count > 0 || min === 0);
|
|
3756
|
+
if (optional && cur >= input.length) break;
|
|
3757
|
+
ctx._fc = false;
|
|
3758
|
+
const end = itemRun(input, cur, ctx);
|
|
3759
|
+
if (end < 0) {
|
|
3760
|
+
if (committed(ctx)) return -1;
|
|
3761
|
+
break;
|
|
3762
|
+
}
|
|
3763
|
+
if (optional && end === cur) break;
|
|
3764
|
+
cur = end;
|
|
3765
|
+
count++;
|
|
3766
|
+
}
|
|
3767
|
+
return count < min ? -1 : cur;
|
|
3768
|
+
}
|
|
3769
|
+
};
|
|
3770
|
+
}
|
|
3501
3771
|
function fixedTreeRunner(words, matchers, classes, expected) {
|
|
3502
3772
|
const stack = [];
|
|
3503
3773
|
const pop = () => {
|
|
@@ -3525,9 +3795,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
3525
3795
|
else stack.push(sequence5(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4]));
|
|
3526
3796
|
continue;
|
|
3527
3797
|
}
|
|
3528
|
-
if (op
|
|
3529
|
-
const count =
|
|
3798
|
+
if (op === LEX_NODE_CHOICE) {
|
|
3799
|
+
const count = words[at++];
|
|
3800
|
+
const exclusive = words[at++];
|
|
3801
|
+
if (exclusive !== 0 && exclusive !== 1) throw new TypeError("table lexical tree choice has an invalid dispatch mode");
|
|
3530
3802
|
const choiceFx = expected[words[at++]];
|
|
3803
|
+
if (!Number.isInteger(count) || count < 2 || count > stack.length) {
|
|
3804
|
+
throw new TypeError("table lexical tree choice has an invalid arm count");
|
|
3805
|
+
}
|
|
3531
3806
|
if (choiceFx === void 0) throw new TypeError("table lexical tree choice has an invalid expected set");
|
|
3532
3807
|
const armClasses = [];
|
|
3533
3808
|
const armFx = [];
|
|
@@ -3540,7 +3815,7 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
3540
3815
|
armFx.push(fx);
|
|
3541
3816
|
}
|
|
3542
3817
|
const arms = Array.from({ length: count }, pop).reverse();
|
|
3543
|
-
stack.push(choiceNode(arms, armClasses, armFx, choiceFx));
|
|
3818
|
+
stack.push(exclusive === 1 ? exclusiveChoiceNode(arms, armClasses, choiceFx) : choiceNode(arms, armClasses, armFx, choiceFx));
|
|
3544
3819
|
continue;
|
|
3545
3820
|
}
|
|
3546
3821
|
if (op === LEX_NODE_NOT) {
|
|
@@ -3553,6 +3828,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
3553
3828
|
stack.push(optionalNode(pop()));
|
|
3554
3829
|
continue;
|
|
3555
3830
|
}
|
|
3831
|
+
if (op === LEX_NODE_REPEAT) {
|
|
3832
|
+
const min = words[at++], max = words[at++];
|
|
3833
|
+
if (!Number.isInteger(min) || min < 0 || !Number.isInteger(max) || max >= 0 && max < min) {
|
|
3834
|
+
throw new TypeError("table lexical tree repeat has invalid bounds");
|
|
3835
|
+
}
|
|
3836
|
+
stack.push(repeatNode(pop(), min, max));
|
|
3837
|
+
continue;
|
|
3838
|
+
}
|
|
3556
3839
|
throw new TypeError("table lexical tree has an unknown fixed body");
|
|
3557
3840
|
}
|
|
3558
3841
|
if (stack.length !== 1) throw new TypeError("table lexical tree does not resolve to one root body");
|
|
@@ -3707,6 +3990,12 @@ function scanRefs(s) {
|
|
|
3707
3990
|
refs.push(...s.skip);
|
|
3708
3991
|
return refs;
|
|
3709
3992
|
}
|
|
3993
|
+
function assemblyExtraIps(prog) {
|
|
3994
|
+
const ips = [];
|
|
3995
|
+
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) ips.push(r[0]);
|
|
3996
|
+
for (const set of prog.scanSkip ?? []) for (const r of set) ips.push(r[0]);
|
|
3997
|
+
return ips;
|
|
3998
|
+
}
|
|
3710
3999
|
function expandCompact(p) {
|
|
3711
4000
|
if ("code" in p) return p;
|
|
3712
4001
|
return ownTableProgram({
|
|
@@ -3837,6 +4126,11 @@ function classHas2(cls, code) {
|
|
|
3837
4126
|
for (let i = 0; i < hi.length; i += 2) if (code >= hi[i] && code <= hi[i + 1]) return true;
|
|
3838
4127
|
return false;
|
|
3839
4128
|
}
|
|
4129
|
+
function dispatchIsExclusive(arms, cc) {
|
|
4130
|
+
const resolved = [];
|
|
4131
|
+
for (const ci of arms) if (ci >= 0) resolved[ci] = resolveClass(cc[ci]);
|
|
4132
|
+
return resolveDispatch(arms, resolved).exclusive;
|
|
4133
|
+
}
|
|
3840
4134
|
function resolveDispatch(arms, cc) {
|
|
3841
4135
|
const ascii = new Uint8Array(128);
|
|
3842
4136
|
const hi = [];
|
|
@@ -4217,7 +4511,7 @@ function sequence(...parsers) {
|
|
|
4217
4511
|
if (tolerant) {
|
|
4218
4512
|
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
4219
4513
|
parsers.slice(i + 1).reduce(
|
|
4220
|
-
(set,
|
|
4514
|
+
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
4221
4515
|
{ kind: "empty" }
|
|
4222
4516
|
)
|
|
4223
4517
|
));
|
|
@@ -4353,13 +4647,13 @@ function ref() {
|
|
|
4353
4647
|
return scalar(input, pos, ctx);
|
|
4354
4648
|
},
|
|
4355
4649
|
parse(input, pos, ctx) {
|
|
4356
|
-
const
|
|
4357
|
-
if (!
|
|
4650
|
+
const parser2 = resolved;
|
|
4651
|
+
if (!parser2) throw new Error("ref<T>() used before .define() was called");
|
|
4358
4652
|
const gt = meta.grammarTrivia;
|
|
4359
4653
|
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
4360
|
-
return withRuleTrivia(gt, ctx, () =>
|
|
4654
|
+
return withRuleTrivia(gt, ctx, () => parser2.parse(input, pos, ctx));
|
|
4361
4655
|
}
|
|
4362
|
-
return
|
|
4656
|
+
return parser2.parse(input, pos, ctx);
|
|
4363
4657
|
},
|
|
4364
4658
|
define(p) {
|
|
4365
4659
|
if (resolved) throw new Error("ref<T>() already defined");
|
|
@@ -4618,7 +4912,7 @@ function confirmedArityForDef(def) {
|
|
|
4618
4912
|
severity: "warn",
|
|
4619
4913
|
where: `node("${def.type ?? "<inferred>"}")`,
|
|
4620
4914
|
subject,
|
|
4621
|
-
fellBackTo: `could not confirm its declared arity \u2014 ${unconfirmableReason(def, src)} \u2014 so this node captures children, fields and raw children, logs trivia, and
|
|
4915
|
+
fellBackTo: `could not confirm its declared arity \u2014 ${unconfirmableReason(def, src)} \u2014 so this node captures children, fields and raw children, logs trivia, and hands it \`_ctx.state\` on every match`,
|
|
4622
4916
|
otherwise: "only the tiers the reducer actually declares would be captured (arity >= 1 children, >= 2 fields, >= 4 raw, >= 5 trivia, >= 6 state). Declare it with `node(..., { buildArity: n })` if it cannot be derived"
|
|
4623
4917
|
});
|
|
4624
4918
|
return null;
|
|
@@ -4644,6 +4938,12 @@ function buildReadsState(def) {
|
|
|
4644
4938
|
}
|
|
4645
4939
|
|
|
4646
4940
|
// src/combinators/token.ts
|
|
4941
|
+
function semanticLeafValue(_ctx, _input, _start, _end, value) {
|
|
4942
|
+
return value;
|
|
4943
|
+
}
|
|
4944
|
+
function sourceLeafValue(ctx, input, start, end, value) {
|
|
4945
|
+
return cstOutputHost(ctx.build) ? input.slice(start, end) : value;
|
|
4946
|
+
}
|
|
4647
4947
|
function token(root) {
|
|
4648
4948
|
const meta = {
|
|
4649
4949
|
firstSet: root._meta.firstSet,
|
|
@@ -4696,6 +4996,64 @@ function token(root) {
|
|
|
4696
4996
|
}
|
|
4697
4997
|
};
|
|
4698
4998
|
}
|
|
4999
|
+
function makeLeaf(root, fn, sourceCstValue) {
|
|
5000
|
+
const cstValue = sourceCstValue ? sourceLeafValue : semanticLeafValue;
|
|
5001
|
+
const meta = {
|
|
5002
|
+
firstSet: root._meta.firstSet,
|
|
5003
|
+
canMatchNewline: root._meta.canMatchNewline,
|
|
5004
|
+
isTrivia: false
|
|
5005
|
+
};
|
|
5006
|
+
return {
|
|
5007
|
+
_tag: "leaf",
|
|
5008
|
+
_meta: meta,
|
|
5009
|
+
_def: {
|
|
5010
|
+
tag: "leaf",
|
|
5011
|
+
parser: root,
|
|
5012
|
+
fn,
|
|
5013
|
+
...sourceCstValue ? { cstValue: "source" } : {}
|
|
5014
|
+
},
|
|
5015
|
+
parse(input, pos, ctx) {
|
|
5016
|
+
const savedBuf = ctx._cstBuf;
|
|
5017
|
+
const savedChildren = ctx._cstChildren;
|
|
5018
|
+
const savedLeaves = ctx._cstLeaves;
|
|
5019
|
+
const savedRaw = ctx._cstRawChildren;
|
|
5020
|
+
const savedTriviaLog = ctx._cstTriviaLog;
|
|
5021
|
+
const savedOuterTriviaLog = ctx._triviaLog;
|
|
5022
|
+
const wasCapturing = cstCaptureActive(ctx);
|
|
5023
|
+
ctx._cstBuf = void 0;
|
|
5024
|
+
ctx._cstChildren = void 0;
|
|
5025
|
+
ctx._cstLeaves = void 0;
|
|
5026
|
+
ctx._cstRawChildren = void 0;
|
|
5027
|
+
ctx._cstTriviaLog = void 0;
|
|
5028
|
+
ctx._triviaLog = void 0;
|
|
5029
|
+
let result;
|
|
5030
|
+
try {
|
|
5031
|
+
result = root.parse(input, pos, ctx);
|
|
5032
|
+
} finally {
|
|
5033
|
+
ctx._cstBuf = savedBuf;
|
|
5034
|
+
ctx._cstChildren = savedChildren;
|
|
5035
|
+
ctx._cstLeaves = savedLeaves;
|
|
5036
|
+
ctx._cstRawChildren = savedRaw;
|
|
5037
|
+
ctx._cstTriviaLog = savedTriviaLog;
|
|
5038
|
+
ctx._triviaLog = savedOuterTriviaLog;
|
|
5039
|
+
}
|
|
5040
|
+
if (!result.ok) return result;
|
|
5041
|
+
const value = fn(result.value, result.span);
|
|
5042
|
+
if (wasCapturing) pushCstLeaf(ctx, {
|
|
5043
|
+
_tag: "leaf",
|
|
5044
|
+
value: cstValue(ctx, input, pos, result.span.end, value),
|
|
5045
|
+
span: result.span
|
|
5046
|
+
});
|
|
5047
|
+
return { ok: true, value, span: result.span };
|
|
5048
|
+
}
|
|
5049
|
+
};
|
|
5050
|
+
}
|
|
5051
|
+
function leaf(root, fn) {
|
|
5052
|
+
return makeLeaf(root, fn, false);
|
|
5053
|
+
}
|
|
5054
|
+
function sourceLeaf(root, fn) {
|
|
5055
|
+
return makeLeaf(root, fn, true);
|
|
5056
|
+
}
|
|
4699
5057
|
|
|
4700
5058
|
// src/combinators/scanTo.ts
|
|
4701
5059
|
function resolveScanSkip(explicitSkip, raw, ctx) {
|
|
@@ -4735,8 +5093,8 @@ function scanTo(sentinel, { skip, raw = false, orEOF = false, recoverAt, stopAt
|
|
|
4735
5093
|
probeCtx._errors = ctx._errors;
|
|
4736
5094
|
const emit = (end) => {
|
|
4737
5095
|
if (end > pos && cstCaptureActive(ctx)) {
|
|
4738
|
-
const
|
|
4739
|
-
pushCstLeaf(ctx,
|
|
5096
|
+
const leaf2 = { _tag: "leaf", value: input.slice(pos, end), span: { start: pos, end } };
|
|
5097
|
+
pushCstLeaf(ctx, leaf2);
|
|
4740
5098
|
}
|
|
4741
5099
|
};
|
|
4742
5100
|
if (recoverAt === void 0 && stopAt === void 0) {
|
|
@@ -5012,11 +5370,75 @@ function buildFieldMap(captures) {
|
|
|
5012
5370
|
return out;
|
|
5013
5371
|
}
|
|
5014
5372
|
|
|
5373
|
+
// src/table/trivia-gap.ts
|
|
5374
|
+
function skipDeferredTrivia(input, cur, ctx) {
|
|
5375
|
+
const triviaP = ctx.trivia;
|
|
5376
|
+
const plain = ctx.trackLines !== true && ctx.captureTrivia !== true;
|
|
5377
|
+
const gap = ctx._gap;
|
|
5378
|
+
if (plain && gap !== void 0 && cur === gap.at && input === gap.input && triviaP === gap.of && ctx._rootTriviaCapture === gap.root && ctx.state === gap.state && ctx._rootTriviaKindIndex === gap.rootKinds && ctx._triviaLog === gap.log) return gap.end;
|
|
5379
|
+
const end = clearRunEnd(input, cur, ctx, triviaP, plain);
|
|
5380
|
+
if (end >= 0) {
|
|
5381
|
+
remember(cur, end, ctx, input, triviaP);
|
|
5382
|
+
return end;
|
|
5383
|
+
}
|
|
5384
|
+
const scan = scanTriviaCompact(input, cur, ctx);
|
|
5385
|
+
if (typeof scan !== "number") return commitTriviaScan(scan);
|
|
5386
|
+
if (plain) remember(cur, scan, ctx, input, triviaP);
|
|
5387
|
+
return scan;
|
|
5388
|
+
}
|
|
5389
|
+
function clearRunEnd(input, cur, ctx, triviaP, plain) {
|
|
5390
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
5391
|
+
const spec = triviaP?._meta.labeledTriviaSpec;
|
|
5392
|
+
if (!plain || triviaP === void 0 || spec == null || rootKinds === void 0 || ctx._triviaLog !== void 0) return -1;
|
|
5393
|
+
if (spec.rootKinds !== rootKinds) prime(spec, triviaP, rootKinds);
|
|
5394
|
+
const fast = spec.rootScan;
|
|
5395
|
+
if (fast === null) return -1;
|
|
5396
|
+
const end = fast(input, cur);
|
|
5397
|
+
return ctx._rootTriviaCapture === false || clearOf(spec.rootLeaders, input, cur, end) ? end : -1;
|
|
5398
|
+
}
|
|
5399
|
+
function remember(cur, end, ctx, input, triviaP) {
|
|
5400
|
+
const gap = ctx._gap;
|
|
5401
|
+
if (gap === void 0) {
|
|
5402
|
+
ctx._gap = { at: cur, end, input, of: triviaP, root: ctx._rootTriviaCapture, rootKinds: ctx._rootTriviaKindIndex, log: ctx._triviaLog, state: ctx.state };
|
|
5403
|
+
return;
|
|
5404
|
+
}
|
|
5405
|
+
gap.at = cur;
|
|
5406
|
+
gap.end = end;
|
|
5407
|
+
gap.input = input;
|
|
5408
|
+
gap.of = triviaP;
|
|
5409
|
+
gap.root = ctx._rootTriviaCapture;
|
|
5410
|
+
gap.rootKinds = ctx._rootTriviaKindIndex;
|
|
5411
|
+
gap.log = ctx._triviaLog;
|
|
5412
|
+
gap.state = ctx.state;
|
|
5413
|
+
}
|
|
5414
|
+
function prime(spec, triviaP, rootKinds) {
|
|
5415
|
+
const ranges = [];
|
|
5416
|
+
let bounded = true;
|
|
5417
|
+
for (const arm of spec.arms) {
|
|
5418
|
+
if (rootKinds[arm.label] === void 0) continue;
|
|
5419
|
+
const fs = arm.parser._meta.firstSet;
|
|
5420
|
+
if (fs.kind === "any") bounded = false;
|
|
5421
|
+
else if (fs.kind === "ranges") ranges.push(...fs.ranges);
|
|
5422
|
+
}
|
|
5423
|
+
const classified = triviaP._meta.triviaScanner;
|
|
5424
|
+
spec.rootKinds = rootKinds;
|
|
5425
|
+
spec.rootLeaders = ranges;
|
|
5426
|
+
spec.rootScan = !bounded ? null : classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
5427
|
+
}
|
|
5428
|
+
function clearOf(ranges, input, from, to) {
|
|
5429
|
+
for (let i = from; i < to; i++) {
|
|
5430
|
+
const c = input.charCodeAt(i);
|
|
5431
|
+
if (c >= 55296 && c <= 57343) return false;
|
|
5432
|
+
for (const r of ranges) if (c >= r.lo && c <= r.hi) return false;
|
|
5433
|
+
}
|
|
5434
|
+
return true;
|
|
5435
|
+
}
|
|
5436
|
+
|
|
5015
5437
|
// src/combinators/dispatch.ts
|
|
5016
|
-
function parserUsesRouted(
|
|
5017
|
-
if (seen.has(
|
|
5018
|
-
seen.add(
|
|
5019
|
-
const def =
|
|
5438
|
+
function parserUsesRouted(parser2, seen = /* @__PURE__ */ new Set()) {
|
|
5439
|
+
if (seen.has(parser2)) return false;
|
|
5440
|
+
seen.add(parser2);
|
|
5441
|
+
const def = parser2._def;
|
|
5020
5442
|
switch (def.tag) {
|
|
5021
5443
|
case "routed":
|
|
5022
5444
|
return true;
|
|
@@ -5066,10 +5488,16 @@ function branchUsesRouted(branch) {
|
|
|
5066
5488
|
return branch.usesRouted === true || parserUsesRouted(branch.parser);
|
|
5067
5489
|
}
|
|
5068
5490
|
function asciiFoldKey(key) {
|
|
5069
|
-
let
|
|
5070
|
-
for (
|
|
5491
|
+
let i = 0;
|
|
5492
|
+
for (; i < key.length; i++) {
|
|
5493
|
+
const c = key.charCodeAt(i);
|
|
5494
|
+
if (c >= 65 && c <= 90) break;
|
|
5495
|
+
}
|
|
5496
|
+
if (i === key.length) return key;
|
|
5497
|
+
let out = key.slice(0, i);
|
|
5498
|
+
for (; i < key.length; i++) {
|
|
5071
5499
|
const c = key.charCodeAt(i);
|
|
5072
|
-
out +=
|
|
5500
|
+
out += c >= 65 && c <= 90 ? String.fromCharCode(c + 32) : key[i];
|
|
5073
5501
|
}
|
|
5074
5502
|
return out;
|
|
5075
5503
|
}
|
|
@@ -5131,6 +5559,7 @@ var OP_SCOPE_PLAIN = 41;
|
|
|
5131
5559
|
var OP_LEX_BODY = 42;
|
|
5132
5560
|
var OP_LEX_PROGRAM = 43;
|
|
5133
5561
|
var OP_SOURCE_LEAF = 44;
|
|
5562
|
+
var OP_RGATE = 45;
|
|
5134
5563
|
var OP_DISPATCH = 25;
|
|
5135
5564
|
var OP_ROUTED = 26;
|
|
5136
5565
|
var OP_NAMES = {
|
|
@@ -5150,6 +5579,7 @@ var OP_NAMES = {
|
|
|
5150
5579
|
[OP_PEEK]: "PEEK",
|
|
5151
5580
|
[OP_LEAF]: "LEAF",
|
|
5152
5581
|
[OP_SOURCE_LEAF]: "SOURCE_LEAF",
|
|
5582
|
+
[OP_RGATE]: "RGATE",
|
|
5153
5583
|
[OP_EMPTY]: "EMPTY",
|
|
5154
5584
|
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
5155
5585
|
[OP_RX_TRACK]: "RX_TRACK",
|
|
@@ -6249,6 +6679,7 @@ function childSlots(code, ip, out) {
|
|
|
6249
6679
|
case OP_LEAF:
|
|
6250
6680
|
case OP_SOURCE_LEAF:
|
|
6251
6681
|
case OP_ARMGATE:
|
|
6682
|
+
case OP_RGATE:
|
|
6252
6683
|
out.push(code[ip + 2]);
|
|
6253
6684
|
return true;
|
|
6254
6685
|
// `ROUTED fallback` — the operand is an offset or −1. The routed token itself is
|
|
@@ -6332,6 +6763,42 @@ function reachableSites(code, roots) {
|
|
|
6332
6763
|
}
|
|
6333
6764
|
return seen;
|
|
6334
6765
|
}
|
|
6766
|
+
function passCollapse(code, ip, hostCst) {
|
|
6767
|
+
const flags = code[ip + 3];
|
|
6768
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return false;
|
|
6769
|
+
if (flags !== 32 && flags !== 34) return false;
|
|
6770
|
+
let at = code[ip + 2];
|
|
6771
|
+
for (let n = 0; n < 8; n++) {
|
|
6772
|
+
const op = code[at];
|
|
6773
|
+
if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[at + 3] === 0) at = code[at + 2];
|
|
6774
|
+
else if (op === OP_RULE) at = code[at + 1];
|
|
6775
|
+
else break;
|
|
6776
|
+
}
|
|
6777
|
+
return code[at] === OP_NODE;
|
|
6778
|
+
}
|
|
6779
|
+
function gatedPassCollapse(code, ip, hostCst) {
|
|
6780
|
+
const flags = code[ip + 3];
|
|
6781
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return void 0;
|
|
6782
|
+
if (flags !== 32 && flags !== 34) return void 0;
|
|
6783
|
+
const seq = code[ip + 2];
|
|
6784
|
+
if (code[seq] !== OP_SEQ && code[seq] !== OP_SEQV) return void 0;
|
|
6785
|
+
const n = code[seq + 1];
|
|
6786
|
+
if (n < 2) return void 0;
|
|
6787
|
+
const leads = [];
|
|
6788
|
+
const lits = [];
|
|
6789
|
+
for (let i = 0; i < n - 1; i++) {
|
|
6790
|
+
const t = code[seq + 2 + i];
|
|
6791
|
+
if (code[t] !== OP_OPT && code[t] !== OP_NOT) return void 0;
|
|
6792
|
+
const g = code[t + 1];
|
|
6793
|
+
if (code[g] === OP_GATE) leads.push(g);
|
|
6794
|
+
else if (code[g] === OP_LIT) lits.push(code[g + 1]);
|
|
6795
|
+
else return void 0;
|
|
6796
|
+
}
|
|
6797
|
+
const last = code[seq + 2 + n - 1];
|
|
6798
|
+
let at = last;
|
|
6799
|
+
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];
|
|
6800
|
+
return code[at] === OP_NODE ? { leads, lits, last } : void 0;
|
|
6801
|
+
}
|
|
6335
6802
|
function transfer(code, ip, at, hostCst) {
|
|
6336
6803
|
const op = code[ip];
|
|
6337
6804
|
if (op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN) {
|
|
@@ -6343,14 +6810,18 @@ function transfer(code, ip, at, hostCst) {
|
|
|
6343
6810
|
}
|
|
6344
6811
|
if (op === OP_NODE || op === OP_NODE_TRACK) {
|
|
6345
6812
|
const flags = code[ip + 3];
|
|
6813
|
+
if (passCollapse(code, ip, hostCst)) return at;
|
|
6814
|
+
const gated = gatedPassCollapse(code, ip, hostCst) !== void 0;
|
|
6346
6815
|
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && ((flags & ~128) === 2 || flags === 18 || flags === 34);
|
|
6347
6816
|
if (directChildren) {
|
|
6348
|
-
|
|
6817
|
+
const framed2 = { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
|
|
6818
|
+
return gated ? meet(at, framed2) : framed2;
|
|
6349
6819
|
}
|
|
6350
6820
|
const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
|
|
6351
6821
|
const raw = !hostCst && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags & 2) !== 0 ? RAW_OMIT : RAW_CAPTURE;
|
|
6352
6822
|
if (at.buf && raw === at.raw && cap === at.cap) return at;
|
|
6353
|
-
|
|
6823
|
+
const framed = { tri: at.tri, buf: true, raw, cap };
|
|
6824
|
+
return gated ? meet(at, framed) : framed;
|
|
6354
6825
|
}
|
|
6355
6826
|
if (op === OP_TOKEN) {
|
|
6356
6827
|
if (at.tri === TRI_NONE && !at.buf) return at;
|
|
@@ -6388,6 +6859,40 @@ function computeSiteLabels(code, roots, hostCst) {
|
|
|
6388
6859
|
}
|
|
6389
6860
|
return { at: (ip) => labels.get(ip) ?? TOP };
|
|
6390
6861
|
}
|
|
6862
|
+
function scopeIsIdentity(code, ip, at) {
|
|
6863
|
+
const op = code[ip];
|
|
6864
|
+
if (op !== OP_SCOPE_PLAIN && !(op === OP_SCOPE && code[ip + 3] === 0)) return false;
|
|
6865
|
+
const ki = code[ip + 1];
|
|
6866
|
+
return at.tri === (ki < 0 ? TRI_NONE : ki);
|
|
6867
|
+
}
|
|
6868
|
+
function scanHandoffNeeded(code, ip, labels) {
|
|
6869
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6870
|
+
const stack = [ip];
|
|
6871
|
+
const kids = [];
|
|
6872
|
+
while (stack.length > 0) {
|
|
6873
|
+
const at = stack.pop();
|
|
6874
|
+
if (seen.has(at)) continue;
|
|
6875
|
+
seen.add(at);
|
|
6876
|
+
const l = labels.at(at);
|
|
6877
|
+
if (l.tri === TRI_UNKNOWN) return true;
|
|
6878
|
+
const op = code[at];
|
|
6879
|
+
if (op === OP_SCAN) return true;
|
|
6880
|
+
if (op === OP_TOKEN || op === OP_SCOPE_CAP) continue;
|
|
6881
|
+
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;
|
|
6882
|
+
kids.length = 0;
|
|
6883
|
+
if (!childSlots(code, at, kids)) return true;
|
|
6884
|
+
for (const c of kids) stack.push(c);
|
|
6885
|
+
}
|
|
6886
|
+
return false;
|
|
6887
|
+
}
|
|
6888
|
+
function triviaLeadRanges(tri, trivia2) {
|
|
6889
|
+
if (tri === TRI_NONE) return [];
|
|
6890
|
+
if (tri < 0) return void 0;
|
|
6891
|
+
const fs = trivia2[tri]?._meta.firstSet;
|
|
6892
|
+
if (fs === void 0) return void 0;
|
|
6893
|
+
if (fs.kind === "empty") return [];
|
|
6894
|
+
return fs.kind === "ranges" && fs.ranges !== void 0 ? fs.ranges : void 0;
|
|
6895
|
+
}
|
|
6391
6896
|
|
|
6392
6897
|
// src/table/scalar-terminal.ts
|
|
6393
6898
|
function makeScalarRecognizer(op, spec) {
|
|
@@ -6425,6 +6930,12 @@ function scalarTerminalNotChild(code, ip) {
|
|
|
6425
6930
|
const op = code[child];
|
|
6426
6931
|
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
6427
6932
|
}
|
|
6933
|
+
function scalarTerminalPeekChild(code, ip) {
|
|
6934
|
+
if (code[ip] !== OP_PEEK) return -1;
|
|
6935
|
+
const child = code[ip + 1];
|
|
6936
|
+
const op = code[child];
|
|
6937
|
+
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
6938
|
+
}
|
|
6428
6939
|
function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, throughPeek = false) {
|
|
6429
6940
|
const seen = /* @__PURE__ */ new Set();
|
|
6430
6941
|
let at = ip;
|
|
@@ -6602,6 +7113,59 @@ function leadingTriviaFieldAt(code, k, ip) {
|
|
|
6602
7113
|
return code[ip] === OP_FIELD && (fieldSpec(k[code[ip + 1]]).bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
6603
7114
|
}
|
|
6604
7115
|
|
|
7116
|
+
// src/table/hold-gap.ts
|
|
7117
|
+
var WRAPPERS = /* @__PURE__ */ new Set([
|
|
7118
|
+
OP_NODE,
|
|
7119
|
+
OP_XFORM,
|
|
7120
|
+
OP_LEAF,
|
|
7121
|
+
OP_SOURCE_LEAF,
|
|
7122
|
+
OP_TOKEN,
|
|
7123
|
+
OP_SCOPE,
|
|
7124
|
+
OP_SCOPE_CAP,
|
|
7125
|
+
OP_SCOPE_PLAIN,
|
|
7126
|
+
OP_FIELD,
|
|
7127
|
+
OP_LABEL,
|
|
7128
|
+
OP_EXPECT,
|
|
7129
|
+
OP_WITHCTX,
|
|
7130
|
+
OP_RULE,
|
|
7131
|
+
OP_ATTEMPT,
|
|
7132
|
+
OP_COV
|
|
7133
|
+
]);
|
|
7134
|
+
function rowNullable(code, k, ip, memo) {
|
|
7135
|
+
const hit = memo.get(ip);
|
|
7136
|
+
if (hit !== void 0) return hit;
|
|
7137
|
+
memo.set(ip, true);
|
|
7138
|
+
const op = code[ip];
|
|
7139
|
+
const kids = [];
|
|
7140
|
+
let out = true;
|
|
7141
|
+
if (op === OP_GATE) out = false;
|
|
7142
|
+
else if (op === OP_LIT || op === OP_LIT_CI) out = k[code[ip + 1]].length === 0;
|
|
7143
|
+
else if (op === OP_RX) {
|
|
7144
|
+
const re = k[code[ip + 1]];
|
|
7145
|
+
out = !(re instanceof RegExp) || regexCanMatchEmpty(re.source);
|
|
7146
|
+
} else if (op === OP_SEQ || op === OP_SEQV || op === OP_SEQX) {
|
|
7147
|
+
childSlots(code, ip, kids);
|
|
7148
|
+
out = kids.every((c) => rowNullable(code, k, c, memo));
|
|
7149
|
+
} else if (op === OP_CHOICE) {
|
|
7150
|
+
childSlots(code, ip, kids);
|
|
7151
|
+
out = kids.length === 0 || kids.some((c) => rowNullable(code, k, c, memo));
|
|
7152
|
+
} else if (op === OP_REP || op === OP_REPV) {
|
|
7153
|
+
out = code[ip + 2] === 0 || rowNullable(code, k, code[ip + 1], memo);
|
|
7154
|
+
} else if (WRAPPERS.has(op)) {
|
|
7155
|
+
if (childSlots(code, ip, kids) && kids.length === 1) out = rowNullable(code, k, kids[0], memo);
|
|
7156
|
+
}
|
|
7157
|
+
memo.set(ip, out);
|
|
7158
|
+
return out;
|
|
7159
|
+
}
|
|
7160
|
+
function holdsGap(code, k, base, n, i, memo) {
|
|
7161
|
+
if (i < 1 || i + 1 >= n) return false;
|
|
7162
|
+
const term = code[base + i];
|
|
7163
|
+
if (code[term] !== OP_NOT && code[term] !== OP_PEEK) return false;
|
|
7164
|
+
const next = code[base + i + 1];
|
|
7165
|
+
if (code[next] === OP_ADJ || leadingTriviaFieldAt(code, k, next)) return false;
|
|
7166
|
+
return !rowNullable(code, k, next, memo);
|
|
7167
|
+
}
|
|
7168
|
+
|
|
6605
7169
|
// src/table/emit-assembly.ts
|
|
6606
7170
|
var Unemittable = class extends Error {
|
|
6607
7171
|
construct;
|
|
@@ -6679,7 +7243,13 @@ var EMITTED_PARAMS = [
|
|
|
6679
7243
|
// Appended for trivia-attributing fields (`field(…, { leadingTrivia })`);
|
|
6680
7244
|
// old factories ignore them.
|
|
6681
7245
|
"LEAD",
|
|
6682
|
-
"triviaFieldCapture"
|
|
7246
|
+
"triviaFieldCapture",
|
|
7247
|
+
// Appended for the deferred-commit trivia skip (`trivia-gap.ts`); old
|
|
7248
|
+
// factories ignore it.
|
|
7249
|
+
"skipDeferredTrivia",
|
|
7250
|
+
// Appended for the pass-through collapse (`run-support.ts`); old factories
|
|
7251
|
+
// ignore it.
|
|
7252
|
+
"collapseEmpty"
|
|
6683
7253
|
];
|
|
6684
7254
|
var RUNTIME_PRELUDE = `
|
|
6685
7255
|
let _pfScan=null
|
|
@@ -6700,7 +7270,7 @@ function _skipTrivia(input,cur,ctx){
|
|
|
6700
7270
|
const s=_pfScan
|
|
6701
7271
|
if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
|
|
6702
7272
|
if(s!==null)return skipTriviaScanned(s,input,cur,ctx)
|
|
6703
|
-
if(needsDeferredTriviaCommit(ctx))return
|
|
7273
|
+
if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
|
|
6704
7274
|
return advanceTrivia(input,cur,ctx)
|
|
6705
7275
|
}
|
|
6706
7276
|
function _pushLeaf(ctx,value,s,e){pushCstLeaf(ctx,{_tag:'leaf',value,span:{start:s,end:e}})}
|
|
@@ -6876,6 +7446,24 @@ ${fast}
|
|
|
6876
7446
|
${scanned}
|
|
6877
7447
|
}`;
|
|
6878
7448
|
}
|
|
7449
|
+
function emitHoldTerm(callee, dst, t, l, skip) {
|
|
7450
|
+
const fast = `const ${t}v=${callee}(input,cur,ctx)
|
|
7451
|
+
if(${t}v===FAIL)return FAIL
|
|
7452
|
+
${dst}=${t}v
|
|
7453
|
+
cur=EC.e`;
|
|
7454
|
+
if (l.tri === TRI_NONE) return fast;
|
|
7455
|
+
const held = `const ${t}s=${skip}(input,cur,ctx)
|
|
7456
|
+
const ${t}v=${callee}(input,${t}s,ctx)
|
|
7457
|
+
if(${t}v===FAIL)return FAIL
|
|
7458
|
+
${dst}=${t}v
|
|
7459
|
+
cur=${t}s`;
|
|
7460
|
+
if (l.tri !== TRI_UNKNOWN) return held;
|
|
7461
|
+
return `if(ctx.trivia===undefined){
|
|
7462
|
+
${fast}
|
|
7463
|
+
}else{
|
|
7464
|
+
${held}
|
|
7465
|
+
}`;
|
|
7466
|
+
}
|
|
6879
7467
|
function leadSkip(hasTrivia, leadTrivia, skip) {
|
|
6880
7468
|
if (hasTrivia === "false") return "{}";
|
|
6881
7469
|
const call = `itemStart=${skip}(input,itemStart,ctx)`;
|
|
@@ -6907,7 +7495,7 @@ function rebuildPools(cc, fx, disp, plan) {
|
|
|
6907
7495
|
})
|
|
6908
7496
|
};
|
|
6909
7497
|
}
|
|
6910
|
-
function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
7498
|
+
function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, select) {
|
|
6911
7499
|
const { code, k, fx, disp, dsp, triviaLabelled } = t;
|
|
6912
7500
|
const swapLegal = !cfg.trackLines;
|
|
6913
7501
|
const hostCst = cfg.hostCst;
|
|
@@ -6917,6 +7505,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
6917
7505
|
const reachable = [...reachableSites(code, roots)];
|
|
6918
7506
|
const labels = computeSiteLabels(code, roots, hostCst);
|
|
6919
7507
|
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
7508
|
+
const nullable2 = /* @__PURE__ */ new Map();
|
|
6920
7509
|
const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
|
|
6921
7510
|
const largeChoiceLiteralFamilies = /* @__PURE__ */ new Map();
|
|
6922
7511
|
const largeChoiceScalarSequences = /* @__PURE__ */ new Map();
|
|
@@ -7006,6 +7595,8 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
7006
7595
|
};
|
|
7007
7596
|
const bodies = [];
|
|
7008
7597
|
const byIp = /* @__PURE__ */ new Map();
|
|
7598
|
+
const externals = [];
|
|
7599
|
+
const siteBytes = /* @__PURE__ */ new Map();
|
|
7009
7600
|
const reached = /* @__PURE__ */ new Set();
|
|
7010
7601
|
const prelude = [];
|
|
7011
7602
|
const skipDefs = [];
|
|
@@ -7141,6 +7732,18 @@ return 1
|
|
|
7141
7732
|
tokenDecisionRefs.set(dispatchIp, made);
|
|
7142
7733
|
return made;
|
|
7143
7734
|
}
|
|
7735
|
+
function gateMissTest(gip) {
|
|
7736
|
+
const resolved = t.cc[code[gip + 1]];
|
|
7737
|
+
const ci = classes.push([resolved]) - 1;
|
|
7738
|
+
classPlan.push([code[gip + 1]]);
|
|
7739
|
+
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
7740
|
+
return isAsciiOnlyClass(resolved) ? `${cls}.ascii[input.charCodeAt(pos)]!==1` : `!classHas(${cls},lead(input,pos))`;
|
|
7741
|
+
}
|
|
7742
|
+
function lookaheadMiss(child, miss) {
|
|
7743
|
+
if (code[child] !== OP_GATE || cfg.tolerant || cfg.probe) return "";
|
|
7744
|
+
return `if(${gateMissTest(child)}){${miss}}
|
|
7745
|
+
`;
|
|
7746
|
+
}
|
|
7144
7747
|
function skipFor(l) {
|
|
7145
7748
|
if (l.tri < 0) return "_skipTrivia";
|
|
7146
7749
|
const ki = l.tri;
|
|
@@ -7151,8 +7754,8 @@ return 1
|
|
|
7151
7754
|
const nm = `_sk${skipPool.size}`;
|
|
7152
7755
|
skipPool.set(key, nm);
|
|
7153
7756
|
if (!hasScan) {
|
|
7154
|
-
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return
|
|
7155
|
-
if(needsDeferredTriviaCommit(ctx))return
|
|
7757
|
+
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return skipDeferredTrivia(input,cur,ctx)}` : `function ${nm}(input,cur,ctx){
|
|
7758
|
+
if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
|
|
7156
7759
|
return advanceTrivia(input,cur,ctx)}`);
|
|
7157
7760
|
return nm;
|
|
7158
7761
|
}
|
|
@@ -7197,9 +7800,17 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
7197
7800
|
const target = resolveAlias(ip);
|
|
7198
7801
|
const done = byIp.get(target);
|
|
7199
7802
|
if (done !== void 0) return done;
|
|
7803
|
+
if (select !== void 0 && !select.has(target)) {
|
|
7804
|
+
const ext = `_px${target}`;
|
|
7805
|
+
byIp.set(target, ext);
|
|
7806
|
+
externals.push(target);
|
|
7807
|
+
return ext;
|
|
7808
|
+
}
|
|
7200
7809
|
const fname = `_pf${target}`;
|
|
7201
7810
|
byIp.set(target, fname);
|
|
7202
|
-
|
|
7811
|
+
const body = lower(target, fname);
|
|
7812
|
+
siteBytes.set(target, body.length);
|
|
7813
|
+
bodies.push(body);
|
|
7203
7814
|
return fname;
|
|
7204
7815
|
}
|
|
7205
7816
|
function resolveAlias(ip) {
|
|
@@ -7219,9 +7830,7 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
7219
7830
|
const op = code[ip];
|
|
7220
7831
|
if (op === OP_GATE && (cfg.tolerant || cfg.probe)) return code[ip + 2];
|
|
7221
7832
|
if (op === OP_RULE) return code[ip + 1];
|
|
7222
|
-
if ((
|
|
7223
|
-
return code[ip + 2];
|
|
7224
|
-
}
|
|
7833
|
+
if (scopeIsIdentity(code, ip, labels.at(ip))) return code[ip + 2];
|
|
7225
7834
|
return void 0;
|
|
7226
7835
|
}
|
|
7227
7836
|
function lower(ip, fname) {
|
|
@@ -7339,14 +7948,44 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
7339
7948
|
return `${head}EC.e=pos;return ''}`;
|
|
7340
7949
|
case OP_GATE: {
|
|
7341
7950
|
const child = link(code[ip + 2]);
|
|
7951
|
+
const xf = fxRef(code[ip + 3]);
|
|
7952
|
+
return `${head}
|
|
7953
|
+
if(${gateMissTest(ip)}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
7954
|
+
return ${child}(input,pos,ctx)
|
|
7955
|
+
}`;
|
|
7956
|
+
}
|
|
7957
|
+
case OP_RGATE: {
|
|
7958
|
+
const child = link(code[ip + 2]);
|
|
7959
|
+
if (cfg.tolerant || cfg.probe) return `${head}
|
|
7960
|
+
return ${child}(input,pos,ctx)
|
|
7961
|
+
}`;
|
|
7342
7962
|
const resolved = t.cc[code[ip + 1]];
|
|
7343
7963
|
const ci = classes.push([resolved]) - 1;
|
|
7344
7964
|
classPlan.push([code[ip + 1]]);
|
|
7345
7965
|
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
7346
7966
|
const xf = fxRef(code[ip + 3]);
|
|
7347
7967
|
return `${head}
|
|
7348
|
-
|
|
7968
|
+
const it=ctx._routed
|
|
7969
|
+
if(it!==undefined&&it.span.start===pos&&!classHas(${cls},lead(input,it.span.end))){ctx._fe=it.span.end;ctx._fx=${xf};return FAIL}
|
|
7349
7970
|
return ${child}(input,pos,ctx)
|
|
7971
|
+
}`;
|
|
7972
|
+
}
|
|
7973
|
+
case OP_ARMGATE: {
|
|
7974
|
+
const pred = fnRef(code[ip + 1]);
|
|
7975
|
+
const child = link(code[ip + 2]);
|
|
7976
|
+
const xf = fxRef(code[ip + 3]);
|
|
7977
|
+
return `${head}
|
|
7978
|
+
if(!${pred}(ctx.state)){ctx._fc=false;ctx._fe=-1;ctx._fx=${xf};return FAIL}
|
|
7979
|
+
return ${child}(input,pos,ctx)
|
|
7980
|
+
}`;
|
|
7981
|
+
}
|
|
7982
|
+
case OP_WITHCTX: {
|
|
7983
|
+
const ki = code[ip + 1];
|
|
7984
|
+
const child = link(code[ip + 2]);
|
|
7985
|
+
return `${head}
|
|
7986
|
+
const saved=ctx.state
|
|
7987
|
+
ctx.state=${ki < 0 ? `${fnRef(~ki)}(saved)` : kRef(ki)}
|
|
7988
|
+
try{return ${child}(input,pos,ctx)}finally{ctx.state=saved}
|
|
7350
7989
|
}`;
|
|
7351
7990
|
}
|
|
7352
7991
|
case OP_XFORM: {
|
|
@@ -7602,24 +8241,34 @@ return FAIL
|
|
|
7602
8241
|
const xf = fxRef(code[ip + 2]);
|
|
7603
8242
|
const p = tmp();
|
|
7604
8243
|
return `${head}
|
|
7605
|
-
${emitMark(p, L.buf, L.raw, sinks)}
|
|
7606
|
-
const v=${child}(input,pos,ctx)
|
|
8244
|
+
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${emitMark(p, L.buf, L.raw, sinks)}
|
|
8245
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
7607
8246
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
7608
|
-
if(v===FAIL){EC.e=pos;return null}
|
|
8247
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){EC.e=pos;return null}
|
|
7609
8248
|
ctx._fe=pos
|
|
7610
8249
|
ctx._fx=${xf}
|
|
7611
8250
|
return FAIL
|
|
7612
8251
|
}`;
|
|
7613
8252
|
}
|
|
7614
8253
|
case OP_PEEK: {
|
|
8254
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
8255
|
+
if (scalarChild >= 0) {
|
|
8256
|
+
const recognize = recognizerRef(code[scalarChild + 1]);
|
|
8257
|
+
const xf2 = fxRef(code[ip + 2]);
|
|
8258
|
+
return `${head}
|
|
8259
|
+
if(${recognize}(input,pos)<0){ctx._fe=pos;ctx._fx=${xf2};return FAIL}
|
|
8260
|
+
EC.e=pos
|
|
8261
|
+
return null
|
|
8262
|
+
}`;
|
|
8263
|
+
}
|
|
7615
8264
|
const child = link(code[ip + 1]);
|
|
7616
8265
|
const xf = fxRef(code[ip + 2]);
|
|
7617
8266
|
const p = tmp();
|
|
7618
8267
|
return `${head}
|
|
7619
|
-
${emitMark(p, L.buf, L.raw, sinks)}
|
|
7620
|
-
const v=${child}(input,pos,ctx)
|
|
8268
|
+
${lookaheadMiss(code[ip + 1], `ctx._fe=pos;ctx._fx=${xf};return FAIL`)}${emitMark(p, L.buf, L.raw, sinks)}
|
|
8269
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
7621
8270
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
7622
|
-
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
8271
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
7623
8272
|
EC.e=pos
|
|
7624
8273
|
return null
|
|
7625
8274
|
}`;
|
|
@@ -7629,7 +8278,7 @@ return null
|
|
|
7629
8278
|
const clean = !REC && failureRollbackClean(prog, ip);
|
|
7630
8279
|
const p = tmp();
|
|
7631
8280
|
return `${head}
|
|
7632
|
-
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
8281
|
+
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
7633
8282
|
ctx._fc=false
|
|
7634
8283
|
const v=${child}(input,pos,ctx)
|
|
7635
8284
|
if(v===FAIL){
|
|
@@ -7690,7 +8339,7 @@ return v
|
|
|
7690
8339
|
);
|
|
7691
8340
|
} else {
|
|
7692
8341
|
const callee = leadingTriviaFieldAt(code, k, childIp) ? `(LEAD.at=cur,${kids[i]})` : kids[i];
|
|
7693
|
-
parts.push(emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
8342
|
+
parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
7694
8343
|
}
|
|
7695
8344
|
names.push(vn);
|
|
7696
8345
|
}
|
|
@@ -7710,7 +8359,7 @@ return v
|
|
|
7710
8359
|
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
7711
8360
|
const hiArr = table.hi;
|
|
7712
8361
|
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
7713
|
-
const directAscii =
|
|
8362
|
+
const directAscii = table.hi.length === 0;
|
|
7714
8363
|
return `${head}
|
|
7715
8364
|
const c=${directAscii ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
7716
8365
|
let arm=-1
|
|
@@ -7737,7 +8386,7 @@ return FAIL
|
|
|
7737
8386
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
7738
8387
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
7739
8388
|
const maskable = n <= 32;
|
|
7740
|
-
const directAsciiMask =
|
|
8389
|
+
const directAsciiMask = maskable && gates.every(isAsciiOnlyClass);
|
|
7741
8390
|
const gateRefs = directAsciiMask ? [] : Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
7742
8391
|
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
7743
8392
|
const pretests = Array.from({ length: n }, (_, i) => {
|
|
@@ -7779,7 +8428,7 @@ return FAIL
|
|
|
7779
8428
|
if (choiceCannotCommit(prog, ip) && !startFailureExact) {
|
|
7780
8429
|
const deepAt = Array.from({ length: n }, () => tmp());
|
|
7781
8430
|
const deepFx = Array.from({ length: n }, () => tmp());
|
|
7782
|
-
const
|
|
8431
|
+
const remember2 = (i, at, expectedSet) => `${deepAt[i]}=${at};${deepFx[i]}=${expectedSet}`;
|
|
7783
8432
|
const lazyArms = (ascii) => arms.map((arm, i) => {
|
|
7784
8433
|
const pretest = pretests[i];
|
|
7785
8434
|
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
@@ -7791,13 +8440,13 @@ return FAIL
|
|
|
7791
8440
|
if(${decision}===0){
|
|
7792
8441
|
ctx._fc=false
|
|
7793
8442
|
{const at=_pfTokEnd
|
|
7794
|
-
${
|
|
8443
|
+
${remember2(i, "at", pretest.token.expected)}}
|
|
7795
8444
|
}`;
|
|
7796
8445
|
const sequenceMiss = pretest?.sequence === void 0 ? "" : `
|
|
7797
8446
|
else if(${ascii ? `(bits&${1 << i})!==0&&` : ""}${decision}<0){
|
|
7798
8447
|
ctx._fc=false
|
|
7799
8448
|
{const at=_pfSeqEnd
|
|
7800
|
-
${
|
|
8449
|
+
${remember2(i, "at", pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("") + pretest.sequence.expected.at(-1))}}
|
|
7801
8450
|
}`;
|
|
7802
8451
|
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
7803
8452
|
`}if(${gate}){
|
|
@@ -7805,7 +8454,7 @@ ctx._fc=false
|
|
|
7805
8454
|
{const v=${arm}(input,pos,ctx)
|
|
7806
8455
|
if(v!==FAIL)return v}
|
|
7807
8456
|
{const at=ctx._fe??pos
|
|
7808
|
-
${
|
|
8457
|
+
${remember2(i, "at", "ctx._fx")}}
|
|
7809
8458
|
${rollbackFor(i)}
|
|
7810
8459
|
}${routeMiss}${sequenceMiss}`;
|
|
7811
8460
|
}).join("\n");
|
|
@@ -7918,7 +8567,7 @@ const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
|
7918
8567
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
7919
8568
|
${startFailureExact ? "" : "let prev=0"}
|
|
7920
8569
|
${maskArms}
|
|
7921
|
-
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${n},prev,acc)`}
|
|
8570
|
+
${startFailureExact ? "" : `if(best===pos&&prev!==0)acc=${catchName}(${n},prev,acc)`}
|
|
7922
8571
|
ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
|
|
7923
8572
|
return FAIL
|
|
7924
8573
|
}
|
|
@@ -8017,7 +8666,7 @@ return [key,v]
|
|
|
8017
8666
|
const ci = classes.push([resolved]) - 1;
|
|
8018
8667
|
classPlan.push([itemClassIndex]);
|
|
8019
8668
|
itemCls = hoist("ri", `CLS[${ci}][0]`);
|
|
8020
|
-
itemAscii =
|
|
8669
|
+
itemAscii = isAsciiOnlyClass(resolved);
|
|
8021
8670
|
}
|
|
8022
8671
|
}
|
|
8023
8672
|
const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
|
|
@@ -8173,6 +8822,26 @@ return nd
|
|
|
8173
8822
|
const trailingTrivia = (flags & 128) !== 0;
|
|
8174
8823
|
const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
|
|
8175
8824
|
const leanFlags = flags & ~128;
|
|
8825
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
8826
|
+
return `${head}
|
|
8827
|
+
const v=${child}(input,pos,ctx)
|
|
8828
|
+
if(v!==undefined)return v
|
|
8829
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
8830
|
+
}`;
|
|
8831
|
+
}
|
|
8832
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
8833
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(labels.at(code[ip + 2]).tri, t.trivia);
|
|
8834
|
+
const gp = gated !== void 0 && triviaLead !== void 0 && triviaLead.length <= 16 ? `const gc=lead(input,pos)
|
|
8835
|
+
if(!(${[
|
|
8836
|
+
...gated.leads.map((g) => `!(${gateMissTest(g)})`),
|
|
8837
|
+
...gated.lits.map((i) => `gc===${k[i].codePointAt(0)}`),
|
|
8838
|
+
...triviaLead.map((r) => r.lo === r.hi ? `gc===${r.lo}` : `(gc>=${r.lo}&&gc<=${r.hi})`)
|
|
8839
|
+
].join("||") || "false"})){
|
|
8840
|
+
const gv=${link(gated.last)}(input,pos,ctx)
|
|
8841
|
+
if(gv!==undefined)return gv
|
|
8842
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
8843
|
+
}
|
|
8844
|
+
` : "";
|
|
8176
8845
|
if (!hostCst && !tracked && build !== void 0 && proj < 0 && (leanFlags === 2 || (flags === 18 || flags === 34))) {
|
|
8177
8846
|
const fields = flags === 18;
|
|
8178
8847
|
const collapseChildren = flags === 34;
|
|
@@ -8207,7 +8876,7 @@ sCh.push(nd)
|
|
|
8207
8876
|
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
8208
8877
|
}`;
|
|
8209
8878
|
return `${head}
|
|
8210
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
8879
|
+
${gp}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
8211
8880
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf,sFields=ctx._fields
|
|
8212
8881
|
const flat=[]
|
|
8213
8882
|
ctx._cstBuf=undefined
|
|
@@ -8243,7 +8912,7 @@ return nd
|
|
|
8243
8912
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
8244
8913
|
const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
|
|
8245
8914
|
const ty = q(type);
|
|
8246
|
-
const stArg =
|
|
8915
|
+
const stArg = "ctx.state";
|
|
8247
8916
|
const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
|
|
8248
8917
|
let value;
|
|
8249
8918
|
if (proj >= 0) {
|
|
@@ -8282,7 +8951,7 @@ const hostKids=kids
|
|
|
8282
8951
|
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
8283
8952
|
const tlog=buf.tl??EMPTY_TLOG`;
|
|
8284
8953
|
return `${head}
|
|
8285
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
8954
|
+
${!hostCst && !tracked ? gp : ""}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
8286
8955
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
8287
8956
|
${openCapture}
|
|
8288
8957
|
ctx.captureTrivia=${captureWide}
|
|
@@ -8304,7 +8973,7 @@ ctx.captureTrivia=sCap
|
|
|
8304
8973
|
if(v===FAIL)return FAIL
|
|
8305
8974
|
const end=EC.e
|
|
8306
8975
|
const span=${tracked ? "spanLines(ctx,pos,end)" : "{start:pos,end}"}
|
|
8307
|
-
const st=${readsState ? "
|
|
8976
|
+
const st=${readsState ? "ctx.state" : "undefined"}
|
|
8308
8977
|
let nd
|
|
8309
8978
|
${unwrap ? "if(kids.length===1)nd=unwrapChild(kids[0])\nelse " : ""}${collapse ? "if(kids.length===1)nd=kids[0]\nelse " : ""}${collapsible ? `if(_pfHost!==undefined&&_pfHost._parsemanCstCollapse!==undefined&&kids.length===1&&rawKids.length===1&&_pfHost._parsemanCstCollapse(${ty},kids[0],kids,rawKids))nd=kids[0]
|
|
8310
8979
|
else ` : ""}{${value}}
|
|
@@ -8317,21 +8986,57 @@ return nd
|
|
|
8317
8986
|
throw new Unemittable(`OP_${OP_NAMES[op] ?? String(op)}`);
|
|
8318
8987
|
}
|
|
8319
8988
|
}
|
|
8989
|
+
const served = (ip) => select === void 0 || select.has(resolveAlias(ip));
|
|
8320
8990
|
const ruleEntries = [];
|
|
8321
8991
|
for (const [rname, entryIp] of Object.entries(prog.rules)) {
|
|
8992
|
+
if (!served(entryIp)) continue;
|
|
8322
8993
|
const target = link(entryIp);
|
|
8323
8994
|
const rn = `_r_${rname.replace(/[^A-Za-z0-9_$]/g, "_")}`;
|
|
8324
8995
|
bodies.push(`const ${rn}=${target}`);
|
|
8325
8996
|
ruleEntries.push(`${q(rname)}:${rn}`);
|
|
8326
8997
|
}
|
|
8327
8998
|
const extra = [];
|
|
8328
|
-
|
|
8999
|
+
const exported = /* @__PURE__ */ new Set();
|
|
9000
|
+
for (const ip of extraIps) {
|
|
9001
|
+
if (!served(ip)) continue;
|
|
9002
|
+
exported.add(ip);
|
|
9003
|
+
extra.push(`${ip}:${link(ip)}`);
|
|
9004
|
+
}
|
|
9005
|
+
if (select !== void 0) {
|
|
9006
|
+
const kids = [];
|
|
9007
|
+
for (const ip of reachable) {
|
|
9008
|
+
if (select.has(resolveAlias(ip))) continue;
|
|
9009
|
+
kids.length = 0;
|
|
9010
|
+
childSlots(code, ip, kids);
|
|
9011
|
+
for (const kid of kids) {
|
|
9012
|
+
const target = resolveAlias(kid);
|
|
9013
|
+
if (!select.has(target) || exported.has(target)) continue;
|
|
9014
|
+
exported.add(target);
|
|
9015
|
+
extra.push(`${target}:${link(target)}`);
|
|
9016
|
+
}
|
|
9017
|
+
}
|
|
9018
|
+
}
|
|
9019
|
+
const hybrid = select === void 0 ? "" : `,
|
|
9020
|
+
ext:[${externals.join(",")}],
|
|
9021
|
+
bind:function(xs,ps){_xScan=xs
|
|
9022
|
+
${externals.map((ip, i) => `_xp${ip}=ps[${i}]`).join("\n")}},
|
|
9023
|
+
scan:function(s){const o=_pfScan;_pfScan=s;return o}`;
|
|
9024
|
+
const scannerFor = (ip) => {
|
|
9025
|
+
const ki = labels.at(ip).tri;
|
|
9026
|
+
if (ki === TRI_UNKNOWN) return "_pfScan";
|
|
9027
|
+
if (ki === TRI_NONE) return "null";
|
|
9028
|
+
return swapLegal && !triviaLabelled[ki] && t.triviaScan[ki] != null ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
9029
|
+
};
|
|
9030
|
+
const externalDefs = select === void 0 ? "" : `let _xScan
|
|
9031
|
+
${externals.map((ip) => `let _xp${ip}
|
|
9032
|
+
function _px${ip}(input,pos,ctx){const o=_xScan(${scannerFor(ip)});const v=_xp${ip}(input,pos,ctx);_xScan(o);return v}`).join("\n")}
|
|
9033
|
+
`;
|
|
8329
9034
|
const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
|
|
8330
9035
|
${prelude.join("\n")}
|
|
8331
9036
|
${skipDefs.join("\n")}
|
|
8332
9037
|
${choiceDefs.join("\n")}
|
|
8333
9038
|
${bodies.join("\n")}
|
|
8334
|
-
function _begin(ctx){
|
|
9039
|
+
${externalDefs}function _begin(ctx){
|
|
8335
9040
|
const host=ctx.build
|
|
8336
9041
|
if(_pfDepth>0)_pfFrames.push([_pfScan,_pfHost,EC.e])
|
|
8337
9042
|
_pfDepth++
|
|
@@ -8358,7 +9063,7 @@ pieces:{${ruleEntries.join(",")}},
|
|
|
8358
9063
|
byIp:{${extra.join(",")}},
|
|
8359
9064
|
end:function(){return EC.e},
|
|
8360
9065
|
begin:_begin,
|
|
8361
|
-
finish:_finish
|
|
9066
|
+
finish:_finish${hybrid}
|
|
8362
9067
|
}`;
|
|
8363
9068
|
return {
|
|
8364
9069
|
source,
|
|
@@ -8366,41 +9071,125 @@ finish:_finish
|
|
|
8366
9071
|
masks,
|
|
8367
9072
|
classes,
|
|
8368
9073
|
armExpected,
|
|
9074
|
+
siteBytes,
|
|
8369
9075
|
plan: { classes: classPlan, armExpected: armExpectedPlan, masks: maskPlan }
|
|
8370
9076
|
};
|
|
8371
9077
|
}
|
|
8372
9078
|
|
|
8373
|
-
// src/table/
|
|
8374
|
-
function
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
9079
|
+
// src/table/fail-clean.ts
|
|
9080
|
+
function passChild(code, ip) {
|
|
9081
|
+
switch (code[ip]) {
|
|
9082
|
+
case OP_RULE:
|
|
9083
|
+
case OP_LABEL:
|
|
9084
|
+
case OP_COV:
|
|
9085
|
+
case OP_TOKEN:
|
|
9086
|
+
return code[ip + 1];
|
|
9087
|
+
case OP_GATE:
|
|
9088
|
+
case OP_NODE:
|
|
9089
|
+
case OP_NODE_TRACK:
|
|
9090
|
+
case OP_XFORM:
|
|
9091
|
+
case OP_FIELD:
|
|
9092
|
+
case OP_SCOPE:
|
|
9093
|
+
case OP_SCOPE_CAP:
|
|
9094
|
+
case OP_SCOPE_PLAIN:
|
|
9095
|
+
case OP_WITHCTX:
|
|
9096
|
+
case OP_LEAF:
|
|
9097
|
+
case OP_SOURCE_LEAF:
|
|
9098
|
+
return code[ip + 2];
|
|
9099
|
+
default:
|
|
9100
|
+
return -1;
|
|
8381
9101
|
}
|
|
8382
|
-
return [lo + 1, offset - starts[lo] + 1];
|
|
8383
|
-
}
|
|
8384
|
-
function spanLines(ctx, start, end) {
|
|
8385
|
-
const s = lineCol(ctx, start), e = lineCol(ctx, end);
|
|
8386
|
-
return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] };
|
|
8387
9102
|
}
|
|
8388
|
-
function
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
|
|
9103
|
+
function seqCount(code, ip) {
|
|
9104
|
+
const op = code[ip];
|
|
9105
|
+
return op === OP_SEQ || op === OP_SEQV ? ip + 1 : op === OP_SEQX ? ip + 2 : -1;
|
|
9106
|
+
}
|
|
9107
|
+
function failCleanAnalysis(code) {
|
|
9108
|
+
const cleanAt = new Uint8Array(code.length);
|
|
9109
|
+
const neverAt = new Uint8Array(code.length);
|
|
9110
|
+
const neverFails = (ip) => {
|
|
9111
|
+
const hit = neverAt[ip];
|
|
9112
|
+
if (hit !== 0) return hit === 1;
|
|
9113
|
+
neverAt[ip] = 3;
|
|
9114
|
+
let out = false;
|
|
9115
|
+
const op = code[ip];
|
|
9116
|
+
if (op === OP_OPT || op === OP_EMPTY || op === OP_EXPECT) out = true;
|
|
9117
|
+
else if (op === OP_REP || op === OP_REPV) out = code[ip + 2] === 0;
|
|
9118
|
+
else {
|
|
9119
|
+
const at = seqCount(code, ip);
|
|
9120
|
+
if (at >= 0) {
|
|
9121
|
+
out = true;
|
|
9122
|
+
for (let i = 1, n = code[at]; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
9123
|
+
} else if (op !== OP_GATE) {
|
|
9124
|
+
const c = passChild(code, ip);
|
|
9125
|
+
out = c >= 0 && neverFails(c);
|
|
9126
|
+
}
|
|
9127
|
+
}
|
|
9128
|
+
neverAt[ip] = out ? 1 : 2;
|
|
9129
|
+
return out;
|
|
8397
9130
|
};
|
|
8398
|
-
|
|
8399
|
-
|
|
8400
|
-
|
|
8401
|
-
|
|
8402
|
-
|
|
8403
|
-
|
|
9131
|
+
const clean = (ip) => {
|
|
9132
|
+
const hit = cleanAt[ip];
|
|
9133
|
+
if (hit !== 0) return hit === 1;
|
|
9134
|
+
cleanAt[ip] = 3;
|
|
9135
|
+
let out = false;
|
|
9136
|
+
switch (code[ip]) {
|
|
9137
|
+
// A terminal pushes its leaf only on a match; NOT/PEEK/ATTEMPT restore
|
|
9138
|
+
// their own mark; OPT, EMPTY and EXPECT do not fail uncommitted.
|
|
9139
|
+
case OP_LIT:
|
|
9140
|
+
case OP_RX:
|
|
9141
|
+
case OP_LIT_TRACK:
|
|
9142
|
+
case OP_RX_TRACK:
|
|
9143
|
+
case OP_LIT_CI:
|
|
9144
|
+
case OP_LIT_CI_TRACK:
|
|
9145
|
+
case OP_GUARD:
|
|
9146
|
+
case OP_NOT:
|
|
9147
|
+
case OP_PEEK:
|
|
9148
|
+
case OP_ATTEMPT:
|
|
9149
|
+
case OP_EMPTY:
|
|
9150
|
+
case OP_OPT:
|
|
9151
|
+
case OP_EXPECT:
|
|
9152
|
+
out = true;
|
|
9153
|
+
break;
|
|
9154
|
+
// Min 0 does not fail uncommitted; min 1 fails only with no item kept, and
|
|
9155
|
+
// restores the failed item itself.
|
|
9156
|
+
case OP_REP:
|
|
9157
|
+
case OP_REPV:
|
|
9158
|
+
out = code[ip + 2] <= 1;
|
|
9159
|
+
break;
|
|
9160
|
+
// Only the first term may fail: a later one fails after the terms before it
|
|
9161
|
+
// wrote, and after the trivia scanned in front of it.
|
|
9162
|
+
case OP_SEQ:
|
|
9163
|
+
case OP_SEQV:
|
|
9164
|
+
case OP_SEQX: {
|
|
9165
|
+
const at = seqCount(code, ip);
|
|
9166
|
+
const n = code[at];
|
|
9167
|
+
out = n > 0 && clean(code[at + 1]);
|
|
9168
|
+
for (let i = 2; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
9169
|
+
break;
|
|
9170
|
+
}
|
|
9171
|
+
case OP_CHOICE: {
|
|
9172
|
+
out = true;
|
|
9173
|
+
for (let i = 0, n = code[ip + 2]; out && i < n; i++) out = clean(code[ip + 4 + i]);
|
|
9174
|
+
break;
|
|
9175
|
+
}
|
|
9176
|
+
case OP_ROUTED:
|
|
9177
|
+
out = code[ip + 1] < 0 || clean(code[ip + 1]);
|
|
9178
|
+
break;
|
|
9179
|
+
// An arm's failure and the fallback's are committed; only the selector's is
|
|
9180
|
+
// not, and without a fallback an unknown key fails after the selector wrote.
|
|
9181
|
+
case OP_DISPATCH:
|
|
9182
|
+
out = code[ip + 3] >= 0 && clean(code[ip + 1]);
|
|
9183
|
+
break;
|
|
9184
|
+
default: {
|
|
9185
|
+
const c = passChild(code, ip);
|
|
9186
|
+
out = c >= 0 && clean(c);
|
|
9187
|
+
}
|
|
9188
|
+
}
|
|
9189
|
+
cleanAt[ip] = out ? 1 : 2;
|
|
9190
|
+
return out;
|
|
9191
|
+
};
|
|
9192
|
+
return clean;
|
|
8404
9193
|
}
|
|
8405
9194
|
|
|
8406
9195
|
// src/cst/host-mode.ts
|
|
@@ -8572,6 +9361,7 @@ function assemble(t, prog, cfg) {
|
|
|
8572
9361
|
const swapLegal = !cfg.trackLines;
|
|
8573
9362
|
const hostCst = cfg.hostCst;
|
|
8574
9363
|
const REC = prog.rec === 1 && cfg.tolerant;
|
|
9364
|
+
const PROBE = cfg.probe;
|
|
8575
9365
|
const sentinels = /* @__PURE__ */ new Map();
|
|
8576
9366
|
function sentinelFor(cls) {
|
|
8577
9367
|
if (cls < 0) return void 0;
|
|
@@ -8586,6 +9376,9 @@ function assemble(t, prog, cfg) {
|
|
|
8586
9376
|
const EC = newEndCell();
|
|
8587
9377
|
const scalarRecognizers = [];
|
|
8588
9378
|
const rawScalarSpecs = /* @__PURE__ */ new Set();
|
|
9379
|
+
function lookaheadClass(child) {
|
|
9380
|
+
return code[child] === OP_GATE && !cfg.tolerant && !cfg.probe ? cc[code[child + 1]] : null;
|
|
9381
|
+
}
|
|
8589
9382
|
function scalarFor(child) {
|
|
8590
9383
|
const spec = code[child + 1];
|
|
8591
9384
|
let recognize = scalarRecognizers[spec];
|
|
@@ -8595,17 +9388,27 @@ function assemble(t, prog, cfg) {
|
|
|
8595
9388
|
}
|
|
8596
9389
|
return recognize;
|
|
8597
9390
|
}
|
|
8598
|
-
const labelExtraIps =
|
|
8599
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) labelExtraIps.push(r[0]);
|
|
8600
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
|
|
9391
|
+
const labelExtraIps = assemblyExtraIps(prog);
|
|
8601
9392
|
const closureLabels = computeSiteLabels(
|
|
8602
9393
|
code,
|
|
8603
9394
|
[...Object.values(prog.rules), ...labelExtraIps],
|
|
8604
9395
|
hostCst
|
|
8605
9396
|
);
|
|
8606
9397
|
let SCAN = null;
|
|
9398
|
+
let HYBRID;
|
|
9399
|
+
function hybridPiece(piece) {
|
|
9400
|
+
const setScan = HYBRID.scan;
|
|
9401
|
+
return (input, pos, ctx) => {
|
|
9402
|
+
const saved = setScan(SCAN);
|
|
9403
|
+
const value = piece(input, pos, ctx);
|
|
9404
|
+
setScan(saved);
|
|
9405
|
+
return value;
|
|
9406
|
+
};
|
|
9407
|
+
}
|
|
8607
9408
|
const memo = /* @__PURE__ */ new Map();
|
|
8608
9409
|
const reached = /* @__PURE__ */ new Set();
|
|
9410
|
+
const NULLABLE = /* @__PURE__ */ new Map();
|
|
9411
|
+
const CLEAN = REC ? () => false : failCleanAnalysis(code);
|
|
8609
9412
|
function pushLeaf(ctx, value, s, e) {
|
|
8610
9413
|
const lf = { _tag: "leaf", value, span: { start: s, end: e } };
|
|
8611
9414
|
pushCstLeaf(ctx, lf);
|
|
@@ -8804,6 +9607,22 @@ function assemble(t, prog, cfg) {
|
|
|
8804
9607
|
return node;
|
|
8805
9608
|
};
|
|
8806
9609
|
}
|
|
9610
|
+
function passCollapseNode(child, build, readsRaw) {
|
|
9611
|
+
return (input, pos, ctx) => {
|
|
9612
|
+
const v = child(input, pos, ctx);
|
|
9613
|
+
if (v !== void 0) return v;
|
|
9614
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
9615
|
+
};
|
|
9616
|
+
}
|
|
9617
|
+
function gatedPassCollapseNode(blockers, last, classic, build, readsRaw) {
|
|
9618
|
+
return (input, pos, ctx) => {
|
|
9619
|
+
const c = lead(input, pos);
|
|
9620
|
+
for (let i = 0; i < blockers.length; i++) if (classHas2(blockers[i], c)) return classic(input, pos, ctx);
|
|
9621
|
+
const v = last(input, pos, ctx);
|
|
9622
|
+
if (v !== void 0) return v;
|
|
9623
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
9624
|
+
};
|
|
9625
|
+
}
|
|
8807
9626
|
function plainProjectNode(child, projection, type) {
|
|
8808
9627
|
return (input, pos, ctx) => {
|
|
8809
9628
|
const sCh = ctx._cstChildren;
|
|
@@ -8895,9 +9714,7 @@ function assemble(t, prog, cfg) {
|
|
|
8895
9714
|
return s(input, cur);
|
|
8896
9715
|
}
|
|
8897
9716
|
if (s !== null) return skipTriviaScanned(s, input, cur, ctx);
|
|
8898
|
-
if (needsDeferredTriviaCommit(ctx))
|
|
8899
|
-
return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
8900
|
-
}
|
|
9717
|
+
if (needsDeferredTriviaCommit(ctx)) return skipDeferredTrivia(input, cur, ctx);
|
|
8901
9718
|
return advanceTrivia(input, cur, ctx);
|
|
8902
9719
|
}
|
|
8903
9720
|
let TERMV;
|
|
@@ -9067,7 +9884,7 @@ function assemble(t, prog, cfg) {
|
|
|
9067
9884
|
if (next !== void 0) {
|
|
9068
9885
|
return next(input, pos, ctx, bits, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
9069
9886
|
}
|
|
9070
|
-
if (best === pos) acc = through(total, prev, acc);
|
|
9887
|
+
if (best === pos && prev !== 0) acc = through(total, prev, acc);
|
|
9071
9888
|
ctx._fe = pos;
|
|
9072
9889
|
ctx._fx = acc ?? choiceFx;
|
|
9073
9890
|
return FAIL;
|
|
@@ -9150,7 +9967,7 @@ function assemble(t, prog, cfg) {
|
|
|
9150
9967
|
if (next !== void 0) {
|
|
9151
9968
|
return next(input, pos, ctx, c, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
9152
9969
|
}
|
|
9153
|
-
if (best === pos) acc = through(total, prev, acc);
|
|
9970
|
+
if (best === pos && prev !== 0) acc = through(total, prev, acc);
|
|
9154
9971
|
ctx._fe = pos;
|
|
9155
9972
|
ctx._fx = acc ?? choiceFx;
|
|
9156
9973
|
return FAIL;
|
|
@@ -9176,21 +9993,27 @@ function assemble(t, prog, cfg) {
|
|
|
9176
9993
|
}
|
|
9177
9994
|
function dispatchBranch(child, usesRouted) {
|
|
9178
9995
|
if (!usesRouted) {
|
|
9179
|
-
return (input, _pos, selEnd, key,
|
|
9180
|
-
const
|
|
9996
|
+
return (input, _pos, selEnd, key, ctx) => {
|
|
9997
|
+
const need = markCst(ctx);
|
|
9998
|
+
const mRaw = MRAW;
|
|
9999
|
+
const mTl = MTL;
|
|
10000
|
+
const mLv = MLV;
|
|
10001
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
10002
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
10003
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
10004
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
9181
10005
|
const v = child(input, selEnd, ctx);
|
|
9182
10006
|
if (v === FAIL) {
|
|
9183
|
-
|
|
10007
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9184
10008
|
ctx._fc = true;
|
|
9185
10009
|
return FAIL;
|
|
9186
10010
|
}
|
|
9187
10011
|
return [key, v];
|
|
9188
10012
|
};
|
|
9189
10013
|
}
|
|
9190
|
-
return (input, pos, selEnd, key,
|
|
10014
|
+
return (input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
9191
10015
|
const savedRouted = ctx._routed;
|
|
9192
|
-
|
|
9193
|
-
const mark = saveTriviaMark(ctx);
|
|
10016
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9194
10017
|
ctx._routed = { value: key, span: { start: pos, end: selEnd } };
|
|
9195
10018
|
let v;
|
|
9196
10019
|
try {
|
|
@@ -9199,7 +10022,7 @@ function assemble(t, prog, cfg) {
|
|
|
9199
10022
|
ctx._routed = savedRouted;
|
|
9200
10023
|
}
|
|
9201
10024
|
if (v === FAIL) {
|
|
9202
|
-
|
|
10025
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9203
10026
|
ctx._fc = true;
|
|
9204
10027
|
return FAIL;
|
|
9205
10028
|
}
|
|
@@ -9207,12 +10030,12 @@ function assemble(t, prog, cfg) {
|
|
|
9207
10030
|
};
|
|
9208
10031
|
}
|
|
9209
10032
|
function dispatchArmBlock(start, a0, a1, a2, a3, next) {
|
|
9210
|
-
return (arm, input, pos, selEnd, key,
|
|
9211
|
-
if (arm === start) return a0(input, pos, selEnd, key,
|
|
9212
|
-
if (arm === start + 1) return a1(input, pos, selEnd, key,
|
|
9213
|
-
if (arm === start + 2) return a2(input, pos, selEnd, key,
|
|
9214
|
-
if (arm === start + 3) return a3(input, pos, selEnd, key,
|
|
9215
|
-
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key,
|
|
10033
|
+
return (arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
10034
|
+
if (arm === start) return a0(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
10035
|
+
if (arm === start + 1) return a1(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
10036
|
+
if (arm === start + 2) return a2(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
10037
|
+
if (arm === start + 3) return a3(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
10038
|
+
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9216
10039
|
};
|
|
9217
10040
|
}
|
|
9218
10041
|
function trackLinesInto(ctx, input, end) {
|
|
@@ -9229,20 +10052,68 @@ function assemble(t, prog, cfg) {
|
|
|
9229
10052
|
if (done !== void 0) return done;
|
|
9230
10053
|
const flight = inFlight.get(ip);
|
|
9231
10054
|
if (flight !== void 0) return flight.fwd;
|
|
10055
|
+
const selected = HYBRID?.byIp[ip];
|
|
10056
|
+
if (selected !== void 0) {
|
|
10057
|
+
const piece2 = scanHandoffNeeded(code, ip, closureLabels) ? hybridPiece(selected) : selected;
|
|
10058
|
+
memo.set(ip, piece2);
|
|
10059
|
+
reached.add(ip);
|
|
10060
|
+
return piece2;
|
|
10061
|
+
}
|
|
9232
10062
|
let target;
|
|
9233
10063
|
const fwd = (input, pos, ctx) => target(input, pos, ctx);
|
|
9234
10064
|
const holder = { fwd, set: (p) => {
|
|
9235
10065
|
target = p;
|
|
9236
10066
|
} };
|
|
9237
10067
|
inFlight.set(ip, holder);
|
|
9238
|
-
const
|
|
9239
|
-
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]) : lower(ip);
|
|
10068
|
+
const piece = scopeIsIdentity(code, ip, closureLabels.at(ip)) ? link(code[ip + 2]) : countedPiece(lookaheadLedNode(ip) ?? lower(ip), ip);
|
|
9240
10069
|
inFlight.delete(ip);
|
|
9241
10070
|
holder.set(piece);
|
|
9242
10071
|
memo.set(ip, piece);
|
|
9243
10072
|
reached.add(ip);
|
|
9244
10073
|
return piece;
|
|
9245
10074
|
}
|
|
10075
|
+
let FIRST_DECIDED;
|
|
10076
|
+
let NODE_BODY;
|
|
10077
|
+
const DECIDED = (_input, pos) => {
|
|
10078
|
+
EC.e = pos;
|
|
10079
|
+
return null;
|
|
10080
|
+
};
|
|
10081
|
+
function lookaheadLedNode(ip) {
|
|
10082
|
+
const op = code[ip];
|
|
10083
|
+
if (op !== OP_NODE && op !== OP_NODE_TRACK || hostCst || REC || cfg.probe || cfg.coverage || cfg.trackLines) return void 0;
|
|
10084
|
+
if (passCollapse(code, ip, hostCst) || gatedPassCollapse(code, ip, hostCst) !== void 0) return void 0;
|
|
10085
|
+
const body = code[ip + 2];
|
|
10086
|
+
const bop = code[body];
|
|
10087
|
+
if (bop !== OP_SEQ && bop !== OP_SEQV && bop !== OP_SEQX) return void 0;
|
|
10088
|
+
const base = bop === OP_SEQX ? body + 3 : body + 2;
|
|
10089
|
+
if (code[bop === OP_SEQX ? body + 2 : body + 1] < 2) return void 0;
|
|
10090
|
+
const first = code[base];
|
|
10091
|
+
const negative = code[first] === OP_NOT;
|
|
10092
|
+
const terminal = negative ? scalarTerminalNotChild(code, first) : code[first] === OP_PEEK ? scalarTerminalPeekChild(code, first) : -1;
|
|
10093
|
+
if (terminal < 0) return void 0;
|
|
10094
|
+
const recognize = scalarFor(terminal);
|
|
10095
|
+
const xf = fx[code[first + 2]];
|
|
10096
|
+
FIRST_DECIDED = DECIDED;
|
|
10097
|
+
NODE_BODY = lower(body);
|
|
10098
|
+
const node = lower(ip);
|
|
10099
|
+
NODE_BODY = void 0;
|
|
10100
|
+
return negative ? (input, pos, ctx) => {
|
|
10101
|
+
if (recognize(input, pos) >= 0) {
|
|
10102
|
+
ctx._fe = pos;
|
|
10103
|
+
ctx._fx = xf;
|
|
10104
|
+
EC.e = pos;
|
|
10105
|
+
return FAIL;
|
|
10106
|
+
}
|
|
10107
|
+
return node(input, pos, ctx);
|
|
10108
|
+
} : (input, pos, ctx) => {
|
|
10109
|
+
if (recognize(input, pos) < 0) {
|
|
10110
|
+
ctx._fe = pos;
|
|
10111
|
+
ctx._fx = xf;
|
|
10112
|
+
return FAIL;
|
|
10113
|
+
}
|
|
10114
|
+
return node(input, pos, ctx);
|
|
10115
|
+
};
|
|
10116
|
+
}
|
|
9246
10117
|
function lower(ip) {
|
|
9247
10118
|
const op = code[ip];
|
|
9248
10119
|
switch (op) {
|
|
@@ -9773,7 +10644,12 @@ function assemble(t, prog, cfg) {
|
|
|
9773
10644
|
}
|
|
9774
10645
|
const child = link(code[ip + 1]);
|
|
9775
10646
|
const xf = fx[code[ip + 2]];
|
|
10647
|
+
const gate = lookaheadClass(code[ip + 1]);
|
|
9776
10648
|
return (input, pos, ctx) => {
|
|
10649
|
+
if (gate !== null && !classHas2(gate, lead(input, pos))) {
|
|
10650
|
+
EC.e = pos;
|
|
10651
|
+
return null;
|
|
10652
|
+
}
|
|
9777
10653
|
const need = markCst(ctx);
|
|
9778
10654
|
const mRaw = MRAW;
|
|
9779
10655
|
const mTl = MTL;
|
|
@@ -9782,8 +10658,10 @@ function assemble(t, prog, cfg) {
|
|
|
9782
10658
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
9783
10659
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
9784
10660
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
10661
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
9785
10662
|
const v = child(input, pos, ctx);
|
|
9786
10663
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
10664
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
9787
10665
|
if (v === FAIL) {
|
|
9788
10666
|
EC.e = pos;
|
|
9789
10667
|
return null;
|
|
@@ -9794,9 +10672,29 @@ function assemble(t, prog, cfg) {
|
|
|
9794
10672
|
};
|
|
9795
10673
|
}
|
|
9796
10674
|
case OP_PEEK: {
|
|
10675
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
10676
|
+
if (scalarChild >= 0) {
|
|
10677
|
+
const recognize = scalarFor(scalarChild);
|
|
10678
|
+
const xf2 = fx[code[ip + 2]];
|
|
10679
|
+
return (input, pos, ctx) => {
|
|
10680
|
+
if (recognize(input, pos) < 0) {
|
|
10681
|
+
ctx._fe = pos;
|
|
10682
|
+
ctx._fx = xf2;
|
|
10683
|
+
return FAIL;
|
|
10684
|
+
}
|
|
10685
|
+
EC.e = pos;
|
|
10686
|
+
return null;
|
|
10687
|
+
};
|
|
10688
|
+
}
|
|
9797
10689
|
const child = link(code[ip + 1]);
|
|
9798
10690
|
const xf = fx[code[ip + 2]];
|
|
10691
|
+
const gate = lookaheadClass(code[ip + 1]);
|
|
9799
10692
|
return (input, pos, ctx) => {
|
|
10693
|
+
if (gate !== null && !classHas2(gate, lead(input, pos))) {
|
|
10694
|
+
ctx._fe = pos;
|
|
10695
|
+
ctx._fx = xf;
|
|
10696
|
+
return FAIL;
|
|
10697
|
+
}
|
|
9800
10698
|
const need = markCst(ctx);
|
|
9801
10699
|
const mRaw = MRAW;
|
|
9802
10700
|
const mTl = MTL;
|
|
@@ -9805,8 +10703,10 @@ function assemble(t, prog, cfg) {
|
|
|
9805
10703
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
9806
10704
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
9807
10705
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
10706
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
9808
10707
|
const v = child(input, pos, ctx);
|
|
9809
10708
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
10709
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
9810
10710
|
if (v === FAIL) {
|
|
9811
10711
|
ctx._fe = pos;
|
|
9812
10712
|
ctx._fx = xf;
|
|
@@ -9818,8 +10718,14 @@ function assemble(t, prog, cfg) {
|
|
|
9818
10718
|
}
|
|
9819
10719
|
case OP_OPT: {
|
|
9820
10720
|
const child = link(code[ip + 1]);
|
|
10721
|
+
const gate = lookaheadClass(code[ip + 1]);
|
|
10722
|
+
const childClean = CLEAN(code[ip + 1]);
|
|
9821
10723
|
return (input, pos, ctx) => {
|
|
9822
|
-
|
|
10724
|
+
if (gate !== null && !classHas2(gate, lead(input, pos))) {
|
|
10725
|
+
EC.e = pos;
|
|
10726
|
+
return null;
|
|
10727
|
+
}
|
|
10728
|
+
const need = !childClean && markCst(ctx);
|
|
9823
10729
|
const mRaw = MRAW;
|
|
9824
10730
|
const mTl = MTL;
|
|
9825
10731
|
const mLv = MLV;
|
|
@@ -10017,6 +10923,9 @@ function assemble(t, prog, cfg) {
|
|
|
10017
10923
|
const projection = reducer < 0 ? ~reducer : -1;
|
|
10018
10924
|
const fn = fused && projection < 0 ? fns[reducer] : void 0;
|
|
10019
10925
|
const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm;
|
|
10926
|
+
const decided = FIRST_DECIDED;
|
|
10927
|
+
FIRST_DECIDED = void 0;
|
|
10928
|
+
const linkFirst = () => decided ?? link(code[base]);
|
|
10020
10929
|
const runnerBlock = (count, r0, r1, r2, r3, next) => {
|
|
10021
10930
|
if (count === 1) return (input, cur, ctx, values, inherited) => {
|
|
10022
10931
|
cur = r0(input, cur, ctx, inherited);
|
|
@@ -10062,7 +10971,7 @@ function assemble(t, prog, cfg) {
|
|
|
10062
10971
|
};
|
|
10063
10972
|
};
|
|
10064
10973
|
if (REC) {
|
|
10065
|
-
const first2 =
|
|
10974
|
+
const first2 = linkFirst();
|
|
10066
10975
|
const firstSync = sentinelFor(code[base + n]);
|
|
10067
10976
|
const runnerAt = (i) => {
|
|
10068
10977
|
const sync = sentinelFor(code[base + n + i]);
|
|
@@ -10098,13 +11007,13 @@ function assemble(t, prog, cfg) {
|
|
|
10098
11007
|
const bindRunners = (start) => {
|
|
10099
11008
|
const count = Math.min(4, n - start);
|
|
10100
11009
|
const at = (offset) => runnerAt(start + offset);
|
|
10101
|
-
const
|
|
11010
|
+
const never2 = () => -1;
|
|
10102
11011
|
return runnerBlock(
|
|
10103
11012
|
count,
|
|
10104
11013
|
at(0),
|
|
10105
|
-
count > 1 ? at(1) :
|
|
10106
|
-
count > 2 ? at(2) :
|
|
10107
|
-
count > 3 ? at(3) :
|
|
11014
|
+
count > 1 ? at(1) : never2,
|
|
11015
|
+
count > 2 ? at(2) : never2,
|
|
11016
|
+
count > 3 ? at(3) : never2,
|
|
10108
11017
|
start + count < n ? bindRunners(start + count) : void 0
|
|
10109
11018
|
);
|
|
10110
11019
|
};
|
|
@@ -10154,15 +11063,31 @@ function assemble(t, prog, cfg) {
|
|
|
10154
11063
|
let hasAdj = false;
|
|
10155
11064
|
for (let i = 1; i < n; i++) {
|
|
10156
11065
|
const kidIp = code[base + i];
|
|
10157
|
-
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp)) {
|
|
11066
|
+
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp) || holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
10158
11067
|
hasAdj = true;
|
|
10159
11068
|
break;
|
|
10160
11069
|
}
|
|
10161
11070
|
}
|
|
10162
11071
|
if (hasAdj) {
|
|
10163
|
-
const first2 =
|
|
11072
|
+
const first2 = linkFirst();
|
|
10164
11073
|
const runnerAt = (i) => {
|
|
10165
11074
|
const kidIp = code[base + i];
|
|
11075
|
+
if (holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
11076
|
+
const kid = link(kidIp);
|
|
11077
|
+
return (input, cur, ctx) => {
|
|
11078
|
+
if (ctx.trivia === void 0) {
|
|
11079
|
+
const v2 = kid(input, cur, ctx);
|
|
11080
|
+
if (v2 === FAIL) return -1;
|
|
11081
|
+
TERMV = v2;
|
|
11082
|
+
return EC.e;
|
|
11083
|
+
}
|
|
11084
|
+
const scanEnd = skipTrivia(input, cur, ctx);
|
|
11085
|
+
const v = kid(input, scanEnd, ctx);
|
|
11086
|
+
if (v === FAIL) return -1;
|
|
11087
|
+
TERMV = v;
|
|
11088
|
+
return scanEnd;
|
|
11089
|
+
};
|
|
11090
|
+
}
|
|
10166
11091
|
if (code[kidIp] !== OP_ADJ) {
|
|
10167
11092
|
const kid = link(kidIp);
|
|
10168
11093
|
if (leadingTriviaFieldAt(code, k, kidIp)) {
|
|
@@ -10187,13 +11112,13 @@ function assemble(t, prog, cfg) {
|
|
|
10187
11112
|
const bindRunners = (start) => {
|
|
10188
11113
|
const count = Math.min(4, n - start);
|
|
10189
11114
|
const at = (offset) => runnerAt(start + offset);
|
|
10190
|
-
const
|
|
11115
|
+
const never2 = () => -1;
|
|
10191
11116
|
return runnerBlock(
|
|
10192
11117
|
count,
|
|
10193
11118
|
at(0),
|
|
10194
|
-
count > 1 ? at(1) :
|
|
10195
|
-
count > 2 ? at(2) :
|
|
10196
|
-
count > 3 ? at(3) :
|
|
11119
|
+
count > 1 ? at(1) : never2,
|
|
11120
|
+
count > 2 ? at(2) : never2,
|
|
11121
|
+
count > 3 ? at(3) : never2,
|
|
10197
11122
|
start + count < n ? bindRunners(start + count) : void 0
|
|
10198
11123
|
);
|
|
10199
11124
|
};
|
|
@@ -10230,7 +11155,7 @@ function assemble(t, prog, cfg) {
|
|
|
10230
11155
|
};
|
|
10231
11156
|
}
|
|
10232
11157
|
if (n === 1) {
|
|
10233
|
-
const k0 =
|
|
11158
|
+
const k0 = linkFirst();
|
|
10234
11159
|
if (fused) {
|
|
10235
11160
|
return (input, pos, ctx) => {
|
|
10236
11161
|
const v = k0(input, pos, ctx);
|
|
@@ -10252,7 +11177,7 @@ function assemble(t, prog, cfg) {
|
|
|
10252
11177
|
};
|
|
10253
11178
|
}
|
|
10254
11179
|
if (n === 2) {
|
|
10255
|
-
const k0 =
|
|
11180
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]);
|
|
10256
11181
|
if (fused) {
|
|
10257
11182
|
return (input, pos, ctx) => {
|
|
10258
11183
|
const v0 = k0(input, pos, ctx);
|
|
@@ -10283,7 +11208,7 @@ function assemble(t, prog, cfg) {
|
|
|
10283
11208
|
};
|
|
10284
11209
|
}
|
|
10285
11210
|
if (n === 3) {
|
|
10286
|
-
const k0 =
|
|
11211
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]), k2 = link(code[base + 2]);
|
|
10287
11212
|
if (fused) {
|
|
10288
11213
|
return (input, pos, ctx) => {
|
|
10289
11214
|
const v0 = k0(input, pos, ctx);
|
|
@@ -10377,7 +11302,7 @@ function assemble(t, prog, cfg) {
|
|
|
10377
11302
|
start + count < n ? bind(start + count) : void 0
|
|
10378
11303
|
);
|
|
10379
11304
|
};
|
|
10380
|
-
const first =
|
|
11305
|
+
const first = linkFirst();
|
|
10381
11306
|
const tail = bind(1);
|
|
10382
11307
|
const runDirectTerms = (input, pos, ctx, values) => {
|
|
10383
11308
|
const v0 = first(input, pos, ctx);
|
|
@@ -10416,6 +11341,8 @@ function assemble(t, prog, cfg) {
|
|
|
10416
11341
|
const n = code[ip + 2];
|
|
10417
11342
|
const choiceFx = fx[code[ip + 3]];
|
|
10418
11343
|
const base = ip + 4;
|
|
11344
|
+
for (let i = 0; i < n; i++) link(code[base + i]);
|
|
11345
|
+
const armsClean = CLEAN(ip);
|
|
10419
11346
|
if (table.exclusive) {
|
|
10420
11347
|
const ascii = table.ascii;
|
|
10421
11348
|
const hi = table.hi;
|
|
@@ -10555,7 +11482,7 @@ function assemble(t, prog, cfg) {
|
|
|
10555
11482
|
if (n === 3) addGate(g2, 4);
|
|
10556
11483
|
return (input, pos, ctx) => {
|
|
10557
11484
|
const c = lead(input, pos);
|
|
10558
|
-
const need = markCst(ctx);
|
|
11485
|
+
const need = !armsClean && markCst(ctx);
|
|
10559
11486
|
const mRaw = MRAW;
|
|
10560
11487
|
const mTl = MTL;
|
|
10561
11488
|
const mLv = MLV;
|
|
@@ -10625,6 +11552,11 @@ function assemble(t, prog, cfg) {
|
|
|
10625
11552
|
}
|
|
10626
11553
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
10627
11554
|
}
|
|
11555
|
+
if (prev === 0) {
|
|
11556
|
+
ctx._fe = pos;
|
|
11557
|
+
ctx._fx = choiceFx;
|
|
11558
|
+
return FAIL;
|
|
11559
|
+
}
|
|
10628
11560
|
if (best === pos && prev < 1) acc = accSet(e0, acc);
|
|
10629
11561
|
if (best === pos && prev < 2) acc = accSet(e1, acc);
|
|
10630
11562
|
if (best === pos && n === 3 && prev < 3) acc = accSet(e2, acc);
|
|
@@ -10767,7 +11699,7 @@ function assemble(t, prog, cfg) {
|
|
|
10767
11699
|
if (pn !== 0) {
|
|
10768
11700
|
return (input, pos, ctx) => {
|
|
10769
11701
|
const c = lead(input, pos);
|
|
10770
|
-
const need = markCst(ctx);
|
|
11702
|
+
const need = !armsClean && markCst(ctx);
|
|
10771
11703
|
const mRaw = MRAW;
|
|
10772
11704
|
const mTl = MTL;
|
|
10773
11705
|
const mLv = MLV;
|
|
@@ -10824,7 +11756,7 @@ function assemble(t, prog, cfg) {
|
|
|
10824
11756
|
}
|
|
10825
11757
|
return (input, pos, ctx) => {
|
|
10826
11758
|
const c = lead(input, pos);
|
|
10827
|
-
const need = markCst(ctx);
|
|
11759
|
+
const need = !armsClean && markCst(ctx);
|
|
10828
11760
|
const mRaw = MRAW;
|
|
10829
11761
|
const mTl = MTL;
|
|
10830
11762
|
const mLv = MLV;
|
|
@@ -10872,7 +11804,7 @@ function assemble(t, prog, cfg) {
|
|
|
10872
11804
|
}
|
|
10873
11805
|
return (input, pos, ctx) => {
|
|
10874
11806
|
const c = lead(input, pos);
|
|
10875
|
-
const need = markCst(ctx);
|
|
11807
|
+
const need = !armsClean && markCst(ctx);
|
|
10876
11808
|
const mRaw = MRAW;
|
|
10877
11809
|
const mTl = MTL;
|
|
10878
11810
|
const mLv = MLV;
|
|
@@ -10926,6 +11858,21 @@ function assemble(t, prog, cfg) {
|
|
|
10926
11858
|
return lit(input, pos, ctx);
|
|
10927
11859
|
};
|
|
10928
11860
|
}
|
|
11861
|
+
case OP_RGATE: {
|
|
11862
|
+
const cls = cc[code[ip + 1]];
|
|
11863
|
+
const xf = fx[code[ip + 3]];
|
|
11864
|
+
const child = link(code[ip + 2]);
|
|
11865
|
+
if (cfg.tolerant || cfg.probe) return child;
|
|
11866
|
+
return (input, pos, ctx) => {
|
|
11867
|
+
const item = ctx._routed;
|
|
11868
|
+
if (item !== void 0 && item.span.start === pos && !classHas2(cls, lead(input, item.span.end))) {
|
|
11869
|
+
ctx._fe = item.span.end;
|
|
11870
|
+
ctx._fx = xf;
|
|
11871
|
+
return FAIL;
|
|
11872
|
+
}
|
|
11873
|
+
return child(input, pos, ctx);
|
|
11874
|
+
};
|
|
11875
|
+
}
|
|
10929
11876
|
case OP_ARMGATE: {
|
|
10930
11877
|
const pred = fns[code[ip + 1]];
|
|
10931
11878
|
const child = link(code[ip + 2]);
|
|
@@ -10933,7 +11880,7 @@ function assemble(t, prog, cfg) {
|
|
|
10933
11880
|
return (input, pos, ctx) => {
|
|
10934
11881
|
if (!pred(ctx.state)) {
|
|
10935
11882
|
ctx._fc = false;
|
|
10936
|
-
ctx._fe =
|
|
11883
|
+
ctx._fe = -1;
|
|
10937
11884
|
ctx._fx = xf;
|
|
10938
11885
|
return FAIL;
|
|
10939
11886
|
}
|
|
@@ -10994,6 +11941,7 @@ function assemble(t, prog, cfg) {
|
|
|
10994
11941
|
const itemClass = !REC && itemClassIndex >= 0 ? cc[itemClassIndex] : void 0;
|
|
10995
11942
|
const itemMayStart = itemClass === void 0 ? void 0 : (input, pos) => classHas2(itemClass, lead(input, pos));
|
|
10996
11943
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
11944
|
+
const itemClean = sepIp < 0 && CLEAN(code[ip + 1]) && !rowNullable(code, k, code[ip + 1], NULLABLE);
|
|
10997
11945
|
if (REC) {
|
|
10998
11946
|
const itemFx2 = fx[code[ip + 6]];
|
|
10999
11947
|
const sepSent = sentinelFor(code[ip + 7]);
|
|
@@ -11090,6 +12038,8 @@ function assemble(t, prog, cfg) {
|
|
|
11090
12038
|
const out = collect ? [] : void 0;
|
|
11091
12039
|
const hasTrivia = ctx.trivia !== void 0;
|
|
11092
12040
|
const needMark = rollbackNeeded(ctx);
|
|
12041
|
+
const markLater = needMark && (!itemClean || hasTrivia);
|
|
12042
|
+
const markFirst = needMark && (!itemClean || hasTrivia && skipBeforeFirst);
|
|
11093
12043
|
const gateItems = itemMayStart !== void 0 && ctx._probe === void 0;
|
|
11094
12044
|
let cur = pos;
|
|
11095
12045
|
let count = 0;
|
|
@@ -11097,14 +12047,15 @@ function assemble(t, prog, cfg) {
|
|
|
11097
12047
|
if (max >= 0 && count >= max) break;
|
|
11098
12048
|
if (sep !== void 0 && count > 0 && count >= min && cur >= input.length) break;
|
|
11099
12049
|
if (count >= min && sep === void 0 && !hasTrivia && gateItems && !itemMayStart(input, cur)) break;
|
|
11100
|
-
|
|
11101
|
-
|
|
11102
|
-
const
|
|
11103
|
-
const
|
|
11104
|
-
const
|
|
11105
|
-
const
|
|
11106
|
-
const
|
|
11107
|
-
const
|
|
12050
|
+
const markIt = count > 0 ? markLater : markFirst;
|
|
12051
|
+
if (markIt) markCst(ctx);
|
|
12052
|
+
const mRaw = markIt ? MRAW : 0;
|
|
12053
|
+
const mTl = markIt ? MTL : 0;
|
|
12054
|
+
const mLv = markIt ? MLV : 0;
|
|
12055
|
+
const mFl = markIt ? ctx._fields?.length ?? 0 : 0;
|
|
12056
|
+
const mEr = markIt ? ctx._errors?.length ?? 0 : 0;
|
|
12057
|
+
const mLog = markIt ? ctx._triviaLog?.length ?? 0 : 0;
|
|
12058
|
+
const mRoot = markIt ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
11108
12059
|
let itemStart = cur;
|
|
11109
12060
|
let sepEnd = -1;
|
|
11110
12061
|
const viaRepItem = sep === void 0 && count >= min && (count > 0 || skipBeforeFirst);
|
|
@@ -11116,7 +12067,7 @@ function assemble(t, prog, cfg) {
|
|
|
11116
12067
|
if (sepLeads) LEAD.at = cur;
|
|
11117
12068
|
const sv = sep(input, sp, ctx);
|
|
11118
12069
|
if (sv === FAIL) {
|
|
11119
|
-
if (
|
|
12070
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
11120
12071
|
if (committed3(ctx)) return FAIL;
|
|
11121
12072
|
break;
|
|
11122
12073
|
}
|
|
@@ -11127,25 +12078,25 @@ function assemble(t, prog, cfg) {
|
|
|
11127
12078
|
itemStart = skipTrivia(input, itemStart, ctx);
|
|
11128
12079
|
}
|
|
11129
12080
|
if (itemStart >= input.length && viaRepItem) {
|
|
11130
|
-
if (
|
|
12081
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
11131
12082
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
11132
12083
|
break;
|
|
11133
12084
|
}
|
|
11134
12085
|
if (count >= min && gateItems && !itemMayStart(input, itemStart)) {
|
|
11135
|
-
if (
|
|
12086
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
11136
12087
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
11137
12088
|
break;
|
|
11138
12089
|
}
|
|
11139
12090
|
ctx._fc = false;
|
|
11140
12091
|
const v = child(input, itemStart, ctx);
|
|
11141
12092
|
if (v === FAIL) {
|
|
11142
|
-
if (
|
|
12093
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
11143
12094
|
if (committed3(ctx)) return FAIL;
|
|
11144
12095
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
11145
12096
|
break;
|
|
11146
12097
|
}
|
|
11147
12098
|
if (EC.e === itemStart && viaRepItem) {
|
|
11148
|
-
if (
|
|
12099
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
11149
12100
|
break;
|
|
11150
12101
|
}
|
|
11151
12102
|
if (out !== void 0) out.push(v);
|
|
@@ -11219,7 +12170,14 @@ function assemble(t, prog, cfg) {
|
|
|
11219
12170
|
const runArm = n === 0 ? void 0 : bindArms(0);
|
|
11220
12171
|
const runOther = other === void 0 ? void 0 : dispatchBranch(other, otherRouted);
|
|
11221
12172
|
return (input, pos, ctx) => {
|
|
11222
|
-
const
|
|
12173
|
+
const need = markCst(ctx);
|
|
12174
|
+
const mRaw = MRAW;
|
|
12175
|
+
const mTl = MTL;
|
|
12176
|
+
const mLv = MLV;
|
|
12177
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
12178
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
12179
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
12180
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
11223
12181
|
const selVal = selector(input, pos, ctx);
|
|
11224
12182
|
if (selVal === FAIL) return FAIL;
|
|
11225
12183
|
const selEnd = EC.e;
|
|
@@ -11231,9 +12189,9 @@ function assemble(t, prog, cfg) {
|
|
|
11231
12189
|
ctx._fx = expected;
|
|
11232
12190
|
return FAIL;
|
|
11233
12191
|
}
|
|
11234
|
-
return runOther(input, pos, selEnd, key,
|
|
12192
|
+
return runOther(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
11235
12193
|
}
|
|
11236
|
-
return runArm(arm, input, pos, selEnd, key,
|
|
12194
|
+
return runArm(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
11237
12195
|
};
|
|
11238
12196
|
}
|
|
11239
12197
|
/* ── node ────────────────────────────────────────────────────────────── */
|
|
@@ -11256,9 +12214,9 @@ function assemble(t, prog, cfg) {
|
|
|
11256
12214
|
return FAIL;
|
|
11257
12215
|
}
|
|
11258
12216
|
const value = regexValue ? input.slice(pos, end) : spec;
|
|
11259
|
-
const
|
|
11260
|
-
const kids = [
|
|
11261
|
-
const rawKids = [
|
|
12217
|
+
const leaf2 = { _tag: "leaf", value, span: { start: pos, end } };
|
|
12218
|
+
const kids = [leaf2];
|
|
12219
|
+
const rawKids = [leaf2];
|
|
11262
12220
|
const span = { start: pos, end };
|
|
11263
12221
|
EC.e = end;
|
|
11264
12222
|
const nd = build2(kids, void 0, span, rawKids, EMPTY_TL, void 0);
|
|
@@ -11269,7 +12227,8 @@ function assemble(t, prog, cfg) {
|
|
|
11269
12227
|
return nd;
|
|
11270
12228
|
};
|
|
11271
12229
|
}
|
|
11272
|
-
const child = link(code[ip + 2]);
|
|
12230
|
+
const child = NODE_BODY ?? link(code[ip + 2]);
|
|
12231
|
+
NODE_BODY = void 0;
|
|
11273
12232
|
const proj = code[ip + 4];
|
|
11274
12233
|
const buildIdx = code[ip + 1];
|
|
11275
12234
|
const type = k[code[ip + 5]];
|
|
@@ -11293,6 +12252,30 @@ function assemble(t, prog, cfg) {
|
|
|
11293
12252
|
if (build !== void 0 && proj < 0 && flags === 18) {
|
|
11294
12253
|
return childrenOnlyFieldsBuildNode(child, build);
|
|
11295
12254
|
}
|
|
12255
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
12256
|
+
return passCollapseNode(child, build, flags === 32);
|
|
12257
|
+
}
|
|
12258
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
12259
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(closureLabels.at(code[ip + 2]).tri, trivia2);
|
|
12260
|
+
if (build !== void 0 && gated !== void 0 && triviaLead !== void 0) {
|
|
12261
|
+
const classic = flags === 32 ? collapseBuildNode(child, build) : childrenOnlyCollapseBuildNode(child, build);
|
|
12262
|
+
return gatedPassCollapseNode(
|
|
12263
|
+
[
|
|
12264
|
+
...gated.leads.map((g) => cc[code[g + 1]]),
|
|
12265
|
+
resolveClass(encodeClassSpec([
|
|
12266
|
+
...triviaLead,
|
|
12267
|
+
...gated.lits.map((i) => {
|
|
12268
|
+
const c = k[i].codePointAt(0);
|
|
12269
|
+
return { lo: c, hi: c };
|
|
12270
|
+
})
|
|
12271
|
+
]))
|
|
12272
|
+
],
|
|
12273
|
+
link(gated.last),
|
|
12274
|
+
classic,
|
|
12275
|
+
build,
|
|
12276
|
+
flags === 32
|
|
12277
|
+
);
|
|
12278
|
+
}
|
|
11296
12279
|
if (build !== void 0 && proj < 0 && flags === 32) {
|
|
11297
12280
|
return collapseBuildNode(child, build);
|
|
11298
12281
|
}
|
|
@@ -11339,7 +12322,7 @@ function assemble(t, prog, cfg) {
|
|
|
11339
12322
|
if (v === FAIL) return FAIL;
|
|
11340
12323
|
const end = EC.e;
|
|
11341
12324
|
const span = tracked ? spanLines(ctx, pos, end) : { start: pos, end };
|
|
11342
|
-
const st = readsState
|
|
12325
|
+
const st = readsState ? ctx.state : void 0;
|
|
11343
12326
|
let nd;
|
|
11344
12327
|
if (unwrap && kids.length === 1) {
|
|
11345
12328
|
nd = unwrapChild(kids[0]);
|
|
@@ -11352,10 +12335,10 @@ function assemble(t, prog, cfg) {
|
|
|
11352
12335
|
) {
|
|
11353
12336
|
nd = kids[0];
|
|
11354
12337
|
} else if (proj >= 0) {
|
|
11355
|
-
nd = hostCst && host !== void 0 ? host(type, kids, fieldMap, span, rawKids, tlog,
|
|
12338
|
+
nd = hostCst && host !== void 0 ? host(type, kids, fieldMap, span, rawKids, tlog, ctx.state, tags) : projectChild(kids, proj, type);
|
|
11356
12339
|
} else if (build !== void 0) {
|
|
11357
12340
|
if (hostCst && host !== void 0) {
|
|
11358
|
-
nd = host(type, kids, fieldMap, span, rawKids, tlog,
|
|
12341
|
+
nd = host(type, kids, fieldMap, span, rawKids, tlog, ctx.state, tags);
|
|
11359
12342
|
} else {
|
|
11360
12343
|
nd = build(kids, fieldMap, span, rawKids, captureWide ? tlog : EMPTY_TL, st);
|
|
11361
12344
|
}
|
|
@@ -11406,9 +12389,7 @@ function assemble(t, prog, cfg) {
|
|
|
11406
12389
|
let emitRefusal;
|
|
11407
12390
|
let emitReached;
|
|
11408
12391
|
{
|
|
11409
|
-
const extraIps =
|
|
11410
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) extraIps.push(r[0]);
|
|
11411
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
12392
|
+
const extraIps = assemblyExtraIps(prog);
|
|
11412
12393
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
11413
12394
|
for (const ip of reachableSites(code, roots)) {
|
|
11414
12395
|
if (code[ip] === OP_DISPATCH) {
|
|
@@ -11443,6 +12424,8 @@ function assemble(t, prog, cfg) {
|
|
|
11443
12424
|
}
|
|
11444
12425
|
const notChild = scalarTerminalNotChild(code, ip);
|
|
11445
12426
|
if (notChild >= 0) scalarFor(notChild);
|
|
12427
|
+
const peekChild = scalarTerminalPeekChild(code, ip);
|
|
12428
|
+
if (peekChild >= 0) scalarFor(peekChild);
|
|
11446
12429
|
}
|
|
11447
12430
|
const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
|
|
11448
12431
|
if (pre !== void 0) {
|
|
@@ -11501,9 +12484,12 @@ function assemble(t, prog, cfg) {
|
|
|
11501
12484
|
adjacencyHolds,
|
|
11502
12485
|
t.lexPrograms,
|
|
11503
12486
|
LEAD,
|
|
11504
|
-
triviaFieldCapture
|
|
12487
|
+
triviaFieldCapture,
|
|
12488
|
+
skipDeferredTrivia,
|
|
12489
|
+
collapseEmpty
|
|
11505
12490
|
);
|
|
11506
12491
|
emitReached = new Set(pre.reached);
|
|
12492
|
+
if (emitted.ext !== void 0) HYBRID = emitted;
|
|
11507
12493
|
}
|
|
11508
12494
|
try {
|
|
11509
12495
|
if (emitted !== void 0) throw new ServedByBuild();
|
|
@@ -11585,7 +12571,9 @@ function assemble(t, prog, cfg) {
|
|
|
11585
12571
|
adjacencyHolds,
|
|
11586
12572
|
t.lexPrograms,
|
|
11587
12573
|
LEAD,
|
|
11588
|
-
triviaFieldCapture
|
|
12574
|
+
triviaFieldCapture,
|
|
12575
|
+
skipDeferredTrivia,
|
|
12576
|
+
collapseEmpty
|
|
11589
12577
|
);
|
|
11590
12578
|
emitReached = em.reached;
|
|
11591
12579
|
} catch (e) {
|
|
@@ -11596,7 +12584,7 @@ function assemble(t, prog, cfg) {
|
|
|
11596
12584
|
}
|
|
11597
12585
|
function pieceAt(ip) {
|
|
11598
12586
|
const em = emitted;
|
|
11599
|
-
if (em !== void 0) {
|
|
12587
|
+
if (em !== void 0 && HYBRID === void 0) {
|
|
11600
12588
|
const p = em.byIp[ip];
|
|
11601
12589
|
if (p === void 0) throw new Error(`table emitter: no emitted body for site ${ip}`);
|
|
11602
12590
|
return p;
|
|
@@ -11626,6 +12614,37 @@ function assemble(t, prog, cfg) {
|
|
|
11626
12614
|
}
|
|
11627
12615
|
const scans = scansArr;
|
|
11628
12616
|
const scanSkip = (prog.scanSkip ?? []).map((set) => set.map((r) => subtreeComb(r)));
|
|
12617
|
+
if (HYBRID !== void 0) {
|
|
12618
|
+
const em = HYBRID;
|
|
12619
|
+
em.bind(
|
|
12620
|
+
(s) => {
|
|
12621
|
+
const saved = SCAN;
|
|
12622
|
+
SCAN = s;
|
|
12623
|
+
return saved;
|
|
12624
|
+
},
|
|
12625
|
+
em.ext.map((ip) => link(ip))
|
|
12626
|
+
);
|
|
12627
|
+
const pieces2 = {};
|
|
12628
|
+
for (const [name, entryIp] of Object.entries(prog.rules)) {
|
|
12629
|
+
pieces2[name] = em.pieces[name] ?? link(entryIp);
|
|
12630
|
+
}
|
|
12631
|
+
for (const ip of emitReached) reached.add(ip);
|
|
12632
|
+
return {
|
|
12633
|
+
pieces: pieces2,
|
|
12634
|
+
end: () => EC.e,
|
|
12635
|
+
begin: (ctx) => {
|
|
12636
|
+
begin(ctx);
|
|
12637
|
+
em.begin(ctx);
|
|
12638
|
+
},
|
|
12639
|
+
finish: () => {
|
|
12640
|
+
em.finish();
|
|
12641
|
+
finish();
|
|
12642
|
+
},
|
|
12643
|
+
scanSkip,
|
|
12644
|
+
reached,
|
|
12645
|
+
emitRefusal: void 0
|
|
12646
|
+
};
|
|
12647
|
+
}
|
|
11629
12648
|
if (emitted !== void 0) {
|
|
11630
12649
|
const em = emitted;
|
|
11631
12650
|
return {
|
|
@@ -11661,6 +12680,15 @@ function assemble(t, prog, cfg) {
|
|
|
11661
12680
|
}
|
|
11662
12681
|
return { pieces, end: () => EC.e, begin, finish, scanSkip, reached, emitRefusal };
|
|
11663
12682
|
}
|
|
12683
|
+
var SITE_COUNTS;
|
|
12684
|
+
function countedPiece(piece, ip) {
|
|
12685
|
+
const counts = SITE_COUNTS;
|
|
12686
|
+
if (counts === void 0) return piece;
|
|
12687
|
+
return (input, pos, ctx) => {
|
|
12688
|
+
counts[ip]++;
|
|
12689
|
+
return piece(input, pos, ctx);
|
|
12690
|
+
};
|
|
12691
|
+
}
|
|
11664
12692
|
var AssemblyCache = class {
|
|
11665
12693
|
t;
|
|
11666
12694
|
prog;
|
|
@@ -11803,6 +12831,172 @@ function tableRules(source, metadataOrEntry = {}) {
|
|
|
11803
12831
|
return map[entry];
|
|
11804
12832
|
}
|
|
11805
12833
|
|
|
12834
|
+
// src/combinators/grammar.ts
|
|
12835
|
+
function annotateResultLines(result, index) {
|
|
12836
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
12837
|
+
const errors = annotated.errors;
|
|
12838
|
+
if (errors) {
|
|
12839
|
+
;
|
|
12840
|
+
annotated.errors = errors.map((error) => ({
|
|
12841
|
+
...error,
|
|
12842
|
+
span: annotateSpan(error.span, index)
|
|
12843
|
+
}));
|
|
12844
|
+
}
|
|
12845
|
+
return annotated;
|
|
12846
|
+
}
|
|
12847
|
+
function createParseLineContext(input, pos) {
|
|
12848
|
+
const lineIndex = createLineIndex();
|
|
12849
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
12850
|
+
return { lineIndex, lineScannedTo: pos };
|
|
12851
|
+
}
|
|
12852
|
+
var TRACK_LINES_ON = () => true;
|
|
12853
|
+
var TRACK_LINES_OFF = () => false;
|
|
12854
|
+
var TRACK_LINES_INHERIT = (ctx) => ctx?.trackLines === true;
|
|
12855
|
+
function parser(opts, root) {
|
|
12856
|
+
const clearTrivia = opts.trivia === null;
|
|
12857
|
+
const opaqueRootCapture = opts.rootCapture === "opaque";
|
|
12858
|
+
if (opaqueRootCapture && opts.trivia === void 0) {
|
|
12859
|
+
throw new TypeError("parser({ rootCapture: 'opaque' }) requires an explicit trivia scope.");
|
|
12860
|
+
}
|
|
12861
|
+
const scopeTrivia = clearTrivia ? void 0 : opts.trivia ?? void 0;
|
|
12862
|
+
const scopeLabels = scopeTrivia?._meta?.triviaKindLabels;
|
|
12863
|
+
const refuseUnclassified = scopeTrivia !== void 0 && !scopeTrivia._meta?.rootTriviaClassified && !opaqueRootCapture;
|
|
12864
|
+
const forceCaptureTrivia = opts.captureTrivia === true;
|
|
12865
|
+
const trackLinesPolicy = opts.trackLines === true ? "on" : opts.trackLines === false ? "off" : "inherit";
|
|
12866
|
+
const trackLinesOf = trackLinesPolicy === "on" ? TRACK_LINES_ON : trackLinesPolicy === "off" ? TRACK_LINES_OFF : TRACK_LINES_INHERIT;
|
|
12867
|
+
const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
|
|
12868
|
+
const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
|
|
12869
|
+
const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
|
|
12870
|
+
const rootScalar = scalarOf(root);
|
|
12871
|
+
const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
|
|
12872
|
+
const parseScalar = scalarEligible ? (input, pos, ctx) => {
|
|
12873
|
+
const savedTrivia = ctx.trivia;
|
|
12874
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
12875
|
+
if (clearTrivia) {
|
|
12876
|
+
ctx.trivia = void 0;
|
|
12877
|
+
ctx.triviaKindLabels = void 0;
|
|
12878
|
+
} else if (scopeTrivia !== void 0) {
|
|
12879
|
+
ctx.trivia = scopeTrivia;
|
|
12880
|
+
ctx.triviaKindLabels = scopeLabels;
|
|
12881
|
+
}
|
|
12882
|
+
const end = rootScalar(input, pos, ctx);
|
|
12883
|
+
ctx.trivia = savedTrivia;
|
|
12884
|
+
ctx.triviaKindLabels = savedLabels;
|
|
12885
|
+
return end;
|
|
12886
|
+
} : void 0;
|
|
12887
|
+
let publicScalar;
|
|
12888
|
+
const grammar = {
|
|
12889
|
+
_tag: "grammar",
|
|
12890
|
+
_meta: {
|
|
12891
|
+
...root._meta,
|
|
12892
|
+
// Trivia classification describes this grammar's own active trivia
|
|
12893
|
+
// scope. A directly nested grammar may have classified trivia of its
|
|
12894
|
+
// own, but that must not advertise classification for this wrapper.
|
|
12895
|
+
triviaKindLabels: void 0,
|
|
12896
|
+
rootTriviaClassified: void 0,
|
|
12897
|
+
...opts.trivia?._meta?.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {},
|
|
12898
|
+
...opts.trivia?._meta?.rootTriviaClassified ? { rootTriviaClassified: true } : {}
|
|
12899
|
+
},
|
|
12900
|
+
_def: {
|
|
12901
|
+
tag: "grammar",
|
|
12902
|
+
parser: root,
|
|
12903
|
+
triviaParser: scopeTrivia,
|
|
12904
|
+
clearTrivia,
|
|
12905
|
+
...opaqueRootCapture ? { rootCapture: "opaque" } : {},
|
|
12906
|
+
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
12907
|
+
trackLines: opts.trackLines ?? false,
|
|
12908
|
+
constructionTrackLines: trackLinesPolicy,
|
|
12909
|
+
...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
|
|
12910
|
+
},
|
|
12911
|
+
_parseScalar: parseScalar,
|
|
12912
|
+
parse(input, pos, _ctx) {
|
|
12913
|
+
if (pos === void 0 && _ctx === void 0) {
|
|
12914
|
+
publicScalar ??= scalarRootOf(grammar) ?? null;
|
|
12915
|
+
if (publicScalar) {
|
|
12916
|
+
const ctx2 = createParseContext();
|
|
12917
|
+
const end = publicScalar(input, 0, ctx2);
|
|
12918
|
+
if (end < 0) {
|
|
12919
|
+
const at = ~end;
|
|
12920
|
+
return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
|
|
12921
|
+
}
|
|
12922
|
+
return { ok: true, value: ctx2._sv, span: { start: 0, end } };
|
|
12923
|
+
}
|
|
12924
|
+
}
|
|
12925
|
+
if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
|
|
12926
|
+
const trackLines = trackLinesOf(_ctx);
|
|
12927
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
12928
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
12929
|
+
const ctx = _ctx === void 0 ? createParseContext() : { ..._ctx };
|
|
12930
|
+
ctx.trackLines = trackLines;
|
|
12931
|
+
if (lineIndex) ctx._lineIndex = lineIndex;
|
|
12932
|
+
if (lineContext) ctx._lineScannedTo = lineContext.lineScannedTo;
|
|
12933
|
+
if (clearTrivia) {
|
|
12934
|
+
ctx.trivia = void 0;
|
|
12935
|
+
ctx.triviaKindLabels = void 0;
|
|
12936
|
+
} else if (scopeTrivia !== void 0) {
|
|
12937
|
+
ctx.trivia = scopeTrivia;
|
|
12938
|
+
if (scopeLabels) ctx.triviaKindLabels = scopeLabels;
|
|
12939
|
+
}
|
|
12940
|
+
if (forceCaptureTrivia || _ctx?.captureTrivia) ctx.captureTrivia = true;
|
|
12941
|
+
if (ownCaptureMask !== void 0) ctx._triviaCaptureMask = ownCaptureMask;
|
|
12942
|
+
else if (inheritCaptureMask) ctx._triviaCaptureMask = triviaKindMask(_ctx?.triviaKindLabels, captureKinds);
|
|
12943
|
+
if (opaqueRootCapture) ctx._rootTriviaCapture = false;
|
|
12944
|
+
const result = root.parse(input, pos ?? 0, ctx);
|
|
12945
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
12946
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
12947
|
+
}
|
|
12948
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
12949
|
+
}
|
|
12950
|
+
};
|
|
12951
|
+
return grammar;
|
|
12952
|
+
}
|
|
12953
|
+
function noTrivia(root) {
|
|
12954
|
+
return parser({ trivia: null }, root);
|
|
12955
|
+
}
|
|
12956
|
+
|
|
12957
|
+
// src/combinators/attempt.ts
|
|
12958
|
+
function containOption(options) {
|
|
12959
|
+
if (options === void 0) return false;
|
|
12960
|
+
for (const key of Object.keys(options)) {
|
|
12961
|
+
if (key !== "contain") throw new TypeError(`attempt(): unknown option ${JSON.stringify(key)}`);
|
|
12962
|
+
}
|
|
12963
|
+
if (options.contain !== void 0 && typeof options.contain !== "boolean") {
|
|
12964
|
+
throw new TypeError("attempt(): `contain` must be a boolean");
|
|
12965
|
+
}
|
|
12966
|
+
return options.contain === true;
|
|
12967
|
+
}
|
|
12968
|
+
function attempt(parser2, options) {
|
|
12969
|
+
const contain = containOption(options);
|
|
12970
|
+
const guardable = parser2._meta.firstSet.kind !== "any" && !matchesEmpty(parser2);
|
|
12971
|
+
let failExpected;
|
|
12972
|
+
return {
|
|
12973
|
+
_tag: "attempt",
|
|
12974
|
+
_meta: parser2._meta,
|
|
12975
|
+
_def: contain ? { tag: "attempt", parser: parser2, contain: true } : { tag: "attempt", parser: parser2 },
|
|
12976
|
+
parse(input, pos, ctx) {
|
|
12977
|
+
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(parser2, input, pos)) {
|
|
12978
|
+
if (failExpected === void 0) {
|
|
12979
|
+
const e = deriveExpected(parser2);
|
|
12980
|
+
failExpected = e.length > 0 ? e : [parser2._tag];
|
|
12981
|
+
}
|
|
12982
|
+
return { ok: false, expected: failExpected, span: { start: pos, end: pos } };
|
|
12983
|
+
}
|
|
12984
|
+
const mark = saveCstMark(ctx);
|
|
12985
|
+
const log = ctx._triviaLog?.length;
|
|
12986
|
+
const rootLog = ctx._rootTriviaLog?.length;
|
|
12987
|
+
const split = ctx._columnsSplit;
|
|
12988
|
+
const result = parser2.parse(input, pos, ctx);
|
|
12989
|
+
if (result.ok) return result;
|
|
12990
|
+
rollbackCstCapture(ctx, mark);
|
|
12991
|
+
ctx._columnsSplit = split;
|
|
12992
|
+
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
12993
|
+
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
12994
|
+
if (result.committed && !contain) return result;
|
|
12995
|
+
return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
|
|
12996
|
+
}
|
|
12997
|
+
};
|
|
12998
|
+
}
|
|
12999
|
+
|
|
11806
13000
|
// src/analysis/gating.ts
|
|
11807
13001
|
function childrenOf(d) {
|
|
11808
13002
|
switch (d.tag) {
|
|
@@ -12270,6 +13464,111 @@ function reachesMarked(root, successors, memo) {
|
|
|
12270
13464
|
return found[visit(root)];
|
|
12271
13465
|
}
|
|
12272
13466
|
|
|
13467
|
+
// src/table/factor-choice.ts
|
|
13468
|
+
var DERIVED = /* @__PURE__ */ new Set(["_tag", "_meta", "_def", "_parseScalar", "_stickyRegex", "parse"]);
|
|
13469
|
+
function isCombinator(v) {
|
|
13470
|
+
return typeof v === "object" && v !== null && "_def" in v && "_meta" in v;
|
|
13471
|
+
}
|
|
13472
|
+
function sameComb(a, b, depth) {
|
|
13473
|
+
if (a === b) return true;
|
|
13474
|
+
if (depth > 32 || a._tag !== b._tag) return false;
|
|
13475
|
+
for (const k of Object.keys(a)) if (!DERIVED.has(k)) return false;
|
|
13476
|
+
for (const k of Object.keys(b)) if (!DERIVED.has(k)) return false;
|
|
13477
|
+
return sameFields(a._def, b._def, depth, void 0);
|
|
13478
|
+
}
|
|
13479
|
+
function sameValue(u, v, depth) {
|
|
13480
|
+
if (u === v) return true;
|
|
13481
|
+
if (isCombinator(u) && isCombinator(v)) return sameComb(u, v, depth + 1);
|
|
13482
|
+
if (Array.isArray(u) && Array.isArray(v)) return u.length === v.length && u.every((x, i) => sameValue(x, v[i], depth));
|
|
13483
|
+
if (typeof u === "object" && u !== null && typeof v === "object" && v !== null && Object.getPrototypeOf(u) === Object.prototype && Object.getPrototypeOf(v) === Object.prototype) {
|
|
13484
|
+
return sameFields(u, v, depth, void 0);
|
|
13485
|
+
}
|
|
13486
|
+
return false;
|
|
13487
|
+
}
|
|
13488
|
+
function sameFields(x, y, depth, skip) {
|
|
13489
|
+
const kx = Object.keys(x).filter((k) => k !== skip && x[k] !== void 0);
|
|
13490
|
+
const ky = Object.keys(y).filter((k) => k !== skip && y[k] !== void 0);
|
|
13491
|
+
if (kx.length !== ky.length) return false;
|
|
13492
|
+
for (const k of kx) {
|
|
13493
|
+
if (!(k in y)) return false;
|
|
13494
|
+
const u = x[k];
|
|
13495
|
+
const v = y[k];
|
|
13496
|
+
if (k === "fn" && typeof u === "function" && typeof v === "function" && u !== v) {
|
|
13497
|
+
if (typeof x.fnSrc !== "string" || x.fnSrc === "" || x.fnSrc !== y.fnSrc) return false;
|
|
13498
|
+
continue;
|
|
13499
|
+
}
|
|
13500
|
+
if (!sameValue(u, v, depth)) return false;
|
|
13501
|
+
}
|
|
13502
|
+
return true;
|
|
13503
|
+
}
|
|
13504
|
+
function rewrap(w, body) {
|
|
13505
|
+
const d = w._def;
|
|
13506
|
+
let out;
|
|
13507
|
+
if (d.tag === "leaf") {
|
|
13508
|
+
out = d.cstValue === "source" ? sourceLeaf(body, d.fn) : leaf(body, d.fn);
|
|
13509
|
+
if (d.fnSrc !== void 0) out._def.fnSrc = d.fnSrc;
|
|
13510
|
+
} else if (d.tag === "grammar") {
|
|
13511
|
+
out = d.clearTrivia === true ? noTrivia(body) : parser({ trivia: d.triviaParser ?? null }, body);
|
|
13512
|
+
} else return void 0;
|
|
13513
|
+
return sameFields(d, out._def, 0, "parser") ? out : void 0;
|
|
13514
|
+
}
|
|
13515
|
+
function unusedOf(seq) {
|
|
13516
|
+
return seq._def.tag === "sequence" && seq._def.valueUnused === true;
|
|
13517
|
+
}
|
|
13518
|
+
function never(c) {
|
|
13519
|
+
const t = c._def.tag;
|
|
13520
|
+
return t === "optional" || t === "many";
|
|
13521
|
+
}
|
|
13522
|
+
function factorSharedEnds(d) {
|
|
13523
|
+
const arms = d.parsers;
|
|
13524
|
+
if (arms.length < 2) return void 0;
|
|
13525
|
+
if (d.strategy.tag !== "firstMatch" && d.strategy.tag !== "sharedPrefix") return void 0;
|
|
13526
|
+
if (d.gates.some((g) => g !== null) || d.autoNot.some((a) => a !== null)) return void 0;
|
|
13527
|
+
const shapes = [];
|
|
13528
|
+
for (const arm of arms) {
|
|
13529
|
+
const wrappers = [];
|
|
13530
|
+
let c = arm;
|
|
13531
|
+
while ((c._def.tag === "leaf" || c._def.tag === "grammar") && wrappers.length < 4) {
|
|
13532
|
+
wrappers.push(c);
|
|
13533
|
+
c = c._def.parser;
|
|
13534
|
+
}
|
|
13535
|
+
if (c._def.tag !== "sequence" || c._def.parsers.length < 2) return void 0;
|
|
13536
|
+
shapes.push({ wrappers, terms: c._def.parsers, seq: c });
|
|
13537
|
+
}
|
|
13538
|
+
const first = shapes[0];
|
|
13539
|
+
const n = first.terms.length;
|
|
13540
|
+
for (const s of shapes) {
|
|
13541
|
+
if (s.wrappers.length !== first.wrappers.length || s.terms.length !== n) return void 0;
|
|
13542
|
+
if (unusedOf(s.seq) !== unusedOf(first.seq)) return void 0;
|
|
13543
|
+
for (let j = 0; j < s.wrappers.length; j++) {
|
|
13544
|
+
const a = first.wrappers[j]._def;
|
|
13545
|
+
const b = s.wrappers[j]._def;
|
|
13546
|
+
if (a.tag !== b.tag || !sameFields(a, b, 0, "parser")) return void 0;
|
|
13547
|
+
}
|
|
13548
|
+
}
|
|
13549
|
+
let at = -1;
|
|
13550
|
+
for (let i = 0; i < n; i++) {
|
|
13551
|
+
if (shapes.every((s) => sameComb(s.terms[i], first.terms[i], 0))) continue;
|
|
13552
|
+
if (at >= 0) return void 0;
|
|
13553
|
+
at = i;
|
|
13554
|
+
}
|
|
13555
|
+
if (at < 0) return void 0;
|
|
13556
|
+
for (let i = at + 1; i < n; i++) if (!never(first.terms[i])) return void 0;
|
|
13557
|
+
if (arms.some((a) => mayCommitFailure(a))) return void 0;
|
|
13558
|
+
const middle = choice(...shapes.map((s) => s.terms[at]));
|
|
13559
|
+
if (middle._def.tag === "choice" && middle._def.autoNot.some((a) => a !== null)) return void 0;
|
|
13560
|
+
const st = middle._def.tag === "choice" ? middle._def.strategy : void 0;
|
|
13561
|
+
if (st === void 0 || st.tag !== "firstMatch" && st.tag !== "sharedPrefix" && !(st.tag === "literalsLongestFirst" && st.sortedIndices.every((x, i) => x === i))) return void 0;
|
|
13562
|
+
let out = sequence(
|
|
13563
|
+
...[...first.terms.slice(0, at), middle, ...first.terms.slice(at + 1)]
|
|
13564
|
+
);
|
|
13565
|
+
if (unusedOf(first.seq)) {
|
|
13566
|
+
out._def.valueUnused = true;
|
|
13567
|
+
}
|
|
13568
|
+
for (let j = first.wrappers.length - 1; j >= 0 && out !== void 0; j--) out = rewrap(first.wrappers[j], out);
|
|
13569
|
+
return out === void 0 ? void 0 : attempt(out);
|
|
13570
|
+
}
|
|
13571
|
+
|
|
12273
13572
|
// src/compiler/direct-projection.ts
|
|
12274
13573
|
function directArrayProjection(fn, fnSrc, arity) {
|
|
12275
13574
|
let source = fnSrc;
|
|
@@ -12330,8 +13629,11 @@ function selectOptionalSuffixLexBody(ir) {
|
|
|
12330
13629
|
const token2 = { strategy: "token", estimatedOps: 2, body };
|
|
12331
13630
|
return token2.estimatedOps < character.estimatedOps ? token2 : character;
|
|
12332
13631
|
}
|
|
12333
|
-
function
|
|
12334
|
-
|
|
13632
|
+
function reinstallsRuleTrivia(reference, target) {
|
|
13633
|
+
return (reference._meta.grammarTrivia ?? target._meta.grammarTrivia) !== void 0 && hasOwnTriviaBoundary(target);
|
|
13634
|
+
}
|
|
13635
|
+
function directTokenBodyParser(parser2, resolve, scope) {
|
|
13636
|
+
const outer = parser2._def;
|
|
12335
13637
|
if (outer.tag !== "token") return void 0;
|
|
12336
13638
|
let body = outer.parser;
|
|
12337
13639
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -12340,12 +13642,13 @@ function directTokenBodyParser(parser, resolve) {
|
|
|
12340
13642
|
const wrapper = body._def;
|
|
12341
13643
|
if (wrapper.tag === "grammar") {
|
|
12342
13644
|
if (wrapper.clearTrivia !== true || wrapper.triviaParser !== void 0 || wrapper.captureTrivia === true || wrapper.rootCapture === "opaque" || wrapper.constructionTrackLines !== "inherit" || wrapper.constructionCaptureTriviaKinds !== void 0) return void 0;
|
|
13645
|
+
if (scope !== void 0) scope.cleared = true;
|
|
12343
13646
|
body = wrapper.parser;
|
|
12344
13647
|
continue;
|
|
12345
13648
|
}
|
|
12346
13649
|
if (wrapper.tag === "lazy") {
|
|
12347
13650
|
const target = resolvedLazyTarget(body, resolve);
|
|
12348
|
-
if (target === void 0) return void 0;
|
|
13651
|
+
if (target === void 0 || reinstallsRuleTrivia(body, target)) return void 0;
|
|
12349
13652
|
body = target;
|
|
12350
13653
|
continue;
|
|
12351
13654
|
}
|
|
@@ -12353,8 +13656,8 @@ function directTokenBodyParser(parser, resolve) {
|
|
|
12353
13656
|
}
|
|
12354
13657
|
return void 0;
|
|
12355
13658
|
}
|
|
12356
|
-
function directOptionalSuffixTokenBody(
|
|
12357
|
-
const inner = directTokenBodyParser(
|
|
13659
|
+
function directOptionalSuffixTokenBody(parser2, resolve) {
|
|
13660
|
+
const inner = directTokenBodyParser(parser2, resolve);
|
|
12358
13661
|
if (inner === void 0) return void 0;
|
|
12359
13662
|
const sequence6 = inner._def;
|
|
12360
13663
|
if (sequence6.tag !== "sequence" || sequence6.parsers.length !== 2) return void 0;
|
|
@@ -12390,10 +13693,10 @@ function directOptionalSuffixTokenBody(parser, resolve) {
|
|
|
12390
13693
|
expected: directTerminalFailureExpected(base)
|
|
12391
13694
|
} : void 0;
|
|
12392
13695
|
}
|
|
12393
|
-
function directTerminalTokenBody(
|
|
12394
|
-
const outer =
|
|
13696
|
+
function directTerminalTokenBody(parser2, resolve) {
|
|
13697
|
+
const outer = parser2._def;
|
|
12395
13698
|
if (outer.tag !== "token") return void 0;
|
|
12396
|
-
const body = directTokenBodyParser(
|
|
13699
|
+
const body = directTokenBodyParser(parser2, resolve);
|
|
12397
13700
|
if (body === void 0) return void 0;
|
|
12398
13701
|
const def = body._def;
|
|
12399
13702
|
if (def.tag === "regex") return {
|
|
@@ -12413,28 +13716,28 @@ function directTerminalTokenBody(parser, resolve) {
|
|
|
12413
13716
|
expected: directTerminalFailureExpected(def)
|
|
12414
13717
|
};
|
|
12415
13718
|
}
|
|
12416
|
-
function directTerminalParser(
|
|
13719
|
+
function directTerminalParser(parser2, resolve) {
|
|
12417
13720
|
const seen = /* @__PURE__ */ new Set();
|
|
12418
|
-
while (!seen.has(
|
|
12419
|
-
seen.add(
|
|
12420
|
-
const def =
|
|
13721
|
+
while (!seen.has(parser2)) {
|
|
13722
|
+
seen.add(parser2);
|
|
13723
|
+
const def = parser2._def;
|
|
12421
13724
|
if (def.tag === "lazy") {
|
|
12422
|
-
const target = resolvedLazyTarget(
|
|
13725
|
+
const target = resolvedLazyTarget(parser2, resolve);
|
|
12423
13726
|
if (target === void 0) return void 0;
|
|
12424
|
-
|
|
13727
|
+
parser2 = target;
|
|
12425
13728
|
continue;
|
|
12426
13729
|
}
|
|
12427
13730
|
if (def.tag === "token") {
|
|
12428
|
-
|
|
13731
|
+
parser2 = def.parser;
|
|
12429
13732
|
continue;
|
|
12430
13733
|
}
|
|
12431
13734
|
if (def.tag === "grammar") return void 0;
|
|
12432
|
-
return
|
|
13735
|
+
return parser2;
|
|
12433
13736
|
}
|
|
12434
13737
|
return void 0;
|
|
12435
13738
|
}
|
|
12436
|
-
function directTerminalLexBody(
|
|
12437
|
-
const terminal = directTerminalParser(
|
|
13739
|
+
function directTerminalLexBody(parser2, resolve) {
|
|
13740
|
+
const terminal = directTerminalParser(parser2, resolve);
|
|
12438
13741
|
if (terminal === void 0) return void 0;
|
|
12439
13742
|
const def = terminal._def;
|
|
12440
13743
|
if (def.tag === "literal") {
|
|
@@ -12465,8 +13768,8 @@ function directTerminalLexBody(parser, resolve) {
|
|
|
12465
13768
|
expected: directTerminalFailureExpected(def)
|
|
12466
13769
|
};
|
|
12467
13770
|
}
|
|
12468
|
-
function directOrdered4TokenBody(
|
|
12469
|
-
const body = directTokenBodyParser(
|
|
13771
|
+
function directOrdered4TokenBody(parser2, resolve) {
|
|
13772
|
+
const body = directTokenBodyParser(parser2, resolve);
|
|
12470
13773
|
return body === void 0 ? void 0 : directOrdered4Body(body, resolve);
|
|
12471
13774
|
}
|
|
12472
13775
|
function directOrdered4Body(body, resolve) {
|
|
@@ -12494,8 +13797,8 @@ function directOrdered4Body(body, resolve) {
|
|
|
12494
13797
|
arms
|
|
12495
13798
|
};
|
|
12496
13799
|
}
|
|
12497
|
-
function directNot2TokenBody(
|
|
12498
|
-
const body = directTokenBodyParser(
|
|
13800
|
+
function directNot2TokenBody(parser2, resolve) {
|
|
13801
|
+
const body = directTokenBodyParser(parser2, resolve);
|
|
12499
13802
|
const sequence6 = body?._def;
|
|
12500
13803
|
if (sequence6?.tag !== "sequence" || sequence6.parsers.length !== 3) return void 0;
|
|
12501
13804
|
const [guard0Parser, guard1Parser, terminalParser] = sequence6.parsers;
|
|
@@ -12517,15 +13820,15 @@ function directNot2TokenBody(parser, resolve) {
|
|
|
12517
13820
|
terminal
|
|
12518
13821
|
};
|
|
12519
13822
|
}
|
|
12520
|
-
function directFixedLexNode(
|
|
12521
|
-
let current =
|
|
13823
|
+
function directFixedLexNode(parser2, resolve, active, pureOnly = false, cleared = false) {
|
|
13824
|
+
let current = parser2;
|
|
12522
13825
|
const wrappers = /* @__PURE__ */ new Set();
|
|
12523
13826
|
while (!wrappers.has(current)) {
|
|
12524
13827
|
wrappers.add(current);
|
|
12525
13828
|
const def = current._def;
|
|
12526
13829
|
if (def.tag === "lazy") {
|
|
12527
13830
|
const target = resolvedLazyTarget(current, resolve);
|
|
12528
|
-
if (target === void 0) return void 0;
|
|
13831
|
+
if (target === void 0 || reinstallsRuleTrivia(current, target)) return void 0;
|
|
12529
13832
|
current = target;
|
|
12530
13833
|
continue;
|
|
12531
13834
|
}
|
|
@@ -12535,7 +13838,7 @@ function directFixedLexNode(parser, resolve, active, pureOnly = false) {
|
|
|
12535
13838
|
}
|
|
12536
13839
|
break;
|
|
12537
13840
|
}
|
|
12538
|
-
if (wrappers.has(current) && current !==
|
|
13841
|
+
if (wrappers.has(current) && current !== parser2 && current._def.tag === "lazy") return void 0;
|
|
12539
13842
|
if (active.has(current)) return void 0;
|
|
12540
13843
|
active.add(current);
|
|
12541
13844
|
try {
|
|
@@ -12543,30 +13846,33 @@ function directFixedLexNode(parser, resolve, active, pureOnly = false) {
|
|
|
12543
13846
|
if (terminal !== void 0) return { kind: "terminal", terminal };
|
|
12544
13847
|
const def = current._def;
|
|
12545
13848
|
if (def.tag === "grammar") {
|
|
13849
|
+
if (def.triviaParser === void 0 && def.captureTrivia !== true && def.rootCapture !== "opaque" && def.constructionCaptureTriviaKinds === void 0) {
|
|
13850
|
+
return directFixedLexNode(def.parser, resolve, active, pureOnly, cleared || def.clearTrivia === true);
|
|
13851
|
+
}
|
|
12546
13852
|
if (!pureOnly || def.parser._def.tag !== "token" && (def.clearTrivia !== true || def.triviaParser !== void 0 || def.captureTrivia === true || def.rootCapture === "opaque")) return void 0;
|
|
12547
|
-
return directFixedLexNode(def.parser, resolve, active, true);
|
|
13853
|
+
return directFixedLexNode(def.parser, resolve, active, true, cleared);
|
|
12548
13854
|
}
|
|
12549
13855
|
if (def.tag === "sequence") {
|
|
12550
13856
|
if (def.parsers.length < 2 || def.parsers.length > 5) return void 0;
|
|
12551
|
-
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve, active, pureOnly));
|
|
13857
|
+
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve, active, pureOnly, cleared));
|
|
12552
13858
|
if (parts.some((part) => part === void 0)) return void 0;
|
|
12553
13859
|
return { kind: "sequence", parts };
|
|
12554
13860
|
}
|
|
12555
13861
|
if (def.tag === "choice") {
|
|
12556
|
-
if (def.parsers.length
|
|
12557
|
-
const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve, active, pureOnly));
|
|
13862
|
+
if (def.parsers.length < 2 || def.strategy.tag !== "firstMatch" || def.gates.some((gate) => gate !== null) || def.autoNot.some((check) => check !== null)) return void 0;
|
|
13863
|
+
const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve, active, pureOnly, cleared));
|
|
12558
13864
|
if (arms.some((arm) => arm === void 0)) return void 0;
|
|
12559
|
-
const final = classifyFinalChoice(def.parsers, resolve);
|
|
12560
13865
|
return {
|
|
12561
13866
|
kind: "choice",
|
|
12562
13867
|
arms,
|
|
12563
|
-
|
|
13868
|
+
parsers: def.parsers,
|
|
13869
|
+
cleared,
|
|
12564
13870
|
armExpected: def.parsers.map(deriveExpected),
|
|
12565
13871
|
expected: def.parsers.flatMap(deriveExpected)
|
|
12566
13872
|
};
|
|
12567
13873
|
}
|
|
12568
13874
|
if (def.tag === "not") {
|
|
12569
|
-
const body = directFixedLexNode(def.parser, resolve, active, true);
|
|
13875
|
+
const body = directFixedLexNode(def.parser, resolve, active, true, cleared);
|
|
12570
13876
|
return body === void 0 ? void 0 : {
|
|
12571
13877
|
kind: "not",
|
|
12572
13878
|
body,
|
|
@@ -12574,23 +13880,33 @@ function directFixedLexNode(parser, resolve, active, pureOnly = false) {
|
|
|
12574
13880
|
};
|
|
12575
13881
|
}
|
|
12576
13882
|
if (def.tag === "optional") {
|
|
12577
|
-
const body = directFixedLexNode(def.parser, resolve, active, pureOnly);
|
|
13883
|
+
const body = directFixedLexNode(def.parser, resolve, active, pureOnly, cleared);
|
|
12578
13884
|
return body === void 0 ? void 0 : { kind: "optional", body };
|
|
12579
13885
|
}
|
|
13886
|
+
if (def.tag === "many" || def.tag === "oneOrMore") {
|
|
13887
|
+
const body = directFixedLexNode(def.parser, resolve, active, pureOnly, cleared);
|
|
13888
|
+
return body === void 0 ? void 0 : {
|
|
13889
|
+
kind: "repeat",
|
|
13890
|
+
body,
|
|
13891
|
+
min: def.tag === "many" ? 0 : def.min,
|
|
13892
|
+
max: def.max ?? -1
|
|
13893
|
+
};
|
|
13894
|
+
}
|
|
12580
13895
|
return void 0;
|
|
12581
13896
|
} finally {
|
|
12582
13897
|
active.delete(current);
|
|
12583
13898
|
}
|
|
12584
13899
|
}
|
|
12585
|
-
function directFixedTokenBody(
|
|
12586
|
-
const
|
|
13900
|
+
function directFixedTokenBody(parser2, resolve) {
|
|
13901
|
+
const scope = { cleared: false };
|
|
13902
|
+
const body = directTokenBodyParser(parser2, resolve, scope);
|
|
12587
13903
|
if (body === void 0) return void 0;
|
|
12588
|
-
const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set());
|
|
13904
|
+
const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set(), false, scope.cleared);
|
|
12589
13905
|
return root === void 0 ? void 0 : { kind: "fixed-tree", root };
|
|
12590
13906
|
}
|
|
12591
|
-
function directBalancedTokenBody(
|
|
12592
|
-
if (directTokenBodyParser(
|
|
12593
|
-
const spec = balancedSpecOf(
|
|
13907
|
+
function directBalancedTokenBody(parser2, resolve) {
|
|
13908
|
+
if (directTokenBodyParser(parser2, resolve) === void 0) return void 0;
|
|
13909
|
+
const spec = balancedSpecOf(parser2);
|
|
12594
13910
|
return spec === void 0 ? void 0 : {
|
|
12595
13911
|
kind: "balanced-scan",
|
|
12596
13912
|
open: spec.open,
|
|
@@ -12600,8 +13916,8 @@ function directBalancedTokenBody(parser, resolve) {
|
|
|
12600
13916
|
ownSkip: spec.ownSkip
|
|
12601
13917
|
};
|
|
12602
13918
|
}
|
|
12603
|
-
function directExecutableTokenBody(
|
|
12604
|
-
return directOptionalSuffixTokenBody(
|
|
13919
|
+
function directExecutableTokenBody(parser2, resolve) {
|
|
13920
|
+
return directOptionalSuffixTokenBody(parser2, resolve) ?? directTerminalTokenBody(parser2, resolve) ?? directOrdered4TokenBody(parser2, resolve) ?? directNot2TokenBody(parser2, resolve) ?? directBalancedTokenBody(parser2, resolve) ?? directFixedTokenBody(parser2, resolve);
|
|
12605
13921
|
}
|
|
12606
13922
|
function winnerWrapsReference(winner, reference) {
|
|
12607
13923
|
let current = winner;
|
|
@@ -12615,13 +13931,13 @@ function winnerWrapsReference(winner, reference) {
|
|
|
12615
13931
|
}
|
|
12616
13932
|
return false;
|
|
12617
13933
|
}
|
|
12618
|
-
function resolvedLazyTarget(
|
|
12619
|
-
const def =
|
|
13934
|
+
function resolvedLazyTarget(parser2, resolve) {
|
|
13935
|
+
const def = parser2._def;
|
|
12620
13936
|
if (def.tag !== "lazy") return void 0;
|
|
12621
|
-
const name =
|
|
13937
|
+
const name = parser2._ruleName;
|
|
12622
13938
|
if (name !== void 0 && resolve !== void 0) {
|
|
12623
13939
|
const winner = resolve(name);
|
|
12624
|
-
if (winner !== void 0 && !winnerWrapsReference(winner,
|
|
13940
|
+
if (winner !== void 0 && !winnerWrapsReference(winner, parser2)) return winner;
|
|
12625
13941
|
}
|
|
12626
13942
|
try {
|
|
12627
13943
|
return def.thunk();
|
|
@@ -12629,8 +13945,8 @@ function resolvedLazyTarget(parser, resolve) {
|
|
|
12629
13945
|
return void 0;
|
|
12630
13946
|
}
|
|
12631
13947
|
}
|
|
12632
|
-
function balancedSpecOf(
|
|
12633
|
-
let current =
|
|
13948
|
+
function balancedSpecOf(parser2) {
|
|
13949
|
+
let current = parser2;
|
|
12634
13950
|
let spec = current._balancedSpec;
|
|
12635
13951
|
const seen = /* @__PURE__ */ new Set();
|
|
12636
13952
|
while (spec === void 0 && current._def.tag === "token" && !seen.has(current)) {
|
|
@@ -12832,13 +14148,16 @@ var Encoder = class {
|
|
|
12832
14148
|
}
|
|
12833
14149
|
case "choice": {
|
|
12834
14150
|
for (const arm of node.arms) if (!emitNode(arm)) return false;
|
|
12835
|
-
const
|
|
12836
|
-
|
|
12837
|
-
|
|
14151
|
+
const final = classifyFinalChoice(
|
|
14152
|
+
node.parsers,
|
|
14153
|
+
this.refResolver(),
|
|
14154
|
+
node.cleared ? void 0 : this.activeTrivia
|
|
14155
|
+
);
|
|
14156
|
+
const classes = final.firstSets.map((first, i) => final.nullable[i] ? -1 : this.charClass(first));
|
|
14157
|
+
const exclusive = final.exclusive && classes.every((cls) => cls >= 0);
|
|
14158
|
+
words.push(LEX_NODE_CHOICE, node.arms.length, exclusive ? 1 : 0, this.expected(node.expected));
|
|
12838
14159
|
for (let i = 0; i < node.arms.length; i++) {
|
|
12839
|
-
|
|
12840
|
-
words.push(first.kind === "ranges" ? this.charClass(first) : -1);
|
|
12841
|
-
words.push(this.expected(node.armExpected[i]));
|
|
14160
|
+
words.push(classes[i], this.expected(node.armExpected[i]));
|
|
12842
14161
|
}
|
|
12843
14162
|
return true;
|
|
12844
14163
|
}
|
|
@@ -12850,6 +14169,10 @@ var Encoder = class {
|
|
|
12850
14169
|
if (!emitNode(node.body)) return false;
|
|
12851
14170
|
words.push(LEX_NODE_OPTIONAL);
|
|
12852
14171
|
return true;
|
|
14172
|
+
case "repeat":
|
|
14173
|
+
if (!emitNode(node.body)) return false;
|
|
14174
|
+
words.push(LEX_NODE_REPEAT, node.min, node.max);
|
|
14175
|
+
return true;
|
|
12853
14176
|
}
|
|
12854
14177
|
};
|
|
12855
14178
|
if (!emitNode(body.root)) return void 0;
|
|
@@ -13177,6 +14500,33 @@ var Encoder = class {
|
|
|
13177
14500
|
return childrenOf(def);
|
|
13178
14501
|
}
|
|
13179
14502
|
}
|
|
14503
|
+
/**
|
|
14504
|
+
* THE FIRST-CHARACTER GATE OF AN `optional`, `not` OR `peek` CHILD.
|
|
14505
|
+
*
|
|
14506
|
+
* A non-nullable child cannot match at a character outside its first set, so
|
|
14507
|
+
* the wrapper's outcome there is already decided: `optional` yields `null`,
|
|
14508
|
+
* `not` succeeds, `peek` fails with its own set. The interpreter's `optional`
|
|
14509
|
+
* makes that test itself (`repeat.ts` `startsFirstSet`); the table entered the
|
|
14510
|
+
* child — a rollback mark, the call, the child's own failure — to learn it.
|
|
14511
|
+
*
|
|
14512
|
+
* The gate is an `OP_GATE` row around the child, so every engine runs it
|
|
14513
|
+
* unchanged, a probe or tolerant parse forwards through it as for a node's
|
|
14514
|
+
* gate, and the wrapper's row keeps its layout. The engines test the class
|
|
14515
|
+
* before taking the wrapper's mark. The first set is resolved through
|
|
14516
|
+
* `winners`, the analysis a choice arm's gate uses, so a composed rule's set
|
|
14517
|
+
* is the merged one. A scalar `not` child stays bare: `scalarTerminalNotChild`
|
|
14518
|
+
* already reduces it to one recognizer call.
|
|
14519
|
+
*/
|
|
14520
|
+
lookaheadGate(p, child) {
|
|
14521
|
+
const op = this.code[child];
|
|
14522
|
+
if (op === OP_GATE || op === OP_LIT || op === OP_LIT_CI || op === OP_LIT_TRACK || op === OP_LIT_CI_TRACK || op === OP_RX || op === OP_RX_TRACK) return child;
|
|
14523
|
+
const rr = this.refResolver();
|
|
14524
|
+
if (matchesEmpty(p, /* @__PURE__ */ new Set(), rr)) return child;
|
|
14525
|
+
const cls = this.charClass(firstSetOf(p, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
14526
|
+
if (cls < 0) return child;
|
|
14527
|
+
const e = deriveExpected(p);
|
|
14528
|
+
return this.emit(OP_GATE, cls, child, this.expected(e.length > 0 ? e : [p._tag]));
|
|
14529
|
+
}
|
|
13180
14530
|
/** A first set becomes a char class string, or −1 for `any`. */
|
|
13181
14531
|
charClass(fs) {
|
|
13182
14532
|
if (fs.kind !== "ranges" || fs.ranges.length === 0) return -1;
|
|
@@ -13188,12 +14538,19 @@ var Encoder = class {
|
|
|
13188
14538
|
this.ccIndex.set(spec, i);
|
|
13189
14539
|
return i;
|
|
13190
14540
|
}
|
|
13191
|
-
/**
|
|
13192
|
-
*
|
|
13193
|
-
|
|
13194
|
-
|
|
13195
|
-
|
|
13196
|
-
|
|
14541
|
+
/**
|
|
14542
|
+
* The first set a node's or an attempt's fail-fast gate tests. A bare
|
|
14543
|
+
* cross-rule ref resolves through `winners` (a compose OVERRIDE may widen
|
|
14544
|
+
* it). Any other body keeps its construction-time `_meta.firstSet`, except
|
|
14545
|
+
* where that is `any`: under `compose()` a body that reaches a rule of
|
|
14546
|
+
* another piece is built before that rule exists, so its cached set is
|
|
14547
|
+
* `any` and the node got NO gate (jess's `CompoundSelector` was entered at
|
|
14548
|
+
* `{`, `Call` at `}`). The resolved set is the one a choice arm's gate uses,
|
|
14549
|
+
* over the final merged map.
|
|
14550
|
+
*/
|
|
14551
|
+
gateFirstSet(p) {
|
|
14552
|
+
const cached = p._meta.firstSet;
|
|
14553
|
+
return p._def.tag === "lazy" || cached.kind === "any" ? firstSetOf(p, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : cached;
|
|
13197
14554
|
}
|
|
13198
14555
|
/**
|
|
13199
14556
|
* Wrap one choice arm in its `autoNot` checks (`OP_REJECT`).
|
|
@@ -13321,6 +14678,50 @@ var Encoder = class {
|
|
|
13321
14678
|
if (!hasOwnTriviaBoundary(target)) return ip;
|
|
13322
14679
|
return this.emit(OP_SCOPE_PLAIN, this.triviaSlot(amb), ip);
|
|
13323
14680
|
}
|
|
14681
|
+
/**
|
|
14682
|
+
* The `OP_RGATE` operands of a choice arm that opens with `routed()`, or
|
|
14683
|
+
* `undefined`. Through `node()`/scope wrappers and first sequence terms, the
|
|
14684
|
+
* arm's next term after the routed token is found; the gate is that term's
|
|
14685
|
+
* first characters, with the trivia in force at the boundary before it, so
|
|
14686
|
+
* the arm is entered only where it can get past the token. The term must be
|
|
14687
|
+
* unable to match empty or to commit, so a miss is exactly that term failing
|
|
14688
|
+
* at the token's end with its own set.
|
|
14689
|
+
*/
|
|
14690
|
+
routedArmGate(arm) {
|
|
14691
|
+
const walk = (p, trivia2, depth) => {
|
|
14692
|
+
if (depth > 16) return void 0;
|
|
14693
|
+
const d = p._def;
|
|
14694
|
+
switch (d.tag) {
|
|
14695
|
+
case "routed":
|
|
14696
|
+
return "end";
|
|
14697
|
+
case "node":
|
|
14698
|
+
return walk(d.parser, trivia2, depth + 1);
|
|
14699
|
+
case "grammar":
|
|
14700
|
+
return walk(d.parser, d.clearTrivia === true ? void 0 : d.triviaParser ?? trivia2, depth + 1);
|
|
14701
|
+
case "sequence": {
|
|
14702
|
+
const head = d.parsers[0];
|
|
14703
|
+
if (head === void 0) return void 0;
|
|
14704
|
+
const r = walk(head, trivia2, depth + 1);
|
|
14705
|
+
if (r !== "end") return r;
|
|
14706
|
+
const next2 = d.parsers[1];
|
|
14707
|
+
return next2 === void 0 ? "end" : { next: next2, boundary: trivia2 };
|
|
14708
|
+
}
|
|
14709
|
+
default:
|
|
14710
|
+
return void 0;
|
|
14711
|
+
}
|
|
14712
|
+
};
|
|
14713
|
+
const follow = walk(arm, this.activeTrivia, 0);
|
|
14714
|
+
if (follow === void 0 || follow === "end") return void 0;
|
|
14715
|
+
const rr = this.refResolver();
|
|
14716
|
+
const { next, boundary } = follow;
|
|
14717
|
+
if (matchesEmpty(next, /* @__PURE__ */ new Set(), rr) || mayCommitFailure(next, rr, this.commitFailureMemo)) return void 0;
|
|
14718
|
+
const nextTag = next._def.tag;
|
|
14719
|
+
if (nextTag !== "literal" && nextTag !== "regex" && nextTag !== "keywords" && nextTag !== "label") return void 0;
|
|
14720
|
+
const first = firstSetOf(next, /* @__PURE__ */ new Set(), rr, boundary);
|
|
14721
|
+
const cls = this.charClass(boundary === void 0 ? first : union(first, firstSetOf(boundary, /* @__PURE__ */ new Set(), rr)));
|
|
14722
|
+
if (cls < 0) return void 0;
|
|
14723
|
+
return { cls, fx: this.expected(deriveExpected(next)) };
|
|
14724
|
+
}
|
|
13324
14725
|
node(p) {
|
|
13325
14726
|
const lazyRef = p._def.tag === "lazy";
|
|
13326
14727
|
const scopeKey = lazyRef ? this.activeTrivia : void 0;
|
|
@@ -13445,6 +14846,10 @@ var Encoder = class {
|
|
|
13445
14846
|
return head;
|
|
13446
14847
|
}
|
|
13447
14848
|
case "choice": {
|
|
14849
|
+
if (this.plan === void 0) {
|
|
14850
|
+
const factored = factorSharedEnds(d);
|
|
14851
|
+
if (factored !== void 0) return this.node(factored).ip;
|
|
14852
|
+
}
|
|
13448
14853
|
if (d.strategy.tag === "greedyClassify") {
|
|
13449
14854
|
const superIndex = d.strategy.superIndex;
|
|
13450
14855
|
const sup = this.node(d.parsers[superIndex]).ip;
|
|
@@ -13468,9 +14873,12 @@ var Encoder = class {
|
|
|
13468
14873
|
const kids = arms.map((c, k) => {
|
|
13469
14874
|
const src = order[k];
|
|
13470
14875
|
const checks = d.autoNot[src];
|
|
13471
|
-
const inner = this.node(c).ip;
|
|
13472
|
-
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
13473
14876
|
const gate = d.gates[src];
|
|
14877
|
+
const plain = (checks === null || checks === void 0 || checks.length === 0) && (gate === null || gate === void 0);
|
|
14878
|
+
const routedGate = plain ? this.routedArmGate(c) : void 0;
|
|
14879
|
+
const body = this.node(c).ip;
|
|
14880
|
+
const inner = routedGate === void 0 ? body : this.emit(OP_RGATE, routedGate.cls, body, routedGate.fx);
|
|
14881
|
+
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
13474
14882
|
const gated = gate === null || gate === void 0 ? ip : this.emit(OP_ARMGATE, this.fn(gate, d.gateSrcs?.[src] ?? null), ip, this.expected(deriveExpected(c)));
|
|
13475
14883
|
return this.covWrap(gated, armCovIds?.[src], 1);
|
|
13476
14884
|
});
|
|
@@ -13498,6 +14906,12 @@ var Encoder = class {
|
|
|
13498
14906
|
if (transactionalFirst[i] !== void 0) classes[i] = -1;
|
|
13499
14907
|
}
|
|
13500
14908
|
}
|
|
14909
|
+
if (d.gates.some((g) => g !== null && g !== void 0) && !dispatchIsExclusive(classes, this.cc)) {
|
|
14910
|
+
for (let k = 0; k < classes.length; k++) {
|
|
14911
|
+
const gate = d.gates[order[k]];
|
|
14912
|
+
if (gate !== null && gate !== void 0) classes[k] = -1;
|
|
14913
|
+
}
|
|
14914
|
+
}
|
|
13501
14915
|
const dispIdx = this.disp.length;
|
|
13502
14916
|
this.disp.push(classes);
|
|
13503
14917
|
let rollbackMask = kids.length > 31 ? -1 : 0;
|
|
@@ -13527,7 +14941,7 @@ var Encoder = class {
|
|
|
13527
14941
|
case "oneOrMore": {
|
|
13528
14942
|
const child = this.node(d.parser).ip;
|
|
13529
14943
|
const rr = this.refResolver();
|
|
13530
|
-
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.
|
|
14944
|
+
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.charClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
13531
14945
|
const op = d.valueUnused ? OP_REPV : OP_REP;
|
|
13532
14946
|
const min = d.tag === "many" ? 0 : d.min;
|
|
13533
14947
|
return this.rec ? this.emit(op, child, min, d.max ?? -1, -1, 0, this.expected(deriveExpected(d.parser)), itemClass) : this.emit(op, child, min, d.max ?? -1, -1, 0);
|
|
@@ -13551,7 +14965,7 @@ var Encoder = class {
|
|
|
13551
14965
|
return d.min >= 2 ? this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags, this.expected(deriveExpected(d.parser))) : this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags);
|
|
13552
14966
|
}
|
|
13553
14967
|
case "optional": {
|
|
13554
|
-
const head = this.emit(OP_OPT, this.node(d.parser).ip);
|
|
14968
|
+
const head = this.emit(OP_OPT, this.lookaheadGate(d.parser, this.node(d.parser).ip));
|
|
13555
14969
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(head);
|
|
13556
14970
|
return head;
|
|
13557
14971
|
}
|
|
@@ -13599,8 +15013,8 @@ var Encoder = class {
|
|
|
13599
15013
|
// every CST node, so this is load-bearing, not reflection trivia.
|
|
13600
15014
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
13601
15015
|
);
|
|
13602
|
-
if (matchesEmpty(d.parser)) return body;
|
|
13603
|
-
const fs =
|
|
15016
|
+
if (matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return body;
|
|
15017
|
+
const fs = this.gateFirstSet(d.parser);
|
|
13604
15018
|
if (fs.kind === "any") return body;
|
|
13605
15019
|
const cls = this.charClass(fs);
|
|
13606
15020
|
if (cls < 0) return body;
|
|
@@ -13692,7 +15106,7 @@ var Encoder = class {
|
|
|
13692
15106
|
// other engine reported `['not(literal)']`. It hid because `expected` is a
|
|
13693
15107
|
// TOP-LEVEL field on `RunResult` and is NOT part of the identity digest.
|
|
13694
15108
|
case "not":
|
|
13695
|
-
return this.emit(OP_NOT, this.node(d.parser).ip, this.expected(assertionFailureExpected(false, d.parser._tag)));
|
|
15109
|
+
return this.emit(OP_NOT, this.lookaheadGate(d.parser, this.node(d.parser).ip), this.expected(assertionFailureExpected(false, d.parser._tag)));
|
|
13696
15110
|
case "guard":
|
|
13697
15111
|
return this.emit(OP_GUARD, this.fn(d.predicate, d.predSrc ?? null), this.expected(["gate"]));
|
|
13698
15112
|
case "adjacency":
|
|
@@ -13713,14 +15127,14 @@ var Encoder = class {
|
|
|
13713
15127
|
return this.emit(OP_WITHCTX, this.constant(d.extra), this.node(d.parser).ip);
|
|
13714
15128
|
}
|
|
13715
15129
|
case "peek":
|
|
13716
|
-
return this.emit(OP_PEEK, this.node(d.parser).ip, this.expected(assertionFailureExpected(true, d.parser._tag)));
|
|
15130
|
+
return this.emit(OP_PEEK, this.lookaheadGate(d.parser, this.node(d.parser).ip), this.expected(assertionFailureExpected(true, d.parser._tag)));
|
|
13717
15131
|
// A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
|
|
13718
15132
|
// lowering was correct only for a choice arm.
|
|
13719
15133
|
case "attempt": {
|
|
13720
15134
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
|
|
13721
15135
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
13722
|
-
const fs =
|
|
13723
|
-
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
15136
|
+
const fs = this.gateFirstSet(d.parser);
|
|
15137
|
+
if (fs.kind === "any" || matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return inner;
|
|
13724
15138
|
const cls = this.charClass(fs);
|
|
13725
15139
|
if (cls < 0) return inner;
|
|
13726
15140
|
const e = deriveExpected(d.parser);
|
|
@@ -13788,6 +15202,7 @@ var Encoder = class {
|
|
|
13788
15202
|
const slots = (ip) => {
|
|
13789
15203
|
switch (this.code[ip]) {
|
|
13790
15204
|
case OP_GATE:
|
|
15205
|
+
case OP_RGATE:
|
|
13791
15206
|
return [ip + 2];
|
|
13792
15207
|
case OP_RULE:
|
|
13793
15208
|
case OP_OPT:
|
|
@@ -13958,7 +15373,7 @@ function emitClassPool(classes) {
|
|
|
13958
15373
|
if (classes.length < 2) return array;
|
|
13959
15374
|
const delimiter = "|/~?^`".split("").find((ch2) => classes.every((spec) => !spec.includes(ch2)));
|
|
13960
15375
|
if (delimiter === void 0) return array;
|
|
13961
|
-
const split =
|
|
15376
|
+
const split = `/* @__PURE__ */ ${jsString(classes.join(delimiter))}.split(${jsString(delimiter)})`;
|
|
13962
15377
|
return split.length < array.length ? split : array;
|
|
13963
15378
|
}
|
|
13964
15379
|
function emitConst(v) {
|
|
@@ -14020,9 +15435,7 @@ function defaultAssemblyCfgs(prog) {
|
|
|
14020
15435
|
function emitAssemblies(prog, cfgs) {
|
|
14021
15436
|
if (cfgs.length === 0) return ["a:[],"];
|
|
14022
15437
|
const t = resolveTable(prog);
|
|
14023
|
-
const extraIps =
|
|
14024
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) extraIps.push(r[0]);
|
|
14025
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
15438
|
+
const extraIps = assemblyExtraIps(prog);
|
|
14026
15439
|
const out = [];
|
|
14027
15440
|
const seen = /* @__PURE__ */ new Set();
|
|
14028
15441
|
for (const cfg of cfgs) {
|
|
@@ -14031,7 +15444,7 @@ function emitAssemblies(prog, cfgs) {
|
|
|
14031
15444
|
seen.add(key);
|
|
14032
15445
|
let em;
|
|
14033
15446
|
try {
|
|
14034
|
-
em = emitAssemblySource(t, prog, cfg, extraIps, true);
|
|
15447
|
+
em = emitAssemblySource(t, prog, cfg, extraIps, true, cfg.select);
|
|
14035
15448
|
} catch (e) {
|
|
14036
15449
|
if (e instanceof Unemittable) continue;
|
|
14037
15450
|
throw e;
|
|
@@ -14243,12 +15656,12 @@ function buildGrammarPlan(entry, winners) {
|
|
|
14243
15656
|
}
|
|
14244
15657
|
}
|
|
14245
15658
|
}
|
|
14246
|
-
const selfWinnerBody = (
|
|
14247
|
-
if (
|
|
14248
|
-
const name = winnerNames.get(
|
|
14249
|
-
if (name === void 0 || winners[name] !==
|
|
15659
|
+
const selfWinnerBody = (parser2) => {
|
|
15660
|
+
if (parser2._def.tag !== "lazy" || winners === void 0) return void 0;
|
|
15661
|
+
const name = winnerNames.get(parser2);
|
|
15662
|
+
if (name === void 0 || winners[name] !== parser2) return void 0;
|
|
14250
15663
|
try {
|
|
14251
|
-
return
|
|
15664
|
+
return parser2._def.thunk();
|
|
14252
15665
|
} catch {
|
|
14253
15666
|
return void 0;
|
|
14254
15667
|
}
|
|
@@ -14260,39 +15673,39 @@ function buildGrammarPlan(entry, winners) {
|
|
|
14260
15673
|
if (body !== void 0) slotsPerBody.set(body, (slotsPerBody.get(body) ?? 0) + 1);
|
|
14261
15674
|
}
|
|
14262
15675
|
}
|
|
14263
|
-
const sharedBody = (
|
|
14264
|
-
const ownRule = (
|
|
15676
|
+
const sharedBody = (parser2) => (slotsPerBody.get(parser2) ?? 0) > 1;
|
|
15677
|
+
const ownRule = (parser2, rule) => {
|
|
14265
15678
|
const id = `rule:${rule}`;
|
|
14266
15679
|
definitions.set(id, { id, kind: "rule" });
|
|
14267
|
-
rules.set(
|
|
15680
|
+
rules.set(parser2, id);
|
|
14268
15681
|
};
|
|
14269
15682
|
const seen = /* @__PURE__ */ new Set();
|
|
14270
|
-
const visit = (
|
|
14271
|
-
if (seen.has(
|
|
14272
|
-
seen.add(
|
|
14273
|
-
const rule = winnerNames.get(
|
|
14274
|
-
const body = selfWinnerBody(
|
|
14275
|
-
if (rule && body === void 0 && !sharedBody(
|
|
14276
|
-
ownRule(
|
|
14277
|
-
}
|
|
14278
|
-
if (rule && body !== void 0 && sharedBody(body)) ownRule(
|
|
14279
|
-
if (
|
|
14280
|
-
const ids =
|
|
14281
|
-
choices.set(
|
|
15683
|
+
const visit = (parser2, path) => {
|
|
15684
|
+
if (seen.has(parser2)) return;
|
|
15685
|
+
seen.add(parser2);
|
|
15686
|
+
const rule = winnerNames.get(parser2) ?? parser2._ruleName;
|
|
15687
|
+
const body = selfWinnerBody(parser2);
|
|
15688
|
+
if (rule && body === void 0 && !sharedBody(parser2) && (winnerNames.has(parser2) || parser2._def.tag !== "lazy")) {
|
|
15689
|
+
ownRule(parser2, rule);
|
|
15690
|
+
}
|
|
15691
|
+
if (rule && body !== void 0 && sharedBody(body)) ownRule(parser2, rule);
|
|
15692
|
+
if (parser2._def.tag === "choice") {
|
|
15693
|
+
const ids = parser2._def.parsers.map((_, index) => `choice:${path}/arm:${index}`);
|
|
15694
|
+
choices.set(parser2, ids);
|
|
14282
15695
|
ids.forEach((id) => definitions.set(id, { id, kind: "choice-arm" }));
|
|
14283
15696
|
}
|
|
14284
|
-
if (
|
|
14285
|
-
const ids = dispatchArmIds(
|
|
14286
|
-
dispatches.set(
|
|
15697
|
+
if (parser2._def.tag === "dispatch") {
|
|
15698
|
+
const ids = dispatchArmIds(parser2._def, path);
|
|
15699
|
+
dispatches.set(parser2, ids);
|
|
14287
15700
|
ids.forEach((id) => definitions.set(id, { id, kind: "dispatch-arm" }));
|
|
14288
15701
|
}
|
|
14289
|
-
if (
|
|
14290
|
-
if (
|
|
15702
|
+
if (parser2._def.tag === "attempt") attempts.set(parser2, `attempt:${path}`);
|
|
15703
|
+
if (parser2._def.tag === "label") {
|
|
14291
15704
|
const id = `label:${path}`;
|
|
14292
|
-
labels.set(
|
|
15705
|
+
labels.set(parser2, [id]);
|
|
14293
15706
|
definitions.set(id, { id, kind: "label" });
|
|
14294
15707
|
}
|
|
14295
|
-
children(
|
|
15708
|
+
children(parser2._def, winners).forEach((child, index) => visit(child, `${path}/${parser2._def.tag}:${index}`));
|
|
14296
15709
|
};
|
|
14297
15710
|
const roots = Array.isArray(entry) ? entry : [entry];
|
|
14298
15711
|
for (const root of roots) {
|
|
@@ -15686,10 +17099,10 @@ function addNode(out, def) {
|
|
|
15686
17099
|
if (!existing.includes(tag)) existing.push(tag);
|
|
15687
17100
|
}
|
|
15688
17101
|
}
|
|
15689
|
-
function collectFromCombinator(
|
|
15690
|
-
if (seen.has(
|
|
15691
|
-
seen.add(
|
|
15692
|
-
const def =
|
|
17102
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
17103
|
+
if (seen.has(parser2)) return;
|
|
17104
|
+
seen.add(parser2);
|
|
17105
|
+
const def = parser2._def;
|
|
15693
17106
|
if (def.tag === "lazy") {
|
|
15694
17107
|
if (followLazy) {
|
|
15695
17108
|
try {
|
|
@@ -15720,8 +17133,46 @@ function collectGrammarReflection(ruleMap, opts) {
|
|
|
15720
17133
|
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
15721
17134
|
}
|
|
15722
17135
|
|
|
17136
|
+
// src/table/select-hot.ts
|
|
17137
|
+
var LOOP = 8;
|
|
17138
|
+
var ROUNDS = 60;
|
|
17139
|
+
var CAP = 1e12;
|
|
17140
|
+
function selectHotSites(code, entries, siteBytes, budget, profile) {
|
|
17141
|
+
const selected = /* @__PURE__ */ new Set();
|
|
17142
|
+
if (budget <= 0) return selected;
|
|
17143
|
+
const weight = profile === void 0 ? staticWeights(code, entries) : void 0;
|
|
17144
|
+
const w = (ip) => (weight !== void 0 ? weight.get(ip) : profile[ip]) ?? 0;
|
|
17145
|
+
const ranked = [...siteBytes.keys()].sort((a, b) => w(b) / siteBytes.get(b) - w(a) / siteBytes.get(a) || a - b);
|
|
17146
|
+
let spent = 0;
|
|
17147
|
+
for (const ip of ranked) {
|
|
17148
|
+
if (w(ip) === 0) break;
|
|
17149
|
+
const bytes = siteBytes.get(ip);
|
|
17150
|
+
if (spent + bytes > budget) continue;
|
|
17151
|
+
spent += bytes;
|
|
17152
|
+
selected.add(ip);
|
|
17153
|
+
}
|
|
17154
|
+
return selected;
|
|
17155
|
+
}
|
|
17156
|
+
function staticWeights(code, entries) {
|
|
17157
|
+
let weight = /* @__PURE__ */ new Map();
|
|
17158
|
+
const kids = [];
|
|
17159
|
+
for (let round = 0; round < ROUNDS; round++) {
|
|
17160
|
+
const next = /* @__PURE__ */ new Map();
|
|
17161
|
+
for (const ip of entries) next.set(ip, 1);
|
|
17162
|
+
for (const [ip, w] of weight) {
|
|
17163
|
+
kids.length = 0;
|
|
17164
|
+
childSlots(code, ip, kids);
|
|
17165
|
+
const op = code[ip];
|
|
17166
|
+
const scale = op === OP_REP || op === OP_REPV ? LOOP : op === OP_CHOICE || op === OP_DISPATCH ? 1 / Math.max(1, kids.length) : 1;
|
|
17167
|
+
for (const kid of kids) next.set(kid, Math.min(CAP, (next.get(kid) ?? 0) + w * scale));
|
|
17168
|
+
}
|
|
17169
|
+
weight = next;
|
|
17170
|
+
}
|
|
17171
|
+
return weight;
|
|
17172
|
+
}
|
|
17173
|
+
|
|
15723
17174
|
// src/table/compile-rule-map.ts
|
|
15724
|
-
var
|
|
17175
|
+
var SUPERCOMPILE_GROWTH = 1.05;
|
|
15725
17176
|
function resolveHostMode(ruleMap, explicit) {
|
|
15726
17177
|
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
15727
17178
|
}
|
|
@@ -15818,14 +17269,45 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
15818
17269
|
entry: null,
|
|
15819
17270
|
runtimeRef: opts.runtimeRef ?? "tableRules",
|
|
15820
17271
|
fnSources: sources,
|
|
15821
|
-
...options.
|
|
17272
|
+
...options.select !== void 0 && options.select.size > 0 ? { assemblies: [{ ...defaultAssemblyCfgs(artifact)[0], select: options.select }] } : {},
|
|
15822
17273
|
...metadataSource === void 0 ? {} : { metadataSource }
|
|
15823
17274
|
});
|
|
15824
17275
|
const replacement = replacementWithMetadata();
|
|
17276
|
+
const selectAssembly = (budget, profile) => {
|
|
17277
|
+
const none = { sites: /* @__PURE__ */ new Set(), bytes: 0 };
|
|
17278
|
+
if (hostMode !== "ast" || prog.lines === 1) return none;
|
|
17279
|
+
const table = resolveTable(artifact);
|
|
17280
|
+
const cfg = defaultAssemblyCfgs(artifact)[0];
|
|
17281
|
+
const roots = assemblyExtraIps(artifact);
|
|
17282
|
+
let siteBytes, fixed;
|
|
17283
|
+
try {
|
|
17284
|
+
siteBytes = emitAssemblySource(table, artifact, cfg, roots, true).siteBytes;
|
|
17285
|
+
fixed = emitAssemblySource(table, artifact, cfg, roots, true, /* @__PURE__ */ new Set()).source.length;
|
|
17286
|
+
} catch (e) {
|
|
17287
|
+
if (e instanceof Unemittable) return { ...none, refusal: e.construct };
|
|
17288
|
+
throw e;
|
|
17289
|
+
}
|
|
17290
|
+
const ceiling = budget / SUPERCOMPILE_GROWTH;
|
|
17291
|
+
if (ceiling <= fixed) return none;
|
|
17292
|
+
let target = ceiling;
|
|
17293
|
+
for (; ; ) {
|
|
17294
|
+
const sites = selectHotSites(artifact.code, Object.values(artifact.rules), siteBytes, target - fixed, profile);
|
|
17295
|
+
if (sites.size === 0) {
|
|
17296
|
+
return {
|
|
17297
|
+
...none,
|
|
17298
|
+
refusal: `a site within its ${Math.floor(ceiling)} B selection ceiling (the prelude alone is ${fixed} B)`
|
|
17299
|
+
};
|
|
17300
|
+
}
|
|
17301
|
+
const bytes = emitAssemblySource(table, artifact, cfg, roots, true, sites).source.length;
|
|
17302
|
+
if (bytes <= ceiling) return { sites, bytes: Math.ceil(bytes * SUPERCOMPILE_GROWTH) };
|
|
17303
|
+
target *= Math.min(ceiling / bytes, 0.99);
|
|
17304
|
+
}
|
|
17305
|
+
};
|
|
15825
17306
|
return {
|
|
15826
17307
|
keys: ruleMap.map(([key]) => key),
|
|
15827
17308
|
replacement,
|
|
15828
17309
|
replacementWithMetadata,
|
|
17310
|
+
selectAssembly,
|
|
15829
17311
|
hostMode,
|
|
15830
17312
|
// WHAT THE FLAG MEANS is "a DIRECT BUILDER's positioned-CST branch was
|
|
15831
17313
|
// dropped", which is what the driver's `'ast' artifact + CST host` check keys
|
|
@@ -15907,16 +17389,16 @@ function ownSource(fn) {
|
|
|
15907
17389
|
return typeof name === "string" && name.length > 0 && globalThis[name] === fn ? name : null;
|
|
15908
17390
|
}
|
|
15909
17391
|
function compile(target, second, third) {
|
|
15910
|
-
if (!
|
|
17392
|
+
if (!isCombinator2(target)) return compileMap(target, second);
|
|
15911
17393
|
return compileRoot(target, second, third);
|
|
15912
17394
|
}
|
|
15913
|
-
function
|
|
17395
|
+
function isCombinator2(x) {
|
|
15914
17396
|
return typeof x === "object" && x !== null && typeof x.parse === "function" && "_def" in x;
|
|
15915
17397
|
}
|
|
15916
17398
|
function compileMap(grammar, opts = {}) {
|
|
15917
17399
|
const entries = [];
|
|
15918
17400
|
for (const [key, value] of Object.entries(grammar)) {
|
|
15919
|
-
if (!
|
|
17401
|
+
if (!isCombinator2(value)) throw new TypeError(`compile: grammar entry "${key}" is not a parser`);
|
|
15920
17402
|
if (value._def.tag === "lazy") {
|
|
15921
17403
|
try {
|
|
15922
17404
|
value._def.thunk();
|