parseman 0.49.0 → 0.50.1
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/commitment.d.ts +2 -1
- package/dist/analysis/commitment.d.ts.map +1 -1
- package/dist/analysis/diagnostics.js +1824 -737
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/analysis/rebuild.d.ts.map +1 -1
- package/dist/cli/index.js +1252 -164
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/trivia-skip.d.ts +1 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/build-arity.d.ts +16 -0
- package/dist/compiler/build-arity.d.ts.map +1 -1
- package/dist/compiler/degradation.d.ts +0 -2
- package/dist/compiler/degradation.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts +11 -0
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +185 -20
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/cst/capture-buffer.d.ts +5 -1
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.js +1365 -279
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +2 -1
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/entry-supercompiler.d.ts +48 -0
- package/dist/plugin/entry-supercompiler.d.ts.map +1 -0
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1957 -385
- package/dist/plugin/index.js.map +3 -3
- package/dist/run/index.js +2 -1
- package/dist/run/index.js.map +1 -1
- package/dist/spec/index.js +28 -7
- package/dist/spec/index.js.map +1 -1
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +6 -5
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +6 -1
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/index.js +1315 -231
- package/dist/table/index.js.map +3 -3
- package/dist/table/ops.d.ts +3 -2
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +15 -1
- package/dist/table/program.d.ts.map +1 -1
- package/dist/table/scalar-terminal.d.ts +30 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -1
- package/dist/table/site-labels.d.ts +8 -0
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/analysis/commitment.ts +19 -8
- package/src/analysis/rebuild.ts +1 -0
- package/src/combinators/trivia-skip.ts +2 -2
- package/src/compiler/build-arity.ts +50 -0
- package/src/compiler/degradation.ts +0 -6
- package/src/compiler/ir-serialize.ts +6 -4
- package/src/compiler/token-alphabet.ts +322 -28
- package/src/cst/capture-buffer.ts +34 -11
- package/src/plugin/entry-supercompiler.ts +567 -0
- package/src/plugin/evaluator.ts +10 -0
- package/src/plugin/index.ts +7 -3
- package/src/table/assemble.ts +125 -42
- package/src/table/compile-rule-map.ts +8 -7
- package/src/table/compile.ts +7 -8
- package/src/table/emit-assembly.ts +646 -126
- package/src/table/emit.ts +1 -1
- package/src/table/encode.ts +152 -7
- package/src/table/ops.ts +3 -2
- package/src/table/program.ts +44 -3
- package/src/table/scalar-terminal.ts +213 -1
- package/src/table/site-labels.ts +22 -9
- package/src/types.ts +1 -1
- package/src/version.ts +1 -1
|
@@ -405,7 +405,7 @@ function beginCstNodeCapture(ctx) {
|
|
|
405
405
|
function finishCstBuf(buf) {
|
|
406
406
|
if (!buf) return { children: EMPTY, rawChildren: EMPTY, triviaLog: EMPTY_TL };
|
|
407
407
|
const children2 = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY);
|
|
408
|
-
const rawChildren = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY);
|
|
408
|
+
const rawChildren = buf.noRaw === true ? EMPTY : buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY);
|
|
409
409
|
const triviaLog = buf.tl ?? EMPTY_TL;
|
|
410
410
|
return { children: children2, rawChildren, triviaLog };
|
|
411
411
|
}
|
|
@@ -437,7 +437,8 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
437
437
|
b.single = void 0;
|
|
438
438
|
} else b.single = built;
|
|
439
439
|
}
|
|
440
|
-
if (b.
|
|
440
|
+
if (b.noRaw === true) b.rawLen = (b.rawLen ?? 0) + 1;
|
|
441
|
+
else if (b.raw) b.raw.push(rawEntry2);
|
|
441
442
|
else if (b.rawSingle !== void 0) {
|
|
442
443
|
b.raw = [b.rawSingle, rawEntry2];
|
|
443
444
|
b.rawSingle = void 0;
|
|
@@ -451,6 +452,7 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
451
452
|
function cstRawLen(ctx) {
|
|
452
453
|
const b = ctx._cstBuf;
|
|
453
454
|
if (b) {
|
|
455
|
+
if (b.noRaw === true) return b.rawLen ?? 0;
|
|
454
456
|
if (b.raw) return b.raw.length;
|
|
455
457
|
return b.rawSingle !== void 0 ? 1 : 0;
|
|
456
458
|
}
|
|
@@ -510,19 +512,37 @@ function rollbackCstCaptureAt(ctx, raw, tlog, leaves, fields, errors) {
|
|
|
510
512
|
if (ctx._errors && errors !== void 0 && ctx._errors.length !== errors) ctx._errors.length = errors;
|
|
511
513
|
const b = ctx._cstBuf;
|
|
512
514
|
if (b) {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
+
if (b.noRaw === true) {
|
|
516
|
+
if (b.rawLen !== raw) b.rawLen = raw;
|
|
517
|
+
} else {
|
|
518
|
+
const rawList = b.raw;
|
|
519
|
+
if (rawList) {
|
|
520
|
+
if (raw === 0) b.raw = void 0;
|
|
521
|
+
else if (raw === 1) {
|
|
522
|
+
b.rawSingle = rawList[0];
|
|
523
|
+
b.raw = void 0;
|
|
524
|
+
} else if (rawList.length !== raw) rawList.length = raw;
|
|
525
|
+
} else if (raw === 0) b.rawSingle = void 0;
|
|
526
|
+
}
|
|
527
|
+
const childList = b.ch;
|
|
528
|
+
if (childList) {
|
|
529
|
+
if (leaves === 0) b.ch = void 0;
|
|
530
|
+
else if (leaves === 1) {
|
|
531
|
+
b.single = childList[0];
|
|
532
|
+
b.ch = void 0;
|
|
533
|
+
} else if (childList.length !== leaves) childList.length = leaves;
|
|
534
|
+
} else if (leaves === 0) b.single = void 0;
|
|
515
535
|
if (b.tl) {
|
|
516
536
|
if (tlog === 0) b.tl = void 0;
|
|
517
537
|
else if (b.tl.length !== tlog) b.tl.length = tlog;
|
|
518
538
|
}
|
|
519
|
-
if (ctx._fields && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
539
|
+
if (ctx._fields && fields !== void 0 && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
520
540
|
return;
|
|
521
541
|
}
|
|
522
542
|
if (ctx._cstRawChildren && ctx._cstRawChildren.length !== raw) ctx._cstRawChildren.length = raw;
|
|
523
543
|
if (ctx._cstTriviaLog && ctx._cstTriviaLog.length !== tlog) ctx._cstTriviaLog.length = tlog;
|
|
524
544
|
if (ctx._cstLeaves && ctx._cstLeaves.length !== leaves) ctx._cstLeaves.length = leaves;
|
|
525
|
-
if (ctx._fields && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
545
|
+
if (ctx._fields && fields !== void 0 && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
526
546
|
}
|
|
527
547
|
function pushCstTriviaEntry(ctx, start, end, kindIndex) {
|
|
528
548
|
const insertIdx = cstRawLen(ctx);
|
|
@@ -2620,222 +2640,780 @@ function analyzeChoice(p, d, rule2, resolve) {
|
|
|
2620
2640
|
};
|
|
2621
2641
|
}
|
|
2622
2642
|
|
|
2623
|
-
// src/
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
_cstLeaves: ctx._cstLeaves,
|
|
2629
|
-
_cstChildren: ctx._cstChildren,
|
|
2630
|
-
_cstRawChildren: ctx._cstRawChildren,
|
|
2631
|
-
_cstTriviaLog: ctx._cstTriviaLog,
|
|
2632
|
-
_triviaLog: ctx._triviaLog,
|
|
2633
|
-
_rootTriviaLog: ctx._rootTriviaLog,
|
|
2634
|
-
_fields: ctx._fields,
|
|
2635
|
-
_cstBuf: ctx._cstBuf,
|
|
2636
|
-
_tolerant: ctx._tolerant,
|
|
2637
|
-
_sync: ctx._sync
|
|
2638
|
-
};
|
|
2639
|
-
ctx._probe = void 0;
|
|
2640
|
-
ctx._errors = void 0;
|
|
2641
|
-
ctx._cstLeaves = void 0;
|
|
2642
|
-
ctx._cstChildren = void 0;
|
|
2643
|
-
ctx._cstRawChildren = void 0;
|
|
2644
|
-
ctx._cstTriviaLog = void 0;
|
|
2645
|
-
ctx._triviaLog = void 0;
|
|
2646
|
-
ctx._rootTriviaLog = void 0;
|
|
2647
|
-
ctx._fields = void 0;
|
|
2648
|
-
ctx._cstBuf = void 0;
|
|
2649
|
-
ctx._tolerant = void 0;
|
|
2650
|
-
ctx._sync = void 0;
|
|
2651
|
-
try {
|
|
2652
|
-
return sentinel.parse(input, pos, ctx).ok;
|
|
2653
|
-
} finally {
|
|
2654
|
-
ctx._probe = s._probe;
|
|
2655
|
-
ctx._errors = s._errors;
|
|
2656
|
-
ctx._cstLeaves = s._cstLeaves;
|
|
2657
|
-
ctx._cstChildren = s._cstChildren;
|
|
2658
|
-
ctx._cstRawChildren = s._cstRawChildren;
|
|
2659
|
-
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
2660
|
-
ctx._triviaLog = s._triviaLog;
|
|
2661
|
-
ctx._rootTriviaLog = s._rootTriviaLog;
|
|
2662
|
-
ctx._fields = s._fields;
|
|
2663
|
-
ctx._cstBuf = s._cstBuf;
|
|
2664
|
-
ctx._tolerant = s._tolerant;
|
|
2665
|
-
ctx._sync = s._sync;
|
|
2666
|
-
}
|
|
2667
|
-
}
|
|
2668
|
-
function orSentinel(a, b) {
|
|
2669
|
-
if (b === void 0) return a;
|
|
2670
|
-
return {
|
|
2671
|
-
_tag: "orSentinel",
|
|
2672
|
-
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
2673
|
-
_def: { tag: "unknown" },
|
|
2674
|
-
parse(input, pos, ctx) {
|
|
2675
|
-
const ra = a.parse(input, pos, ctx);
|
|
2676
|
-
if (ra.ok) return ra;
|
|
2677
|
-
return b.parse(input, pos, ctx);
|
|
2678
|
-
}
|
|
2679
|
-
};
|
|
2680
|
-
}
|
|
2681
|
-
function firstSetSentinel(fs) {
|
|
2682
|
-
if (fs.kind !== "ranges" || fs.ranges.length === 0) return null;
|
|
2683
|
-
const ranges = fs.ranges;
|
|
2684
|
-
return {
|
|
2685
|
-
_tag: "firstSetSentinel",
|
|
2686
|
-
_meta: { firstSet: fs, canMatchNewline: false, isTrivia: false },
|
|
2687
|
-
_def: { tag: "unknown" },
|
|
2688
|
-
parse(input, pos) {
|
|
2689
|
-
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
2690
|
-
if (code !== void 0) {
|
|
2691
|
-
for (const r of ranges) {
|
|
2692
|
-
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
2693
|
-
}
|
|
2694
|
-
}
|
|
2695
|
-
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
2696
|
-
}
|
|
2697
|
-
};
|
|
2698
|
-
}
|
|
2699
|
-
function recoverScan(input, from, ctx, sync, expected) {
|
|
2700
|
-
let scanPos = from;
|
|
2701
|
-
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
2702
|
-
const span = { start: from, end: scanPos };
|
|
2703
|
-
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
2704
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
2705
|
-
ctx._errors?.push(error);
|
|
2706
|
-
return { error, end: scanPos };
|
|
2707
|
-
}
|
|
2708
|
-
function matchesAt(sentinel, input, pos, ctx) {
|
|
2709
|
-
return probeAt(sentinel, input, pos, ctx);
|
|
2643
|
+
// src/regex/first-set.ts
|
|
2644
|
+
var ANY = { t: "any" };
|
|
2645
|
+
var EMPTY2 = { t: "empty" };
|
|
2646
|
+
function charNode(set, nl) {
|
|
2647
|
+
return { t: "char", set, nl };
|
|
2710
2648
|
}
|
|
2711
|
-
function
|
|
2712
|
-
|
|
2649
|
+
function rangesToSet(ranges) {
|
|
2650
|
+
let fs = empty();
|
|
2651
|
+
for (const [lo, hi] of ranges) fs = union(fs, fromRange(lo, hi));
|
|
2652
|
+
return fs;
|
|
2713
2653
|
}
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
function deriveExpected(c) {
|
|
2717
|
-
return [...new Set(derive(c, /* @__PURE__ */ new Set()))];
|
|
2654
|
+
function rangesHaveNewline(ranges) {
|
|
2655
|
+
return ranges.some(([lo, hi]) => lo <= 10 && 10 <= hi);
|
|
2718
2656
|
}
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
case "keywords":
|
|
2728
|
-
return def.words.map((w) => JSON.stringify(w));
|
|
2729
|
-
case "label":
|
|
2730
|
-
return [def.label];
|
|
2731
|
-
case "choice":
|
|
2732
|
-
return def.parsers.flatMap(deriveExpected2);
|
|
2733
|
-
case "dispatch":
|
|
2734
|
-
return deriveExpected2(def.selector);
|
|
2735
|
-
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
2736
|
-
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
2737
|
-
// able to fail first — deriving from term 0 alone named a token the parse
|
|
2738
|
-
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
2739
|
-
// nothing (its own expectation is about what must NOT be here), but it is
|
|
2740
|
-
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
2741
|
-
case "sequence": {
|
|
2742
|
-
const out = [];
|
|
2743
|
-
for (const term of def.parsers) {
|
|
2744
|
-
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
2745
|
-
if (!matchesEmpty(term)) break;
|
|
2746
|
-
}
|
|
2747
|
-
return out;
|
|
2748
|
-
}
|
|
2749
|
-
case "attempt":
|
|
2750
|
-
return deriveExpected2(def.parser);
|
|
2751
|
-
// Delegating wrappers whose first-token failure is their inner parser's — must
|
|
2752
|
-
// pass through so a start-failure (and the first-set-miss fast-path in attempt/
|
|
2753
|
-
// node, which reads this) names the real expected token, not the wrapper tag.
|
|
2754
|
-
case "field":
|
|
2755
|
-
case "withCtx":
|
|
2756
|
-
case "recover":
|
|
2757
|
-
return deriveExpected2(def.parser);
|
|
2758
|
-
case "expect":
|
|
2759
|
-
return def.expected;
|
|
2760
|
-
case "node":
|
|
2761
|
-
case "grammar":
|
|
2762
|
-
case "trivia":
|
|
2763
|
-
case "token":
|
|
2764
|
-
case "leaf":
|
|
2765
|
-
case "optional":
|
|
2766
|
-
case "many":
|
|
2767
|
-
case "oneOrMore":
|
|
2768
|
-
case "transform":
|
|
2769
|
-
case "not":
|
|
2770
|
-
case "peek":
|
|
2771
|
-
return deriveExpected2(def.parser);
|
|
2772
|
-
// A bare routed() can only fail as "there is no routed token here". With a
|
|
2773
|
-
// fallback, THAT is the branch that can fail, so its expectations are the useful
|
|
2774
|
-
// ones — the routed path either succeeds or is not taken.
|
|
2775
|
-
case "routed":
|
|
2776
|
-
return def.fallback === void 0 ? ["routed()"] : deriveExpected2(def.fallback);
|
|
2777
|
-
// A bare adjacency assertion names the JOIN it requires. Inside a sequence it is
|
|
2778
|
-
// skipped entirely (isZeroWidthAssertion, above), which is the normal path.
|
|
2779
|
-
case "adjacency":
|
|
2780
|
-
return [def.polarity];
|
|
2781
|
-
case "lazy": {
|
|
2782
|
-
const name = c._ruleName;
|
|
2783
|
-
if (seen.has(c)) return name ? [name] : [];
|
|
2784
|
-
seen.add(c);
|
|
2785
|
-
try {
|
|
2786
|
-
return deriveExpected2(def.thunk());
|
|
2787
|
-
} catch {
|
|
2788
|
-
return name ? [name] : [];
|
|
2789
|
-
} finally {
|
|
2790
|
-
seen.delete(c);
|
|
2791
|
-
}
|
|
2657
|
+
var BAIL = /* @__PURE__ */ Symbol("regex-bail");
|
|
2658
|
+
function parseRegex(src) {
|
|
2659
|
+
let i = 0;
|
|
2660
|
+
const parseAlt = () => {
|
|
2661
|
+
const arms = [parseSeq()];
|
|
2662
|
+
while (src[i] === "|") {
|
|
2663
|
+
i++;
|
|
2664
|
+
arms.push(parseSeq());
|
|
2792
2665
|
}
|
|
2793
|
-
|
|
2794
|
-
return [];
|
|
2795
|
-
}
|
|
2796
|
-
}
|
|
2797
|
-
function expect(combinator, label2) {
|
|
2798
|
-
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
2799
|
-
const meta = {
|
|
2800
|
-
firstSet: combinator._meta.firstSet,
|
|
2801
|
-
canMatchNewline: combinator._meta.canMatchNewline,
|
|
2802
|
-
isTrivia: false
|
|
2666
|
+
return arms.length === 1 ? arms[0] : { t: "alt", arms };
|
|
2803
2667
|
};
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
if (result.ok) return result;
|
|
2811
|
-
const span = { start: pos, end: pos };
|
|
2812
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
2813
|
-
ctx._errors?.push(error);
|
|
2814
|
-
if (ctx._tolerant) captureError(ctx, error);
|
|
2815
|
-
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
2668
|
+
const parseSeq = () => {
|
|
2669
|
+
const parts = [];
|
|
2670
|
+
while (i < src.length) {
|
|
2671
|
+
const ch2 = src[i];
|
|
2672
|
+
if (ch2 === "|" || ch2 === ")") break;
|
|
2673
|
+
parts.push(parseQuantified());
|
|
2816
2674
|
}
|
|
2675
|
+
if (parts.length === 0) return EMPTY2;
|
|
2676
|
+
return parts.length === 1 ? parts[0] : { t: "seq", parts };
|
|
2817
2677
|
};
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2678
|
+
const parseQuantified = () => {
|
|
2679
|
+
const atom = parseAtom();
|
|
2680
|
+
const ch2 = src[i];
|
|
2681
|
+
let min = null;
|
|
2682
|
+
if (ch2 === "*") {
|
|
2683
|
+
min = 0;
|
|
2684
|
+
i++;
|
|
2685
|
+
} else if (ch2 === "+") {
|
|
2686
|
+
min = 1;
|
|
2687
|
+
i++;
|
|
2688
|
+
} else if (ch2 === "?") {
|
|
2689
|
+
min = 0;
|
|
2690
|
+
i++;
|
|
2691
|
+
} else if (ch2 === "{") {
|
|
2692
|
+
min = parseBraceQuantifier();
|
|
2693
|
+
}
|
|
2694
|
+
if (min === null) return atom;
|
|
2695
|
+
if (src[i] === "?") i++;
|
|
2696
|
+
return { t: "rep", node: atom, min };
|
|
2833
2697
|
};
|
|
2834
|
-
const
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2698
|
+
const parseBraceQuantifier = () => {
|
|
2699
|
+
const close = src.indexOf("}", i);
|
|
2700
|
+
if (close === -1) return null;
|
|
2701
|
+
const m = /^(\d+)(?:,(\d*))?$/.exec(src.slice(i + 1, close));
|
|
2702
|
+
if (!m) return null;
|
|
2703
|
+
i = close + 1;
|
|
2704
|
+
return Number.parseInt(m[1], 10);
|
|
2705
|
+
};
|
|
2706
|
+
const parseAtom = () => {
|
|
2707
|
+
const ch2 = src[i];
|
|
2708
|
+
switch (ch2) {
|
|
2709
|
+
case "(":
|
|
2710
|
+
return parseGroup();
|
|
2711
|
+
case "[":
|
|
2712
|
+
return parseClass();
|
|
2713
|
+
case ".":
|
|
2714
|
+
i++;
|
|
2715
|
+
return charNode(any(), false);
|
|
2716
|
+
// `.` matches any char except line terminators
|
|
2717
|
+
case "\\":
|
|
2718
|
+
return parseEscape();
|
|
2719
|
+
case "^":
|
|
2720
|
+
case "$":
|
|
2721
|
+
i++;
|
|
2722
|
+
return EMPTY2;
|
|
2723
|
+
// anchors are zero-width
|
|
2724
|
+
case "{":
|
|
2725
|
+
i++;
|
|
2726
|
+
return charNode(fromRange(123, 123), false);
|
|
2727
|
+
// a `{` with nothing to quantify is a literal brace
|
|
2728
|
+
default:
|
|
2729
|
+
i += ch2.length;
|
|
2730
|
+
return charNode(fromRange(ch2.codePointAt(0), ch2.codePointAt(0)), ch2 === "\n");
|
|
2731
|
+
}
|
|
2732
|
+
};
|
|
2733
|
+
const parseGroup = () => {
|
|
2734
|
+
i++;
|
|
2735
|
+
let lookaround = false;
|
|
2736
|
+
if (src[i] === "?") {
|
|
2737
|
+
const c1 = src[i + 1];
|
|
2738
|
+
if (c1 === ":") i += 2;
|
|
2739
|
+
else if (c1 === "=" || c1 === "!") {
|
|
2740
|
+
i += 2;
|
|
2741
|
+
lookaround = true;
|
|
2742
|
+
} else if (c1 === "<") {
|
|
2743
|
+
const c2 = src[i + 2];
|
|
2744
|
+
if (c2 === "=" || c2 === "!") {
|
|
2745
|
+
i += 3;
|
|
2746
|
+
lookaround = true;
|
|
2747
|
+
} else {
|
|
2748
|
+
const gt = src.indexOf(">", i);
|
|
2749
|
+
if (gt === -1) throw BAIL;
|
|
2750
|
+
i = gt + 1;
|
|
2751
|
+
}
|
|
2752
|
+
} else throw BAIL;
|
|
2753
|
+
}
|
|
2754
|
+
const inner = parseAlt();
|
|
2755
|
+
if (src[i] !== ")") throw BAIL;
|
|
2756
|
+
i++;
|
|
2757
|
+
return lookaround ? EMPTY2 : inner;
|
|
2758
|
+
};
|
|
2759
|
+
const parseClass = () => {
|
|
2760
|
+
let k = i + 1;
|
|
2761
|
+
const negated = src[k] === "^";
|
|
2762
|
+
if (negated) k++;
|
|
2763
|
+
let body = "";
|
|
2764
|
+
while (k < src.length && src[k] !== "]") {
|
|
2765
|
+
if (src[k] === "\\") {
|
|
2766
|
+
body += src[k] + (src[k + 1] ?? "");
|
|
2767
|
+
k += 2;
|
|
2768
|
+
} else {
|
|
2769
|
+
body += src[k];
|
|
2770
|
+
k++;
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
if (src[k] !== "]") throw BAIL;
|
|
2774
|
+
i = k + 1;
|
|
2775
|
+
const ranges = parseClassRanges(body);
|
|
2776
|
+
if (negated) return charNode(any(), !ranges || !rangesHaveNewline(ranges));
|
|
2777
|
+
if (!ranges) return charNode(any(), true);
|
|
2778
|
+
return charNode(rangesToSet(ranges), rangesHaveNewline(ranges));
|
|
2779
|
+
};
|
|
2780
|
+
const parseEscape = () => {
|
|
2781
|
+
const e = src[i + 1];
|
|
2782
|
+
if (e === void 0) throw BAIL;
|
|
2783
|
+
if (e === "u" && /^[0-9a-fA-F]{4}$/.test(src.slice(i + 2, i + 6))) {
|
|
2784
|
+
const cp = Number.parseInt(src.slice(i + 2, i + 6), 16);
|
|
2785
|
+
i += 6;
|
|
2786
|
+
return charNode(fromRange(cp, cp), cp === 10);
|
|
2787
|
+
}
|
|
2788
|
+
if (e === "x" && /^[0-9a-fA-F]{2}$/.test(src.slice(i + 2, i + 4))) {
|
|
2789
|
+
const cp = Number.parseInt(src.slice(i + 2, i + 4), 16);
|
|
2790
|
+
i += 4;
|
|
2791
|
+
return charNode(fromRange(cp, cp), cp === 10);
|
|
2792
|
+
}
|
|
2793
|
+
i += 2;
|
|
2794
|
+
switch (e) {
|
|
2795
|
+
case "d":
|
|
2796
|
+
return charNode(rangesToSet(shorthandRanges("d")), false);
|
|
2797
|
+
case "w":
|
|
2798
|
+
return charNode(rangesToSet(shorthandRanges("w")), false);
|
|
2799
|
+
case "s":
|
|
2800
|
+
return charNode(rangesToSet(shorthandRanges("s")), true);
|
|
2801
|
+
case "D":
|
|
2802
|
+
case "W":
|
|
2803
|
+
case "S":
|
|
2804
|
+
return charNode(any(), true);
|
|
2805
|
+
// negated shorthand → widen
|
|
2806
|
+
case "b":
|
|
2807
|
+
case "B":
|
|
2808
|
+
return EMPTY2;
|
|
2809
|
+
// word boundary: zero-width
|
|
2810
|
+
case "n":
|
|
2811
|
+
return charNode(fromRange(10, 10), true);
|
|
2812
|
+
case "r":
|
|
2813
|
+
return charNode(fromRange(13, 13), false);
|
|
2814
|
+
case "t":
|
|
2815
|
+
return charNode(fromRange(9, 9), false);
|
|
2816
|
+
case "f":
|
|
2817
|
+
return charNode(fromRange(12, 12), false);
|
|
2818
|
+
case "v":
|
|
2819
|
+
return charNode(fromRange(11, 11), false);
|
|
2820
|
+
case "0":
|
|
2821
|
+
return charNode(fromRange(0, 0), false);
|
|
2822
|
+
default:
|
|
2823
|
+
if (e >= "1" && e <= "9") return ANY;
|
|
2824
|
+
return charNode(fromRange(e.codePointAt(0), e.codePointAt(0)), e === "\n");
|
|
2825
|
+
}
|
|
2826
|
+
};
|
|
2827
|
+
const node2 = parseAlt();
|
|
2828
|
+
if (i < src.length) throw BAIL;
|
|
2829
|
+
return node2;
|
|
2830
|
+
}
|
|
2831
|
+
function nullable(n) {
|
|
2832
|
+
switch (n.t) {
|
|
2833
|
+
case "char":
|
|
2834
|
+
return false;
|
|
2835
|
+
case "any":
|
|
2836
|
+
return true;
|
|
2837
|
+
case "empty":
|
|
2838
|
+
return true;
|
|
2839
|
+
case "seq":
|
|
2840
|
+
return n.parts.every(nullable);
|
|
2841
|
+
case "alt":
|
|
2842
|
+
return n.arms.some(nullable);
|
|
2843
|
+
case "rep":
|
|
2844
|
+
return n.min === 0 || nullable(n.node);
|
|
2845
|
+
}
|
|
2846
|
+
}
|
|
2847
|
+
function firstSet(n) {
|
|
2848
|
+
switch (n.t) {
|
|
2849
|
+
case "char":
|
|
2850
|
+
return n.set;
|
|
2851
|
+
case "any":
|
|
2852
|
+
return any();
|
|
2853
|
+
case "empty":
|
|
2854
|
+
return empty();
|
|
2855
|
+
case "rep":
|
|
2856
|
+
return firstSet(n.node);
|
|
2857
|
+
case "alt": {
|
|
2858
|
+
let fs = empty();
|
|
2859
|
+
for (const arm of n.arms) fs = union(fs, firstSet(arm));
|
|
2860
|
+
return fs;
|
|
2861
|
+
}
|
|
2862
|
+
case "seq": {
|
|
2863
|
+
let fs = empty();
|
|
2864
|
+
for (const part of n.parts) {
|
|
2865
|
+
fs = union(fs, firstSet(part));
|
|
2866
|
+
if (!nullable(part)) break;
|
|
2867
|
+
}
|
|
2868
|
+
return fs;
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
function canConsumeNewline(n) {
|
|
2873
|
+
switch (n.t) {
|
|
2874
|
+
case "char":
|
|
2875
|
+
return n.nl;
|
|
2876
|
+
case "any":
|
|
2877
|
+
return true;
|
|
2878
|
+
case "empty":
|
|
2879
|
+
return false;
|
|
2880
|
+
case "rep":
|
|
2881
|
+
return canConsumeNewline(n.node);
|
|
2882
|
+
case "alt":
|
|
2883
|
+
return n.arms.some(canConsumeNewline);
|
|
2884
|
+
case "seq":
|
|
2885
|
+
return n.parts.some(canConsumeNewline);
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
function regexCanMatchEmpty(source) {
|
|
2889
|
+
try {
|
|
2890
|
+
return nullable(parseRegex(source));
|
|
2891
|
+
} catch {
|
|
2892
|
+
return true;
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
function firstSetFromRegex(source) {
|
|
2896
|
+
let ast;
|
|
2897
|
+
try {
|
|
2898
|
+
ast = parseRegex(source);
|
|
2899
|
+
} catch {
|
|
2900
|
+
return { firstSet: any(), canMatchNewline: true };
|
|
2901
|
+
}
|
|
2902
|
+
if (nullable(ast)) return { firstSet: any(), canMatchNewline: canConsumeNewline(ast) };
|
|
2903
|
+
return { firstSet: firstSet(ast), canMatchNewline: canConsumeNewline(ast) };
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2906
|
+
// src/analysis/commitment.ts
|
|
2907
|
+
function mayFail(p, seen = /* @__PURE__ */ new Set()) {
|
|
2908
|
+
if (seen.has(p)) return true;
|
|
2909
|
+
seen.add(p);
|
|
2910
|
+
const d = p._def;
|
|
2911
|
+
switch (d.tag) {
|
|
2912
|
+
case "literal":
|
|
2913
|
+
return d.value.length > 0;
|
|
2914
|
+
case "trivia":
|
|
2915
|
+
return false;
|
|
2916
|
+
// `optional`/`many`/a min-0 `sepBy` swallow an ORDINARY failure — zero
|
|
2917
|
+
// repetitions is a match. They do NOT swallow a COMMITTED one: a dispatch
|
|
2918
|
+
// that has selected an arm and then failed inside it breaks out past every
|
|
2919
|
+
// enclosing repeat, straight to the fallible boundary. So these are total
|
|
2920
|
+
// exactly when their body cannot commit. (Measured: treating them as
|
|
2921
|
+
// unconditionally total left an extra zero-width leaf in
|
|
2922
|
+
// `BareInterpolatedSelector` on benchmark.less — a rollback the legacy
|
|
2923
|
+
// build fired and this one had deleted.)
|
|
2924
|
+
case "optional":
|
|
2925
|
+
case "many":
|
|
2926
|
+
return mayCommitFailure(d.parser);
|
|
2927
|
+
case "sepBy":
|
|
2928
|
+
return d.min >= 1 ? mayFail(d.parser, seen) : mayCommitFailure(d.parser) || mayCommitFailure(d.separator);
|
|
2929
|
+
case "oneOrMore":
|
|
2930
|
+
return mayFail(d.parser, seen);
|
|
2931
|
+
case "sequence":
|
|
2932
|
+
return d.parsers.some((x) => mayFail(x, seen));
|
|
2933
|
+
// Delegating wrappers: as fallible as what they wrap.
|
|
2934
|
+
case "node":
|
|
2935
|
+
case "transform":
|
|
2936
|
+
case "label":
|
|
2937
|
+
case "field":
|
|
2938
|
+
case "expect":
|
|
2939
|
+
case "withCtx":
|
|
2940
|
+
case "grammar":
|
|
2941
|
+
case "token":
|
|
2942
|
+
case "leaf":
|
|
2943
|
+
return mayFail(d.parser, seen);
|
|
2944
|
+
case "lazy": {
|
|
2945
|
+
try {
|
|
2946
|
+
return mayFail(d.thunk(), seen);
|
|
2947
|
+
} catch {
|
|
2948
|
+
return true;
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
// An adjacency assertion is a TEST — failing is its whole job.
|
|
2952
|
+
case "adjacency":
|
|
2953
|
+
return true;
|
|
2954
|
+
default:
|
|
2955
|
+
return true;
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActive = true) {
|
|
2959
|
+
if (seen.has(p)) return false;
|
|
2960
|
+
seen.add(p);
|
|
2961
|
+
const d = p._def;
|
|
2962
|
+
switch (d.tag) {
|
|
2963
|
+
// Atomic / non-capturing-then-failing: a failure happens before any push.
|
|
2964
|
+
case "literal":
|
|
2965
|
+
case "regex":
|
|
2966
|
+
case "keywords":
|
|
2967
|
+
case "guard":
|
|
2968
|
+
// Adjacency probes with `_cap = 0` / no `commit()`: it cannot push anything.
|
|
2969
|
+
case "adjacency":
|
|
2970
|
+
case "not":
|
|
2971
|
+
// peek(): emitted under a non-capturing probe ctx and zero-width on both
|
|
2972
|
+
// outcomes, so it can never leave a partial capture behind.
|
|
2973
|
+
case "peek":
|
|
2974
|
+
case "trivia":
|
|
2975
|
+
case "token":
|
|
2976
|
+
case "leaf":
|
|
2977
|
+
case "scanTo":
|
|
2978
|
+
case "unknown":
|
|
2979
|
+
return false;
|
|
2980
|
+
// node() captures into its own private buffers and rolls them back on
|
|
2981
|
+
// failure (emitNode restores _ctx.* and never pushes on the !ok path).
|
|
2982
|
+
case "node":
|
|
2983
|
+
return false;
|
|
2984
|
+
// choice/firstMatch already roll back each failed arm; on overall failure
|
|
2985
|
+
// nothing committed remains.
|
|
2986
|
+
case "choice":
|
|
2987
|
+
return false;
|
|
2988
|
+
case "dispatch":
|
|
2989
|
+
return capturesLeaf(d.selector, new Set(seen)) || d.cases.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) || (d.matchers ? d.matchers.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) : false) || (d.otherwise ? mayLeavePartialCapture(d.otherwise, new Set(seen), triviaActive) || capturesLeaf(d.otherwise, new Set(seen)) : false);
|
|
2990
|
+
case "attempt":
|
|
2991
|
+
return false;
|
|
2992
|
+
// optional never fails; many/oneOrMore only "fail" with zero captured items.
|
|
2993
|
+
case "optional":
|
|
2994
|
+
case "many":
|
|
2995
|
+
case "oneOrMore":
|
|
2996
|
+
return false;
|
|
2997
|
+
// sepBy emits its own per-iteration rollback in emitSepBy.
|
|
2998
|
+
case "sepBy":
|
|
2999
|
+
return false;
|
|
3000
|
+
// A sequence is the real case: an earlier capturing term followed by a term
|
|
3001
|
+
// that can fail leaves the earlier captures buffered.
|
|
3002
|
+
//
|
|
3003
|
+
// BOTH halves of that sentence are load-bearing, and the second half is what
|
|
3004
|
+
// this walk exists to exploit. "Some earlier term captures" alone was the old
|
|
3005
|
+
// test, and it is true of very nearly every sequence in a real grammar — a
|
|
3006
|
+
// sequence almost always opens with a literal or a node. The rollback is only
|
|
3007
|
+
// reachable if something AFTER the capture can still fail; once the remainder
|
|
3008
|
+
// is total (`optional`/`many`/trivia/a min-0 `sepBy`), the sequence has no
|
|
3009
|
+
// failure path left to roll back from, and the save+restore is dead code.
|
|
3010
|
+
//
|
|
3011
|
+
// `captured` tracks whether anything is in the buffers yet as the scan moves
|
|
3012
|
+
// left to right. Two things put it there:
|
|
3013
|
+
// - a term that captures (`capturesLeaf`/`hasNodeDef`), and
|
|
3014
|
+
// - the inter-term TRIVIA scan, which under `capturing` pushes into
|
|
3015
|
+
// `_cstRawChildren`/`_cstTriviaLog` BEFORE the term at each boundary
|
|
3016
|
+
// i >= 1. `emitSeqValues` only rewinds that push on the term's SUCCESS
|
|
3017
|
+
// path (the "matched empty, so leave the whitespace out of the span"
|
|
3018
|
+
// branch); a term that FAILS breaks straight out with the trivia still
|
|
3019
|
+
// buffered, so from boundary 1 onward the buffers are dirty regardless of
|
|
3020
|
+
// what the earlier terms did.
|
|
3021
|
+
// Each term is also asked about itself: a nested sequence can leave its own
|
|
3022
|
+
// partial capture behind, and its terms are emitted inline into this same
|
|
3023
|
+
// block with no boundary of their own to roll them back.
|
|
3024
|
+
case "sequence": {
|
|
3025
|
+
const parts = d.parsers;
|
|
3026
|
+
let captured = false;
|
|
3027
|
+
for (let i = 0; i < parts.length; i++) {
|
|
3028
|
+
const part = parts[i];
|
|
3029
|
+
if (i > 0 && triviaActive) captured = true;
|
|
3030
|
+
if (captured && mayFail(part)) return true;
|
|
3031
|
+
if (mayLeavePartialCapture(part, seen, triviaActive)) return true;
|
|
3032
|
+
if (capturesLeaf(part) || hasNodeDef(part)) captured = true;
|
|
3033
|
+
}
|
|
3034
|
+
return false;
|
|
3035
|
+
}
|
|
3036
|
+
// Delegating wrappers: defer to the wrapped parser.
|
|
3037
|
+
case "transform":
|
|
3038
|
+
case "label":
|
|
3039
|
+
case "field":
|
|
3040
|
+
case "expect":
|
|
3041
|
+
case "withCtx":
|
|
3042
|
+
case "grammar":
|
|
3043
|
+
return mayLeavePartialCapture(d.parser, seen, triviaActive);
|
|
3044
|
+
case "recover":
|
|
3045
|
+
return mayLeavePartialCapture(d.parser, seen, triviaActive);
|
|
3046
|
+
case "lazy": {
|
|
3047
|
+
try {
|
|
3048
|
+
return mayLeavePartialCapture(d.thunk(), seen, triviaActive);
|
|
3049
|
+
} catch {
|
|
3050
|
+
return true;
|
|
3051
|
+
}
|
|
3052
|
+
}
|
|
3053
|
+
// Unknown shapes: be safe and keep the rollback.
|
|
3054
|
+
default:
|
|
3055
|
+
return true;
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
|
|
3059
|
+
if (seen.has(p)) return false;
|
|
3060
|
+
seen.add(p);
|
|
3061
|
+
const d = p._def;
|
|
3062
|
+
switch (d.tag) {
|
|
3063
|
+
case "literal":
|
|
3064
|
+
case "regex":
|
|
3065
|
+
case "keywords":
|
|
3066
|
+
case "node":
|
|
3067
|
+
case "token":
|
|
3068
|
+
case "routed":
|
|
3069
|
+
case "leaf":
|
|
3070
|
+
return true;
|
|
3071
|
+
case "not":
|
|
3072
|
+
case "peek":
|
|
3073
|
+
case "guard":
|
|
3074
|
+
case "adjacency":
|
|
3075
|
+
case "trivia":
|
|
3076
|
+
case "unknown":
|
|
3077
|
+
return false;
|
|
3078
|
+
case "sequence":
|
|
3079
|
+
case "choice":
|
|
3080
|
+
return d.parsers.some((x) => capturesLeaf(x, seen));
|
|
3081
|
+
case "dispatch":
|
|
3082
|
+
return capturesLeaf(d.selector, seen) || d.cases.some((x) => capturesLeaf(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => capturesLeaf(entry.parser, seen)) : false) || (d.otherwise ? capturesLeaf(d.otherwise, seen) : false);
|
|
3083
|
+
case "sepBy":
|
|
3084
|
+
return capturesLeaf(d.parser, seen) || capturesLeaf(d.separator, seen);
|
|
3085
|
+
case "many":
|
|
3086
|
+
case "oneOrMore":
|
|
3087
|
+
case "optional":
|
|
3088
|
+
case "attempt":
|
|
3089
|
+
case "transform":
|
|
3090
|
+
case "label":
|
|
3091
|
+
case "field":
|
|
3092
|
+
case "expect":
|
|
3093
|
+
case "withCtx":
|
|
3094
|
+
case "grammar":
|
|
3095
|
+
case "recover":
|
|
3096
|
+
return capturesLeaf(d.parser, seen);
|
|
3097
|
+
case "scanTo":
|
|
3098
|
+
return true;
|
|
3099
|
+
case "lazy": {
|
|
3100
|
+
try {
|
|
3101
|
+
return capturesLeaf(d.thunk(), seen);
|
|
3102
|
+
} catch {
|
|
3103
|
+
return true;
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3106
|
+
default:
|
|
3107
|
+
return true;
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
3111
|
+
if (seen.has(p)) return false;
|
|
3112
|
+
seen.add(p);
|
|
3113
|
+
const d = p._def;
|
|
3114
|
+
switch (d.tag) {
|
|
3115
|
+
case "node":
|
|
3116
|
+
return true;
|
|
3117
|
+
case "lazy": {
|
|
3118
|
+
try {
|
|
3119
|
+
return hasNodeDef(d.thunk(), seen);
|
|
3120
|
+
} catch {
|
|
3121
|
+
return false;
|
|
3122
|
+
}
|
|
3123
|
+
}
|
|
3124
|
+
case "grammar":
|
|
3125
|
+
case "trivia":
|
|
3126
|
+
case "token":
|
|
3127
|
+
case "leaf":
|
|
3128
|
+
case "label":
|
|
3129
|
+
case "field":
|
|
3130
|
+
case "optional":
|
|
3131
|
+
case "many":
|
|
3132
|
+
case "oneOrMore":
|
|
3133
|
+
case "not":
|
|
3134
|
+
case "peek":
|
|
3135
|
+
case "transform":
|
|
3136
|
+
return hasNodeDef(d.parser, seen);
|
|
3137
|
+
case "sequence":
|
|
3138
|
+
case "choice":
|
|
3139
|
+
return d.parsers.some((x) => hasNodeDef(x, seen));
|
|
3140
|
+
case "dispatch":
|
|
3141
|
+
return hasNodeDef(d.selector, seen) || d.cases.some((x) => hasNodeDef(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => hasNodeDef(entry.parser, seen)) : false) || (d.otherwise ? hasNodeDef(d.otherwise, seen) : false);
|
|
3142
|
+
case "sepBy":
|
|
3143
|
+
return hasNodeDef(d.parser, seen) || hasNodeDef(d.separator, seen);
|
|
3144
|
+
case "scanTo":
|
|
3145
|
+
return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen));
|
|
3146
|
+
case "recover":
|
|
3147
|
+
return hasNodeDef(d.parser, seen) || hasNodeDef(d.sentinel, seen);
|
|
3148
|
+
case "expect":
|
|
3149
|
+
return hasNodeDef(d.parser, seen);
|
|
3150
|
+
case "withCtx":
|
|
3151
|
+
return hasNodeDef(d.parser, seen);
|
|
3152
|
+
default:
|
|
3153
|
+
return false;
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve) {
|
|
3157
|
+
if (seen.has(p)) return false;
|
|
3158
|
+
seen.add(p);
|
|
3159
|
+
const d = p._def;
|
|
3160
|
+
switch (d.tag) {
|
|
3161
|
+
case "dispatch":
|
|
3162
|
+
return true;
|
|
3163
|
+
case "choice":
|
|
3164
|
+
case "sequence":
|
|
3165
|
+
return d.parsers.some((x) => mayCommitFailure(x, seen, resolve));
|
|
3166
|
+
case "many":
|
|
3167
|
+
case "oneOrMore":
|
|
3168
|
+
case "optional":
|
|
3169
|
+
case "attempt":
|
|
3170
|
+
case "transform":
|
|
3171
|
+
case "label":
|
|
3172
|
+
case "field":
|
|
3173
|
+
case "grammar":
|
|
3174
|
+
case "node":
|
|
3175
|
+
return mayCommitFailure(d.parser, seen, resolve);
|
|
3176
|
+
case "sepBy":
|
|
3177
|
+
return mayCommitFailure(d.parser, seen, resolve) || mayCommitFailure(d.separator, seen, resolve);
|
|
3178
|
+
case "token":
|
|
3179
|
+
case "leaf":
|
|
3180
|
+
return mayCommitFailure(d.parser, seen, resolve);
|
|
3181
|
+
case "withCtx":
|
|
3182
|
+
return mayCommitFailure(d.parser, seen, resolve);
|
|
3183
|
+
case "scanTo":
|
|
3184
|
+
return mayCommitFailure(d.sentinel, seen, resolve) || d.skip.some((x) => mayCommitFailure(x, seen, resolve));
|
|
3185
|
+
case "lazy": {
|
|
3186
|
+
try {
|
|
3187
|
+
return mayCommitFailure(d.thunk(), seen, resolve);
|
|
3188
|
+
} catch {
|
|
3189
|
+
const name = p._ruleName;
|
|
3190
|
+
const target = name === void 0 ? void 0 : resolve?.(name);
|
|
3191
|
+
return target === void 0 ? true : mayCommitFailure(target, seen, resolve);
|
|
3192
|
+
}
|
|
3193
|
+
}
|
|
3194
|
+
case "unknown":
|
|
3195
|
+
return true;
|
|
3196
|
+
default:
|
|
3197
|
+
return false;
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
|
|
3201
|
+
// src/recovery/scan.ts
|
|
3202
|
+
function probeAt(sentinel, input, pos, ctx) {
|
|
3203
|
+
const s = {
|
|
3204
|
+
_probe: ctx._probe,
|
|
3205
|
+
_errors: ctx._errors,
|
|
3206
|
+
_cstLeaves: ctx._cstLeaves,
|
|
3207
|
+
_cstChildren: ctx._cstChildren,
|
|
3208
|
+
_cstRawChildren: ctx._cstRawChildren,
|
|
3209
|
+
_cstTriviaLog: ctx._cstTriviaLog,
|
|
3210
|
+
_triviaLog: ctx._triviaLog,
|
|
3211
|
+
_rootTriviaLog: ctx._rootTriviaLog,
|
|
3212
|
+
_fields: ctx._fields,
|
|
3213
|
+
_cstBuf: ctx._cstBuf,
|
|
3214
|
+
_tolerant: ctx._tolerant,
|
|
3215
|
+
_sync: ctx._sync
|
|
3216
|
+
};
|
|
3217
|
+
ctx._probe = void 0;
|
|
3218
|
+
ctx._errors = void 0;
|
|
3219
|
+
ctx._cstLeaves = void 0;
|
|
3220
|
+
ctx._cstChildren = void 0;
|
|
3221
|
+
ctx._cstRawChildren = void 0;
|
|
3222
|
+
ctx._cstTriviaLog = void 0;
|
|
3223
|
+
ctx._triviaLog = void 0;
|
|
3224
|
+
ctx._rootTriviaLog = void 0;
|
|
3225
|
+
ctx._fields = void 0;
|
|
3226
|
+
ctx._cstBuf = void 0;
|
|
3227
|
+
ctx._tolerant = void 0;
|
|
3228
|
+
ctx._sync = void 0;
|
|
3229
|
+
try {
|
|
3230
|
+
return sentinel.parse(input, pos, ctx).ok;
|
|
3231
|
+
} finally {
|
|
3232
|
+
ctx._probe = s._probe;
|
|
3233
|
+
ctx._errors = s._errors;
|
|
3234
|
+
ctx._cstLeaves = s._cstLeaves;
|
|
3235
|
+
ctx._cstChildren = s._cstChildren;
|
|
3236
|
+
ctx._cstRawChildren = s._cstRawChildren;
|
|
3237
|
+
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
3238
|
+
ctx._triviaLog = s._triviaLog;
|
|
3239
|
+
ctx._rootTriviaLog = s._rootTriviaLog;
|
|
3240
|
+
ctx._fields = s._fields;
|
|
3241
|
+
ctx._cstBuf = s._cstBuf;
|
|
3242
|
+
ctx._tolerant = s._tolerant;
|
|
3243
|
+
ctx._sync = s._sync;
|
|
3244
|
+
}
|
|
3245
|
+
}
|
|
3246
|
+
function orSentinel(a, b) {
|
|
3247
|
+
if (b === void 0) return a;
|
|
3248
|
+
return {
|
|
3249
|
+
_tag: "orSentinel",
|
|
3250
|
+
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
3251
|
+
_def: { tag: "unknown" },
|
|
3252
|
+
parse(input, pos, ctx) {
|
|
3253
|
+
const ra = a.parse(input, pos, ctx);
|
|
3254
|
+
if (ra.ok) return ra;
|
|
3255
|
+
return b.parse(input, pos, ctx);
|
|
3256
|
+
}
|
|
3257
|
+
};
|
|
3258
|
+
}
|
|
3259
|
+
function firstSetSentinel(fs) {
|
|
3260
|
+
if (fs.kind !== "ranges" || fs.ranges.length === 0) return null;
|
|
3261
|
+
const ranges = fs.ranges;
|
|
3262
|
+
return {
|
|
3263
|
+
_tag: "firstSetSentinel",
|
|
3264
|
+
_meta: { firstSet: fs, canMatchNewline: false, isTrivia: false },
|
|
3265
|
+
_def: { tag: "unknown" },
|
|
3266
|
+
parse(input, pos) {
|
|
3267
|
+
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
3268
|
+
if (code !== void 0) {
|
|
3269
|
+
for (const r of ranges) {
|
|
3270
|
+
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
3271
|
+
}
|
|
3272
|
+
}
|
|
3273
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
3274
|
+
}
|
|
3275
|
+
};
|
|
3276
|
+
}
|
|
3277
|
+
function recoverScan(input, from, ctx, sync, expected) {
|
|
3278
|
+
let scanPos = from;
|
|
3279
|
+
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
3280
|
+
const span = { start: from, end: scanPos };
|
|
3281
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
3282
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
3283
|
+
ctx._errors?.push(error);
|
|
3284
|
+
return { error, end: scanPos };
|
|
3285
|
+
}
|
|
3286
|
+
function matchesAt(sentinel, input, pos, ctx) {
|
|
3287
|
+
return probeAt(sentinel, input, pos, ctx);
|
|
3288
|
+
}
|
|
3289
|
+
function captureError(ctx, error) {
|
|
3290
|
+
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
3291
|
+
}
|
|
3292
|
+
|
|
3293
|
+
// src/combinators/expect.ts
|
|
3294
|
+
function deriveExpected(c) {
|
|
3295
|
+
return [...new Set(derive(c, /* @__PURE__ */ new Set()))];
|
|
3296
|
+
}
|
|
3297
|
+
function derive(c, seen) {
|
|
3298
|
+
const deriveExpected2 = (p) => derive(p, seen);
|
|
3299
|
+
const def = c._def;
|
|
3300
|
+
switch (def.tag) {
|
|
3301
|
+
case "literal":
|
|
3302
|
+
return [JSON.stringify(def.value)];
|
|
3303
|
+
case "regex":
|
|
3304
|
+
return [`/${def.source}/`];
|
|
3305
|
+
case "keywords":
|
|
3306
|
+
return def.words.map((w) => JSON.stringify(w));
|
|
3307
|
+
case "label":
|
|
3308
|
+
return [def.label];
|
|
3309
|
+
case "choice":
|
|
3310
|
+
return def.parsers.flatMap(deriveExpected2);
|
|
3311
|
+
case "dispatch":
|
|
3312
|
+
return deriveExpected2(def.selector);
|
|
3313
|
+
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
3314
|
+
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
3315
|
+
// able to fail first — deriving from term 0 alone named a token the parse
|
|
3316
|
+
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
3317
|
+
// nothing (its own expectation is about what must NOT be here), but it is
|
|
3318
|
+
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
3319
|
+
case "sequence": {
|
|
3320
|
+
const out = [];
|
|
3321
|
+
for (const term of def.parsers) {
|
|
3322
|
+
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
3323
|
+
if (!matchesEmpty(term)) break;
|
|
3324
|
+
}
|
|
3325
|
+
return out;
|
|
3326
|
+
}
|
|
3327
|
+
case "attempt":
|
|
3328
|
+
return deriveExpected2(def.parser);
|
|
3329
|
+
// Delegating wrappers whose first-token failure is their inner parser's — must
|
|
3330
|
+
// pass through so a start-failure (and the first-set-miss fast-path in attempt/
|
|
3331
|
+
// node, which reads this) names the real expected token, not the wrapper tag.
|
|
3332
|
+
case "field":
|
|
3333
|
+
case "withCtx":
|
|
3334
|
+
case "recover":
|
|
3335
|
+
return deriveExpected2(def.parser);
|
|
3336
|
+
case "expect":
|
|
3337
|
+
return def.expected;
|
|
3338
|
+
case "node":
|
|
3339
|
+
case "grammar":
|
|
3340
|
+
case "trivia":
|
|
3341
|
+
case "token":
|
|
3342
|
+
case "leaf":
|
|
3343
|
+
case "optional":
|
|
3344
|
+
case "many":
|
|
3345
|
+
case "oneOrMore":
|
|
3346
|
+
case "transform":
|
|
3347
|
+
case "not":
|
|
3348
|
+
case "peek":
|
|
3349
|
+
return deriveExpected2(def.parser);
|
|
3350
|
+
// A bare routed() can only fail as "there is no routed token here". With a
|
|
3351
|
+
// fallback, THAT is the branch that can fail, so its expectations are the useful
|
|
3352
|
+
// ones — the routed path either succeeds or is not taken.
|
|
3353
|
+
case "routed":
|
|
3354
|
+
return def.fallback === void 0 ? ["routed()"] : deriveExpected2(def.fallback);
|
|
3355
|
+
// A bare adjacency assertion names the JOIN it requires. Inside a sequence it is
|
|
3356
|
+
// skipped entirely (isZeroWidthAssertion, above), which is the normal path.
|
|
3357
|
+
case "adjacency":
|
|
3358
|
+
return [def.polarity];
|
|
3359
|
+
case "lazy": {
|
|
3360
|
+
const name = c._ruleName;
|
|
3361
|
+
if (seen.has(c)) return name ? [name] : [];
|
|
3362
|
+
seen.add(c);
|
|
3363
|
+
try {
|
|
3364
|
+
return deriveExpected2(def.thunk());
|
|
3365
|
+
} catch {
|
|
3366
|
+
return name ? [name] : [];
|
|
3367
|
+
} finally {
|
|
3368
|
+
seen.delete(c);
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
default:
|
|
3372
|
+
return [];
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
function expect(combinator, label2) {
|
|
3376
|
+
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
3377
|
+
const meta = {
|
|
3378
|
+
firstSet: combinator._meta.firstSet,
|
|
3379
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
3380
|
+
isTrivia: false
|
|
3381
|
+
};
|
|
3382
|
+
return {
|
|
3383
|
+
_tag: "expect",
|
|
3384
|
+
_meta: meta,
|
|
3385
|
+
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
3386
|
+
parse(input, pos, ctx) {
|
|
3387
|
+
const result = combinator.parse(input, pos, ctx);
|
|
3388
|
+
if (result.ok) return result;
|
|
3389
|
+
const span = { start: pos, end: pos };
|
|
3390
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
3391
|
+
ctx._errors?.push(error);
|
|
3392
|
+
if (ctx._tolerant) captureError(ctx, error);
|
|
3393
|
+
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
3394
|
+
}
|
|
3395
|
+
};
|
|
3396
|
+
}
|
|
3397
|
+
|
|
3398
|
+
// src/combinators/choice.ts
|
|
3399
|
+
function choice(...args) {
|
|
3400
|
+
const parsers = args.map((a) => "gate" in a ? a.combinator : a);
|
|
3401
|
+
const gates = args.map((a) => "gate" in a ? a.gate : null);
|
|
3402
|
+
const hasGates = gates.some((g) => g !== null);
|
|
3403
|
+
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
3404
|
+
let combined = { kind: "empty" };
|
|
3405
|
+
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
3406
|
+
const meta = {
|
|
3407
|
+
firstSet: combined,
|
|
3408
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
3409
|
+
isTrivia: false,
|
|
3410
|
+
disjoint
|
|
3411
|
+
};
|
|
3412
|
+
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
3413
|
+
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
3414
|
+
let greedyLitMap = null;
|
|
3415
|
+
let sortedParsers = null;
|
|
3416
|
+
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
2839
3417
|
if (strategy?.tag === "greedyClassify") {
|
|
2840
3418
|
greedyLitMap = /* @__PURE__ */ new Map();
|
|
2841
3419
|
for (let i = 0; i < parsers.length; i++) {
|
|
@@ -3363,6 +3941,7 @@ function confirmedArityForDef(def) {
|
|
|
3363
3941
|
}
|
|
3364
3942
|
function buildReadsRaw(def) {
|
|
3365
3943
|
if (!def.build) return true;
|
|
3944
|
+
if (def.buildRawUnused === true) return false;
|
|
3366
3945
|
const arity = confirmedArityForDef(def);
|
|
3367
3946
|
if (arity === null) return true;
|
|
3368
3947
|
return arity >= 4;
|
|
@@ -4420,381 +4999,125 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4420
4999
|
let sepPos = cur;
|
|
4421
5000
|
if (ctx.trivia) {
|
|
4422
5001
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
4423
|
-
sepPos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
4424
|
-
} else {
|
|
4425
|
-
sepPos = advanceTrivia(input, cur, ctx);
|
|
4426
|
-
}
|
|
4427
|
-
}
|
|
4428
|
-
const sep = separator.parse(input, sepPos, ctx);
|
|
4429
|
-
if (!sep.ok) {
|
|
4430
|
-
rollbackTrivia(ctx, loopMark);
|
|
4431
|
-
if (sep.committed) return sep;
|
|
4432
|
-
break;
|
|
4433
|
-
}
|
|
4434
|
-
if (!keepSeparators) demoteCapturedToRaw(ctx, loopMark.leaves);
|
|
4435
|
-
const sepMark = trailing === "forbid" ? void 0 : saveTriviaMark(ctx);
|
|
4436
|
-
let nextPos = sep.span.end;
|
|
4437
|
-
if (ctx.trivia) {
|
|
4438
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
4439
|
-
nextPos = commitTriviaScan(scanTriviaCompact(input, sep.span.end, ctx));
|
|
4440
|
-
} else {
|
|
4441
|
-
nextPos = advanceTrivia(input, sep.span.end, ctx);
|
|
4442
|
-
}
|
|
4443
|
-
}
|
|
4444
|
-
const next = combinator.parse(input, nextPos, ctx);
|
|
4445
|
-
if (!next.ok) {
|
|
4446
|
-
if (next.committed) return next;
|
|
4447
|
-
const term = ctx._tolerant ? ctx._sync : void 0;
|
|
4448
|
-
if (term !== void 0 && !matchesAt(term, input, nextPos, ctx)) {
|
|
4449
|
-
expected ??= deriveExpected(combinator);
|
|
4450
|
-
const rec = recoverScan(input, nextPos, ctx, orSentinel(separator, term), expected);
|
|
4451
|
-
values.push(rec.error);
|
|
4452
|
-
captureError(ctx, rec.error);
|
|
4453
|
-
cur = rec.end;
|
|
4454
|
-
continue;
|
|
4455
|
-
}
|
|
4456
|
-
if (sepMark !== void 0) {
|
|
4457
|
-
rollbackTrivia(ctx, sepMark);
|
|
4458
|
-
cur = sep.span.end;
|
|
4459
|
-
break;
|
|
4460
|
-
}
|
|
4461
|
-
rollbackTrivia(ctx, loopMark);
|
|
4462
|
-
break;
|
|
4463
|
-
}
|
|
4464
|
-
values.push(next.value);
|
|
4465
|
-
cur = next.span.end;
|
|
4466
|
-
}
|
|
4467
|
-
if (values.length < min) return failAt2(cur);
|
|
4468
|
-
return { ok: true, value: values, span: { start: pos, end: cur } };
|
|
4469
|
-
}
|
|
4470
|
-
};
|
|
4471
|
-
}
|
|
4472
|
-
|
|
4473
|
-
// src/combinators/map.ts
|
|
4474
|
-
function transform(combinator, fn) {
|
|
4475
|
-
return {
|
|
4476
|
-
_tag: "transform",
|
|
4477
|
-
_meta: combinator._meta,
|
|
4478
|
-
_def: { tag: "transform", parser: combinator, fn },
|
|
4479
|
-
parse(input, pos, ctx) {
|
|
4480
|
-
const result = combinator.parse(input, pos, ctx);
|
|
4481
|
-
if (!result.ok) return result;
|
|
4482
|
-
return { ok: true, value: fn(result.value, result.span), span: result.span };
|
|
4483
|
-
}
|
|
4484
|
-
};
|
|
4485
|
-
}
|
|
4486
|
-
function trivia(combinator) {
|
|
4487
|
-
const kindLabels = analyzeLabeledTrivia(combinator)?.labels;
|
|
4488
|
-
return {
|
|
4489
|
-
_tag: combinator._tag,
|
|
4490
|
-
_meta: {
|
|
4491
|
-
...combinator._meta,
|
|
4492
|
-
isTrivia: true,
|
|
4493
|
-
...kindLabels ? { triviaKindLabels: kindLabels } : {}
|
|
4494
|
-
},
|
|
4495
|
-
_def: { tag: "trivia", parser: combinator },
|
|
4496
|
-
parse: combinator.parse.bind(combinator)
|
|
4497
|
-
};
|
|
4498
|
-
}
|
|
4499
|
-
function classifiedTrivia(arms) {
|
|
4500
|
-
const entries = Object.entries(arms);
|
|
4501
|
-
if (entries.length === 0) {
|
|
4502
|
-
throw new TypeError("classifiedTrivia() requires at least one named trivia arm.");
|
|
4503
|
-
}
|
|
4504
|
-
for (let i = 0; i < entries.length; i++) {
|
|
4505
|
-
const [name, arm] = entries[i];
|
|
4506
|
-
const first = arm._meta.firstSet;
|
|
4507
|
-
if (matchesEmpty(arm) || first.kind !== "ranges" || first.ranges.length === 0) {
|
|
4508
|
-
throw new TypeError(
|
|
4509
|
-
`classifiedTrivia(): ${JSON.stringify(name)} must be non-nullable with a concrete finite first set.`
|
|
4510
|
-
);
|
|
4511
|
-
}
|
|
4512
|
-
}
|
|
4513
|
-
const labeledArms = entries.map(([name, arm]) => label(name, arm));
|
|
4514
|
-
const result = trivia(oneOrMore(choice(...labeledArms)));
|
|
4515
|
-
result._meta.rootTriviaClassified = true;
|
|
4516
|
-
return result;
|
|
4517
|
-
}
|
|
4518
|
-
function label(name, combinator) {
|
|
4519
|
-
return {
|
|
4520
|
-
_tag: combinator._tag,
|
|
4521
|
-
_meta: combinator._meta,
|
|
4522
|
-
_def: { tag: "label", label: name, parser: combinator },
|
|
4523
|
-
parse(input, pos, ctx) {
|
|
4524
|
-
const result = combinator.parse(input, pos, ctx);
|
|
4525
|
-
if (!result.ok) return { ok: false, expected: [name], span: result.span };
|
|
4526
|
-
return result;
|
|
4527
|
-
}
|
|
4528
|
-
};
|
|
4529
|
-
}
|
|
4530
|
-
function field(name, combinator) {
|
|
4531
|
-
return {
|
|
4532
|
-
_tag: combinator._tag,
|
|
4533
|
-
_meta: combinator._meta,
|
|
4534
|
-
_def: { tag: "field", name, parser: combinator },
|
|
4535
|
-
parse(input, pos, ctx) {
|
|
4536
|
-
const result = combinator.parse(input, pos, ctx);
|
|
4537
|
-
if (!result.ok) return result;
|
|
4538
|
-
ctx._fields?.push({ name, value: result.value, span: result.span });
|
|
4539
|
-
return result;
|
|
4540
|
-
}
|
|
4541
|
-
};
|
|
4542
|
-
}
|
|
4543
|
-
|
|
4544
|
-
// src/regex/first-set.ts
|
|
4545
|
-
var ANY = { t: "any" };
|
|
4546
|
-
var EMPTY2 = { t: "empty" };
|
|
4547
|
-
function charNode(set, nl) {
|
|
4548
|
-
return { t: "char", set, nl };
|
|
4549
|
-
}
|
|
4550
|
-
function rangesToSet(ranges) {
|
|
4551
|
-
let fs = empty();
|
|
4552
|
-
for (const [lo, hi] of ranges) fs = union(fs, fromRange(lo, hi));
|
|
4553
|
-
return fs;
|
|
4554
|
-
}
|
|
4555
|
-
function rangesHaveNewline(ranges) {
|
|
4556
|
-
return ranges.some(([lo, hi]) => lo <= 10 && 10 <= hi);
|
|
4557
|
-
}
|
|
4558
|
-
var BAIL = /* @__PURE__ */ Symbol("regex-bail");
|
|
4559
|
-
function parseRegex(src) {
|
|
4560
|
-
let i = 0;
|
|
4561
|
-
const parseAlt = () => {
|
|
4562
|
-
const arms = [parseSeq()];
|
|
4563
|
-
while (src[i] === "|") {
|
|
4564
|
-
i++;
|
|
4565
|
-
arms.push(parseSeq());
|
|
4566
|
-
}
|
|
4567
|
-
return arms.length === 1 ? arms[0] : { t: "alt", arms };
|
|
4568
|
-
};
|
|
4569
|
-
const parseSeq = () => {
|
|
4570
|
-
const parts = [];
|
|
4571
|
-
while (i < src.length) {
|
|
4572
|
-
const ch2 = src[i];
|
|
4573
|
-
if (ch2 === "|" || ch2 === ")") break;
|
|
4574
|
-
parts.push(parseQuantified());
|
|
4575
|
-
}
|
|
4576
|
-
if (parts.length === 0) return EMPTY2;
|
|
4577
|
-
return parts.length === 1 ? parts[0] : { t: "seq", parts };
|
|
4578
|
-
};
|
|
4579
|
-
const parseQuantified = () => {
|
|
4580
|
-
const atom = parseAtom();
|
|
4581
|
-
const ch2 = src[i];
|
|
4582
|
-
let min = null;
|
|
4583
|
-
if (ch2 === "*") {
|
|
4584
|
-
min = 0;
|
|
4585
|
-
i++;
|
|
4586
|
-
} else if (ch2 === "+") {
|
|
4587
|
-
min = 1;
|
|
4588
|
-
i++;
|
|
4589
|
-
} else if (ch2 === "?") {
|
|
4590
|
-
min = 0;
|
|
4591
|
-
i++;
|
|
4592
|
-
} else if (ch2 === "{") {
|
|
4593
|
-
min = parseBraceQuantifier();
|
|
4594
|
-
}
|
|
4595
|
-
if (min === null) return atom;
|
|
4596
|
-
if (src[i] === "?") i++;
|
|
4597
|
-
return { t: "rep", node: atom, min };
|
|
4598
|
-
};
|
|
4599
|
-
const parseBraceQuantifier = () => {
|
|
4600
|
-
const close = src.indexOf("}", i);
|
|
4601
|
-
if (close === -1) return null;
|
|
4602
|
-
const m = /^(\d+)(?:,(\d*))?$/.exec(src.slice(i + 1, close));
|
|
4603
|
-
if (!m) return null;
|
|
4604
|
-
i = close + 1;
|
|
4605
|
-
return Number.parseInt(m[1], 10);
|
|
4606
|
-
};
|
|
4607
|
-
const parseAtom = () => {
|
|
4608
|
-
const ch2 = src[i];
|
|
4609
|
-
switch (ch2) {
|
|
4610
|
-
case "(":
|
|
4611
|
-
return parseGroup();
|
|
4612
|
-
case "[":
|
|
4613
|
-
return parseClass();
|
|
4614
|
-
case ".":
|
|
4615
|
-
i++;
|
|
4616
|
-
return charNode(any(), false);
|
|
4617
|
-
// `.` matches any char except line terminators
|
|
4618
|
-
case "\\":
|
|
4619
|
-
return parseEscape();
|
|
4620
|
-
case "^":
|
|
4621
|
-
case "$":
|
|
4622
|
-
i++;
|
|
4623
|
-
return EMPTY2;
|
|
4624
|
-
// anchors are zero-width
|
|
4625
|
-
case "{":
|
|
4626
|
-
i++;
|
|
4627
|
-
return charNode(fromRange(123, 123), false);
|
|
4628
|
-
// a `{` with nothing to quantify is a literal brace
|
|
4629
|
-
default:
|
|
4630
|
-
i += ch2.length;
|
|
4631
|
-
return charNode(fromRange(ch2.codePointAt(0), ch2.codePointAt(0)), ch2 === "\n");
|
|
4632
|
-
}
|
|
4633
|
-
};
|
|
4634
|
-
const parseGroup = () => {
|
|
4635
|
-
i++;
|
|
4636
|
-
let lookaround = false;
|
|
4637
|
-
if (src[i] === "?") {
|
|
4638
|
-
const c1 = src[i + 1];
|
|
4639
|
-
if (c1 === ":") i += 2;
|
|
4640
|
-
else if (c1 === "=" || c1 === "!") {
|
|
4641
|
-
i += 2;
|
|
4642
|
-
lookaround = true;
|
|
4643
|
-
} else if (c1 === "<") {
|
|
4644
|
-
const c2 = src[i + 2];
|
|
4645
|
-
if (c2 === "=" || c2 === "!") {
|
|
4646
|
-
i += 3;
|
|
4647
|
-
lookaround = true;
|
|
4648
|
-
} else {
|
|
4649
|
-
const gt = src.indexOf(">", i);
|
|
4650
|
-
if (gt === -1) throw BAIL;
|
|
4651
|
-
i = gt + 1;
|
|
5002
|
+
sepPos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
5003
|
+
} else {
|
|
5004
|
+
sepPos = advanceTrivia(input, cur, ctx);
|
|
5005
|
+
}
|
|
4652
5006
|
}
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
5007
|
+
const sep = separator.parse(input, sepPos, ctx);
|
|
5008
|
+
if (!sep.ok) {
|
|
5009
|
+
rollbackTrivia(ctx, loopMark);
|
|
5010
|
+
if (sep.committed) return sep;
|
|
5011
|
+
break;
|
|
5012
|
+
}
|
|
5013
|
+
if (!keepSeparators) demoteCapturedToRaw(ctx, loopMark.leaves);
|
|
5014
|
+
const sepMark = trailing === "forbid" ? void 0 : saveTriviaMark(ctx);
|
|
5015
|
+
let nextPos = sep.span.end;
|
|
5016
|
+
if (ctx.trivia) {
|
|
5017
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
5018
|
+
nextPos = commitTriviaScan(scanTriviaCompact(input, sep.span.end, ctx));
|
|
5019
|
+
} else {
|
|
5020
|
+
nextPos = advanceTrivia(input, sep.span.end, ctx);
|
|
5021
|
+
}
|
|
5022
|
+
}
|
|
5023
|
+
const next = combinator.parse(input, nextPos, ctx);
|
|
5024
|
+
if (!next.ok) {
|
|
5025
|
+
if (next.committed) return next;
|
|
5026
|
+
const term = ctx._tolerant ? ctx._sync : void 0;
|
|
5027
|
+
if (term !== void 0 && !matchesAt(term, input, nextPos, ctx)) {
|
|
5028
|
+
expected ??= deriveExpected(combinator);
|
|
5029
|
+
const rec = recoverScan(input, nextPos, ctx, orSentinel(separator, term), expected);
|
|
5030
|
+
values.push(rec.error);
|
|
5031
|
+
captureError(ctx, rec.error);
|
|
5032
|
+
cur = rec.end;
|
|
5033
|
+
continue;
|
|
5034
|
+
}
|
|
5035
|
+
if (sepMark !== void 0) {
|
|
5036
|
+
rollbackTrivia(ctx, sepMark);
|
|
5037
|
+
cur = sep.span.end;
|
|
5038
|
+
break;
|
|
5039
|
+
}
|
|
5040
|
+
rollbackTrivia(ctx, loopMark);
|
|
5041
|
+
break;
|
|
5042
|
+
}
|
|
5043
|
+
values.push(next.value);
|
|
5044
|
+
cur = next.span.end;
|
|
4672
5045
|
}
|
|
5046
|
+
if (values.length < min) return failAt2(cur);
|
|
5047
|
+
return { ok: true, value: values, span: { start: pos, end: cur } };
|
|
4673
5048
|
}
|
|
4674
|
-
if (src[k] !== "]") throw BAIL;
|
|
4675
|
-
i = k + 1;
|
|
4676
|
-
const ranges = parseClassRanges(body);
|
|
4677
|
-
if (negated) return charNode(any(), !ranges || !rangesHaveNewline(ranges));
|
|
4678
|
-
if (!ranges) return charNode(any(), true);
|
|
4679
|
-
return charNode(rangesToSet(ranges), rangesHaveNewline(ranges));
|
|
4680
5049
|
};
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
}
|
|
4689
|
-
|
|
4690
|
-
const
|
|
4691
|
-
|
|
4692
|
-
return
|
|
4693
|
-
}
|
|
4694
|
-
i += 2;
|
|
4695
|
-
switch (e) {
|
|
4696
|
-
case "d":
|
|
4697
|
-
return charNode(rangesToSet(shorthandRanges("d")), false);
|
|
4698
|
-
case "w":
|
|
4699
|
-
return charNode(rangesToSet(shorthandRanges("w")), false);
|
|
4700
|
-
case "s":
|
|
4701
|
-
return charNode(rangesToSet(shorthandRanges("s")), true);
|
|
4702
|
-
case "D":
|
|
4703
|
-
case "W":
|
|
4704
|
-
case "S":
|
|
4705
|
-
return charNode(any(), true);
|
|
4706
|
-
// negated shorthand → widen
|
|
4707
|
-
case "b":
|
|
4708
|
-
case "B":
|
|
4709
|
-
return EMPTY2;
|
|
4710
|
-
// word boundary: zero-width
|
|
4711
|
-
case "n":
|
|
4712
|
-
return charNode(fromRange(10, 10), true);
|
|
4713
|
-
case "r":
|
|
4714
|
-
return charNode(fromRange(13, 13), false);
|
|
4715
|
-
case "t":
|
|
4716
|
-
return charNode(fromRange(9, 9), false);
|
|
4717
|
-
case "f":
|
|
4718
|
-
return charNode(fromRange(12, 12), false);
|
|
4719
|
-
case "v":
|
|
4720
|
-
return charNode(fromRange(11, 11), false);
|
|
4721
|
-
case "0":
|
|
4722
|
-
return charNode(fromRange(0, 0), false);
|
|
4723
|
-
default:
|
|
4724
|
-
if (e >= "1" && e <= "9") return ANY;
|
|
4725
|
-
return charNode(fromRange(e.codePointAt(0), e.codePointAt(0)), e === "\n");
|
|
5050
|
+
}
|
|
5051
|
+
|
|
5052
|
+
// src/combinators/map.ts
|
|
5053
|
+
function transform(combinator, fn) {
|
|
5054
|
+
return {
|
|
5055
|
+
_tag: "transform",
|
|
5056
|
+
_meta: combinator._meta,
|
|
5057
|
+
_def: { tag: "transform", parser: combinator, fn },
|
|
5058
|
+
parse(input, pos, ctx) {
|
|
5059
|
+
const result = combinator.parse(input, pos, ctx);
|
|
5060
|
+
if (!result.ok) return result;
|
|
5061
|
+
return { ok: true, value: fn(result.value, result.span), span: result.span };
|
|
4726
5062
|
}
|
|
4727
5063
|
};
|
|
4728
|
-
const node2 = parseAlt();
|
|
4729
|
-
if (i < src.length) throw BAIL;
|
|
4730
|
-
return node2;
|
|
4731
5064
|
}
|
|
4732
|
-
function
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
case "rep":
|
|
4745
|
-
return n.min === 0 || nullable(n.node);
|
|
4746
|
-
}
|
|
5065
|
+
function trivia(combinator) {
|
|
5066
|
+
const kindLabels = analyzeLabeledTrivia(combinator)?.labels;
|
|
5067
|
+
return {
|
|
5068
|
+
_tag: combinator._tag,
|
|
5069
|
+
_meta: {
|
|
5070
|
+
...combinator._meta,
|
|
5071
|
+
isTrivia: true,
|
|
5072
|
+
...kindLabels ? { triviaKindLabels: kindLabels } : {}
|
|
5073
|
+
},
|
|
5074
|
+
_def: { tag: "trivia", parser: combinator },
|
|
5075
|
+
parse: combinator.parse.bind(combinator)
|
|
5076
|
+
};
|
|
4747
5077
|
}
|
|
4748
|
-
function
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
for (const arm of n.arms) fs = union(fs, firstSet(arm));
|
|
4761
|
-
return fs;
|
|
4762
|
-
}
|
|
4763
|
-
case "seq": {
|
|
4764
|
-
let fs = empty();
|
|
4765
|
-
for (const part of n.parts) {
|
|
4766
|
-
fs = union(fs, firstSet(part));
|
|
4767
|
-
if (!nullable(part)) break;
|
|
4768
|
-
}
|
|
4769
|
-
return fs;
|
|
5078
|
+
function classifiedTrivia(arms) {
|
|
5079
|
+
const entries = Object.entries(arms);
|
|
5080
|
+
if (entries.length === 0) {
|
|
5081
|
+
throw new TypeError("classifiedTrivia() requires at least one named trivia arm.");
|
|
5082
|
+
}
|
|
5083
|
+
for (let i = 0; i < entries.length; i++) {
|
|
5084
|
+
const [name, arm] = entries[i];
|
|
5085
|
+
const first = arm._meta.firstSet;
|
|
5086
|
+
if (matchesEmpty(arm) || first.kind !== "ranges" || first.ranges.length === 0) {
|
|
5087
|
+
throw new TypeError(
|
|
5088
|
+
`classifiedTrivia(): ${JSON.stringify(name)} must be non-nullable with a concrete finite first set.`
|
|
5089
|
+
);
|
|
4770
5090
|
}
|
|
4771
5091
|
}
|
|
5092
|
+
const labeledArms = entries.map(([name, arm]) => label(name, arm));
|
|
5093
|
+
const result = trivia(oneOrMore(choice(...labeledArms)));
|
|
5094
|
+
result._meta.rootTriviaClassified = true;
|
|
5095
|
+
return result;
|
|
4772
5096
|
}
|
|
4773
|
-
function
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
return false;
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
return n.arms.some(canConsumeNewline);
|
|
4785
|
-
case "seq":
|
|
4786
|
-
return n.parts.some(canConsumeNewline);
|
|
4787
|
-
}
|
|
5097
|
+
function label(name, combinator) {
|
|
5098
|
+
return {
|
|
5099
|
+
_tag: combinator._tag,
|
|
5100
|
+
_meta: combinator._meta,
|
|
5101
|
+
_def: { tag: "label", label: name, parser: combinator },
|
|
5102
|
+
parse(input, pos, ctx) {
|
|
5103
|
+
const result = combinator.parse(input, pos, ctx);
|
|
5104
|
+
if (!result.ok) return { ok: false, expected: [name], span: result.span };
|
|
5105
|
+
return result;
|
|
5106
|
+
}
|
|
5107
|
+
};
|
|
4788
5108
|
}
|
|
4789
|
-
function
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
5109
|
+
function field(name, combinator) {
|
|
5110
|
+
return {
|
|
5111
|
+
_tag: combinator._tag,
|
|
5112
|
+
_meta: combinator._meta,
|
|
5113
|
+
_def: { tag: "field", name, parser: combinator },
|
|
5114
|
+
parse(input, pos, ctx) {
|
|
5115
|
+
const result = combinator.parse(input, pos, ctx);
|
|
5116
|
+
if (!result.ok) return result;
|
|
5117
|
+
ctx._fields?.push({ name, value: result.value, span: result.span });
|
|
5118
|
+
return result;
|
|
5119
|
+
}
|
|
5120
|
+
};
|
|
4798
5121
|
}
|
|
4799
5122
|
|
|
4800
5123
|
// src/combinators/regex.ts
|
|
@@ -4983,8 +5306,26 @@ function validateDispatchSpec(spec, arity, fallbackRouted) {
|
|
|
4983
5306
|
}
|
|
4984
5307
|
}
|
|
4985
5308
|
var TABLE_RUNTIME = /* @__PURE__ */ Symbol("parseman.tableRuntime");
|
|
4986
|
-
function ownTableProgram(prog, resolved) {
|
|
4987
|
-
|
|
5309
|
+
function ownTableProgram(prog, resolved, caches = {}) {
|
|
5310
|
+
const runtime = prog[TABLE_RUNTIME];
|
|
5311
|
+
return {
|
|
5312
|
+
...prog,
|
|
5313
|
+
[TABLE_RUNTIME]: {
|
|
5314
|
+
resolved,
|
|
5315
|
+
choiceRollbackMasks: caches.choiceRollbackMasks ?? runtime?.choiceRollbackMasks,
|
|
5316
|
+
nonCommittingChoiceSites: caches.nonCommittingChoiceSites ?? runtime?.nonCommittingChoiceSites,
|
|
5317
|
+
failureRollbackCleanSites: caches.failureRollbackCleanSites ?? runtime?.failureRollbackCleanSites
|
|
5318
|
+
}
|
|
5319
|
+
};
|
|
5320
|
+
}
|
|
5321
|
+
function choiceRollbackMask(prog, ip) {
|
|
5322
|
+
return prog[TABLE_RUNTIME]?.choiceRollbackMasks?.get(ip);
|
|
5323
|
+
}
|
|
5324
|
+
function choiceCannotCommit(prog, ip) {
|
|
5325
|
+
return prog[TABLE_RUNTIME]?.nonCommittingChoiceSites?.has(ip) === true;
|
|
5326
|
+
}
|
|
5327
|
+
function failureRollbackClean(prog, ip) {
|
|
5328
|
+
return prog[TABLE_RUNTIME]?.failureRollbackCleanSites?.has(ip) === true;
|
|
4988
5329
|
}
|
|
4989
5330
|
var WIDE_CLASS_PREFIX_LO = 65535;
|
|
4990
5331
|
var WIDE_CLASS_PREFIX_HI = 0;
|
|
@@ -5159,7 +5500,6 @@ function directArrayProjection(fn, fnSrc, arity) {
|
|
|
5159
5500
|
|
|
5160
5501
|
// src/table/encode.ts
|
|
5161
5502
|
import {
|
|
5162
|
-
assertLexicalCapabilityClosure,
|
|
5163
5503
|
collectLexicalCapabilities,
|
|
5164
5504
|
winnerWrapsReference as winnerWrapsReference2
|
|
5165
5505
|
} from "../compiler/token-capability.js";
|
|
@@ -5541,6 +5881,25 @@ var Encoder = class {
|
|
|
5541
5881
|
lexIndex = /* @__PURE__ */ new Map();
|
|
5542
5882
|
lexPrograms = [];
|
|
5543
5883
|
lexProgramIndex = /* @__PURE__ */ new Map();
|
|
5884
|
+
choiceRollbackMasks = /* @__PURE__ */ new Map();
|
|
5885
|
+
nonCommittingChoiceSites = /* @__PURE__ */ new Set();
|
|
5886
|
+
failureRollbackCleanSites = /* @__PURE__ */ new Set();
|
|
5887
|
+
/**
|
|
5888
|
+
* `hasSideWriter` memo for `failureNeedsRollback`, shared across every call
|
|
5889
|
+
* for the lifetime of this `Encoder`. A cached entry is written only when
|
|
5890
|
+
* `complete` is true, which means the answer is a path-independent fact
|
|
5891
|
+
* about that combinator node — it does not depend on which root's traversal
|
|
5892
|
+
* asked, only on the node's own reachable subgraph. Scoping the memo per call
|
|
5893
|
+
* (as a local inside `failureNeedsRollback`) was correct but discarded that
|
|
5894
|
+
* fact after every arm, so a grammar with many ordered-choice arms / optional
|
|
5895
|
+
* / attempt sites re-walked the SAME shared rule graph from scratch for each
|
|
5896
|
+
* site — O(sites × graph size) instead of O(graph size). Measured on the
|
|
5897
|
+
* scss-parser grammar (composed CSS-base superset, the deepest/largest of the
|
|
5898
|
+
* four grammars): 47-50s for one `compileRuleMap` with the per-call memo,
|
|
5899
|
+
* versus the whole macro transform completing in under a second once this
|
|
5900
|
+
* memo is hoisted here.
|
|
5901
|
+
*/
|
|
5902
|
+
sideWriterMemo = /* @__PURE__ */ new Map();
|
|
5544
5903
|
labels = void 0;
|
|
5545
5904
|
/** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
|
|
5546
5905
|
activeTrivia = void 0;
|
|
@@ -5947,9 +6306,75 @@ var Encoder = class {
|
|
|
5947
6306
|
* nothing consults the resolver and nothing changes, which is why the runtime
|
|
5948
6307
|
* leg's counts are byte-for-byte what they were.
|
|
5949
6308
|
*/
|
|
5950
|
-
refResolver() {
|
|
5951
|
-
const w = this.winners;
|
|
5952
|
-
return w === void 0 ? void 0 : (name) => w[name];
|
|
6309
|
+
refResolver() {
|
|
6310
|
+
const w = this.winners;
|
|
6311
|
+
return w === void 0 ? void 0 : (name) => w[name];
|
|
6312
|
+
}
|
|
6313
|
+
/**
|
|
6314
|
+
* Whether a failed ordered-choice arm can leave state that the enclosing
|
|
6315
|
+
* choice must restore before trying its successor.
|
|
6316
|
+
*
|
|
6317
|
+
* `mayLeavePartialCapture` is the existing sound CST/trivia proof. The extra
|
|
6318
|
+
* writer census covers the side sinks that proof deliberately does not model:
|
|
6319
|
+
* fields, recovered errors, and interpreted scanners. Strict assemblies do
|
|
6320
|
+
* not run repeat recovery, but these rows can still publish through a caller's
|
|
6321
|
+
* context. Cycles are safe to stop: revisiting the same combinator cannot
|
|
6322
|
+
* discover a writer the first traversal did not already reach.
|
|
6323
|
+
*/
|
|
6324
|
+
failureNeedsRollback(p, autoNot) {
|
|
6325
|
+
const refName = p._ruleName;
|
|
6326
|
+
const winner = refName === void 0 ? void 0 : this.winners?.[refName];
|
|
6327
|
+
const root = winner !== void 0 && !winnerWrapsReference2(winner, p) ? winner : p;
|
|
6328
|
+
const sideWriterMemo = this.sideWriterMemo;
|
|
6329
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6330
|
+
const hasSideWriter = (current) => {
|
|
6331
|
+
const cached = sideWriterMemo.get(current);
|
|
6332
|
+
if (cached !== void 0) return { found: cached, complete: true };
|
|
6333
|
+
if (seen.has(current)) return { found: false, complete: false };
|
|
6334
|
+
seen.add(current);
|
|
6335
|
+
const def = current._def;
|
|
6336
|
+
let result;
|
|
6337
|
+
switch (def.tag) {
|
|
6338
|
+
case "field":
|
|
6339
|
+
case "expect":
|
|
6340
|
+
case "recover":
|
|
6341
|
+
case "scanTo":
|
|
6342
|
+
case "unknown":
|
|
6343
|
+
result = { found: true, complete: true };
|
|
6344
|
+
break;
|
|
6345
|
+
case "lazy": {
|
|
6346
|
+
const name = current._ruleName;
|
|
6347
|
+
const resolvedWinner = name === void 0 ? void 0 : this.winners?.[name];
|
|
6348
|
+
if (resolvedWinner !== void 0 && !winnerWrapsReference2(resolvedWinner, current)) {
|
|
6349
|
+
result = hasSideWriter(resolvedWinner);
|
|
6350
|
+
break;
|
|
6351
|
+
}
|
|
6352
|
+
try {
|
|
6353
|
+
result = hasSideWriter(def.thunk());
|
|
6354
|
+
} catch {
|
|
6355
|
+
result = { found: true, complete: true };
|
|
6356
|
+
}
|
|
6357
|
+
break;
|
|
6358
|
+
}
|
|
6359
|
+
default: {
|
|
6360
|
+
let complete = true;
|
|
6361
|
+
result = { found: false, complete: true };
|
|
6362
|
+
for (const child of childrenOf(def)) {
|
|
6363
|
+
const childResult = hasSideWriter(child);
|
|
6364
|
+
if (childResult.found) {
|
|
6365
|
+
result = { found: true, complete: true };
|
|
6366
|
+
break;
|
|
6367
|
+
}
|
|
6368
|
+
complete &&= childResult.complete;
|
|
6369
|
+
}
|
|
6370
|
+
if (!result.found) result = { found: false, complete };
|
|
6371
|
+
}
|
|
6372
|
+
}
|
|
6373
|
+
seen.delete(current);
|
|
6374
|
+
if (result.found || result.complete) sideWriterMemo.set(current, result.found);
|
|
6375
|
+
return result;
|
|
6376
|
+
};
|
|
6377
|
+
return mayLeavePartialCapture(root, /* @__PURE__ */ new Set(), true) || hasSideWriter(root).found || (autoNot?.length ?? 0) > 0 && capturesLeaf(root);
|
|
5953
6378
|
}
|
|
5954
6379
|
/** A first set becomes a char class string, or −1 for `any`. */
|
|
5955
6380
|
charClass(fs) {
|
|
@@ -6236,9 +6661,39 @@ var Encoder = class {
|
|
|
6236
6661
|
});
|
|
6237
6662
|
const rr = this.refResolver();
|
|
6238
6663
|
const finalChoice = classifyFinalChoice(arms, rr);
|
|
6239
|
-
const
|
|
6664
|
+
const transactionalFirst = arms.map((arm, i) => {
|
|
6665
|
+
if (!finalChoice.nullable[i]) return void 0;
|
|
6666
|
+
const def = arm._def;
|
|
6667
|
+
if (def.tag !== "attempt" || matchesEmpty(def.parser, /* @__PURE__ */ new Set(), rr)) return void 0;
|
|
6668
|
+
return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr);
|
|
6669
|
+
});
|
|
6670
|
+
const gateFirst = finalChoice.firstSets.map((first, i) => transactionalFirst[i] ?? first);
|
|
6671
|
+
const classes = gateFirst.map((first, i) => finalChoice.nullable[i] && transactionalFirst[i] === void 0 ? -1 : this.charClass(first));
|
|
6672
|
+
if (transactionalFirst.some((first) => first !== void 0) && classes.every((cls) => cls >= 0)) {
|
|
6673
|
+
let overlap = false;
|
|
6674
|
+
for (let i = 0; i < gateFirst.length && !overlap; i++) {
|
|
6675
|
+
for (let j = i + 1; j < gateFirst.length; j++) {
|
|
6676
|
+
if (intersects(gateFirst[i], gateFirst[j])) {
|
|
6677
|
+
overlap = true;
|
|
6678
|
+
break;
|
|
6679
|
+
}
|
|
6680
|
+
}
|
|
6681
|
+
}
|
|
6682
|
+
if (!overlap) for (let i = 0; i < classes.length; i++) {
|
|
6683
|
+
if (transactionalFirst[i] !== void 0) classes[i] = -1;
|
|
6684
|
+
}
|
|
6685
|
+
}
|
|
6240
6686
|
const dispIdx = this.disp.length;
|
|
6241
6687
|
this.disp.push(classes);
|
|
6688
|
+
let rollbackMask = kids.length > 31 ? -1 : 0;
|
|
6689
|
+
if (rollbackMask === 0) {
|
|
6690
|
+
for (let i = 0; i < arms.length; i++) {
|
|
6691
|
+
const src = order[i];
|
|
6692
|
+
if (this.failureNeedsRollback(arms[i], d.autoNot[src])) {
|
|
6693
|
+
rollbackMask |= 1 << i;
|
|
6694
|
+
}
|
|
6695
|
+
}
|
|
6696
|
+
}
|
|
6242
6697
|
const head = this.emitHead(OP_CHOICE, 3 + 2 * kids.length);
|
|
6243
6698
|
this.code[head + 1] = dispIdx;
|
|
6244
6699
|
this.code[head + 2] = kids.length;
|
|
@@ -6247,6 +6702,10 @@ var Encoder = class {
|
|
|
6247
6702
|
this.code[head + 4 + i] = kids[i];
|
|
6248
6703
|
this.code[head + 4 + kids.length + i] = this.expected(deriveExpected(arms[i]));
|
|
6249
6704
|
}
|
|
6705
|
+
this.choiceRollbackMasks.set(head, rollbackMask);
|
|
6706
|
+
if (arms.every((arm) => !mayCommitFailure(arm, /* @__PURE__ */ new Set(), rr))) {
|
|
6707
|
+
this.nonCommittingChoiceSites.add(head);
|
|
6708
|
+
}
|
|
6250
6709
|
return head;
|
|
6251
6710
|
}
|
|
6252
6711
|
case "many":
|
|
@@ -6276,8 +6735,11 @@ var Encoder = class {
|
|
|
6276
6735
|
}
|
|
6277
6736
|
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);
|
|
6278
6737
|
}
|
|
6279
|
-
case "optional":
|
|
6280
|
-
|
|
6738
|
+
case "optional": {
|
|
6739
|
+
const head = this.emit(OP_OPT, this.node(d.parser).ip);
|
|
6740
|
+
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(head);
|
|
6741
|
+
return head;
|
|
6742
|
+
}
|
|
6281
6743
|
case "transform": {
|
|
6282
6744
|
const inner = d.parser._def;
|
|
6283
6745
|
if (inner.tag === "sequence" && !this.memo.has(d.parser) && !this.pending.has(d.parser)) {
|
|
@@ -6436,6 +6898,7 @@ var Encoder = class {
|
|
|
6436
6898
|
// lowering was correct only for a choice arm.
|
|
6437
6899
|
case "attempt": {
|
|
6438
6900
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
|
|
6901
|
+
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
6439
6902
|
const fs = d.parser._meta.firstSet;
|
|
6440
6903
|
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
6441
6904
|
const cls = this.charClass(fs);
|
|
@@ -6604,6 +7067,10 @@ var Encoder = class {
|
|
|
6604
7067
|
...this.rec ? { rec: 1 } : {},
|
|
6605
7068
|
...this.cov === void 0 ? {} : { cov: this.cov },
|
|
6606
7069
|
lines: this.track ? 1 : 0
|
|
7070
|
+
}, void 0, {
|
|
7071
|
+
choiceRollbackMasks: this.choiceRollbackMasks,
|
|
7072
|
+
failureRollbackCleanSites: this.failureRollbackCleanSites,
|
|
7073
|
+
nonCommittingChoiceSites: this.nonCommittingChoiceSites
|
|
6607
7074
|
});
|
|
6608
7075
|
}
|
|
6609
7076
|
};
|
|
@@ -6648,7 +7115,6 @@ function encodeTableProgram(ruleMap, settings = {}) {
|
|
|
6648
7115
|
const lexicalRoots = [...names].sort().map((name) => ruleMap[name]);
|
|
6649
7116
|
const resolveLexical = (name) => ruleMap[name];
|
|
6650
7117
|
const capabilities = collectLexicalCapabilities(lexicalRoots, resolveLexical);
|
|
6651
|
-
assertLexicalCapabilityClosure(lexicalRoots, capabilities, resolveLexical);
|
|
6652
7118
|
const enc = new Encoder(resolvedSettings, capabilities.capabilityComplete);
|
|
6653
7119
|
enc.winners = ruleMap;
|
|
6654
7120
|
for (const name of names) enc.encodeRule(name, ruleMap[name]);
|
|
@@ -7781,13 +8247,17 @@ var TRI_NONE = -1;
|
|
|
7781
8247
|
var CAP_UNKNOWN = 0;
|
|
7782
8248
|
var CAP_OFF = 1;
|
|
7783
8249
|
var CAP_ON = 2;
|
|
7784
|
-
var
|
|
8250
|
+
var RAW_UNKNOWN = 0;
|
|
8251
|
+
var RAW_CAPTURE = 1;
|
|
8252
|
+
var RAW_OMIT = 2;
|
|
8253
|
+
var TOP = { tri: TRI_UNKNOWN, buf: false, raw: RAW_UNKNOWN, cap: CAP_UNKNOWN };
|
|
7785
8254
|
function meet(a, b) {
|
|
7786
8255
|
const tri = a.tri === b.tri ? a.tri : TRI_UNKNOWN;
|
|
7787
8256
|
const buf = a.buf && b.buf;
|
|
8257
|
+
const raw = a.raw === b.raw ? a.raw : RAW_UNKNOWN;
|
|
7788
8258
|
const cap = a.cap === b.cap ? a.cap : CAP_UNKNOWN;
|
|
7789
|
-
if (tri === a.tri && buf === a.buf && cap === a.cap) return a;
|
|
7790
|
-
return { tri, buf, cap };
|
|
8259
|
+
if (tri === a.tri && buf === a.buf && raw === a.raw && cap === a.cap) return a;
|
|
8260
|
+
return { tri, buf, raw, cap };
|
|
7791
8261
|
}
|
|
7792
8262
|
function reachableSites(code, roots) {
|
|
7793
8263
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -7810,25 +8280,26 @@ function transfer(code, ip, at, hostCst) {
|
|
|
7810
8280
|
const tri = ki < 0 ? TRI_NONE : ki;
|
|
7811
8281
|
const cap = op === OP_SCOPE_CAP ? CAP_ON : at.cap;
|
|
7812
8282
|
if (tri === at.tri && cap === at.cap) return at;
|
|
7813
|
-
return { tri, buf: at.buf, cap };
|
|
8283
|
+
return { tri, buf: at.buf, raw: at.raw, cap };
|
|
7814
8284
|
}
|
|
7815
8285
|
if (op === OP_NODE || op === OP_NODE_TRACK) {
|
|
7816
8286
|
const flags = code[ip + 3];
|
|
7817
8287
|
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
|
|
7818
8288
|
if (directChildren) {
|
|
7819
|
-
return { tri: at.tri, buf: false, cap: CAP_OFF };
|
|
8289
|
+
return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
|
|
7820
8290
|
}
|
|
7821
8291
|
const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
|
|
7822
|
-
|
|
7823
|
-
|
|
8292
|
+
const raw = !hostCst && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags & 2) !== 0 ? RAW_OMIT : RAW_CAPTURE;
|
|
8293
|
+
if (at.buf && raw === at.raw && cap === at.cap) return at;
|
|
8294
|
+
return { tri: at.tri, buf: true, raw, cap };
|
|
7824
8295
|
}
|
|
7825
8296
|
if (op === OP_TOKEN) {
|
|
7826
8297
|
if (at.tri === TRI_NONE && !at.buf) return at;
|
|
7827
|
-
return { tri: TRI_NONE, buf: false, cap: at.cap };
|
|
8298
|
+
return { tri: TRI_NONE, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
|
|
7828
8299
|
}
|
|
7829
8300
|
if (op === OP_LEAF) {
|
|
7830
8301
|
if (!at.buf) return at;
|
|
7831
|
-
return { tri: at.tri, buf: false, cap: at.cap };
|
|
8302
|
+
return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
|
|
7832
8303
|
}
|
|
7833
8304
|
return at;
|
|
7834
8305
|
}
|
|
@@ -7895,6 +8366,162 @@ function scalarTerminalNotChild(code, ip) {
|
|
|
7895
8366
|
const op = code[child];
|
|
7896
8367
|
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
7897
8368
|
}
|
|
8369
|
+
function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, throughPeek = false) {
|
|
8370
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8371
|
+
let at = ip;
|
|
8372
|
+
let depth = 0;
|
|
8373
|
+
while (!seen.has(at)) {
|
|
8374
|
+
seen.add(at);
|
|
8375
|
+
const op = code[at];
|
|
8376
|
+
if (op === OP_LIT || op === OP_RX) return depth >= minDepth ? at : -1;
|
|
8377
|
+
if (op === OP_RULE || op === OP_LABEL || op === OP_TOKEN || throughAttempt && op === OP_ATTEMPT) {
|
|
8378
|
+
at = code[at + 1];
|
|
8379
|
+
depth++;
|
|
8380
|
+
continue;
|
|
8381
|
+
}
|
|
8382
|
+
if (throughPeek && op === OP_PEEK) {
|
|
8383
|
+
at = code[at + 1];
|
|
8384
|
+
depth++;
|
|
8385
|
+
continue;
|
|
8386
|
+
}
|
|
8387
|
+
if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
8388
|
+
at = code[at + 2];
|
|
8389
|
+
depth++;
|
|
8390
|
+
continue;
|
|
8391
|
+
}
|
|
8392
|
+
if (op === OP_SEQ || op === OP_SEQV) {
|
|
8393
|
+
if (code[at + 1] < 1) return -1;
|
|
8394
|
+
at = code[at + 2];
|
|
8395
|
+
depth++;
|
|
8396
|
+
continue;
|
|
8397
|
+
}
|
|
8398
|
+
if (op === OP_SEQX) {
|
|
8399
|
+
if (code[at + 2] < 1) return -1;
|
|
8400
|
+
at = code[at + 3];
|
|
8401
|
+
depth++;
|
|
8402
|
+
continue;
|
|
8403
|
+
}
|
|
8404
|
+
return -1;
|
|
8405
|
+
}
|
|
8406
|
+
return -1;
|
|
8407
|
+
}
|
|
8408
|
+
function leadingScalarSequence(code, ip) {
|
|
8409
|
+
const wholeScalar = (start) => {
|
|
8410
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
8411
|
+
let at2 = start;
|
|
8412
|
+
while (!seen2.has(at2)) {
|
|
8413
|
+
seen2.add(at2);
|
|
8414
|
+
const op = code[at2];
|
|
8415
|
+
if (op === OP_LIT || op === OP_RX) return at2;
|
|
8416
|
+
if (op === OP_RULE || op === OP_TOKEN || op === OP_ATTEMPT) {
|
|
8417
|
+
at2 = code[at2 + 1];
|
|
8418
|
+
continue;
|
|
8419
|
+
}
|
|
8420
|
+
if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
8421
|
+
at2 = code[at2 + 2];
|
|
8422
|
+
continue;
|
|
8423
|
+
}
|
|
8424
|
+
if (op === OP_SEQ || op === OP_SEQV) {
|
|
8425
|
+
if (code[at2 + 1] !== 1) return -1;
|
|
8426
|
+
at2 = code[at2 + 2];
|
|
8427
|
+
continue;
|
|
8428
|
+
}
|
|
8429
|
+
if (op === OP_SEQX) {
|
|
8430
|
+
if (code[at2 + 2] !== 1) return -1;
|
|
8431
|
+
at2 = code[at2 + 3];
|
|
8432
|
+
continue;
|
|
8433
|
+
}
|
|
8434
|
+
return -1;
|
|
8435
|
+
}
|
|
8436
|
+
return -1;
|
|
8437
|
+
};
|
|
8438
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8439
|
+
let at = ip;
|
|
8440
|
+
let ambientTrivia;
|
|
8441
|
+
while (!seen.has(at)) {
|
|
8442
|
+
seen.add(at);
|
|
8443
|
+
const op = code[at];
|
|
8444
|
+
if (op === OP_RULE) {
|
|
8445
|
+
at = code[at + 1];
|
|
8446
|
+
continue;
|
|
8447
|
+
}
|
|
8448
|
+
if (op === OP_SCOPE_PLAIN) {
|
|
8449
|
+
ambientTrivia = code[at + 1];
|
|
8450
|
+
at = code[at + 2];
|
|
8451
|
+
continue;
|
|
8452
|
+
}
|
|
8453
|
+
if (op === OP_GATE || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
8454
|
+
at = code[at + 2];
|
|
8455
|
+
continue;
|
|
8456
|
+
}
|
|
8457
|
+
const n = op === OP_SEQ || op === OP_SEQV ? code[at + 1] : op === OP_SEQX ? code[at + 2] : 0;
|
|
8458
|
+
if (n < 3 || ambientTrivia === void 0) return void 0;
|
|
8459
|
+
const base = op === OP_SEQX ? at + 3 : at + 2;
|
|
8460
|
+
const terminals = [
|
|
8461
|
+
wholeScalar(code[base]),
|
|
8462
|
+
wholeScalar(code[base + 1]),
|
|
8463
|
+
wholeScalar(code[base + 2])
|
|
8464
|
+
];
|
|
8465
|
+
return terminals.every((terminal) => terminal >= 0) ? { terminals, trivia: ambientTrivia } : void 0;
|
|
8466
|
+
}
|
|
8467
|
+
return void 0;
|
|
8468
|
+
}
|
|
8469
|
+
function leadingLiteralFamily(code, constants, ip, minDepth = 2, limit = 4) {
|
|
8470
|
+
const active = /* @__PURE__ */ new Set();
|
|
8471
|
+
const walk = (at, depth) => {
|
|
8472
|
+
if (active.has(at)) return void 0;
|
|
8473
|
+
active.add(at);
|
|
8474
|
+
try {
|
|
8475
|
+
const op = code[at];
|
|
8476
|
+
if (op === OP_LIT) {
|
|
8477
|
+
const value = constants[code[at + 1]];
|
|
8478
|
+
return depth >= minDepth && typeof value === "string" && value.length > 0 ? [at] : void 0;
|
|
8479
|
+
}
|
|
8480
|
+
if (op === OP_RULE || op === OP_LABEL || op === OP_TOKEN || op === OP_ATTEMPT || op === OP_PEEK) {
|
|
8481
|
+
return walk(code[at + 1], depth + 1);
|
|
8482
|
+
}
|
|
8483
|
+
if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
8484
|
+
return walk(code[at + 2], depth + 1);
|
|
8485
|
+
}
|
|
8486
|
+
if (op === OP_SEQ || op === OP_SEQV) {
|
|
8487
|
+
return code[at + 1] < 1 ? void 0 : walk(code[at + 2], depth + 1);
|
|
8488
|
+
}
|
|
8489
|
+
if (op === OP_SEQX) {
|
|
8490
|
+
return code[at + 2] < 1 ? void 0 : walk(code[at + 3], depth + 1);
|
|
8491
|
+
}
|
|
8492
|
+
if (op !== OP_CHOICE) return void 0;
|
|
8493
|
+
const n = code[at + 2];
|
|
8494
|
+
if (n < 1) return void 0;
|
|
8495
|
+
const out = [];
|
|
8496
|
+
for (let i = 0; i < n; i++) {
|
|
8497
|
+
const branch = walk(code[at + 4 + i], depth + 1);
|
|
8498
|
+
if (branch === void 0) return void 0;
|
|
8499
|
+
for (const terminal of branch) {
|
|
8500
|
+
const value = constants[code[terminal + 1]];
|
|
8501
|
+
let covered = false;
|
|
8502
|
+
for (let j = 0; j < out.length; j++) {
|
|
8503
|
+
const prior = constants[code[out[j] + 1]];
|
|
8504
|
+
if (value.startsWith(prior)) {
|
|
8505
|
+
covered = true;
|
|
8506
|
+
break;
|
|
8507
|
+
}
|
|
8508
|
+
}
|
|
8509
|
+
if (covered) continue;
|
|
8510
|
+
for (let j = out.length - 1; j >= 0; j--) {
|
|
8511
|
+
const prior = constants[code[out[j] + 1]];
|
|
8512
|
+
if (prior.startsWith(value)) out.splice(j, 1);
|
|
8513
|
+
}
|
|
8514
|
+
out.push(terminal);
|
|
8515
|
+
if (out.length > limit) return void 0;
|
|
8516
|
+
}
|
|
8517
|
+
}
|
|
8518
|
+
return out;
|
|
8519
|
+
} finally {
|
|
8520
|
+
active.delete(at);
|
|
8521
|
+
}
|
|
8522
|
+
};
|
|
8523
|
+
return walk(ip, 0);
|
|
8524
|
+
}
|
|
7898
8525
|
|
|
7899
8526
|
// src/table/emit-assembly.ts
|
|
7900
8527
|
var Unemittable = class extends Error {
|
|
@@ -7976,6 +8603,16 @@ let _pfScan=null
|
|
|
7976
8603
|
let _pfHost
|
|
7977
8604
|
let _pfDepth=0
|
|
7978
8605
|
const _pfFrames=[]
|
|
8606
|
+
let _pfTokInput
|
|
8607
|
+
let _pfTokPos=-1
|
|
8608
|
+
let _pfTokBody=-1
|
|
8609
|
+
let _pfTokPacked=-1
|
|
8610
|
+
let _pfTokValue
|
|
8611
|
+
let _pfTokDispatch=-1
|
|
8612
|
+
let _pfTokArm=-1
|
|
8613
|
+
let _pfTokEnd=-1
|
|
8614
|
+
let _pfSeqEnd=-1
|
|
8615
|
+
function _asciiFoldCode(c){return c>=65&&c<=90?c+32:c}
|
|
7979
8616
|
function _skipTrivia(input,cur,ctx){
|
|
7980
8617
|
const s=_pfScan
|
|
7981
8618
|
if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
|
|
@@ -8041,6 +8678,40 @@ if(ctx._triviaLog!==undefined&&ctx._triviaLog.length!==lg)ctx._triviaLog.length=
|
|
|
8041
8678
|
if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTriviaLog.length=rt
|
|
8042
8679
|
}
|
|
8043
8680
|
`;
|
|
8681
|
+
var NO_RAW_RUNTIME_PRELUDE = `
|
|
8682
|
+
function _pushLeafNoRawBuf(ctx,value,s,e){
|
|
8683
|
+
const l={_tag:'leaf',value,span:{start:s,end:e}}
|
|
8684
|
+
const b=ctx._cstBuf
|
|
8685
|
+
if(b.ch!==undefined)b.ch.push(l)
|
|
8686
|
+
else if(b.single!==undefined){b.ch=[b.single,l];b.single=undefined}
|
|
8687
|
+
else b.single=l
|
|
8688
|
+
b.rawLen++
|
|
8689
|
+
}
|
|
8690
|
+
function _pushNodeNoRawBuf(ctx,value){
|
|
8691
|
+
const b=ctx._cstBuf
|
|
8692
|
+
if(b.ch!==undefined)b.ch.push(value)
|
|
8693
|
+
else if(b.single!==undefined){b.ch=[b.single,value];b.single=undefined}
|
|
8694
|
+
else b.single=value
|
|
8695
|
+
b.rawLen++
|
|
8696
|
+
}
|
|
8697
|
+
function _rbNoRawBuf(ctx,raw,tl,lv,lg,rt){
|
|
8698
|
+
const b=ctx._cstBuf
|
|
8699
|
+
if(b.rawLen!==raw)b.rawLen=raw
|
|
8700
|
+
const ch=b.ch
|
|
8701
|
+
if(ch!==undefined){
|
|
8702
|
+
if(lv===0)b.ch=undefined
|
|
8703
|
+
else if(lv===1){b.single=ch[0];b.ch=undefined}
|
|
8704
|
+
else if(ch.length!==lv)ch.length=lv
|
|
8705
|
+
}else if(lv===0)b.single=undefined
|
|
8706
|
+
const bt=b.tl
|
|
8707
|
+
if(bt!==undefined){
|
|
8708
|
+
if(tl===0)b.tl=undefined
|
|
8709
|
+
else if(bt.length!==tl)bt.length=tl
|
|
8710
|
+
}
|
|
8711
|
+
if(ctx._triviaLog!==undefined&&ctx._triviaLog.length!==lg)ctx._triviaLog.length=lg
|
|
8712
|
+
if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTriviaLog.length=rt
|
|
8713
|
+
}
|
|
8714
|
+
`;
|
|
8044
8715
|
function q(s) {
|
|
8045
8716
|
return JSON.stringify(s);
|
|
8046
8717
|
}
|
|
@@ -8053,11 +8724,12 @@ function sinkReads(t2, s) {
|
|
|
8053
8724
|
${t2}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${s.er ? `
|
|
8054
8725
|
${t2}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
|
|
8055
8726
|
}
|
|
8056
|
-
function emitMark(t2, buf, s = NO_SINKS, decl = true) {
|
|
8727
|
+
function emitMark(t2, buf, rawMode, s = NO_SINKS, decl = true) {
|
|
8057
8728
|
if (buf) {
|
|
8729
|
+
const raw = rawMode === RAW_OMIT ? `${t2}raw=b.rawLen` : rawMode === RAW_CAPTURE ? `const r=b.raw;${t2}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0` : `const r=b.raw;${t2}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)`;
|
|
8058
8730
|
return `${decl ? `let ${t2}raw=0,${t2}tl=0,${t2}lv=0,${t2}lg=0,${t2}rt=0${sinkSlots(t2, s)}
|
|
8059
8731
|
` : ""}{const b=ctx._cstBuf
|
|
8060
|
-
|
|
8732
|
+
${raw}
|
|
8061
8733
|
const h=b.ch;${t2}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
8062
8734
|
const l=b.tl;${t2}tl=l!==undefined?l.length:0
|
|
8063
8735
|
${t2}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
@@ -8067,7 +8739,7 @@ ${t2}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${sinkReads(t2
|
|
|
8067
8739
|
` : `${t2}n=false
|
|
8068
8740
|
`}{const b=ctx._cstBuf
|
|
8069
8741
|
if(b!==undefined){
|
|
8070
|
-
const r=b.raw;${t2}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
8742
|
+
const r=b.raw;${t2}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)
|
|
8071
8743
|
const h=b.ch;${t2}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
8072
8744
|
const l=b.tl;${t2}tl=l!==undefined?l.length:0
|
|
8073
8745
|
${t2}n=true
|
|
@@ -8082,14 +8754,16 @@ ${t2}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
|
8082
8754
|
${t2}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${sinkReads(t2, s)}
|
|
8083
8755
|
}}`;
|
|
8084
8756
|
}
|
|
8085
|
-
function emitRollback(t2, buf, s = NO_SINKS) {
|
|
8757
|
+
function emitRollback(t2, buf, rawMode, s = NO_SINKS) {
|
|
8086
8758
|
const fd = s.fd ? `
|
|
8087
8759
|
if(ctx._fields!==undefined&&ctx._fields.length!==${t2}fd)ctx._fields.length=${t2}fd` : "";
|
|
8088
8760
|
const er = s.er ? `
|
|
8089
8761
|
if(ctx._errors!==undefined&&ctx._errors.length!==${t2}er)ctx._errors.length=${t2}er` : "";
|
|
8090
|
-
if (buf) return `
|
|
8091
|
-
if (
|
|
8092
|
-
return `
|
|
8762
|
+
if (buf && rawMode === RAW_OMIT) return `_rbNoRawBuf(ctx,${t2}raw,${t2}tl,${t2}lv,${t2}lg,${t2}rt)${fd}${er}`;
|
|
8763
|
+
if (buf && rawMode === RAW_CAPTURE) return `_rbBuf(ctx,${t2}raw,${t2}tl,${t2}lv,${t2}lg,${t2}rt)${fd}${er}`;
|
|
8764
|
+
if (buf) return `rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,${s.fd ? `${t2}fd` : "undefined"},${s.er ? `${t2}er` : "undefined"},${t2}lg,${t2}rt)`;
|
|
8765
|
+
if (!s.fd && !s.er) return `if(${t2}n)rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,undefined,undefined,${t2}lg,${t2}rt)`;
|
|
8766
|
+
return `if(${t2}n){rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,${s.fd ? `${t2}fd` : "undefined"},${s.er ? `${t2}er` : "undefined"},${t2}lg,${t2}rt)}`;
|
|
8093
8767
|
}
|
|
8094
8768
|
function emitTerm(callee, dst, t2, l, skip) {
|
|
8095
8769
|
const fast = `const ${t2}v=${callee}(input,cur,ctx)
|
|
@@ -8147,37 +8821,111 @@ function rebuildPools(cc, fx, disp, plan) {
|
|
|
8147
8821
|
})
|
|
8148
8822
|
};
|
|
8149
8823
|
}
|
|
8150
|
-
function emitAssemblySource(t2, prog, cfg, extraIps = []) {
|
|
8151
|
-
const { code, k, disp, dsp, triviaLabelled } = t2;
|
|
8824
|
+
function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false) {
|
|
8825
|
+
const { code, k, fx, disp, dsp, triviaLabelled } = t2;
|
|
8152
8826
|
const swapLegal = !cfg.trackLines;
|
|
8153
8827
|
const hostCst = cfg.hostCst;
|
|
8154
8828
|
const REC = prog.rec === 1 && cfg.tolerant;
|
|
8155
8829
|
if (cfg.coverage) throw new Unemittable("a coverage assembly");
|
|
8156
8830
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
8831
|
+
const reachable = [...reachableSites(code, roots)];
|
|
8157
8832
|
const labels = computeSiteLabels(code, roots, hostCst);
|
|
8158
8833
|
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
8834
|
+
const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
|
|
8835
|
+
const largeChoiceLiteralFamilies = /* @__PURE__ */ new Map();
|
|
8836
|
+
const largeChoiceScalarSequences = /* @__PURE__ */ new Map();
|
|
8837
|
+
const tokenChoiceCandidates = /* @__PURE__ */ new Map();
|
|
8838
|
+
const tokenChoiceDispatches = /* @__PURE__ */ new Set();
|
|
8839
|
+
const tokenChoiceBodies = /* @__PURE__ */ new Set();
|
|
8159
8840
|
if (!hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
|
|
8160
|
-
for (const ip of
|
|
8161
|
-
if (code[ip]
|
|
8162
|
-
|
|
8163
|
-
|
|
8841
|
+
for (const ip of reachable) {
|
|
8842
|
+
if (code[ip] === OP_NODE) {
|
|
8843
|
+
const child = scalarTerminalNodeChild(code, ip);
|
|
8844
|
+
if (child >= 0) scalarSpecs.add(code[child + 1]);
|
|
8845
|
+
continue;
|
|
8846
|
+
}
|
|
8847
|
+
if (code[ip] !== OP_CHOICE || disp[code[ip + 1]].exclusive) continue;
|
|
8848
|
+
const n = code[ip + 2];
|
|
8849
|
+
for (let i = 0; i < n; i++) {
|
|
8850
|
+
const armIp = code[ip + 4 + i];
|
|
8851
|
+
const child = leadingScalarTerminal(code, armIp, 2, true, true);
|
|
8852
|
+
if (n === 2 || n === 3) {
|
|
8853
|
+
if (child >= 0) scalarSpecs.add(code[child + 1]);
|
|
8854
|
+
continue;
|
|
8855
|
+
}
|
|
8856
|
+
if (child >= 0) {
|
|
8857
|
+
const spec = k[code[child + 1]];
|
|
8858
|
+
if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) {
|
|
8859
|
+
largeChoiceScalarSpecs.add(code[child + 1]);
|
|
8860
|
+
continue;
|
|
8861
|
+
}
|
|
8862
|
+
}
|
|
8863
|
+
const family = leadingLiteralFamily(code, k, armIp);
|
|
8864
|
+
if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
8865
|
+
const value = k[code[terminal + 1]];
|
|
8866
|
+
return typeof value === "string" && value.length >= 2;
|
|
8867
|
+
})) {
|
|
8868
|
+
largeChoiceLiteralFamilies.set(armIp, family);
|
|
8869
|
+
}
|
|
8870
|
+
const sequence6 = leadingScalarSequence(code, armIp);
|
|
8871
|
+
if (sequence6 !== void 0 && (sequence6.trivia < 0 || swapLegal && t2.triviaScan[sequence6.trivia] != null)) {
|
|
8872
|
+
largeChoiceScalarSequences.set(armIp, sequence6);
|
|
8873
|
+
}
|
|
8874
|
+
}
|
|
8875
|
+
let candidate;
|
|
8876
|
+
let ambiguous = false;
|
|
8877
|
+
for (let i = 0; i < n; i++) {
|
|
8878
|
+
const armIp = code[ip + 4 + i];
|
|
8879
|
+
if (code[armIp] !== OP_XFORM) continue;
|
|
8880
|
+
const dispatchIp = code[armIp + 2];
|
|
8881
|
+
if (code[dispatchIp] !== OP_DISPATCH) continue;
|
|
8882
|
+
const selectorIp = code[dispatchIp + 1];
|
|
8883
|
+
if (code[selectorIp] !== OP_LEX_BODY) continue;
|
|
8884
|
+
if (candidate !== void 0) {
|
|
8885
|
+
ambiguous = true;
|
|
8886
|
+
break;
|
|
8887
|
+
}
|
|
8888
|
+
candidate = { arm: i, dispatchIp };
|
|
8889
|
+
}
|
|
8890
|
+
if (!ambiguous && candidate !== void 0) {
|
|
8891
|
+
tokenChoiceCandidates.set(ip, candidate);
|
|
8892
|
+
tokenChoiceDispatches.add(candidate.dispatchIp);
|
|
8893
|
+
tokenChoiceBodies.add(code[code[candidate.dispatchIp + 1] + 1]);
|
|
8894
|
+
}
|
|
8164
8895
|
}
|
|
8165
8896
|
}
|
|
8166
|
-
const
|
|
8167
|
-
|
|
8168
|
-
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8897
|
+
const needsNoRawPrelude = !hostCst && reachable.some((ip) => {
|
|
8898
|
+
const op = code[ip];
|
|
8899
|
+
return (op === OP_NODE || op === OP_NODE_TRACK) && code[ip + 1] >= 0 && code[ip + 4] < 0 && (code[ip + 3] & 2) !== 0;
|
|
8900
|
+
});
|
|
8901
|
+
const sinkSites = reachable;
|
|
8902
|
+
const sinkBits = /* @__PURE__ */ new Map();
|
|
8903
|
+
for (const ip of sinkSites) {
|
|
8904
|
+
const op = code[ip];
|
|
8905
|
+
sinkBits.set(
|
|
8906
|
+
ip,
|
|
8907
|
+
op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC && (op === OP_REP || op === OP_REPV) ? 2 : 0)
|
|
8908
|
+
);
|
|
8909
|
+
}
|
|
8910
|
+
const sinkKids = [];
|
|
8911
|
+
let sinkChanged = true;
|
|
8912
|
+
while (sinkChanged) {
|
|
8913
|
+
sinkChanged = false;
|
|
8914
|
+
for (const ip of sinkSites) {
|
|
8915
|
+
let bits = sinkBits.get(ip) ?? 0;
|
|
8916
|
+
sinkKids.length = 0;
|
|
8917
|
+
childSlots(code, ip, sinkKids);
|
|
8918
|
+
for (let i = 0; i < sinkKids.length; i++) bits |= sinkBits.get(sinkKids[i]) ?? 0;
|
|
8919
|
+
if (bits !== sinkBits.get(ip)) {
|
|
8920
|
+
sinkBits.set(ip, bits);
|
|
8921
|
+
sinkChanged = true;
|
|
8175
8922
|
}
|
|
8176
|
-
if (op === OP_FIELD) fd = true;
|
|
8177
|
-
else if (op === OP_EXPECT) er = true;
|
|
8178
8923
|
}
|
|
8179
|
-
|
|
8180
|
-
|
|
8924
|
+
}
|
|
8925
|
+
const sinksAt = (ip) => {
|
|
8926
|
+
const bits = sinkBits.get(ip) ?? 0;
|
|
8927
|
+
return bits === 0 ? NO_SINKS : { fd: (bits & 1) !== 0, er: (bits & 2) !== 0 };
|
|
8928
|
+
};
|
|
8181
8929
|
const bodies = [];
|
|
8182
8930
|
const byIp = /* @__PURE__ */ new Map();
|
|
8183
8931
|
const reached = /* @__PURE__ */ new Set();
|
|
@@ -8204,9 +8952,117 @@ function emitAssemblySource(t2, prog, cfg, extraIps = []) {
|
|
|
8204
8952
|
const fxRef = (i) => hoist("fx", `FX[${i}]`);
|
|
8205
8953
|
const fnRef = (i) => hoist("fn", `FNS[${i}]`);
|
|
8206
8954
|
const recognizerRef = (i) => hoist("rec", `RECOG[${i}]`);
|
|
8955
|
+
const scalarSequenceRefs = /* @__PURE__ */ new Map();
|
|
8956
|
+
const scalarSequenceRef = (sequence6) => {
|
|
8957
|
+
const key = `${sequence6.trivia}:${sequence6.terminals.map((terminal) => code[terminal + 1]).join(",")}`;
|
|
8958
|
+
const prior = scalarSequenceRefs.get(key);
|
|
8959
|
+
if (prior !== void 0) return prior;
|
|
8960
|
+
const recognizers = sequence6.terminals.map((terminal) => recognizerRef(code[terminal + 1]));
|
|
8961
|
+
const expected = sequence6.terminals.map((terminal) => fxRef(code[terminal + 2]));
|
|
8962
|
+
const scan = sequence6.trivia < 0 ? void 0 : hoist("ts", `TRIVIASCAN[${sequence6.trivia}]`);
|
|
8963
|
+
const name = `_sd${scalarSequenceRefs.size}_`;
|
|
8964
|
+
const steps = recognizers.map((recognize, i) => `${i === 0 ? "let " : ""}at=${i === 0 ? "pos" : scan === void 0 ? "cur" : `${scan}(input,cur)`}
|
|
8965
|
+
${i === 0 ? "let " : ""}cur=${recognize}(input,at)
|
|
8966
|
+
if(cur<0){_pfSeqEnd=at;return ${~i}}`).join("\n");
|
|
8967
|
+
choiceDefs.push(`function ${name}(input,pos){
|
|
8968
|
+
${steps}
|
|
8969
|
+
return cur
|
|
8970
|
+
}`);
|
|
8971
|
+
const made = { name, expected };
|
|
8972
|
+
scalarSequenceRefs.set(key, made);
|
|
8973
|
+
return made;
|
|
8974
|
+
};
|
|
8207
8975
|
const sentRef = (cls) => cls < 0 ? "undefined" : hoist("sent", `SENTS[${cls}]`);
|
|
8208
8976
|
let uid = 0;
|
|
8209
8977
|
const tmp = () => `_t${uid++}_`;
|
|
8978
|
+
const dispatchClaim = (m) => {
|
|
8979
|
+
switch (m[0]) {
|
|
8980
|
+
case 0:
|
|
8981
|
+
return `key.startsWith(${q(m[1])})`;
|
|
8982
|
+
case 1:
|
|
8983
|
+
return `key.endsWith(${q(m[1])})`;
|
|
8984
|
+
case 3:
|
|
8985
|
+
return `asciiFoldKey(key).startsWith(${q(m[1])})`;
|
|
8986
|
+
case 4:
|
|
8987
|
+
return `asciiFoldKey(key).endsWith(${q(m[1])})`;
|
|
8988
|
+
default: {
|
|
8989
|
+
if (!m[2].includes("g") && !m[2].includes("y")) {
|
|
8990
|
+
try {
|
|
8991
|
+
new RegExp(m[1], m[2]);
|
|
8992
|
+
return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
|
|
8993
|
+
} catch {
|
|
8994
|
+
}
|
|
8995
|
+
}
|
|
8996
|
+
return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
|
|
8997
|
+
}
|
|
8998
|
+
}
|
|
8999
|
+
};
|
|
9000
|
+
const tokenDecisionRefs = /* @__PURE__ */ new Map();
|
|
9001
|
+
function tokenDecisionFor(dispatchIp) {
|
|
9002
|
+
const prior = tokenDecisionRefs.get(dispatchIp);
|
|
9003
|
+
if (prior !== void 0) return prior;
|
|
9004
|
+
const selectorIp = code[dispatchIp + 1];
|
|
9005
|
+
const body = code[selectorIp + 1];
|
|
9006
|
+
const lineFlags = code[selectorIp + 4];
|
|
9007
|
+
const hasSuffix = (lineFlags & 4) !== 0;
|
|
9008
|
+
const di = code[dispatchIp + 2];
|
|
9009
|
+
const spec = dsp[di];
|
|
9010
|
+
const n = code[dispatchIp + 5];
|
|
9011
|
+
validateDispatchSpec(spec, n, code[dispatchIp + 4]);
|
|
9012
|
+
const recognize = hoist("lex", `LEX[${body}]`);
|
|
9013
|
+
const bk = hoist("bk", `DSP[${di}].byKey`);
|
|
9014
|
+
const expected = hoist("dx", `DSP[${di}].expected`);
|
|
9015
|
+
const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
|
|
9016
|
+
` : "";
|
|
9017
|
+
const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
|
|
9018
|
+
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${dispatchClaim(m)})arm=${m[3]}`).join("\n")}
|
|
9019
|
+
}
|
|
9020
|
+
`;
|
|
9021
|
+
const foldedEntries = [...spec.byFold.entries()];
|
|
9022
|
+
const fixedFunctionChoice = spec.byKey.size === 0 && foldedEntries.length === 1 && spec.match.length === 1 && spec.match[0][0] === 2 && spec.match[0][1] === "^(?!(?:url|calc)\\($).+\\($" && spec.match[0][2] === "i" && code[dispatchIp + 3] < 0;
|
|
9023
|
+
const foldedRangeEquals = (value) => {
|
|
9024
|
+
const folded = value.replace(/[A-Z]/g, (c) => c.toLowerCase());
|
|
9025
|
+
return `e-pos===${folded.length}&&${[...folded].map((c, i) => {
|
|
9026
|
+
const cc = c.charCodeAt(0);
|
|
9027
|
+
return `_asciiFoldCode(input.charCodeAt(pos+${i}))===${cc}`;
|
|
9028
|
+
}).join("&&")}`;
|
|
9029
|
+
};
|
|
9030
|
+
const classify = fixedFunctionChoice ? (() => {
|
|
9031
|
+
const [exact, exactArm] = foldedEntries[0];
|
|
9032
|
+
const genericArm = spec.match[0][3];
|
|
9033
|
+
return `let arm
|
|
9034
|
+
if(${foldedRangeEquals(exact)})arm=${exactArm}
|
|
9035
|
+
else if(sm&&e>pos+1){
|
|
9036
|
+
let clean=true
|
|
9037
|
+
for(let i=pos;i<e;i++){const c=input.charCodeAt(i);if(c===10||c===13||c===0x2028||c===0x2029){clean=false;break}}
|
|
9038
|
+
if(clean&&!(${foldedRangeEquals("url(")})&&!(${foldedRangeEquals("calc(")}))arm=${genericArm}
|
|
9039
|
+
}`;
|
|
9040
|
+
})() : `const key=input.slice(pos,e)
|
|
9041
|
+
let arm=${bk}.get(key)
|
|
9042
|
+
${fold}${chain}`;
|
|
9043
|
+
const name = `_td${tokenDecisionRefs.size}_`;
|
|
9044
|
+
choiceDefs.push(`function ${name}(input,pos){
|
|
9045
|
+
const r=${recognize}(input,pos)
|
|
9046
|
+
if(r<0)return -1
|
|
9047
|
+
const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
|
|
9048
|
+
${classify}
|
|
9049
|
+
if(arm===undefined){
|
|
9050
|
+
${code[dispatchIp + 3] < 0 ? "_pfTokEnd=e;return 0" : `arm=${n}`}
|
|
9051
|
+
}
|
|
9052
|
+
${fixedFunctionChoice ? "const key=input.slice(pos,e)" : ""}
|
|
9053
|
+
_pfTokInput=input
|
|
9054
|
+
_pfTokPos=pos
|
|
9055
|
+
_pfTokBody=${body}
|
|
9056
|
+
_pfTokPacked=r
|
|
9057
|
+
_pfTokValue=key
|
|
9058
|
+
_pfTokDispatch=${dispatchIp}
|
|
9059
|
+
_pfTokArm=arm
|
|
9060
|
+
return 1
|
|
9061
|
+
}`);
|
|
9062
|
+
const made = { name, expected };
|
|
9063
|
+
tokenDecisionRefs.set(dispatchIp, made);
|
|
9064
|
+
return made;
|
|
9065
|
+
}
|
|
8210
9066
|
function skipFor(l) {
|
|
8211
9067
|
if (l.tri < 0) return "_skipTrivia";
|
|
8212
9068
|
const ki = l.tri;
|
|
@@ -8294,7 +9150,8 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
8294
9150
|
const op = code[ip];
|
|
8295
9151
|
const head = `function ${fname}(input,pos,ctx){`;
|
|
8296
9152
|
const L = labels.at(ip);
|
|
8297
|
-
const
|
|
9153
|
+
const sinks = sinksAt(ip);
|
|
9154
|
+
const pushLeaf = L.buf && !cfg.trackLines ? L.raw === RAW_OMIT ? "_pushLeafNoRawBuf" : L.raw === RAW_CAPTURE ? "_pushLeafBuf" : "_pushLeaf" : "_pushLeaf";
|
|
8298
9155
|
const captureLeaf = (value) => {
|
|
8299
9156
|
const call = `${pushLeaf}(ctx,${value},pos,e)`;
|
|
8300
9157
|
return L.buf ? call : `if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)${call}`;
|
|
@@ -8545,20 +9402,24 @@ return out
|
|
|
8545
9402
|
}`;
|
|
8546
9403
|
}
|
|
8547
9404
|
case OP_LEX_BODY: {
|
|
8548
|
-
const
|
|
9405
|
+
const body = code[ip + 1];
|
|
9406
|
+
const recognize = hoist("lex", `LEX[${body}]`);
|
|
8549
9407
|
const expected = fxRef(code[ip + 2]);
|
|
8550
9408
|
const suffixExpected = fxRef(code[ip + 3]);
|
|
8551
9409
|
const lineFlags = code[ip + 4];
|
|
8552
9410
|
const hasSuffix = (lineFlags & 4) !== 0;
|
|
9411
|
+
const pending = tokenChoiceBodies.has(body);
|
|
8553
9412
|
return `${head}
|
|
8554
|
-
const
|
|
9413
|
+
${pending ? `const tp=_pfTokBody===${body}&&_pfTokInput===input&&_pfTokPos===pos
|
|
9414
|
+
const r=tp?_pfTokPacked:${recognize}(input,pos)` : `const r=${recognize}(input,pos)`}
|
|
8555
9415
|
if(r<0){ctx._fe=pos;ctx._fx=${expected};if(ctx._probe!==undefined)failAt(ctx,${expected},pos);return FAIL}
|
|
8556
9416
|
const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
|
|
8557
9417
|
${(lineFlags & 1) !== 0 ? "_trackLines(ctx,input,sm?e-1:e)" : ""}
|
|
8558
9418
|
${hasSuffix ? "ctx._fc=false" : ""}
|
|
8559
9419
|
${hasSuffix && (lineFlags & 2) !== 0 ? "if(sm)_trackLines(ctx,input,e)" : ""}
|
|
8560
9420
|
${hasSuffix ? `if(!sm){ctx._fe=e;ctx._fx=${suffixExpected};if(ctx._probe!==undefined)failAt(ctx,${suffixExpected},e)}` : ""}
|
|
8561
|
-
const v
|
|
9421
|
+
const v=${pending ? "tp?_pfTokValue:" : ""}input.slice(pos,e)
|
|
9422
|
+
${pending ? "if(tp){_pfTokBody=-1;_pfTokValue=undefined}" : ""}
|
|
8562
9423
|
if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
|
|
8563
9424
|
EC.e=e
|
|
8564
9425
|
return v
|
|
@@ -8614,12 +9475,13 @@ return v
|
|
|
8614
9475
|
/* ── transaction ─────────────────────────────────────────────────────── */
|
|
8615
9476
|
case OP_ATTEMPT: {
|
|
8616
9477
|
const child = link(code[ip + 1]);
|
|
9478
|
+
const clean = !REC && failureRollbackClean(prog, ip);
|
|
8617
9479
|
const p = tmp();
|
|
8618
9480
|
return `${head}
|
|
8619
|
-
${emitMark(p, L.buf, sinks)}
|
|
9481
|
+
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
8620
9482
|
const v=${child}(input,pos,ctx)
|
|
8621
9483
|
if(v!==FAIL)return v
|
|
8622
|
-
${emitRollback(p, L.buf, sinks)}
|
|
9484
|
+
${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
|
|
8623
9485
|
if(ctx._fc===true)return FAIL
|
|
8624
9486
|
ctx._fe=pos
|
|
8625
9487
|
return FAIL
|
|
@@ -8642,9 +9504,9 @@ return FAIL
|
|
|
8642
9504
|
const xf = fxRef(code[ip + 2]);
|
|
8643
9505
|
const p = tmp();
|
|
8644
9506
|
return `${head}
|
|
8645
|
-
${emitMark(p, L.buf, sinks)}
|
|
9507
|
+
${emitMark(p, L.buf, L.raw, sinks)}
|
|
8646
9508
|
const v=${child}(input,pos,ctx)
|
|
8647
|
-
${emitRollback(p, L.buf, sinks)}
|
|
9509
|
+
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
8648
9510
|
if(v===FAIL){EC.e=pos;return null}
|
|
8649
9511
|
ctx._fe=pos
|
|
8650
9512
|
ctx._fx=${xf}
|
|
@@ -8656,9 +9518,9 @@ return FAIL
|
|
|
8656
9518
|
const xf = fxRef(code[ip + 2]);
|
|
8657
9519
|
const p = tmp();
|
|
8658
9520
|
return `${head}
|
|
8659
|
-
${emitMark(p, L.buf, sinks)}
|
|
9521
|
+
${emitMark(p, L.buf, L.raw, sinks)}
|
|
8660
9522
|
const v=${child}(input,pos,ctx)
|
|
8661
|
-
${emitRollback(p, L.buf, sinks)}
|
|
9523
|
+
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
8662
9524
|
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
8663
9525
|
EC.e=pos
|
|
8664
9526
|
return null
|
|
@@ -8666,14 +9528,15 @@ return null
|
|
|
8666
9528
|
}
|
|
8667
9529
|
case OP_OPT: {
|
|
8668
9530
|
const child = link(code[ip + 1]);
|
|
9531
|
+
const clean = !REC && failureRollbackClean(prog, ip);
|
|
8669
9532
|
const p = tmp();
|
|
8670
9533
|
return `${head}
|
|
8671
|
-
${emitMark(p, L.buf, sinks)}
|
|
9534
|
+
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
8672
9535
|
ctx._fc=false
|
|
8673
9536
|
const v=${child}(input,pos,ctx)
|
|
8674
9537
|
if(v===FAIL){
|
|
8675
9538
|
if(ctx._fc===true)return FAIL
|
|
8676
|
-
${emitRollback(p, L.buf, sinks)}
|
|
9539
|
+
${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
|
|
8677
9540
|
EC.e=pos
|
|
8678
9541
|
return null
|
|
8679
9542
|
}
|
|
@@ -8772,57 +9635,193 @@ return FAIL
|
|
|
8772
9635
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
8773
9636
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
8774
9637
|
const gateRefs = Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
9638
|
+
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
9639
|
+
const pretests = Array.from({ length: n }, (_, i) => {
|
|
9640
|
+
if (tokenCandidate?.arm === i) {
|
|
9641
|
+
return { token: tokenDecisionFor(tokenCandidate.dispatchIp) };
|
|
9642
|
+
}
|
|
9643
|
+
const terminal = leadingScalarTerminal(code, code[base + i], 2, true, true);
|
|
9644
|
+
if (terminal >= 0) {
|
|
9645
|
+
const spec = code[terminal + 1];
|
|
9646
|
+
if ((n === 2 || n === 3 ? scalarSpecs : largeChoiceScalarSpecs).has(spec)) {
|
|
9647
|
+
return { scalar: [recognizerRef(spec)] };
|
|
9648
|
+
}
|
|
9649
|
+
}
|
|
9650
|
+
const family = largeChoiceLiteralFamilies.get(code[base + i]);
|
|
9651
|
+
if (family !== void 0) {
|
|
9652
|
+
return { scalar: family.map((member) => recognizerRef(code[member + 1])) };
|
|
9653
|
+
}
|
|
9654
|
+
const sequence6 = largeChoiceScalarSequences.get(code[base + i]);
|
|
9655
|
+
return sequence6 === void 0 ? void 0 : { sequence: scalarSequenceRef(sequence6) };
|
|
9656
|
+
});
|
|
8775
9657
|
const maskable = n <= 32;
|
|
8776
9658
|
const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
|
|
8777
9659
|
if (maskable) maskPlan.push(~di);
|
|
8778
9660
|
const p = tmp();
|
|
8779
|
-
const
|
|
8780
|
-
|
|
9661
|
+
const encodedRollbackMask = choiceRollbackMask(prog, ip) ?? -1;
|
|
9662
|
+
const rollbackMask = REC ? -1 : encodedRollbackMask;
|
|
9663
|
+
const hasRollback = rollbackMask !== 0;
|
|
9664
|
+
const startFailureExact = arms.every((_arm, i) => {
|
|
9665
|
+
const terminal = leadingScalarTerminal(code, code[base + i], 0, false);
|
|
9666
|
+
if (terminal < 0) return false;
|
|
9667
|
+
const op2 = code[terminal];
|
|
9668
|
+
const spec = k[code[terminal + 1]];
|
|
9669
|
+
const terminalFx = fx[code[terminal + 2]];
|
|
9670
|
+
const armFx = fx[code[base + n + i]];
|
|
9671
|
+
if (terminalFx.length !== armFx.length || terminalFx.some((expected2, at) => expected2 !== armFx[at])) return false;
|
|
9672
|
+
if (op2 === OP_LIT) return typeof spec === "string" && spec.length > 0;
|
|
9673
|
+
return op2 === OP_RX && spec instanceof RegExp && !regexCanMatchEmpty(spec.source);
|
|
9674
|
+
});
|
|
9675
|
+
const rollbackFor = (i) => rollbackMask === -1 || (rollbackMask & 1 << i) !== 0 ? emitRollback(p, L.buf, L.raw, sinks) : "";
|
|
9676
|
+
if (choiceCannotCommit(prog, ip) && !startFailureExact) {
|
|
9677
|
+
const deepAt = Array.from({ length: n }, () => tmp());
|
|
9678
|
+
const deepFx = Array.from({ length: n }, () => tmp());
|
|
9679
|
+
const remember = (i, at, expectedSet) => `${deepAt[i]}=${at};${deepFx[i]}=${expectedSet}`;
|
|
9680
|
+
const lazyArms = (ascii) => arms.map((arm, i) => {
|
|
9681
|
+
const pretest = pretests[i];
|
|
9682
|
+
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
9683
|
+
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
9684
|
+
const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
|
|
9685
|
+
const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
|
|
9686
|
+
const gate = ascii ? `(bits&${1 << i})!==0${condition}` : `(${gateRefs[i]}===null||classHas(${gateRefs[i]},c))${condition}`;
|
|
9687
|
+
const routeMiss = pretest?.token === void 0 ? "" : `
|
|
9688
|
+
if(${decision}===0){
|
|
9689
|
+
ctx._fc=false
|
|
9690
|
+
{const at=_pfTokEnd
|
|
9691
|
+
${remember(i, "at", pretest.token.expected)}}
|
|
9692
|
+
}`;
|
|
9693
|
+
const sequenceMiss = pretest?.sequence === void 0 ? "" : `
|
|
9694
|
+
else if(${ascii ? `(bits&${1 << i})!==0&&` : ""}${decision}<0){
|
|
9695
|
+
ctx._fc=false
|
|
9696
|
+
{const at=_pfSeqEnd
|
|
9697
|
+
${remember(i, "at", pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("") + pretest.sequence.expected.at(-1))}}
|
|
9698
|
+
}`;
|
|
9699
|
+
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
9700
|
+
`}if(${gate}){
|
|
9701
|
+
ctx._fc=false
|
|
9702
|
+
{const v=${arm}(input,pos,ctx)
|
|
9703
|
+
if(v!==FAIL)return v}
|
|
9704
|
+
{const at=ctx._fe??pos
|
|
9705
|
+
${remember(i, "at", "ctx._fx")}}
|
|
9706
|
+
${rollbackFor(i)}
|
|
9707
|
+
}${routeMiss}${sequenceMiss}`;
|
|
9708
|
+
}).join("\n");
|
|
9709
|
+
const merge = deepAt.map((at, i) => `{const at=${at}??pos
|
|
9710
|
+
const ex=${at}===undefined?${expected[i]}:${deepFx[i]}
|
|
9711
|
+
if(at>best){best=at;acc=_accSet(ex,undefined)}
|
|
9712
|
+
else if(at===best)acc=_accSet(ex,acc)
|
|
9713
|
+
}`).join("\n");
|
|
9714
|
+
const finish = `let best=pos,acc
|
|
9715
|
+
${merge}
|
|
9716
|
+
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
9717
|
+
return FAIL`;
|
|
9718
|
+
return `${head}
|
|
9719
|
+
const c=lead(input,pos)
|
|
9720
|
+
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
9721
|
+
${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
|
|
9722
|
+
${maskable ? `if(c<128){
|
|
9723
|
+
const bits=${maskName}[c<0?128:c]
|
|
9724
|
+
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
9725
|
+
${lazyArms(true)}
|
|
9726
|
+
}else{
|
|
9727
|
+
${lazyArms(false)}
|
|
9728
|
+
}
|
|
9729
|
+
` : lazyArms(false)}
|
|
9730
|
+
${finish}
|
|
9731
|
+
}`;
|
|
9732
|
+
}
|
|
9733
|
+
const needsCatch = maskable || startFailureExact;
|
|
9734
|
+
const catchName = needsCatch ? `_cx${uid++}_` : "";
|
|
9735
|
+
if (needsCatch) {
|
|
8781
9736
|
const catchCases = expected.map((e, i) => `case ${i}:if(target<=${i})return acc;acc=_accSet(${e},acc)`).join("\n");
|
|
8782
9737
|
choiceDefs.push(`function ${catchName}(target,prev,acc){switch(prev){
|
|
8783
9738
|
${catchCases}
|
|
8784
9739
|
}return acc}`);
|
|
8785
9740
|
}
|
|
8786
9741
|
const maskArms = maskable ? arms.map((arm, i) => {
|
|
8787
|
-
|
|
9742
|
+
const pretest = pretests[i];
|
|
9743
|
+
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
9744
|
+
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
9745
|
+
const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
|
|
9746
|
+
const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
|
|
9747
|
+
const routeMiss = pretest?.token === void 0 ? "" : `
|
|
9748
|
+
if(${decision}===0){
|
|
9749
|
+
ctx._fc=false
|
|
9750
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
9751
|
+
prev=${i + 1}`}
|
|
9752
|
+
{const at=_pfTokEnd
|
|
9753
|
+
if(at>best){best=at;acc=undefined}
|
|
9754
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.token.expected},acc)}
|
|
9755
|
+
}`;
|
|
9756
|
+
const sequenceMiss = pretest?.sequence === void 0 ? "" : `
|
|
9757
|
+
else if((bits&${1 << i})!==0&&${decision}<0){
|
|
9758
|
+
ctx._fc=false
|
|
9759
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
9760
|
+
prev=${i + 1}`}
|
|
9761
|
+
{const at=_pfSeqEnd
|
|
9762
|
+
if(at>best){best=at;acc=undefined}
|
|
9763
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("")}${pretest.sequence.expected.at(-1)},acc)}
|
|
9764
|
+
}`;
|
|
9765
|
+
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
9766
|
+
`}if((bits&${1 << i})!==0${condition}){
|
|
8788
9767
|
ctx._fc=false
|
|
8789
9768
|
{const v=${arm}(input,pos,ctx)
|
|
8790
9769
|
if(v!==FAIL)return v}
|
|
8791
|
-
if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
8792
|
-
prev=${i + 1}
|
|
9770
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
9771
|
+
prev=${i + 1}`}
|
|
8793
9772
|
{const at=ctx._fe??pos
|
|
8794
9773
|
if(at>best){best=at;acc=undefined}
|
|
8795
|
-
if(at===best)acc=_accSet(ctx._fx,acc)}
|
|
8796
|
-
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
8797
|
-
${
|
|
8798
|
-
}`;
|
|
9774
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(ctx._fx,acc)}
|
|
9775
|
+
if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0,undefined);acc=_accSet(ctx._fx,acc)}` : ""}if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
9776
|
+
${rollbackFor(i)}
|
|
9777
|
+
}${routeMiss}${sequenceMiss}`;
|
|
8799
9778
|
}).join("\n") : "";
|
|
8800
|
-
const generalArms = arms.map((arm, i) =>
|
|
9779
|
+
const generalArms = arms.map((arm, i) => {
|
|
9780
|
+
const pretest = pretests[i];
|
|
9781
|
+
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
9782
|
+
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
9783
|
+
const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
|
|
9784
|
+
const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
|
|
9785
|
+
const miss = pretest?.sequence !== void 0 ? `else if(${decision}<0){
|
|
9786
|
+
ctx._fc=false
|
|
9787
|
+
const at=_pfSeqEnd
|
|
9788
|
+
if(at>best){best=at;acc=undefined}
|
|
9789
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("")}${pretest.sequence.expected.at(-1)},acc)
|
|
9790
|
+
}${startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)`}` : pretest?.token === void 0 ? startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)` : `else if(${decision}===0){
|
|
9791
|
+
ctx._fc=false
|
|
9792
|
+
const at=_pfTokEnd
|
|
9793
|
+
if(at>best){best=at;acc=undefined}
|
|
9794
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.token.expected},acc)
|
|
9795
|
+
}${startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)`}`;
|
|
9796
|
+
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
9797
|
+
`}if((${gateRefs[i]}===null||classHas(${gateRefs[i]},c))${condition}){
|
|
8801
9798
|
ctx._fc=false
|
|
8802
9799
|
{const v=${arm}(input,pos,ctx)
|
|
8803
9800
|
if(v!==FAIL)return v}
|
|
8804
9801
|
{const at=ctx._fe??pos
|
|
8805
9802
|
if(at>best){best=at;acc=undefined}
|
|
8806
|
-
if(at===best)acc=_accSet(ctx._fx,acc)}
|
|
8807
|
-
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
8808
|
-
${
|
|
8809
|
-
}
|
|
9803
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(ctx._fx,acc)}
|
|
9804
|
+
if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0,undefined);acc=_accSet(ctx._fx,acc)}` : ""}if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
9805
|
+
${rollbackFor(i)}
|
|
9806
|
+
}${miss}`;
|
|
9807
|
+
}).join("\n");
|
|
8810
9808
|
return `${head}
|
|
8811
9809
|
const c=lead(input,pos)
|
|
8812
|
-
${emitMark(p, L.buf, sinks)}
|
|
9810
|
+
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
8813
9811
|
let acc
|
|
8814
9812
|
let best=pos
|
|
8815
9813
|
${maskable ? `if(c<128){
|
|
8816
9814
|
const bits=${maskName}[c<0?128:c]
|
|
8817
|
-
|
|
9815
|
+
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
9816
|
+
${startFailureExact ? "" : "let prev=0"}
|
|
8818
9817
|
${maskArms}
|
|
8819
|
-
if(best===pos)acc=${catchName}(${n},prev,acc)
|
|
8820
|
-
ctx._fe=pos;ctx._fx
|
|
9818
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${n},prev,acc)`}
|
|
9819
|
+
ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
|
|
8821
9820
|
return FAIL
|
|
8822
9821
|
}
|
|
8823
9822
|
` : ""}
|
|
8824
9823
|
${generalArms}
|
|
8825
|
-
ctx._fe=pos;ctx._fx
|
|
9824
|
+
ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
|
|
8826
9825
|
return FAIL
|
|
8827
9826
|
}`;
|
|
8828
9827
|
}
|
|
@@ -8841,30 +9840,8 @@ return FAIL
|
|
|
8841
9840
|
for (let i = 0; i < n; i++) arms.push(link(code[armBase + i]));
|
|
8842
9841
|
const bk = hoist("bk", `DSP[${di}].byKey`);
|
|
8843
9842
|
const dx = hoist("dx", `DSP[${di}].expected`);
|
|
8844
|
-
const claims = (m) => {
|
|
8845
|
-
switch (m[0]) {
|
|
8846
|
-
case 0:
|
|
8847
|
-
return `key.startsWith(${q(m[1])})`;
|
|
8848
|
-
case 1:
|
|
8849
|
-
return `key.endsWith(${q(m[1])})`;
|
|
8850
|
-
case 3:
|
|
8851
|
-
return `asciiFoldKey(key).startsWith(${q(m[1])})`;
|
|
8852
|
-
case 4:
|
|
8853
|
-
return `asciiFoldKey(key).endsWith(${q(m[1])})`;
|
|
8854
|
-
default: {
|
|
8855
|
-
if (!m[2].includes("g") && !m[2].includes("y")) {
|
|
8856
|
-
try {
|
|
8857
|
-
new RegExp(m[1], m[2]);
|
|
8858
|
-
return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
|
|
8859
|
-
} catch {
|
|
8860
|
-
}
|
|
8861
|
-
}
|
|
8862
|
-
return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
|
|
8863
|
-
}
|
|
8864
|
-
}
|
|
8865
|
-
};
|
|
8866
9843
|
const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
|
|
8867
|
-
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${
|
|
9844
|
+
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${dispatchClaim(m)})arm=${m[3]}`).join("\n")}
|
|
8868
9845
|
}
|
|
8869
9846
|
`;
|
|
8870
9847
|
const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
|
|
@@ -8872,33 +9849,43 @@ ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${claims(m)})arm=${m[3]}
|
|
|
8872
9849
|
const m1 = tmp();
|
|
8873
9850
|
const m2 = tmp();
|
|
8874
9851
|
const routedCall = (target) => `{const savedRouted=ctx._routed
|
|
8875
|
-
${emitRollback(m1, L.buf, sinks)}
|
|
8876
|
-
${emitMark(m2, L.buf, sinks, false)}
|
|
9852
|
+
${emitRollback(m1, L.buf, L.raw, sinks)}
|
|
9853
|
+
${emitMark(m2, L.buf, L.raw, sinks, false)}
|
|
8877
9854
|
ctx._routed={value:key,span:{start:pos,end:selEnd}}
|
|
8878
9855
|
try{v=${target}(input,pos,ctx)}finally{ctx._routed=savedRouted}
|
|
8879
9856
|
break}`;
|
|
8880
9857
|
const plainCall = (target) => `v=${target}(input,selEnd,ctx);break`;
|
|
8881
9858
|
const armCases = arms.map((target, i) => `case ${i}:${spec.routed[i] === 1 ? routedCall(target) : plainCall(target)}`).join("\n");
|
|
8882
9859
|
const fallbackCase = other === void 0 ? "" : `default:${otherRouted ? routedCall(other) : plainCall(other)}`;
|
|
9860
|
+
const armSelection = tokenChoiceDispatches.has(ip) ? `const tp=_pfTokDispatch===${ip}&&_pfTokInput===input&&_pfTokPos===pos
|
|
9861
|
+
let arm
|
|
9862
|
+
if(tp){
|
|
9863
|
+
arm=_pfTokArm
|
|
9864
|
+
_pfTokDispatch=-1
|
|
9865
|
+
_pfTokInput=undefined
|
|
9866
|
+
if(arm===${n})arm=undefined
|
|
9867
|
+
}else{
|
|
9868
|
+
arm=${bk}.get(key)
|
|
9869
|
+
${fold}${chain}}` : `let arm=${bk}.get(key)
|
|
9870
|
+
${fold}${chain}`;
|
|
8883
9871
|
return `${head}
|
|
8884
|
-
${emitMark(m1, L.buf, sinks)}
|
|
9872
|
+
${emitMark(m1, L.buf, L.raw, sinks)}
|
|
8885
9873
|
const sv=${selector}(input,pos,ctx)
|
|
8886
9874
|
if(sv===FAIL)return FAIL
|
|
8887
9875
|
const selEnd=EC.e
|
|
8888
9876
|
const key=sv
|
|
8889
|
-
|
|
8890
|
-
${fold}${chain}
|
|
9877
|
+
${armSelection}
|
|
8891
9878
|
if(arm===undefined){
|
|
8892
9879
|
${other === void 0 ? `ctx._fe=selEnd;ctx._fx=${dx};return FAIL` : ""}
|
|
8893
9880
|
}
|
|
8894
|
-
${emitMark(m2, L.buf, sinks)}
|
|
9881
|
+
${emitMark(m2, L.buf, L.raw, sinks)}
|
|
8895
9882
|
let v
|
|
8896
9883
|
switch(arm){
|
|
8897
9884
|
${armCases}
|
|
8898
9885
|
${fallbackCase}
|
|
8899
9886
|
}
|
|
8900
9887
|
if(v===FAIL){
|
|
8901
|
-
${emitRollback(m2, L.buf, sinks)}
|
|
9888
|
+
${emitRollback(m2, L.buf, L.raw, sinks)}
|
|
8902
9889
|
ctx._fc=true
|
|
8903
9890
|
return FAIL
|
|
8904
9891
|
}
|
|
@@ -8934,23 +9921,25 @@ return [key,v]
|
|
|
8934
9921
|
const skip = skipFor(L);
|
|
8935
9922
|
const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
|
|
8936
9923
|
const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
|
|
8937
|
-
const pfd = sinks.fd ? `${p}fd` : "
|
|
9924
|
+
const pfd = sinks.fd ? `${p}fd` : "undefined";
|
|
8938
9925
|
const per = sinks.er ? `${p}er` : "undefined";
|
|
8939
|
-
const
|
|
9926
|
+
const rbHelper = L.raw === RAW_OMIT ? "_rbNoRawBuf" : "_rbBuf";
|
|
9927
|
+
const rb = L.buf && L.raw !== 0 ? `${rbHelper}(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
|
|
8940
9928
|
if(ctx._fields!==undefined&&ctx._fields.length!==${p}fd)ctx._fields.length=${p}fd` : ""}${sinks.er ? `
|
|
8941
|
-
if(ctx._errors!==undefined&&ctx._errors.length!==${p}er)ctx._errors.length=${p}er` : ""}` : `if(needMark)rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)`;
|
|
9929
|
+
if(ctx._errors!==undefined&&ctx._errors.length!==${p}er)ctx._errors.length=${p}er` : ""}` : L.buf ? `rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)` : `if(needMark)rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)`;
|
|
8942
9930
|
const markSinks = `${sinks.fd ? `
|
|
8943
9931
|
${p}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${sinks.er ? `
|
|
8944
9932
|
${p}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
|
|
9933
|
+
const markRaw = L.raw === RAW_OMIT ? `${p}raw=b.rawLen` : L.raw === RAW_CAPTURE ? `const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0` : `const r=b.raw;${p}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)`;
|
|
8945
9934
|
const markBody = L.buf ? `const b=ctx._cstBuf
|
|
8946
|
-
|
|
9935
|
+
${markRaw}
|
|
8947
9936
|
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
8948
9937
|
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
8949
9938
|
${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
8950
9939
|
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}` : `if(needMark){
|
|
8951
9940
|
const b=ctx._cstBuf
|
|
8952
9941
|
if(b!==undefined){
|
|
8953
|
-
const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
9942
|
+
const r=b.raw;${p}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)
|
|
8954
9943
|
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
8955
9944
|
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
8956
9945
|
}else{
|
|
@@ -9057,7 +10046,7 @@ const leaf={_tag:'leaf',value,span:{start:pos,end}}
|
|
|
9057
10046
|
const kids=[leaf],rawKids=[leaf],span={start:pos,end}
|
|
9058
10047
|
EC.e=end
|
|
9059
10048
|
const nd=${build2}(kids,undefined,span,rawKids,EMPTY_TL,undefined)
|
|
9060
|
-
${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
10049
|
+
${L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : staticBuild ? "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,ctx._cstBuf!==undefined&&ctx._cstBuf.noRaw===true?undefined:ctx._cstBuf!==undefined||ctx._cstRawChildren!==undefined?rawEntry(nd,input,pos,end):undefined)" : "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
9061
10050
|
EC.e=end
|
|
9062
10051
|
return nd
|
|
9063
10052
|
}`;
|
|
@@ -9079,7 +10068,22 @@ return nd
|
|
|
9079
10068
|
if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
|
|
9080
10069
|
const fields = flags === 18;
|
|
9081
10070
|
const collapseChildren = flags === 34;
|
|
9082
|
-
const publish = `if(sBuf!==undefined){
|
|
10071
|
+
const publish = L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? `if(sBuf!==undefined){
|
|
10072
|
+
if(sBuf.rawOnly!==true){
|
|
10073
|
+
if(sBuf.ch!==undefined)sBuf.ch.push(nd)
|
|
10074
|
+
else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
|
|
10075
|
+
else sBuf.single=nd
|
|
10076
|
+
}
|
|
10077
|
+
const rawNd=rawEntry(nd,input,pos,end)
|
|
10078
|
+
if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
|
|
10079
|
+
else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
|
|
10080
|
+
else sBuf.rawSingle=rawNd
|
|
10081
|
+
}else if(sCh!==undefined){
|
|
10082
|
+
sCh.push(nd)
|
|
10083
|
+
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
10084
|
+
}` : `if(sBuf!==undefined){
|
|
10085
|
+
if(sBuf.noRaw===true)_pushNodeNoRawBuf(ctx,nd)
|
|
10086
|
+
else{
|
|
9083
10087
|
if(sBuf.rawOnly!==true){
|
|
9084
10088
|
if(sBuf.ch!==undefined)sBuf.ch.push(nd)
|
|
9085
10089
|
else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
|
|
@@ -9089,6 +10093,7 @@ const rawNd=rawEntry(nd,input,pos,end)
|
|
|
9089
10093
|
if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
|
|
9090
10094
|
else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
|
|
9091
10095
|
else sBuf.rawSingle=rawNd
|
|
10096
|
+
}
|
|
9092
10097
|
}else if(sCh!==undefined){
|
|
9093
10098
|
sCh.push(nd)
|
|
9094
10099
|
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
@@ -9127,6 +10132,7 @@ return nd
|
|
|
9127
10132
|
const wantFields = hasFields || hostCst;
|
|
9128
10133
|
const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
|
|
9129
10134
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
10135
|
+
const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
|
|
9130
10136
|
const ty = q(type);
|
|
9131
10137
|
const stArg = readsState ? "st" : "(ctx.state!==undefined?Object.assign({},ctx.state):undefined)";
|
|
9132
10138
|
const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
|
|
@@ -9140,7 +10146,12 @@ return nd
|
|
|
9140
10146
|
value = `nd=_pfHost!==undefined?_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,st,${tags}):{_tag:'node',type:${ty},span,state:st??null,children:kids}`;
|
|
9141
10147
|
}
|
|
9142
10148
|
const collapsible = keepChildren && (hostCst || build === void 0 && proj < 0);
|
|
9143
|
-
const openCapture =
|
|
10149
|
+
const openCapture = omitsRaw ? `const buf={noRaw:true,rawLen:0}
|
|
10150
|
+
ctx._cstBuf=buf
|
|
10151
|
+
ctx._cstChildren=undefined
|
|
10152
|
+
ctx._cstLeaves=undefined
|
|
10153
|
+
ctx._cstRawChildren=undefined
|
|
10154
|
+
ctx._cstTriviaLog=undefined` : keepChildren ? `const buf={}
|
|
9144
10155
|
ctx._cstBuf=buf
|
|
9145
10156
|
ctx._cstChildren=undefined
|
|
9146
10157
|
ctx._cstLeaves=undefined
|
|
@@ -9151,7 +10162,10 @@ ctx._cstChildren=undefined
|
|
|
9151
10162
|
ctx._cstLeaves=undefined
|
|
9152
10163
|
ctx._cstRawChildren=undefined
|
|
9153
10164
|
ctx._cstTriviaLog=undefined`;
|
|
9154
|
-
const finishCapture =
|
|
10165
|
+
const finishCapture = omitsRaw ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
|
|
10166
|
+
const hostKids=kids
|
|
10167
|
+
const rawKids=EMPTY_CH
|
|
10168
|
+
const tlog=buf.tl??EMPTY_TLOG` : keepChildren ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
|
|
9155
10169
|
const hostKids=kids
|
|
9156
10170
|
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
9157
10171
|
const tlog=buf.tl??EMPTY_TLOG` : `const kids=EMPTY_CH
|
|
@@ -9185,7 +10199,7 @@ const st=${readsState ? "(ctx.state!==undefined?Object.assign({},ctx.state):unde
|
|
|
9185
10199
|
let nd
|
|
9186
10200
|
${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]
|
|
9187
10201
|
else ` : ""}{${value}}
|
|
9188
|
-
${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
10202
|
+
${L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : staticBuild ? "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,sBuf!==undefined?(sBuf.noRaw===true?undefined:rawEntry(nd,input,pos,end)):sRaw!==undefined?rawEntry(nd,input,pos,end):undefined)" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
9189
10203
|
EC.e=end
|
|
9190
10204
|
return nd
|
|
9191
10205
|
}`;
|
|
@@ -9203,7 +10217,7 @@ return nd
|
|
|
9203
10217
|
}
|
|
9204
10218
|
const extra = [];
|
|
9205
10219
|
for (const ip of extraIps) extra.push(`${ip}:${link(ip)}`);
|
|
9206
|
-
const source = `${RUNTIME_PRELUDE}
|
|
10220
|
+
const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
|
|
9207
10221
|
${prelude.join("\n")}
|
|
9208
10222
|
${skipDefs.join("\n")}
|
|
9209
10223
|
${choiceDefs.join("\n")}
|
|
@@ -9218,7 +10232,13 @@ _pfHost=host
|
|
|
9218
10232
|
function _finish(){
|
|
9219
10233
|
if(_pfDepth<=0)throw new Error('parseman emitted table assembly frame underflow')
|
|
9220
10234
|
_pfDepth--
|
|
9221
|
-
if(_pfDepth===0)
|
|
10235
|
+
if(_pfDepth===0){
|
|
10236
|
+
_pfTokInput=undefined
|
|
10237
|
+
_pfTokBody=-1
|
|
10238
|
+
_pfTokValue=undefined
|
|
10239
|
+
_pfTokDispatch=-1
|
|
10240
|
+
return
|
|
10241
|
+
}
|
|
9222
10242
|
const prior=_pfFrames.pop()
|
|
9223
10243
|
_pfScan=prior[0]
|
|
9224
10244
|
_pfHost=prior[1]
|
|
@@ -9985,6 +11005,17 @@ function assemble(t2, prog, cfg) {
|
|
|
9985
11005
|
}
|
|
9986
11006
|
return recognize;
|
|
9987
11007
|
}
|
|
11008
|
+
const labelExtraIps = [];
|
|
11009
|
+
for (const s of prog.scans ?? []) {
|
|
11010
|
+
for (const r of s.skip) labelExtraIps.push(r[0]);
|
|
11011
|
+
if (s.sentinel !== void 0) labelExtraIps.push(s.sentinel[0]);
|
|
11012
|
+
}
|
|
11013
|
+
for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
|
|
11014
|
+
const closureLabels = computeSiteLabels(
|
|
11015
|
+
code,
|
|
11016
|
+
[...Object.values(prog.rules), ...labelExtraIps],
|
|
11017
|
+
hostCst
|
|
11018
|
+
);
|
|
9988
11019
|
let SCAN = null;
|
|
9989
11020
|
const memo = /* @__PURE__ */ new Map();
|
|
9990
11021
|
const reached = /* @__PURE__ */ new Set();
|
|
@@ -10230,7 +11261,7 @@ function assemble(t2, prog, cfg) {
|
|
|
10230
11261
|
const b = ctx._cstBuf;
|
|
10231
11262
|
if (b !== void 0) {
|
|
10232
11263
|
const raw = b.raw;
|
|
10233
|
-
MRAW = raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
|
|
11264
|
+
MRAW = b.noRaw === true ? b.rawLen ?? 0 : raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
|
|
10234
11265
|
const ch2 = b.ch;
|
|
10235
11266
|
MLV = ch2 !== void 0 ? ch2.length : b.single !== void 0 ? 1 : 0;
|
|
10236
11267
|
const tl = b.tl;
|
|
@@ -10314,6 +11345,31 @@ function assemble(t2, prog, cfg) {
|
|
|
10314
11345
|
if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
10315
11346
|
return cur;
|
|
10316
11347
|
}
|
|
11348
|
+
function nextTermBuffered(child, input, cur, ctx) {
|
|
11349
|
+
if (ctx.trivia === void 0) {
|
|
11350
|
+
const v2 = child(input, cur, ctx);
|
|
11351
|
+
if (v2 === FAIL) return -1;
|
|
11352
|
+
TERMV = v2;
|
|
11353
|
+
return EC.e;
|
|
11354
|
+
}
|
|
11355
|
+
const before = ctx._cstBuf;
|
|
11356
|
+
const beforeTl = before.tl;
|
|
11357
|
+
const mTl = beforeTl === void 0 ? 0 : beforeTl.length;
|
|
11358
|
+
const mLog = ctx._triviaLog?.length ?? 0;
|
|
11359
|
+
const mRoot = ctx._rootTriviaLog?.length ?? 0;
|
|
11360
|
+
const scanEnd = skipTrivia(input, cur, ctx);
|
|
11361
|
+
const scanned = ctx._cstBuf;
|
|
11362
|
+
const scannedTl = scanned.tl;
|
|
11363
|
+
const scanTl = scannedTl === void 0 ? 0 : scannedTl.length;
|
|
11364
|
+
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
11365
|
+
const scanRoot = ctx._rootTriviaLog?.length ?? 0;
|
|
11366
|
+
const v = child(input, scanEnd, ctx);
|
|
11367
|
+
if (v === FAIL) return -1;
|
|
11368
|
+
TERMV = v;
|
|
11369
|
+
if (EC.e > scanEnd) return EC.e;
|
|
11370
|
+
rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
11371
|
+
return cur;
|
|
11372
|
+
}
|
|
10317
11373
|
function committed3(c) {
|
|
10318
11374
|
return c._fc === true;
|
|
10319
11375
|
}
|
|
@@ -10584,7 +11640,8 @@ function assemble(t2, prog, cfg) {
|
|
|
10584
11640
|
target = p;
|
|
10585
11641
|
} };
|
|
10586
11642
|
inFlight.set(ip, holder);
|
|
10587
|
-
const
|
|
11643
|
+
const op = code[ip];
|
|
11644
|
+
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);
|
|
10588
11645
|
inFlight.delete(ip);
|
|
10589
11646
|
holder.set(piece);
|
|
10590
11647
|
memo.set(ip, piece);
|
|
@@ -11327,6 +12384,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11327
12384
|
const reducer = fused ? code[ip + 1] : -1;
|
|
11328
12385
|
const projection = reducer < 0 ? ~reducer : -1;
|
|
11329
12386
|
const fn = fused && projection < 0 ? fns[reducer] : void 0;
|
|
12387
|
+
const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm;
|
|
11330
12388
|
const runnerBlock = (count, r0, r1, r2, r3, next) => {
|
|
11331
12389
|
if (count === 1) return (input, cur, ctx, values, inherited) => {
|
|
11332
12390
|
cur = r0(input, cur, ctx, inherited);
|
|
@@ -11381,7 +12439,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11381
12439
|
const kid = link(kidIp);
|
|
11382
12440
|
return (input, cur, ctx, inherited) => {
|
|
11383
12441
|
ctx._sync = sync ?? inherited;
|
|
11384
|
-
return
|
|
12442
|
+
return step(kid, input, cur, ctx);
|
|
11385
12443
|
};
|
|
11386
12444
|
}
|
|
11387
12445
|
const negated = code[kidIp + 1] === 1;
|
|
@@ -11466,7 +12524,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11466
12524
|
const kidIp = code[base + i];
|
|
11467
12525
|
if (code[kidIp] !== OP_ADJ) {
|
|
11468
12526
|
const kid = link(kidIp);
|
|
11469
|
-
return (input, cur, ctx) =>
|
|
12527
|
+
return (input, cur, ctx) => step(kid, input, cur, ctx);
|
|
11470
12528
|
}
|
|
11471
12529
|
const negated = code[kidIp + 1] === 1;
|
|
11472
12530
|
const ki = code[kidIp + 2];
|
|
@@ -11555,7 +12613,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11555
12613
|
return (input, pos, ctx) => {
|
|
11556
12614
|
const v0 = k0(input, pos, ctx);
|
|
11557
12615
|
if (v0 === FAIL) return FAIL;
|
|
11558
|
-
const cur =
|
|
12616
|
+
const cur = step(k1, input, EC.e, ctx);
|
|
11559
12617
|
if (cur < 0) return FAIL;
|
|
11560
12618
|
EC.e = cur;
|
|
11561
12619
|
return projection === 0 ? v0 : projection === 1 ? TERMV : fn([v0, TERMV], { start: pos, end: cur });
|
|
@@ -11565,7 +12623,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11565
12623
|
return (input, pos, ctx) => {
|
|
11566
12624
|
const v0 = k0(input, pos, ctx);
|
|
11567
12625
|
if (v0 === FAIL) return FAIL;
|
|
11568
|
-
const cur =
|
|
12626
|
+
const cur = step(k1, input, EC.e, ctx);
|
|
11569
12627
|
if (cur < 0) return FAIL;
|
|
11570
12628
|
EC.e = cur;
|
|
11571
12629
|
return [v0, TERMV];
|
|
@@ -11574,7 +12632,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11574
12632
|
return (input, pos, ctx) => {
|
|
11575
12633
|
const v0 = k0(input, pos, ctx);
|
|
11576
12634
|
if (v0 === FAIL) return FAIL;
|
|
11577
|
-
const cur =
|
|
12635
|
+
const cur = step(k1, input, EC.e, ctx);
|
|
11578
12636
|
if (cur < 0) return FAIL;
|
|
11579
12637
|
EC.e = cur;
|
|
11580
12638
|
return void 0;
|
|
@@ -11586,10 +12644,10 @@ function assemble(t2, prog, cfg) {
|
|
|
11586
12644
|
return (input, pos, ctx) => {
|
|
11587
12645
|
const v0 = k0(input, pos, ctx);
|
|
11588
12646
|
if (v0 === FAIL) return FAIL;
|
|
11589
|
-
let cur =
|
|
12647
|
+
let cur = step(k1, input, EC.e, ctx);
|
|
11590
12648
|
if (cur < 0) return FAIL;
|
|
11591
12649
|
const v1 = TERMV;
|
|
11592
|
-
cur =
|
|
12650
|
+
cur = step(k2, input, cur, ctx);
|
|
11593
12651
|
if (cur < 0) return FAIL;
|
|
11594
12652
|
EC.e = cur;
|
|
11595
12653
|
return projection === 0 ? v0 : projection === 1 ? v1 : projection === 2 ? TERMV : fn([v0, v1, TERMV], { start: pos, end: cur });
|
|
@@ -11599,10 +12657,10 @@ function assemble(t2, prog, cfg) {
|
|
|
11599
12657
|
return (input, pos, ctx) => {
|
|
11600
12658
|
const v0 = k0(input, pos, ctx);
|
|
11601
12659
|
if (v0 === FAIL) return FAIL;
|
|
11602
|
-
let cur =
|
|
12660
|
+
let cur = step(k1, input, EC.e, ctx);
|
|
11603
12661
|
if (cur < 0) return FAIL;
|
|
11604
12662
|
const v1 = TERMV;
|
|
11605
|
-
cur =
|
|
12663
|
+
cur = step(k2, input, cur, ctx);
|
|
11606
12664
|
if (cur < 0) return FAIL;
|
|
11607
12665
|
EC.e = cur;
|
|
11608
12666
|
return [v0, v1, TERMV];
|
|
@@ -11611,9 +12669,9 @@ function assemble(t2, prog, cfg) {
|
|
|
11611
12669
|
return (input, pos, ctx) => {
|
|
11612
12670
|
const v0 = k0(input, pos, ctx);
|
|
11613
12671
|
if (v0 === FAIL) return FAIL;
|
|
11614
|
-
let cur =
|
|
12672
|
+
let cur = step(k1, input, EC.e, ctx);
|
|
11615
12673
|
if (cur < 0) return FAIL;
|
|
11616
|
-
cur =
|
|
12674
|
+
cur = step(k2, input, cur, ctx);
|
|
11617
12675
|
if (cur < 0) return FAIL;
|
|
11618
12676
|
EC.e = cur;
|
|
11619
12677
|
return void 0;
|
|
@@ -11621,43 +12679,43 @@ function assemble(t2, prog, cfg) {
|
|
|
11621
12679
|
}
|
|
11622
12680
|
const block = (count, k0, k1, k2, k3, next) => {
|
|
11623
12681
|
if (count === 1) return (input, cur, ctx, values) => {
|
|
11624
|
-
cur =
|
|
12682
|
+
cur = step(k0, input, cur, ctx);
|
|
11625
12683
|
if (cur < 0) return -1;
|
|
11626
12684
|
if (values !== void 0) values.push(TERMV);
|
|
11627
12685
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
11628
12686
|
};
|
|
11629
12687
|
if (count === 2) return (input, cur, ctx, values) => {
|
|
11630
|
-
cur =
|
|
12688
|
+
cur = step(k0, input, cur, ctx);
|
|
11631
12689
|
if (cur < 0) return -1;
|
|
11632
12690
|
if (values !== void 0) values.push(TERMV);
|
|
11633
|
-
cur =
|
|
12691
|
+
cur = step(k1, input, cur, ctx);
|
|
11634
12692
|
if (cur < 0) return -1;
|
|
11635
12693
|
if (values !== void 0) values.push(TERMV);
|
|
11636
12694
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
11637
12695
|
};
|
|
11638
12696
|
if (count === 3) return (input, cur, ctx, values) => {
|
|
11639
|
-
cur =
|
|
12697
|
+
cur = step(k0, input, cur, ctx);
|
|
11640
12698
|
if (cur < 0) return -1;
|
|
11641
12699
|
if (values !== void 0) values.push(TERMV);
|
|
11642
|
-
cur =
|
|
12700
|
+
cur = step(k1, input, cur, ctx);
|
|
11643
12701
|
if (cur < 0) return -1;
|
|
11644
12702
|
if (values !== void 0) values.push(TERMV);
|
|
11645
|
-
cur =
|
|
12703
|
+
cur = step(k2, input, cur, ctx);
|
|
11646
12704
|
if (cur < 0) return -1;
|
|
11647
12705
|
if (values !== void 0) values.push(TERMV);
|
|
11648
12706
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
11649
12707
|
};
|
|
11650
12708
|
return (input, cur, ctx, values) => {
|
|
11651
|
-
cur =
|
|
12709
|
+
cur = step(k0, input, cur, ctx);
|
|
11652
12710
|
if (cur < 0) return -1;
|
|
11653
12711
|
if (values !== void 0) values.push(TERMV);
|
|
11654
|
-
cur =
|
|
12712
|
+
cur = step(k1, input, cur, ctx);
|
|
11655
12713
|
if (cur < 0) return -1;
|
|
11656
12714
|
if (values !== void 0) values.push(TERMV);
|
|
11657
|
-
cur =
|
|
12715
|
+
cur = step(k2, input, cur, ctx);
|
|
11658
12716
|
if (cur < 0) return -1;
|
|
11659
12717
|
if (values !== void 0) values.push(TERMV);
|
|
11660
|
-
cur =
|
|
12718
|
+
cur = step(k3, input, cur, ctx);
|
|
11661
12719
|
if (cur < 0) return -1;
|
|
11662
12720
|
if (values !== void 0) values.push(TERMV);
|
|
11663
12721
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
@@ -11828,6 +12886,13 @@ function assemble(t2, prog, cfg) {
|
|
|
11828
12886
|
if (n === 2 || n === 3) {
|
|
11829
12887
|
const a0 = link(code[base]), a1 = link(code[base + 1]);
|
|
11830
12888
|
const a2 = n === 3 ? link(code[base + 2]) : void 0;
|
|
12889
|
+
const predecide = !hostCst && !REC && !cfg.probe && !cfg.coverage && !cfg.trackLines;
|
|
12890
|
+
const p0ip = predecide ? leadingScalarTerminal(code, code[base], 2, true, true) : -1;
|
|
12891
|
+
const p1ip = predecide ? leadingScalarTerminal(code, code[base + 1], 2, true, true) : -1;
|
|
12892
|
+
const p2ip = predecide && n === 3 ? leadingScalarTerminal(code, code[base + 2], 2, true, true) : -1;
|
|
12893
|
+
const p0 = p0ip < 0 ? void 0 : scalarFor(p0ip);
|
|
12894
|
+
const p1 = p1ip < 0 ? void 0 : scalarFor(p1ip);
|
|
12895
|
+
const p2 = p2ip < 0 ? void 0 : scalarFor(p2ip);
|
|
11831
12896
|
const e0 = fx[code[base + n]];
|
|
11832
12897
|
const e1 = fx[code[base + n + 1]];
|
|
11833
12898
|
const e2 = n === 3 ? fx[code[base + n + 2]] : void 0;
|
|
@@ -11857,7 +12922,10 @@ function assemble(t2, prog, cfg) {
|
|
|
11857
12922
|
let acc;
|
|
11858
12923
|
let best = pos;
|
|
11859
12924
|
if (c < 128) {
|
|
11860
|
-
|
|
12925
|
+
let bits = mask[c < 0 ? 128 : c];
|
|
12926
|
+
if ((bits & 1) !== 0 && p0 !== void 0 && p0(input, pos) < 0) bits &= ~1;
|
|
12927
|
+
if ((bits & 2) !== 0 && p1 !== void 0 && p1(input, pos) < 0) bits &= ~2;
|
|
12928
|
+
if ((bits & 4) !== 0 && p2 !== void 0 && p2(input, pos) < 0) bits &= ~4;
|
|
11861
12929
|
let prev = 0;
|
|
11862
12930
|
if ((bits & 1) !== 0) {
|
|
11863
12931
|
ctx._fc = false;
|
|
@@ -11920,7 +12988,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11920
12988
|
ctx._fx = acc ?? choiceFx;
|
|
11921
12989
|
return FAIL;
|
|
11922
12990
|
}
|
|
11923
|
-
if (g0 === null || classHas2(g0, c)) {
|
|
12991
|
+
if ((g0 === null || classHas2(g0, c)) && (p0 === void 0 || p0(input, pos) >= 0)) {
|
|
11924
12992
|
ctx._fc = false;
|
|
11925
12993
|
const v = a0(input, pos, ctx);
|
|
11926
12994
|
if (v !== FAIL) return v;
|
|
@@ -11936,7 +13004,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11936
13004
|
}
|
|
11937
13005
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
11938
13006
|
} else if (best === pos) acc = accSet(e0, acc);
|
|
11939
|
-
if (g1 === null || classHas2(g1, c)) {
|
|
13007
|
+
if ((g1 === null || classHas2(g1, c)) && (p1 === void 0 || p1(input, pos) >= 0)) {
|
|
11940
13008
|
ctx._fc = false;
|
|
11941
13009
|
const v = a1(input, pos, ctx);
|
|
11942
13010
|
if (v !== FAIL) return v;
|
|
@@ -11953,7 +13021,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11953
13021
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
11954
13022
|
} else if (best === pos) acc = accSet(e1, acc);
|
|
11955
13023
|
if (n === 3) {
|
|
11956
|
-
if (g2 === null || classHas2(g2, c)) {
|
|
13024
|
+
if ((g2 === null || classHas2(g2, c)) && (p2 === void 0 || p2(input, pos) >= 0)) {
|
|
11957
13025
|
ctx._fc = false;
|
|
11958
13026
|
const v = a2(input, pos, ctx);
|
|
11959
13027
|
if (v !== FAIL) return v;
|
|
@@ -12526,20 +13594,14 @@ function assemble(t2, prog, cfg) {
|
|
|
12526
13594
|
const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
|
|
12527
13595
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
12528
13596
|
const rawOnly = !keepChildren;
|
|
13597
|
+
const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
|
|
12529
13598
|
return (input, pos, ctx) => {
|
|
12530
13599
|
const host = HOST;
|
|
12531
13600
|
const sCh = ctx._cstChildren;
|
|
12532
|
-
const sLv = ctx._cstLeaves;
|
|
12533
|
-
const sRaw = ctx._cstRawChildren;
|
|
12534
|
-
const sTl = ctx._cstTriviaLog;
|
|
12535
13601
|
const sCap = ctx.captureTrivia;
|
|
12536
13602
|
const sBuf = ctx._cstBuf;
|
|
12537
|
-
const buf = rawOnly ? { rawOnly: true } : {};
|
|
13603
|
+
const buf = rawOnly ? { rawOnly: true } : omitsRaw ? { noRaw: true, rawLen: 0 } : {};
|
|
12538
13604
|
ctx._cstBuf = buf;
|
|
12539
|
-
ctx._cstChildren = void 0;
|
|
12540
|
-
ctx._cstLeaves = void 0;
|
|
12541
|
-
ctx._cstRawChildren = void 0;
|
|
12542
|
-
ctx._cstTriviaLog = void 0;
|
|
12543
13605
|
ctx.captureTrivia = captureWide;
|
|
12544
13606
|
const savedFields = ctx._fields;
|
|
12545
13607
|
ctx._fields = wantFields ? [] : void 0;
|
|
@@ -12554,13 +13616,9 @@ function assemble(t2, prog, cfg) {
|
|
|
12554
13616
|
if (structural) ctx._triviaCaptureMask = savedMask;
|
|
12555
13617
|
const kids = rawOnly ? EMPTY_CH : buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
|
|
12556
13618
|
const hostKids = kids;
|
|
12557
|
-
const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
|
|
13619
|
+
const rawKids = omitsRaw ? EMPTY_CH : buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
|
|
12558
13620
|
const tlog = buf.tl ?? EMPTY_TLOG;
|
|
12559
13621
|
ctx._cstBuf = sBuf;
|
|
12560
|
-
ctx._cstChildren = sCh;
|
|
12561
|
-
ctx._cstLeaves = sLv;
|
|
12562
|
-
ctx._cstRawChildren = sRaw;
|
|
12563
|
-
ctx._cstTriviaLog = sTl;
|
|
12564
13622
|
ctx.captureTrivia = sCap;
|
|
12565
13623
|
if (v === FAIL) return FAIL;
|
|
12566
13624
|
const end = EC.e;
|
|
@@ -12651,6 +13709,34 @@ function assemble(t2, prog, cfg) {
|
|
|
12651
13709
|
rawScalarSpecs.add(code[child + 1]);
|
|
12652
13710
|
scalarFor(child);
|
|
12653
13711
|
}
|
|
13712
|
+
} else if (code[ip] === OP_CHOICE && !disp[code[ip + 1]].exclusive) {
|
|
13713
|
+
const n = code[ip + 2];
|
|
13714
|
+
for (let i = 0; i < n; i++) {
|
|
13715
|
+
const armIp = code[ip + 4 + i];
|
|
13716
|
+
const child = leadingScalarTerminal(code, armIp, 2, true, true);
|
|
13717
|
+
if (n === 2 || n === 3) {
|
|
13718
|
+
if (child >= 0) scalarFor(child);
|
|
13719
|
+
continue;
|
|
13720
|
+
}
|
|
13721
|
+
if (child >= 0) {
|
|
13722
|
+
const spec = k[code[child + 1]];
|
|
13723
|
+
if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) {
|
|
13724
|
+
scalarFor(child);
|
|
13725
|
+
continue;
|
|
13726
|
+
}
|
|
13727
|
+
}
|
|
13728
|
+
const family = leadingLiteralFamily(code, k, armIp);
|
|
13729
|
+
if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
13730
|
+
const value = k[code[terminal + 1]];
|
|
13731
|
+
return typeof value === "string" && value.length >= 2;
|
|
13732
|
+
})) {
|
|
13733
|
+
for (const terminal of family) scalarFor(terminal);
|
|
13734
|
+
}
|
|
13735
|
+
const sequence6 = leadingScalarSequence(code, armIp);
|
|
13736
|
+
if (sequence6 !== void 0 && (sequence6.trivia < 0 || triviaScan[sequence6.trivia] != null)) {
|
|
13737
|
+
for (const terminal of sequence6.terminals) scalarFor(terminal);
|
|
13738
|
+
}
|
|
13739
|
+
}
|
|
12654
13740
|
}
|
|
12655
13741
|
}
|
|
12656
13742
|
const notChild = scalarTerminalNotChild(code, ip);
|
|
@@ -13061,7 +14147,7 @@ function emitAssemblies(prog, cfgs) {
|
|
|
13061
14147
|
seen.add(key);
|
|
13062
14148
|
let em;
|
|
13063
14149
|
try {
|
|
13064
|
-
em = emitAssemblySource(t2, prog, cfg, extraIps);
|
|
14150
|
+
em = emitAssemblySource(t2, prog, cfg, extraIps, true);
|
|
13065
14151
|
} catch (e) {
|
|
13066
14152
|
if (e instanceof Unemittable) continue;
|
|
13067
14153
|
throw e;
|
|
@@ -14594,7 +15680,7 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
|
14594
15680
|
};
|
|
14595
15681
|
const { prog, fnSrcs } = encodeTableProgram({ [ENTRY]: combinator }, settings);
|
|
14596
15682
|
const artifact = closureArtifact(prog);
|
|
14597
|
-
const entry = tableRules(
|
|
15683
|
+
const entry = tableRules(prog)[ENTRY];
|
|
14598
15684
|
const offered = opts.fnSources ?? mapFnSources;
|
|
14599
15685
|
const supplied = offered !== void 0 && offered.length === fnSrcs.length ? offered : void 0;
|
|
14600
15686
|
const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? ownSource(prog.fns[i]));
|
|
@@ -15116,6 +16202,7 @@ function rebuildCombinator(root, replacements) {
|
|
|
15116
16202
|
return p;
|
|
15117
16203
|
}
|
|
15118
16204
|
out = d.type === void 0 ? d.build === void 0 ? node(one(d.parser), opts) : node(one(d.parser), d.build) : node(d.type, one(d.parser), d.build, opts);
|
|
16205
|
+
if (d.buildRawUnused === true && out._def.tag === "node") out._def.buildRawUnused = true;
|
|
15119
16206
|
break;
|
|
15120
16207
|
}
|
|
15121
16208
|
case "grammar": {
|