parseman 0.56.0 → 0.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/diagnostics.js +2232 -1088
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +2247 -1103
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/combinators/node.d.ts +1 -1
- package/dist/compiler/build-arity.d.ts +1 -1
- package/dist/compiler/build-arity.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts +11 -1
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +69 -16
- package/dist/compiler/token-capability.js.map +2 -2
- package/dist/cst/capture-buffer.d.ts +6 -0
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/cst/trivia-kinds.d.ts +9 -1
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/index.js +1446 -236
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +1 -0
- package/dist/language-service/index.js.map +1 -1
- package/dist/parse-context.d.ts.map +1 -1
- package/dist/plugin/entry-supercompiler.d.ts +1 -1
- package/dist/plugin/entry-supercompiler.d.ts.map +1 -1
- package/dist/plugin/index.d.ts +51 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +2126 -380
- package/dist/plugin/index.js.map +3 -3
- package/dist/plugin/ir-eval.d.ts +2 -0
- package/dist/plugin/ir-eval.d.ts.map +1 -1
- package/dist/regex/classes.d.ts.map +1 -1
- package/dist/run/index.js +1 -0
- package/dist/run/index.js.map +1 -1
- package/dist/table/assemble.d.ts +9 -0
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/child-slots.d.ts +4 -6
- package/dist/table/child-slots.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +14 -2
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +17 -2
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts +5 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec-baseline.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/factor-choice.d.ts +42 -0
- package/dist/table/factor-choice.d.ts.map +1 -0
- package/dist/table/fail-clean.d.ts +3 -0
- package/dist/table/fail-clean.d.ts.map +1 -0
- package/dist/table/hold-gap.d.ts +8 -0
- package/dist/table/hold-gap.d.ts.map +1 -0
- package/dist/table/index.js +1798 -316
- package/dist/table/index.js.map +3 -3
- package/dist/table/lex-program.d.ts +7 -3
- package/dist/table/lex-program.d.ts.map +1 -1
- package/dist/table/ops.d.ts +17 -6
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +13 -0
- package/dist/table/program.d.ts.map +1 -1
- package/dist/table/run-support.d.ts +19 -0
- package/dist/table/run-support.d.ts.map +1 -1
- package/dist/table/scalar-terminal.d.ts +2 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -1
- package/dist/table/select-hot.d.ts +6 -0
- package/dist/table/select-hot.d.ts.map +1 -0
- package/dist/table/site-labels.d.ts +66 -0
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/table/trivia-gap.d.ts +31 -0
- package/dist/table/trivia-gap.d.ts.map +1 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +4 -1
- package/src/combinators/dispatch.ts +12 -3
- package/src/combinators/node.ts +6 -13
- package/src/combinators/trivia-skip.ts +44 -1
- package/src/compiler/build-arity.ts +3 -3
- package/src/compiler/token-alphabet.ts +57 -17
- package/src/cst/capture-buffer.ts +25 -0
- package/src/cst/trivia-kinds.ts +12 -1
- package/src/parse-context.ts +1 -0
- package/src/plugin/entry-supercompiler.ts +8 -9
- package/src/plugin/index.ts +362 -42
- package/src/plugin/ir-eval.ts +7 -1
- package/src/regex/classes.ts +3 -0
- package/src/table/assemble.ts +371 -83
- package/src/table/child-slots.ts +6 -8
- package/src/table/compile-rule-map.ts +64 -15
- package/src/table/emit-assembly.ts +244 -42
- package/src/table/emit.ts +11 -8
- package/src/table/encode.ts +149 -35
- package/src/table/exec-baseline.ts +1 -3
- package/src/table/exec.ts +34 -14
- package/src/table/factor-choice.ts +173 -0
- package/src/table/fail-clean.ts +130 -0
- package/src/table/hold-gap.ts +68 -0
- package/src/table/lex-program.ts +197 -43
- package/src/table/ops.ts +18 -7
- package/src/table/program.ts +24 -0
- package/src/table/run-support.ts +35 -0
- package/src/table/scalar-terminal.ts +8 -0
- package/src/table/select-hot.ts +70 -0
- package/src/table/site-labels.ts +135 -4
- package/src/table/trivia-gap.ts +109 -0
- package/src/types.ts +18 -0
- package/src/version.ts +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -819,6 +819,31 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
819
819
|
else if (ctx._cstLeaves) ctx._cstLeaves.push(built);
|
|
820
820
|
if (ctx._cstRawChildren) ctx._cstRawChildren.push(rawEntry2);
|
|
821
821
|
}
|
|
822
|
+
function popCstChild(ctx) {
|
|
823
|
+
const b = ctx._cstBuf;
|
|
824
|
+
if (b) {
|
|
825
|
+
const ch2 = b.ch;
|
|
826
|
+
if (b.rawOnly !== true && ch2) {
|
|
827
|
+
ch2.pop();
|
|
828
|
+
if (ch2.length === 1) {
|
|
829
|
+
b.single = ch2[0];
|
|
830
|
+
b.ch = void 0;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
if (b.noRaw === true) b.rawLen = (b.rawLen ?? 1) - 1;
|
|
834
|
+
else if (b.raw) {
|
|
835
|
+
b.raw.pop();
|
|
836
|
+
if (b.raw.length === 1) {
|
|
837
|
+
b.rawSingle = b.raw[0];
|
|
838
|
+
b.raw = void 0;
|
|
839
|
+
}
|
|
840
|
+
} else b.rawSingle = void 0;
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
if (ctx._cstChildren) ctx._cstChildren.pop();
|
|
844
|
+
else if (ctx._cstLeaves) ctx._cstLeaves.pop();
|
|
845
|
+
if (ctx._cstRawChildren) ctx._cstRawChildren.pop();
|
|
846
|
+
}
|
|
822
847
|
function cstRawLen(ctx) {
|
|
823
848
|
const b = ctx._cstBuf;
|
|
824
849
|
if (b) {
|
|
@@ -977,6 +1002,7 @@ function literalCodePoints(frag) {
|
|
|
977
1002
|
if (ch2 === "\\") {
|
|
978
1003
|
const e = frag[i + 1];
|
|
979
1004
|
if (e === void 0) return null;
|
|
1005
|
+
if (!(e in CLASS_ESCAPES) && /\w/.test(e)) return null;
|
|
980
1006
|
out.push(e in CLASS_ESCAPES ? CLASS_ESCAPES[e] : e.codePointAt(0));
|
|
981
1007
|
i += 2;
|
|
982
1008
|
continue;
|
|
@@ -1089,6 +1115,7 @@ function createParseContext() {
|
|
|
1089
1115
|
_rootTriviaKindIndex: void 0,
|
|
1090
1116
|
_rootTriviaStrictScopes: void 0,
|
|
1091
1117
|
_rootTriviaCapture: void 0,
|
|
1118
|
+
_gap: void 0,
|
|
1092
1119
|
_cstTriviaLog: void 0,
|
|
1093
1120
|
_fields: void 0,
|
|
1094
1121
|
_cstBuf: void 0,
|
|
@@ -1571,7 +1598,10 @@ function labeledTriviaSpec(arms, minRepeats) {
|
|
|
1571
1598
|
arms,
|
|
1572
1599
|
minRepeats,
|
|
1573
1600
|
visitor: commonLabeledTriviaVisitor({ arms, minRepeats }),
|
|
1574
|
-
charArms: charArmsFor({ arms, minRepeats })
|
|
1601
|
+
charArms: charArmsFor({ arms, minRepeats }),
|
|
1602
|
+
rootKinds: void 0,
|
|
1603
|
+
rootLeaders: [],
|
|
1604
|
+
rootScan: null
|
|
1575
1605
|
};
|
|
1576
1606
|
}
|
|
1577
1607
|
function matchArmAt(input, pos, arm, state) {
|
|
@@ -2031,8 +2061,50 @@ function loopScanner(arms) {
|
|
|
2031
2061
|
function regexTriviaScanner(parser2) {
|
|
2032
2062
|
const d = parser2._def.tag === "label" ? parser2._def.parser._def : parser2._def;
|
|
2033
2063
|
if (d.tag !== "regex" || d.flags) return null;
|
|
2034
|
-
|
|
2035
|
-
|
|
2064
|
+
return sourceScanner(d.source);
|
|
2065
|
+
}
|
|
2066
|
+
function sourceScanner(source) {
|
|
2067
|
+
return classRunSource(source) ?? altStarSource(source) ?? prefixRunSource(source) ?? delimitedSource(source) ?? sharedPrefixAltSource(source);
|
|
2068
|
+
}
|
|
2069
|
+
function sharedPrefixAltSource(source) {
|
|
2070
|
+
const m = /^((?:\\.|[^\\[\]()*+?|^$.{}])+)\(\?:(.*)\)$/.exec(source);
|
|
2071
|
+
if (!m) return null;
|
|
2072
|
+
const alts = [];
|
|
2073
|
+
const body = m[2];
|
|
2074
|
+
let depth = 0;
|
|
2075
|
+
let start = 0;
|
|
2076
|
+
for (let i = 0; i < body.length; i++) {
|
|
2077
|
+
const c = body[i];
|
|
2078
|
+
if (c === "\\") {
|
|
2079
|
+
i++;
|
|
2080
|
+
continue;
|
|
2081
|
+
}
|
|
2082
|
+
if (c === "[") {
|
|
2083
|
+
while (i < body.length && body[i] !== "]") i += body[i] === "\\" ? 2 : 1;
|
|
2084
|
+
continue;
|
|
2085
|
+
}
|
|
2086
|
+
if (c === "(") depth++;
|
|
2087
|
+
else if (c === ")" && --depth < 0) return null;
|
|
2088
|
+
else if (c === "|" && depth === 0) {
|
|
2089
|
+
alts.push(body.slice(start, i));
|
|
2090
|
+
start = i + 1;
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
if (depth !== 0 || alts.length === 0) return null;
|
|
2094
|
+
alts.push(body.slice(start));
|
|
2095
|
+
const scanners = [];
|
|
2096
|
+
for (const alt of alts) {
|
|
2097
|
+
const scanner = sourceScanner(m[1] + alt);
|
|
2098
|
+
if (scanner === null) return null;
|
|
2099
|
+
scanners.push(scanner);
|
|
2100
|
+
}
|
|
2101
|
+
return (input, cur) => {
|
|
2102
|
+
for (const scanner of scanners) {
|
|
2103
|
+
const end = scanner(input, cur);
|
|
2104
|
+
if (end > cur) return end;
|
|
2105
|
+
}
|
|
2106
|
+
return cur;
|
|
2107
|
+
};
|
|
2036
2108
|
}
|
|
2037
2109
|
function bmpString(cps) {
|
|
2038
2110
|
if (!cps) return null;
|
|
@@ -2348,10 +2420,16 @@ function branchUsesRouted(branch) {
|
|
|
2348
2420
|
return branch.usesRouted === true || parserUsesRouted(branch.parser);
|
|
2349
2421
|
}
|
|
2350
2422
|
function asciiFoldKey(key) {
|
|
2351
|
-
let
|
|
2352
|
-
for (
|
|
2423
|
+
let i = 0;
|
|
2424
|
+
for (; i < key.length; i++) {
|
|
2425
|
+
const c = key.charCodeAt(i);
|
|
2426
|
+
if (c >= 65 && c <= 90) break;
|
|
2427
|
+
}
|
|
2428
|
+
if (i === key.length) return key;
|
|
2429
|
+
let out = key.slice(0, i);
|
|
2430
|
+
for (; i < key.length; i++) {
|
|
2353
2431
|
const c = key.charCodeAt(i);
|
|
2354
|
-
out +=
|
|
2432
|
+
out += c >= 65 && c <= 90 ? String.fromCharCode(c + 32) : key[i];
|
|
2355
2433
|
}
|
|
2356
2434
|
return out;
|
|
2357
2435
|
}
|
|
@@ -2680,6 +2758,42 @@ function keywords(words, opts = {}) {
|
|
|
2680
2758
|
};
|
|
2681
2759
|
}
|
|
2682
2760
|
|
|
2761
|
+
// src/combinators/trivia-boundary.ts
|
|
2762
|
+
var MAX_DEPTH = 12;
|
|
2763
|
+
function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
2764
|
+
if (depth === 0) return true;
|
|
2765
|
+
const d = p._def;
|
|
2766
|
+
switch (d.tag) {
|
|
2767
|
+
// Multi-term forms: the gaps BETWEEN terms are the ambient-trivia positions.
|
|
2768
|
+
case "sequence":
|
|
2769
|
+
return d.parsers.length > 1;
|
|
2770
|
+
case "many":
|
|
2771
|
+
case "oneOrMore":
|
|
2772
|
+
case "sepBy":
|
|
2773
|
+
return true;
|
|
2774
|
+
// Transparent wrappers — they add no position, so ask what they wrap.
|
|
2775
|
+
case "node":
|
|
2776
|
+
case "transform":
|
|
2777
|
+
case "leaf":
|
|
2778
|
+
case "label":
|
|
2779
|
+
case "field":
|
|
2780
|
+
case "token":
|
|
2781
|
+
case "attempt":
|
|
2782
|
+
case "optional":
|
|
2783
|
+
case "expect":
|
|
2784
|
+
case "withCtx":
|
|
2785
|
+
case "recover":
|
|
2786
|
+
case "trivia":
|
|
2787
|
+
return hasOwnTriviaBoundary(d.parser, depth - 1);
|
|
2788
|
+
// An alternation adds no position either, but ONE arm that has one is enough
|
|
2789
|
+
// to make the scope meaningful for this rule.
|
|
2790
|
+
case "choice":
|
|
2791
|
+
return d.parsers.some((a) => hasOwnTriviaBoundary(a, depth - 1));
|
|
2792
|
+
default:
|
|
2793
|
+
return false;
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2683
2797
|
// src/compiler/token-alphabet.ts
|
|
2684
2798
|
function optionalSuffixLexBody(ir) {
|
|
2685
2799
|
if (ir.kind !== "sequence" || ir.parts.length !== 2) return void 0;
|
|
@@ -2699,7 +2813,10 @@ function selectOptionalSuffixLexBody(ir) {
|
|
|
2699
2813
|
const token2 = { strategy: "token", estimatedOps: 2, body };
|
|
2700
2814
|
return token2.estimatedOps < character.estimatedOps ? token2 : character;
|
|
2701
2815
|
}
|
|
2702
|
-
function
|
|
2816
|
+
function reinstallsRuleTrivia(reference, target) {
|
|
2817
|
+
return (reference._meta.grammarTrivia ?? target._meta.grammarTrivia) !== void 0 && hasOwnTriviaBoundary(target);
|
|
2818
|
+
}
|
|
2819
|
+
function directTokenBodyParser(parser2, resolve2, scope) {
|
|
2703
2820
|
const outer = parser2._def;
|
|
2704
2821
|
if (outer.tag !== "token") return void 0;
|
|
2705
2822
|
let body = outer.parser;
|
|
@@ -2709,12 +2826,13 @@ function directTokenBodyParser(parser2, resolve2) {
|
|
|
2709
2826
|
const wrapper = body._def;
|
|
2710
2827
|
if (wrapper.tag === "grammar") {
|
|
2711
2828
|
if (wrapper.clearTrivia !== true || wrapper.triviaParser !== void 0 || wrapper.captureTrivia === true || wrapper.rootCapture === "opaque" || wrapper.constructionTrackLines !== "inherit" || wrapper.constructionCaptureTriviaKinds !== void 0) return void 0;
|
|
2829
|
+
if (scope !== void 0) scope.cleared = true;
|
|
2712
2830
|
body = wrapper.parser;
|
|
2713
2831
|
continue;
|
|
2714
2832
|
}
|
|
2715
2833
|
if (wrapper.tag === "lazy") {
|
|
2716
2834
|
const target = resolvedLazyTarget(body, resolve2);
|
|
2717
|
-
if (target === void 0) return void 0;
|
|
2835
|
+
if (target === void 0 || reinstallsRuleTrivia(body, target)) return void 0;
|
|
2718
2836
|
body = target;
|
|
2719
2837
|
continue;
|
|
2720
2838
|
}
|
|
@@ -2886,7 +3004,7 @@ function directNot2TokenBody(parser2, resolve2) {
|
|
|
2886
3004
|
terminal
|
|
2887
3005
|
};
|
|
2888
3006
|
}
|
|
2889
|
-
function directFixedLexNode(parser2, resolve2, active, pureOnly = false) {
|
|
3007
|
+
function directFixedLexNode(parser2, resolve2, active, pureOnly = false, cleared = false) {
|
|
2890
3008
|
let current = parser2;
|
|
2891
3009
|
const wrappers = /* @__PURE__ */ new Set();
|
|
2892
3010
|
while (!wrappers.has(current)) {
|
|
@@ -2894,7 +3012,7 @@ function directFixedLexNode(parser2, resolve2, active, pureOnly = false) {
|
|
|
2894
3012
|
const def = current._def;
|
|
2895
3013
|
if (def.tag === "lazy") {
|
|
2896
3014
|
const target = resolvedLazyTarget(current, resolve2);
|
|
2897
|
-
if (target === void 0) return void 0;
|
|
3015
|
+
if (target === void 0 || reinstallsRuleTrivia(current, target)) return void 0;
|
|
2898
3016
|
current = target;
|
|
2899
3017
|
continue;
|
|
2900
3018
|
}
|
|
@@ -2912,30 +3030,33 @@ function directFixedLexNode(parser2, resolve2, active, pureOnly = false) {
|
|
|
2912
3030
|
if (terminal !== void 0) return { kind: "terminal", terminal };
|
|
2913
3031
|
const def = current._def;
|
|
2914
3032
|
if (def.tag === "grammar") {
|
|
3033
|
+
if (def.triviaParser === void 0 && def.captureTrivia !== true && def.rootCapture !== "opaque" && def.constructionCaptureTriviaKinds === void 0) {
|
|
3034
|
+
return directFixedLexNode(def.parser, resolve2, active, pureOnly, cleared || def.clearTrivia === true);
|
|
3035
|
+
}
|
|
2915
3036
|
if (!pureOnly || def.parser._def.tag !== "token" && (def.clearTrivia !== true || def.triviaParser !== void 0 || def.captureTrivia === true || def.rootCapture === "opaque")) return void 0;
|
|
2916
|
-
return directFixedLexNode(def.parser, resolve2, active, true);
|
|
3037
|
+
return directFixedLexNode(def.parser, resolve2, active, true, cleared);
|
|
2917
3038
|
}
|
|
2918
3039
|
if (def.tag === "sequence") {
|
|
2919
3040
|
if (def.parsers.length < 2 || def.parsers.length > 5) return void 0;
|
|
2920
|
-
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve2, active, pureOnly));
|
|
3041
|
+
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve2, active, pureOnly, cleared));
|
|
2921
3042
|
if (parts.some((part) => part === void 0)) return void 0;
|
|
2922
3043
|
return { kind: "sequence", parts };
|
|
2923
3044
|
}
|
|
2924
3045
|
if (def.tag === "choice") {
|
|
2925
|
-
if (def.parsers.length
|
|
2926
|
-
const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve2, active, pureOnly));
|
|
3046
|
+
if (def.parsers.length < 2 || def.strategy.tag !== "firstMatch" || def.gates.some((gate) => gate !== null) || def.autoNot.some((check) => check !== null)) return void 0;
|
|
3047
|
+
const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve2, active, pureOnly, cleared));
|
|
2927
3048
|
if (arms.some((arm) => arm === void 0)) return void 0;
|
|
2928
|
-
const final = classifyFinalChoice(def.parsers, resolve2);
|
|
2929
3049
|
return {
|
|
2930
3050
|
kind: "choice",
|
|
2931
3051
|
arms,
|
|
2932
|
-
|
|
3052
|
+
parsers: def.parsers,
|
|
3053
|
+
cleared,
|
|
2933
3054
|
armExpected: def.parsers.map(deriveExpected),
|
|
2934
3055
|
expected: def.parsers.flatMap(deriveExpected)
|
|
2935
3056
|
};
|
|
2936
3057
|
}
|
|
2937
3058
|
if (def.tag === "not") {
|
|
2938
|
-
const body = directFixedLexNode(def.parser, resolve2, active, true);
|
|
3059
|
+
const body = directFixedLexNode(def.parser, resolve2, active, true, cleared);
|
|
2939
3060
|
return body === void 0 ? void 0 : {
|
|
2940
3061
|
kind: "not",
|
|
2941
3062
|
body,
|
|
@@ -2943,18 +3064,28 @@ function directFixedLexNode(parser2, resolve2, active, pureOnly = false) {
|
|
|
2943
3064
|
};
|
|
2944
3065
|
}
|
|
2945
3066
|
if (def.tag === "optional") {
|
|
2946
|
-
const body = directFixedLexNode(def.parser, resolve2, active, pureOnly);
|
|
3067
|
+
const body = directFixedLexNode(def.parser, resolve2, active, pureOnly, cleared);
|
|
2947
3068
|
return body === void 0 ? void 0 : { kind: "optional", body };
|
|
2948
3069
|
}
|
|
3070
|
+
if (def.tag === "many" || def.tag === "oneOrMore") {
|
|
3071
|
+
const body = directFixedLexNode(def.parser, resolve2, active, pureOnly, cleared);
|
|
3072
|
+
return body === void 0 ? void 0 : {
|
|
3073
|
+
kind: "repeat",
|
|
3074
|
+
body,
|
|
3075
|
+
min: def.tag === "many" ? 0 : def.min,
|
|
3076
|
+
max: def.max ?? -1
|
|
3077
|
+
};
|
|
3078
|
+
}
|
|
2949
3079
|
return void 0;
|
|
2950
3080
|
} finally {
|
|
2951
3081
|
active.delete(current);
|
|
2952
3082
|
}
|
|
2953
3083
|
}
|
|
2954
3084
|
function directFixedTokenBody(parser2, resolve2) {
|
|
2955
|
-
const
|
|
3085
|
+
const scope = { cleared: false };
|
|
3086
|
+
const body = directTokenBodyParser(parser2, resolve2, scope);
|
|
2956
3087
|
if (body === void 0) return void 0;
|
|
2957
|
-
const root = directFixedLexNode(body, resolve2, /* @__PURE__ */ new Set());
|
|
3088
|
+
const root = directFixedLexNode(body, resolve2, /* @__PURE__ */ new Set(), false, scope.cleared);
|
|
2958
3089
|
return root === void 0 ? void 0 : { kind: "fixed-tree", root };
|
|
2959
3090
|
}
|
|
2960
3091
|
function directBalancedTokenBody(parser2, resolve2) {
|
|
@@ -4863,17 +4994,59 @@ function buildLexBodyRecognizer(spec, constants) {
|
|
|
4863
4994
|
};
|
|
4864
4995
|
}
|
|
4865
4996
|
|
|
4997
|
+
// src/table/run-support.ts
|
|
4998
|
+
function lineCol(ctx, offset) {
|
|
4999
|
+
const starts = ctx._lineStarts ?? [0];
|
|
5000
|
+
let lo = 0, hi = starts.length - 1;
|
|
5001
|
+
while (lo < hi) {
|
|
5002
|
+
const mid = lo + hi + 1 >> 1;
|
|
5003
|
+
if (starts[mid] <= offset) lo = mid;
|
|
5004
|
+
else hi = mid - 1;
|
|
5005
|
+
}
|
|
5006
|
+
return [lo + 1, offset - starts[lo] + 1];
|
|
5007
|
+
}
|
|
5008
|
+
function spanLines(ctx, start, end) {
|
|
5009
|
+
const s = lineCol(ctx, start), e = lineCol(ctx, end);
|
|
5010
|
+
return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] };
|
|
5011
|
+
}
|
|
5012
|
+
function rawEntry(v, input, s, e) {
|
|
5013
|
+
if (typeof v === "object" && v !== null) {
|
|
5014
|
+
const tg = v._tag;
|
|
5015
|
+
if (tg === "node" || tg === "leaf" || tg === "parseError") return v;
|
|
5016
|
+
}
|
|
5017
|
+
return {
|
|
5018
|
+
_tag: "leaf",
|
|
5019
|
+
value: typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "",
|
|
5020
|
+
span: { start: s, end: e }
|
|
5021
|
+
};
|
|
5022
|
+
}
|
|
5023
|
+
function lead(input, pos) {
|
|
5024
|
+
if (pos >= input.length) return -1;
|
|
5025
|
+
const c = input.charCodeAt(pos);
|
|
5026
|
+
if (c < 55296 || c > 56319) return c;
|
|
5027
|
+
return input.codePointAt(pos) ?? c;
|
|
5028
|
+
}
|
|
5029
|
+
var EMPTY_KIDS = Object.freeze([]);
|
|
5030
|
+
var EMPTY_TRIVIA = Object.freeze([]);
|
|
5031
|
+
function collapseEmpty(ctx, build, input, pos, end, readsRaw) {
|
|
5032
|
+
const collected = ctx._cstBuf !== void 0 || ctx._cstChildren !== void 0;
|
|
5033
|
+
if (collected) popCstChild(ctx);
|
|
5034
|
+
const raw = readsRaw ? [rawEntry(void 0, input, pos, end)] : EMPTY_KIDS;
|
|
5035
|
+
const nd = build(EMPTY_KIDS, void 0, { start: pos, end }, raw, EMPTY_TRIVIA, void 0);
|
|
5036
|
+
if (collected) pushCstChild(ctx, nd, ctx._cstBuf?.noRaw === true ? void 0 : rawEntry(nd, input, pos, end));
|
|
5037
|
+
return nd;
|
|
5038
|
+
}
|
|
5039
|
+
|
|
4866
5040
|
// src/table/lex-program.ts
|
|
4867
5041
|
var LEX_NODE_TERMINAL = 0;
|
|
4868
5042
|
var LEX_NODE_SEQUENCE2 = 1;
|
|
4869
5043
|
var LEX_NODE_SEQUENCE3 = 2;
|
|
4870
5044
|
var LEX_NODE_SEQUENCE4 = 3;
|
|
4871
5045
|
var LEX_NODE_SEQUENCE5 = 4;
|
|
4872
|
-
var
|
|
4873
|
-
var LEX_NODE_CHOICE4 = 6;
|
|
4874
|
-
var LEX_NODE_CHOICE8 = 7;
|
|
5046
|
+
var LEX_NODE_CHOICE = 5;
|
|
4875
5047
|
var LEX_NODE_NOT = 8;
|
|
4876
5048
|
var LEX_NODE_OPTIONAL = 9;
|
|
5049
|
+
var LEX_NODE_REPEAT = 10;
|
|
4877
5050
|
function lexProgramDigest(words) {
|
|
4878
5051
|
let hash = 2166136261;
|
|
4879
5052
|
for (const word of words) {
|
|
@@ -4902,85 +5075,114 @@ function trackLexLines(ctx, input, end) {
|
|
|
4902
5075
|
ctx._lineScannedTo = end;
|
|
4903
5076
|
}
|
|
4904
5077
|
function terminalNode(matcher, failure, tracksLines) {
|
|
4905
|
-
const match = (input, pos) => {
|
|
4906
|
-
const result = matcher(input, pos);
|
|
4907
|
-
return result < 0 ? -1 : result / 2;
|
|
4908
|
-
};
|
|
4909
5078
|
return {
|
|
4910
|
-
match,
|
|
5079
|
+
match: (input, pos) => {
|
|
5080
|
+
const result = matcher(input, pos);
|
|
5081
|
+
return result < 0 ? -1 : result / 2;
|
|
5082
|
+
},
|
|
4911
5083
|
run: (input, pos, ctx) => {
|
|
4912
|
-
const
|
|
4913
|
-
if (
|
|
5084
|
+
const result = matcher(input, pos);
|
|
5085
|
+
if (result < 0) {
|
|
4914
5086
|
ctx._fe = pos;
|
|
4915
5087
|
ctx._fx = failure;
|
|
4916
5088
|
if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
|
|
4917
5089
|
return -1;
|
|
4918
5090
|
}
|
|
5091
|
+
const end = result / 2;
|
|
4919
5092
|
if (tracksLines) trackLexLines(ctx, input, end);
|
|
4920
5093
|
return end;
|
|
4921
5094
|
}
|
|
4922
5095
|
};
|
|
4923
5096
|
}
|
|
4924
5097
|
function sequence2(a, b) {
|
|
5098
|
+
const am = a.match, bm = b.match, ar = a.run, br = b.run;
|
|
4925
5099
|
return {
|
|
4926
5100
|
match: (input, pos) => {
|
|
4927
|
-
const e0 =
|
|
4928
|
-
return e0 < 0 ? -1 :
|
|
5101
|
+
const e0 = am(input, pos);
|
|
5102
|
+
return e0 < 0 ? -1 : bm(input, e0);
|
|
4929
5103
|
},
|
|
4930
5104
|
run: (input, pos, ctx) => {
|
|
4931
|
-
const e0 =
|
|
5105
|
+
const e0 = ar(input, pos, ctx);
|
|
4932
5106
|
if (e0 < 0) return -1;
|
|
4933
5107
|
ctx._fc = false;
|
|
4934
|
-
return
|
|
5108
|
+
return br(input, e0, ctx);
|
|
4935
5109
|
}
|
|
4936
5110
|
};
|
|
4937
5111
|
}
|
|
4938
5112
|
function sequence3(a, b, c) {
|
|
5113
|
+
const am = a.match, bm = b.match, cm = c.match, ar = a.run, br = b.run, cr = c.run;
|
|
4939
5114
|
return {
|
|
4940
5115
|
match: (input, pos) => {
|
|
4941
|
-
const e0 =
|
|
5116
|
+
const e0 = am(input, pos);
|
|
4942
5117
|
if (e0 < 0) return -1;
|
|
4943
|
-
const e1 =
|
|
4944
|
-
return e1 < 0 ? -1 :
|
|
5118
|
+
const e1 = bm(input, e0);
|
|
5119
|
+
return e1 < 0 ? -1 : cm(input, e1);
|
|
4945
5120
|
},
|
|
4946
5121
|
run: (input, pos, ctx) => {
|
|
4947
|
-
const e0 =
|
|
5122
|
+
const e0 = ar(input, pos, ctx);
|
|
4948
5123
|
if (e0 < 0) return -1;
|
|
4949
5124
|
ctx._fc = false;
|
|
4950
|
-
const e1 =
|
|
5125
|
+
const e1 = br(input, e0, ctx);
|
|
4951
5126
|
if (e1 < 0) return -1;
|
|
4952
5127
|
ctx._fc = false;
|
|
4953
|
-
return
|
|
5128
|
+
return cr(input, e1, ctx);
|
|
4954
5129
|
}
|
|
4955
5130
|
};
|
|
4956
5131
|
}
|
|
4957
5132
|
function sequence4(a, b, c, d) {
|
|
4958
|
-
const
|
|
5133
|
+
const am = a.match, bm = b.match, cm = c.match, dm = d.match;
|
|
5134
|
+
const ar = a.run, br = b.run, cr = c.run, dr = d.run;
|
|
4959
5135
|
return {
|
|
4960
5136
|
match: (input, pos) => {
|
|
4961
|
-
const
|
|
4962
|
-
|
|
5137
|
+
const e0 = am(input, pos);
|
|
5138
|
+
if (e0 < 0) return -1;
|
|
5139
|
+
const e1 = bm(input, e0);
|
|
5140
|
+
if (e1 < 0) return -1;
|
|
5141
|
+
const e2 = cm(input, e1);
|
|
5142
|
+
return e2 < 0 ? -1 : dm(input, e2);
|
|
4963
5143
|
},
|
|
4964
5144
|
run: (input, pos, ctx) => {
|
|
4965
|
-
const
|
|
4966
|
-
if (
|
|
5145
|
+
const e0 = ar(input, pos, ctx);
|
|
5146
|
+
if (e0 < 0) return -1;
|
|
5147
|
+
ctx._fc = false;
|
|
5148
|
+
const e1 = br(input, e0, ctx);
|
|
5149
|
+
if (e1 < 0) return -1;
|
|
4967
5150
|
ctx._fc = false;
|
|
4968
|
-
|
|
5151
|
+
const e2 = cr(input, e1, ctx);
|
|
5152
|
+
if (e2 < 0) return -1;
|
|
5153
|
+
ctx._fc = false;
|
|
5154
|
+
return dr(input, e2, ctx);
|
|
4969
5155
|
}
|
|
4970
5156
|
};
|
|
4971
5157
|
}
|
|
4972
5158
|
function sequence5(a, b, c, d, e) {
|
|
4973
|
-
const
|
|
5159
|
+
const am = a.match, bm = b.match, cm = c.match, dm = d.match, em = e.match;
|
|
5160
|
+
const ar = a.run, br = b.run, cr = c.run, dr = d.run, er = e.run;
|
|
4974
5161
|
return {
|
|
4975
5162
|
match: (input, pos) => {
|
|
4976
|
-
const
|
|
4977
|
-
|
|
5163
|
+
const e0 = am(input, pos);
|
|
5164
|
+
if (e0 < 0) return -1;
|
|
5165
|
+
const e1 = bm(input, e0);
|
|
5166
|
+
if (e1 < 0) return -1;
|
|
5167
|
+
const e2 = cm(input, e1);
|
|
5168
|
+
if (e2 < 0) return -1;
|
|
5169
|
+
const e3 = dm(input, e2);
|
|
5170
|
+
return e3 < 0 ? -1 : em(input, e3);
|
|
4978
5171
|
},
|
|
4979
5172
|
run: (input, pos, ctx) => {
|
|
4980
|
-
const
|
|
4981
|
-
if (
|
|
5173
|
+
const e0 = ar(input, pos, ctx);
|
|
5174
|
+
if (e0 < 0) return -1;
|
|
5175
|
+
ctx._fc = false;
|
|
5176
|
+
const e1 = br(input, e0, ctx);
|
|
5177
|
+
if (e1 < 0) return -1;
|
|
5178
|
+
ctx._fc = false;
|
|
5179
|
+
const e2 = cr(input, e1, ctx);
|
|
5180
|
+
if (e2 < 0) return -1;
|
|
5181
|
+
ctx._fc = false;
|
|
5182
|
+
const e3 = dr(input, e2, ctx);
|
|
5183
|
+
if (e3 < 0) return -1;
|
|
4982
5184
|
ctx._fc = false;
|
|
4983
|
-
return
|
|
5185
|
+
return er(input, e3, ctx);
|
|
4984
5186
|
}
|
|
4985
5187
|
};
|
|
4986
5188
|
}
|
|
@@ -4993,9 +5195,9 @@ function appendExpected(acc, values) {
|
|
|
4993
5195
|
function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
4994
5196
|
let matchTail = () => -1;
|
|
4995
5197
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
4996
|
-
const
|
|
5198
|
+
const armMatch = arms[i].match, next = matchTail;
|
|
4997
5199
|
matchTail = (input, pos) => {
|
|
4998
|
-
const end =
|
|
5200
|
+
const end = armMatch(input, pos);
|
|
4999
5201
|
return end < 0 ? next(input, pos) : end;
|
|
5000
5202
|
};
|
|
5001
5203
|
}
|
|
@@ -5005,7 +5207,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5005
5207
|
return -1;
|
|
5006
5208
|
};
|
|
5007
5209
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5008
|
-
const
|
|
5210
|
+
const armRun = arms[i].run, cls = classes[i], staticExpected = armExpected[i], next = tail;
|
|
5009
5211
|
tail = (input, pos, ctx, lead2, acc, best) => {
|
|
5010
5212
|
if (cls !== void 0 && !classHas(cls, lead2)) {
|
|
5011
5213
|
return next(
|
|
@@ -5018,7 +5220,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5018
5220
|
);
|
|
5019
5221
|
}
|
|
5020
5222
|
ctx._fc = false;
|
|
5021
|
-
const end =
|
|
5223
|
+
const end = armRun(input, pos, ctx);
|
|
5022
5224
|
if (end >= 0) return end;
|
|
5023
5225
|
const at = ctx._fe ?? pos;
|
|
5024
5226
|
if (at > best) {
|
|
@@ -5045,11 +5247,58 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5045
5247
|
)
|
|
5046
5248
|
};
|
|
5047
5249
|
}
|
|
5250
|
+
function exclusiveChoiceNode(arms, classes, choiceFx) {
|
|
5251
|
+
const ascii = (classes.length <= 128 ? new Int8Array(128) : new Int32Array(128)).fill(-1);
|
|
5252
|
+
const hi = [];
|
|
5253
|
+
for (let i = 0; i < classes.length; i++) {
|
|
5254
|
+
const cls = classes[i];
|
|
5255
|
+
for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) ascii[c] = i;
|
|
5256
|
+
for (let r = 0; r < cls.hi.length; r += 2) hi.push(cls.hi[r], cls.hi[r + 1], i);
|
|
5257
|
+
}
|
|
5258
|
+
const select = (code) => {
|
|
5259
|
+
if (code < 0) return -1;
|
|
5260
|
+
if (code < 128) return ascii[code];
|
|
5261
|
+
for (let r = 0; r < hi.length; r += 3) if (code >= hi[r] && code <= hi[r + 1]) return hi[r + 2];
|
|
5262
|
+
return -1;
|
|
5263
|
+
};
|
|
5264
|
+
let matchArm = () => -1;
|
|
5265
|
+
let selectRun = () => -1;
|
|
5266
|
+
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5267
|
+
const armMatch = arms[i].match, armRun = arms[i].run, nextMatch = matchArm, nextRun = selectRun;
|
|
5268
|
+
matchArm = (selected, input, pos) => selected === i ? armMatch(input, pos) : nextMatch(selected, input, pos);
|
|
5269
|
+
selectRun = (selected, input, pos, ctx) => selected === i ? armRun(input, pos, ctx) : nextRun(selected, input, pos, ctx);
|
|
5270
|
+
}
|
|
5271
|
+
const runArm = (input, pos, ctx) => {
|
|
5272
|
+
const arm = select(lead(input, pos));
|
|
5273
|
+
if (arm >= 0) {
|
|
5274
|
+
ctx._fc = false;
|
|
5275
|
+
const end = selectRun(arm, input, pos, ctx);
|
|
5276
|
+
if (end >= 0) return end;
|
|
5277
|
+
if (committed(ctx)) return -1;
|
|
5278
|
+
const failed = ctx._fx;
|
|
5279
|
+
if (failed !== void 0 && failed.length > 0) {
|
|
5280
|
+
ctx._fe = pos;
|
|
5281
|
+
return -1;
|
|
5282
|
+
}
|
|
5283
|
+
}
|
|
5284
|
+
ctx._fe = pos;
|
|
5285
|
+
ctx._fx = choiceFx;
|
|
5286
|
+
return -1;
|
|
5287
|
+
};
|
|
5288
|
+
return {
|
|
5289
|
+
match: (input, pos) => {
|
|
5290
|
+
const arm = select(lead(input, pos));
|
|
5291
|
+
return arm < 0 ? -1 : matchArm(arm, input, pos);
|
|
5292
|
+
},
|
|
5293
|
+
run: runArm
|
|
5294
|
+
};
|
|
5295
|
+
}
|
|
5048
5296
|
function notNode(body, failure) {
|
|
5297
|
+
const bodyMatch = body.match;
|
|
5049
5298
|
return {
|
|
5050
|
-
match: (input, pos) =>
|
|
5299
|
+
match: (input, pos) => bodyMatch(input, pos) < 0 ? pos : -1,
|
|
5051
5300
|
run: (input, pos, ctx) => {
|
|
5052
|
-
if (
|
|
5301
|
+
if (bodyMatch(input, pos) < 0) return pos;
|
|
5053
5302
|
ctx._fe = pos;
|
|
5054
5303
|
ctx._fx = failure;
|
|
5055
5304
|
return -1;
|
|
@@ -5057,18 +5306,57 @@ function notNode(body, failure) {
|
|
|
5057
5306
|
};
|
|
5058
5307
|
}
|
|
5059
5308
|
function optionalNode(body) {
|
|
5309
|
+
const bodyMatch = body.match, bodyRun = body.run;
|
|
5060
5310
|
return {
|
|
5061
5311
|
match: (input, pos) => {
|
|
5062
|
-
const end =
|
|
5312
|
+
const end = bodyMatch(input, pos);
|
|
5063
5313
|
return end < 0 ? pos : end;
|
|
5064
5314
|
},
|
|
5065
5315
|
run: (input, pos, ctx) => {
|
|
5066
5316
|
ctx._fc = false;
|
|
5067
|
-
const end =
|
|
5317
|
+
const end = bodyRun(input, pos, ctx);
|
|
5068
5318
|
return end < 0 && !committed(ctx) ? pos : end;
|
|
5069
5319
|
}
|
|
5070
5320
|
};
|
|
5071
5321
|
}
|
|
5322
|
+
function repeatNode(item, min, max) {
|
|
5323
|
+
const itemMatch = item.match, itemRun = item.run;
|
|
5324
|
+
return {
|
|
5325
|
+
match: (input, pos) => {
|
|
5326
|
+
let cur = pos;
|
|
5327
|
+
let count = 0;
|
|
5328
|
+
for (; ; ) {
|
|
5329
|
+
if (max >= 0 && count >= max) break;
|
|
5330
|
+
const optional2 = count >= min && (count > 0 || min === 0);
|
|
5331
|
+
if (optional2 && cur >= input.length) break;
|
|
5332
|
+
const end = itemMatch(input, cur);
|
|
5333
|
+
if (end < 0 || optional2 && end === cur) break;
|
|
5334
|
+
cur = end;
|
|
5335
|
+
count++;
|
|
5336
|
+
}
|
|
5337
|
+
return count < min ? -1 : cur;
|
|
5338
|
+
},
|
|
5339
|
+
run: (input, pos, ctx) => {
|
|
5340
|
+
let cur = pos;
|
|
5341
|
+
let count = 0;
|
|
5342
|
+
for (; ; ) {
|
|
5343
|
+
if (max >= 0 && count >= max) break;
|
|
5344
|
+
const optional2 = count >= min && (count > 0 || min === 0);
|
|
5345
|
+
if (optional2 && cur >= input.length) break;
|
|
5346
|
+
ctx._fc = false;
|
|
5347
|
+
const end = itemRun(input, cur, ctx);
|
|
5348
|
+
if (end < 0) {
|
|
5349
|
+
if (committed(ctx)) return -1;
|
|
5350
|
+
break;
|
|
5351
|
+
}
|
|
5352
|
+
if (optional2 && end === cur) break;
|
|
5353
|
+
cur = end;
|
|
5354
|
+
count++;
|
|
5355
|
+
}
|
|
5356
|
+
return count < min ? -1 : cur;
|
|
5357
|
+
}
|
|
5358
|
+
};
|
|
5359
|
+
}
|
|
5072
5360
|
function fixedTreeRunner(words, matchers, classes, expected) {
|
|
5073
5361
|
const stack = [];
|
|
5074
5362
|
const pop = () => {
|
|
@@ -5096,9 +5384,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5096
5384
|
else stack.push(sequence5(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4]));
|
|
5097
5385
|
continue;
|
|
5098
5386
|
}
|
|
5099
|
-
if (op
|
|
5100
|
-
const count =
|
|
5387
|
+
if (op === LEX_NODE_CHOICE) {
|
|
5388
|
+
const count = words[at++];
|
|
5389
|
+
const exclusive = words[at++];
|
|
5390
|
+
if (exclusive !== 0 && exclusive !== 1) throw new TypeError("table lexical tree choice has an invalid dispatch mode");
|
|
5101
5391
|
const choiceFx = expected[words[at++]];
|
|
5392
|
+
if (!Number.isInteger(count) || count < 2 || count > stack.length) {
|
|
5393
|
+
throw new TypeError("table lexical tree choice has an invalid arm count");
|
|
5394
|
+
}
|
|
5102
5395
|
if (choiceFx === void 0) throw new TypeError("table lexical tree choice has an invalid expected set");
|
|
5103
5396
|
const armClasses = [];
|
|
5104
5397
|
const armFx = [];
|
|
@@ -5111,7 +5404,7 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5111
5404
|
armFx.push(fx);
|
|
5112
5405
|
}
|
|
5113
5406
|
const arms = Array.from({ length: count }, pop).reverse();
|
|
5114
|
-
stack.push(choiceNode(arms, armClasses, armFx, choiceFx));
|
|
5407
|
+
stack.push(exclusive === 1 ? exclusiveChoiceNode(arms, armClasses, choiceFx) : choiceNode(arms, armClasses, armFx, choiceFx));
|
|
5115
5408
|
continue;
|
|
5116
5409
|
}
|
|
5117
5410
|
if (op === LEX_NODE_NOT) {
|
|
@@ -5124,6 +5417,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5124
5417
|
stack.push(optionalNode(pop()));
|
|
5125
5418
|
continue;
|
|
5126
5419
|
}
|
|
5420
|
+
if (op === LEX_NODE_REPEAT) {
|
|
5421
|
+
const min = words[at++], max = words[at++];
|
|
5422
|
+
if (!Number.isInteger(min) || min < 0 || !Number.isInteger(max) || max >= 0 && max < min) {
|
|
5423
|
+
throw new TypeError("table lexical tree repeat has invalid bounds");
|
|
5424
|
+
}
|
|
5425
|
+
stack.push(repeatNode(pop(), min, max));
|
|
5426
|
+
continue;
|
|
5427
|
+
}
|
|
5127
5428
|
throw new TypeError("table lexical tree has an unknown fixed body");
|
|
5128
5429
|
}
|
|
5129
5430
|
if (stack.length !== 1) throw new TypeError("table lexical tree does not resolve to one root body");
|
|
@@ -5278,6 +5579,12 @@ function scanRefs(s) {
|
|
|
5278
5579
|
refs.push(...s.skip);
|
|
5279
5580
|
return refs;
|
|
5280
5581
|
}
|
|
5582
|
+
function assemblyExtraIps(prog) {
|
|
5583
|
+
const ips = [];
|
|
5584
|
+
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) ips.push(r[0]);
|
|
5585
|
+
for (const set of prog.scanSkip ?? []) for (const r of set) ips.push(r[0]);
|
|
5586
|
+
return ips;
|
|
5587
|
+
}
|
|
5281
5588
|
function expandCompact(p) {
|
|
5282
5589
|
if ("code" in p) return p;
|
|
5283
5590
|
return ownTableProgram({
|
|
@@ -5408,6 +5715,11 @@ function classHas2(cls, code) {
|
|
|
5408
5715
|
for (let i = 0; i < hi.length; i += 2) if (code >= hi[i] && code <= hi[i + 1]) return true;
|
|
5409
5716
|
return false;
|
|
5410
5717
|
}
|
|
5718
|
+
function dispatchIsExclusive(arms, cc) {
|
|
5719
|
+
const resolved = [];
|
|
5720
|
+
for (const ci of arms) if (ci >= 0) resolved[ci] = resolveClass(cc[ci]);
|
|
5721
|
+
return resolveDispatch(arms, resolved).exclusive;
|
|
5722
|
+
}
|
|
5411
5723
|
function resolveDispatch(arms, cc) {
|
|
5412
5724
|
const ascii = new Uint8Array(128);
|
|
5413
5725
|
const hi = [];
|
|
@@ -5481,66 +5793,261 @@ function resolveTable(prog) {
|
|
|
5481
5793
|
return built;
|
|
5482
5794
|
}
|
|
5483
5795
|
|
|
5484
|
-
// src/
|
|
5485
|
-
function
|
|
5486
|
-
return
|
|
5487
|
-
}
|
|
5488
|
-
var DETAIL_CAP = 8;
|
|
5489
|
-
function formatDegradations(list) {
|
|
5490
|
-
const byCode = /* @__PURE__ */ new Map();
|
|
5491
|
-
for (const d of list) {
|
|
5492
|
-
const bucket = byCode.get(d.code);
|
|
5493
|
-
if (bucket) bucket.push(d);
|
|
5494
|
-
else byCode.set(d.code, [d]);
|
|
5495
|
-
}
|
|
5496
|
-
const out = [];
|
|
5497
|
-
for (const [code, items] of byCode) {
|
|
5498
|
-
for (const d of items.slice(0, DETAIL_CAP)) out.push(formatDegradation(d));
|
|
5499
|
-
if (items.length > DETAIL_CAP) {
|
|
5500
|
-
out.push(
|
|
5501
|
-
`[parseman] degraded [${code}] +${items.length - DETAIL_CAP} more site(s) not listed (${items.length} total). Set PARSEMAN_DEGRADATION=error to fail the build on these.`
|
|
5502
|
-
);
|
|
5503
|
-
}
|
|
5504
|
-
}
|
|
5505
|
-
return out;
|
|
5796
|
+
// src/combinators/adjacency.ts
|
|
5797
|
+
function adjacencyOf(p) {
|
|
5798
|
+
return p._def.tag === "adjacency" ? p._def : null;
|
|
5506
5799
|
}
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5800
|
+
function adjacencyExpected(def) {
|
|
5801
|
+
if (def.polarity === "adjacent") return "adjacent";
|
|
5802
|
+
return def.kinds === void 0 ? "notAdjacent" : `notAdjacent(${def.kinds.join("|")})`;
|
|
5510
5803
|
}
|
|
5511
|
-
function
|
|
5512
|
-
return
|
|
5804
|
+
function holdsAdjacency(input, cur, ctx, def) {
|
|
5805
|
+
return adjacencyHolds(input, cur, ctx, def.polarity === "notAdjacent", def.kinds);
|
|
5513
5806
|
}
|
|
5514
|
-
function
|
|
5515
|
-
const
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5807
|
+
function adjacencyHolds(input, cur, ctx, negated, kinds) {
|
|
5808
|
+
const end = probeTriviaEnd(input, cur, ctx);
|
|
5809
|
+
if (!negated) return end === cur;
|
|
5810
|
+
if (end === cur) return false;
|
|
5811
|
+
if (kinds === void 0) return true;
|
|
5812
|
+
const want = resolveAdjacencyKindMask(ctx.trivia, kinds);
|
|
5813
|
+
const spec = analyzeLabeledTrivia(ctx.trivia);
|
|
5814
|
+
return (triviaKindMaskAt(input, cur, spec, ctx.state) & want) !== 0;
|
|
5521
5815
|
}
|
|
5522
|
-
function
|
|
5523
|
-
|
|
5524
|
-
const env = typeof process !== "undefined" ? process.env?.PARSEMAN_DEGRADATION : void 0;
|
|
5525
|
-
if (env === "off" || env === "warn" || env === "error") return env;
|
|
5526
|
-
return "warn";
|
|
5816
|
+
function adjacencyFail(pos, def) {
|
|
5817
|
+
return { ok: false, expected: [adjacencyExpected(def)], span: { start: pos, end: pos } };
|
|
5527
5818
|
}
|
|
5528
|
-
|
|
5529
|
-
|
|
5819
|
+
var NO_STANDALONE_PARSE = "adjacency assertions are boundary tests: use adjacent()/notAdjacent() as a NON-FIRST term of a sequence(), where the preceding term defines the gap being asserted.";
|
|
5820
|
+
function adjacencyMisuse(polarity) {
|
|
5821
|
+
return new TypeError(`${polarity}(): ${NO_STANDALONE_PARSE}`);
|
|
5530
5822
|
}
|
|
5531
|
-
function
|
|
5532
|
-
const
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
}
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5823
|
+
function adjacencyCombinator(def) {
|
|
5824
|
+
const meta = {
|
|
5825
|
+
// Zero-width and never leading (sequence() rejects index 0), so it contributes
|
|
5826
|
+
// no first char. `isZeroWidthAssertion` drops it from a sequence's first-set
|
|
5827
|
+
// rather than letting `any` poison the enclosing choice's dispatch.
|
|
5828
|
+
firstSet: { kind: "any" },
|
|
5829
|
+
canMatchNewline: false,
|
|
5830
|
+
isTrivia: false
|
|
5831
|
+
};
|
|
5832
|
+
return {
|
|
5833
|
+
_tag: "adjacency",
|
|
5834
|
+
_meta: meta,
|
|
5835
|
+
_def: def,
|
|
5836
|
+
parse() {
|
|
5837
|
+
throw adjacencyMisuse(def.polarity);
|
|
5838
|
+
}
|
|
5839
|
+
};
|
|
5840
|
+
}
|
|
5841
|
+
function adjacent() {
|
|
5842
|
+
return adjacencyCombinator({ tag: "adjacency", polarity: "adjacent" });
|
|
5843
|
+
}
|
|
5844
|
+
function notAdjacent(options) {
|
|
5845
|
+
const kinds = options?.kinds;
|
|
5846
|
+
if (kinds !== void 0) {
|
|
5847
|
+
if (!Array.isArray(kinds) || kinds.length === 0) {
|
|
5848
|
+
throw new TypeError("notAdjacent({ kinds }): kinds must be a non-empty array of trivia category names.");
|
|
5849
|
+
}
|
|
5850
|
+
for (const k of kinds) {
|
|
5851
|
+
if (typeof k !== "string" || k.length === 0) {
|
|
5852
|
+
throw new TypeError(`notAdjacent({ kinds }): every kind must be a non-empty string, got ${JSON.stringify(k)}.`);
|
|
5853
|
+
}
|
|
5854
|
+
}
|
|
5855
|
+
}
|
|
5856
|
+
return adjacencyCombinator(
|
|
5857
|
+
kinds === void 0 ? { tag: "adjacency", polarity: "notAdjacent" } : { tag: "adjacency", polarity: "notAdjacent", kinds: [...kinds] }
|
|
5858
|
+
);
|
|
5859
|
+
}
|
|
5860
|
+
|
|
5861
|
+
// src/combinators/sequence.ts
|
|
5862
|
+
function sequence(...parsers) {
|
|
5863
|
+
let adjacency = null;
|
|
5864
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
5865
|
+
const a = adjacencyOf(parsers[i]);
|
|
5866
|
+
if (a === null) continue;
|
|
5867
|
+
if (i === 0) {
|
|
5868
|
+
throw new TypeError(
|
|
5869
|
+
`sequence(): ${a.polarity}() cannot be the FIRST term \u2014 an adjacency assertion tests the gap after the PRECEDING term. Put a concrete term first.`
|
|
5870
|
+
);
|
|
5871
|
+
}
|
|
5872
|
+
;
|
|
5873
|
+
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
5874
|
+
}
|
|
5875
|
+
const hasAdjacency = adjacency !== null;
|
|
5876
|
+
let leading = null;
|
|
5877
|
+
for (let i = 1; i < parsers.length; i++) {
|
|
5878
|
+
if (leadsTrivia(parsers[i])) (leading ??= Array.from({ length: parsers.length }, () => false))[i] = true;
|
|
5879
|
+
}
|
|
5880
|
+
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
5881
|
+
const meta = {
|
|
5882
|
+
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
5883
|
+
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
5884
|
+
firstSet: sequenceFirstSet(parsers),
|
|
5885
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
5886
|
+
isTrivia: false
|
|
5887
|
+
};
|
|
5888
|
+
const def = { tag: "sequence", parsers };
|
|
5889
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
5890
|
+
const parseScalar = (input, pos, ctx) => {
|
|
5891
|
+
let cur = pos;
|
|
5892
|
+
if (strictArity !== 0) {
|
|
5893
|
+
cur = scalarParsers[0](input, cur, ctx);
|
|
5894
|
+
if (cur < 0) return cur;
|
|
5895
|
+
const first = ctx._sv;
|
|
5896
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
5897
|
+
cur = scalarParsers[1](input, cur, ctx);
|
|
5898
|
+
if (cur < 0) return cur;
|
|
5899
|
+
const second = ctx._sv;
|
|
5900
|
+
if (strictArity === 2) {
|
|
5901
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second];
|
|
5902
|
+
return cur;
|
|
5903
|
+
}
|
|
5904
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
5905
|
+
cur = scalarParsers[2](input, cur, ctx);
|
|
5906
|
+
if (cur < 0) return cur;
|
|
5907
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second, ctx._sv];
|
|
5908
|
+
return cur;
|
|
5909
|
+
}
|
|
5910
|
+
const values = def.valueUnused ? void 0 : [];
|
|
5911
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
5912
|
+
let termPos = cur;
|
|
5913
|
+
if (i > 0 && ctx.trivia) termPos = advanceTrivia(input, cur, ctx);
|
|
5914
|
+
const end = scalarParsers[i](input, termPos, ctx);
|
|
5915
|
+
if (end < 0) return end;
|
|
5916
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
5917
|
+
if (end > termPos || termPos === cur) cur = end;
|
|
5918
|
+
}
|
|
5919
|
+
ctx._sv = values;
|
|
5920
|
+
return cur;
|
|
5921
|
+
};
|
|
5922
|
+
let followSentinels;
|
|
5923
|
+
return {
|
|
5924
|
+
_tag: "sequence",
|
|
5925
|
+
_meta: meta,
|
|
5926
|
+
_def: def,
|
|
5927
|
+
_parseScalar: hasAdjacency || leading !== null ? void 0 : parseScalar,
|
|
5928
|
+
parse(input, pos, ctx) {
|
|
5929
|
+
const tolerant = ctx._tolerant === true;
|
|
5930
|
+
if (tolerant) {
|
|
5931
|
+
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
5932
|
+
parsers.slice(i + 1).reduce(
|
|
5933
|
+
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
5934
|
+
{ kind: "empty" }
|
|
5935
|
+
)
|
|
5936
|
+
));
|
|
5937
|
+
}
|
|
5938
|
+
const inheritedSync = ctx._sync;
|
|
5939
|
+
const deferredTrivia = needsDeferredTriviaCommit(ctx);
|
|
5940
|
+
const values = def.valueUnused ? void 0 : [];
|
|
5941
|
+
let cur = pos;
|
|
5942
|
+
try {
|
|
5943
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
5944
|
+
if (tolerant) ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
5945
|
+
const assertion = adjacency?.[i];
|
|
5946
|
+
if (assertion) {
|
|
5947
|
+
if (!holdsAdjacency(input, cur, ctx, assertion)) return adjacencyFail(cur, assertion);
|
|
5948
|
+
if (values !== void 0) values.push(null);
|
|
5949
|
+
continue;
|
|
5950
|
+
}
|
|
5951
|
+
let termPos = cur;
|
|
5952
|
+
const markTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
5953
|
+
const markLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
5954
|
+
const markRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
5955
|
+
if (ctx.trivia && i > 0) {
|
|
5956
|
+
termPos = deferredTrivia ? commitTriviaScan(scanTriviaCompact(input, cur, ctx)) : advanceTrivia(input, cur, ctx);
|
|
5957
|
+
}
|
|
5958
|
+
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
5959
|
+
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
5960
|
+
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
5961
|
+
if (leading?.[i] === true) LEAD.at = cur;
|
|
5962
|
+
const result = parsers[i].parse(input, termPos, ctx);
|
|
5963
|
+
if (!result.ok) return result;
|
|
5964
|
+
if (values !== void 0) values.push(result.value);
|
|
5965
|
+
if (result.span.end > termPos || termPos === cur) cur = result.span.end;
|
|
5966
|
+
else if (deferredTrivia) {
|
|
5967
|
+
rollbackScannedTriviaAt(
|
|
5968
|
+
ctx,
|
|
5969
|
+
markTlog,
|
|
5970
|
+
scanTlog,
|
|
5971
|
+
markLog,
|
|
5972
|
+
scanLog,
|
|
5973
|
+
markRootLog,
|
|
5974
|
+
scanRootLog
|
|
5975
|
+
);
|
|
5976
|
+
}
|
|
5977
|
+
}
|
|
5978
|
+
} finally {
|
|
5979
|
+
if (tolerant) ctx._sync = inheritedSync;
|
|
5980
|
+
}
|
|
5981
|
+
return {
|
|
5982
|
+
ok: true,
|
|
5983
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
5984
|
+
value: values ?? void 0,
|
|
5985
|
+
span: { start: pos, end: cur }
|
|
5986
|
+
};
|
|
5987
|
+
}
|
|
5988
|
+
};
|
|
5989
|
+
}
|
|
5990
|
+
|
|
5991
|
+
// src/compiler/degradation.ts
|
|
5992
|
+
function formatDegradation(d) {
|
|
5993
|
+
return `[parseman] degraded [${d.code}] ${d.where}: ${d.subject} \u2014 ${d.fellBackTo}; otherwise ${d.otherwise}`;
|
|
5994
|
+
}
|
|
5995
|
+
var DETAIL_CAP = 8;
|
|
5996
|
+
function formatDegradations(list) {
|
|
5997
|
+
const byCode = /* @__PURE__ */ new Map();
|
|
5998
|
+
for (const d of list) {
|
|
5999
|
+
const bucket = byCode.get(d.code);
|
|
6000
|
+
if (bucket) bucket.push(d);
|
|
6001
|
+
else byCode.set(d.code, [d]);
|
|
6002
|
+
}
|
|
6003
|
+
const out = [];
|
|
6004
|
+
for (const [code, items] of byCode) {
|
|
6005
|
+
for (const d of items.slice(0, DETAIL_CAP)) out.push(formatDegradation(d));
|
|
6006
|
+
if (items.length > DETAIL_CAP) {
|
|
6007
|
+
out.push(
|
|
6008
|
+
`[parseman] degraded [${code}] +${items.length - DETAIL_CAP} more site(s) not listed (${items.length} total). Set PARSEMAN_DEGRADATION=error to fail the build on these.`
|
|
6009
|
+
);
|
|
6010
|
+
}
|
|
6011
|
+
}
|
|
6012
|
+
return out;
|
|
6013
|
+
}
|
|
6014
|
+
var _sinks = [];
|
|
6015
|
+
function beginDegradationCapture() {
|
|
6016
|
+
_sinks.push(/* @__PURE__ */ new Map());
|
|
6017
|
+
}
|
|
6018
|
+
function degradationCaptureDepth() {
|
|
6019
|
+
return _sinks.length;
|
|
6020
|
+
}
|
|
6021
|
+
function unwindDegradationCapture(depth) {
|
|
6022
|
+
const found = [];
|
|
6023
|
+
while (_sinks.length > depth) {
|
|
6024
|
+
const sink = _sinks.pop();
|
|
6025
|
+
found.unshift(...sink.values());
|
|
6026
|
+
}
|
|
6027
|
+
return found;
|
|
6028
|
+
}
|
|
6029
|
+
function resolveDegradationLevel(explicit) {
|
|
6030
|
+
if (explicit !== void 0) return explicit;
|
|
6031
|
+
const env = typeof process !== "undefined" ? process.env?.PARSEMAN_DEGRADATION : void 0;
|
|
6032
|
+
if (env === "off" || env === "warn" || env === "error") return env;
|
|
6033
|
+
return "warn";
|
|
6034
|
+
}
|
|
6035
|
+
function degradationKey(d) {
|
|
6036
|
+
return JSON.stringify([d.code, d.where, d.subject]);
|
|
6037
|
+
}
|
|
6038
|
+
function recordDegradation(d) {
|
|
6039
|
+
const level = resolveDegradationLevel();
|
|
6040
|
+
if (level === "off") return;
|
|
6041
|
+
const key = degradationKey(d);
|
|
6042
|
+
const sink = _sinks[_sinks.length - 1];
|
|
6043
|
+
if (sink) {
|
|
6044
|
+
if (!sink.has(key)) sink.set(key, d);
|
|
6045
|
+
return;
|
|
6046
|
+
}
|
|
6047
|
+
if (_immediate.has(key)) return;
|
|
6048
|
+
_immediate.add(key);
|
|
6049
|
+
if (level === "error") throw new Error(`parseman: degraded compilation path
|
|
6050
|
+
${formatDegradation(d)}`);
|
|
5544
6051
|
console.warn(formatDegradation(d));
|
|
5545
6052
|
}
|
|
5546
6053
|
var _immediate = /* @__PURE__ */ new Set();
|
|
@@ -5659,91 +6166,620 @@ function splitTopLevel(inner) {
|
|
|
5659
6166
|
last = i + 1;
|
|
5660
6167
|
}
|
|
5661
6168
|
}
|
|
5662
|
-
if (depth !== 0 || angle !== 0) return null;
|
|
5663
|
-
parts.push(inner.slice(last));
|
|
5664
|
-
return parts;
|
|
6169
|
+
if (depth !== 0 || angle !== 0) return null;
|
|
6170
|
+
parts.push(inner.slice(last));
|
|
6171
|
+
return parts;
|
|
6172
|
+
}
|
|
6173
|
+
function isConfirmableParam(part) {
|
|
6174
|
+
const head = PARAM_HEAD_RE.exec(part);
|
|
6175
|
+
if (!head) return false;
|
|
6176
|
+
const rest = part.slice(head[0].length);
|
|
6177
|
+
if (rest === "") return true;
|
|
6178
|
+
if (rest[0] !== ":") return false;
|
|
6179
|
+
return !hasDefaultAssign(rest.slice(1));
|
|
6180
|
+
}
|
|
6181
|
+
function hasDefaultAssign(annotation) {
|
|
6182
|
+
for (let i = 0; i < annotation.length; i++) {
|
|
6183
|
+
if (annotation[i] !== "=") continue;
|
|
6184
|
+
if (annotation[i + 1] === ">" || annotation[i + 1] === "=") {
|
|
6185
|
+
i++;
|
|
6186
|
+
continue;
|
|
6187
|
+
}
|
|
6188
|
+
const prev = annotation[i - 1];
|
|
6189
|
+
if (prev === "<" || prev === ">" || prev === "!" || prev === "=") continue;
|
|
6190
|
+
return true;
|
|
6191
|
+
}
|
|
6192
|
+
return false;
|
|
6193
|
+
}
|
|
6194
|
+
function buildAnalysisSrc(def) {
|
|
6195
|
+
return def.buildSigSrc ?? def.buildSrc ?? def.build.toString();
|
|
6196
|
+
}
|
|
6197
|
+
var RESOLVER_REASONS = {
|
|
6198
|
+
"rest-parameter": "its parameter list uses a rest parameter, so the declared arity is unbounded",
|
|
6199
|
+
"arguments": "its body references `arguments`",
|
|
6200
|
+
"reassigned": "the binding it names is reassigned, so the function read here is not decidable",
|
|
6201
|
+
"not-a-function": "the binding it names is not a function declaration",
|
|
6202
|
+
"unresolved-import": "its module could not be resolved or parsed",
|
|
6203
|
+
"not-found": "the name did not resolve to any binding",
|
|
6204
|
+
"computed": "it is a computed expression",
|
|
6205
|
+
"foreign-source": "it is named in a module the resolver was never told about, so its offsets index no scope tree the resolver holds",
|
|
6206
|
+
"ambiguous-source": "two distinct registered modules hold byte-identical text, so that text no longer names the module its offsets index"
|
|
6207
|
+
};
|
|
6208
|
+
function unconfirmableReason(def, src) {
|
|
6209
|
+
const declared = def.buildArityUnresolved;
|
|
6210
|
+
if (declared !== void 0 && RESOLVER_REASONS[declared]) return RESOLVER_REASONS[declared];
|
|
6211
|
+
const s = src.trim();
|
|
6212
|
+
const params = s.slice(0, s.indexOf(")") + 1);
|
|
6213
|
+
if (params.includes("...")) return RESOLVER_REASONS["rest-parameter"];
|
|
6214
|
+
if (/\barguments\b/.test(s)) return RESOLVER_REASONS["arguments"];
|
|
6215
|
+
if (/^[A-Za-z_$][\w$]*(\s*\.\s*[A-Za-z_$][\w$]*)?$/.test(s)) {
|
|
6216
|
+
return "it names a binding this build could not resolve to a function declaration";
|
|
6217
|
+
}
|
|
6218
|
+
return "its parameter list could not be parsed";
|
|
6219
|
+
}
|
|
6220
|
+
function confirmedArityForDef(def) {
|
|
6221
|
+
if (def.buildArity !== void 0) return def.buildArity;
|
|
6222
|
+
const src = buildAnalysisSrc(def);
|
|
6223
|
+
const arity = confirmedBuildArity(src);
|
|
6224
|
+
if (arity !== null) return arity;
|
|
6225
|
+
const subject = `build reducer \`${(def.buildSrc ?? "<runtime fn>").trim().split("\n")[0].slice(0, 60)}\``;
|
|
6226
|
+
recordDegradation({
|
|
6227
|
+
code: "build-arity-unconfirmed",
|
|
6228
|
+
severity: "warn",
|
|
6229
|
+
where: `node("${def.type ?? "<inferred>"}")`,
|
|
6230
|
+
subject,
|
|
6231
|
+
fellBackTo: `could not confirm its declared arity \u2014 ${unconfirmableReason(def, src)} \u2014 so this node captures children, fields and raw children, logs trivia, and hands it \`_ctx.state\` on every match`,
|
|
6232
|
+
otherwise: "only the tiers the reducer actually declares would be captured (arity >= 1 children, >= 2 fields, >= 4 raw, >= 5 trivia, >= 6 state). Declare it with `node(..., { buildArity: n })` if it cannot be derived"
|
|
6233
|
+
});
|
|
6234
|
+
return null;
|
|
6235
|
+
}
|
|
6236
|
+
function buildReadsRaw(def) {
|
|
6237
|
+
if (!def.build) return true;
|
|
6238
|
+
if (def.buildRawUnused === true) return false;
|
|
6239
|
+
const arity = confirmedArityForDef(def);
|
|
6240
|
+
if (arity === null) return true;
|
|
6241
|
+
return arity >= 4;
|
|
6242
|
+
}
|
|
6243
|
+
function buildReadsTrivia(def) {
|
|
6244
|
+
if (!def.build) return true;
|
|
6245
|
+
const arity = confirmedArityForDef(def);
|
|
6246
|
+
if (arity === null) return true;
|
|
6247
|
+
return arity >= 5;
|
|
6248
|
+
}
|
|
6249
|
+
function buildReadsState(def) {
|
|
6250
|
+
if (!def.build) return true;
|
|
6251
|
+
const arity = confirmedArityForDef(def);
|
|
6252
|
+
if (arity === null) return true;
|
|
6253
|
+
return arity >= 6;
|
|
6254
|
+
}
|
|
6255
|
+
|
|
6256
|
+
// src/combinators/token.ts
|
|
6257
|
+
function semanticLeafValue(_ctx, _input, _start, _end, value) {
|
|
6258
|
+
return value;
|
|
6259
|
+
}
|
|
6260
|
+
function sourceLeafValue(ctx, input, start, end, value) {
|
|
6261
|
+
return cstOutputHost(ctx.build) ? input.slice(start, end) : value;
|
|
6262
|
+
}
|
|
6263
|
+
function token(root) {
|
|
6264
|
+
const meta = {
|
|
6265
|
+
firstSet: root._meta.firstSet,
|
|
6266
|
+
canMatchNewline: root._meta.canMatchNewline,
|
|
6267
|
+
isTrivia: false
|
|
6268
|
+
};
|
|
6269
|
+
return {
|
|
6270
|
+
_tag: "token",
|
|
6271
|
+
_meta: meta,
|
|
6272
|
+
_def: { tag: "token", parser: root },
|
|
6273
|
+
parse(input, pos, ctx) {
|
|
6274
|
+
const savedTrivia = ctx.trivia;
|
|
6275
|
+
const savedKinds = ctx.triviaKindLabels;
|
|
6276
|
+
const savedBuf = ctx._cstBuf;
|
|
6277
|
+
const savedChildren = ctx._cstChildren;
|
|
6278
|
+
const savedLeaves = ctx._cstLeaves;
|
|
6279
|
+
const savedRaw = ctx._cstRawChildren;
|
|
6280
|
+
const savedTriviaLog = ctx._cstTriviaLog;
|
|
6281
|
+
const savedOuterTriviaLog = ctx._triviaLog;
|
|
6282
|
+
const savedRootTriviaLog = ctx._rootTriviaLog;
|
|
6283
|
+
const wasCapturing = cstCaptureActive(ctx);
|
|
6284
|
+
ctx.trivia = void 0;
|
|
6285
|
+
ctx.triviaKindLabels = void 0;
|
|
6286
|
+
ctx._cstBuf = void 0;
|
|
6287
|
+
ctx._cstChildren = void 0;
|
|
6288
|
+
ctx._cstLeaves = void 0;
|
|
6289
|
+
ctx._cstRawChildren = void 0;
|
|
6290
|
+
ctx._cstTriviaLog = void 0;
|
|
6291
|
+
ctx._triviaLog = void 0;
|
|
6292
|
+
ctx._rootTriviaLog = void 0;
|
|
6293
|
+
let result;
|
|
6294
|
+
try {
|
|
6295
|
+
result = root.parse(input, pos, ctx);
|
|
6296
|
+
} finally {
|
|
6297
|
+
ctx.trivia = savedTrivia;
|
|
6298
|
+
ctx.triviaKindLabels = savedKinds;
|
|
6299
|
+
ctx._cstBuf = savedBuf;
|
|
6300
|
+
ctx._cstChildren = savedChildren;
|
|
6301
|
+
ctx._cstLeaves = savedLeaves;
|
|
6302
|
+
ctx._cstRawChildren = savedRaw;
|
|
6303
|
+
ctx._cstTriviaLog = savedTriviaLog;
|
|
6304
|
+
ctx._triviaLog = savedOuterTriviaLog;
|
|
6305
|
+
ctx._rootTriviaLog = savedRootTriviaLog;
|
|
6306
|
+
}
|
|
6307
|
+
if (!result.ok) return result;
|
|
6308
|
+
const span = result.span;
|
|
6309
|
+
const value = input.slice(pos, span.end);
|
|
6310
|
+
if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
6311
|
+
return { ok: true, value, span };
|
|
6312
|
+
}
|
|
6313
|
+
};
|
|
6314
|
+
}
|
|
6315
|
+
function makeLeaf(root, fn, sourceCstValue) {
|
|
6316
|
+
const cstValue = sourceCstValue ? sourceLeafValue : semanticLeafValue;
|
|
6317
|
+
const meta = {
|
|
6318
|
+
firstSet: root._meta.firstSet,
|
|
6319
|
+
canMatchNewline: root._meta.canMatchNewline,
|
|
6320
|
+
isTrivia: false
|
|
6321
|
+
};
|
|
6322
|
+
return {
|
|
6323
|
+
_tag: "leaf",
|
|
6324
|
+
_meta: meta,
|
|
6325
|
+
_def: {
|
|
6326
|
+
tag: "leaf",
|
|
6327
|
+
parser: root,
|
|
6328
|
+
fn,
|
|
6329
|
+
...sourceCstValue ? { cstValue: "source" } : {}
|
|
6330
|
+
},
|
|
6331
|
+
parse(input, pos, ctx) {
|
|
6332
|
+
const savedBuf = ctx._cstBuf;
|
|
6333
|
+
const savedChildren = ctx._cstChildren;
|
|
6334
|
+
const savedLeaves = ctx._cstLeaves;
|
|
6335
|
+
const savedRaw = ctx._cstRawChildren;
|
|
6336
|
+
const savedTriviaLog = ctx._cstTriviaLog;
|
|
6337
|
+
const savedOuterTriviaLog = ctx._triviaLog;
|
|
6338
|
+
const wasCapturing = cstCaptureActive(ctx);
|
|
6339
|
+
ctx._cstBuf = void 0;
|
|
6340
|
+
ctx._cstChildren = void 0;
|
|
6341
|
+
ctx._cstLeaves = void 0;
|
|
6342
|
+
ctx._cstRawChildren = void 0;
|
|
6343
|
+
ctx._cstTriviaLog = void 0;
|
|
6344
|
+
ctx._triviaLog = void 0;
|
|
6345
|
+
let result;
|
|
6346
|
+
try {
|
|
6347
|
+
result = root.parse(input, pos, ctx);
|
|
6348
|
+
} finally {
|
|
6349
|
+
ctx._cstBuf = savedBuf;
|
|
6350
|
+
ctx._cstChildren = savedChildren;
|
|
6351
|
+
ctx._cstLeaves = savedLeaves;
|
|
6352
|
+
ctx._cstRawChildren = savedRaw;
|
|
6353
|
+
ctx._cstTriviaLog = savedTriviaLog;
|
|
6354
|
+
ctx._triviaLog = savedOuterTriviaLog;
|
|
6355
|
+
}
|
|
6356
|
+
if (!result.ok) return result;
|
|
6357
|
+
const value = fn(result.value, result.span);
|
|
6358
|
+
if (wasCapturing) pushCstLeaf(ctx, {
|
|
6359
|
+
_tag: "leaf",
|
|
6360
|
+
value: cstValue(ctx, input, pos, result.span.end, value),
|
|
6361
|
+
span: result.span
|
|
6362
|
+
});
|
|
6363
|
+
return { ok: true, value, span: result.span };
|
|
6364
|
+
}
|
|
6365
|
+
};
|
|
6366
|
+
}
|
|
6367
|
+
function leaf(root, fn) {
|
|
6368
|
+
return makeLeaf(root, fn, false);
|
|
6369
|
+
}
|
|
6370
|
+
function sourceLeaf(root, fn) {
|
|
6371
|
+
return makeLeaf(root, fn, true);
|
|
6372
|
+
}
|
|
6373
|
+
|
|
6374
|
+
// src/compiler/value-usage.ts
|
|
6375
|
+
function markUnusedValues(root) {
|
|
6376
|
+
const seenConsumed = /* @__PURE__ */ new WeakSet();
|
|
6377
|
+
const seenUnconsumed = /* @__PURE__ */ new WeakSet();
|
|
6378
|
+
const mark = (def, consumed) => {
|
|
6379
|
+
if (consumed) def.valueUnused = false;
|
|
6380
|
+
else if (def.valueUnused !== false) def.valueUnused = true;
|
|
6381
|
+
};
|
|
6382
|
+
const visit = (c, consumed) => {
|
|
6383
|
+
const seen = consumed ? seenConsumed : seenUnconsumed;
|
|
6384
|
+
if (seen.has(c)) return;
|
|
6385
|
+
seen.add(c);
|
|
6386
|
+
const def = c._def;
|
|
6387
|
+
switch (def.tag) {
|
|
6388
|
+
case "many":
|
|
6389
|
+
case "oneOrMore":
|
|
6390
|
+
mark(def, consumed);
|
|
6391
|
+
visit(def.parser, consumed);
|
|
6392
|
+
return;
|
|
6393
|
+
case "optional":
|
|
6394
|
+
visit(def.parser, consumed);
|
|
6395
|
+
return;
|
|
6396
|
+
case "sequence":
|
|
6397
|
+
mark(def, consumed);
|
|
6398
|
+
for (const p of def.parsers) visit(p, consumed);
|
|
6399
|
+
return;
|
|
6400
|
+
case "choice":
|
|
6401
|
+
for (const p of def.parsers) visit(p, consumed);
|
|
6402
|
+
return;
|
|
6403
|
+
case "dispatch":
|
|
6404
|
+
visit(def.selector, consumed);
|
|
6405
|
+
for (const entry of def.cases) visit(entry.parser, consumed);
|
|
6406
|
+
if (def.matchers) for (const entry of def.matchers) visit(entry.parser, consumed);
|
|
6407
|
+
if (def.otherwise) visit(def.otherwise, consumed);
|
|
6408
|
+
return;
|
|
6409
|
+
case "node":
|
|
6410
|
+
visit(def.parser, false);
|
|
6411
|
+
return;
|
|
6412
|
+
case "transform":
|
|
6413
|
+
visit(def.parser, true);
|
|
6414
|
+
return;
|
|
6415
|
+
case "field":
|
|
6416
|
+
visit(def.parser, true);
|
|
6417
|
+
return;
|
|
6418
|
+
case "sepBy":
|
|
6419
|
+
visit(def.parser, true);
|
|
6420
|
+
visit(def.separator, false);
|
|
6421
|
+
return;
|
|
6422
|
+
case "not":
|
|
6423
|
+
case "peek":
|
|
6424
|
+
visit(def.parser, false);
|
|
6425
|
+
return;
|
|
6426
|
+
case "grammar":
|
|
6427
|
+
visit(def.parser, consumed);
|
|
6428
|
+
if (def.triviaParser) visit(def.triviaParser, false);
|
|
6429
|
+
return;
|
|
6430
|
+
case "recover":
|
|
6431
|
+
visit(def.parser, consumed);
|
|
6432
|
+
visit(def.sentinel, false);
|
|
6433
|
+
return;
|
|
6434
|
+
case "token":
|
|
6435
|
+
visit(def.parser, false);
|
|
6436
|
+
return;
|
|
6437
|
+
case "label":
|
|
6438
|
+
case "trivia":
|
|
6439
|
+
case "attempt":
|
|
6440
|
+
case "withCtx":
|
|
6441
|
+
case "expect":
|
|
6442
|
+
visit(def.parser, consumed);
|
|
6443
|
+
return;
|
|
6444
|
+
case "leaf":
|
|
6445
|
+
visit(def.parser, true);
|
|
6446
|
+
return;
|
|
6447
|
+
case "lazy":
|
|
6448
|
+
return;
|
|
6449
|
+
default:
|
|
6450
|
+
return;
|
|
6451
|
+
}
|
|
6452
|
+
};
|
|
6453
|
+
const resolveRoot = (c) => {
|
|
6454
|
+
const guard = /* @__PURE__ */ new Set();
|
|
6455
|
+
let cur = c;
|
|
6456
|
+
while (!guard.has(cur)) {
|
|
6457
|
+
const d = cur._def;
|
|
6458
|
+
if (d.tag === "grammar") {
|
|
6459
|
+
guard.add(cur);
|
|
6460
|
+
cur = d.parser;
|
|
6461
|
+
continue;
|
|
6462
|
+
}
|
|
6463
|
+
if (d.tag !== "lazy") return cur;
|
|
6464
|
+
guard.add(cur);
|
|
6465
|
+
try {
|
|
6466
|
+
cur = d.thunk();
|
|
6467
|
+
} catch {
|
|
6468
|
+
return c;
|
|
6469
|
+
}
|
|
6470
|
+
}
|
|
6471
|
+
return cur;
|
|
6472
|
+
};
|
|
6473
|
+
visit(resolveRoot(root), true);
|
|
6474
|
+
}
|
|
6475
|
+
|
|
6476
|
+
// src/cst/root-trivia-scope.ts
|
|
6477
|
+
var ROOT_TRIVIA_SCOPE_REFUSAL = "parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'.";
|
|
6478
|
+
function refuseUnclassifiedRootScope(strict) {
|
|
6479
|
+
if (strict === true) throw new TypeError(ROOT_TRIVIA_SCOPE_REFUSAL);
|
|
6480
|
+
}
|
|
6481
|
+
|
|
6482
|
+
// src/combinators/grammar.ts
|
|
6483
|
+
function annotateResultLines(result, index) {
|
|
6484
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
6485
|
+
const errors = annotated.errors;
|
|
6486
|
+
if (errors) {
|
|
6487
|
+
;
|
|
6488
|
+
annotated.errors = errors.map((error) => ({
|
|
6489
|
+
...error,
|
|
6490
|
+
span: annotateSpan(error.span, index)
|
|
6491
|
+
}));
|
|
6492
|
+
}
|
|
6493
|
+
return annotated;
|
|
6494
|
+
}
|
|
6495
|
+
function createParseLineContext(input, pos) {
|
|
6496
|
+
const lineIndex = createLineIndex();
|
|
6497
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
6498
|
+
return { lineIndex, lineScannedTo: pos };
|
|
6499
|
+
}
|
|
6500
|
+
var TRACK_LINES_ON = () => true;
|
|
6501
|
+
var TRACK_LINES_OFF = () => false;
|
|
6502
|
+
var TRACK_LINES_INHERIT = (ctx) => ctx?.trackLines === true;
|
|
6503
|
+
function parser(opts, root) {
|
|
6504
|
+
const clearTrivia = opts.trivia === null;
|
|
6505
|
+
const opaqueRootCapture = opts.rootCapture === "opaque";
|
|
6506
|
+
if (opaqueRootCapture && opts.trivia === void 0) {
|
|
6507
|
+
throw new TypeError("parser({ rootCapture: 'opaque' }) requires an explicit trivia scope.");
|
|
6508
|
+
}
|
|
6509
|
+
const scopeTrivia = clearTrivia ? void 0 : opts.trivia ?? void 0;
|
|
6510
|
+
const scopeLabels = scopeTrivia?._meta?.triviaKindLabels;
|
|
6511
|
+
const refuseUnclassified = scopeTrivia !== void 0 && !scopeTrivia._meta?.rootTriviaClassified && !opaqueRootCapture;
|
|
6512
|
+
const forceCaptureTrivia = opts.captureTrivia === true;
|
|
6513
|
+
const trackLinesPolicy = opts.trackLines === true ? "on" : opts.trackLines === false ? "off" : "inherit";
|
|
6514
|
+
const trackLinesOf = trackLinesPolicy === "on" ? TRACK_LINES_ON : trackLinesPolicy === "off" ? TRACK_LINES_OFF : TRACK_LINES_INHERIT;
|
|
6515
|
+
const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
|
|
6516
|
+
const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
|
|
6517
|
+
const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
|
|
6518
|
+
const rootScalar = scalarOf(root);
|
|
6519
|
+
const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
|
|
6520
|
+
const parseScalar = scalarEligible ? (input, pos, ctx) => {
|
|
6521
|
+
const savedTrivia = ctx.trivia;
|
|
6522
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
6523
|
+
if (clearTrivia) {
|
|
6524
|
+
ctx.trivia = void 0;
|
|
6525
|
+
ctx.triviaKindLabels = void 0;
|
|
6526
|
+
} else if (scopeTrivia !== void 0) {
|
|
6527
|
+
ctx.trivia = scopeTrivia;
|
|
6528
|
+
ctx.triviaKindLabels = scopeLabels;
|
|
6529
|
+
}
|
|
6530
|
+
const end = rootScalar(input, pos, ctx);
|
|
6531
|
+
ctx.trivia = savedTrivia;
|
|
6532
|
+
ctx.triviaKindLabels = savedLabels;
|
|
6533
|
+
return end;
|
|
6534
|
+
} : void 0;
|
|
6535
|
+
let publicScalar;
|
|
6536
|
+
const grammar = {
|
|
6537
|
+
_tag: "grammar",
|
|
6538
|
+
_meta: {
|
|
6539
|
+
...root._meta,
|
|
6540
|
+
// Trivia classification describes this grammar's own active trivia
|
|
6541
|
+
// scope. A directly nested grammar may have classified trivia of its
|
|
6542
|
+
// own, but that must not advertise classification for this wrapper.
|
|
6543
|
+
triviaKindLabels: void 0,
|
|
6544
|
+
rootTriviaClassified: void 0,
|
|
6545
|
+
...opts.trivia?._meta?.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {},
|
|
6546
|
+
...opts.trivia?._meta?.rootTriviaClassified ? { rootTriviaClassified: true } : {}
|
|
6547
|
+
},
|
|
6548
|
+
_def: {
|
|
6549
|
+
tag: "grammar",
|
|
6550
|
+
parser: root,
|
|
6551
|
+
triviaParser: scopeTrivia,
|
|
6552
|
+
clearTrivia,
|
|
6553
|
+
...opaqueRootCapture ? { rootCapture: "opaque" } : {},
|
|
6554
|
+
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
6555
|
+
trackLines: opts.trackLines ?? false,
|
|
6556
|
+
constructionTrackLines: trackLinesPolicy,
|
|
6557
|
+
...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
|
|
6558
|
+
},
|
|
6559
|
+
_parseScalar: parseScalar,
|
|
6560
|
+
parse(input, pos, _ctx) {
|
|
6561
|
+
if (pos === void 0 && _ctx === void 0) {
|
|
6562
|
+
publicScalar ??= scalarRootOf(grammar) ?? null;
|
|
6563
|
+
if (publicScalar) {
|
|
6564
|
+
const ctx2 = createParseContext();
|
|
6565
|
+
const end = publicScalar(input, 0, ctx2);
|
|
6566
|
+
if (end < 0) {
|
|
6567
|
+
const at = ~end;
|
|
6568
|
+
return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
|
|
6569
|
+
}
|
|
6570
|
+
return { ok: true, value: ctx2._sv, span: { start: 0, end } };
|
|
6571
|
+
}
|
|
6572
|
+
}
|
|
6573
|
+
if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
|
|
6574
|
+
const trackLines = trackLinesOf(_ctx);
|
|
6575
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
6576
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
6577
|
+
const ctx = _ctx === void 0 ? createParseContext() : { ..._ctx };
|
|
6578
|
+
ctx.trackLines = trackLines;
|
|
6579
|
+
if (lineIndex) ctx._lineIndex = lineIndex;
|
|
6580
|
+
if (lineContext) ctx._lineScannedTo = lineContext.lineScannedTo;
|
|
6581
|
+
if (clearTrivia) {
|
|
6582
|
+
ctx.trivia = void 0;
|
|
6583
|
+
ctx.triviaKindLabels = void 0;
|
|
6584
|
+
} else if (scopeTrivia !== void 0) {
|
|
6585
|
+
ctx.trivia = scopeTrivia;
|
|
6586
|
+
if (scopeLabels) ctx.triviaKindLabels = scopeLabels;
|
|
6587
|
+
}
|
|
6588
|
+
if (forceCaptureTrivia || _ctx?.captureTrivia) ctx.captureTrivia = true;
|
|
6589
|
+
if (ownCaptureMask !== void 0) ctx._triviaCaptureMask = ownCaptureMask;
|
|
6590
|
+
else if (inheritCaptureMask) ctx._triviaCaptureMask = triviaKindMask(_ctx?.triviaKindLabels, captureKinds);
|
|
6591
|
+
if (opaqueRootCapture) ctx._rootTriviaCapture = false;
|
|
6592
|
+
const result = root.parse(input, pos ?? 0, ctx);
|
|
6593
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
6594
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
6595
|
+
}
|
|
6596
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
6597
|
+
}
|
|
6598
|
+
};
|
|
6599
|
+
return grammar;
|
|
6600
|
+
}
|
|
6601
|
+
function noTrivia(root) {
|
|
6602
|
+
return parser({ trivia: null }, root);
|
|
6603
|
+
}
|
|
6604
|
+
var _analyzed = /* @__PURE__ */ new WeakSet();
|
|
6605
|
+
function parse(combinator, input, opts = {}) {
|
|
6606
|
+
if (!_analyzed.has(combinator)) {
|
|
6607
|
+
_analyzed.add(combinator);
|
|
6608
|
+
markUnusedValues(combinator);
|
|
6609
|
+
}
|
|
6610
|
+
if (!opts.trackLines && !opts.recover && combinator._def.tag === "grammar" && combinator._meta.grammarScanSkip === void 0) {
|
|
6611
|
+
return combinator.parse(input);
|
|
6612
|
+
}
|
|
6613
|
+
const trackLines = opts.trackLines ?? combinator._meta.grammarTrackLines ?? false;
|
|
6614
|
+
const lineContext = trackLines ? createParseLineContext(input, 0) : void 0;
|
|
6615
|
+
const lineIndex = lineContext?.lineIndex;
|
|
6616
|
+
const _errors = opts.recover ? [] : void 0;
|
|
6617
|
+
const _probe = opts.recover ? { offset: input.length, best: null } : void 0;
|
|
6618
|
+
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
6619
|
+
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
6620
|
+
const ctx = createParseContext();
|
|
6621
|
+
ctx.trackLines = trackLines;
|
|
6622
|
+
if (lineIndex) ctx._lineIndex = lineIndex;
|
|
6623
|
+
if (lineContext) ctx._lineScannedTo = lineContext.lineScannedTo;
|
|
6624
|
+
if (grammarTrivia !== void 0) {
|
|
6625
|
+
ctx.trivia = grammarTrivia;
|
|
6626
|
+
if (grammarTrivia._meta.triviaKindLabels) ctx.triviaKindLabels = grammarTrivia._meta.triviaKindLabels;
|
|
6627
|
+
}
|
|
6628
|
+
if (grammarScanSkip !== void 0) ctx.scanSkip = grammarScanSkip;
|
|
6629
|
+
if (_errors !== void 0) ctx._errors = _errors;
|
|
6630
|
+
if (_probe !== void 0) ctx._probe = _probe;
|
|
6631
|
+
const result = combinator.parse(input, 0, ctx);
|
|
6632
|
+
if (!result.ok) return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
6633
|
+
const withErrors = _errors !== void 0 ? { ...result, errors: _errors, furthestFail: _probe?.best ?? null } : result;
|
|
6634
|
+
return lineIndex ? annotateResultLines(withErrors, normalizeLineIndex(lineIndex)) : withErrors;
|
|
5665
6635
|
}
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
6636
|
+
|
|
6637
|
+
// src/combinators/attempt.ts
|
|
6638
|
+
function containOption(options) {
|
|
6639
|
+
if (options === void 0) return false;
|
|
6640
|
+
for (const key of Object.keys(options)) {
|
|
6641
|
+
if (key !== "contain") throw new TypeError(`attempt(): unknown option ${JSON.stringify(key)}`);
|
|
6642
|
+
}
|
|
6643
|
+
if (options.contain !== void 0 && typeof options.contain !== "boolean") {
|
|
6644
|
+
throw new TypeError("attempt(): `contain` must be a boolean");
|
|
6645
|
+
}
|
|
6646
|
+
return options.contain === true;
|
|
5673
6647
|
}
|
|
5674
|
-
function
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
6648
|
+
function attempt(parser2, options) {
|
|
6649
|
+
const contain = containOption(options);
|
|
6650
|
+
const guardable = parser2._meta.firstSet.kind !== "any" && !matchesEmpty(parser2);
|
|
6651
|
+
let failExpected;
|
|
6652
|
+
return {
|
|
6653
|
+
_tag: "attempt",
|
|
6654
|
+
_meta: parser2._meta,
|
|
6655
|
+
_def: contain ? { tag: "attempt", parser: parser2, contain: true } : { tag: "attempt", parser: parser2 },
|
|
6656
|
+
parse(input, pos, ctx) {
|
|
6657
|
+
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(parser2, input, pos)) {
|
|
6658
|
+
if (failExpected === void 0) {
|
|
6659
|
+
const e = deriveExpected(parser2);
|
|
6660
|
+
failExpected = e.length > 0 ? e : [parser2._tag];
|
|
6661
|
+
}
|
|
6662
|
+
return { ok: false, expected: failExpected, span: { start: pos, end: pos } };
|
|
6663
|
+
}
|
|
6664
|
+
const mark = saveCstMark(ctx);
|
|
6665
|
+
const log = ctx._triviaLog?.length;
|
|
6666
|
+
const rootLog = ctx._rootTriviaLog?.length;
|
|
6667
|
+
const split = ctx._columnsSplit;
|
|
6668
|
+
const result = parser2.parse(input, pos, ctx);
|
|
6669
|
+
if (result.ok) return result;
|
|
6670
|
+
rollbackCstCapture(ctx, mark);
|
|
6671
|
+
ctx._columnsSplit = split;
|
|
6672
|
+
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
6673
|
+
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
6674
|
+
if (result.committed && !contain) return result;
|
|
6675
|
+
return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
|
|
5680
6676
|
}
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
6677
|
+
};
|
|
6678
|
+
}
|
|
6679
|
+
|
|
6680
|
+
// src/table/factor-choice.ts
|
|
6681
|
+
var DERIVED = /* @__PURE__ */ new Set(["_tag", "_meta", "_def", "_parseScalar", "_stickyRegex", "parse"]);
|
|
6682
|
+
function isCombinator(v) {
|
|
6683
|
+
return typeof v === "object" && v !== null && "_def" in v && "_meta" in v;
|
|
6684
|
+
}
|
|
6685
|
+
function sameComb(a, b, depth) {
|
|
6686
|
+
if (a === b) return true;
|
|
6687
|
+
if (depth > 32 || a._tag !== b._tag) return false;
|
|
6688
|
+
for (const k of Object.keys(a)) if (!DERIVED.has(k)) return false;
|
|
6689
|
+
for (const k of Object.keys(b)) if (!DERIVED.has(k)) return false;
|
|
6690
|
+
return sameFields(a._def, b._def, depth, void 0);
|
|
6691
|
+
}
|
|
6692
|
+
function sameValue(u, v, depth) {
|
|
6693
|
+
if (u === v) return true;
|
|
6694
|
+
if (isCombinator(u) && isCombinator(v)) return sameComb(u, v, depth + 1);
|
|
6695
|
+
if (Array.isArray(u) && Array.isArray(v)) return u.length === v.length && u.every((x, i) => sameValue(x, v[i], depth));
|
|
6696
|
+
if (typeof u === "object" && u !== null && typeof v === "object" && v !== null && Object.getPrototypeOf(u) === Object.prototype && Object.getPrototypeOf(v) === Object.prototype) {
|
|
6697
|
+
return sameFields(u, v, depth, void 0);
|
|
5684
6698
|
}
|
|
5685
6699
|
return false;
|
|
5686
6700
|
}
|
|
5687
|
-
function
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
};
|
|
5701
|
-
function unconfirmableReason(def, src) {
|
|
5702
|
-
const declared = def.buildArityUnresolved;
|
|
5703
|
-
if (declared !== void 0 && RESOLVER_REASONS[declared]) return RESOLVER_REASONS[declared];
|
|
5704
|
-
const s = src.trim();
|
|
5705
|
-
const params = s.slice(0, s.indexOf(")") + 1);
|
|
5706
|
-
if (params.includes("...")) return RESOLVER_REASONS["rest-parameter"];
|
|
5707
|
-
if (/\barguments\b/.test(s)) return RESOLVER_REASONS["arguments"];
|
|
5708
|
-
if (/^[A-Za-z_$][\w$]*(\s*\.\s*[A-Za-z_$][\w$]*)?$/.test(s)) {
|
|
5709
|
-
return "it names a binding this build could not resolve to a function declaration";
|
|
6701
|
+
function sameFields(x, y, depth, skip) {
|
|
6702
|
+
const kx = Object.keys(x).filter((k) => k !== skip && x[k] !== void 0);
|
|
6703
|
+
const ky = Object.keys(y).filter((k) => k !== skip && y[k] !== void 0);
|
|
6704
|
+
if (kx.length !== ky.length) return false;
|
|
6705
|
+
for (const k of kx) {
|
|
6706
|
+
if (!(k in y)) return false;
|
|
6707
|
+
const u = x[k];
|
|
6708
|
+
const v = y[k];
|
|
6709
|
+
if (k === "fn" && typeof u === "function" && typeof v === "function" && u !== v) {
|
|
6710
|
+
if (typeof x.fnSrc !== "string" || x.fnSrc === "" || x.fnSrc !== y.fnSrc) return false;
|
|
6711
|
+
continue;
|
|
6712
|
+
}
|
|
6713
|
+
if (!sameValue(u, v, depth)) return false;
|
|
5710
6714
|
}
|
|
5711
|
-
return
|
|
5712
|
-
}
|
|
5713
|
-
function confirmedArityForDef(def) {
|
|
5714
|
-
if (def.buildArity !== void 0) return def.buildArity;
|
|
5715
|
-
const src = buildAnalysisSrc(def);
|
|
5716
|
-
const arity = confirmedBuildArity(src);
|
|
5717
|
-
if (arity !== null) return arity;
|
|
5718
|
-
const subject = `build reducer \`${(def.buildSrc ?? "<runtime fn>").trim().split("\n")[0].slice(0, 60)}\``;
|
|
5719
|
-
recordDegradation({
|
|
5720
|
-
code: "build-arity-unconfirmed",
|
|
5721
|
-
severity: "warn",
|
|
5722
|
-
where: `node("${def.type ?? "<inferred>"}")`,
|
|
5723
|
-
subject,
|
|
5724
|
-
fellBackTo: `could not confirm its declared arity \u2014 ${unconfirmableReason(def, src)} \u2014 so this node captures children, fields and raw children, logs trivia, and clones \`_ctx.state\` on every match`,
|
|
5725
|
-
otherwise: "only the tiers the reducer actually declares would be captured (arity >= 1 children, >= 2 fields, >= 4 raw, >= 5 trivia, >= 6 state). Declare it with `node(..., { buildArity: n })` if it cannot be derived"
|
|
5726
|
-
});
|
|
5727
|
-
return null;
|
|
5728
|
-
}
|
|
5729
|
-
function buildReadsRaw(def) {
|
|
5730
|
-
if (!def.build) return true;
|
|
5731
|
-
if (def.buildRawUnused === true) return false;
|
|
5732
|
-
const arity = confirmedArityForDef(def);
|
|
5733
|
-
if (arity === null) return true;
|
|
5734
|
-
return arity >= 4;
|
|
5735
|
-
}
|
|
5736
|
-
function buildReadsTrivia(def) {
|
|
5737
|
-
if (!def.build) return true;
|
|
5738
|
-
const arity = confirmedArityForDef(def);
|
|
5739
|
-
if (arity === null) return true;
|
|
5740
|
-
return arity >= 5;
|
|
6715
|
+
return true;
|
|
5741
6716
|
}
|
|
5742
|
-
function
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
if (
|
|
5746
|
-
|
|
6717
|
+
function rewrap(w, body) {
|
|
6718
|
+
const d = w._def;
|
|
6719
|
+
let out;
|
|
6720
|
+
if (d.tag === "leaf") {
|
|
6721
|
+
out = d.cstValue === "source" ? sourceLeaf(body, d.fn) : leaf(body, d.fn);
|
|
6722
|
+
if (d.fnSrc !== void 0) out._def.fnSrc = d.fnSrc;
|
|
6723
|
+
} else if (d.tag === "grammar") {
|
|
6724
|
+
out = d.clearTrivia === true ? noTrivia(body) : parser({ trivia: d.triviaParser ?? null }, body);
|
|
6725
|
+
} else return void 0;
|
|
6726
|
+
return sameFields(d, out._def, 0, "parser") ? out : void 0;
|
|
6727
|
+
}
|
|
6728
|
+
function unusedOf(seq) {
|
|
6729
|
+
return seq._def.tag === "sequence" && seq._def.valueUnused === true;
|
|
6730
|
+
}
|
|
6731
|
+
function never(c) {
|
|
6732
|
+
const t2 = c._def.tag;
|
|
6733
|
+
return t2 === "optional" || t2 === "many";
|
|
6734
|
+
}
|
|
6735
|
+
function factorSharedEnds(d) {
|
|
6736
|
+
const arms = d.parsers;
|
|
6737
|
+
if (arms.length < 2) return void 0;
|
|
6738
|
+
if (d.strategy.tag !== "firstMatch" && d.strategy.tag !== "sharedPrefix") return void 0;
|
|
6739
|
+
if (d.gates.some((g) => g !== null) || d.autoNot.some((a) => a !== null)) return void 0;
|
|
6740
|
+
const shapes = [];
|
|
6741
|
+
for (const arm of arms) {
|
|
6742
|
+
const wrappers = [];
|
|
6743
|
+
let c = arm;
|
|
6744
|
+
while ((c._def.tag === "leaf" || c._def.tag === "grammar") && wrappers.length < 4) {
|
|
6745
|
+
wrappers.push(c);
|
|
6746
|
+
c = c._def.parser;
|
|
6747
|
+
}
|
|
6748
|
+
if (c._def.tag !== "sequence" || c._def.parsers.length < 2) return void 0;
|
|
6749
|
+
shapes.push({ wrappers, terms: c._def.parsers, seq: c });
|
|
6750
|
+
}
|
|
6751
|
+
const first = shapes[0];
|
|
6752
|
+
const n = first.terms.length;
|
|
6753
|
+
for (const s of shapes) {
|
|
6754
|
+
if (s.wrappers.length !== first.wrappers.length || s.terms.length !== n) return void 0;
|
|
6755
|
+
if (unusedOf(s.seq) !== unusedOf(first.seq)) return void 0;
|
|
6756
|
+
for (let j = 0; j < s.wrappers.length; j++) {
|
|
6757
|
+
const a = first.wrappers[j]._def;
|
|
6758
|
+
const b = s.wrappers[j]._def;
|
|
6759
|
+
if (a.tag !== b.tag || !sameFields(a, b, 0, "parser")) return void 0;
|
|
6760
|
+
}
|
|
6761
|
+
}
|
|
6762
|
+
let at = -1;
|
|
6763
|
+
for (let i = 0; i < n; i++) {
|
|
6764
|
+
if (shapes.every((s) => sameComb(s.terms[i], first.terms[i], 0))) continue;
|
|
6765
|
+
if (at >= 0) return void 0;
|
|
6766
|
+
at = i;
|
|
6767
|
+
}
|
|
6768
|
+
if (at < 0) return void 0;
|
|
6769
|
+
for (let i = at + 1; i < n; i++) if (!never(first.terms[i])) return void 0;
|
|
6770
|
+
if (arms.some((a) => mayCommitFailure(a))) return void 0;
|
|
6771
|
+
const middle = choice(...shapes.map((s) => s.terms[at]));
|
|
6772
|
+
if (middle._def.tag === "choice" && middle._def.autoNot.some((a) => a !== null)) return void 0;
|
|
6773
|
+
const st = middle._def.tag === "choice" ? middle._def.strategy : void 0;
|
|
6774
|
+
if (st === void 0 || st.tag !== "firstMatch" && st.tag !== "sharedPrefix" && !(st.tag === "literalsLongestFirst" && st.sortedIndices.every((x, i) => x === i))) return void 0;
|
|
6775
|
+
let out = sequence(
|
|
6776
|
+
...[...first.terms.slice(0, at), middle, ...first.terms.slice(at + 1)]
|
|
6777
|
+
);
|
|
6778
|
+
if (unusedOf(first.seq)) {
|
|
6779
|
+
out._def.valueUnused = true;
|
|
6780
|
+
}
|
|
6781
|
+
for (let j = first.wrappers.length - 1; j >= 0 && out !== void 0; j--) out = rewrap(first.wrappers[j], out);
|
|
6782
|
+
return out === void 0 ? void 0 : attempt(out);
|
|
5747
6783
|
}
|
|
5748
6784
|
|
|
5749
6785
|
// src/compiler/fields.ts
|
|
@@ -5860,6 +6896,7 @@ var OP_SCOPE_PLAIN = 41;
|
|
|
5860
6896
|
var OP_LEX_BODY = 42;
|
|
5861
6897
|
var OP_LEX_PROGRAM = 43;
|
|
5862
6898
|
var OP_SOURCE_LEAF = 44;
|
|
6899
|
+
var OP_RGATE = 45;
|
|
5863
6900
|
var OP_DISPATCH = 25;
|
|
5864
6901
|
var OP_ROUTED = 26;
|
|
5865
6902
|
var OP_NAMES = {
|
|
@@ -5879,6 +6916,7 @@ var OP_NAMES = {
|
|
|
5879
6916
|
[OP_PEEK]: "PEEK",
|
|
5880
6917
|
[OP_LEAF]: "LEAF",
|
|
5881
6918
|
[OP_SOURCE_LEAF]: "SOURCE_LEAF",
|
|
6919
|
+
[OP_RGATE]: "RGATE",
|
|
5882
6920
|
[OP_EMPTY]: "EMPTY",
|
|
5883
6921
|
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
5884
6922
|
[OP_RX_TRACK]: "RX_TRACK",
|
|
@@ -5909,71 +6947,6 @@ var OP_NAMES = {
|
|
|
5909
6947
|
[OP_LEX_PROGRAM]: "LEX_PROGRAM"
|
|
5910
6948
|
};
|
|
5911
6949
|
|
|
5912
|
-
// src/combinators/adjacency.ts
|
|
5913
|
-
function adjacencyOf(p) {
|
|
5914
|
-
return p._def.tag === "adjacency" ? p._def : null;
|
|
5915
|
-
}
|
|
5916
|
-
function adjacencyExpected(def) {
|
|
5917
|
-
if (def.polarity === "adjacent") return "adjacent";
|
|
5918
|
-
return def.kinds === void 0 ? "notAdjacent" : `notAdjacent(${def.kinds.join("|")})`;
|
|
5919
|
-
}
|
|
5920
|
-
function holdsAdjacency(input, cur, ctx, def) {
|
|
5921
|
-
return adjacencyHolds(input, cur, ctx, def.polarity === "notAdjacent", def.kinds);
|
|
5922
|
-
}
|
|
5923
|
-
function adjacencyHolds(input, cur, ctx, negated, kinds) {
|
|
5924
|
-
const end = probeTriviaEnd(input, cur, ctx);
|
|
5925
|
-
if (!negated) return end === cur;
|
|
5926
|
-
if (end === cur) return false;
|
|
5927
|
-
if (kinds === void 0) return true;
|
|
5928
|
-
const want = resolveAdjacencyKindMask(ctx.trivia, kinds);
|
|
5929
|
-
const spec = analyzeLabeledTrivia(ctx.trivia);
|
|
5930
|
-
return (triviaKindMaskAt(input, cur, spec, ctx.state) & want) !== 0;
|
|
5931
|
-
}
|
|
5932
|
-
function adjacencyFail(pos, def) {
|
|
5933
|
-
return { ok: false, expected: [adjacencyExpected(def)], span: { start: pos, end: pos } };
|
|
5934
|
-
}
|
|
5935
|
-
var NO_STANDALONE_PARSE = "adjacency assertions are boundary tests: use adjacent()/notAdjacent() as a NON-FIRST term of a sequence(), where the preceding term defines the gap being asserted.";
|
|
5936
|
-
function adjacencyMisuse(polarity) {
|
|
5937
|
-
return new TypeError(`${polarity}(): ${NO_STANDALONE_PARSE}`);
|
|
5938
|
-
}
|
|
5939
|
-
function adjacencyCombinator(def) {
|
|
5940
|
-
const meta = {
|
|
5941
|
-
// Zero-width and never leading (sequence() rejects index 0), so it contributes
|
|
5942
|
-
// no first char. `isZeroWidthAssertion` drops it from a sequence's first-set
|
|
5943
|
-
// rather than letting `any` poison the enclosing choice's dispatch.
|
|
5944
|
-
firstSet: { kind: "any" },
|
|
5945
|
-
canMatchNewline: false,
|
|
5946
|
-
isTrivia: false
|
|
5947
|
-
};
|
|
5948
|
-
return {
|
|
5949
|
-
_tag: "adjacency",
|
|
5950
|
-
_meta: meta,
|
|
5951
|
-
_def: def,
|
|
5952
|
-
parse() {
|
|
5953
|
-
throw adjacencyMisuse(def.polarity);
|
|
5954
|
-
}
|
|
5955
|
-
};
|
|
5956
|
-
}
|
|
5957
|
-
function adjacent() {
|
|
5958
|
-
return adjacencyCombinator({ tag: "adjacency", polarity: "adjacent" });
|
|
5959
|
-
}
|
|
5960
|
-
function notAdjacent(options) {
|
|
5961
|
-
const kinds = options?.kinds;
|
|
5962
|
-
if (kinds !== void 0) {
|
|
5963
|
-
if (!Array.isArray(kinds) || kinds.length === 0) {
|
|
5964
|
-
throw new TypeError("notAdjacent({ kinds }): kinds must be a non-empty array of trivia category names.");
|
|
5965
|
-
}
|
|
5966
|
-
for (const k of kinds) {
|
|
5967
|
-
if (typeof k !== "string" || k.length === 0) {
|
|
5968
|
-
throw new TypeError(`notAdjacent({ kinds }): every kind must be a non-empty string, got ${JSON.stringify(k)}.`);
|
|
5969
|
-
}
|
|
5970
|
-
}
|
|
5971
|
-
}
|
|
5972
|
-
return adjacencyCombinator(
|
|
5973
|
-
kinds === void 0 ? { tag: "adjacency", polarity: "notAdjacent" } : { tag: "adjacency", polarity: "notAdjacent", kinds: [...kinds] }
|
|
5974
|
-
);
|
|
5975
|
-
}
|
|
5976
|
-
|
|
5977
6950
|
// src/combinators/node.ts
|
|
5978
6951
|
function unwrapChild(child) {
|
|
5979
6952
|
return child !== null && typeof child === "object" && child._tag === "leaf" ? child.value : child;
|
|
@@ -6035,7 +7008,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
6035
7008
|
}
|
|
6036
7009
|
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || buildArity !== void 0 || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...buildArity !== void 0 ? { buildArity } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
|
|
6037
7010
|
const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
6038
|
-
const
|
|
7011
|
+
const readsState = build ? buildReadsState(def) : project === void 0;
|
|
6039
7012
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
6040
7013
|
const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
|
|
6041
7014
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
@@ -6076,12 +7049,11 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
6076
7049
|
ctx._triviaCaptureMask = savedMask;
|
|
6077
7050
|
const { children: children2, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
|
|
6078
7051
|
if (!r.ok) return r;
|
|
6079
|
-
const st =
|
|
7052
|
+
const st = readsState ? ctx.state : void 0;
|
|
6080
7053
|
const nodeType = def.type ?? missingInferredType();
|
|
6081
7054
|
const cstOutput = cstOutputHost(ctx.build);
|
|
6082
7055
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
6083
|
-
const
|
|
6084
|
-
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : (cstOutput || !build && project === void 0) && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
7056
|
+
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : (cstOutput || !build && project === void 0) && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, ctx.state, tags) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, ctx.state, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
6085
7057
|
const rawEntry2 = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
|
|
6086
7058
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
6087
7059
|
pushCstChild(ctx, built, rawEntry2);
|
|
@@ -6091,42 +7063,6 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
6091
7063
|
};
|
|
6092
7064
|
}
|
|
6093
7065
|
|
|
6094
|
-
// src/combinators/trivia-boundary.ts
|
|
6095
|
-
var MAX_DEPTH = 12;
|
|
6096
|
-
function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
6097
|
-
if (depth === 0) return true;
|
|
6098
|
-
const d = p._def;
|
|
6099
|
-
switch (d.tag) {
|
|
6100
|
-
// Multi-term forms: the gaps BETWEEN terms are the ambient-trivia positions.
|
|
6101
|
-
case "sequence":
|
|
6102
|
-
return d.parsers.length > 1;
|
|
6103
|
-
case "many":
|
|
6104
|
-
case "oneOrMore":
|
|
6105
|
-
case "sepBy":
|
|
6106
|
-
return true;
|
|
6107
|
-
// Transparent wrappers — they add no position, so ask what they wrap.
|
|
6108
|
-
case "node":
|
|
6109
|
-
case "transform":
|
|
6110
|
-
case "leaf":
|
|
6111
|
-
case "label":
|
|
6112
|
-
case "field":
|
|
6113
|
-
case "token":
|
|
6114
|
-
case "attempt":
|
|
6115
|
-
case "optional":
|
|
6116
|
-
case "expect":
|
|
6117
|
-
case "withCtx":
|
|
6118
|
-
case "recover":
|
|
6119
|
-
case "trivia":
|
|
6120
|
-
return hasOwnTriviaBoundary(d.parser, depth - 1);
|
|
6121
|
-
// An alternation adds no position either, but ONE arm that has one is enough
|
|
6122
|
-
// to make the scope meaningful for this rule.
|
|
6123
|
-
case "choice":
|
|
6124
|
-
return d.parsers.some((a) => hasOwnTriviaBoundary(a, depth - 1));
|
|
6125
|
-
default:
|
|
6126
|
-
return false;
|
|
6127
|
-
}
|
|
6128
|
-
}
|
|
6129
|
-
|
|
6130
7066
|
// src/compiler/direct-projection.ts
|
|
6131
7067
|
function directArrayProjection(fn, fnSrc, arity) {
|
|
6132
7068
|
let source = fnSrc;
|
|
@@ -6347,13 +7283,16 @@ var Encoder = class {
|
|
|
6347
7283
|
}
|
|
6348
7284
|
case "choice": {
|
|
6349
7285
|
for (const arm of node2.arms) if (!emitNode(arm)) return false;
|
|
6350
|
-
const
|
|
6351
|
-
|
|
6352
|
-
|
|
7286
|
+
const final = classifyFinalChoice(
|
|
7287
|
+
node2.parsers,
|
|
7288
|
+
this.refResolver(),
|
|
7289
|
+
node2.cleared ? void 0 : this.activeTrivia
|
|
7290
|
+
);
|
|
7291
|
+
const classes = final.firstSets.map((first, i) => final.nullable[i] ? -1 : this.charClass(first));
|
|
7292
|
+
const exclusive = final.exclusive && classes.every((cls) => cls >= 0);
|
|
7293
|
+
words.push(LEX_NODE_CHOICE, node2.arms.length, exclusive ? 1 : 0, this.expected(node2.expected));
|
|
6353
7294
|
for (let i = 0; i < node2.arms.length; i++) {
|
|
6354
|
-
|
|
6355
|
-
words.push(first.kind === "ranges" ? this.charClass(first) : -1);
|
|
6356
|
-
words.push(this.expected(node2.armExpected[i]));
|
|
7295
|
+
words.push(classes[i], this.expected(node2.armExpected[i]));
|
|
6357
7296
|
}
|
|
6358
7297
|
return true;
|
|
6359
7298
|
}
|
|
@@ -6365,6 +7304,10 @@ var Encoder = class {
|
|
|
6365
7304
|
if (!emitNode(node2.body)) return false;
|
|
6366
7305
|
words.push(LEX_NODE_OPTIONAL);
|
|
6367
7306
|
return true;
|
|
7307
|
+
case "repeat":
|
|
7308
|
+
if (!emitNode(node2.body)) return false;
|
|
7309
|
+
words.push(LEX_NODE_REPEAT, node2.min, node2.max);
|
|
7310
|
+
return true;
|
|
6368
7311
|
}
|
|
6369
7312
|
};
|
|
6370
7313
|
if (!emitNode(body.root)) return void 0;
|
|
@@ -6692,6 +7635,33 @@ var Encoder = class {
|
|
|
6692
7635
|
return childrenOf(def);
|
|
6693
7636
|
}
|
|
6694
7637
|
}
|
|
7638
|
+
/**
|
|
7639
|
+
* THE FIRST-CHARACTER GATE OF AN `optional`, `not` OR `peek` CHILD.
|
|
7640
|
+
*
|
|
7641
|
+
* A non-nullable child cannot match at a character outside its first set, so
|
|
7642
|
+
* the wrapper's outcome there is already decided: `optional` yields `null`,
|
|
7643
|
+
* `not` succeeds, `peek` fails with its own set. The interpreter's `optional`
|
|
7644
|
+
* makes that test itself (`repeat.ts` `startsFirstSet`); the table entered the
|
|
7645
|
+
* child — a rollback mark, the call, the child's own failure — to learn it.
|
|
7646
|
+
*
|
|
7647
|
+
* The gate is an `OP_GATE` row around the child, so every engine runs it
|
|
7648
|
+
* unchanged, a probe or tolerant parse forwards through it as for a node's
|
|
7649
|
+
* gate, and the wrapper's row keeps its layout. The engines test the class
|
|
7650
|
+
* before taking the wrapper's mark. The first set is resolved through
|
|
7651
|
+
* `winners`, the analysis a choice arm's gate uses, so a composed rule's set
|
|
7652
|
+
* is the merged one. A scalar `not` child stays bare: `scalarTerminalNotChild`
|
|
7653
|
+
* already reduces it to one recognizer call.
|
|
7654
|
+
*/
|
|
7655
|
+
lookaheadGate(p, child) {
|
|
7656
|
+
const op = this.code[child];
|
|
7657
|
+
if (op === OP_GATE || op === OP_LIT || op === OP_LIT_CI || op === OP_LIT_TRACK || op === OP_LIT_CI_TRACK || op === OP_RX || op === OP_RX_TRACK) return child;
|
|
7658
|
+
const rr = this.refResolver();
|
|
7659
|
+
if (matchesEmpty(p, /* @__PURE__ */ new Set(), rr)) return child;
|
|
7660
|
+
const cls = this.charClass(firstSetOf(p, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
7661
|
+
if (cls < 0) return child;
|
|
7662
|
+
const e = deriveExpected(p);
|
|
7663
|
+
return this.emit(OP_GATE, cls, child, this.expected(e.length > 0 ? e : [p._tag]));
|
|
7664
|
+
}
|
|
6695
7665
|
/** A first set becomes a char class string, or −1 for `any`. */
|
|
6696
7666
|
charClass(fs) {
|
|
6697
7667
|
if (fs.kind !== "ranges" || fs.ranges.length === 0) return -1;
|
|
@@ -6703,12 +7673,19 @@ var Encoder = class {
|
|
|
6703
7673
|
this.ccIndex.set(spec, i);
|
|
6704
7674
|
return i;
|
|
6705
7675
|
}
|
|
6706
|
-
/**
|
|
6707
|
-
*
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
7676
|
+
/**
|
|
7677
|
+
* The first set a node's or an attempt's fail-fast gate tests. A bare
|
|
7678
|
+
* cross-rule ref resolves through `winners` (a compose OVERRIDE may widen
|
|
7679
|
+
* it). Any other body keeps its construction-time `_meta.firstSet`, except
|
|
7680
|
+
* where that is `any`: under `compose()` a body that reaches a rule of
|
|
7681
|
+
* another piece is built before that rule exists, so its cached set is
|
|
7682
|
+
* `any` and the node got NO gate (jess's `CompoundSelector` was entered at
|
|
7683
|
+
* `{`, `Call` at `}`). The resolved set is the one a choice arm's gate uses,
|
|
7684
|
+
* over the final merged map.
|
|
7685
|
+
*/
|
|
7686
|
+
gateFirstSet(p) {
|
|
7687
|
+
const cached = p._meta.firstSet;
|
|
7688
|
+
return p._def.tag === "lazy" || cached.kind === "any" ? firstSetOf(p, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : cached;
|
|
6712
7689
|
}
|
|
6713
7690
|
/**
|
|
6714
7691
|
* Wrap one choice arm in its `autoNot` checks (`OP_REJECT`).
|
|
@@ -6836,6 +7813,50 @@ var Encoder = class {
|
|
|
6836
7813
|
if (!hasOwnTriviaBoundary(target)) return ip;
|
|
6837
7814
|
return this.emit(OP_SCOPE_PLAIN, this.triviaSlot(amb), ip);
|
|
6838
7815
|
}
|
|
7816
|
+
/**
|
|
7817
|
+
* The `OP_RGATE` operands of a choice arm that opens with `routed()`, or
|
|
7818
|
+
* `undefined`. Through `node()`/scope wrappers and first sequence terms, the
|
|
7819
|
+
* arm's next term after the routed token is found; the gate is that term's
|
|
7820
|
+
* first characters, with the trivia in force at the boundary before it, so
|
|
7821
|
+
* the arm is entered only where it can get past the token. The term must be
|
|
7822
|
+
* unable to match empty or to commit, so a miss is exactly that term failing
|
|
7823
|
+
* at the token's end with its own set.
|
|
7824
|
+
*/
|
|
7825
|
+
routedArmGate(arm) {
|
|
7826
|
+
const walk = (p, trivia2, depth) => {
|
|
7827
|
+
if (depth > 16) return void 0;
|
|
7828
|
+
const d = p._def;
|
|
7829
|
+
switch (d.tag) {
|
|
7830
|
+
case "routed":
|
|
7831
|
+
return "end";
|
|
7832
|
+
case "node":
|
|
7833
|
+
return walk(d.parser, trivia2, depth + 1);
|
|
7834
|
+
case "grammar":
|
|
7835
|
+
return walk(d.parser, d.clearTrivia === true ? void 0 : d.triviaParser ?? trivia2, depth + 1);
|
|
7836
|
+
case "sequence": {
|
|
7837
|
+
const head = d.parsers[0];
|
|
7838
|
+
if (head === void 0) return void 0;
|
|
7839
|
+
const r = walk(head, trivia2, depth + 1);
|
|
7840
|
+
if (r !== "end") return r;
|
|
7841
|
+
const next2 = d.parsers[1];
|
|
7842
|
+
return next2 === void 0 ? "end" : { next: next2, boundary: trivia2 };
|
|
7843
|
+
}
|
|
7844
|
+
default:
|
|
7845
|
+
return void 0;
|
|
7846
|
+
}
|
|
7847
|
+
};
|
|
7848
|
+
const follow = walk(arm, this.activeTrivia, 0);
|
|
7849
|
+
if (follow === void 0 || follow === "end") return void 0;
|
|
7850
|
+
const rr = this.refResolver();
|
|
7851
|
+
const { next, boundary } = follow;
|
|
7852
|
+
if (matchesEmpty(next, /* @__PURE__ */ new Set(), rr) || mayCommitFailure(next, rr, this.commitFailureMemo)) return void 0;
|
|
7853
|
+
const nextTag = next._def.tag;
|
|
7854
|
+
if (nextTag !== "literal" && nextTag !== "regex" && nextTag !== "keywords" && nextTag !== "label") return void 0;
|
|
7855
|
+
const first = firstSetOf(next, /* @__PURE__ */ new Set(), rr, boundary);
|
|
7856
|
+
const cls = this.charClass(boundary === void 0 ? first : union(first, firstSetOf(boundary, /* @__PURE__ */ new Set(), rr)));
|
|
7857
|
+
if (cls < 0) return void 0;
|
|
7858
|
+
return { cls, fx: this.expected(deriveExpected(next)) };
|
|
7859
|
+
}
|
|
6839
7860
|
node(p) {
|
|
6840
7861
|
const lazyRef = p._def.tag === "lazy";
|
|
6841
7862
|
const scopeKey = lazyRef ? this.activeTrivia : void 0;
|
|
@@ -6960,6 +7981,10 @@ var Encoder = class {
|
|
|
6960
7981
|
return head;
|
|
6961
7982
|
}
|
|
6962
7983
|
case "choice": {
|
|
7984
|
+
if (this.plan === void 0) {
|
|
7985
|
+
const factored = factorSharedEnds(d);
|
|
7986
|
+
if (factored !== void 0) return this.node(factored).ip;
|
|
7987
|
+
}
|
|
6963
7988
|
if (d.strategy.tag === "greedyClassify") {
|
|
6964
7989
|
const superIndex = d.strategy.superIndex;
|
|
6965
7990
|
const sup = this.node(d.parsers[superIndex]).ip;
|
|
@@ -6983,9 +8008,12 @@ var Encoder = class {
|
|
|
6983
8008
|
const kids = arms.map((c, k) => {
|
|
6984
8009
|
const src = order[k];
|
|
6985
8010
|
const checks = d.autoNot[src];
|
|
6986
|
-
const inner = this.node(c).ip;
|
|
6987
|
-
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
6988
8011
|
const gate = d.gates[src];
|
|
8012
|
+
const plain2 = (checks === null || checks === void 0 || checks.length === 0) && (gate === null || gate === void 0);
|
|
8013
|
+
const routedGate = plain2 ? this.routedArmGate(c) : void 0;
|
|
8014
|
+
const body = this.node(c).ip;
|
|
8015
|
+
const inner = routedGate === void 0 ? body : this.emit(OP_RGATE, routedGate.cls, body, routedGate.fx);
|
|
8016
|
+
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
6989
8017
|
const gated = gate === null || gate === void 0 ? ip : this.emit(OP_ARMGATE, this.fn(gate, d.gateSrcs?.[src] ?? null), ip, this.expected(deriveExpected(c)));
|
|
6990
8018
|
return this.covWrap(gated, armCovIds?.[src], 1);
|
|
6991
8019
|
});
|
|
@@ -7013,6 +8041,12 @@ var Encoder = class {
|
|
|
7013
8041
|
if (transactionalFirst[i] !== void 0) classes[i] = -1;
|
|
7014
8042
|
}
|
|
7015
8043
|
}
|
|
8044
|
+
if (d.gates.some((g) => g !== null && g !== void 0) && !dispatchIsExclusive(classes, this.cc)) {
|
|
8045
|
+
for (let k = 0; k < classes.length; k++) {
|
|
8046
|
+
const gate = d.gates[order[k]];
|
|
8047
|
+
if (gate !== null && gate !== void 0) classes[k] = -1;
|
|
8048
|
+
}
|
|
8049
|
+
}
|
|
7016
8050
|
const dispIdx = this.disp.length;
|
|
7017
8051
|
this.disp.push(classes);
|
|
7018
8052
|
let rollbackMask = kids.length > 31 ? -1 : 0;
|
|
@@ -7042,7 +8076,7 @@ var Encoder = class {
|
|
|
7042
8076
|
case "oneOrMore": {
|
|
7043
8077
|
const child = this.node(d.parser).ip;
|
|
7044
8078
|
const rr = this.refResolver();
|
|
7045
|
-
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.
|
|
8079
|
+
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.charClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
7046
8080
|
const op = d.valueUnused ? OP_REPV : OP_REP;
|
|
7047
8081
|
const min = d.tag === "many" ? 0 : d.min;
|
|
7048
8082
|
return this.rec ? this.emit(op, child, min, d.max ?? -1, -1, 0, this.expected(deriveExpected(d.parser)), itemClass) : this.emit(op, child, min, d.max ?? -1, -1, 0);
|
|
@@ -7066,7 +8100,7 @@ var Encoder = class {
|
|
|
7066
8100
|
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);
|
|
7067
8101
|
}
|
|
7068
8102
|
case "optional": {
|
|
7069
|
-
const head = this.emit(OP_OPT, this.node(d.parser).ip);
|
|
8103
|
+
const head = this.emit(OP_OPT, this.lookaheadGate(d.parser, this.node(d.parser).ip));
|
|
7070
8104
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(head);
|
|
7071
8105
|
return head;
|
|
7072
8106
|
}
|
|
@@ -7114,8 +8148,8 @@ var Encoder = class {
|
|
|
7114
8148
|
// every CST node, so this is load-bearing, not reflection trivia.
|
|
7115
8149
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
7116
8150
|
);
|
|
7117
|
-
if (matchesEmpty(d.parser)) return body;
|
|
7118
|
-
const fs =
|
|
8151
|
+
if (matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return body;
|
|
8152
|
+
const fs = this.gateFirstSet(d.parser);
|
|
7119
8153
|
if (fs.kind === "any") return body;
|
|
7120
8154
|
const cls = this.charClass(fs);
|
|
7121
8155
|
if (cls < 0) return body;
|
|
@@ -7207,7 +8241,7 @@ var Encoder = class {
|
|
|
7207
8241
|
// other engine reported `['not(literal)']`. It hid because `expected` is a
|
|
7208
8242
|
// TOP-LEVEL field on `RunResult` and is NOT part of the identity digest.
|
|
7209
8243
|
case "not":
|
|
7210
|
-
return this.emit(OP_NOT, this.node(d.parser).ip, this.expected(assertionFailureExpected(false, d.parser._tag)));
|
|
8244
|
+
return this.emit(OP_NOT, this.lookaheadGate(d.parser, this.node(d.parser).ip), this.expected(assertionFailureExpected(false, d.parser._tag)));
|
|
7211
8245
|
case "guard":
|
|
7212
8246
|
return this.emit(OP_GUARD, this.fn(d.predicate, d.predSrc ?? null), this.expected(["gate"]));
|
|
7213
8247
|
case "adjacency":
|
|
@@ -7228,14 +8262,14 @@ var Encoder = class {
|
|
|
7228
8262
|
return this.emit(OP_WITHCTX, this.constant(d.extra), this.node(d.parser).ip);
|
|
7229
8263
|
}
|
|
7230
8264
|
case "peek":
|
|
7231
|
-
return this.emit(OP_PEEK, this.node(d.parser).ip, this.expected(assertionFailureExpected(true, d.parser._tag)));
|
|
8265
|
+
return this.emit(OP_PEEK, this.lookaheadGate(d.parser, this.node(d.parser).ip), this.expected(assertionFailureExpected(true, d.parser._tag)));
|
|
7232
8266
|
// A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
|
|
7233
8267
|
// lowering was correct only for a choice arm.
|
|
7234
8268
|
case "attempt": {
|
|
7235
8269
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
|
|
7236
8270
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
7237
|
-
const fs =
|
|
7238
|
-
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
8271
|
+
const fs = this.gateFirstSet(d.parser);
|
|
8272
|
+
if (fs.kind === "any" || matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return inner;
|
|
7239
8273
|
const cls = this.charClass(fs);
|
|
7240
8274
|
if (cls < 0) return inner;
|
|
7241
8275
|
const e = deriveExpected(d.parser);
|
|
@@ -7303,6 +8337,7 @@ var Encoder = class {
|
|
|
7303
8337
|
const slots = (ip) => {
|
|
7304
8338
|
switch (this.code[ip]) {
|
|
7305
8339
|
case OP_GATE:
|
|
8340
|
+
case OP_RGATE:
|
|
7306
8341
|
return [ip + 2];
|
|
7307
8342
|
case OP_RULE:
|
|
7308
8343
|
case OP_OPT:
|
|
@@ -8530,6 +9565,7 @@ function childSlots(code, ip, out) {
|
|
|
8530
9565
|
case OP_LEAF:
|
|
8531
9566
|
case OP_SOURCE_LEAF:
|
|
8532
9567
|
case OP_ARMGATE:
|
|
9568
|
+
case OP_RGATE:
|
|
8533
9569
|
out.push(code[ip + 2]);
|
|
8534
9570
|
return true;
|
|
8535
9571
|
// `ROUTED fallback` — the operand is an offset or −1. The routed token itself is
|
|
@@ -8613,6 +9649,42 @@ function reachableSites(code, roots) {
|
|
|
8613
9649
|
}
|
|
8614
9650
|
return seen;
|
|
8615
9651
|
}
|
|
9652
|
+
function passCollapse(code, ip, hostCst) {
|
|
9653
|
+
const flags = code[ip + 3];
|
|
9654
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return false;
|
|
9655
|
+
if (flags !== 32 && flags !== 34) return false;
|
|
9656
|
+
let at = code[ip + 2];
|
|
9657
|
+
for (let n = 0; n < 8; n++) {
|
|
9658
|
+
const op = code[at];
|
|
9659
|
+
if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[at + 3] === 0) at = code[at + 2];
|
|
9660
|
+
else if (op === OP_RULE) at = code[at + 1];
|
|
9661
|
+
else break;
|
|
9662
|
+
}
|
|
9663
|
+
return code[at] === OP_NODE;
|
|
9664
|
+
}
|
|
9665
|
+
function gatedPassCollapse(code, ip, hostCst) {
|
|
9666
|
+
const flags = code[ip + 3];
|
|
9667
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return void 0;
|
|
9668
|
+
if (flags !== 32 && flags !== 34) return void 0;
|
|
9669
|
+
const seq = code[ip + 2];
|
|
9670
|
+
if (code[seq] !== OP_SEQ && code[seq] !== OP_SEQV) return void 0;
|
|
9671
|
+
const n = code[seq + 1];
|
|
9672
|
+
if (n < 2) return void 0;
|
|
9673
|
+
const leads = [];
|
|
9674
|
+
const lits = [];
|
|
9675
|
+
for (let i = 0; i < n - 1; i++) {
|
|
9676
|
+
const t2 = code[seq + 2 + i];
|
|
9677
|
+
if (code[t2] !== OP_OPT && code[t2] !== OP_NOT) return void 0;
|
|
9678
|
+
const g = code[t2 + 1];
|
|
9679
|
+
if (code[g] === OP_GATE) leads.push(g);
|
|
9680
|
+
else if (code[g] === OP_LIT) lits.push(code[g + 1]);
|
|
9681
|
+
else return void 0;
|
|
9682
|
+
}
|
|
9683
|
+
const last = code[seq + 2 + n - 1];
|
|
9684
|
+
let at = last;
|
|
9685
|
+
for (let k = 0; k < 8 && (code[at] === OP_GATE || code[at] === OP_RULE); k++) at = code[at] === OP_RULE ? code[at + 1] : code[at + 2];
|
|
9686
|
+
return code[at] === OP_NODE ? { leads, lits, last } : void 0;
|
|
9687
|
+
}
|
|
8616
9688
|
function transfer(code, ip, at, hostCst) {
|
|
8617
9689
|
const op = code[ip];
|
|
8618
9690
|
if (op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN) {
|
|
@@ -8624,14 +9696,18 @@ function transfer(code, ip, at, hostCst) {
|
|
|
8624
9696
|
}
|
|
8625
9697
|
if (op === OP_NODE || op === OP_NODE_TRACK) {
|
|
8626
9698
|
const flags = code[ip + 3];
|
|
9699
|
+
if (passCollapse(code, ip, hostCst)) return at;
|
|
9700
|
+
const gated = gatedPassCollapse(code, ip, hostCst) !== void 0;
|
|
8627
9701
|
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && ((flags & ~128) === 2 || flags === 18 || flags === 34);
|
|
8628
9702
|
if (directChildren) {
|
|
8629
|
-
|
|
9703
|
+
const framed2 = { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
|
|
9704
|
+
return gated ? meet(at, framed2) : framed2;
|
|
8630
9705
|
}
|
|
8631
9706
|
const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
|
|
8632
9707
|
const raw = !hostCst && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags & 2) !== 0 ? RAW_OMIT : RAW_CAPTURE;
|
|
8633
9708
|
if (at.buf && raw === at.raw && cap === at.cap) return at;
|
|
8634
|
-
|
|
9709
|
+
const framed = { tri: at.tri, buf: true, raw, cap };
|
|
9710
|
+
return gated ? meet(at, framed) : framed;
|
|
8635
9711
|
}
|
|
8636
9712
|
if (op === OP_TOKEN) {
|
|
8637
9713
|
if (at.tri === TRI_NONE && !at.buf) return at;
|
|
@@ -8669,6 +9745,40 @@ function computeSiteLabels(code, roots, hostCst) {
|
|
|
8669
9745
|
}
|
|
8670
9746
|
return { at: (ip) => labels.get(ip) ?? TOP };
|
|
8671
9747
|
}
|
|
9748
|
+
function scopeIsIdentity(code, ip, at) {
|
|
9749
|
+
const op = code[ip];
|
|
9750
|
+
if (op !== OP_SCOPE_PLAIN && !(op === OP_SCOPE && code[ip + 3] === 0)) return false;
|
|
9751
|
+
const ki = code[ip + 1];
|
|
9752
|
+
return at.tri === (ki < 0 ? TRI_NONE : ki);
|
|
9753
|
+
}
|
|
9754
|
+
function scanHandoffNeeded(code, ip, labels) {
|
|
9755
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9756
|
+
const stack = [ip];
|
|
9757
|
+
const kids = [];
|
|
9758
|
+
while (stack.length > 0) {
|
|
9759
|
+
const at = stack.pop();
|
|
9760
|
+
if (seen.has(at)) continue;
|
|
9761
|
+
seen.add(at);
|
|
9762
|
+
const l = labels.at(at);
|
|
9763
|
+
if (l.tri === TRI_UNKNOWN) return true;
|
|
9764
|
+
const op = code[at];
|
|
9765
|
+
if (op === OP_SCAN) return true;
|
|
9766
|
+
if (op === OP_TOKEN || op === OP_SCOPE_CAP) continue;
|
|
9767
|
+
if ((op === OP_SCOPE_PLAIN || op === OP_SCOPE) && !(code[at + 1] >= 0 && l.tri === code[at + 1] && (op === OP_SCOPE_PLAIN || code[at + 3] === 0))) continue;
|
|
9768
|
+
kids.length = 0;
|
|
9769
|
+
if (!childSlots(code, at, kids)) return true;
|
|
9770
|
+
for (const c of kids) stack.push(c);
|
|
9771
|
+
}
|
|
9772
|
+
return false;
|
|
9773
|
+
}
|
|
9774
|
+
function triviaLeadRanges(tri, trivia2) {
|
|
9775
|
+
if (tri === TRI_NONE) return [];
|
|
9776
|
+
if (tri < 0) return void 0;
|
|
9777
|
+
const fs = trivia2[tri]?._meta.firstSet;
|
|
9778
|
+
if (fs === void 0) return void 0;
|
|
9779
|
+
if (fs.kind === "empty") return [];
|
|
9780
|
+
return fs.kind === "ranges" && fs.ranges !== void 0 ? fs.ranges : void 0;
|
|
9781
|
+
}
|
|
8672
9782
|
|
|
8673
9783
|
// src/table/scalar-terminal.ts
|
|
8674
9784
|
function makeScalarRecognizer(op, spec) {
|
|
@@ -8706,6 +9816,12 @@ function scalarTerminalNotChild(code, ip) {
|
|
|
8706
9816
|
const op = code[child];
|
|
8707
9817
|
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
8708
9818
|
}
|
|
9819
|
+
function scalarTerminalPeekChild(code, ip) {
|
|
9820
|
+
if (code[ip] !== OP_PEEK) return -1;
|
|
9821
|
+
const child = code[ip + 1];
|
|
9822
|
+
const op = code[child];
|
|
9823
|
+
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
9824
|
+
}
|
|
8709
9825
|
function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, throughPeek = false) {
|
|
8710
9826
|
const seen = /* @__PURE__ */ new Set();
|
|
8711
9827
|
let at = ip;
|
|
@@ -8883,6 +9999,59 @@ function leadingTriviaFieldAt(code, k, ip) {
|
|
|
8883
9999
|
return code[ip] === OP_FIELD && (fieldSpec(k[code[ip + 1]]).bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
8884
10000
|
}
|
|
8885
10001
|
|
|
10002
|
+
// src/table/hold-gap.ts
|
|
10003
|
+
var WRAPPERS = /* @__PURE__ */ new Set([
|
|
10004
|
+
OP_NODE,
|
|
10005
|
+
OP_XFORM,
|
|
10006
|
+
OP_LEAF,
|
|
10007
|
+
OP_SOURCE_LEAF,
|
|
10008
|
+
OP_TOKEN,
|
|
10009
|
+
OP_SCOPE,
|
|
10010
|
+
OP_SCOPE_CAP,
|
|
10011
|
+
OP_SCOPE_PLAIN,
|
|
10012
|
+
OP_FIELD,
|
|
10013
|
+
OP_LABEL,
|
|
10014
|
+
OP_EXPECT,
|
|
10015
|
+
OP_WITHCTX,
|
|
10016
|
+
OP_RULE,
|
|
10017
|
+
OP_ATTEMPT,
|
|
10018
|
+
OP_COV
|
|
10019
|
+
]);
|
|
10020
|
+
function rowNullable(code, k, ip, memo) {
|
|
10021
|
+
const hit = memo.get(ip);
|
|
10022
|
+
if (hit !== void 0) return hit;
|
|
10023
|
+
memo.set(ip, true);
|
|
10024
|
+
const op = code[ip];
|
|
10025
|
+
const kids = [];
|
|
10026
|
+
let out = true;
|
|
10027
|
+
if (op === OP_GATE) out = false;
|
|
10028
|
+
else if (op === OP_LIT || op === OP_LIT_CI) out = k[code[ip + 1]].length === 0;
|
|
10029
|
+
else if (op === OP_RX) {
|
|
10030
|
+
const re = k[code[ip + 1]];
|
|
10031
|
+
out = !(re instanceof RegExp) || regexCanMatchEmpty(re.source);
|
|
10032
|
+
} else if (op === OP_SEQ || op === OP_SEQV || op === OP_SEQX) {
|
|
10033
|
+
childSlots(code, ip, kids);
|
|
10034
|
+
out = kids.every((c) => rowNullable(code, k, c, memo));
|
|
10035
|
+
} else if (op === OP_CHOICE) {
|
|
10036
|
+
childSlots(code, ip, kids);
|
|
10037
|
+
out = kids.length === 0 || kids.some((c) => rowNullable(code, k, c, memo));
|
|
10038
|
+
} else if (op === OP_REP || op === OP_REPV) {
|
|
10039
|
+
out = code[ip + 2] === 0 || rowNullable(code, k, code[ip + 1], memo);
|
|
10040
|
+
} else if (WRAPPERS.has(op)) {
|
|
10041
|
+
if (childSlots(code, ip, kids) && kids.length === 1) out = rowNullable(code, k, kids[0], memo);
|
|
10042
|
+
}
|
|
10043
|
+
memo.set(ip, out);
|
|
10044
|
+
return out;
|
|
10045
|
+
}
|
|
10046
|
+
function holdsGap(code, k, base, n, i, memo) {
|
|
10047
|
+
if (i < 1 || i + 1 >= n) return false;
|
|
10048
|
+
const term = code[base + i];
|
|
10049
|
+
if (code[term] !== OP_NOT && code[term] !== OP_PEEK) return false;
|
|
10050
|
+
const next = code[base + i + 1];
|
|
10051
|
+
if (code[next] === OP_ADJ || leadingTriviaFieldAt(code, k, next)) return false;
|
|
10052
|
+
return !rowNullable(code, k, next, memo);
|
|
10053
|
+
}
|
|
10054
|
+
|
|
8886
10055
|
// src/table/emit-assembly.ts
|
|
8887
10056
|
var Unemittable = class extends Error {
|
|
8888
10057
|
construct;
|
|
@@ -8960,7 +10129,13 @@ var EMITTED_PARAMS = [
|
|
|
8960
10129
|
// Appended for trivia-attributing fields (`field(…, { leadingTrivia })`);
|
|
8961
10130
|
// old factories ignore them.
|
|
8962
10131
|
"LEAD",
|
|
8963
|
-
"triviaFieldCapture"
|
|
10132
|
+
"triviaFieldCapture",
|
|
10133
|
+
// Appended for the deferred-commit trivia skip (`trivia-gap.ts`); old
|
|
10134
|
+
// factories ignore it.
|
|
10135
|
+
"skipDeferredTrivia",
|
|
10136
|
+
// Appended for the pass-through collapse (`run-support.ts`); old factories
|
|
10137
|
+
// ignore it.
|
|
10138
|
+
"collapseEmpty"
|
|
8964
10139
|
];
|
|
8965
10140
|
var RUNTIME_PRELUDE = `
|
|
8966
10141
|
let _pfScan=null
|
|
@@ -8981,7 +10156,7 @@ function _skipTrivia(input,cur,ctx){
|
|
|
8981
10156
|
const s=_pfScan
|
|
8982
10157
|
if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
|
|
8983
10158
|
if(s!==null)return skipTriviaScanned(s,input,cur,ctx)
|
|
8984
|
-
if(needsDeferredTriviaCommit(ctx))return
|
|
10159
|
+
if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
|
|
8985
10160
|
return advanceTrivia(input,cur,ctx)
|
|
8986
10161
|
}
|
|
8987
10162
|
function _pushLeaf(ctx,value,s,e){pushCstLeaf(ctx,{_tag:'leaf',value,span:{start:s,end:e}})}
|
|
@@ -9157,6 +10332,24 @@ ${fast}
|
|
|
9157
10332
|
${scanned}
|
|
9158
10333
|
}`;
|
|
9159
10334
|
}
|
|
10335
|
+
function emitHoldTerm(callee, dst, t2, l, skip) {
|
|
10336
|
+
const fast = `const ${t2}v=${callee}(input,cur,ctx)
|
|
10337
|
+
if(${t2}v===FAIL)return FAIL
|
|
10338
|
+
${dst}=${t2}v
|
|
10339
|
+
cur=EC.e`;
|
|
10340
|
+
if (l.tri === TRI_NONE) return fast;
|
|
10341
|
+
const held = `const ${t2}s=${skip}(input,cur,ctx)
|
|
10342
|
+
const ${t2}v=${callee}(input,${t2}s,ctx)
|
|
10343
|
+
if(${t2}v===FAIL)return FAIL
|
|
10344
|
+
${dst}=${t2}v
|
|
10345
|
+
cur=${t2}s`;
|
|
10346
|
+
if (l.tri !== TRI_UNKNOWN) return held;
|
|
10347
|
+
return `if(ctx.trivia===undefined){
|
|
10348
|
+
${fast}
|
|
10349
|
+
}else{
|
|
10350
|
+
${held}
|
|
10351
|
+
}`;
|
|
10352
|
+
}
|
|
9160
10353
|
function leadSkip(hasTrivia, leadTrivia, skip) {
|
|
9161
10354
|
if (hasTrivia === "false") return "{}";
|
|
9162
10355
|
const call = `itemStart=${skip}(input,itemStart,ctx)`;
|
|
@@ -9188,7 +10381,7 @@ function rebuildPools(cc, fx, disp, plan) {
|
|
|
9188
10381
|
})
|
|
9189
10382
|
};
|
|
9190
10383
|
}
|
|
9191
|
-
function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false) {
|
|
10384
|
+
function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false, select) {
|
|
9192
10385
|
const { code, k, fx, disp, dsp, triviaLabelled } = t2;
|
|
9193
10386
|
const swapLegal = !cfg.trackLines;
|
|
9194
10387
|
const hostCst = cfg.hostCst;
|
|
@@ -9198,6 +10391,7 @@ function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
9198
10391
|
const reachable = [...reachableSites(code, roots)];
|
|
9199
10392
|
const labels = computeSiteLabels(code, roots, hostCst);
|
|
9200
10393
|
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
10394
|
+
const nullable2 = /* @__PURE__ */ new Map();
|
|
9201
10395
|
const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
|
|
9202
10396
|
const largeChoiceLiteralFamilies = /* @__PURE__ */ new Map();
|
|
9203
10397
|
const largeChoiceScalarSequences = /* @__PURE__ */ new Map();
|
|
@@ -9287,6 +10481,8 @@ function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
9287
10481
|
};
|
|
9288
10482
|
const bodies = [];
|
|
9289
10483
|
const byIp = /* @__PURE__ */ new Map();
|
|
10484
|
+
const externals = [];
|
|
10485
|
+
const siteBytes = /* @__PURE__ */ new Map();
|
|
9290
10486
|
const reached = /* @__PURE__ */ new Set();
|
|
9291
10487
|
const prelude = [];
|
|
9292
10488
|
const skipDefs = [];
|
|
@@ -9422,6 +10618,18 @@ return 1
|
|
|
9422
10618
|
tokenDecisionRefs.set(dispatchIp, made);
|
|
9423
10619
|
return made;
|
|
9424
10620
|
}
|
|
10621
|
+
function gateMissTest(gip) {
|
|
10622
|
+
const resolved = t2.cc[code[gip + 1]];
|
|
10623
|
+
const ci = classes.push([resolved]) - 1;
|
|
10624
|
+
classPlan.push([code[gip + 1]]);
|
|
10625
|
+
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
10626
|
+
return isAsciiOnlyClass(resolved) ? `${cls}.ascii[input.charCodeAt(pos)]!==1` : `!classHas(${cls},lead(input,pos))`;
|
|
10627
|
+
}
|
|
10628
|
+
function lookaheadMiss(child, miss) {
|
|
10629
|
+
if (code[child] !== OP_GATE || cfg.tolerant || cfg.probe) return "";
|
|
10630
|
+
return `if(${gateMissTest(child)}){${miss}}
|
|
10631
|
+
`;
|
|
10632
|
+
}
|
|
9425
10633
|
function skipFor(l) {
|
|
9426
10634
|
if (l.tri < 0) return "_skipTrivia";
|
|
9427
10635
|
const ki = l.tri;
|
|
@@ -9432,8 +10640,8 @@ return 1
|
|
|
9432
10640
|
const nm = `_sk${skipPool.size}`;
|
|
9433
10641
|
skipPool.set(key, nm);
|
|
9434
10642
|
if (!hasScan) {
|
|
9435
|
-
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return
|
|
9436
|
-
if(needsDeferredTriviaCommit(ctx))return
|
|
10643
|
+
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return skipDeferredTrivia(input,cur,ctx)}` : `function ${nm}(input,cur,ctx){
|
|
10644
|
+
if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
|
|
9437
10645
|
return advanceTrivia(input,cur,ctx)}`);
|
|
9438
10646
|
return nm;
|
|
9439
10647
|
}
|
|
@@ -9478,9 +10686,17 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
9478
10686
|
const target = resolveAlias(ip);
|
|
9479
10687
|
const done = byIp.get(target);
|
|
9480
10688
|
if (done !== void 0) return done;
|
|
10689
|
+
if (select !== void 0 && !select.has(target)) {
|
|
10690
|
+
const ext = `_px${target}`;
|
|
10691
|
+
byIp.set(target, ext);
|
|
10692
|
+
externals.push(target);
|
|
10693
|
+
return ext;
|
|
10694
|
+
}
|
|
9481
10695
|
const fname = `_pf${target}`;
|
|
9482
10696
|
byIp.set(target, fname);
|
|
9483
|
-
|
|
10697
|
+
const body = lower(target, fname);
|
|
10698
|
+
siteBytes.set(target, body.length);
|
|
10699
|
+
bodies.push(body);
|
|
9484
10700
|
return fname;
|
|
9485
10701
|
}
|
|
9486
10702
|
function resolveAlias(ip) {
|
|
@@ -9500,9 +10716,7 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
9500
10716
|
const op = code[ip];
|
|
9501
10717
|
if (op === OP_GATE && (cfg.tolerant || cfg.probe)) return code[ip + 2];
|
|
9502
10718
|
if (op === OP_RULE) return code[ip + 1];
|
|
9503
|
-
if ((
|
|
9504
|
-
return code[ip + 2];
|
|
9505
|
-
}
|
|
10719
|
+
if (scopeIsIdentity(code, ip, labels.at(ip))) return code[ip + 2];
|
|
9506
10720
|
return void 0;
|
|
9507
10721
|
}
|
|
9508
10722
|
function lower(ip, fname) {
|
|
@@ -9620,14 +10834,44 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
9620
10834
|
return `${head}EC.e=pos;return ''}`;
|
|
9621
10835
|
case OP_GATE: {
|
|
9622
10836
|
const child = link(code[ip + 2]);
|
|
10837
|
+
const xf = fxRef(code[ip + 3]);
|
|
10838
|
+
return `${head}
|
|
10839
|
+
if(${gateMissTest(ip)}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
10840
|
+
return ${child}(input,pos,ctx)
|
|
10841
|
+
}`;
|
|
10842
|
+
}
|
|
10843
|
+
case OP_RGATE: {
|
|
10844
|
+
const child = link(code[ip + 2]);
|
|
10845
|
+
if (cfg.tolerant || cfg.probe) return `${head}
|
|
10846
|
+
return ${child}(input,pos,ctx)
|
|
10847
|
+
}`;
|
|
9623
10848
|
const resolved = t2.cc[code[ip + 1]];
|
|
9624
10849
|
const ci = classes.push([resolved]) - 1;
|
|
9625
10850
|
classPlan.push([code[ip + 1]]);
|
|
9626
10851
|
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
9627
10852
|
const xf = fxRef(code[ip + 3]);
|
|
9628
10853
|
return `${head}
|
|
9629
|
-
|
|
10854
|
+
const it=ctx._routed
|
|
10855
|
+
if(it!==undefined&&it.span.start===pos&&!classHas(${cls},lead(input,it.span.end))){ctx._fe=it.span.end;ctx._fx=${xf};return FAIL}
|
|
10856
|
+
return ${child}(input,pos,ctx)
|
|
10857
|
+
}`;
|
|
10858
|
+
}
|
|
10859
|
+
case OP_ARMGATE: {
|
|
10860
|
+
const pred = fnRef(code[ip + 1]);
|
|
10861
|
+
const child = link(code[ip + 2]);
|
|
10862
|
+
const xf = fxRef(code[ip + 3]);
|
|
10863
|
+
return `${head}
|
|
10864
|
+
if(!${pred}(ctx.state)){ctx._fc=false;ctx._fe=-1;ctx._fx=${xf};return FAIL}
|
|
9630
10865
|
return ${child}(input,pos,ctx)
|
|
10866
|
+
}`;
|
|
10867
|
+
}
|
|
10868
|
+
case OP_WITHCTX: {
|
|
10869
|
+
const ki = code[ip + 1];
|
|
10870
|
+
const child = link(code[ip + 2]);
|
|
10871
|
+
return `${head}
|
|
10872
|
+
const saved=ctx.state
|
|
10873
|
+
ctx.state=${ki < 0 ? `${fnRef(~ki)}(saved)` : kRef(ki)}
|
|
10874
|
+
try{return ${child}(input,pos,ctx)}finally{ctx.state=saved}
|
|
9631
10875
|
}`;
|
|
9632
10876
|
}
|
|
9633
10877
|
case OP_XFORM: {
|
|
@@ -9883,24 +11127,34 @@ return FAIL
|
|
|
9883
11127
|
const xf = fxRef(code[ip + 2]);
|
|
9884
11128
|
const p = tmp();
|
|
9885
11129
|
return `${head}
|
|
9886
|
-
${emitMark(p, L.buf, L.raw, sinks)}
|
|
9887
|
-
const v=${child}(input,pos,ctx)
|
|
11130
|
+
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${emitMark(p, L.buf, L.raw, sinks)}
|
|
11131
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
9888
11132
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
9889
|
-
if(v===FAIL){EC.e=pos;return null}
|
|
11133
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){EC.e=pos;return null}
|
|
9890
11134
|
ctx._fe=pos
|
|
9891
11135
|
ctx._fx=${xf}
|
|
9892
11136
|
return FAIL
|
|
9893
11137
|
}`;
|
|
9894
11138
|
}
|
|
9895
11139
|
case OP_PEEK: {
|
|
11140
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
11141
|
+
if (scalarChild >= 0) {
|
|
11142
|
+
const recognize = recognizerRef(code[scalarChild + 1]);
|
|
11143
|
+
const xf2 = fxRef(code[ip + 2]);
|
|
11144
|
+
return `${head}
|
|
11145
|
+
if(${recognize}(input,pos)<0){ctx._fe=pos;ctx._fx=${xf2};return FAIL}
|
|
11146
|
+
EC.e=pos
|
|
11147
|
+
return null
|
|
11148
|
+
}`;
|
|
11149
|
+
}
|
|
9896
11150
|
const child = link(code[ip + 1]);
|
|
9897
11151
|
const xf = fxRef(code[ip + 2]);
|
|
9898
11152
|
const p = tmp();
|
|
9899
11153
|
return `${head}
|
|
9900
|
-
${emitMark(p, L.buf, L.raw, sinks)}
|
|
9901
|
-
const v=${child}(input,pos,ctx)
|
|
11154
|
+
${lookaheadMiss(code[ip + 1], `ctx._fe=pos;ctx._fx=${xf};return FAIL`)}${emitMark(p, L.buf, L.raw, sinks)}
|
|
11155
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
9902
11156
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
9903
|
-
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
11157
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
9904
11158
|
EC.e=pos
|
|
9905
11159
|
return null
|
|
9906
11160
|
}`;
|
|
@@ -9910,7 +11164,7 @@ return null
|
|
|
9910
11164
|
const clean = !REC && failureRollbackClean(prog, ip);
|
|
9911
11165
|
const p = tmp();
|
|
9912
11166
|
return `${head}
|
|
9913
|
-
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
11167
|
+
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
9914
11168
|
ctx._fc=false
|
|
9915
11169
|
const v=${child}(input,pos,ctx)
|
|
9916
11170
|
if(v===FAIL){
|
|
@@ -9971,7 +11225,7 @@ return v
|
|
|
9971
11225
|
);
|
|
9972
11226
|
} else {
|
|
9973
11227
|
const callee = leadingTriviaFieldAt(code, k, childIp) ? `(LEAD.at=cur,${kids[i]})` : kids[i];
|
|
9974
|
-
parts.push(emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
11228
|
+
parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
9975
11229
|
}
|
|
9976
11230
|
names.push(vn);
|
|
9977
11231
|
}
|
|
@@ -9991,7 +11245,7 @@ return v
|
|
|
9991
11245
|
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
9992
11246
|
const hiArr = table.hi;
|
|
9993
11247
|
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
9994
|
-
const directAscii =
|
|
11248
|
+
const directAscii = table.hi.length === 0;
|
|
9995
11249
|
return `${head}
|
|
9996
11250
|
const c=${directAscii ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
9997
11251
|
let arm=-1
|
|
@@ -10018,7 +11272,7 @@ return FAIL
|
|
|
10018
11272
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
10019
11273
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
10020
11274
|
const maskable = n <= 32;
|
|
10021
|
-
const directAsciiMask =
|
|
11275
|
+
const directAsciiMask = maskable && gates.every(isAsciiOnlyClass);
|
|
10022
11276
|
const gateRefs = directAsciiMask ? [] : Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
10023
11277
|
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
10024
11278
|
const pretests = Array.from({ length: n }, (_, i) => {
|
|
@@ -10060,7 +11314,7 @@ return FAIL
|
|
|
10060
11314
|
if (choiceCannotCommit(prog, ip) && !startFailureExact) {
|
|
10061
11315
|
const deepAt = Array.from({ length: n }, () => tmp());
|
|
10062
11316
|
const deepFx = Array.from({ length: n }, () => tmp());
|
|
10063
|
-
const
|
|
11317
|
+
const remember2 = (i, at, expectedSet) => `${deepAt[i]}=${at};${deepFx[i]}=${expectedSet}`;
|
|
10064
11318
|
const lazyArms = (ascii) => arms.map((arm, i) => {
|
|
10065
11319
|
const pretest = pretests[i];
|
|
10066
11320
|
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
@@ -10072,13 +11326,13 @@ return FAIL
|
|
|
10072
11326
|
if(${decision}===0){
|
|
10073
11327
|
ctx._fc=false
|
|
10074
11328
|
{const at=_pfTokEnd
|
|
10075
|
-
${
|
|
11329
|
+
${remember2(i, "at", pretest.token.expected)}}
|
|
10076
11330
|
}`;
|
|
10077
11331
|
const sequenceMiss = pretest?.sequence === void 0 ? "" : `
|
|
10078
11332
|
else if(${ascii ? `(bits&${1 << i})!==0&&` : ""}${decision}<0){
|
|
10079
11333
|
ctx._fc=false
|
|
10080
11334
|
{const at=_pfSeqEnd
|
|
10081
|
-
${
|
|
11335
|
+
${remember2(i, "at", pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("") + pretest.sequence.expected.at(-1))}}
|
|
10082
11336
|
}`;
|
|
10083
11337
|
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
10084
11338
|
`}if(${gate}){
|
|
@@ -10086,7 +11340,7 @@ ctx._fc=false
|
|
|
10086
11340
|
{const v=${arm}(input,pos,ctx)
|
|
10087
11341
|
if(v!==FAIL)return v}
|
|
10088
11342
|
{const at=ctx._fe??pos
|
|
10089
|
-
${
|
|
11343
|
+
${remember2(i, "at", "ctx._fx")}}
|
|
10090
11344
|
${rollbackFor(i)}
|
|
10091
11345
|
}${routeMiss}${sequenceMiss}`;
|
|
10092
11346
|
}).join("\n");
|
|
@@ -10199,7 +11453,7 @@ const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
|
10199
11453
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
10200
11454
|
${startFailureExact ? "" : "let prev=0"}
|
|
10201
11455
|
${maskArms}
|
|
10202
|
-
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${n},prev,acc)`}
|
|
11456
|
+
${startFailureExact ? "" : `if(best===pos&&prev!==0)acc=${catchName}(${n},prev,acc)`}
|
|
10203
11457
|
ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
|
|
10204
11458
|
return FAIL
|
|
10205
11459
|
}
|
|
@@ -10298,7 +11552,7 @@ return [key,v]
|
|
|
10298
11552
|
const ci = classes.push([resolved]) - 1;
|
|
10299
11553
|
classPlan.push([itemClassIndex]);
|
|
10300
11554
|
itemCls = hoist("ri", `CLS[${ci}][0]`);
|
|
10301
|
-
itemAscii =
|
|
11555
|
+
itemAscii = isAsciiOnlyClass(resolved);
|
|
10302
11556
|
}
|
|
10303
11557
|
}
|
|
10304
11558
|
const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
|
|
@@ -10454,6 +11708,26 @@ return nd
|
|
|
10454
11708
|
const trailingTrivia = (flags & 128) !== 0;
|
|
10455
11709
|
const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
|
|
10456
11710
|
const leanFlags = flags & ~128;
|
|
11711
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
11712
|
+
return `${head}
|
|
11713
|
+
const v=${child}(input,pos,ctx)
|
|
11714
|
+
if(v!==undefined)return v
|
|
11715
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
11716
|
+
}`;
|
|
11717
|
+
}
|
|
11718
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
11719
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(labels.at(code[ip + 2]).tri, t2.trivia);
|
|
11720
|
+
const gp = gated !== void 0 && triviaLead !== void 0 && triviaLead.length <= 16 ? `const gc=lead(input,pos)
|
|
11721
|
+
if(!(${[
|
|
11722
|
+
...gated.leads.map((g) => `!(${gateMissTest(g)})`),
|
|
11723
|
+
...gated.lits.map((i) => `gc===${k[i].codePointAt(0)}`),
|
|
11724
|
+
...triviaLead.map((r) => r.lo === r.hi ? `gc===${r.lo}` : `(gc>=${r.lo}&&gc<=${r.hi})`)
|
|
11725
|
+
].join("||") || "false"})){
|
|
11726
|
+
const gv=${link(gated.last)}(input,pos,ctx)
|
|
11727
|
+
if(gv!==undefined)return gv
|
|
11728
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
11729
|
+
}
|
|
11730
|
+
` : "";
|
|
10457
11731
|
if (!hostCst && !tracked && build !== void 0 && proj < 0 && (leanFlags === 2 || (flags === 18 || flags === 34))) {
|
|
10458
11732
|
const fields = flags === 18;
|
|
10459
11733
|
const collapseChildren = flags === 34;
|
|
@@ -10488,7 +11762,7 @@ sCh.push(nd)
|
|
|
10488
11762
|
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
10489
11763
|
}`;
|
|
10490
11764
|
return `${head}
|
|
10491
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
11765
|
+
${gp}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
10492
11766
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf,sFields=ctx._fields
|
|
10493
11767
|
const flat=[]
|
|
10494
11768
|
ctx._cstBuf=undefined
|
|
@@ -10524,7 +11798,7 @@ return nd
|
|
|
10524
11798
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
10525
11799
|
const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
|
|
10526
11800
|
const ty = q(type);
|
|
10527
|
-
const stArg =
|
|
11801
|
+
const stArg = "ctx.state";
|
|
10528
11802
|
const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
|
|
10529
11803
|
let value;
|
|
10530
11804
|
if (proj >= 0) {
|
|
@@ -10563,7 +11837,7 @@ const hostKids=kids
|
|
|
10563
11837
|
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
10564
11838
|
const tlog=buf.tl??EMPTY_TLOG`;
|
|
10565
11839
|
return `${head}
|
|
10566
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
11840
|
+
${!hostCst && !tracked ? gp : ""}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
10567
11841
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
10568
11842
|
${openCapture}
|
|
10569
11843
|
ctx.captureTrivia=${captureWide}
|
|
@@ -10585,7 +11859,7 @@ ctx.captureTrivia=sCap
|
|
|
10585
11859
|
if(v===FAIL)return FAIL
|
|
10586
11860
|
const end=EC.e
|
|
10587
11861
|
const span=${tracked ? "spanLines(ctx,pos,end)" : "{start:pos,end}"}
|
|
10588
|
-
const st=${readsState ? "
|
|
11862
|
+
const st=${readsState ? "ctx.state" : "undefined"}
|
|
10589
11863
|
let nd
|
|
10590
11864
|
${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]
|
|
10591
11865
|
else ` : ""}{${value}}
|
|
@@ -10598,21 +11872,57 @@ return nd
|
|
|
10598
11872
|
throw new Unemittable(`OP_${OP_NAMES[op] ?? String(op)}`);
|
|
10599
11873
|
}
|
|
10600
11874
|
}
|
|
11875
|
+
const served = (ip) => select === void 0 || select.has(resolveAlias(ip));
|
|
10601
11876
|
const ruleEntries = [];
|
|
10602
11877
|
for (const [rname, entryIp] of Object.entries(prog.rules)) {
|
|
11878
|
+
if (!served(entryIp)) continue;
|
|
10603
11879
|
const target = link(entryIp);
|
|
10604
11880
|
const rn = `_r_${rname.replace(/[^A-Za-z0-9_$]/g, "_")}`;
|
|
10605
11881
|
bodies.push(`const ${rn}=${target}`);
|
|
10606
11882
|
ruleEntries.push(`${q(rname)}:${rn}`);
|
|
10607
11883
|
}
|
|
10608
11884
|
const extra = [];
|
|
10609
|
-
|
|
11885
|
+
const exported = /* @__PURE__ */ new Set();
|
|
11886
|
+
for (const ip of extraIps) {
|
|
11887
|
+
if (!served(ip)) continue;
|
|
11888
|
+
exported.add(ip);
|
|
11889
|
+
extra.push(`${ip}:${link(ip)}`);
|
|
11890
|
+
}
|
|
11891
|
+
if (select !== void 0) {
|
|
11892
|
+
const kids = [];
|
|
11893
|
+
for (const ip of reachable) {
|
|
11894
|
+
if (select.has(resolveAlias(ip))) continue;
|
|
11895
|
+
kids.length = 0;
|
|
11896
|
+
childSlots(code, ip, kids);
|
|
11897
|
+
for (const kid of kids) {
|
|
11898
|
+
const target = resolveAlias(kid);
|
|
11899
|
+
if (!select.has(target) || exported.has(target)) continue;
|
|
11900
|
+
exported.add(target);
|
|
11901
|
+
extra.push(`${target}:${link(target)}`);
|
|
11902
|
+
}
|
|
11903
|
+
}
|
|
11904
|
+
}
|
|
11905
|
+
const hybrid = select === void 0 ? "" : `,
|
|
11906
|
+
ext:[${externals.join(",")}],
|
|
11907
|
+
bind:function(xs,ps){_xScan=xs
|
|
11908
|
+
${externals.map((ip, i) => `_xp${ip}=ps[${i}]`).join("\n")}},
|
|
11909
|
+
scan:function(s){const o=_pfScan;_pfScan=s;return o}`;
|
|
11910
|
+
const scannerFor = (ip) => {
|
|
11911
|
+
const ki = labels.at(ip).tri;
|
|
11912
|
+
if (ki === TRI_UNKNOWN) return "_pfScan";
|
|
11913
|
+
if (ki === TRI_NONE) return "null";
|
|
11914
|
+
return swapLegal && !triviaLabelled[ki] && t2.triviaScan[ki] != null ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
11915
|
+
};
|
|
11916
|
+
const externalDefs = select === void 0 ? "" : `let _xScan
|
|
11917
|
+
${externals.map((ip) => `let _xp${ip}
|
|
11918
|
+
function _px${ip}(input,pos,ctx){const o=_xScan(${scannerFor(ip)});const v=_xp${ip}(input,pos,ctx);_xScan(o);return v}`).join("\n")}
|
|
11919
|
+
`;
|
|
10610
11920
|
const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
|
|
10611
11921
|
${prelude.join("\n")}
|
|
10612
11922
|
${skipDefs.join("\n")}
|
|
10613
11923
|
${choiceDefs.join("\n")}
|
|
10614
11924
|
${bodies.join("\n")}
|
|
10615
|
-
function _begin(ctx){
|
|
11925
|
+
${externalDefs}function _begin(ctx){
|
|
10616
11926
|
const host=ctx.build
|
|
10617
11927
|
if(_pfDepth>0)_pfFrames.push([_pfScan,_pfHost,EC.e])
|
|
10618
11928
|
_pfDepth++
|
|
@@ -10639,7 +11949,7 @@ pieces:{${ruleEntries.join(",")}},
|
|
|
10639
11949
|
byIp:{${extra.join(",")}},
|
|
10640
11950
|
end:function(){return EC.e},
|
|
10641
11951
|
begin:_begin,
|
|
10642
|
-
finish:_finish
|
|
11952
|
+
finish:_finish${hybrid}
|
|
10643
11953
|
}`;
|
|
10644
11954
|
return {
|
|
10645
11955
|
source,
|
|
@@ -10647,6 +11957,7 @@ finish:_finish
|
|
|
10647
11957
|
masks,
|
|
10648
11958
|
classes,
|
|
10649
11959
|
armExpected,
|
|
11960
|
+
siteBytes,
|
|
10650
11961
|
plan: { classes: classPlan, armExpected: armExpectedPlan, masks: maskPlan }
|
|
10651
11962
|
};
|
|
10652
11963
|
}
|
|
@@ -10897,157 +12208,27 @@ function literal(value, opts = {}) {
|
|
|
10897
12208
|
return { ok: true, value, span };
|
|
10898
12209
|
}
|
|
10899
12210
|
return failAt(ctx, expected, pos);
|
|
10900
|
-
};
|
|
10901
|
-
})() : function parse3(input, pos, ctx) {
|
|
10902
|
-
const end = pos + value.length;
|
|
10903
|
-
if (end > input.length) {
|
|
10904
|
-
return failAt(ctx, expected, pos);
|
|
10905
|
-
}
|
|
10906
|
-
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
10907
|
-
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
10908
|
-
const span = { start: pos, end };
|
|
10909
|
-
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
|
|
10910
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
10911
|
-
return { ok: true, value: matchedValue, span };
|
|
10912
|
-
}
|
|
10913
|
-
return failAt(ctx, expected, pos);
|
|
10914
|
-
};
|
|
10915
|
-
return {
|
|
10916
|
-
_tag: "literal",
|
|
10917
|
-
_meta: meta,
|
|
10918
|
-
_def: { tag: "literal", value, caseInsensitive },
|
|
10919
|
-
_parseScalar: parseScalar,
|
|
10920
|
-
parse: parse2
|
|
10921
|
-
};
|
|
10922
|
-
}
|
|
10923
|
-
|
|
10924
|
-
// src/combinators/sequence.ts
|
|
10925
|
-
function sequence(...parsers) {
|
|
10926
|
-
let adjacency = null;
|
|
10927
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
10928
|
-
const a = adjacencyOf(parsers[i]);
|
|
10929
|
-
if (a === null) continue;
|
|
10930
|
-
if (i === 0) {
|
|
10931
|
-
throw new TypeError(
|
|
10932
|
-
`sequence(): ${a.polarity}() cannot be the FIRST term \u2014 an adjacency assertion tests the gap after the PRECEDING term. Put a concrete term first.`
|
|
10933
|
-
);
|
|
10934
|
-
}
|
|
10935
|
-
;
|
|
10936
|
-
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
10937
|
-
}
|
|
10938
|
-
const hasAdjacency = adjacency !== null;
|
|
10939
|
-
let leading = null;
|
|
10940
|
-
for (let i = 1; i < parsers.length; i++) {
|
|
10941
|
-
if (leadsTrivia(parsers[i])) (leading ??= Array.from({ length: parsers.length }, () => false))[i] = true;
|
|
10942
|
-
}
|
|
10943
|
-
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
10944
|
-
const meta = {
|
|
10945
|
-
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
10946
|
-
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
10947
|
-
firstSet: sequenceFirstSet(parsers),
|
|
10948
|
-
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
10949
|
-
isTrivia: false
|
|
10950
|
-
};
|
|
10951
|
-
const def = { tag: "sequence", parsers };
|
|
10952
|
-
const scalarParsers = parsers.map(scalarOf);
|
|
10953
|
-
const parseScalar = (input, pos, ctx) => {
|
|
10954
|
-
let cur = pos;
|
|
10955
|
-
if (strictArity !== 0) {
|
|
10956
|
-
cur = scalarParsers[0](input, cur, ctx);
|
|
10957
|
-
if (cur < 0) return cur;
|
|
10958
|
-
const first = ctx._sv;
|
|
10959
|
-
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
10960
|
-
cur = scalarParsers[1](input, cur, ctx);
|
|
10961
|
-
if (cur < 0) return cur;
|
|
10962
|
-
const second = ctx._sv;
|
|
10963
|
-
if (strictArity === 2) {
|
|
10964
|
-
ctx._sv = def.valueUnused ? void 0 : [first, second];
|
|
10965
|
-
return cur;
|
|
10966
|
-
}
|
|
10967
|
-
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
10968
|
-
cur = scalarParsers[2](input, cur, ctx);
|
|
10969
|
-
if (cur < 0) return cur;
|
|
10970
|
-
ctx._sv = def.valueUnused ? void 0 : [first, second, ctx._sv];
|
|
10971
|
-
return cur;
|
|
10972
|
-
}
|
|
10973
|
-
const values = def.valueUnused ? void 0 : [];
|
|
10974
|
-
for (let i = 0; i < scalarParsers.length; i++) {
|
|
10975
|
-
let termPos = cur;
|
|
10976
|
-
if (i > 0 && ctx.trivia) termPos = advanceTrivia(input, cur, ctx);
|
|
10977
|
-
const end = scalarParsers[i](input, termPos, ctx);
|
|
10978
|
-
if (end < 0) return end;
|
|
10979
|
-
if (values !== void 0) values.push(ctx._sv);
|
|
10980
|
-
if (end > termPos || termPos === cur) cur = end;
|
|
10981
|
-
}
|
|
10982
|
-
ctx._sv = values;
|
|
10983
|
-
return cur;
|
|
10984
|
-
};
|
|
10985
|
-
let followSentinels;
|
|
10986
|
-
return {
|
|
10987
|
-
_tag: "sequence",
|
|
10988
|
-
_meta: meta,
|
|
10989
|
-
_def: def,
|
|
10990
|
-
_parseScalar: hasAdjacency || leading !== null ? void 0 : parseScalar,
|
|
10991
|
-
parse(input, pos, ctx) {
|
|
10992
|
-
const tolerant = ctx._tolerant === true;
|
|
10993
|
-
if (tolerant) {
|
|
10994
|
-
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
10995
|
-
parsers.slice(i + 1).reduce(
|
|
10996
|
-
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
10997
|
-
{ kind: "empty" }
|
|
10998
|
-
)
|
|
10999
|
-
));
|
|
11000
|
-
}
|
|
11001
|
-
const inheritedSync = ctx._sync;
|
|
11002
|
-
const deferredTrivia = needsDeferredTriviaCommit(ctx);
|
|
11003
|
-
const values = def.valueUnused ? void 0 : [];
|
|
11004
|
-
let cur = pos;
|
|
11005
|
-
try {
|
|
11006
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
11007
|
-
if (tolerant) ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
11008
|
-
const assertion = adjacency?.[i];
|
|
11009
|
-
if (assertion) {
|
|
11010
|
-
if (!holdsAdjacency(input, cur, ctx, assertion)) return adjacencyFail(cur, assertion);
|
|
11011
|
-
if (values !== void 0) values.push(null);
|
|
11012
|
-
continue;
|
|
11013
|
-
}
|
|
11014
|
-
let termPos = cur;
|
|
11015
|
-
const markTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
11016
|
-
const markLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
11017
|
-
const markRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
11018
|
-
if (ctx.trivia && i > 0) {
|
|
11019
|
-
termPos = deferredTrivia ? commitTriviaScan(scanTriviaCompact(input, cur, ctx)) : advanceTrivia(input, cur, ctx);
|
|
11020
|
-
}
|
|
11021
|
-
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
11022
|
-
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
11023
|
-
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
11024
|
-
if (leading?.[i] === true) LEAD.at = cur;
|
|
11025
|
-
const result = parsers[i].parse(input, termPos, ctx);
|
|
11026
|
-
if (!result.ok) return result;
|
|
11027
|
-
if (values !== void 0) values.push(result.value);
|
|
11028
|
-
if (result.span.end > termPos || termPos === cur) cur = result.span.end;
|
|
11029
|
-
else if (deferredTrivia) {
|
|
11030
|
-
rollbackScannedTriviaAt(
|
|
11031
|
-
ctx,
|
|
11032
|
-
markTlog,
|
|
11033
|
-
scanTlog,
|
|
11034
|
-
markLog,
|
|
11035
|
-
scanLog,
|
|
11036
|
-
markRootLog,
|
|
11037
|
-
scanRootLog
|
|
11038
|
-
);
|
|
11039
|
-
}
|
|
11040
|
-
}
|
|
11041
|
-
} finally {
|
|
11042
|
-
if (tolerant) ctx._sync = inheritedSync;
|
|
11043
|
-
}
|
|
11044
|
-
return {
|
|
11045
|
-
ok: true,
|
|
11046
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
11047
|
-
value: values ?? void 0,
|
|
11048
|
-
span: { start: pos, end: cur }
|
|
11049
|
-
};
|
|
12211
|
+
};
|
|
12212
|
+
})() : function parse3(input, pos, ctx) {
|
|
12213
|
+
const end = pos + value.length;
|
|
12214
|
+
if (end > input.length) {
|
|
12215
|
+
return failAt(ctx, expected, pos);
|
|
12216
|
+
}
|
|
12217
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
12218
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
12219
|
+
const span = { start: pos, end };
|
|
12220
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
|
|
12221
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
12222
|
+
return { ok: true, value: matchedValue, span };
|
|
11050
12223
|
}
|
|
12224
|
+
return failAt(ctx, expected, pos);
|
|
12225
|
+
};
|
|
12226
|
+
return {
|
|
12227
|
+
_tag: "literal",
|
|
12228
|
+
_meta: meta,
|
|
12229
|
+
_def: { tag: "literal", value, caseInsensitive },
|
|
12230
|
+
_parseScalar: parseScalar,
|
|
12231
|
+
parse: parse2
|
|
11051
12232
|
};
|
|
11052
12233
|
}
|
|
11053
12234
|
|
|
@@ -11118,124 +12299,6 @@ function ref() {
|
|
|
11118
12299
|
return slot;
|
|
11119
12300
|
}
|
|
11120
12301
|
|
|
11121
|
-
// src/combinators/token.ts
|
|
11122
|
-
function semanticLeafValue(_ctx, _input, _start, _end, value) {
|
|
11123
|
-
return value;
|
|
11124
|
-
}
|
|
11125
|
-
function sourceLeafValue(ctx, input, start, end, value) {
|
|
11126
|
-
return cstOutputHost(ctx.build) ? input.slice(start, end) : value;
|
|
11127
|
-
}
|
|
11128
|
-
function token(root) {
|
|
11129
|
-
const meta = {
|
|
11130
|
-
firstSet: root._meta.firstSet,
|
|
11131
|
-
canMatchNewline: root._meta.canMatchNewline,
|
|
11132
|
-
isTrivia: false
|
|
11133
|
-
};
|
|
11134
|
-
return {
|
|
11135
|
-
_tag: "token",
|
|
11136
|
-
_meta: meta,
|
|
11137
|
-
_def: { tag: "token", parser: root },
|
|
11138
|
-
parse(input, pos, ctx) {
|
|
11139
|
-
const savedTrivia = ctx.trivia;
|
|
11140
|
-
const savedKinds = ctx.triviaKindLabels;
|
|
11141
|
-
const savedBuf = ctx._cstBuf;
|
|
11142
|
-
const savedChildren = ctx._cstChildren;
|
|
11143
|
-
const savedLeaves = ctx._cstLeaves;
|
|
11144
|
-
const savedRaw = ctx._cstRawChildren;
|
|
11145
|
-
const savedTriviaLog = ctx._cstTriviaLog;
|
|
11146
|
-
const savedOuterTriviaLog = ctx._triviaLog;
|
|
11147
|
-
const savedRootTriviaLog = ctx._rootTriviaLog;
|
|
11148
|
-
const wasCapturing = cstCaptureActive(ctx);
|
|
11149
|
-
ctx.trivia = void 0;
|
|
11150
|
-
ctx.triviaKindLabels = void 0;
|
|
11151
|
-
ctx._cstBuf = void 0;
|
|
11152
|
-
ctx._cstChildren = void 0;
|
|
11153
|
-
ctx._cstLeaves = void 0;
|
|
11154
|
-
ctx._cstRawChildren = void 0;
|
|
11155
|
-
ctx._cstTriviaLog = void 0;
|
|
11156
|
-
ctx._triviaLog = void 0;
|
|
11157
|
-
ctx._rootTriviaLog = void 0;
|
|
11158
|
-
let result;
|
|
11159
|
-
try {
|
|
11160
|
-
result = root.parse(input, pos, ctx);
|
|
11161
|
-
} finally {
|
|
11162
|
-
ctx.trivia = savedTrivia;
|
|
11163
|
-
ctx.triviaKindLabels = savedKinds;
|
|
11164
|
-
ctx._cstBuf = savedBuf;
|
|
11165
|
-
ctx._cstChildren = savedChildren;
|
|
11166
|
-
ctx._cstLeaves = savedLeaves;
|
|
11167
|
-
ctx._cstRawChildren = savedRaw;
|
|
11168
|
-
ctx._cstTriviaLog = savedTriviaLog;
|
|
11169
|
-
ctx._triviaLog = savedOuterTriviaLog;
|
|
11170
|
-
ctx._rootTriviaLog = savedRootTriviaLog;
|
|
11171
|
-
}
|
|
11172
|
-
if (!result.ok) return result;
|
|
11173
|
-
const span = result.span;
|
|
11174
|
-
const value = input.slice(pos, span.end);
|
|
11175
|
-
if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
11176
|
-
return { ok: true, value, span };
|
|
11177
|
-
}
|
|
11178
|
-
};
|
|
11179
|
-
}
|
|
11180
|
-
function makeLeaf(root, fn, sourceCstValue) {
|
|
11181
|
-
const cstValue = sourceCstValue ? sourceLeafValue : semanticLeafValue;
|
|
11182
|
-
const meta = {
|
|
11183
|
-
firstSet: root._meta.firstSet,
|
|
11184
|
-
canMatchNewline: root._meta.canMatchNewline,
|
|
11185
|
-
isTrivia: false
|
|
11186
|
-
};
|
|
11187
|
-
return {
|
|
11188
|
-
_tag: "leaf",
|
|
11189
|
-
_meta: meta,
|
|
11190
|
-
_def: {
|
|
11191
|
-
tag: "leaf",
|
|
11192
|
-
parser: root,
|
|
11193
|
-
fn,
|
|
11194
|
-
...sourceCstValue ? { cstValue: "source" } : {}
|
|
11195
|
-
},
|
|
11196
|
-
parse(input, pos, ctx) {
|
|
11197
|
-
const savedBuf = ctx._cstBuf;
|
|
11198
|
-
const savedChildren = ctx._cstChildren;
|
|
11199
|
-
const savedLeaves = ctx._cstLeaves;
|
|
11200
|
-
const savedRaw = ctx._cstRawChildren;
|
|
11201
|
-
const savedTriviaLog = ctx._cstTriviaLog;
|
|
11202
|
-
const savedOuterTriviaLog = ctx._triviaLog;
|
|
11203
|
-
const wasCapturing = cstCaptureActive(ctx);
|
|
11204
|
-
ctx._cstBuf = void 0;
|
|
11205
|
-
ctx._cstChildren = void 0;
|
|
11206
|
-
ctx._cstLeaves = void 0;
|
|
11207
|
-
ctx._cstRawChildren = void 0;
|
|
11208
|
-
ctx._cstTriviaLog = void 0;
|
|
11209
|
-
ctx._triviaLog = void 0;
|
|
11210
|
-
let result;
|
|
11211
|
-
try {
|
|
11212
|
-
result = root.parse(input, pos, ctx);
|
|
11213
|
-
} finally {
|
|
11214
|
-
ctx._cstBuf = savedBuf;
|
|
11215
|
-
ctx._cstChildren = savedChildren;
|
|
11216
|
-
ctx._cstLeaves = savedLeaves;
|
|
11217
|
-
ctx._cstRawChildren = savedRaw;
|
|
11218
|
-
ctx._cstTriviaLog = savedTriviaLog;
|
|
11219
|
-
ctx._triviaLog = savedOuterTriviaLog;
|
|
11220
|
-
}
|
|
11221
|
-
if (!result.ok) return result;
|
|
11222
|
-
const value = fn(result.value, result.span);
|
|
11223
|
-
if (wasCapturing) pushCstLeaf(ctx, {
|
|
11224
|
-
_tag: "leaf",
|
|
11225
|
-
value: cstValue(ctx, input, pos, result.span.end, value),
|
|
11226
|
-
span: result.span
|
|
11227
|
-
});
|
|
11228
|
-
return { ok: true, value, span: result.span };
|
|
11229
|
-
}
|
|
11230
|
-
};
|
|
11231
|
-
}
|
|
11232
|
-
function leaf(root, fn) {
|
|
11233
|
-
return makeLeaf(root, fn, false);
|
|
11234
|
-
}
|
|
11235
|
-
function sourceLeaf(root, fn) {
|
|
11236
|
-
return makeLeaf(root, fn, true);
|
|
11237
|
-
}
|
|
11238
|
-
|
|
11239
12302
|
// src/combinators/scanTo.ts
|
|
11240
12303
|
function resolveScanSkip(explicitSkip, raw, ctx) {
|
|
11241
12304
|
if (raw) return [];
|
|
@@ -11480,37 +12543,184 @@ function escapeClassChar(ch2) {
|
|
|
11480
12543
|
return ch2.replace(/[\\\]^-]/g, "\\$&");
|
|
11481
12544
|
}
|
|
11482
12545
|
|
|
11483
|
-
// src/table/
|
|
11484
|
-
function
|
|
11485
|
-
const
|
|
11486
|
-
|
|
11487
|
-
|
|
11488
|
-
|
|
11489
|
-
|
|
11490
|
-
|
|
12546
|
+
// src/table/trivia-gap.ts
|
|
12547
|
+
function skipDeferredTrivia(input, cur, ctx) {
|
|
12548
|
+
const triviaP = ctx.trivia;
|
|
12549
|
+
const plain2 = ctx.trackLines !== true && ctx.captureTrivia !== true;
|
|
12550
|
+
const gap = ctx._gap;
|
|
12551
|
+
if (plain2 && gap !== void 0 && cur === gap.at && input === gap.input && triviaP === gap.of && ctx._rootTriviaCapture === gap.root && ctx.state === gap.state && ctx._rootTriviaKindIndex === gap.rootKinds && ctx._triviaLog === gap.log) return gap.end;
|
|
12552
|
+
const end = clearRunEnd(input, cur, ctx, triviaP, plain2);
|
|
12553
|
+
if (end >= 0) {
|
|
12554
|
+
remember(cur, end, ctx, input, triviaP);
|
|
12555
|
+
return end;
|
|
11491
12556
|
}
|
|
11492
|
-
|
|
12557
|
+
const scan = scanTriviaCompact(input, cur, ctx);
|
|
12558
|
+
if (typeof scan !== "number") return commitTriviaScan(scan);
|
|
12559
|
+
if (plain2) remember(cur, scan, ctx, input, triviaP);
|
|
12560
|
+
return scan;
|
|
11493
12561
|
}
|
|
11494
|
-
function
|
|
11495
|
-
const
|
|
11496
|
-
|
|
12562
|
+
function clearRunEnd(input, cur, ctx, triviaP, plain2) {
|
|
12563
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
12564
|
+
const spec = triviaP?._meta.labeledTriviaSpec;
|
|
12565
|
+
if (!plain2 || triviaP === void 0 || spec == null || rootKinds === void 0 || ctx._triviaLog !== void 0) return -1;
|
|
12566
|
+
if (spec.rootKinds !== rootKinds) prime(spec, triviaP, rootKinds);
|
|
12567
|
+
const fast = spec.rootScan;
|
|
12568
|
+
if (fast === null) return -1;
|
|
12569
|
+
const end = fast(input, cur);
|
|
12570
|
+
return ctx._rootTriviaCapture === false || clearOf(spec.rootLeaders, input, cur, end) ? end : -1;
|
|
12571
|
+
}
|
|
12572
|
+
function remember(cur, end, ctx, input, triviaP) {
|
|
12573
|
+
const gap = ctx._gap;
|
|
12574
|
+
if (gap === void 0) {
|
|
12575
|
+
ctx._gap = { at: cur, end, input, of: triviaP, root: ctx._rootTriviaCapture, rootKinds: ctx._rootTriviaKindIndex, log: ctx._triviaLog, state: ctx.state };
|
|
12576
|
+
return;
|
|
12577
|
+
}
|
|
12578
|
+
gap.at = cur;
|
|
12579
|
+
gap.end = end;
|
|
12580
|
+
gap.input = input;
|
|
12581
|
+
gap.of = triviaP;
|
|
12582
|
+
gap.root = ctx._rootTriviaCapture;
|
|
12583
|
+
gap.rootKinds = ctx._rootTriviaKindIndex;
|
|
12584
|
+
gap.log = ctx._triviaLog;
|
|
12585
|
+
gap.state = ctx.state;
|
|
11497
12586
|
}
|
|
11498
|
-
function
|
|
11499
|
-
|
|
11500
|
-
|
|
11501
|
-
|
|
12587
|
+
function prime(spec, triviaP, rootKinds) {
|
|
12588
|
+
const ranges = [];
|
|
12589
|
+
let bounded = true;
|
|
12590
|
+
for (const arm of spec.arms) {
|
|
12591
|
+
if (rootKinds[arm.label] === void 0) continue;
|
|
12592
|
+
const fs = arm.parser._meta.firstSet;
|
|
12593
|
+
if (fs.kind === "any") bounded = false;
|
|
12594
|
+
else if (fs.kind === "ranges") ranges.push(...fs.ranges);
|
|
12595
|
+
}
|
|
12596
|
+
const classified = triviaP._meta.triviaScanner;
|
|
12597
|
+
spec.rootKinds = rootKinds;
|
|
12598
|
+
spec.rootLeaders = ranges;
|
|
12599
|
+
spec.rootScan = !bounded ? null : classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
12600
|
+
}
|
|
12601
|
+
function clearOf(ranges, input, from, to) {
|
|
12602
|
+
for (let i = from; i < to; i++) {
|
|
12603
|
+
const c = input.charCodeAt(i);
|
|
12604
|
+
if (c >= 55296 && c <= 57343) return false;
|
|
12605
|
+
for (const r of ranges) if (c >= r.lo && c <= r.hi) return false;
|
|
11502
12606
|
}
|
|
11503
|
-
return
|
|
11504
|
-
_tag: "leaf",
|
|
11505
|
-
value: typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "",
|
|
11506
|
-
span: { start: s, end: e }
|
|
11507
|
-
};
|
|
12607
|
+
return true;
|
|
11508
12608
|
}
|
|
11509
|
-
|
|
11510
|
-
|
|
11511
|
-
|
|
11512
|
-
|
|
11513
|
-
|
|
12609
|
+
|
|
12610
|
+
// src/table/fail-clean.ts
|
|
12611
|
+
function passChild(code, ip) {
|
|
12612
|
+
switch (code[ip]) {
|
|
12613
|
+
case OP_RULE:
|
|
12614
|
+
case OP_LABEL:
|
|
12615
|
+
case OP_COV:
|
|
12616
|
+
case OP_TOKEN:
|
|
12617
|
+
return code[ip + 1];
|
|
12618
|
+
case OP_GATE:
|
|
12619
|
+
case OP_NODE:
|
|
12620
|
+
case OP_NODE_TRACK:
|
|
12621
|
+
case OP_XFORM:
|
|
12622
|
+
case OP_FIELD:
|
|
12623
|
+
case OP_SCOPE:
|
|
12624
|
+
case OP_SCOPE_CAP:
|
|
12625
|
+
case OP_SCOPE_PLAIN:
|
|
12626
|
+
case OP_WITHCTX:
|
|
12627
|
+
case OP_LEAF:
|
|
12628
|
+
case OP_SOURCE_LEAF:
|
|
12629
|
+
return code[ip + 2];
|
|
12630
|
+
default:
|
|
12631
|
+
return -1;
|
|
12632
|
+
}
|
|
12633
|
+
}
|
|
12634
|
+
function seqCount(code, ip) {
|
|
12635
|
+
const op = code[ip];
|
|
12636
|
+
return op === OP_SEQ || op === OP_SEQV ? ip + 1 : op === OP_SEQX ? ip + 2 : -1;
|
|
12637
|
+
}
|
|
12638
|
+
function failCleanAnalysis(code) {
|
|
12639
|
+
const cleanAt = new Uint8Array(code.length);
|
|
12640
|
+
const neverAt = new Uint8Array(code.length);
|
|
12641
|
+
const neverFails = (ip) => {
|
|
12642
|
+
const hit = neverAt[ip];
|
|
12643
|
+
if (hit !== 0) return hit === 1;
|
|
12644
|
+
neverAt[ip] = 3;
|
|
12645
|
+
let out = false;
|
|
12646
|
+
const op = code[ip];
|
|
12647
|
+
if (op === OP_OPT || op === OP_EMPTY || op === OP_EXPECT) out = true;
|
|
12648
|
+
else if (op === OP_REP || op === OP_REPV) out = code[ip + 2] === 0;
|
|
12649
|
+
else {
|
|
12650
|
+
const at = seqCount(code, ip);
|
|
12651
|
+
if (at >= 0) {
|
|
12652
|
+
out = true;
|
|
12653
|
+
for (let i = 1, n = code[at]; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
12654
|
+
} else if (op !== OP_GATE) {
|
|
12655
|
+
const c = passChild(code, ip);
|
|
12656
|
+
out = c >= 0 && neverFails(c);
|
|
12657
|
+
}
|
|
12658
|
+
}
|
|
12659
|
+
neverAt[ip] = out ? 1 : 2;
|
|
12660
|
+
return out;
|
|
12661
|
+
};
|
|
12662
|
+
const clean = (ip) => {
|
|
12663
|
+
const hit = cleanAt[ip];
|
|
12664
|
+
if (hit !== 0) return hit === 1;
|
|
12665
|
+
cleanAt[ip] = 3;
|
|
12666
|
+
let out = false;
|
|
12667
|
+
switch (code[ip]) {
|
|
12668
|
+
// A terminal pushes its leaf only on a match; NOT/PEEK/ATTEMPT restore
|
|
12669
|
+
// their own mark; OPT, EMPTY and EXPECT do not fail uncommitted.
|
|
12670
|
+
case OP_LIT:
|
|
12671
|
+
case OP_RX:
|
|
12672
|
+
case OP_LIT_TRACK:
|
|
12673
|
+
case OP_RX_TRACK:
|
|
12674
|
+
case OP_LIT_CI:
|
|
12675
|
+
case OP_LIT_CI_TRACK:
|
|
12676
|
+
case OP_GUARD:
|
|
12677
|
+
case OP_NOT:
|
|
12678
|
+
case OP_PEEK:
|
|
12679
|
+
case OP_ATTEMPT:
|
|
12680
|
+
case OP_EMPTY:
|
|
12681
|
+
case OP_OPT:
|
|
12682
|
+
case OP_EXPECT:
|
|
12683
|
+
out = true;
|
|
12684
|
+
break;
|
|
12685
|
+
// Min 0 does not fail uncommitted; min 1 fails only with no item kept, and
|
|
12686
|
+
// restores the failed item itself.
|
|
12687
|
+
case OP_REP:
|
|
12688
|
+
case OP_REPV:
|
|
12689
|
+
out = code[ip + 2] <= 1;
|
|
12690
|
+
break;
|
|
12691
|
+
// Only the first term may fail: a later one fails after the terms before it
|
|
12692
|
+
// wrote, and after the trivia scanned in front of it.
|
|
12693
|
+
case OP_SEQ:
|
|
12694
|
+
case OP_SEQV:
|
|
12695
|
+
case OP_SEQX: {
|
|
12696
|
+
const at = seqCount(code, ip);
|
|
12697
|
+
const n = code[at];
|
|
12698
|
+
out = n > 0 && clean(code[at + 1]);
|
|
12699
|
+
for (let i = 2; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
12700
|
+
break;
|
|
12701
|
+
}
|
|
12702
|
+
case OP_CHOICE: {
|
|
12703
|
+
out = true;
|
|
12704
|
+
for (let i = 0, n = code[ip + 2]; out && i < n; i++) out = clean(code[ip + 4 + i]);
|
|
12705
|
+
break;
|
|
12706
|
+
}
|
|
12707
|
+
case OP_ROUTED:
|
|
12708
|
+
out = code[ip + 1] < 0 || clean(code[ip + 1]);
|
|
12709
|
+
break;
|
|
12710
|
+
// An arm's failure and the fallback's are committed; only the selector's is
|
|
12711
|
+
// not, and without a fallback an unknown key fails after the selector wrote.
|
|
12712
|
+
case OP_DISPATCH:
|
|
12713
|
+
out = code[ip + 3] >= 0 && clean(code[ip + 1]);
|
|
12714
|
+
break;
|
|
12715
|
+
default: {
|
|
12716
|
+
const c = passChild(code, ip);
|
|
12717
|
+
out = c >= 0 && clean(c);
|
|
12718
|
+
}
|
|
12719
|
+
}
|
|
12720
|
+
cleanAt[ip] = out ? 1 : 2;
|
|
12721
|
+
return out;
|
|
12722
|
+
};
|
|
12723
|
+
return clean;
|
|
11514
12724
|
}
|
|
11515
12725
|
|
|
11516
12726
|
// src/grammar-metadata.ts
|
|
@@ -11608,12 +12818,6 @@ function hasDirectBuilder(prog) {
|
|
|
11608
12818
|
return false;
|
|
11609
12819
|
}
|
|
11610
12820
|
|
|
11611
|
-
// src/cst/root-trivia-scope.ts
|
|
11612
|
-
var ROOT_TRIVIA_SCOPE_REFUSAL = "parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'.";
|
|
11613
|
-
function refuseUnclassifiedRootScope(strict) {
|
|
11614
|
-
if (strict === true) throw new TypeError(ROOT_TRIVIA_SCOPE_REFUSAL);
|
|
11615
|
-
}
|
|
11616
|
-
|
|
11617
12821
|
// src/table/cell.ts
|
|
11618
12822
|
var FAIL = /* @__PURE__ */ Symbol("pm.fail");
|
|
11619
12823
|
var newEndCell = () => ({ e: 0 });
|
|
@@ -11664,6 +12868,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11664
12868
|
const swapLegal = !cfg.trackLines;
|
|
11665
12869
|
const hostCst = cfg.hostCst;
|
|
11666
12870
|
const REC = prog.rec === 1 && cfg.tolerant;
|
|
12871
|
+
const PROBE = cfg.probe;
|
|
11667
12872
|
const sentinels = /* @__PURE__ */ new Map();
|
|
11668
12873
|
function sentinelFor(cls) {
|
|
11669
12874
|
if (cls < 0) return void 0;
|
|
@@ -11678,6 +12883,9 @@ function assemble(t2, prog, cfg) {
|
|
|
11678
12883
|
const EC = newEndCell();
|
|
11679
12884
|
const scalarRecognizers = [];
|
|
11680
12885
|
const rawScalarSpecs = /* @__PURE__ */ new Set();
|
|
12886
|
+
function lookaheadClass(child) {
|
|
12887
|
+
return code[child] === OP_GATE && !cfg.tolerant && !cfg.probe ? cc[code[child + 1]] : null;
|
|
12888
|
+
}
|
|
11681
12889
|
function scalarFor(child) {
|
|
11682
12890
|
const spec = code[child + 1];
|
|
11683
12891
|
let recognize = scalarRecognizers[spec];
|
|
@@ -11687,17 +12895,27 @@ function assemble(t2, prog, cfg) {
|
|
|
11687
12895
|
}
|
|
11688
12896
|
return recognize;
|
|
11689
12897
|
}
|
|
11690
|
-
const labelExtraIps =
|
|
11691
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) labelExtraIps.push(r[0]);
|
|
11692
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
|
|
12898
|
+
const labelExtraIps = assemblyExtraIps(prog);
|
|
11693
12899
|
const closureLabels = computeSiteLabels(
|
|
11694
12900
|
code,
|
|
11695
12901
|
[...Object.values(prog.rules), ...labelExtraIps],
|
|
11696
12902
|
hostCst
|
|
11697
12903
|
);
|
|
11698
12904
|
let SCAN = null;
|
|
12905
|
+
let HYBRID;
|
|
12906
|
+
function hybridPiece(piece) {
|
|
12907
|
+
const setScan = HYBRID.scan;
|
|
12908
|
+
return (input, pos, ctx) => {
|
|
12909
|
+
const saved = setScan(SCAN);
|
|
12910
|
+
const value = piece(input, pos, ctx);
|
|
12911
|
+
setScan(saved);
|
|
12912
|
+
return value;
|
|
12913
|
+
};
|
|
12914
|
+
}
|
|
11699
12915
|
const memo = /* @__PURE__ */ new Map();
|
|
11700
12916
|
const reached = /* @__PURE__ */ new Set();
|
|
12917
|
+
const NULLABLE = /* @__PURE__ */ new Map();
|
|
12918
|
+
const CLEAN = REC ? () => false : failCleanAnalysis(code);
|
|
11701
12919
|
function pushLeaf(ctx, value, s, e) {
|
|
11702
12920
|
const lf = { _tag: "leaf", value, span: { start: s, end: e } };
|
|
11703
12921
|
pushCstLeaf(ctx, lf);
|
|
@@ -11896,6 +13114,22 @@ function assemble(t2, prog, cfg) {
|
|
|
11896
13114
|
return node2;
|
|
11897
13115
|
};
|
|
11898
13116
|
}
|
|
13117
|
+
function passCollapseNode(child, build, readsRaw) {
|
|
13118
|
+
return (input, pos, ctx) => {
|
|
13119
|
+
const v = child(input, pos, ctx);
|
|
13120
|
+
if (v !== void 0) return v;
|
|
13121
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
13122
|
+
};
|
|
13123
|
+
}
|
|
13124
|
+
function gatedPassCollapseNode(blockers, last, classic, build, readsRaw) {
|
|
13125
|
+
return (input, pos, ctx) => {
|
|
13126
|
+
const c = lead(input, pos);
|
|
13127
|
+
for (let i = 0; i < blockers.length; i++) if (classHas2(blockers[i], c)) return classic(input, pos, ctx);
|
|
13128
|
+
const v = last(input, pos, ctx);
|
|
13129
|
+
if (v !== void 0) return v;
|
|
13130
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
13131
|
+
};
|
|
13132
|
+
}
|
|
11899
13133
|
function plainProjectNode(child, projection, type) {
|
|
11900
13134
|
return (input, pos, ctx) => {
|
|
11901
13135
|
const sCh = ctx._cstChildren;
|
|
@@ -11987,9 +13221,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11987
13221
|
return s(input, cur);
|
|
11988
13222
|
}
|
|
11989
13223
|
if (s !== null) return skipTriviaScanned(s, input, cur, ctx);
|
|
11990
|
-
if (needsDeferredTriviaCommit(ctx))
|
|
11991
|
-
return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
11992
|
-
}
|
|
13224
|
+
if (needsDeferredTriviaCommit(ctx)) return skipDeferredTrivia(input, cur, ctx);
|
|
11993
13225
|
return advanceTrivia(input, cur, ctx);
|
|
11994
13226
|
}
|
|
11995
13227
|
let TERMV;
|
|
@@ -12159,7 +13391,7 @@ function assemble(t2, prog, cfg) {
|
|
|
12159
13391
|
if (next !== void 0) {
|
|
12160
13392
|
return next(input, pos, ctx, bits, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
12161
13393
|
}
|
|
12162
|
-
if (best === pos) acc = through(total, prev, acc);
|
|
13394
|
+
if (best === pos && prev !== 0) acc = through(total, prev, acc);
|
|
12163
13395
|
ctx._fe = pos;
|
|
12164
13396
|
ctx._fx = acc ?? choiceFx;
|
|
12165
13397
|
return FAIL;
|
|
@@ -12242,7 +13474,7 @@ function assemble(t2, prog, cfg) {
|
|
|
12242
13474
|
if (next !== void 0) {
|
|
12243
13475
|
return next(input, pos, ctx, c, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
12244
13476
|
}
|
|
12245
|
-
if (best === pos) acc = through(total, prev, acc);
|
|
13477
|
+
if (best === pos && prev !== 0) acc = through(total, prev, acc);
|
|
12246
13478
|
ctx._fe = pos;
|
|
12247
13479
|
ctx._fx = acc ?? choiceFx;
|
|
12248
13480
|
return FAIL;
|
|
@@ -12268,21 +13500,27 @@ function assemble(t2, prog, cfg) {
|
|
|
12268
13500
|
}
|
|
12269
13501
|
function dispatchBranch(child, usesRouted) {
|
|
12270
13502
|
if (!usesRouted) {
|
|
12271
|
-
return (input, _pos, selEnd, key,
|
|
12272
|
-
const
|
|
13503
|
+
return (input, _pos, selEnd, key, ctx) => {
|
|
13504
|
+
const need = markCst(ctx);
|
|
13505
|
+
const mRaw = MRAW;
|
|
13506
|
+
const mTl = MTL;
|
|
13507
|
+
const mLv = MLV;
|
|
13508
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
13509
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13510
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13511
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
12273
13512
|
const v = child(input, selEnd, ctx);
|
|
12274
13513
|
if (v === FAIL) {
|
|
12275
|
-
|
|
13514
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12276
13515
|
ctx._fc = true;
|
|
12277
13516
|
return FAIL;
|
|
12278
13517
|
}
|
|
12279
13518
|
return [key, v];
|
|
12280
13519
|
};
|
|
12281
13520
|
}
|
|
12282
|
-
return (input, pos, selEnd, key,
|
|
13521
|
+
return (input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
12283
13522
|
const savedRouted = ctx._routed;
|
|
12284
|
-
|
|
12285
|
-
const mark = saveTriviaMark(ctx);
|
|
13523
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12286
13524
|
ctx._routed = { value: key, span: { start: pos, end: selEnd } };
|
|
12287
13525
|
let v;
|
|
12288
13526
|
try {
|
|
@@ -12291,7 +13529,7 @@ function assemble(t2, prog, cfg) {
|
|
|
12291
13529
|
ctx._routed = savedRouted;
|
|
12292
13530
|
}
|
|
12293
13531
|
if (v === FAIL) {
|
|
12294
|
-
|
|
13532
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12295
13533
|
ctx._fc = true;
|
|
12296
13534
|
return FAIL;
|
|
12297
13535
|
}
|
|
@@ -12299,12 +13537,12 @@ function assemble(t2, prog, cfg) {
|
|
|
12299
13537
|
};
|
|
12300
13538
|
}
|
|
12301
13539
|
function dispatchArmBlock(start, a0, a1, a2, a3, next) {
|
|
12302
|
-
return (arm, input, pos, selEnd, key,
|
|
12303
|
-
if (arm === start) return a0(input, pos, selEnd, key,
|
|
12304
|
-
if (arm === start + 1) return a1(input, pos, selEnd, key,
|
|
12305
|
-
if (arm === start + 2) return a2(input, pos, selEnd, key,
|
|
12306
|
-
if (arm === start + 3) return a3(input, pos, selEnd, key,
|
|
12307
|
-
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key,
|
|
13540
|
+
return (arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
13541
|
+
if (arm === start) return a0(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13542
|
+
if (arm === start + 1) return a1(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13543
|
+
if (arm === start + 2) return a2(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13544
|
+
if (arm === start + 3) return a3(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13545
|
+
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12308
13546
|
};
|
|
12309
13547
|
}
|
|
12310
13548
|
function trackLinesInto(ctx, input, end) {
|
|
@@ -12321,20 +13559,68 @@ function assemble(t2, prog, cfg) {
|
|
|
12321
13559
|
if (done !== void 0) return done;
|
|
12322
13560
|
const flight = inFlight.get(ip);
|
|
12323
13561
|
if (flight !== void 0) return flight.fwd;
|
|
13562
|
+
const selected = HYBRID?.byIp[ip];
|
|
13563
|
+
if (selected !== void 0) {
|
|
13564
|
+
const piece2 = scanHandoffNeeded(code, ip, closureLabels) ? hybridPiece(selected) : selected;
|
|
13565
|
+
memo.set(ip, piece2);
|
|
13566
|
+
reached.add(ip);
|
|
13567
|
+
return piece2;
|
|
13568
|
+
}
|
|
12324
13569
|
let target;
|
|
12325
13570
|
const fwd = (input, pos, ctx) => target(input, pos, ctx);
|
|
12326
13571
|
const holder = { fwd, set: (p) => {
|
|
12327
13572
|
target = p;
|
|
12328
13573
|
} };
|
|
12329
13574
|
inFlight.set(ip, holder);
|
|
12330
|
-
const
|
|
12331
|
-
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);
|
|
13575
|
+
const piece = scopeIsIdentity(code, ip, closureLabels.at(ip)) ? link(code[ip + 2]) : countedPiece(lookaheadLedNode(ip) ?? lower(ip), ip);
|
|
12332
13576
|
inFlight.delete(ip);
|
|
12333
13577
|
holder.set(piece);
|
|
12334
13578
|
memo.set(ip, piece);
|
|
12335
13579
|
reached.add(ip);
|
|
12336
13580
|
return piece;
|
|
12337
13581
|
}
|
|
13582
|
+
let FIRST_DECIDED;
|
|
13583
|
+
let NODE_BODY;
|
|
13584
|
+
const DECIDED = (_input, pos) => {
|
|
13585
|
+
EC.e = pos;
|
|
13586
|
+
return null;
|
|
13587
|
+
};
|
|
13588
|
+
function lookaheadLedNode(ip) {
|
|
13589
|
+
const op = code[ip];
|
|
13590
|
+
if (op !== OP_NODE && op !== OP_NODE_TRACK || hostCst || REC || cfg.probe || cfg.coverage || cfg.trackLines) return void 0;
|
|
13591
|
+
if (passCollapse(code, ip, hostCst) || gatedPassCollapse(code, ip, hostCst) !== void 0) return void 0;
|
|
13592
|
+
const body = code[ip + 2];
|
|
13593
|
+
const bop = code[body];
|
|
13594
|
+
if (bop !== OP_SEQ && bop !== OP_SEQV && bop !== OP_SEQX) return void 0;
|
|
13595
|
+
const base = bop === OP_SEQX ? body + 3 : body + 2;
|
|
13596
|
+
if (code[bop === OP_SEQX ? body + 2 : body + 1] < 2) return void 0;
|
|
13597
|
+
const first = code[base];
|
|
13598
|
+
const negative = code[first] === OP_NOT;
|
|
13599
|
+
const terminal = negative ? scalarTerminalNotChild(code, first) : code[first] === OP_PEEK ? scalarTerminalPeekChild(code, first) : -1;
|
|
13600
|
+
if (terminal < 0) return void 0;
|
|
13601
|
+
const recognize = scalarFor(terminal);
|
|
13602
|
+
const xf = fx[code[first + 2]];
|
|
13603
|
+
FIRST_DECIDED = DECIDED;
|
|
13604
|
+
NODE_BODY = lower(body);
|
|
13605
|
+
const node2 = lower(ip);
|
|
13606
|
+
NODE_BODY = void 0;
|
|
13607
|
+
return negative ? (input, pos, ctx) => {
|
|
13608
|
+
if (recognize(input, pos) >= 0) {
|
|
13609
|
+
ctx._fe = pos;
|
|
13610
|
+
ctx._fx = xf;
|
|
13611
|
+
EC.e = pos;
|
|
13612
|
+
return FAIL;
|
|
13613
|
+
}
|
|
13614
|
+
return node2(input, pos, ctx);
|
|
13615
|
+
} : (input, pos, ctx) => {
|
|
13616
|
+
if (recognize(input, pos) < 0) {
|
|
13617
|
+
ctx._fe = pos;
|
|
13618
|
+
ctx._fx = xf;
|
|
13619
|
+
return FAIL;
|
|
13620
|
+
}
|
|
13621
|
+
return node2(input, pos, ctx);
|
|
13622
|
+
};
|
|
13623
|
+
}
|
|
12338
13624
|
function lower(ip) {
|
|
12339
13625
|
const op = code[ip];
|
|
12340
13626
|
switch (op) {
|
|
@@ -12865,7 +14151,12 @@ function assemble(t2, prog, cfg) {
|
|
|
12865
14151
|
}
|
|
12866
14152
|
const child = link(code[ip + 1]);
|
|
12867
14153
|
const xf = fx[code[ip + 2]];
|
|
14154
|
+
const gate = lookaheadClass(code[ip + 1]);
|
|
12868
14155
|
return (input, pos, ctx) => {
|
|
14156
|
+
if (gate !== null && !classHas2(gate, lead(input, pos))) {
|
|
14157
|
+
EC.e = pos;
|
|
14158
|
+
return null;
|
|
14159
|
+
}
|
|
12869
14160
|
const need = markCst(ctx);
|
|
12870
14161
|
const mRaw = MRAW;
|
|
12871
14162
|
const mTl = MTL;
|
|
@@ -12874,8 +14165,10 @@ function assemble(t2, prog, cfg) {
|
|
|
12874
14165
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
12875
14166
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
12876
14167
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14168
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
12877
14169
|
const v = child(input, pos, ctx);
|
|
12878
14170
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14171
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
12879
14172
|
if (v === FAIL) {
|
|
12880
14173
|
EC.e = pos;
|
|
12881
14174
|
return null;
|
|
@@ -12886,9 +14179,29 @@ function assemble(t2, prog, cfg) {
|
|
|
12886
14179
|
};
|
|
12887
14180
|
}
|
|
12888
14181
|
case OP_PEEK: {
|
|
14182
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
14183
|
+
if (scalarChild >= 0) {
|
|
14184
|
+
const recognize = scalarFor(scalarChild);
|
|
14185
|
+
const xf2 = fx[code[ip + 2]];
|
|
14186
|
+
return (input, pos, ctx) => {
|
|
14187
|
+
if (recognize(input, pos) < 0) {
|
|
14188
|
+
ctx._fe = pos;
|
|
14189
|
+
ctx._fx = xf2;
|
|
14190
|
+
return FAIL;
|
|
14191
|
+
}
|
|
14192
|
+
EC.e = pos;
|
|
14193
|
+
return null;
|
|
14194
|
+
};
|
|
14195
|
+
}
|
|
12889
14196
|
const child = link(code[ip + 1]);
|
|
12890
14197
|
const xf = fx[code[ip + 2]];
|
|
14198
|
+
const gate = lookaheadClass(code[ip + 1]);
|
|
12891
14199
|
return (input, pos, ctx) => {
|
|
14200
|
+
if (gate !== null && !classHas2(gate, lead(input, pos))) {
|
|
14201
|
+
ctx._fe = pos;
|
|
14202
|
+
ctx._fx = xf;
|
|
14203
|
+
return FAIL;
|
|
14204
|
+
}
|
|
12892
14205
|
const need = markCst(ctx);
|
|
12893
14206
|
const mRaw = MRAW;
|
|
12894
14207
|
const mTl = MTL;
|
|
@@ -12897,8 +14210,10 @@ function assemble(t2, prog, cfg) {
|
|
|
12897
14210
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
12898
14211
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
12899
14212
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14213
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
12900
14214
|
const v = child(input, pos, ctx);
|
|
12901
14215
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14216
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
12902
14217
|
if (v === FAIL) {
|
|
12903
14218
|
ctx._fe = pos;
|
|
12904
14219
|
ctx._fx = xf;
|
|
@@ -12910,8 +14225,14 @@ function assemble(t2, prog, cfg) {
|
|
|
12910
14225
|
}
|
|
12911
14226
|
case OP_OPT: {
|
|
12912
14227
|
const child = link(code[ip + 1]);
|
|
14228
|
+
const gate = lookaheadClass(code[ip + 1]);
|
|
14229
|
+
const childClean = CLEAN(code[ip + 1]);
|
|
12913
14230
|
return (input, pos, ctx) => {
|
|
12914
|
-
|
|
14231
|
+
if (gate !== null && !classHas2(gate, lead(input, pos))) {
|
|
14232
|
+
EC.e = pos;
|
|
14233
|
+
return null;
|
|
14234
|
+
}
|
|
14235
|
+
const need = !childClean && markCst(ctx);
|
|
12915
14236
|
const mRaw = MRAW;
|
|
12916
14237
|
const mTl = MTL;
|
|
12917
14238
|
const mLv = MLV;
|
|
@@ -13109,6 +14430,9 @@ function assemble(t2, prog, cfg) {
|
|
|
13109
14430
|
const projection = reducer < 0 ? ~reducer : -1;
|
|
13110
14431
|
const fn = fused && projection < 0 ? fns[reducer] : void 0;
|
|
13111
14432
|
const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm;
|
|
14433
|
+
const decided = FIRST_DECIDED;
|
|
14434
|
+
FIRST_DECIDED = void 0;
|
|
14435
|
+
const linkFirst = () => decided ?? link(code[base]);
|
|
13112
14436
|
const runnerBlock = (count, r0, r1, r2, r3, next) => {
|
|
13113
14437
|
if (count === 1) return (input, cur, ctx, values, inherited) => {
|
|
13114
14438
|
cur = r0(input, cur, ctx, inherited);
|
|
@@ -13154,7 +14478,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13154
14478
|
};
|
|
13155
14479
|
};
|
|
13156
14480
|
if (REC) {
|
|
13157
|
-
const first2 =
|
|
14481
|
+
const first2 = linkFirst();
|
|
13158
14482
|
const firstSync = sentinelFor(code[base + n]);
|
|
13159
14483
|
const runnerAt = (i) => {
|
|
13160
14484
|
const sync = sentinelFor(code[base + n + i]);
|
|
@@ -13190,13 +14514,13 @@ function assemble(t2, prog, cfg) {
|
|
|
13190
14514
|
const bindRunners = (start) => {
|
|
13191
14515
|
const count = Math.min(4, n - start);
|
|
13192
14516
|
const at = (offset) => runnerAt(start + offset);
|
|
13193
|
-
const
|
|
14517
|
+
const never2 = () => -1;
|
|
13194
14518
|
return runnerBlock(
|
|
13195
14519
|
count,
|
|
13196
14520
|
at(0),
|
|
13197
|
-
count > 1 ? at(1) :
|
|
13198
|
-
count > 2 ? at(2) :
|
|
13199
|
-
count > 3 ? at(3) :
|
|
14521
|
+
count > 1 ? at(1) : never2,
|
|
14522
|
+
count > 2 ? at(2) : never2,
|
|
14523
|
+
count > 3 ? at(3) : never2,
|
|
13200
14524
|
start + count < n ? bindRunners(start + count) : void 0
|
|
13201
14525
|
);
|
|
13202
14526
|
};
|
|
@@ -13246,15 +14570,31 @@ function assemble(t2, prog, cfg) {
|
|
|
13246
14570
|
let hasAdj = false;
|
|
13247
14571
|
for (let i = 1; i < n; i++) {
|
|
13248
14572
|
const kidIp = code[base + i];
|
|
13249
|
-
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp)) {
|
|
14573
|
+
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp) || holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
13250
14574
|
hasAdj = true;
|
|
13251
14575
|
break;
|
|
13252
14576
|
}
|
|
13253
14577
|
}
|
|
13254
14578
|
if (hasAdj) {
|
|
13255
|
-
const first2 =
|
|
14579
|
+
const first2 = linkFirst();
|
|
13256
14580
|
const runnerAt = (i) => {
|
|
13257
14581
|
const kidIp = code[base + i];
|
|
14582
|
+
if (holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
14583
|
+
const kid = link(kidIp);
|
|
14584
|
+
return (input, cur, ctx) => {
|
|
14585
|
+
if (ctx.trivia === void 0) {
|
|
14586
|
+
const v2 = kid(input, cur, ctx);
|
|
14587
|
+
if (v2 === FAIL) return -1;
|
|
14588
|
+
TERMV = v2;
|
|
14589
|
+
return EC.e;
|
|
14590
|
+
}
|
|
14591
|
+
const scanEnd = skipTrivia(input, cur, ctx);
|
|
14592
|
+
const v = kid(input, scanEnd, ctx);
|
|
14593
|
+
if (v === FAIL) return -1;
|
|
14594
|
+
TERMV = v;
|
|
14595
|
+
return scanEnd;
|
|
14596
|
+
};
|
|
14597
|
+
}
|
|
13258
14598
|
if (code[kidIp] !== OP_ADJ) {
|
|
13259
14599
|
const kid = link(kidIp);
|
|
13260
14600
|
if (leadingTriviaFieldAt(code, k, kidIp)) {
|
|
@@ -13279,13 +14619,13 @@ function assemble(t2, prog, cfg) {
|
|
|
13279
14619
|
const bindRunners = (start) => {
|
|
13280
14620
|
const count = Math.min(4, n - start);
|
|
13281
14621
|
const at = (offset) => runnerAt(start + offset);
|
|
13282
|
-
const
|
|
14622
|
+
const never2 = () => -1;
|
|
13283
14623
|
return runnerBlock(
|
|
13284
14624
|
count,
|
|
13285
14625
|
at(0),
|
|
13286
|
-
count > 1 ? at(1) :
|
|
13287
|
-
count > 2 ? at(2) :
|
|
13288
|
-
count > 3 ? at(3) :
|
|
14626
|
+
count > 1 ? at(1) : never2,
|
|
14627
|
+
count > 2 ? at(2) : never2,
|
|
14628
|
+
count > 3 ? at(3) : never2,
|
|
13289
14629
|
start + count < n ? bindRunners(start + count) : void 0
|
|
13290
14630
|
);
|
|
13291
14631
|
};
|
|
@@ -13322,7 +14662,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13322
14662
|
};
|
|
13323
14663
|
}
|
|
13324
14664
|
if (n === 1) {
|
|
13325
|
-
const k0 =
|
|
14665
|
+
const k0 = linkFirst();
|
|
13326
14666
|
if (fused) {
|
|
13327
14667
|
return (input, pos, ctx) => {
|
|
13328
14668
|
const v = k0(input, pos, ctx);
|
|
@@ -13344,7 +14684,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13344
14684
|
};
|
|
13345
14685
|
}
|
|
13346
14686
|
if (n === 2) {
|
|
13347
|
-
const k0 =
|
|
14687
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]);
|
|
13348
14688
|
if (fused) {
|
|
13349
14689
|
return (input, pos, ctx) => {
|
|
13350
14690
|
const v0 = k0(input, pos, ctx);
|
|
@@ -13375,7 +14715,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13375
14715
|
};
|
|
13376
14716
|
}
|
|
13377
14717
|
if (n === 3) {
|
|
13378
|
-
const k0 =
|
|
14718
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]), k2 = link(code[base + 2]);
|
|
13379
14719
|
if (fused) {
|
|
13380
14720
|
return (input, pos, ctx) => {
|
|
13381
14721
|
const v0 = k0(input, pos, ctx);
|
|
@@ -13469,7 +14809,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13469
14809
|
start + count < n ? bind(start + count) : void 0
|
|
13470
14810
|
);
|
|
13471
14811
|
};
|
|
13472
|
-
const first =
|
|
14812
|
+
const first = linkFirst();
|
|
13473
14813
|
const tail = bind(1);
|
|
13474
14814
|
const runDirectTerms = (input, pos, ctx, values) => {
|
|
13475
14815
|
const v0 = first(input, pos, ctx);
|
|
@@ -13508,6 +14848,8 @@ function assemble(t2, prog, cfg) {
|
|
|
13508
14848
|
const n = code[ip + 2];
|
|
13509
14849
|
const choiceFx = fx[code[ip + 3]];
|
|
13510
14850
|
const base = ip + 4;
|
|
14851
|
+
for (let i = 0; i < n; i++) link(code[base + i]);
|
|
14852
|
+
const armsClean = CLEAN(ip);
|
|
13511
14853
|
if (table.exclusive) {
|
|
13512
14854
|
const ascii = table.ascii;
|
|
13513
14855
|
const hi = table.hi;
|
|
@@ -13647,7 +14989,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13647
14989
|
if (n === 3) addGate(g2, 4);
|
|
13648
14990
|
return (input, pos, ctx) => {
|
|
13649
14991
|
const c = lead(input, pos);
|
|
13650
|
-
const need = markCst(ctx);
|
|
14992
|
+
const need = !armsClean && markCst(ctx);
|
|
13651
14993
|
const mRaw = MRAW;
|
|
13652
14994
|
const mTl = MTL;
|
|
13653
14995
|
const mLv = MLV;
|
|
@@ -13717,6 +15059,11 @@ function assemble(t2, prog, cfg) {
|
|
|
13717
15059
|
}
|
|
13718
15060
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13719
15061
|
}
|
|
15062
|
+
if (prev === 0) {
|
|
15063
|
+
ctx._fe = pos;
|
|
15064
|
+
ctx._fx = choiceFx;
|
|
15065
|
+
return FAIL;
|
|
15066
|
+
}
|
|
13720
15067
|
if (best === pos && prev < 1) acc = accSet(e0, acc);
|
|
13721
15068
|
if (best === pos && prev < 2) acc = accSet(e1, acc);
|
|
13722
15069
|
if (best === pos && n === 3 && prev < 3) acc = accSet(e2, acc);
|
|
@@ -13859,7 +15206,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13859
15206
|
if (pn !== 0) {
|
|
13860
15207
|
return (input, pos, ctx) => {
|
|
13861
15208
|
const c = lead(input, pos);
|
|
13862
|
-
const need = markCst(ctx);
|
|
15209
|
+
const need = !armsClean && markCst(ctx);
|
|
13863
15210
|
const mRaw = MRAW;
|
|
13864
15211
|
const mTl = MTL;
|
|
13865
15212
|
const mLv = MLV;
|
|
@@ -13916,7 +15263,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13916
15263
|
}
|
|
13917
15264
|
return (input, pos, ctx) => {
|
|
13918
15265
|
const c = lead(input, pos);
|
|
13919
|
-
const need = markCst(ctx);
|
|
15266
|
+
const need = !armsClean && markCst(ctx);
|
|
13920
15267
|
const mRaw = MRAW;
|
|
13921
15268
|
const mTl = MTL;
|
|
13922
15269
|
const mLv = MLV;
|
|
@@ -13964,7 +15311,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13964
15311
|
}
|
|
13965
15312
|
return (input, pos, ctx) => {
|
|
13966
15313
|
const c = lead(input, pos);
|
|
13967
|
-
const need = markCst(ctx);
|
|
15314
|
+
const need = !armsClean && markCst(ctx);
|
|
13968
15315
|
const mRaw = MRAW;
|
|
13969
15316
|
const mTl = MTL;
|
|
13970
15317
|
const mLv = MLV;
|
|
@@ -14018,6 +15365,21 @@ function assemble(t2, prog, cfg) {
|
|
|
14018
15365
|
return lit(input, pos, ctx);
|
|
14019
15366
|
};
|
|
14020
15367
|
}
|
|
15368
|
+
case OP_RGATE: {
|
|
15369
|
+
const cls = cc[code[ip + 1]];
|
|
15370
|
+
const xf = fx[code[ip + 3]];
|
|
15371
|
+
const child = link(code[ip + 2]);
|
|
15372
|
+
if (cfg.tolerant || cfg.probe) return child;
|
|
15373
|
+
return (input, pos, ctx) => {
|
|
15374
|
+
const item = ctx._routed;
|
|
15375
|
+
if (item !== void 0 && item.span.start === pos && !classHas2(cls, lead(input, item.span.end))) {
|
|
15376
|
+
ctx._fe = item.span.end;
|
|
15377
|
+
ctx._fx = xf;
|
|
15378
|
+
return FAIL;
|
|
15379
|
+
}
|
|
15380
|
+
return child(input, pos, ctx);
|
|
15381
|
+
};
|
|
15382
|
+
}
|
|
14021
15383
|
case OP_ARMGATE: {
|
|
14022
15384
|
const pred = fns[code[ip + 1]];
|
|
14023
15385
|
const child = link(code[ip + 2]);
|
|
@@ -14025,7 +15387,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14025
15387
|
return (input, pos, ctx) => {
|
|
14026
15388
|
if (!pred(ctx.state)) {
|
|
14027
15389
|
ctx._fc = false;
|
|
14028
|
-
ctx._fe =
|
|
15390
|
+
ctx._fe = -1;
|
|
14029
15391
|
ctx._fx = xf;
|
|
14030
15392
|
return FAIL;
|
|
14031
15393
|
}
|
|
@@ -14086,6 +15448,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14086
15448
|
const itemClass = !REC && itemClassIndex >= 0 ? cc[itemClassIndex] : void 0;
|
|
14087
15449
|
const itemMayStart = itemClass === void 0 ? void 0 : (input, pos) => classHas2(itemClass, lead(input, pos));
|
|
14088
15450
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
15451
|
+
const itemClean = sepIp < 0 && CLEAN(code[ip + 1]) && !rowNullable(code, k, code[ip + 1], NULLABLE);
|
|
14089
15452
|
if (REC) {
|
|
14090
15453
|
const itemFx2 = fx[code[ip + 6]];
|
|
14091
15454
|
const sepSent = sentinelFor(code[ip + 7]);
|
|
@@ -14182,6 +15545,8 @@ function assemble(t2, prog, cfg) {
|
|
|
14182
15545
|
const out = collect ? [] : void 0;
|
|
14183
15546
|
const hasTrivia = ctx.trivia !== void 0;
|
|
14184
15547
|
const needMark = rollbackNeeded(ctx);
|
|
15548
|
+
const markLater = needMark && (!itemClean || hasTrivia);
|
|
15549
|
+
const markFirst = needMark && (!itemClean || hasTrivia && skipBeforeFirst);
|
|
14185
15550
|
const gateItems = itemMayStart !== void 0 && ctx._probe === void 0;
|
|
14186
15551
|
let cur = pos;
|
|
14187
15552
|
let count = 0;
|
|
@@ -14189,14 +15554,15 @@ function assemble(t2, prog, cfg) {
|
|
|
14189
15554
|
if (max >= 0 && count >= max) break;
|
|
14190
15555
|
if (sep !== void 0 && count > 0 && count >= min && cur >= input.length) break;
|
|
14191
15556
|
if (count >= min && sep === void 0 && !hasTrivia && gateItems && !itemMayStart(input, cur)) break;
|
|
14192
|
-
|
|
14193
|
-
|
|
14194
|
-
const
|
|
14195
|
-
const
|
|
14196
|
-
const
|
|
14197
|
-
const
|
|
14198
|
-
const
|
|
14199
|
-
const
|
|
15557
|
+
const markIt = count > 0 ? markLater : markFirst;
|
|
15558
|
+
if (markIt) markCst(ctx);
|
|
15559
|
+
const mRaw = markIt ? MRAW : 0;
|
|
15560
|
+
const mTl = markIt ? MTL : 0;
|
|
15561
|
+
const mLv = markIt ? MLV : 0;
|
|
15562
|
+
const mFl = markIt ? ctx._fields?.length ?? 0 : 0;
|
|
15563
|
+
const mEr = markIt ? ctx._errors?.length ?? 0 : 0;
|
|
15564
|
+
const mLog = markIt ? ctx._triviaLog?.length ?? 0 : 0;
|
|
15565
|
+
const mRoot = markIt ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14200
15566
|
let itemStart = cur;
|
|
14201
15567
|
let sepEnd = -1;
|
|
14202
15568
|
const viaRepItem = sep === void 0 && count >= min && (count > 0 || skipBeforeFirst);
|
|
@@ -14208,7 +15574,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14208
15574
|
if (sepLeads) LEAD.at = cur;
|
|
14209
15575
|
const sv = sep(input, sp, ctx);
|
|
14210
15576
|
if (sv === FAIL) {
|
|
14211
|
-
if (
|
|
15577
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14212
15578
|
if (committed3(ctx)) return FAIL;
|
|
14213
15579
|
break;
|
|
14214
15580
|
}
|
|
@@ -14219,25 +15585,25 @@ function assemble(t2, prog, cfg) {
|
|
|
14219
15585
|
itemStart = skipTrivia(input, itemStart, ctx);
|
|
14220
15586
|
}
|
|
14221
15587
|
if (itemStart >= input.length && viaRepItem) {
|
|
14222
|
-
if (
|
|
15588
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14223
15589
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
14224
15590
|
break;
|
|
14225
15591
|
}
|
|
14226
15592
|
if (count >= min && gateItems && !itemMayStart(input, itemStart)) {
|
|
14227
|
-
if (
|
|
15593
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14228
15594
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
14229
15595
|
break;
|
|
14230
15596
|
}
|
|
14231
15597
|
ctx._fc = false;
|
|
14232
15598
|
const v = child(input, itemStart, ctx);
|
|
14233
15599
|
if (v === FAIL) {
|
|
14234
|
-
if (
|
|
15600
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14235
15601
|
if (committed3(ctx)) return FAIL;
|
|
14236
15602
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
14237
15603
|
break;
|
|
14238
15604
|
}
|
|
14239
15605
|
if (EC.e === itemStart && viaRepItem) {
|
|
14240
|
-
if (
|
|
15606
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14241
15607
|
break;
|
|
14242
15608
|
}
|
|
14243
15609
|
if (out !== void 0) out.push(v);
|
|
@@ -14311,7 +15677,14 @@ function assemble(t2, prog, cfg) {
|
|
|
14311
15677
|
const runArm = n === 0 ? void 0 : bindArms(0);
|
|
14312
15678
|
const runOther = other === void 0 ? void 0 : dispatchBranch(other, otherRouted);
|
|
14313
15679
|
return (input, pos, ctx) => {
|
|
14314
|
-
const
|
|
15680
|
+
const need = markCst(ctx);
|
|
15681
|
+
const mRaw = MRAW;
|
|
15682
|
+
const mTl = MTL;
|
|
15683
|
+
const mLv = MLV;
|
|
15684
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
15685
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
15686
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
15687
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14315
15688
|
const selVal = selector(input, pos, ctx);
|
|
14316
15689
|
if (selVal === FAIL) return FAIL;
|
|
14317
15690
|
const selEnd = EC.e;
|
|
@@ -14323,9 +15696,9 @@ function assemble(t2, prog, cfg) {
|
|
|
14323
15696
|
ctx._fx = expected;
|
|
14324
15697
|
return FAIL;
|
|
14325
15698
|
}
|
|
14326
|
-
return runOther(input, pos, selEnd, key,
|
|
15699
|
+
return runOther(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14327
15700
|
}
|
|
14328
|
-
return runArm(arm, input, pos, selEnd, key,
|
|
15701
|
+
return runArm(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14329
15702
|
};
|
|
14330
15703
|
}
|
|
14331
15704
|
/* ── node ────────────────────────────────────────────────────────────── */
|
|
@@ -14361,7 +15734,8 @@ function assemble(t2, prog, cfg) {
|
|
|
14361
15734
|
return nd;
|
|
14362
15735
|
};
|
|
14363
15736
|
}
|
|
14364
|
-
const child = link(code[ip + 2]);
|
|
15737
|
+
const child = NODE_BODY ?? link(code[ip + 2]);
|
|
15738
|
+
NODE_BODY = void 0;
|
|
14365
15739
|
const proj = code[ip + 4];
|
|
14366
15740
|
const buildIdx = code[ip + 1];
|
|
14367
15741
|
const type = k[code[ip + 5]];
|
|
@@ -14385,6 +15759,30 @@ function assemble(t2, prog, cfg) {
|
|
|
14385
15759
|
if (build !== void 0 && proj < 0 && flags === 18) {
|
|
14386
15760
|
return childrenOnlyFieldsBuildNode(child, build);
|
|
14387
15761
|
}
|
|
15762
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
15763
|
+
return passCollapseNode(child, build, flags === 32);
|
|
15764
|
+
}
|
|
15765
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
15766
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(closureLabels.at(code[ip + 2]).tri, trivia2);
|
|
15767
|
+
if (build !== void 0 && gated !== void 0 && triviaLead !== void 0) {
|
|
15768
|
+
const classic = flags === 32 ? collapseBuildNode(child, build) : childrenOnlyCollapseBuildNode(child, build);
|
|
15769
|
+
return gatedPassCollapseNode(
|
|
15770
|
+
[
|
|
15771
|
+
...gated.leads.map((g) => cc[code[g + 1]]),
|
|
15772
|
+
resolveClass(encodeClassSpec([
|
|
15773
|
+
...triviaLead,
|
|
15774
|
+
...gated.lits.map((i) => {
|
|
15775
|
+
const c = k[i].codePointAt(0);
|
|
15776
|
+
return { lo: c, hi: c };
|
|
15777
|
+
})
|
|
15778
|
+
]))
|
|
15779
|
+
],
|
|
15780
|
+
link(gated.last),
|
|
15781
|
+
classic,
|
|
15782
|
+
build,
|
|
15783
|
+
flags === 32
|
|
15784
|
+
);
|
|
15785
|
+
}
|
|
14388
15786
|
if (build !== void 0 && proj < 0 && flags === 32) {
|
|
14389
15787
|
return collapseBuildNode(child, build);
|
|
14390
15788
|
}
|
|
@@ -14431,7 +15829,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14431
15829
|
if (v === FAIL) return FAIL;
|
|
14432
15830
|
const end = EC.e;
|
|
14433
15831
|
const span = tracked ? spanLines(ctx, pos, end) : { start: pos, end };
|
|
14434
|
-
const st = readsState
|
|
15832
|
+
const st = readsState ? ctx.state : void 0;
|
|
14435
15833
|
let nd;
|
|
14436
15834
|
if (unwrap && kids.length === 1) {
|
|
14437
15835
|
nd = unwrapChild(kids[0]);
|
|
@@ -14444,10 +15842,10 @@ function assemble(t2, prog, cfg) {
|
|
|
14444
15842
|
) {
|
|
14445
15843
|
nd = kids[0];
|
|
14446
15844
|
} else if (proj >= 0) {
|
|
14447
|
-
nd = hostCst && host !== void 0 ? host(type, kids, fieldMap, span, rawKids, tlog,
|
|
15845
|
+
nd = hostCst && host !== void 0 ? host(type, kids, fieldMap, span, rawKids, tlog, ctx.state, tags) : projectChild(kids, proj, type);
|
|
14448
15846
|
} else if (build !== void 0) {
|
|
14449
15847
|
if (hostCst && host !== void 0) {
|
|
14450
|
-
nd = host(type, kids, fieldMap, span, rawKids, tlog,
|
|
15848
|
+
nd = host(type, kids, fieldMap, span, rawKids, tlog, ctx.state, tags);
|
|
14451
15849
|
} else {
|
|
14452
15850
|
nd = build(kids, fieldMap, span, rawKids, captureWide ? tlog : EMPTY_TL2, st);
|
|
14453
15851
|
}
|
|
@@ -14498,9 +15896,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14498
15896
|
let emitRefusal;
|
|
14499
15897
|
let emitReached;
|
|
14500
15898
|
{
|
|
14501
|
-
const extraIps =
|
|
14502
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) extraIps.push(r[0]);
|
|
14503
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
15899
|
+
const extraIps = assemblyExtraIps(prog);
|
|
14504
15900
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
14505
15901
|
for (const ip of reachableSites(code, roots)) {
|
|
14506
15902
|
if (code[ip] === OP_DISPATCH) {
|
|
@@ -14535,6 +15931,8 @@ function assemble(t2, prog, cfg) {
|
|
|
14535
15931
|
}
|
|
14536
15932
|
const notChild = scalarTerminalNotChild(code, ip);
|
|
14537
15933
|
if (notChild >= 0) scalarFor(notChild);
|
|
15934
|
+
const peekChild = scalarTerminalPeekChild(code, ip);
|
|
15935
|
+
if (peekChild >= 0) scalarFor(peekChild);
|
|
14538
15936
|
}
|
|
14539
15937
|
const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
|
|
14540
15938
|
if (pre !== void 0) {
|
|
@@ -14593,9 +15991,12 @@ function assemble(t2, prog, cfg) {
|
|
|
14593
15991
|
adjacencyHolds,
|
|
14594
15992
|
t2.lexPrograms,
|
|
14595
15993
|
LEAD,
|
|
14596
|
-
triviaFieldCapture
|
|
15994
|
+
triviaFieldCapture,
|
|
15995
|
+
skipDeferredTrivia,
|
|
15996
|
+
collapseEmpty
|
|
14597
15997
|
);
|
|
14598
15998
|
emitReached = new Set(pre.reached);
|
|
15999
|
+
if (emitted.ext !== void 0) HYBRID = emitted;
|
|
14599
16000
|
}
|
|
14600
16001
|
try {
|
|
14601
16002
|
if (emitted !== void 0) throw new ServedByBuild();
|
|
@@ -14677,7 +16078,9 @@ function assemble(t2, prog, cfg) {
|
|
|
14677
16078
|
adjacencyHolds,
|
|
14678
16079
|
t2.lexPrograms,
|
|
14679
16080
|
LEAD,
|
|
14680
|
-
triviaFieldCapture
|
|
16081
|
+
triviaFieldCapture,
|
|
16082
|
+
skipDeferredTrivia,
|
|
16083
|
+
collapseEmpty
|
|
14681
16084
|
);
|
|
14682
16085
|
emitReached = em.reached;
|
|
14683
16086
|
} catch (e) {
|
|
@@ -14688,7 +16091,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14688
16091
|
}
|
|
14689
16092
|
function pieceAt(ip) {
|
|
14690
16093
|
const em = emitted;
|
|
14691
|
-
if (em !== void 0) {
|
|
16094
|
+
if (em !== void 0 && HYBRID === void 0) {
|
|
14692
16095
|
const p = em.byIp[ip];
|
|
14693
16096
|
if (p === void 0) throw new Error(`table emitter: no emitted body for site ${ip}`);
|
|
14694
16097
|
return p;
|
|
@@ -14718,6 +16121,37 @@ function assemble(t2, prog, cfg) {
|
|
|
14718
16121
|
}
|
|
14719
16122
|
const scans = scansArr;
|
|
14720
16123
|
const scanSkip = (prog.scanSkip ?? []).map((set) => set.map((r) => subtreeComb(r)));
|
|
16124
|
+
if (HYBRID !== void 0) {
|
|
16125
|
+
const em = HYBRID;
|
|
16126
|
+
em.bind(
|
|
16127
|
+
(s) => {
|
|
16128
|
+
const saved = SCAN;
|
|
16129
|
+
SCAN = s;
|
|
16130
|
+
return saved;
|
|
16131
|
+
},
|
|
16132
|
+
em.ext.map((ip) => link(ip))
|
|
16133
|
+
);
|
|
16134
|
+
const pieces2 = {};
|
|
16135
|
+
for (const [name, entryIp] of Object.entries(prog.rules)) {
|
|
16136
|
+
pieces2[name] = em.pieces[name] ?? link(entryIp);
|
|
16137
|
+
}
|
|
16138
|
+
for (const ip of emitReached) reached.add(ip);
|
|
16139
|
+
return {
|
|
16140
|
+
pieces: pieces2,
|
|
16141
|
+
end: () => EC.e,
|
|
16142
|
+
begin: (ctx) => {
|
|
16143
|
+
begin(ctx);
|
|
16144
|
+
em.begin(ctx);
|
|
16145
|
+
},
|
|
16146
|
+
finish: () => {
|
|
16147
|
+
em.finish();
|
|
16148
|
+
finish();
|
|
16149
|
+
},
|
|
16150
|
+
scanSkip,
|
|
16151
|
+
reached,
|
|
16152
|
+
emitRefusal: void 0
|
|
16153
|
+
};
|
|
16154
|
+
}
|
|
14721
16155
|
if (emitted !== void 0) {
|
|
14722
16156
|
const em = emitted;
|
|
14723
16157
|
return {
|
|
@@ -14753,6 +16187,15 @@ function assemble(t2, prog, cfg) {
|
|
|
14753
16187
|
}
|
|
14754
16188
|
return { pieces, end: () => EC.e, begin, finish, scanSkip, reached, emitRefusal };
|
|
14755
16189
|
}
|
|
16190
|
+
var SITE_COUNTS;
|
|
16191
|
+
function countedPiece(piece, ip) {
|
|
16192
|
+
const counts = SITE_COUNTS;
|
|
16193
|
+
if (counts === void 0) return piece;
|
|
16194
|
+
return (input, pos, ctx) => {
|
|
16195
|
+
counts[ip]++;
|
|
16196
|
+
return piece(input, pos, ctx);
|
|
16197
|
+
};
|
|
16198
|
+
}
|
|
14756
16199
|
var AssemblyCache = class {
|
|
14757
16200
|
t;
|
|
14758
16201
|
prog;
|
|
@@ -14904,7 +16347,7 @@ function emitClassPool(classes) {
|
|
|
14904
16347
|
if (classes.length < 2) return array;
|
|
14905
16348
|
const delimiter = "|/~?^`".split("").find((ch2) => classes.every((spec) => !spec.includes(ch2)));
|
|
14906
16349
|
if (delimiter === void 0) return array;
|
|
14907
|
-
const split =
|
|
16350
|
+
const split = `/* @__PURE__ */ ${jsString(classes.join(delimiter))}.split(${jsString(delimiter)})`;
|
|
14908
16351
|
return split.length < array.length ? split : array;
|
|
14909
16352
|
}
|
|
14910
16353
|
function emitConst(v) {
|
|
@@ -14955,9 +16398,7 @@ function emitDispatchSpec(d) {
|
|
|
14955
16398
|
function emitAssemblies(prog, cfgs) {
|
|
14956
16399
|
if (cfgs.length === 0) return ["a:[],"];
|
|
14957
16400
|
const t2 = resolveTable(prog);
|
|
14958
|
-
const extraIps =
|
|
14959
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) extraIps.push(r[0]);
|
|
14960
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
16401
|
+
const extraIps = assemblyExtraIps(prog);
|
|
14961
16402
|
const out = [];
|
|
14962
16403
|
const seen = /* @__PURE__ */ new Set();
|
|
14963
16404
|
for (const cfg of cfgs) {
|
|
@@ -14966,7 +16407,7 @@ function emitAssemblies(prog, cfgs) {
|
|
|
14966
16407
|
seen.add(key);
|
|
14967
16408
|
let em;
|
|
14968
16409
|
try {
|
|
14969
|
-
em = emitAssemblySource(t2, prog, cfg, extraIps, true);
|
|
16410
|
+
em = emitAssemblySource(t2, prog, cfg, extraIps, true, cfg.select);
|
|
14970
16411
|
} catch (e) {
|
|
14971
16412
|
if (e instanceof Unemittable) continue;
|
|
14972
16413
|
throw e;
|
|
@@ -16513,339 +17954,85 @@ function reportDuplication(opt, analyze) {
|
|
|
16513
17954
|
if (level === "error") throw new Error(`parseman: ${duplicationFindingCount(report)} duplication/overlap finding(s)
|
|
16514
17955
|
${lines2.join("\n")}`);
|
|
16515
17956
|
for (const l of lines2) console.warn(l);
|
|
16516
|
-
}
|
|
16517
|
-
return report;
|
|
16518
|
-
}
|
|
16519
|
-
function runDuplicationDiagnostic(combinator, opt) {
|
|
16520
|
-
return reportDuplication(opt, (o) => analyzeDuplication(combinator, o));
|
|
16521
|
-
}
|
|
16522
|
-
function runDuplicationDiagnosticRules(ruleMap, opt) {
|
|
16523
|
-
return reportDuplication(opt, (o) => analyzeDuplicationRules(ruleMap, o));
|
|
16524
|
-
}
|
|
16525
|
-
|
|
16526
|
-
// src/table/compile-rule-map.ts
|
|
16527
|
-
function resolveHostMode(ruleMap, explicit) {
|
|
16528
|
-
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
16529
|
-
}
|
|
16530
|
-
function resolveTrackLines(ruleMap, explicit) {
|
|
16531
|
-
return explicit === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
16532
|
-
}
|
|
16533
|
-
function withAmbient(ruleMap, opts) {
|
|
16534
|
-
if (opts.trivia === void 0 && opts.scanSkip === void 0) return ruleMap;
|
|
16535
|
-
const wrappers = /* @__PURE__ */ new Map();
|
|
16536
|
-
return ruleMap.map(([name, rule2]) => {
|
|
16537
|
-
if (rule2._meta.isTrivia) return [name, rule2];
|
|
16538
|
-
const addTrivia = opts.trivia !== void 0 && rule2._meta.grammarTrivia === void 0;
|
|
16539
|
-
const addScanSkip = opts.scanSkip !== void 0 && rule2._meta.grammarScanSkip === void 0;
|
|
16540
|
-
if (!addTrivia && !addScanSkip) return [name, rule2];
|
|
16541
|
-
let wrapped = wrappers.get(rule2);
|
|
16542
|
-
if (wrapped === void 0) {
|
|
16543
|
-
wrapped = {
|
|
16544
|
-
...rule2,
|
|
16545
|
-
_meta: {
|
|
16546
|
-
...rule2._meta,
|
|
16547
|
-
...addTrivia ? { grammarTrivia: opts.trivia } : {},
|
|
16548
|
-
...addScanSkip ? { grammarScanSkip: opts.scanSkip } : {}
|
|
16549
|
-
}
|
|
16550
|
-
};
|
|
16551
|
-
wrappers.set(rule2, wrapped);
|
|
16552
|
-
}
|
|
16553
|
-
return [name, wrapped];
|
|
16554
|
-
});
|
|
16555
|
-
}
|
|
16556
|
-
function compileRuleMapRunnable(ruleMap, opts = {}) {
|
|
16557
|
-
const encoded = encodeForRun(ruleMap, opts);
|
|
16558
|
-
if (encoded === null) return null;
|
|
16559
|
-
const { prog, hostMode, plan } = encoded;
|
|
16560
|
-
const artifact = closureArtifact(prog);
|
|
16561
|
-
const reflection = collectGrammarReflection(ruleMap);
|
|
16562
|
-
return {
|
|
16563
|
-
keys: ruleMap.map(([key]) => key),
|
|
16564
|
-
hostMode,
|
|
16565
|
-
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule2]) => hasDirectBuildDef(rule2)),
|
|
16566
|
-
reflection,
|
|
16567
|
-
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
16568
|
-
// Reflection rides on the map's metadata prototype from birth. Only `compile()`
|
|
16569
|
-
// asks to specialise; every other caller runs the closure artifact.
|
|
16570
|
-
rules: tableRules(opts.specialise === true ? prog : artifact, { [GRAMMAR_REFLECTION]: reflection }),
|
|
16571
|
-
prog: artifact
|
|
16572
|
-
};
|
|
16573
|
-
}
|
|
16574
|
-
function encodeForRun(ruleMap, opts) {
|
|
16575
|
-
runDuplicationDiagnosticRules(ruleMap, opts.duplication);
|
|
16576
|
-
const encodeMap = withAmbient(ruleMap, opts);
|
|
16577
|
-
const plan = opts.coverage === true ? buildGrammarPlan(
|
|
16578
|
-
encodeMap.map(([, rule2]) => rule2),
|
|
16579
|
-
Object.fromEntries(encodeMap.filter(([, rule2]) => rule2._def.tag !== "lazy"))
|
|
16580
|
-
) : void 0;
|
|
16581
|
-
const hostMode = resolveHostMode(ruleMap, opts.hostMode);
|
|
16582
|
-
const settings = {
|
|
16583
|
-
hostMode,
|
|
16584
|
-
...resolveTrackLines(ruleMap, opts.trackLines) ? { trackLines: true } : {},
|
|
16585
|
-
...opts.recovery === true ? { recovery: true } : {},
|
|
16586
|
-
...plan === void 0 ? {} : { coverage: plan }
|
|
16587
|
-
};
|
|
16588
|
-
try {
|
|
16589
|
-
const { prog, fnSrcs } = encodeTableProgram(Object.fromEntries(encodeMap), settings);
|
|
16590
|
-
return { prog, fnSrcs, hostMode, plan };
|
|
16591
|
-
} catch (e) {
|
|
16592
|
-
opts.refusals?.push(e instanceof Error ? e.message : String(e));
|
|
16593
|
-
return null;
|
|
16594
|
-
}
|
|
16595
|
-
}
|
|
16596
|
-
|
|
16597
|
-
// src/compiler/value-usage.ts
|
|
16598
|
-
function markUnusedValues(root) {
|
|
16599
|
-
const seenConsumed = /* @__PURE__ */ new WeakSet();
|
|
16600
|
-
const seenUnconsumed = /* @__PURE__ */ new WeakSet();
|
|
16601
|
-
const mark = (def, consumed) => {
|
|
16602
|
-
if (consumed) def.valueUnused = false;
|
|
16603
|
-
else if (def.valueUnused !== false) def.valueUnused = true;
|
|
16604
|
-
};
|
|
16605
|
-
const visit = (c, consumed) => {
|
|
16606
|
-
const seen = consumed ? seenConsumed : seenUnconsumed;
|
|
16607
|
-
if (seen.has(c)) return;
|
|
16608
|
-
seen.add(c);
|
|
16609
|
-
const def = c._def;
|
|
16610
|
-
switch (def.tag) {
|
|
16611
|
-
case "many":
|
|
16612
|
-
case "oneOrMore":
|
|
16613
|
-
mark(def, consumed);
|
|
16614
|
-
visit(def.parser, consumed);
|
|
16615
|
-
return;
|
|
16616
|
-
case "optional":
|
|
16617
|
-
visit(def.parser, consumed);
|
|
16618
|
-
return;
|
|
16619
|
-
case "sequence":
|
|
16620
|
-
mark(def, consumed);
|
|
16621
|
-
for (const p of def.parsers) visit(p, consumed);
|
|
16622
|
-
return;
|
|
16623
|
-
case "choice":
|
|
16624
|
-
for (const p of def.parsers) visit(p, consumed);
|
|
16625
|
-
return;
|
|
16626
|
-
case "dispatch":
|
|
16627
|
-
visit(def.selector, consumed);
|
|
16628
|
-
for (const entry of def.cases) visit(entry.parser, consumed);
|
|
16629
|
-
if (def.matchers) for (const entry of def.matchers) visit(entry.parser, consumed);
|
|
16630
|
-
if (def.otherwise) visit(def.otherwise, consumed);
|
|
16631
|
-
return;
|
|
16632
|
-
case "node":
|
|
16633
|
-
visit(def.parser, false);
|
|
16634
|
-
return;
|
|
16635
|
-
case "transform":
|
|
16636
|
-
visit(def.parser, true);
|
|
16637
|
-
return;
|
|
16638
|
-
case "field":
|
|
16639
|
-
visit(def.parser, true);
|
|
16640
|
-
return;
|
|
16641
|
-
case "sepBy":
|
|
16642
|
-
visit(def.parser, true);
|
|
16643
|
-
visit(def.separator, false);
|
|
16644
|
-
return;
|
|
16645
|
-
case "not":
|
|
16646
|
-
case "peek":
|
|
16647
|
-
visit(def.parser, false);
|
|
16648
|
-
return;
|
|
16649
|
-
case "grammar":
|
|
16650
|
-
visit(def.parser, consumed);
|
|
16651
|
-
if (def.triviaParser) visit(def.triviaParser, false);
|
|
16652
|
-
return;
|
|
16653
|
-
case "recover":
|
|
16654
|
-
visit(def.parser, consumed);
|
|
16655
|
-
visit(def.sentinel, false);
|
|
16656
|
-
return;
|
|
16657
|
-
case "token":
|
|
16658
|
-
visit(def.parser, false);
|
|
16659
|
-
return;
|
|
16660
|
-
case "label":
|
|
16661
|
-
case "trivia":
|
|
16662
|
-
case "attempt":
|
|
16663
|
-
case "withCtx":
|
|
16664
|
-
case "expect":
|
|
16665
|
-
visit(def.parser, consumed);
|
|
16666
|
-
return;
|
|
16667
|
-
case "leaf":
|
|
16668
|
-
visit(def.parser, true);
|
|
16669
|
-
return;
|
|
16670
|
-
case "lazy":
|
|
16671
|
-
return;
|
|
16672
|
-
default:
|
|
16673
|
-
return;
|
|
16674
|
-
}
|
|
16675
|
-
};
|
|
16676
|
-
const resolveRoot = (c) => {
|
|
16677
|
-
const guard = /* @__PURE__ */ new Set();
|
|
16678
|
-
let cur = c;
|
|
16679
|
-
while (!guard.has(cur)) {
|
|
16680
|
-
const d = cur._def;
|
|
16681
|
-
if (d.tag === "grammar") {
|
|
16682
|
-
guard.add(cur);
|
|
16683
|
-
cur = d.parser;
|
|
16684
|
-
continue;
|
|
16685
|
-
}
|
|
16686
|
-
if (d.tag !== "lazy") return cur;
|
|
16687
|
-
guard.add(cur);
|
|
16688
|
-
try {
|
|
16689
|
-
cur = d.thunk();
|
|
16690
|
-
} catch {
|
|
16691
|
-
return c;
|
|
16692
|
-
}
|
|
16693
|
-
}
|
|
16694
|
-
return cur;
|
|
16695
|
-
};
|
|
16696
|
-
visit(resolveRoot(root), true);
|
|
17957
|
+
}
|
|
17958
|
+
return report;
|
|
17959
|
+
}
|
|
17960
|
+
function runDuplicationDiagnostic(combinator, opt) {
|
|
17961
|
+
return reportDuplication(opt, (o) => analyzeDuplication(combinator, o));
|
|
17962
|
+
}
|
|
17963
|
+
function runDuplicationDiagnosticRules(ruleMap, opt) {
|
|
17964
|
+
return reportDuplication(opt, (o) => analyzeDuplicationRules(ruleMap, o));
|
|
16697
17965
|
}
|
|
16698
17966
|
|
|
16699
|
-
// src/
|
|
16700
|
-
function
|
|
16701
|
-
|
|
16702
|
-
const errors = annotated.errors;
|
|
16703
|
-
if (errors) {
|
|
16704
|
-
;
|
|
16705
|
-
annotated.errors = errors.map((error) => ({
|
|
16706
|
-
...error,
|
|
16707
|
-
span: annotateSpan(error.span, index)
|
|
16708
|
-
}));
|
|
16709
|
-
}
|
|
16710
|
-
return annotated;
|
|
17967
|
+
// src/table/compile-rule-map.ts
|
|
17968
|
+
function resolveHostMode(ruleMap, explicit) {
|
|
17969
|
+
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
16711
17970
|
}
|
|
16712
|
-
function
|
|
16713
|
-
|
|
16714
|
-
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
16715
|
-
return { lineIndex, lineScannedTo: pos };
|
|
17971
|
+
function resolveTrackLines(ruleMap, explicit) {
|
|
17972
|
+
return explicit === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
16716
17973
|
}
|
|
16717
|
-
|
|
16718
|
-
|
|
16719
|
-
|
|
16720
|
-
|
|
16721
|
-
|
|
16722
|
-
|
|
16723
|
-
|
|
16724
|
-
|
|
16725
|
-
|
|
16726
|
-
|
|
16727
|
-
|
|
16728
|
-
|
|
16729
|
-
|
|
16730
|
-
|
|
16731
|
-
|
|
16732
|
-
|
|
16733
|
-
const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
|
|
16734
|
-
const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
|
|
16735
|
-
const rootScalar = scalarOf(root);
|
|
16736
|
-
const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
|
|
16737
|
-
const parseScalar = scalarEligible ? (input, pos, ctx) => {
|
|
16738
|
-
const savedTrivia = ctx.trivia;
|
|
16739
|
-
const savedLabels = ctx.triviaKindLabels;
|
|
16740
|
-
if (clearTrivia) {
|
|
16741
|
-
ctx.trivia = void 0;
|
|
16742
|
-
ctx.triviaKindLabels = void 0;
|
|
16743
|
-
} else if (scopeTrivia !== void 0) {
|
|
16744
|
-
ctx.trivia = scopeTrivia;
|
|
16745
|
-
ctx.triviaKindLabels = scopeLabels;
|
|
16746
|
-
}
|
|
16747
|
-
const end = rootScalar(input, pos, ctx);
|
|
16748
|
-
ctx.trivia = savedTrivia;
|
|
16749
|
-
ctx.triviaKindLabels = savedLabels;
|
|
16750
|
-
return end;
|
|
16751
|
-
} : void 0;
|
|
16752
|
-
let publicScalar;
|
|
16753
|
-
const grammar = {
|
|
16754
|
-
_tag: "grammar",
|
|
16755
|
-
_meta: {
|
|
16756
|
-
...root._meta,
|
|
16757
|
-
// Trivia classification describes this grammar's own active trivia
|
|
16758
|
-
// scope. A directly nested grammar may have classified trivia of its
|
|
16759
|
-
// own, but that must not advertise classification for this wrapper.
|
|
16760
|
-
triviaKindLabels: void 0,
|
|
16761
|
-
rootTriviaClassified: void 0,
|
|
16762
|
-
...opts.trivia?._meta?.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {},
|
|
16763
|
-
...opts.trivia?._meta?.rootTriviaClassified ? { rootTriviaClassified: true } : {}
|
|
16764
|
-
},
|
|
16765
|
-
_def: {
|
|
16766
|
-
tag: "grammar",
|
|
16767
|
-
parser: root,
|
|
16768
|
-
triviaParser: scopeTrivia,
|
|
16769
|
-
clearTrivia,
|
|
16770
|
-
...opaqueRootCapture ? { rootCapture: "opaque" } : {},
|
|
16771
|
-
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
16772
|
-
trackLines: opts.trackLines ?? false,
|
|
16773
|
-
constructionTrackLines: trackLinesPolicy,
|
|
16774
|
-
...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
|
|
16775
|
-
},
|
|
16776
|
-
_parseScalar: parseScalar,
|
|
16777
|
-
parse(input, pos, _ctx) {
|
|
16778
|
-
if (pos === void 0 && _ctx === void 0) {
|
|
16779
|
-
publicScalar ??= scalarRootOf(grammar) ?? null;
|
|
16780
|
-
if (publicScalar) {
|
|
16781
|
-
const ctx2 = createParseContext();
|
|
16782
|
-
const end = publicScalar(input, 0, ctx2);
|
|
16783
|
-
if (end < 0) {
|
|
16784
|
-
const at = ~end;
|
|
16785
|
-
return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
|
|
16786
|
-
}
|
|
16787
|
-
return { ok: true, value: ctx2._sv, span: { start: 0, end } };
|
|
17974
|
+
function withAmbient(ruleMap, opts) {
|
|
17975
|
+
if (opts.trivia === void 0 && opts.scanSkip === void 0) return ruleMap;
|
|
17976
|
+
const wrappers = /* @__PURE__ */ new Map();
|
|
17977
|
+
return ruleMap.map(([name, rule2]) => {
|
|
17978
|
+
if (rule2._meta.isTrivia) return [name, rule2];
|
|
17979
|
+
const addTrivia = opts.trivia !== void 0 && rule2._meta.grammarTrivia === void 0;
|
|
17980
|
+
const addScanSkip = opts.scanSkip !== void 0 && rule2._meta.grammarScanSkip === void 0;
|
|
17981
|
+
if (!addTrivia && !addScanSkip) return [name, rule2];
|
|
17982
|
+
let wrapped = wrappers.get(rule2);
|
|
17983
|
+
if (wrapped === void 0) {
|
|
17984
|
+
wrapped = {
|
|
17985
|
+
...rule2,
|
|
17986
|
+
_meta: {
|
|
17987
|
+
...rule2._meta,
|
|
17988
|
+
...addTrivia ? { grammarTrivia: opts.trivia } : {},
|
|
17989
|
+
...addScanSkip ? { grammarScanSkip: opts.scanSkip } : {}
|
|
16788
17990
|
}
|
|
16789
|
-
}
|
|
16790
|
-
|
|
16791
|
-
const trackLines = trackLinesOf(_ctx);
|
|
16792
|
-
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
16793
|
-
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
16794
|
-
const ctx = _ctx === void 0 ? createParseContext() : { ..._ctx };
|
|
16795
|
-
ctx.trackLines = trackLines;
|
|
16796
|
-
if (lineIndex) ctx._lineIndex = lineIndex;
|
|
16797
|
-
if (lineContext) ctx._lineScannedTo = lineContext.lineScannedTo;
|
|
16798
|
-
if (clearTrivia) {
|
|
16799
|
-
ctx.trivia = void 0;
|
|
16800
|
-
ctx.triviaKindLabels = void 0;
|
|
16801
|
-
} else if (scopeTrivia !== void 0) {
|
|
16802
|
-
ctx.trivia = scopeTrivia;
|
|
16803
|
-
if (scopeLabels) ctx.triviaKindLabels = scopeLabels;
|
|
16804
|
-
}
|
|
16805
|
-
if (forceCaptureTrivia || _ctx?.captureTrivia) ctx.captureTrivia = true;
|
|
16806
|
-
if (ownCaptureMask !== void 0) ctx._triviaCaptureMask = ownCaptureMask;
|
|
16807
|
-
else if (inheritCaptureMask) ctx._triviaCaptureMask = triviaKindMask(_ctx?.triviaKindLabels, captureKinds);
|
|
16808
|
-
if (opaqueRootCapture) ctx._rootTriviaCapture = false;
|
|
16809
|
-
const result = root.parse(input, pos ?? 0, ctx);
|
|
16810
|
-
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
16811
|
-
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
16812
|
-
}
|
|
16813
|
-
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
17991
|
+
};
|
|
17992
|
+
wrappers.set(rule2, wrapped);
|
|
16814
17993
|
}
|
|
17994
|
+
return [name, wrapped];
|
|
17995
|
+
});
|
|
17996
|
+
}
|
|
17997
|
+
function compileRuleMapRunnable(ruleMap, opts = {}) {
|
|
17998
|
+
const encoded = encodeForRun(ruleMap, opts);
|
|
17999
|
+
if (encoded === null) return null;
|
|
18000
|
+
const { prog, hostMode, plan } = encoded;
|
|
18001
|
+
const artifact = closureArtifact(prog);
|
|
18002
|
+
const reflection = collectGrammarReflection(ruleMap);
|
|
18003
|
+
return {
|
|
18004
|
+
keys: ruleMap.map(([key]) => key),
|
|
18005
|
+
hostMode,
|
|
18006
|
+
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule2]) => hasDirectBuildDef(rule2)),
|
|
18007
|
+
reflection,
|
|
18008
|
+
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
18009
|
+
// Reflection rides on the map's metadata prototype from birth. Only `compile()`
|
|
18010
|
+
// asks to specialise; every other caller runs the closure artifact.
|
|
18011
|
+
rules: tableRules(opts.specialise === true ? prog : artifact, { [GRAMMAR_REFLECTION]: reflection }),
|
|
18012
|
+
prog: artifact
|
|
16815
18013
|
};
|
|
16816
|
-
return grammar;
|
|
16817
18014
|
}
|
|
16818
|
-
|
|
16819
|
-
|
|
16820
|
-
|
|
16821
|
-
|
|
16822
|
-
|
|
16823
|
-
|
|
16824
|
-
|
|
16825
|
-
|
|
16826
|
-
|
|
16827
|
-
|
|
16828
|
-
|
|
16829
|
-
|
|
16830
|
-
|
|
16831
|
-
|
|
16832
|
-
|
|
16833
|
-
|
|
16834
|
-
|
|
16835
|
-
|
|
16836
|
-
|
|
16837
|
-
|
|
16838
|
-
if (grammarTrivia !== void 0) {
|
|
16839
|
-
ctx.trivia = grammarTrivia;
|
|
16840
|
-
if (grammarTrivia._meta.triviaKindLabels) ctx.triviaKindLabels = grammarTrivia._meta.triviaKindLabels;
|
|
18015
|
+
function encodeForRun(ruleMap, opts) {
|
|
18016
|
+
runDuplicationDiagnosticRules(ruleMap, opts.duplication);
|
|
18017
|
+
const encodeMap = withAmbient(ruleMap, opts);
|
|
18018
|
+
const plan = opts.coverage === true ? buildGrammarPlan(
|
|
18019
|
+
encodeMap.map(([, rule2]) => rule2),
|
|
18020
|
+
Object.fromEntries(encodeMap.filter(([, rule2]) => rule2._def.tag !== "lazy"))
|
|
18021
|
+
) : void 0;
|
|
18022
|
+
const hostMode = resolveHostMode(ruleMap, opts.hostMode);
|
|
18023
|
+
const settings = {
|
|
18024
|
+
hostMode,
|
|
18025
|
+
...resolveTrackLines(ruleMap, opts.trackLines) ? { trackLines: true } : {},
|
|
18026
|
+
...opts.recovery === true ? { recovery: true } : {},
|
|
18027
|
+
...plan === void 0 ? {} : { coverage: plan }
|
|
18028
|
+
};
|
|
18029
|
+
try {
|
|
18030
|
+
const { prog, fnSrcs } = encodeTableProgram(Object.fromEntries(encodeMap), settings);
|
|
18031
|
+
return { prog, fnSrcs, hostMode, plan };
|
|
18032
|
+
} catch (e) {
|
|
18033
|
+
opts.refusals?.push(e instanceof Error ? e.message : String(e));
|
|
18034
|
+
return null;
|
|
16841
18035
|
}
|
|
16842
|
-
if (grammarScanSkip !== void 0) ctx.scanSkip = grammarScanSkip;
|
|
16843
|
-
if (_errors !== void 0) ctx._errors = _errors;
|
|
16844
|
-
if (_probe !== void 0) ctx._probe = _probe;
|
|
16845
|
-
const result = combinator.parse(input, 0, ctx);
|
|
16846
|
-
if (!result.ok) return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
16847
|
-
const withErrors = _errors !== void 0 ? { ...result, errors: _errors, furthestFail: _probe?.best ?? null } : result;
|
|
16848
|
-
return lineIndex ? annotateResultLines(withErrors, normalizeLineIndex(lineIndex)) : withErrors;
|
|
16849
18036
|
}
|
|
16850
18037
|
|
|
16851
18038
|
// src/compiler/linker.ts
|
|
@@ -16945,7 +18132,7 @@ function analyzeGrammarGating(grammar, opts) {
|
|
|
16945
18132
|
}
|
|
16946
18133
|
|
|
16947
18134
|
// src/analysis/diagnose.ts
|
|
16948
|
-
var
|
|
18135
|
+
var isCombinator2 = (g) => typeof g === "object" && g !== null && "_def" in g;
|
|
16949
18136
|
var isRuleEntries = (g) => Array.isArray(g);
|
|
16950
18137
|
function diagnoseGrammar(grammar, opts) {
|
|
16951
18138
|
const depth = degradationCaptureDepth();
|
|
@@ -16966,7 +18153,7 @@ function examinedNothing(d) {
|
|
|
16966
18153
|
return d.summary.totalChoices === 0 && d.summary.unanalysable > 0;
|
|
16967
18154
|
}
|
|
16968
18155
|
function runAnalysis(grammar, opts) {
|
|
16969
|
-
if (
|
|
18156
|
+
if (isCombinator2(grammar)) return analyzeGating(grammar, opts);
|
|
16970
18157
|
if (isRuleEntries(grammar)) return analyzeGatingRules(grammar, opts);
|
|
16971
18158
|
return analyzeGrammarGating(grammar, opts);
|
|
16972
18159
|
}
|
|
@@ -17725,16 +18912,16 @@ function ownSource(fn) {
|
|
|
17725
18912
|
return typeof name === "string" && name.length > 0 && globalThis[name] === fn ? name : null;
|
|
17726
18913
|
}
|
|
17727
18914
|
function compile(target, second, third) {
|
|
17728
|
-
if (!
|
|
18915
|
+
if (!isCombinator3(target)) return compileMap(target, second);
|
|
17729
18916
|
return compileRoot(target, second, third);
|
|
17730
18917
|
}
|
|
17731
|
-
function
|
|
18918
|
+
function isCombinator3(x) {
|
|
17732
18919
|
return typeof x === "object" && x !== null && typeof x.parse === "function" && "_def" in x;
|
|
17733
18920
|
}
|
|
17734
18921
|
function compileMap(grammar, opts = {}) {
|
|
17735
18922
|
const entries = [];
|
|
17736
18923
|
for (const [key, value] of Object.entries(grammar)) {
|
|
17737
|
-
if (!
|
|
18924
|
+
if (!isCombinator3(value)) throw new TypeError(`compile: grammar entry "${key}" is not a parser`);
|
|
17738
18925
|
if (value._def.tag === "lazy") {
|
|
17739
18926
|
try {
|
|
17740
18927
|
value._def.thunk();
|
|
@@ -18048,49 +19235,6 @@ function digestValue(value, prefix = "", options) {
|
|
|
18048
19235
|
return sha.digest("hex");
|
|
18049
19236
|
}
|
|
18050
19237
|
|
|
18051
|
-
// src/combinators/attempt.ts
|
|
18052
|
-
function containOption(options) {
|
|
18053
|
-
if (options === void 0) return false;
|
|
18054
|
-
for (const key of Object.keys(options)) {
|
|
18055
|
-
if (key !== "contain") throw new TypeError(`attempt(): unknown option ${JSON.stringify(key)}`);
|
|
18056
|
-
}
|
|
18057
|
-
if (options.contain !== void 0 && typeof options.contain !== "boolean") {
|
|
18058
|
-
throw new TypeError("attempt(): `contain` must be a boolean");
|
|
18059
|
-
}
|
|
18060
|
-
return options.contain === true;
|
|
18061
|
-
}
|
|
18062
|
-
function attempt(parser2, options) {
|
|
18063
|
-
const contain = containOption(options);
|
|
18064
|
-
const guardable = parser2._meta.firstSet.kind !== "any" && !matchesEmpty(parser2);
|
|
18065
|
-
let failExpected;
|
|
18066
|
-
return {
|
|
18067
|
-
_tag: "attempt",
|
|
18068
|
-
_meta: parser2._meta,
|
|
18069
|
-
_def: contain ? { tag: "attempt", parser: parser2, contain: true } : { tag: "attempt", parser: parser2 },
|
|
18070
|
-
parse(input, pos, ctx) {
|
|
18071
|
-
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(parser2, input, pos)) {
|
|
18072
|
-
if (failExpected === void 0) {
|
|
18073
|
-
const e = deriveExpected(parser2);
|
|
18074
|
-
failExpected = e.length > 0 ? e : [parser2._tag];
|
|
18075
|
-
}
|
|
18076
|
-
return { ok: false, expected: failExpected, span: { start: pos, end: pos } };
|
|
18077
|
-
}
|
|
18078
|
-
const mark = saveCstMark(ctx);
|
|
18079
|
-
const log = ctx._triviaLog?.length;
|
|
18080
|
-
const rootLog = ctx._rootTriviaLog?.length;
|
|
18081
|
-
const split = ctx._columnsSplit;
|
|
18082
|
-
const result = parser2.parse(input, pos, ctx);
|
|
18083
|
-
if (result.ok) return result;
|
|
18084
|
-
rollbackCstCapture(ctx, mark);
|
|
18085
|
-
ctx._columnsSplit = split;
|
|
18086
|
-
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
18087
|
-
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
18088
|
-
if (result.committed && !contain) return result;
|
|
18089
|
-
return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
|
|
18090
|
-
}
|
|
18091
|
-
};
|
|
18092
|
-
}
|
|
18093
|
-
|
|
18094
19238
|
// src/combinators/not.ts
|
|
18095
19239
|
function not(combinator) {
|
|
18096
19240
|
const meta = {
|