parseman 0.57.0 → 0.58.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/diagnostics.js +1800 -962
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +1929 -1091
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts +11 -1
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +69 -16
- package/dist/compiler/token-capability.js.map +2 -2
- package/dist/cst/capture-buffer.d.ts +6 -0
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.js +1017 -177
- package/dist/index.js.map +3 -3
- package/dist/plugin/index.d.ts +25 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1210 -236
- package/dist/plugin/index.js.map +3 -3
- package/dist/run/index.d.ts +2 -0
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +9 -0
- package/dist/run/index.js.map +1 -1
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +1 -1
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/factor-choice.d.ts +42 -0
- package/dist/table/factor-choice.d.ts.map +1 -0
- package/dist/table/fail-clean.d.ts +3 -0
- package/dist/table/fail-clean.d.ts.map +1 -0
- package/dist/table/hold-gap.d.ts +8 -0
- package/dist/table/hold-gap.d.ts.map +1 -0
- package/dist/table/index.js +1370 -259
- package/dist/table/index.js.map +3 -3
- package/dist/table/lex-program.d.ts +7 -3
- package/dist/table/lex-program.d.ts.map +1 -1
- package/dist/table/ops.d.ts +8 -0
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/run-support.d.ts +19 -0
- package/dist/table/run-support.d.ts.map +1 -1
- package/dist/table/scalar-terminal.d.ts +2 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -1
- package/dist/table/site-labels.d.ts +66 -0
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/combinators/dispatch.ts +12 -3
- package/src/compiler/token-alphabet.ts +57 -17
- package/src/cst/capture-buffer.ts +25 -0
- package/src/plugin/index.ts +230 -35
- package/src/run/index.ts +5 -0
- package/src/table/assemble.ts +252 -62
- package/src/table/child-slots.ts +2 -2
- package/src/table/compile-rule-map.ts +14 -5
- package/src/table/emit-assembly.ts +112 -23
- package/src/table/emit.ts +3 -1
- package/src/table/encode.ts +83 -14
- package/src/table/exec.ts +27 -8
- package/src/table/factor-choice.ts +173 -0
- package/src/table/fail-clean.ts +130 -0
- package/src/table/hold-gap.ts +68 -0
- package/src/table/lex-program.ts +197 -43
- package/src/table/ops.ts +9 -1
- package/src/table/run-support.ts +35 -0
- package/src/table/scalar-terminal.ts +8 -0
- package/src/table/site-labels.ts +135 -4
- package/src/version.ts +1 -1
package/dist/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) {
|
|
@@ -2395,10 +2420,16 @@ function branchUsesRouted(branch) {
|
|
|
2395
2420
|
return branch.usesRouted === true || parserUsesRouted(branch.parser);
|
|
2396
2421
|
}
|
|
2397
2422
|
function asciiFoldKey(key) {
|
|
2398
|
-
let
|
|
2399
|
-
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++) {
|
|
2400
2431
|
const c = key.charCodeAt(i);
|
|
2401
|
-
out +=
|
|
2432
|
+
out += c >= 65 && c <= 90 ? String.fromCharCode(c + 32) : key[i];
|
|
2402
2433
|
}
|
|
2403
2434
|
return out;
|
|
2404
2435
|
}
|
|
@@ -2727,6 +2758,42 @@ function keywords(words, opts = {}) {
|
|
|
2727
2758
|
};
|
|
2728
2759
|
}
|
|
2729
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
|
+
|
|
2730
2797
|
// src/compiler/token-alphabet.ts
|
|
2731
2798
|
function optionalSuffixLexBody(ir) {
|
|
2732
2799
|
if (ir.kind !== "sequence" || ir.parts.length !== 2) return void 0;
|
|
@@ -2746,7 +2813,10 @@ function selectOptionalSuffixLexBody(ir) {
|
|
|
2746
2813
|
const token2 = { strategy: "token", estimatedOps: 2, body };
|
|
2747
2814
|
return token2.estimatedOps < character.estimatedOps ? token2 : character;
|
|
2748
2815
|
}
|
|
2749
|
-
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) {
|
|
2750
2820
|
const outer = parser2._def;
|
|
2751
2821
|
if (outer.tag !== "token") return void 0;
|
|
2752
2822
|
let body = outer.parser;
|
|
@@ -2756,12 +2826,13 @@ function directTokenBodyParser(parser2, resolve2) {
|
|
|
2756
2826
|
const wrapper = body._def;
|
|
2757
2827
|
if (wrapper.tag === "grammar") {
|
|
2758
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;
|
|
2759
2830
|
body = wrapper.parser;
|
|
2760
2831
|
continue;
|
|
2761
2832
|
}
|
|
2762
2833
|
if (wrapper.tag === "lazy") {
|
|
2763
2834
|
const target = resolvedLazyTarget(body, resolve2);
|
|
2764
|
-
if (target === void 0) return void 0;
|
|
2835
|
+
if (target === void 0 || reinstallsRuleTrivia(body, target)) return void 0;
|
|
2765
2836
|
body = target;
|
|
2766
2837
|
continue;
|
|
2767
2838
|
}
|
|
@@ -2933,7 +3004,7 @@ function directNot2TokenBody(parser2, resolve2) {
|
|
|
2933
3004
|
terminal
|
|
2934
3005
|
};
|
|
2935
3006
|
}
|
|
2936
|
-
function directFixedLexNode(parser2, resolve2, active, pureOnly = false) {
|
|
3007
|
+
function directFixedLexNode(parser2, resolve2, active, pureOnly = false, cleared = false) {
|
|
2937
3008
|
let current = parser2;
|
|
2938
3009
|
const wrappers = /* @__PURE__ */ new Set();
|
|
2939
3010
|
while (!wrappers.has(current)) {
|
|
@@ -2941,7 +3012,7 @@ function directFixedLexNode(parser2, resolve2, active, pureOnly = false) {
|
|
|
2941
3012
|
const def = current._def;
|
|
2942
3013
|
if (def.tag === "lazy") {
|
|
2943
3014
|
const target = resolvedLazyTarget(current, resolve2);
|
|
2944
|
-
if (target === void 0) return void 0;
|
|
3015
|
+
if (target === void 0 || reinstallsRuleTrivia(current, target)) return void 0;
|
|
2945
3016
|
current = target;
|
|
2946
3017
|
continue;
|
|
2947
3018
|
}
|
|
@@ -2959,30 +3030,33 @@ function directFixedLexNode(parser2, resolve2, active, pureOnly = false) {
|
|
|
2959
3030
|
if (terminal !== void 0) return { kind: "terminal", terminal };
|
|
2960
3031
|
const def = current._def;
|
|
2961
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
|
+
}
|
|
2962
3036
|
if (!pureOnly || def.parser._def.tag !== "token" && (def.clearTrivia !== true || def.triviaParser !== void 0 || def.captureTrivia === true || def.rootCapture === "opaque")) return void 0;
|
|
2963
|
-
return directFixedLexNode(def.parser, resolve2, active, true);
|
|
3037
|
+
return directFixedLexNode(def.parser, resolve2, active, true, cleared);
|
|
2964
3038
|
}
|
|
2965
3039
|
if (def.tag === "sequence") {
|
|
2966
3040
|
if (def.parsers.length < 2 || def.parsers.length > 5) return void 0;
|
|
2967
|
-
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve2, active, pureOnly));
|
|
3041
|
+
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve2, active, pureOnly, cleared));
|
|
2968
3042
|
if (parts.some((part) => part === void 0)) return void 0;
|
|
2969
3043
|
return { kind: "sequence", parts };
|
|
2970
3044
|
}
|
|
2971
3045
|
if (def.tag === "choice") {
|
|
2972
|
-
if (def.parsers.length
|
|
2973
|
-
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));
|
|
2974
3048
|
if (arms.some((arm) => arm === void 0)) return void 0;
|
|
2975
|
-
const final = classifyFinalChoice(def.parsers, resolve2);
|
|
2976
3049
|
return {
|
|
2977
3050
|
kind: "choice",
|
|
2978
3051
|
arms,
|
|
2979
|
-
|
|
3052
|
+
parsers: def.parsers,
|
|
3053
|
+
cleared,
|
|
2980
3054
|
armExpected: def.parsers.map(deriveExpected),
|
|
2981
3055
|
expected: def.parsers.flatMap(deriveExpected)
|
|
2982
3056
|
};
|
|
2983
3057
|
}
|
|
2984
3058
|
if (def.tag === "not") {
|
|
2985
|
-
const body = directFixedLexNode(def.parser, resolve2, active, true);
|
|
3059
|
+
const body = directFixedLexNode(def.parser, resolve2, active, true, cleared);
|
|
2986
3060
|
return body === void 0 ? void 0 : {
|
|
2987
3061
|
kind: "not",
|
|
2988
3062
|
body,
|
|
@@ -2990,18 +3064,28 @@ function directFixedLexNode(parser2, resolve2, active, pureOnly = false) {
|
|
|
2990
3064
|
};
|
|
2991
3065
|
}
|
|
2992
3066
|
if (def.tag === "optional") {
|
|
2993
|
-
const body = directFixedLexNode(def.parser, resolve2, active, pureOnly);
|
|
3067
|
+
const body = directFixedLexNode(def.parser, resolve2, active, pureOnly, cleared);
|
|
2994
3068
|
return body === void 0 ? void 0 : { kind: "optional", body };
|
|
2995
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
|
+
}
|
|
2996
3079
|
return void 0;
|
|
2997
3080
|
} finally {
|
|
2998
3081
|
active.delete(current);
|
|
2999
3082
|
}
|
|
3000
3083
|
}
|
|
3001
3084
|
function directFixedTokenBody(parser2, resolve2) {
|
|
3002
|
-
const
|
|
3085
|
+
const scope = { cleared: false };
|
|
3086
|
+
const body = directTokenBodyParser(parser2, resolve2, scope);
|
|
3003
3087
|
if (body === void 0) return void 0;
|
|
3004
|
-
const root = directFixedLexNode(body, resolve2, /* @__PURE__ */ new Set());
|
|
3088
|
+
const root = directFixedLexNode(body, resolve2, /* @__PURE__ */ new Set(), false, scope.cleared);
|
|
3005
3089
|
return root === void 0 ? void 0 : { kind: "fixed-tree", root };
|
|
3006
3090
|
}
|
|
3007
3091
|
function directBalancedTokenBody(parser2, resolve2) {
|
|
@@ -4910,17 +4994,59 @@ function buildLexBodyRecognizer(spec, constants) {
|
|
|
4910
4994
|
};
|
|
4911
4995
|
}
|
|
4912
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
|
+
|
|
4913
5040
|
// src/table/lex-program.ts
|
|
4914
5041
|
var LEX_NODE_TERMINAL = 0;
|
|
4915
5042
|
var LEX_NODE_SEQUENCE2 = 1;
|
|
4916
5043
|
var LEX_NODE_SEQUENCE3 = 2;
|
|
4917
5044
|
var LEX_NODE_SEQUENCE4 = 3;
|
|
4918
5045
|
var LEX_NODE_SEQUENCE5 = 4;
|
|
4919
|
-
var
|
|
4920
|
-
var LEX_NODE_CHOICE4 = 6;
|
|
4921
|
-
var LEX_NODE_CHOICE8 = 7;
|
|
5046
|
+
var LEX_NODE_CHOICE = 5;
|
|
4922
5047
|
var LEX_NODE_NOT = 8;
|
|
4923
5048
|
var LEX_NODE_OPTIONAL = 9;
|
|
5049
|
+
var LEX_NODE_REPEAT = 10;
|
|
4924
5050
|
function lexProgramDigest(words) {
|
|
4925
5051
|
let hash = 2166136261;
|
|
4926
5052
|
for (const word of words) {
|
|
@@ -4949,85 +5075,114 @@ function trackLexLines(ctx, input, end) {
|
|
|
4949
5075
|
ctx._lineScannedTo = end;
|
|
4950
5076
|
}
|
|
4951
5077
|
function terminalNode(matcher, failure, tracksLines) {
|
|
4952
|
-
const match = (input, pos) => {
|
|
4953
|
-
const result = matcher(input, pos);
|
|
4954
|
-
return result < 0 ? -1 : result / 2;
|
|
4955
|
-
};
|
|
4956
5078
|
return {
|
|
4957
|
-
match,
|
|
5079
|
+
match: (input, pos) => {
|
|
5080
|
+
const result = matcher(input, pos);
|
|
5081
|
+
return result < 0 ? -1 : result / 2;
|
|
5082
|
+
},
|
|
4958
5083
|
run: (input, pos, ctx) => {
|
|
4959
|
-
const
|
|
4960
|
-
if (
|
|
5084
|
+
const result = matcher(input, pos);
|
|
5085
|
+
if (result < 0) {
|
|
4961
5086
|
ctx._fe = pos;
|
|
4962
5087
|
ctx._fx = failure;
|
|
4963
5088
|
if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
|
|
4964
5089
|
return -1;
|
|
4965
5090
|
}
|
|
5091
|
+
const end = result / 2;
|
|
4966
5092
|
if (tracksLines) trackLexLines(ctx, input, end);
|
|
4967
5093
|
return end;
|
|
4968
5094
|
}
|
|
4969
5095
|
};
|
|
4970
5096
|
}
|
|
4971
5097
|
function sequence2(a, b) {
|
|
5098
|
+
const am = a.match, bm = b.match, ar = a.run, br = b.run;
|
|
4972
5099
|
return {
|
|
4973
5100
|
match: (input, pos) => {
|
|
4974
|
-
const e0 =
|
|
4975
|
-
return e0 < 0 ? -1 :
|
|
5101
|
+
const e0 = am(input, pos);
|
|
5102
|
+
return e0 < 0 ? -1 : bm(input, e0);
|
|
4976
5103
|
},
|
|
4977
5104
|
run: (input, pos, ctx) => {
|
|
4978
|
-
const e0 =
|
|
5105
|
+
const e0 = ar(input, pos, ctx);
|
|
4979
5106
|
if (e0 < 0) return -1;
|
|
4980
5107
|
ctx._fc = false;
|
|
4981
|
-
return
|
|
5108
|
+
return br(input, e0, ctx);
|
|
4982
5109
|
}
|
|
4983
5110
|
};
|
|
4984
5111
|
}
|
|
4985
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;
|
|
4986
5114
|
return {
|
|
4987
5115
|
match: (input, pos) => {
|
|
4988
|
-
const e0 =
|
|
5116
|
+
const e0 = am(input, pos);
|
|
4989
5117
|
if (e0 < 0) return -1;
|
|
4990
|
-
const e1 =
|
|
4991
|
-
return e1 < 0 ? -1 :
|
|
5118
|
+
const e1 = bm(input, e0);
|
|
5119
|
+
return e1 < 0 ? -1 : cm(input, e1);
|
|
4992
5120
|
},
|
|
4993
5121
|
run: (input, pos, ctx) => {
|
|
4994
|
-
const e0 =
|
|
5122
|
+
const e0 = ar(input, pos, ctx);
|
|
4995
5123
|
if (e0 < 0) return -1;
|
|
4996
5124
|
ctx._fc = false;
|
|
4997
|
-
const e1 =
|
|
5125
|
+
const e1 = br(input, e0, ctx);
|
|
4998
5126
|
if (e1 < 0) return -1;
|
|
4999
5127
|
ctx._fc = false;
|
|
5000
|
-
return
|
|
5128
|
+
return cr(input, e1, ctx);
|
|
5001
5129
|
}
|
|
5002
5130
|
};
|
|
5003
5131
|
}
|
|
5004
5132
|
function sequence4(a, b, c, d) {
|
|
5005
|
-
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;
|
|
5006
5135
|
return {
|
|
5007
5136
|
match: (input, pos) => {
|
|
5008
|
-
const
|
|
5009
|
-
|
|
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);
|
|
5010
5143
|
},
|
|
5011
5144
|
run: (input, pos, ctx) => {
|
|
5012
|
-
const
|
|
5013
|
-
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;
|
|
5014
5150
|
ctx._fc = false;
|
|
5015
|
-
|
|
5151
|
+
const e2 = cr(input, e1, ctx);
|
|
5152
|
+
if (e2 < 0) return -1;
|
|
5153
|
+
ctx._fc = false;
|
|
5154
|
+
return dr(input, e2, ctx);
|
|
5016
5155
|
}
|
|
5017
5156
|
};
|
|
5018
5157
|
}
|
|
5019
5158
|
function sequence5(a, b, c, d, e) {
|
|
5020
|
-
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;
|
|
5021
5161
|
return {
|
|
5022
5162
|
match: (input, pos) => {
|
|
5023
|
-
const
|
|
5024
|
-
|
|
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);
|
|
5025
5171
|
},
|
|
5026
5172
|
run: (input, pos, ctx) => {
|
|
5027
|
-
const
|
|
5028
|
-
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;
|
|
5029
5184
|
ctx._fc = false;
|
|
5030
|
-
return
|
|
5185
|
+
return er(input, e3, ctx);
|
|
5031
5186
|
}
|
|
5032
5187
|
};
|
|
5033
5188
|
}
|
|
@@ -5040,9 +5195,9 @@ function appendExpected(acc, values) {
|
|
|
5040
5195
|
function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
5041
5196
|
let matchTail = () => -1;
|
|
5042
5197
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5043
|
-
const
|
|
5198
|
+
const armMatch = arms[i].match, next = matchTail;
|
|
5044
5199
|
matchTail = (input, pos) => {
|
|
5045
|
-
const end =
|
|
5200
|
+
const end = armMatch(input, pos);
|
|
5046
5201
|
return end < 0 ? next(input, pos) : end;
|
|
5047
5202
|
};
|
|
5048
5203
|
}
|
|
@@ -5052,7 +5207,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5052
5207
|
return -1;
|
|
5053
5208
|
};
|
|
5054
5209
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5055
|
-
const
|
|
5210
|
+
const armRun = arms[i].run, cls = classes[i], staticExpected = armExpected[i], next = tail;
|
|
5056
5211
|
tail = (input, pos, ctx, lead2, acc, best) => {
|
|
5057
5212
|
if (cls !== void 0 && !classHas(cls, lead2)) {
|
|
5058
5213
|
return next(
|
|
@@ -5065,7 +5220,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5065
5220
|
);
|
|
5066
5221
|
}
|
|
5067
5222
|
ctx._fc = false;
|
|
5068
|
-
const end =
|
|
5223
|
+
const end = armRun(input, pos, ctx);
|
|
5069
5224
|
if (end >= 0) return end;
|
|
5070
5225
|
const at = ctx._fe ?? pos;
|
|
5071
5226
|
if (at > best) {
|
|
@@ -5092,11 +5247,58 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5092
5247
|
)
|
|
5093
5248
|
};
|
|
5094
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
|
+
}
|
|
5095
5296
|
function notNode(body, failure) {
|
|
5297
|
+
const bodyMatch = body.match;
|
|
5096
5298
|
return {
|
|
5097
|
-
match: (input, pos) =>
|
|
5299
|
+
match: (input, pos) => bodyMatch(input, pos) < 0 ? pos : -1,
|
|
5098
5300
|
run: (input, pos, ctx) => {
|
|
5099
|
-
if (
|
|
5301
|
+
if (bodyMatch(input, pos) < 0) return pos;
|
|
5100
5302
|
ctx._fe = pos;
|
|
5101
5303
|
ctx._fx = failure;
|
|
5102
5304
|
return -1;
|
|
@@ -5104,18 +5306,57 @@ function notNode(body, failure) {
|
|
|
5104
5306
|
};
|
|
5105
5307
|
}
|
|
5106
5308
|
function optionalNode(body) {
|
|
5309
|
+
const bodyMatch = body.match, bodyRun = body.run;
|
|
5107
5310
|
return {
|
|
5108
5311
|
match: (input, pos) => {
|
|
5109
|
-
const end =
|
|
5312
|
+
const end = bodyMatch(input, pos);
|
|
5110
5313
|
return end < 0 ? pos : end;
|
|
5111
5314
|
},
|
|
5112
5315
|
run: (input, pos, ctx) => {
|
|
5113
5316
|
ctx._fc = false;
|
|
5114
|
-
const end =
|
|
5317
|
+
const end = bodyRun(input, pos, ctx);
|
|
5115
5318
|
return end < 0 && !committed(ctx) ? pos : end;
|
|
5116
5319
|
}
|
|
5117
5320
|
};
|
|
5118
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
|
+
}
|
|
5119
5360
|
function fixedTreeRunner(words, matchers, classes, expected) {
|
|
5120
5361
|
const stack = [];
|
|
5121
5362
|
const pop = () => {
|
|
@@ -5143,9 +5384,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5143
5384
|
else stack.push(sequence5(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4]));
|
|
5144
5385
|
continue;
|
|
5145
5386
|
}
|
|
5146
|
-
if (op
|
|
5147
|
-
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");
|
|
5148
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
|
+
}
|
|
5149
5395
|
if (choiceFx === void 0) throw new TypeError("table lexical tree choice has an invalid expected set");
|
|
5150
5396
|
const armClasses = [];
|
|
5151
5397
|
const armFx = [];
|
|
@@ -5158,7 +5404,7 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5158
5404
|
armFx.push(fx);
|
|
5159
5405
|
}
|
|
5160
5406
|
const arms = Array.from({ length: count }, pop).reverse();
|
|
5161
|
-
stack.push(choiceNode(arms, armClasses, armFx, choiceFx));
|
|
5407
|
+
stack.push(exclusive === 1 ? exclusiveChoiceNode(arms, armClasses, choiceFx) : choiceNode(arms, armClasses, armFx, choiceFx));
|
|
5162
5408
|
continue;
|
|
5163
5409
|
}
|
|
5164
5410
|
if (op === LEX_NODE_NOT) {
|
|
@@ -5171,6 +5417,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5171
5417
|
stack.push(optionalNode(pop()));
|
|
5172
5418
|
continue;
|
|
5173
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
|
+
}
|
|
5174
5428
|
throw new TypeError("table lexical tree has an unknown fixed body");
|
|
5175
5429
|
}
|
|
5176
5430
|
if (stack.length !== 1) throw new TypeError("table lexical tree does not resolve to one root body");
|
|
@@ -5539,75 +5793,270 @@ function resolveTable(prog) {
|
|
|
5539
5793
|
return built;
|
|
5540
5794
|
}
|
|
5541
5795
|
|
|
5542
|
-
// src/
|
|
5543
|
-
function
|
|
5544
|
-
return
|
|
5796
|
+
// src/combinators/adjacency.ts
|
|
5797
|
+
function adjacencyOf(p) {
|
|
5798
|
+
return p._def.tag === "adjacency" ? p._def : null;
|
|
5545
5799
|
}
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
for (const d of list) {
|
|
5550
|
-
const bucket = byCode.get(d.code);
|
|
5551
|
-
if (bucket) bucket.push(d);
|
|
5552
|
-
else byCode.set(d.code, [d]);
|
|
5553
|
-
}
|
|
5554
|
-
const out = [];
|
|
5555
|
-
for (const [code, items] of byCode) {
|
|
5556
|
-
for (const d of items.slice(0, DETAIL_CAP)) out.push(formatDegradation(d));
|
|
5557
|
-
if (items.length > DETAIL_CAP) {
|
|
5558
|
-
out.push(
|
|
5559
|
-
`[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.`
|
|
5560
|
-
);
|
|
5561
|
-
}
|
|
5562
|
-
}
|
|
5563
|
-
return out;
|
|
5800
|
+
function adjacencyExpected(def) {
|
|
5801
|
+
if (def.polarity === "adjacent") return "adjacent";
|
|
5802
|
+
return def.kinds === void 0 ? "notAdjacent" : `notAdjacent(${def.kinds.join("|")})`;
|
|
5564
5803
|
}
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
_sinks.push(/* @__PURE__ */ new Map());
|
|
5804
|
+
function holdsAdjacency(input, cur, ctx, def) {
|
|
5805
|
+
return adjacencyHolds(input, cur, ctx, def.polarity === "notAdjacent", def.kinds);
|
|
5568
5806
|
}
|
|
5569
|
-
function
|
|
5570
|
-
|
|
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;
|
|
5571
5815
|
}
|
|
5572
|
-
function
|
|
5573
|
-
|
|
5574
|
-
while (_sinks.length > depth) {
|
|
5575
|
-
const sink = _sinks.pop();
|
|
5576
|
-
found.unshift(...sink.values());
|
|
5577
|
-
}
|
|
5578
|
-
return found;
|
|
5816
|
+
function adjacencyFail(pos, def) {
|
|
5817
|
+
return { ok: false, expected: [adjacencyExpected(def)], span: { start: pos, end: pos } };
|
|
5579
5818
|
}
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
if (env === "off" || env === "warn" || env === "error") return env;
|
|
5584
|
-
return "warn";
|
|
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}`);
|
|
5585
5822
|
}
|
|
5586
|
-
function
|
|
5587
|
-
|
|
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
|
+
};
|
|
5588
5840
|
}
|
|
5589
|
-
function
|
|
5590
|
-
|
|
5591
|
-
if (level === "off") return;
|
|
5592
|
-
const key = degradationKey(d);
|
|
5593
|
-
const sink = _sinks[_sinks.length - 1];
|
|
5594
|
-
if (sink) {
|
|
5595
|
-
if (!sink.has(key)) sink.set(key, d);
|
|
5596
|
-
return;
|
|
5597
|
-
}
|
|
5598
|
-
if (_immediate.has(key)) return;
|
|
5599
|
-
_immediate.add(key);
|
|
5600
|
-
if (level === "error") throw new Error(`parseman: degraded compilation path
|
|
5601
|
-
${formatDegradation(d)}`);
|
|
5602
|
-
console.warn(formatDegradation(d));
|
|
5841
|
+
function adjacent() {
|
|
5842
|
+
return adjacencyCombinator({ tag: "adjacency", polarity: "adjacent" });
|
|
5603
5843
|
}
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
if (
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
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)}`);
|
|
6051
|
+
console.warn(formatDegradation(d));
|
|
6052
|
+
}
|
|
6053
|
+
var _immediate = /* @__PURE__ */ new Set();
|
|
6054
|
+
function beginCompileDegradationDrain() {
|
|
6055
|
+
if (resolveDegradationLevel() === "off" || _sinks.length > 0) return () => {
|
|
6056
|
+
};
|
|
6057
|
+
const depth = degradationCaptureDepth();
|
|
6058
|
+
beginDegradationCapture();
|
|
6059
|
+
return (report) => {
|
|
5611
6060
|
const found = unwindDegradationCapture(depth);
|
|
5612
6061
|
if (!report || found.length === 0) return;
|
|
5613
6062
|
const fresh = found.filter((d) => {
|
|
@@ -5717,91 +6166,620 @@ function splitTopLevel(inner) {
|
|
|
5717
6166
|
last = i + 1;
|
|
5718
6167
|
}
|
|
5719
6168
|
}
|
|
5720
|
-
if (depth !== 0 || angle !== 0) return null;
|
|
5721
|
-
parts.push(inner.slice(last));
|
|
5722
|
-
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;
|
|
5723
6635
|
}
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
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;
|
|
5731
6647
|
}
|
|
5732
|
-
function
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
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 } };
|
|
5738
6676
|
}
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
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);
|
|
5742
6698
|
}
|
|
5743
6699
|
return false;
|
|
5744
6700
|
}
|
|
5745
|
-
function
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
};
|
|
5759
|
-
function unconfirmableReason(def, src) {
|
|
5760
|
-
const declared = def.buildArityUnresolved;
|
|
5761
|
-
if (declared !== void 0 && RESOLVER_REASONS[declared]) return RESOLVER_REASONS[declared];
|
|
5762
|
-
const s = src.trim();
|
|
5763
|
-
const params = s.slice(0, s.indexOf(")") + 1);
|
|
5764
|
-
if (params.includes("...")) return RESOLVER_REASONS["rest-parameter"];
|
|
5765
|
-
if (/\barguments\b/.test(s)) return RESOLVER_REASONS["arguments"];
|
|
5766
|
-
if (/^[A-Za-z_$][\w$]*(\s*\.\s*[A-Za-z_$][\w$]*)?$/.test(s)) {
|
|
5767
|
-
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;
|
|
5768
6714
|
}
|
|
5769
|
-
return
|
|
5770
|
-
}
|
|
5771
|
-
function confirmedArityForDef(def) {
|
|
5772
|
-
if (def.buildArity !== void 0) return def.buildArity;
|
|
5773
|
-
const src = buildAnalysisSrc(def);
|
|
5774
|
-
const arity = confirmedBuildArity(src);
|
|
5775
|
-
if (arity !== null) return arity;
|
|
5776
|
-
const subject = `build reducer \`${(def.buildSrc ?? "<runtime fn>").trim().split("\n")[0].slice(0, 60)}\``;
|
|
5777
|
-
recordDegradation({
|
|
5778
|
-
code: "build-arity-unconfirmed",
|
|
5779
|
-
severity: "warn",
|
|
5780
|
-
where: `node("${def.type ?? "<inferred>"}")`,
|
|
5781
|
-
subject,
|
|
5782
|
-
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`,
|
|
5783
|
-
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"
|
|
5784
|
-
});
|
|
5785
|
-
return null;
|
|
5786
|
-
}
|
|
5787
|
-
function buildReadsRaw(def) {
|
|
5788
|
-
if (!def.build) return true;
|
|
5789
|
-
if (def.buildRawUnused === true) return false;
|
|
5790
|
-
const arity = confirmedArityForDef(def);
|
|
5791
|
-
if (arity === null) return true;
|
|
5792
|
-
return arity >= 4;
|
|
5793
|
-
}
|
|
5794
|
-
function buildReadsTrivia(def) {
|
|
5795
|
-
if (!def.build) return true;
|
|
5796
|
-
const arity = confirmedArityForDef(def);
|
|
5797
|
-
if (arity === null) return true;
|
|
5798
|
-
return arity >= 5;
|
|
6715
|
+
return true;
|
|
5799
6716
|
}
|
|
5800
|
-
function
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
if (
|
|
5804
|
-
|
|
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);
|
|
5805
6783
|
}
|
|
5806
6784
|
|
|
5807
6785
|
// src/compiler/fields.ts
|
|
@@ -5918,6 +6896,7 @@ var OP_SCOPE_PLAIN = 41;
|
|
|
5918
6896
|
var OP_LEX_BODY = 42;
|
|
5919
6897
|
var OP_LEX_PROGRAM = 43;
|
|
5920
6898
|
var OP_SOURCE_LEAF = 44;
|
|
6899
|
+
var OP_RGATE = 45;
|
|
5921
6900
|
var OP_DISPATCH = 25;
|
|
5922
6901
|
var OP_ROUTED = 26;
|
|
5923
6902
|
var OP_NAMES = {
|
|
@@ -5937,6 +6916,7 @@ var OP_NAMES = {
|
|
|
5937
6916
|
[OP_PEEK]: "PEEK",
|
|
5938
6917
|
[OP_LEAF]: "LEAF",
|
|
5939
6918
|
[OP_SOURCE_LEAF]: "SOURCE_LEAF",
|
|
6919
|
+
[OP_RGATE]: "RGATE",
|
|
5940
6920
|
[OP_EMPTY]: "EMPTY",
|
|
5941
6921
|
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
5942
6922
|
[OP_RX_TRACK]: "RX_TRACK",
|
|
@@ -5967,71 +6947,6 @@ var OP_NAMES = {
|
|
|
5967
6947
|
[OP_LEX_PROGRAM]: "LEX_PROGRAM"
|
|
5968
6948
|
};
|
|
5969
6949
|
|
|
5970
|
-
// src/combinators/adjacency.ts
|
|
5971
|
-
function adjacencyOf(p) {
|
|
5972
|
-
return p._def.tag === "adjacency" ? p._def : null;
|
|
5973
|
-
}
|
|
5974
|
-
function adjacencyExpected(def) {
|
|
5975
|
-
if (def.polarity === "adjacent") return "adjacent";
|
|
5976
|
-
return def.kinds === void 0 ? "notAdjacent" : `notAdjacent(${def.kinds.join("|")})`;
|
|
5977
|
-
}
|
|
5978
|
-
function holdsAdjacency(input, cur, ctx, def) {
|
|
5979
|
-
return adjacencyHolds(input, cur, ctx, def.polarity === "notAdjacent", def.kinds);
|
|
5980
|
-
}
|
|
5981
|
-
function adjacencyHolds(input, cur, ctx, negated, kinds) {
|
|
5982
|
-
const end = probeTriviaEnd(input, cur, ctx);
|
|
5983
|
-
if (!negated) return end === cur;
|
|
5984
|
-
if (end === cur) return false;
|
|
5985
|
-
if (kinds === void 0) return true;
|
|
5986
|
-
const want = resolveAdjacencyKindMask(ctx.trivia, kinds);
|
|
5987
|
-
const spec = analyzeLabeledTrivia(ctx.trivia);
|
|
5988
|
-
return (triviaKindMaskAt(input, cur, spec, ctx.state) & want) !== 0;
|
|
5989
|
-
}
|
|
5990
|
-
function adjacencyFail(pos, def) {
|
|
5991
|
-
return { ok: false, expected: [adjacencyExpected(def)], span: { start: pos, end: pos } };
|
|
5992
|
-
}
|
|
5993
|
-
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.";
|
|
5994
|
-
function adjacencyMisuse(polarity) {
|
|
5995
|
-
return new TypeError(`${polarity}(): ${NO_STANDALONE_PARSE}`);
|
|
5996
|
-
}
|
|
5997
|
-
function adjacencyCombinator(def) {
|
|
5998
|
-
const meta = {
|
|
5999
|
-
// Zero-width and never leading (sequence() rejects index 0), so it contributes
|
|
6000
|
-
// no first char. `isZeroWidthAssertion` drops it from a sequence's first-set
|
|
6001
|
-
// rather than letting `any` poison the enclosing choice's dispatch.
|
|
6002
|
-
firstSet: { kind: "any" },
|
|
6003
|
-
canMatchNewline: false,
|
|
6004
|
-
isTrivia: false
|
|
6005
|
-
};
|
|
6006
|
-
return {
|
|
6007
|
-
_tag: "adjacency",
|
|
6008
|
-
_meta: meta,
|
|
6009
|
-
_def: def,
|
|
6010
|
-
parse() {
|
|
6011
|
-
throw adjacencyMisuse(def.polarity);
|
|
6012
|
-
}
|
|
6013
|
-
};
|
|
6014
|
-
}
|
|
6015
|
-
function adjacent() {
|
|
6016
|
-
return adjacencyCombinator({ tag: "adjacency", polarity: "adjacent" });
|
|
6017
|
-
}
|
|
6018
|
-
function notAdjacent(options) {
|
|
6019
|
-
const kinds = options?.kinds;
|
|
6020
|
-
if (kinds !== void 0) {
|
|
6021
|
-
if (!Array.isArray(kinds) || kinds.length === 0) {
|
|
6022
|
-
throw new TypeError("notAdjacent({ kinds }): kinds must be a non-empty array of trivia category names.");
|
|
6023
|
-
}
|
|
6024
|
-
for (const k of kinds) {
|
|
6025
|
-
if (typeof k !== "string" || k.length === 0) {
|
|
6026
|
-
throw new TypeError(`notAdjacent({ kinds }): every kind must be a non-empty string, got ${JSON.stringify(k)}.`);
|
|
6027
|
-
}
|
|
6028
|
-
}
|
|
6029
|
-
}
|
|
6030
|
-
return adjacencyCombinator(
|
|
6031
|
-
kinds === void 0 ? { tag: "adjacency", polarity: "notAdjacent" } : { tag: "adjacency", polarity: "notAdjacent", kinds: [...kinds] }
|
|
6032
|
-
);
|
|
6033
|
-
}
|
|
6034
|
-
|
|
6035
6950
|
// src/combinators/node.ts
|
|
6036
6951
|
function unwrapChild(child) {
|
|
6037
6952
|
return child !== null && typeof child === "object" && child._tag === "leaf" ? child.value : child;
|
|
@@ -6148,42 +7063,6 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
6148
7063
|
};
|
|
6149
7064
|
}
|
|
6150
7065
|
|
|
6151
|
-
// src/combinators/trivia-boundary.ts
|
|
6152
|
-
var MAX_DEPTH = 12;
|
|
6153
|
-
function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
6154
|
-
if (depth === 0) return true;
|
|
6155
|
-
const d = p._def;
|
|
6156
|
-
switch (d.tag) {
|
|
6157
|
-
// Multi-term forms: the gaps BETWEEN terms are the ambient-trivia positions.
|
|
6158
|
-
case "sequence":
|
|
6159
|
-
return d.parsers.length > 1;
|
|
6160
|
-
case "many":
|
|
6161
|
-
case "oneOrMore":
|
|
6162
|
-
case "sepBy":
|
|
6163
|
-
return true;
|
|
6164
|
-
// Transparent wrappers — they add no position, so ask what they wrap.
|
|
6165
|
-
case "node":
|
|
6166
|
-
case "transform":
|
|
6167
|
-
case "leaf":
|
|
6168
|
-
case "label":
|
|
6169
|
-
case "field":
|
|
6170
|
-
case "token":
|
|
6171
|
-
case "attempt":
|
|
6172
|
-
case "optional":
|
|
6173
|
-
case "expect":
|
|
6174
|
-
case "withCtx":
|
|
6175
|
-
case "recover":
|
|
6176
|
-
case "trivia":
|
|
6177
|
-
return hasOwnTriviaBoundary(d.parser, depth - 1);
|
|
6178
|
-
// An alternation adds no position either, but ONE arm that has one is enough
|
|
6179
|
-
// to make the scope meaningful for this rule.
|
|
6180
|
-
case "choice":
|
|
6181
|
-
return d.parsers.some((a) => hasOwnTriviaBoundary(a, depth - 1));
|
|
6182
|
-
default:
|
|
6183
|
-
return false;
|
|
6184
|
-
}
|
|
6185
|
-
}
|
|
6186
|
-
|
|
6187
7066
|
// src/compiler/direct-projection.ts
|
|
6188
7067
|
function directArrayProjection(fn, fnSrc, arity) {
|
|
6189
7068
|
let source = fnSrc;
|
|
@@ -6404,13 +7283,16 @@ var Encoder = class {
|
|
|
6404
7283
|
}
|
|
6405
7284
|
case "choice": {
|
|
6406
7285
|
for (const arm of node2.arms) if (!emitNode(arm)) return false;
|
|
6407
|
-
const
|
|
6408
|
-
|
|
6409
|
-
|
|
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));
|
|
6410
7294
|
for (let i = 0; i < node2.arms.length; i++) {
|
|
6411
|
-
|
|
6412
|
-
words.push(first.kind === "ranges" ? this.charClass(first) : -1);
|
|
6413
|
-
words.push(this.expected(node2.armExpected[i]));
|
|
7295
|
+
words.push(classes[i], this.expected(node2.armExpected[i]));
|
|
6414
7296
|
}
|
|
6415
7297
|
return true;
|
|
6416
7298
|
}
|
|
@@ -6422,6 +7304,10 @@ var Encoder = class {
|
|
|
6422
7304
|
if (!emitNode(node2.body)) return false;
|
|
6423
7305
|
words.push(LEX_NODE_OPTIONAL);
|
|
6424
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;
|
|
6425
7311
|
}
|
|
6426
7312
|
};
|
|
6427
7313
|
if (!emitNode(body.root)) return void 0;
|
|
@@ -6927,6 +7813,51 @@ var Encoder = class {
|
|
|
6927
7813
|
if (!hasOwnTriviaBoundary(target)) return ip;
|
|
6928
7814
|
return this.emit(OP_SCOPE_PLAIN, this.triviaSlot(amb), ip);
|
|
6929
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 nextDef = next._def;
|
|
7854
|
+
if (nextDef.tag !== "literal" && nextDef.tag !== "regex" && nextDef.tag !== "keywords" && nextDef.tag !== "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
|
+
const miss = nextDef.tag === "label" ? deriveExpected(next) : directTerminalFailureExpected(nextDef);
|
|
7859
|
+
return { cls, fx: this.expected(miss) };
|
|
7860
|
+
}
|
|
6930
7861
|
node(p) {
|
|
6931
7862
|
const lazyRef = p._def.tag === "lazy";
|
|
6932
7863
|
const scopeKey = lazyRef ? this.activeTrivia : void 0;
|
|
@@ -7051,6 +7982,10 @@ var Encoder = class {
|
|
|
7051
7982
|
return head;
|
|
7052
7983
|
}
|
|
7053
7984
|
case "choice": {
|
|
7985
|
+
if (this.plan === void 0) {
|
|
7986
|
+
const factored = factorSharedEnds(d);
|
|
7987
|
+
if (factored !== void 0) return this.node(factored).ip;
|
|
7988
|
+
}
|
|
7054
7989
|
if (d.strategy.tag === "greedyClassify") {
|
|
7055
7990
|
const superIndex = d.strategy.superIndex;
|
|
7056
7991
|
const sup = this.node(d.parsers[superIndex]).ip;
|
|
@@ -7074,9 +8009,12 @@ var Encoder = class {
|
|
|
7074
8009
|
const kids = arms.map((c, k) => {
|
|
7075
8010
|
const src = order[k];
|
|
7076
8011
|
const checks = d.autoNot[src];
|
|
7077
|
-
const inner = this.node(c).ip;
|
|
7078
|
-
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
7079
8012
|
const gate = d.gates[src];
|
|
8013
|
+
const plain2 = (checks === null || checks === void 0 || checks.length === 0) && (gate === null || gate === void 0);
|
|
8014
|
+
const routedGate = plain2 ? this.routedArmGate(c) : void 0;
|
|
8015
|
+
const body = this.node(c).ip;
|
|
8016
|
+
const inner = routedGate === void 0 ? body : this.emit(OP_RGATE, routedGate.cls, body, routedGate.fx);
|
|
8017
|
+
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
7080
8018
|
const gated = gate === null || gate === void 0 ? ip : this.emit(OP_ARMGATE, this.fn(gate, d.gateSrcs?.[src] ?? null), ip, this.expected(deriveExpected(c)));
|
|
7081
8019
|
return this.covWrap(gated, armCovIds?.[src], 1);
|
|
7082
8020
|
});
|
|
@@ -7400,6 +8338,7 @@ var Encoder = class {
|
|
|
7400
8338
|
const slots = (ip) => {
|
|
7401
8339
|
switch (this.code[ip]) {
|
|
7402
8340
|
case OP_GATE:
|
|
8341
|
+
case OP_RGATE:
|
|
7403
8342
|
return [ip + 2];
|
|
7404
8343
|
case OP_RULE:
|
|
7405
8344
|
case OP_OPT:
|
|
@@ -8627,6 +9566,7 @@ function childSlots(code, ip, out) {
|
|
|
8627
9566
|
case OP_LEAF:
|
|
8628
9567
|
case OP_SOURCE_LEAF:
|
|
8629
9568
|
case OP_ARMGATE:
|
|
9569
|
+
case OP_RGATE:
|
|
8630
9570
|
out.push(code[ip + 2]);
|
|
8631
9571
|
return true;
|
|
8632
9572
|
// `ROUTED fallback` — the operand is an offset or −1. The routed token itself is
|
|
@@ -8710,6 +9650,42 @@ function reachableSites(code, roots) {
|
|
|
8710
9650
|
}
|
|
8711
9651
|
return seen;
|
|
8712
9652
|
}
|
|
9653
|
+
function passCollapse(code, ip, hostCst) {
|
|
9654
|
+
const flags = code[ip + 3];
|
|
9655
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return false;
|
|
9656
|
+
if (flags !== 32 && flags !== 34) return false;
|
|
9657
|
+
let at = code[ip + 2];
|
|
9658
|
+
for (let n = 0; n < 8; n++) {
|
|
9659
|
+
const op = code[at];
|
|
9660
|
+
if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[at + 3] === 0) at = code[at + 2];
|
|
9661
|
+
else if (op === OP_RULE) at = code[at + 1];
|
|
9662
|
+
else break;
|
|
9663
|
+
}
|
|
9664
|
+
return code[at] === OP_NODE;
|
|
9665
|
+
}
|
|
9666
|
+
function gatedPassCollapse(code, ip, hostCst) {
|
|
9667
|
+
const flags = code[ip + 3];
|
|
9668
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return void 0;
|
|
9669
|
+
if (flags !== 32 && flags !== 34) return void 0;
|
|
9670
|
+
const seq = code[ip + 2];
|
|
9671
|
+
if (code[seq] !== OP_SEQ && code[seq] !== OP_SEQV) return void 0;
|
|
9672
|
+
const n = code[seq + 1];
|
|
9673
|
+
if (n < 2) return void 0;
|
|
9674
|
+
const leads = [];
|
|
9675
|
+
const lits = [];
|
|
9676
|
+
for (let i = 0; i < n - 1; i++) {
|
|
9677
|
+
const t2 = code[seq + 2 + i];
|
|
9678
|
+
if (code[t2] !== OP_OPT && code[t2] !== OP_NOT) return void 0;
|
|
9679
|
+
const g = code[t2 + 1];
|
|
9680
|
+
if (code[g] === OP_GATE) leads.push(g);
|
|
9681
|
+
else if (code[g] === OP_LIT) lits.push(code[g + 1]);
|
|
9682
|
+
else return void 0;
|
|
9683
|
+
}
|
|
9684
|
+
const last = code[seq + 2 + n - 1];
|
|
9685
|
+
let at = last;
|
|
9686
|
+
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];
|
|
9687
|
+
return code[at] === OP_NODE ? { leads, lits, last } : void 0;
|
|
9688
|
+
}
|
|
8713
9689
|
function transfer(code, ip, at, hostCst) {
|
|
8714
9690
|
const op = code[ip];
|
|
8715
9691
|
if (op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN) {
|
|
@@ -8721,14 +9697,18 @@ function transfer(code, ip, at, hostCst) {
|
|
|
8721
9697
|
}
|
|
8722
9698
|
if (op === OP_NODE || op === OP_NODE_TRACK) {
|
|
8723
9699
|
const flags = code[ip + 3];
|
|
9700
|
+
if (passCollapse(code, ip, hostCst)) return at;
|
|
9701
|
+
const gated = gatedPassCollapse(code, ip, hostCst) !== void 0;
|
|
8724
9702
|
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && ((flags & ~128) === 2 || flags === 18 || flags === 34);
|
|
8725
9703
|
if (directChildren) {
|
|
8726
|
-
|
|
9704
|
+
const framed2 = { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
|
|
9705
|
+
return gated ? meet(at, framed2) : framed2;
|
|
8727
9706
|
}
|
|
8728
9707
|
const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
|
|
8729
9708
|
const raw = !hostCst && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags & 2) !== 0 ? RAW_OMIT : RAW_CAPTURE;
|
|
8730
9709
|
if (at.buf && raw === at.raw && cap === at.cap) return at;
|
|
8731
|
-
|
|
9710
|
+
const framed = { tri: at.tri, buf: true, raw, cap };
|
|
9711
|
+
return gated ? meet(at, framed) : framed;
|
|
8732
9712
|
}
|
|
8733
9713
|
if (op === OP_TOKEN) {
|
|
8734
9714
|
if (at.tri === TRI_NONE && !at.buf) return at;
|
|
@@ -8766,6 +9746,40 @@ function computeSiteLabels(code, roots, hostCst) {
|
|
|
8766
9746
|
}
|
|
8767
9747
|
return { at: (ip) => labels.get(ip) ?? TOP };
|
|
8768
9748
|
}
|
|
9749
|
+
function scopeIsIdentity(code, ip, at) {
|
|
9750
|
+
const op = code[ip];
|
|
9751
|
+
if (op !== OP_SCOPE_PLAIN && !(op === OP_SCOPE && code[ip + 3] === 0)) return false;
|
|
9752
|
+
const ki = code[ip + 1];
|
|
9753
|
+
return at.tri === (ki < 0 ? TRI_NONE : ki);
|
|
9754
|
+
}
|
|
9755
|
+
function scanHandoffNeeded(code, ip, labels) {
|
|
9756
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9757
|
+
const stack = [ip];
|
|
9758
|
+
const kids = [];
|
|
9759
|
+
while (stack.length > 0) {
|
|
9760
|
+
const at = stack.pop();
|
|
9761
|
+
if (seen.has(at)) continue;
|
|
9762
|
+
seen.add(at);
|
|
9763
|
+
const l = labels.at(at);
|
|
9764
|
+
if (l.tri === TRI_UNKNOWN) return true;
|
|
9765
|
+
const op = code[at];
|
|
9766
|
+
if (op === OP_SCAN) return true;
|
|
9767
|
+
if (op === OP_TOKEN || op === OP_SCOPE_CAP) continue;
|
|
9768
|
+
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;
|
|
9769
|
+
kids.length = 0;
|
|
9770
|
+
if (!childSlots(code, at, kids)) return true;
|
|
9771
|
+
for (const c of kids) stack.push(c);
|
|
9772
|
+
}
|
|
9773
|
+
return false;
|
|
9774
|
+
}
|
|
9775
|
+
function triviaLeadRanges(tri, trivia2) {
|
|
9776
|
+
if (tri === TRI_NONE) return [];
|
|
9777
|
+
if (tri < 0) return void 0;
|
|
9778
|
+
const fs = trivia2[tri]?._meta.firstSet;
|
|
9779
|
+
if (fs === void 0) return void 0;
|
|
9780
|
+
if (fs.kind === "empty") return [];
|
|
9781
|
+
return fs.kind === "ranges" && fs.ranges !== void 0 ? fs.ranges : void 0;
|
|
9782
|
+
}
|
|
8769
9783
|
|
|
8770
9784
|
// src/table/scalar-terminal.ts
|
|
8771
9785
|
function makeScalarRecognizer(op, spec) {
|
|
@@ -8803,6 +9817,12 @@ function scalarTerminalNotChild(code, ip) {
|
|
|
8803
9817
|
const op = code[child];
|
|
8804
9818
|
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
8805
9819
|
}
|
|
9820
|
+
function scalarTerminalPeekChild(code, ip) {
|
|
9821
|
+
if (code[ip] !== OP_PEEK) return -1;
|
|
9822
|
+
const child = code[ip + 1];
|
|
9823
|
+
const op = code[child];
|
|
9824
|
+
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
9825
|
+
}
|
|
8806
9826
|
function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, throughPeek = false) {
|
|
8807
9827
|
const seen = /* @__PURE__ */ new Set();
|
|
8808
9828
|
let at = ip;
|
|
@@ -8980,6 +10000,59 @@ function leadingTriviaFieldAt(code, k, ip) {
|
|
|
8980
10000
|
return code[ip] === OP_FIELD && (fieldSpec(k[code[ip + 1]]).bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
8981
10001
|
}
|
|
8982
10002
|
|
|
10003
|
+
// src/table/hold-gap.ts
|
|
10004
|
+
var WRAPPERS = /* @__PURE__ */ new Set([
|
|
10005
|
+
OP_NODE,
|
|
10006
|
+
OP_XFORM,
|
|
10007
|
+
OP_LEAF,
|
|
10008
|
+
OP_SOURCE_LEAF,
|
|
10009
|
+
OP_TOKEN,
|
|
10010
|
+
OP_SCOPE,
|
|
10011
|
+
OP_SCOPE_CAP,
|
|
10012
|
+
OP_SCOPE_PLAIN,
|
|
10013
|
+
OP_FIELD,
|
|
10014
|
+
OP_LABEL,
|
|
10015
|
+
OP_EXPECT,
|
|
10016
|
+
OP_WITHCTX,
|
|
10017
|
+
OP_RULE,
|
|
10018
|
+
OP_ATTEMPT,
|
|
10019
|
+
OP_COV
|
|
10020
|
+
]);
|
|
10021
|
+
function rowNullable(code, k, ip, memo) {
|
|
10022
|
+
const hit = memo.get(ip);
|
|
10023
|
+
if (hit !== void 0) return hit;
|
|
10024
|
+
memo.set(ip, true);
|
|
10025
|
+
const op = code[ip];
|
|
10026
|
+
const kids = [];
|
|
10027
|
+
let out = true;
|
|
10028
|
+
if (op === OP_GATE) out = false;
|
|
10029
|
+
else if (op === OP_LIT || op === OP_LIT_CI) out = k[code[ip + 1]].length === 0;
|
|
10030
|
+
else if (op === OP_RX) {
|
|
10031
|
+
const re = k[code[ip + 1]];
|
|
10032
|
+
out = !(re instanceof RegExp) || regexCanMatchEmpty(re.source);
|
|
10033
|
+
} else if (op === OP_SEQ || op === OP_SEQV || op === OP_SEQX) {
|
|
10034
|
+
childSlots(code, ip, kids);
|
|
10035
|
+
out = kids.every((c) => rowNullable(code, k, c, memo));
|
|
10036
|
+
} else if (op === OP_CHOICE) {
|
|
10037
|
+
childSlots(code, ip, kids);
|
|
10038
|
+
out = kids.length === 0 || kids.some((c) => rowNullable(code, k, c, memo));
|
|
10039
|
+
} else if (op === OP_REP || op === OP_REPV) {
|
|
10040
|
+
out = code[ip + 2] === 0 || rowNullable(code, k, code[ip + 1], memo);
|
|
10041
|
+
} else if (WRAPPERS.has(op)) {
|
|
10042
|
+
if (childSlots(code, ip, kids) && kids.length === 1) out = rowNullable(code, k, kids[0], memo);
|
|
10043
|
+
}
|
|
10044
|
+
memo.set(ip, out);
|
|
10045
|
+
return out;
|
|
10046
|
+
}
|
|
10047
|
+
function holdsGap(code, k, base, n, i, memo) {
|
|
10048
|
+
if (i < 1 || i + 1 >= n) return false;
|
|
10049
|
+
const term = code[base + i];
|
|
10050
|
+
if (code[term] !== OP_NOT && code[term] !== OP_PEEK) return false;
|
|
10051
|
+
const next = code[base + i + 1];
|
|
10052
|
+
if (code[next] === OP_ADJ || leadingTriviaFieldAt(code, k, next)) return false;
|
|
10053
|
+
return !rowNullable(code, k, next, memo);
|
|
10054
|
+
}
|
|
10055
|
+
|
|
8983
10056
|
// src/table/emit-assembly.ts
|
|
8984
10057
|
var Unemittable = class extends Error {
|
|
8985
10058
|
construct;
|
|
@@ -9060,7 +10133,10 @@ var EMITTED_PARAMS = [
|
|
|
9060
10133
|
"triviaFieldCapture",
|
|
9061
10134
|
// Appended for the deferred-commit trivia skip (`trivia-gap.ts`); old
|
|
9062
10135
|
// factories ignore it.
|
|
9063
|
-
"skipDeferredTrivia"
|
|
10136
|
+
"skipDeferredTrivia",
|
|
10137
|
+
// Appended for the pass-through collapse (`run-support.ts`); old factories
|
|
10138
|
+
// ignore it.
|
|
10139
|
+
"collapseEmpty"
|
|
9064
10140
|
];
|
|
9065
10141
|
var RUNTIME_PRELUDE = `
|
|
9066
10142
|
let _pfScan=null
|
|
@@ -9257,6 +10333,24 @@ ${fast}
|
|
|
9257
10333
|
${scanned}
|
|
9258
10334
|
}`;
|
|
9259
10335
|
}
|
|
10336
|
+
function emitHoldTerm(callee, dst, t2, l, skip) {
|
|
10337
|
+
const fast = `const ${t2}v=${callee}(input,cur,ctx)
|
|
10338
|
+
if(${t2}v===FAIL)return FAIL
|
|
10339
|
+
${dst}=${t2}v
|
|
10340
|
+
cur=EC.e`;
|
|
10341
|
+
if (l.tri === TRI_NONE) return fast;
|
|
10342
|
+
const held = `const ${t2}s=${skip}(input,cur,ctx)
|
|
10343
|
+
const ${t2}v=${callee}(input,${t2}s,ctx)
|
|
10344
|
+
if(${t2}v===FAIL)return FAIL
|
|
10345
|
+
${dst}=${t2}v
|
|
10346
|
+
cur=${t2}s`;
|
|
10347
|
+
if (l.tri !== TRI_UNKNOWN) return held;
|
|
10348
|
+
return `if(ctx.trivia===undefined){
|
|
10349
|
+
${fast}
|
|
10350
|
+
}else{
|
|
10351
|
+
${held}
|
|
10352
|
+
}`;
|
|
10353
|
+
}
|
|
9260
10354
|
function leadSkip(hasTrivia, leadTrivia, skip) {
|
|
9261
10355
|
if (hasTrivia === "false") return "{}";
|
|
9262
10356
|
const call = `itemStart=${skip}(input,itemStart,ctx)`;
|
|
@@ -9298,6 +10392,7 @@ function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false, s
|
|
|
9298
10392
|
const reachable = [...reachableSites(code, roots)];
|
|
9299
10393
|
const labels = computeSiteLabels(code, roots, hostCst);
|
|
9300
10394
|
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
10395
|
+
const nullable2 = /* @__PURE__ */ new Map();
|
|
9301
10396
|
const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
|
|
9302
10397
|
const largeChoiceLiteralFamilies = /* @__PURE__ */ new Map();
|
|
9303
10398
|
const largeChoiceScalarSequences = /* @__PURE__ */ new Map();
|
|
@@ -9622,9 +10717,7 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
9622
10717
|
const op = code[ip];
|
|
9623
10718
|
if (op === OP_GATE && (cfg.tolerant || cfg.probe)) return code[ip + 2];
|
|
9624
10719
|
if (op === OP_RULE) return code[ip + 1];
|
|
9625
|
-
if ((
|
|
9626
|
-
return code[ip + 2];
|
|
9627
|
-
}
|
|
10720
|
+
if (scopeIsIdentity(code, ip, labels.at(ip))) return code[ip + 2];
|
|
9628
10721
|
return void 0;
|
|
9629
10722
|
}
|
|
9630
10723
|
function lower(ip, fname) {
|
|
@@ -9746,6 +10839,22 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
9746
10839
|
return `${head}
|
|
9747
10840
|
if(${gateMissTest(ip)}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
9748
10841
|
return ${child}(input,pos,ctx)
|
|
10842
|
+
}`;
|
|
10843
|
+
}
|
|
10844
|
+
case OP_RGATE: {
|
|
10845
|
+
const child = link(code[ip + 2]);
|
|
10846
|
+
if (cfg.tolerant || cfg.probe) return `${head}
|
|
10847
|
+
return ${child}(input,pos,ctx)
|
|
10848
|
+
}`;
|
|
10849
|
+
const resolved = t2.cc[code[ip + 1]];
|
|
10850
|
+
const ci = classes.push([resolved]) - 1;
|
|
10851
|
+
classPlan.push([code[ip + 1]]);
|
|
10852
|
+
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
10853
|
+
const xf = fxRef(code[ip + 3]);
|
|
10854
|
+
return `${head}
|
|
10855
|
+
const it=ctx._routed
|
|
10856
|
+
if(it!==undefined&&it.span.start===pos&&!classHas(${cls},lead(input,it.span.end))){ctx._fe=it.span.end;ctx._fx=${xf};return FAIL}
|
|
10857
|
+
return ${child}(input,pos,ctx)
|
|
9749
10858
|
}`;
|
|
9750
10859
|
}
|
|
9751
10860
|
case OP_ARMGATE: {
|
|
@@ -10020,23 +11129,33 @@ return FAIL
|
|
|
10020
11129
|
const p = tmp();
|
|
10021
11130
|
return `${head}
|
|
10022
11131
|
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${emitMark(p, L.buf, L.raw, sinks)}
|
|
10023
|
-
const v=${child}(input,pos,ctx)
|
|
11132
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
10024
11133
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
10025
|
-
if(v===FAIL){EC.e=pos;return null}
|
|
11134
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){EC.e=pos;return null}
|
|
10026
11135
|
ctx._fe=pos
|
|
10027
11136
|
ctx._fx=${xf}
|
|
10028
11137
|
return FAIL
|
|
10029
11138
|
}`;
|
|
10030
11139
|
}
|
|
10031
11140
|
case OP_PEEK: {
|
|
11141
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
11142
|
+
if (scalarChild >= 0) {
|
|
11143
|
+
const recognize = recognizerRef(code[scalarChild + 1]);
|
|
11144
|
+
const xf2 = fxRef(code[ip + 2]);
|
|
11145
|
+
return `${head}
|
|
11146
|
+
if(${recognize}(input,pos)<0){ctx._fe=pos;ctx._fx=${xf2};return FAIL}
|
|
11147
|
+
EC.e=pos
|
|
11148
|
+
return null
|
|
11149
|
+
}`;
|
|
11150
|
+
}
|
|
10032
11151
|
const child = link(code[ip + 1]);
|
|
10033
11152
|
const xf = fxRef(code[ip + 2]);
|
|
10034
11153
|
const p = tmp();
|
|
10035
11154
|
return `${head}
|
|
10036
11155
|
${lookaheadMiss(code[ip + 1], `ctx._fe=pos;ctx._fx=${xf};return FAIL`)}${emitMark(p, L.buf, L.raw, sinks)}
|
|
10037
|
-
const v=${child}(input,pos,ctx)
|
|
11156
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
10038
11157
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
10039
|
-
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
11158
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
10040
11159
|
EC.e=pos
|
|
10041
11160
|
return null
|
|
10042
11161
|
}`;
|
|
@@ -10107,7 +11226,7 @@ return v
|
|
|
10107
11226
|
);
|
|
10108
11227
|
} else {
|
|
10109
11228
|
const callee = leadingTriviaFieldAt(code, k, childIp) ? `(LEAD.at=cur,${kids[i]})` : kids[i];
|
|
10110
|
-
parts.push(emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
11229
|
+
parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
10111
11230
|
}
|
|
10112
11231
|
names.push(vn);
|
|
10113
11232
|
}
|
|
@@ -10590,6 +11709,26 @@ return nd
|
|
|
10590
11709
|
const trailingTrivia = (flags & 128) !== 0;
|
|
10591
11710
|
const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
|
|
10592
11711
|
const leanFlags = flags & ~128;
|
|
11712
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
11713
|
+
return `${head}
|
|
11714
|
+
const v=${child}(input,pos,ctx)
|
|
11715
|
+
if(v!==undefined)return v
|
|
11716
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
11717
|
+
}`;
|
|
11718
|
+
}
|
|
11719
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
11720
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(labels.at(code[ip + 2]).tri, t2.trivia);
|
|
11721
|
+
const gp = gated !== void 0 && triviaLead !== void 0 && triviaLead.length <= 16 ? `const gc=lead(input,pos)
|
|
11722
|
+
if(!(${[
|
|
11723
|
+
...gated.leads.map((g) => `!(${gateMissTest(g)})`),
|
|
11724
|
+
...gated.lits.map((i) => `gc===${k[i].codePointAt(0)}`),
|
|
11725
|
+
...triviaLead.map((r) => r.lo === r.hi ? `gc===${r.lo}` : `(gc>=${r.lo}&&gc<=${r.hi})`)
|
|
11726
|
+
].join("||") || "false"})){
|
|
11727
|
+
const gv=${link(gated.last)}(input,pos,ctx)
|
|
11728
|
+
if(gv!==undefined)return gv
|
|
11729
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
11730
|
+
}
|
|
11731
|
+
` : "";
|
|
10593
11732
|
if (!hostCst && !tracked && build !== void 0 && proj < 0 && (leanFlags === 2 || (flags === 18 || flags === 34))) {
|
|
10594
11733
|
const fields = flags === 18;
|
|
10595
11734
|
const collapseChildren = flags === 34;
|
|
@@ -10624,7 +11763,7 @@ sCh.push(nd)
|
|
|
10624
11763
|
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
10625
11764
|
}`;
|
|
10626
11765
|
return `${head}
|
|
10627
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
11766
|
+
${gp}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
10628
11767
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf,sFields=ctx._fields
|
|
10629
11768
|
const flat=[]
|
|
10630
11769
|
ctx._cstBuf=undefined
|
|
@@ -10699,7 +11838,7 @@ const hostKids=kids
|
|
|
10699
11838
|
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
10700
11839
|
const tlog=buf.tl??EMPTY_TLOG`;
|
|
10701
11840
|
return `${head}
|
|
10702
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
11841
|
+
${!hostCst && !tracked ? gp : ""}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
10703
11842
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
10704
11843
|
${openCapture}
|
|
10705
11844
|
ctx.captureTrivia=${captureWide}
|
|
@@ -10769,9 +11908,15 @@ ext:[${externals.join(",")}],
|
|
|
10769
11908
|
bind:function(xs,ps){_xScan=xs
|
|
10770
11909
|
${externals.map((ip, i) => `_xp${ip}=ps[${i}]`).join("\n")}},
|
|
10771
11910
|
scan:function(s){const o=_pfScan;_pfScan=s;return o}`;
|
|
11911
|
+
const scannerFor = (ip) => {
|
|
11912
|
+
const ki = labels.at(ip).tri;
|
|
11913
|
+
if (ki === TRI_UNKNOWN) return "_pfScan";
|
|
11914
|
+
if (ki === TRI_NONE) return "null";
|
|
11915
|
+
return swapLegal && !triviaLabelled[ki] && t2.triviaScan[ki] != null ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
11916
|
+
};
|
|
10772
11917
|
const externalDefs = select === void 0 ? "" : `let _xScan
|
|
10773
11918
|
${externals.map((ip) => `let _xp${ip}
|
|
10774
|
-
function _px${ip}(input,pos,ctx){const o=_xScan(
|
|
11919
|
+
function _px${ip}(input,pos,ctx){const o=_xScan(${scannerFor(ip)});const v=_xp${ip}(input,pos,ctx);_xScan(o);return v}`).join("\n")}
|
|
10775
11920
|
`;
|
|
10776
11921
|
const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
|
|
10777
11922
|
${prelude.join("\n")}
|
|
@@ -11023,198 +12168,68 @@ function literal(value, opts = {}) {
|
|
|
11023
12168
|
const canMatchNewline = meta.canMatchNewline;
|
|
11024
12169
|
const parseScalar = !caseInsensitive && value.length === 1 ? (() => {
|
|
11025
12170
|
const code = value.charCodeAt(0);
|
|
11026
|
-
return (input, pos, ctx) => {
|
|
11027
|
-
if (input.charCodeAt(pos) === code) {
|
|
11028
|
-
ctx._sv = value;
|
|
11029
|
-
return pos + 1;
|
|
11030
|
-
}
|
|
11031
|
-
ctx._fx = expected;
|
|
11032
|
-
return ~pos;
|
|
11033
|
-
};
|
|
11034
|
-
})() : (input, pos, ctx) => {
|
|
11035
|
-
const end = pos + value.length;
|
|
11036
|
-
if (end <= input.length) {
|
|
11037
|
-
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
11038
|
-
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
11039
|
-
ctx._sv = matchedValue;
|
|
11040
|
-
return end;
|
|
11041
|
-
}
|
|
11042
|
-
}
|
|
11043
|
-
ctx._fx = expected;
|
|
11044
|
-
return ~pos;
|
|
11045
|
-
};
|
|
11046
|
-
if (caseInsensitive) {
|
|
11047
|
-
const upper = value.toUpperCase();
|
|
11048
|
-
const lower = value.toLowerCase();
|
|
11049
|
-
const firstUpper = upper.codePointAt(0);
|
|
11050
|
-
const firstLower = lower.codePointAt(0);
|
|
11051
|
-
meta.firstSet = firstLower !== void 0 && firstUpper !== void 0 ? firstLower === firstUpper ? { kind: "ranges", ranges: [{ lo: firstLower, hi: firstLower }] } : { kind: "ranges", ranges: [
|
|
11052
|
-
{ lo: firstLower, hi: firstLower },
|
|
11053
|
-
{ lo: firstUpper, hi: firstUpper }
|
|
11054
|
-
] } : firstSet2;
|
|
11055
|
-
}
|
|
11056
|
-
const expected = directTerminalFailureExpected({ tag: "literal", value, caseInsensitive });
|
|
11057
|
-
const parse2 = !caseInsensitive && value.length === 1 ? (() => {
|
|
11058
|
-
const code = value.charCodeAt(0);
|
|
11059
|
-
return function parse3(input, pos, ctx) {
|
|
11060
|
-
if (input.charCodeAt(pos) === code) {
|
|
11061
|
-
const span = { start: pos, end: pos + 1 };
|
|
11062
|
-
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
11063
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
11064
|
-
return { ok: true, value, span };
|
|
11065
|
-
}
|
|
11066
|
-
return failAt(ctx, expected, pos);
|
|
11067
|
-
};
|
|
11068
|
-
})() : function parse3(input, pos, ctx) {
|
|
11069
|
-
const end = pos + value.length;
|
|
11070
|
-
if (end > input.length) {
|
|
11071
|
-
return failAt(ctx, expected, pos);
|
|
11072
|
-
}
|
|
11073
|
-
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
11074
|
-
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
11075
|
-
const span = { start: pos, end };
|
|
11076
|
-
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
|
|
11077
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
11078
|
-
return { ok: true, value: matchedValue, span };
|
|
11079
|
-
}
|
|
11080
|
-
return failAt(ctx, expected, pos);
|
|
11081
|
-
};
|
|
11082
|
-
return {
|
|
11083
|
-
_tag: "literal",
|
|
11084
|
-
_meta: meta,
|
|
11085
|
-
_def: { tag: "literal", value, caseInsensitive },
|
|
11086
|
-
_parseScalar: parseScalar,
|
|
11087
|
-
parse: parse2
|
|
11088
|
-
};
|
|
11089
|
-
}
|
|
11090
|
-
|
|
11091
|
-
// src/combinators/sequence.ts
|
|
11092
|
-
function sequence(...parsers) {
|
|
11093
|
-
let adjacency = null;
|
|
11094
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
11095
|
-
const a = adjacencyOf(parsers[i]);
|
|
11096
|
-
if (a === null) continue;
|
|
11097
|
-
if (i === 0) {
|
|
11098
|
-
throw new TypeError(
|
|
11099
|
-
`sequence(): ${a.polarity}() cannot be the FIRST term \u2014 an adjacency assertion tests the gap after the PRECEDING term. Put a concrete term first.`
|
|
11100
|
-
);
|
|
11101
|
-
}
|
|
11102
|
-
;
|
|
11103
|
-
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
11104
|
-
}
|
|
11105
|
-
const hasAdjacency = adjacency !== null;
|
|
11106
|
-
let leading = null;
|
|
11107
|
-
for (let i = 1; i < parsers.length; i++) {
|
|
11108
|
-
if (leadsTrivia(parsers[i])) (leading ??= Array.from({ length: parsers.length }, () => false))[i] = true;
|
|
11109
|
-
}
|
|
11110
|
-
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
11111
|
-
const meta = {
|
|
11112
|
-
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
11113
|
-
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
11114
|
-
firstSet: sequenceFirstSet(parsers),
|
|
11115
|
-
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
11116
|
-
isTrivia: false
|
|
11117
|
-
};
|
|
11118
|
-
const def = { tag: "sequence", parsers };
|
|
11119
|
-
const scalarParsers = parsers.map(scalarOf);
|
|
11120
|
-
const parseScalar = (input, pos, ctx) => {
|
|
11121
|
-
let cur = pos;
|
|
11122
|
-
if (strictArity !== 0) {
|
|
11123
|
-
cur = scalarParsers[0](input, cur, ctx);
|
|
11124
|
-
if (cur < 0) return cur;
|
|
11125
|
-
const first = ctx._sv;
|
|
11126
|
-
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
11127
|
-
cur = scalarParsers[1](input, cur, ctx);
|
|
11128
|
-
if (cur < 0) return cur;
|
|
11129
|
-
const second = ctx._sv;
|
|
11130
|
-
if (strictArity === 2) {
|
|
11131
|
-
ctx._sv = def.valueUnused ? void 0 : [first, second];
|
|
11132
|
-
return cur;
|
|
11133
|
-
}
|
|
11134
|
-
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
11135
|
-
cur = scalarParsers[2](input, cur, ctx);
|
|
11136
|
-
if (cur < 0) return cur;
|
|
11137
|
-
ctx._sv = def.valueUnused ? void 0 : [first, second, ctx._sv];
|
|
11138
|
-
return cur;
|
|
11139
|
-
}
|
|
11140
|
-
const values = def.valueUnused ? void 0 : [];
|
|
11141
|
-
for (let i = 0; i < scalarParsers.length; i++) {
|
|
11142
|
-
let termPos = cur;
|
|
11143
|
-
if (i > 0 && ctx.trivia) termPos = advanceTrivia(input, cur, ctx);
|
|
11144
|
-
const end = scalarParsers[i](input, termPos, ctx);
|
|
11145
|
-
if (end < 0) return end;
|
|
11146
|
-
if (values !== void 0) values.push(ctx._sv);
|
|
11147
|
-
if (end > termPos || termPos === cur) cur = end;
|
|
11148
|
-
}
|
|
11149
|
-
ctx._sv = values;
|
|
11150
|
-
return cur;
|
|
11151
|
-
};
|
|
11152
|
-
let followSentinels;
|
|
11153
|
-
return {
|
|
11154
|
-
_tag: "sequence",
|
|
11155
|
-
_meta: meta,
|
|
11156
|
-
_def: def,
|
|
11157
|
-
_parseScalar: hasAdjacency || leading !== null ? void 0 : parseScalar,
|
|
11158
|
-
parse(input, pos, ctx) {
|
|
11159
|
-
const tolerant = ctx._tolerant === true;
|
|
11160
|
-
if (tolerant) {
|
|
11161
|
-
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
11162
|
-
parsers.slice(i + 1).reduce(
|
|
11163
|
-
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
11164
|
-
{ kind: "empty" }
|
|
11165
|
-
)
|
|
11166
|
-
));
|
|
11167
|
-
}
|
|
11168
|
-
const inheritedSync = ctx._sync;
|
|
11169
|
-
const deferredTrivia = needsDeferredTriviaCommit(ctx);
|
|
11170
|
-
const values = def.valueUnused ? void 0 : [];
|
|
11171
|
-
let cur = pos;
|
|
11172
|
-
try {
|
|
11173
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
11174
|
-
if (tolerant) ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
11175
|
-
const assertion = adjacency?.[i];
|
|
11176
|
-
if (assertion) {
|
|
11177
|
-
if (!holdsAdjacency(input, cur, ctx, assertion)) return adjacencyFail(cur, assertion);
|
|
11178
|
-
if (values !== void 0) values.push(null);
|
|
11179
|
-
continue;
|
|
11180
|
-
}
|
|
11181
|
-
let termPos = cur;
|
|
11182
|
-
const markTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
11183
|
-
const markLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
11184
|
-
const markRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
11185
|
-
if (ctx.trivia && i > 0) {
|
|
11186
|
-
termPos = deferredTrivia ? commitTriviaScan(scanTriviaCompact(input, cur, ctx)) : advanceTrivia(input, cur, ctx);
|
|
11187
|
-
}
|
|
11188
|
-
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
11189
|
-
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
11190
|
-
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
11191
|
-
if (leading?.[i] === true) LEAD.at = cur;
|
|
11192
|
-
const result = parsers[i].parse(input, termPos, ctx);
|
|
11193
|
-
if (!result.ok) return result;
|
|
11194
|
-
if (values !== void 0) values.push(result.value);
|
|
11195
|
-
if (result.span.end > termPos || termPos === cur) cur = result.span.end;
|
|
11196
|
-
else if (deferredTrivia) {
|
|
11197
|
-
rollbackScannedTriviaAt(
|
|
11198
|
-
ctx,
|
|
11199
|
-
markTlog,
|
|
11200
|
-
scanTlog,
|
|
11201
|
-
markLog,
|
|
11202
|
-
scanLog,
|
|
11203
|
-
markRootLog,
|
|
11204
|
-
scanRootLog
|
|
11205
|
-
);
|
|
11206
|
-
}
|
|
11207
|
-
}
|
|
11208
|
-
} finally {
|
|
11209
|
-
if (tolerant) ctx._sync = inheritedSync;
|
|
12171
|
+
return (input, pos, ctx) => {
|
|
12172
|
+
if (input.charCodeAt(pos) === code) {
|
|
12173
|
+
ctx._sv = value;
|
|
12174
|
+
return pos + 1;
|
|
11210
12175
|
}
|
|
11211
|
-
|
|
11212
|
-
|
|
11213
|
-
|
|
11214
|
-
|
|
11215
|
-
|
|
11216
|
-
|
|
12176
|
+
ctx._fx = expected;
|
|
12177
|
+
return ~pos;
|
|
12178
|
+
};
|
|
12179
|
+
})() : (input, pos, ctx) => {
|
|
12180
|
+
const end = pos + value.length;
|
|
12181
|
+
if (end <= input.length) {
|
|
12182
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
12183
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
12184
|
+
ctx._sv = matchedValue;
|
|
12185
|
+
return end;
|
|
12186
|
+
}
|
|
12187
|
+
}
|
|
12188
|
+
ctx._fx = expected;
|
|
12189
|
+
return ~pos;
|
|
12190
|
+
};
|
|
12191
|
+
if (caseInsensitive) {
|
|
12192
|
+
const upper = value.toUpperCase();
|
|
12193
|
+
const lower = value.toLowerCase();
|
|
12194
|
+
const firstUpper = upper.codePointAt(0);
|
|
12195
|
+
const firstLower = lower.codePointAt(0);
|
|
12196
|
+
meta.firstSet = firstLower !== void 0 && firstUpper !== void 0 ? firstLower === firstUpper ? { kind: "ranges", ranges: [{ lo: firstLower, hi: firstLower }] } : { kind: "ranges", ranges: [
|
|
12197
|
+
{ lo: firstLower, hi: firstLower },
|
|
12198
|
+
{ lo: firstUpper, hi: firstUpper }
|
|
12199
|
+
] } : firstSet2;
|
|
12200
|
+
}
|
|
12201
|
+
const expected = directTerminalFailureExpected({ tag: "literal", value, caseInsensitive });
|
|
12202
|
+
const parse2 = !caseInsensitive && value.length === 1 ? (() => {
|
|
12203
|
+
const code = value.charCodeAt(0);
|
|
12204
|
+
return function parse3(input, pos, ctx) {
|
|
12205
|
+
if (input.charCodeAt(pos) === code) {
|
|
12206
|
+
const span = { start: pos, end: pos + 1 };
|
|
12207
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
12208
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
12209
|
+
return { ok: true, value, span };
|
|
12210
|
+
}
|
|
12211
|
+
return failAt(ctx, expected, pos);
|
|
12212
|
+
};
|
|
12213
|
+
})() : function parse3(input, pos, ctx) {
|
|
12214
|
+
const end = pos + value.length;
|
|
12215
|
+
if (end > input.length) {
|
|
12216
|
+
return failAt(ctx, expected, pos);
|
|
12217
|
+
}
|
|
12218
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
12219
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
12220
|
+
const span = { start: pos, end };
|
|
12221
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
|
|
12222
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
12223
|
+
return { ok: true, value: matchedValue, span };
|
|
11217
12224
|
}
|
|
12225
|
+
return failAt(ctx, expected, pos);
|
|
12226
|
+
};
|
|
12227
|
+
return {
|
|
12228
|
+
_tag: "literal",
|
|
12229
|
+
_meta: meta,
|
|
12230
|
+
_def: { tag: "literal", value, caseInsensitive },
|
|
12231
|
+
_parseScalar: parseScalar,
|
|
12232
|
+
parse: parse2
|
|
11218
12233
|
};
|
|
11219
12234
|
}
|
|
11220
12235
|
|
|
@@ -11285,124 +12300,6 @@ function ref() {
|
|
|
11285
12300
|
return slot;
|
|
11286
12301
|
}
|
|
11287
12302
|
|
|
11288
|
-
// src/combinators/token.ts
|
|
11289
|
-
function semanticLeafValue(_ctx, _input, _start, _end, value) {
|
|
11290
|
-
return value;
|
|
11291
|
-
}
|
|
11292
|
-
function sourceLeafValue(ctx, input, start, end, value) {
|
|
11293
|
-
return cstOutputHost(ctx.build) ? input.slice(start, end) : value;
|
|
11294
|
-
}
|
|
11295
|
-
function token(root) {
|
|
11296
|
-
const meta = {
|
|
11297
|
-
firstSet: root._meta.firstSet,
|
|
11298
|
-
canMatchNewline: root._meta.canMatchNewline,
|
|
11299
|
-
isTrivia: false
|
|
11300
|
-
};
|
|
11301
|
-
return {
|
|
11302
|
-
_tag: "token",
|
|
11303
|
-
_meta: meta,
|
|
11304
|
-
_def: { tag: "token", parser: root },
|
|
11305
|
-
parse(input, pos, ctx) {
|
|
11306
|
-
const savedTrivia = ctx.trivia;
|
|
11307
|
-
const savedKinds = ctx.triviaKindLabels;
|
|
11308
|
-
const savedBuf = ctx._cstBuf;
|
|
11309
|
-
const savedChildren = ctx._cstChildren;
|
|
11310
|
-
const savedLeaves = ctx._cstLeaves;
|
|
11311
|
-
const savedRaw = ctx._cstRawChildren;
|
|
11312
|
-
const savedTriviaLog = ctx._cstTriviaLog;
|
|
11313
|
-
const savedOuterTriviaLog = ctx._triviaLog;
|
|
11314
|
-
const savedRootTriviaLog = ctx._rootTriviaLog;
|
|
11315
|
-
const wasCapturing = cstCaptureActive(ctx);
|
|
11316
|
-
ctx.trivia = void 0;
|
|
11317
|
-
ctx.triviaKindLabels = void 0;
|
|
11318
|
-
ctx._cstBuf = void 0;
|
|
11319
|
-
ctx._cstChildren = void 0;
|
|
11320
|
-
ctx._cstLeaves = void 0;
|
|
11321
|
-
ctx._cstRawChildren = void 0;
|
|
11322
|
-
ctx._cstTriviaLog = void 0;
|
|
11323
|
-
ctx._triviaLog = void 0;
|
|
11324
|
-
ctx._rootTriviaLog = void 0;
|
|
11325
|
-
let result;
|
|
11326
|
-
try {
|
|
11327
|
-
result = root.parse(input, pos, ctx);
|
|
11328
|
-
} finally {
|
|
11329
|
-
ctx.trivia = savedTrivia;
|
|
11330
|
-
ctx.triviaKindLabels = savedKinds;
|
|
11331
|
-
ctx._cstBuf = savedBuf;
|
|
11332
|
-
ctx._cstChildren = savedChildren;
|
|
11333
|
-
ctx._cstLeaves = savedLeaves;
|
|
11334
|
-
ctx._cstRawChildren = savedRaw;
|
|
11335
|
-
ctx._cstTriviaLog = savedTriviaLog;
|
|
11336
|
-
ctx._triviaLog = savedOuterTriviaLog;
|
|
11337
|
-
ctx._rootTriviaLog = savedRootTriviaLog;
|
|
11338
|
-
}
|
|
11339
|
-
if (!result.ok) return result;
|
|
11340
|
-
const span = result.span;
|
|
11341
|
-
const value = input.slice(pos, span.end);
|
|
11342
|
-
if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
11343
|
-
return { ok: true, value, span };
|
|
11344
|
-
}
|
|
11345
|
-
};
|
|
11346
|
-
}
|
|
11347
|
-
function makeLeaf(root, fn, sourceCstValue) {
|
|
11348
|
-
const cstValue = sourceCstValue ? sourceLeafValue : semanticLeafValue;
|
|
11349
|
-
const meta = {
|
|
11350
|
-
firstSet: root._meta.firstSet,
|
|
11351
|
-
canMatchNewline: root._meta.canMatchNewline,
|
|
11352
|
-
isTrivia: false
|
|
11353
|
-
};
|
|
11354
|
-
return {
|
|
11355
|
-
_tag: "leaf",
|
|
11356
|
-
_meta: meta,
|
|
11357
|
-
_def: {
|
|
11358
|
-
tag: "leaf",
|
|
11359
|
-
parser: root,
|
|
11360
|
-
fn,
|
|
11361
|
-
...sourceCstValue ? { cstValue: "source" } : {}
|
|
11362
|
-
},
|
|
11363
|
-
parse(input, pos, ctx) {
|
|
11364
|
-
const savedBuf = ctx._cstBuf;
|
|
11365
|
-
const savedChildren = ctx._cstChildren;
|
|
11366
|
-
const savedLeaves = ctx._cstLeaves;
|
|
11367
|
-
const savedRaw = ctx._cstRawChildren;
|
|
11368
|
-
const savedTriviaLog = ctx._cstTriviaLog;
|
|
11369
|
-
const savedOuterTriviaLog = ctx._triviaLog;
|
|
11370
|
-
const wasCapturing = cstCaptureActive(ctx);
|
|
11371
|
-
ctx._cstBuf = void 0;
|
|
11372
|
-
ctx._cstChildren = void 0;
|
|
11373
|
-
ctx._cstLeaves = void 0;
|
|
11374
|
-
ctx._cstRawChildren = void 0;
|
|
11375
|
-
ctx._cstTriviaLog = void 0;
|
|
11376
|
-
ctx._triviaLog = void 0;
|
|
11377
|
-
let result;
|
|
11378
|
-
try {
|
|
11379
|
-
result = root.parse(input, pos, ctx);
|
|
11380
|
-
} finally {
|
|
11381
|
-
ctx._cstBuf = savedBuf;
|
|
11382
|
-
ctx._cstChildren = savedChildren;
|
|
11383
|
-
ctx._cstLeaves = savedLeaves;
|
|
11384
|
-
ctx._cstRawChildren = savedRaw;
|
|
11385
|
-
ctx._cstTriviaLog = savedTriviaLog;
|
|
11386
|
-
ctx._triviaLog = savedOuterTriviaLog;
|
|
11387
|
-
}
|
|
11388
|
-
if (!result.ok) return result;
|
|
11389
|
-
const value = fn(result.value, result.span);
|
|
11390
|
-
if (wasCapturing) pushCstLeaf(ctx, {
|
|
11391
|
-
_tag: "leaf",
|
|
11392
|
-
value: cstValue(ctx, input, pos, result.span.end, value),
|
|
11393
|
-
span: result.span
|
|
11394
|
-
});
|
|
11395
|
-
return { ok: true, value, span: result.span };
|
|
11396
|
-
}
|
|
11397
|
-
};
|
|
11398
|
-
}
|
|
11399
|
-
function leaf(root, fn) {
|
|
11400
|
-
return makeLeaf(root, fn, false);
|
|
11401
|
-
}
|
|
11402
|
-
function sourceLeaf(root, fn) {
|
|
11403
|
-
return makeLeaf(root, fn, true);
|
|
11404
|
-
}
|
|
11405
|
-
|
|
11406
12303
|
// src/combinators/scanTo.ts
|
|
11407
12304
|
function resolveScanSkip(explicitSkip, raw, ctx) {
|
|
11408
12305
|
if (raw) return [];
|
|
@@ -11711,37 +12608,120 @@ function clearOf(ranges, input, from, to) {
|
|
|
11711
12608
|
return true;
|
|
11712
12609
|
}
|
|
11713
12610
|
|
|
11714
|
-
// src/table/
|
|
11715
|
-
function
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
12611
|
+
// src/table/fail-clean.ts
|
|
12612
|
+
function passChild(code, ip) {
|
|
12613
|
+
switch (code[ip]) {
|
|
12614
|
+
case OP_RULE:
|
|
12615
|
+
case OP_LABEL:
|
|
12616
|
+
case OP_COV:
|
|
12617
|
+
case OP_TOKEN:
|
|
12618
|
+
return code[ip + 1];
|
|
12619
|
+
case OP_GATE:
|
|
12620
|
+
case OP_NODE:
|
|
12621
|
+
case OP_NODE_TRACK:
|
|
12622
|
+
case OP_XFORM:
|
|
12623
|
+
case OP_FIELD:
|
|
12624
|
+
case OP_SCOPE:
|
|
12625
|
+
case OP_SCOPE_CAP:
|
|
12626
|
+
case OP_SCOPE_PLAIN:
|
|
12627
|
+
case OP_WITHCTX:
|
|
12628
|
+
case OP_LEAF:
|
|
12629
|
+
case OP_SOURCE_LEAF:
|
|
12630
|
+
return code[ip + 2];
|
|
12631
|
+
default:
|
|
12632
|
+
return -1;
|
|
11722
12633
|
}
|
|
11723
|
-
return [lo + 1, offset - starts[lo] + 1];
|
|
11724
|
-
}
|
|
11725
|
-
function spanLines(ctx, start, end) {
|
|
11726
|
-
const s = lineCol(ctx, start), e = lineCol(ctx, end);
|
|
11727
|
-
return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] };
|
|
11728
12634
|
}
|
|
11729
|
-
function
|
|
11730
|
-
|
|
11731
|
-
|
|
11732
|
-
|
|
11733
|
-
|
|
11734
|
-
|
|
11735
|
-
|
|
11736
|
-
|
|
11737
|
-
|
|
12635
|
+
function seqCount(code, ip) {
|
|
12636
|
+
const op = code[ip];
|
|
12637
|
+
return op === OP_SEQ || op === OP_SEQV ? ip + 1 : op === OP_SEQX ? ip + 2 : -1;
|
|
12638
|
+
}
|
|
12639
|
+
function failCleanAnalysis(code) {
|
|
12640
|
+
const cleanAt = new Uint8Array(code.length);
|
|
12641
|
+
const neverAt = new Uint8Array(code.length);
|
|
12642
|
+
const neverFails = (ip) => {
|
|
12643
|
+
const hit = neverAt[ip];
|
|
12644
|
+
if (hit !== 0) return hit === 1;
|
|
12645
|
+
neverAt[ip] = 3;
|
|
12646
|
+
let out = false;
|
|
12647
|
+
const op = code[ip];
|
|
12648
|
+
if (op === OP_OPT || op === OP_EMPTY || op === OP_EXPECT) out = true;
|
|
12649
|
+
else if (op === OP_REP || op === OP_REPV) out = code[ip + 2] === 0;
|
|
12650
|
+
else {
|
|
12651
|
+
const at = seqCount(code, ip);
|
|
12652
|
+
if (at >= 0) {
|
|
12653
|
+
out = true;
|
|
12654
|
+
for (let i = 1, n = code[at]; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
12655
|
+
} else if (op !== OP_GATE) {
|
|
12656
|
+
const c = passChild(code, ip);
|
|
12657
|
+
out = c >= 0 && neverFails(c);
|
|
12658
|
+
}
|
|
12659
|
+
}
|
|
12660
|
+
neverAt[ip] = out ? 1 : 2;
|
|
12661
|
+
return out;
|
|
11738
12662
|
};
|
|
11739
|
-
|
|
11740
|
-
|
|
11741
|
-
|
|
11742
|
-
|
|
11743
|
-
|
|
11744
|
-
|
|
12663
|
+
const clean = (ip) => {
|
|
12664
|
+
const hit = cleanAt[ip];
|
|
12665
|
+
if (hit !== 0) return hit === 1;
|
|
12666
|
+
cleanAt[ip] = 3;
|
|
12667
|
+
let out = false;
|
|
12668
|
+
switch (code[ip]) {
|
|
12669
|
+
// A terminal pushes its leaf only on a match; NOT/PEEK/ATTEMPT restore
|
|
12670
|
+
// their own mark; OPT, EMPTY and EXPECT do not fail uncommitted.
|
|
12671
|
+
case OP_LIT:
|
|
12672
|
+
case OP_RX:
|
|
12673
|
+
case OP_LIT_TRACK:
|
|
12674
|
+
case OP_RX_TRACK:
|
|
12675
|
+
case OP_LIT_CI:
|
|
12676
|
+
case OP_LIT_CI_TRACK:
|
|
12677
|
+
case OP_GUARD:
|
|
12678
|
+
case OP_NOT:
|
|
12679
|
+
case OP_PEEK:
|
|
12680
|
+
case OP_ATTEMPT:
|
|
12681
|
+
case OP_EMPTY:
|
|
12682
|
+
case OP_OPT:
|
|
12683
|
+
case OP_EXPECT:
|
|
12684
|
+
out = true;
|
|
12685
|
+
break;
|
|
12686
|
+
// Min 0 does not fail uncommitted; min 1 fails only with no item kept, and
|
|
12687
|
+
// restores the failed item itself.
|
|
12688
|
+
case OP_REP:
|
|
12689
|
+
case OP_REPV:
|
|
12690
|
+
out = code[ip + 2] <= 1;
|
|
12691
|
+
break;
|
|
12692
|
+
// Only the first term may fail: a later one fails after the terms before it
|
|
12693
|
+
// wrote, and after the trivia scanned in front of it.
|
|
12694
|
+
case OP_SEQ:
|
|
12695
|
+
case OP_SEQV:
|
|
12696
|
+
case OP_SEQX: {
|
|
12697
|
+
const at = seqCount(code, ip);
|
|
12698
|
+
const n = code[at];
|
|
12699
|
+
out = n > 0 && clean(code[at + 1]);
|
|
12700
|
+
for (let i = 2; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
12701
|
+
break;
|
|
12702
|
+
}
|
|
12703
|
+
case OP_CHOICE: {
|
|
12704
|
+
out = true;
|
|
12705
|
+
for (let i = 0, n = code[ip + 2]; out && i < n; i++) out = clean(code[ip + 4 + i]);
|
|
12706
|
+
break;
|
|
12707
|
+
}
|
|
12708
|
+
case OP_ROUTED:
|
|
12709
|
+
out = code[ip + 1] < 0 || clean(code[ip + 1]);
|
|
12710
|
+
break;
|
|
12711
|
+
// An arm's failure and the fallback's are committed; only the selector's is
|
|
12712
|
+
// not, and without a fallback an unknown key fails after the selector wrote.
|
|
12713
|
+
case OP_DISPATCH:
|
|
12714
|
+
out = code[ip + 3] >= 0 && clean(code[ip + 1]);
|
|
12715
|
+
break;
|
|
12716
|
+
default: {
|
|
12717
|
+
const c = passChild(code, ip);
|
|
12718
|
+
out = c >= 0 && clean(c);
|
|
12719
|
+
}
|
|
12720
|
+
}
|
|
12721
|
+
cleanAt[ip] = out ? 1 : 2;
|
|
12722
|
+
return out;
|
|
12723
|
+
};
|
|
12724
|
+
return clean;
|
|
11745
12725
|
}
|
|
11746
12726
|
|
|
11747
12727
|
// src/grammar-metadata.ts
|
|
@@ -11839,12 +12819,6 @@ function hasDirectBuilder(prog) {
|
|
|
11839
12819
|
return false;
|
|
11840
12820
|
}
|
|
11841
12821
|
|
|
11842
|
-
// src/cst/root-trivia-scope.ts
|
|
11843
|
-
var ROOT_TRIVIA_SCOPE_REFUSAL = "parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'.";
|
|
11844
|
-
function refuseUnclassifiedRootScope(strict) {
|
|
11845
|
-
if (strict === true) throw new TypeError(ROOT_TRIVIA_SCOPE_REFUSAL);
|
|
11846
|
-
}
|
|
11847
|
-
|
|
11848
12822
|
// src/table/cell.ts
|
|
11849
12823
|
var FAIL = /* @__PURE__ */ Symbol("pm.fail");
|
|
11850
12824
|
var newEndCell = () => ({ e: 0 });
|
|
@@ -11895,6 +12869,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11895
12869
|
const swapLegal = !cfg.trackLines;
|
|
11896
12870
|
const hostCst = cfg.hostCst;
|
|
11897
12871
|
const REC = prog.rec === 1 && cfg.tolerant;
|
|
12872
|
+
const PROBE = cfg.probe;
|
|
11898
12873
|
const sentinels = /* @__PURE__ */ new Map();
|
|
11899
12874
|
function sentinelFor(cls) {
|
|
11900
12875
|
if (cls < 0) return void 0;
|
|
@@ -11940,6 +12915,8 @@ function assemble(t2, prog, cfg) {
|
|
|
11940
12915
|
}
|
|
11941
12916
|
const memo = /* @__PURE__ */ new Map();
|
|
11942
12917
|
const reached = /* @__PURE__ */ new Set();
|
|
12918
|
+
const NULLABLE = /* @__PURE__ */ new Map();
|
|
12919
|
+
const CLEAN = REC ? () => false : failCleanAnalysis(code);
|
|
11943
12920
|
function pushLeaf(ctx, value, s, e) {
|
|
11944
12921
|
const lf = { _tag: "leaf", value, span: { start: s, end: e } };
|
|
11945
12922
|
pushCstLeaf(ctx, lf);
|
|
@@ -12138,6 +13115,22 @@ function assemble(t2, prog, cfg) {
|
|
|
12138
13115
|
return node2;
|
|
12139
13116
|
};
|
|
12140
13117
|
}
|
|
13118
|
+
function passCollapseNode(child, build, readsRaw) {
|
|
13119
|
+
return (input, pos, ctx) => {
|
|
13120
|
+
const v = child(input, pos, ctx);
|
|
13121
|
+
if (v !== void 0) return v;
|
|
13122
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
13123
|
+
};
|
|
13124
|
+
}
|
|
13125
|
+
function gatedPassCollapseNode(blockers, last, classic, build, readsRaw) {
|
|
13126
|
+
return (input, pos, ctx) => {
|
|
13127
|
+
const c = lead(input, pos);
|
|
13128
|
+
for (let i = 0; i < blockers.length; i++) if (classHas2(blockers[i], c)) return classic(input, pos, ctx);
|
|
13129
|
+
const v = last(input, pos, ctx);
|
|
13130
|
+
if (v !== void 0) return v;
|
|
13131
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
13132
|
+
};
|
|
13133
|
+
}
|
|
12141
13134
|
function plainProjectNode(child, projection, type) {
|
|
12142
13135
|
return (input, pos, ctx) => {
|
|
12143
13136
|
const sCh = ctx._cstChildren;
|
|
@@ -12508,21 +13501,27 @@ function assemble(t2, prog, cfg) {
|
|
|
12508
13501
|
}
|
|
12509
13502
|
function dispatchBranch(child, usesRouted) {
|
|
12510
13503
|
if (!usesRouted) {
|
|
12511
|
-
return (input, _pos, selEnd, key,
|
|
12512
|
-
const
|
|
13504
|
+
return (input, _pos, selEnd, key, ctx) => {
|
|
13505
|
+
const need = markCst(ctx);
|
|
13506
|
+
const mRaw = MRAW;
|
|
13507
|
+
const mTl = MTL;
|
|
13508
|
+
const mLv = MLV;
|
|
13509
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
13510
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13511
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13512
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
12513
13513
|
const v = child(input, selEnd, ctx);
|
|
12514
13514
|
if (v === FAIL) {
|
|
12515
|
-
|
|
13515
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12516
13516
|
ctx._fc = true;
|
|
12517
13517
|
return FAIL;
|
|
12518
13518
|
}
|
|
12519
13519
|
return [key, v];
|
|
12520
13520
|
};
|
|
12521
13521
|
}
|
|
12522
|
-
return (input, pos, selEnd, key,
|
|
13522
|
+
return (input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
12523
13523
|
const savedRouted = ctx._routed;
|
|
12524
|
-
|
|
12525
|
-
const mark = saveTriviaMark(ctx);
|
|
13524
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12526
13525
|
ctx._routed = { value: key, span: { start: pos, end: selEnd } };
|
|
12527
13526
|
let v;
|
|
12528
13527
|
try {
|
|
@@ -12531,7 +13530,7 @@ function assemble(t2, prog, cfg) {
|
|
|
12531
13530
|
ctx._routed = savedRouted;
|
|
12532
13531
|
}
|
|
12533
13532
|
if (v === FAIL) {
|
|
12534
|
-
|
|
13533
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12535
13534
|
ctx._fc = true;
|
|
12536
13535
|
return FAIL;
|
|
12537
13536
|
}
|
|
@@ -12539,12 +13538,12 @@ function assemble(t2, prog, cfg) {
|
|
|
12539
13538
|
};
|
|
12540
13539
|
}
|
|
12541
13540
|
function dispatchArmBlock(start, a0, a1, a2, a3, next) {
|
|
12542
|
-
return (arm, input, pos, selEnd, key,
|
|
12543
|
-
if (arm === start) return a0(input, pos, selEnd, key,
|
|
12544
|
-
if (arm === start + 1) return a1(input, pos, selEnd, key,
|
|
12545
|
-
if (arm === start + 2) return a2(input, pos, selEnd, key,
|
|
12546
|
-
if (arm === start + 3) return a3(input, pos, selEnd, key,
|
|
12547
|
-
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key,
|
|
13541
|
+
return (arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
13542
|
+
if (arm === start) return a0(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13543
|
+
if (arm === start + 1) return a1(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13544
|
+
if (arm === start + 2) return a2(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13545
|
+
if (arm === start + 3) return a3(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13546
|
+
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12548
13547
|
};
|
|
12549
13548
|
}
|
|
12550
13549
|
function trackLinesInto(ctx, input, end) {
|
|
@@ -12563,7 +13562,7 @@ function assemble(t2, prog, cfg) {
|
|
|
12563
13562
|
if (flight !== void 0) return flight.fwd;
|
|
12564
13563
|
const selected = HYBRID?.byIp[ip];
|
|
12565
13564
|
if (selected !== void 0) {
|
|
12566
|
-
const piece2 = hybridPiece(selected);
|
|
13565
|
+
const piece2 = scanHandoffNeeded(code, ip, closureLabels) ? hybridPiece(selected) : selected;
|
|
12567
13566
|
memo.set(ip, piece2);
|
|
12568
13567
|
reached.add(ip);
|
|
12569
13568
|
return piece2;
|
|
@@ -12574,14 +13573,55 @@ function assemble(t2, prog, cfg) {
|
|
|
12574
13573
|
target = p;
|
|
12575
13574
|
} };
|
|
12576
13575
|
inFlight.set(ip, holder);
|
|
12577
|
-
const
|
|
12578
|
-
const piece = (op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[ip + 3] === 0) && code[ip + 1] >= 0 && closureLabels.at(ip).tri === code[ip + 1] ? link(code[ip + 2]) : countedPiece(lower(ip), ip);
|
|
13576
|
+
const piece = scopeIsIdentity(code, ip, closureLabels.at(ip)) ? link(code[ip + 2]) : countedPiece(lookaheadLedNode(ip) ?? lower(ip), ip);
|
|
12579
13577
|
inFlight.delete(ip);
|
|
12580
13578
|
holder.set(piece);
|
|
12581
13579
|
memo.set(ip, piece);
|
|
12582
13580
|
reached.add(ip);
|
|
12583
13581
|
return piece;
|
|
12584
13582
|
}
|
|
13583
|
+
let FIRST_DECIDED;
|
|
13584
|
+
let NODE_BODY;
|
|
13585
|
+
const DECIDED = (_input, pos) => {
|
|
13586
|
+
EC.e = pos;
|
|
13587
|
+
return null;
|
|
13588
|
+
};
|
|
13589
|
+
function lookaheadLedNode(ip) {
|
|
13590
|
+
const op = code[ip];
|
|
13591
|
+
if (op !== OP_NODE && op !== OP_NODE_TRACK || hostCst || REC || cfg.probe || cfg.coverage || cfg.trackLines) return void 0;
|
|
13592
|
+
if (passCollapse(code, ip, hostCst) || gatedPassCollapse(code, ip, hostCst) !== void 0) return void 0;
|
|
13593
|
+
const body = code[ip + 2];
|
|
13594
|
+
const bop = code[body];
|
|
13595
|
+
if (bop !== OP_SEQ && bop !== OP_SEQV && bop !== OP_SEQX) return void 0;
|
|
13596
|
+
const base = bop === OP_SEQX ? body + 3 : body + 2;
|
|
13597
|
+
if (code[bop === OP_SEQX ? body + 2 : body + 1] < 2) return void 0;
|
|
13598
|
+
const first = code[base];
|
|
13599
|
+
const negative = code[first] === OP_NOT;
|
|
13600
|
+
const terminal = negative ? scalarTerminalNotChild(code, first) : code[first] === OP_PEEK ? scalarTerminalPeekChild(code, first) : -1;
|
|
13601
|
+
if (terminal < 0) return void 0;
|
|
13602
|
+
const recognize = scalarFor(terminal);
|
|
13603
|
+
const xf = fx[code[first + 2]];
|
|
13604
|
+
FIRST_DECIDED = DECIDED;
|
|
13605
|
+
NODE_BODY = lower(body);
|
|
13606
|
+
const node2 = lower(ip);
|
|
13607
|
+
NODE_BODY = void 0;
|
|
13608
|
+
return negative ? (input, pos, ctx) => {
|
|
13609
|
+
if (recognize(input, pos) >= 0) {
|
|
13610
|
+
ctx._fe = pos;
|
|
13611
|
+
ctx._fx = xf;
|
|
13612
|
+
EC.e = pos;
|
|
13613
|
+
return FAIL;
|
|
13614
|
+
}
|
|
13615
|
+
return node2(input, pos, ctx);
|
|
13616
|
+
} : (input, pos, ctx) => {
|
|
13617
|
+
if (recognize(input, pos) < 0) {
|
|
13618
|
+
ctx._fe = pos;
|
|
13619
|
+
ctx._fx = xf;
|
|
13620
|
+
return FAIL;
|
|
13621
|
+
}
|
|
13622
|
+
return node2(input, pos, ctx);
|
|
13623
|
+
};
|
|
13624
|
+
}
|
|
12585
13625
|
function lower(ip) {
|
|
12586
13626
|
const op = code[ip];
|
|
12587
13627
|
switch (op) {
|
|
@@ -13126,8 +14166,10 @@ function assemble(t2, prog, cfg) {
|
|
|
13126
14166
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13127
14167
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13128
14168
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14169
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
13129
14170
|
const v = child(input, pos, ctx);
|
|
13130
14171
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14172
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
13131
14173
|
if (v === FAIL) {
|
|
13132
14174
|
EC.e = pos;
|
|
13133
14175
|
return null;
|
|
@@ -13138,6 +14180,20 @@ function assemble(t2, prog, cfg) {
|
|
|
13138
14180
|
};
|
|
13139
14181
|
}
|
|
13140
14182
|
case OP_PEEK: {
|
|
14183
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
14184
|
+
if (scalarChild >= 0) {
|
|
14185
|
+
const recognize = scalarFor(scalarChild);
|
|
14186
|
+
const xf2 = fx[code[ip + 2]];
|
|
14187
|
+
return (input, pos, ctx) => {
|
|
14188
|
+
if (recognize(input, pos) < 0) {
|
|
14189
|
+
ctx._fe = pos;
|
|
14190
|
+
ctx._fx = xf2;
|
|
14191
|
+
return FAIL;
|
|
14192
|
+
}
|
|
14193
|
+
EC.e = pos;
|
|
14194
|
+
return null;
|
|
14195
|
+
};
|
|
14196
|
+
}
|
|
13141
14197
|
const child = link(code[ip + 1]);
|
|
13142
14198
|
const xf = fx[code[ip + 2]];
|
|
13143
14199
|
const gate = lookaheadClass(code[ip + 1]);
|
|
@@ -13155,8 +14211,10 @@ function assemble(t2, prog, cfg) {
|
|
|
13155
14211
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13156
14212
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13157
14213
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14214
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
13158
14215
|
const v = child(input, pos, ctx);
|
|
13159
14216
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14217
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
13160
14218
|
if (v === FAIL) {
|
|
13161
14219
|
ctx._fe = pos;
|
|
13162
14220
|
ctx._fx = xf;
|
|
@@ -13169,12 +14227,13 @@ function assemble(t2, prog, cfg) {
|
|
|
13169
14227
|
case OP_OPT: {
|
|
13170
14228
|
const child = link(code[ip + 1]);
|
|
13171
14229
|
const gate = lookaheadClass(code[ip + 1]);
|
|
14230
|
+
const childClean = CLEAN(code[ip + 1]);
|
|
13172
14231
|
return (input, pos, ctx) => {
|
|
13173
14232
|
if (gate !== null && !classHas2(gate, lead(input, pos))) {
|
|
13174
14233
|
EC.e = pos;
|
|
13175
14234
|
return null;
|
|
13176
14235
|
}
|
|
13177
|
-
const need = markCst(ctx);
|
|
14236
|
+
const need = !childClean && markCst(ctx);
|
|
13178
14237
|
const mRaw = MRAW;
|
|
13179
14238
|
const mTl = MTL;
|
|
13180
14239
|
const mLv = MLV;
|
|
@@ -13372,6 +14431,9 @@ function assemble(t2, prog, cfg) {
|
|
|
13372
14431
|
const projection = reducer < 0 ? ~reducer : -1;
|
|
13373
14432
|
const fn = fused && projection < 0 ? fns[reducer] : void 0;
|
|
13374
14433
|
const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm;
|
|
14434
|
+
const decided = FIRST_DECIDED;
|
|
14435
|
+
FIRST_DECIDED = void 0;
|
|
14436
|
+
const linkFirst = () => decided ?? link(code[base]);
|
|
13375
14437
|
const runnerBlock = (count, r0, r1, r2, r3, next) => {
|
|
13376
14438
|
if (count === 1) return (input, cur, ctx, values, inherited) => {
|
|
13377
14439
|
cur = r0(input, cur, ctx, inherited);
|
|
@@ -13417,7 +14479,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13417
14479
|
};
|
|
13418
14480
|
};
|
|
13419
14481
|
if (REC) {
|
|
13420
|
-
const first2 =
|
|
14482
|
+
const first2 = linkFirst();
|
|
13421
14483
|
const firstSync = sentinelFor(code[base + n]);
|
|
13422
14484
|
const runnerAt = (i) => {
|
|
13423
14485
|
const sync = sentinelFor(code[base + n + i]);
|
|
@@ -13453,13 +14515,13 @@ function assemble(t2, prog, cfg) {
|
|
|
13453
14515
|
const bindRunners = (start) => {
|
|
13454
14516
|
const count = Math.min(4, n - start);
|
|
13455
14517
|
const at = (offset) => runnerAt(start + offset);
|
|
13456
|
-
const
|
|
14518
|
+
const never2 = () => -1;
|
|
13457
14519
|
return runnerBlock(
|
|
13458
14520
|
count,
|
|
13459
14521
|
at(0),
|
|
13460
|
-
count > 1 ? at(1) :
|
|
13461
|
-
count > 2 ? at(2) :
|
|
13462
|
-
count > 3 ? at(3) :
|
|
14522
|
+
count > 1 ? at(1) : never2,
|
|
14523
|
+
count > 2 ? at(2) : never2,
|
|
14524
|
+
count > 3 ? at(3) : never2,
|
|
13463
14525
|
start + count < n ? bindRunners(start + count) : void 0
|
|
13464
14526
|
);
|
|
13465
14527
|
};
|
|
@@ -13509,15 +14571,31 @@ function assemble(t2, prog, cfg) {
|
|
|
13509
14571
|
let hasAdj = false;
|
|
13510
14572
|
for (let i = 1; i < n; i++) {
|
|
13511
14573
|
const kidIp = code[base + i];
|
|
13512
|
-
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp)) {
|
|
14574
|
+
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp) || holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
13513
14575
|
hasAdj = true;
|
|
13514
14576
|
break;
|
|
13515
14577
|
}
|
|
13516
14578
|
}
|
|
13517
14579
|
if (hasAdj) {
|
|
13518
|
-
const first2 =
|
|
14580
|
+
const first2 = linkFirst();
|
|
13519
14581
|
const runnerAt = (i) => {
|
|
13520
14582
|
const kidIp = code[base + i];
|
|
14583
|
+
if (holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
14584
|
+
const kid = link(kidIp);
|
|
14585
|
+
return (input, cur, ctx) => {
|
|
14586
|
+
if (ctx.trivia === void 0) {
|
|
14587
|
+
const v2 = kid(input, cur, ctx);
|
|
14588
|
+
if (v2 === FAIL) return -1;
|
|
14589
|
+
TERMV = v2;
|
|
14590
|
+
return EC.e;
|
|
14591
|
+
}
|
|
14592
|
+
const scanEnd = skipTrivia(input, cur, ctx);
|
|
14593
|
+
const v = kid(input, scanEnd, ctx);
|
|
14594
|
+
if (v === FAIL) return -1;
|
|
14595
|
+
TERMV = v;
|
|
14596
|
+
return scanEnd;
|
|
14597
|
+
};
|
|
14598
|
+
}
|
|
13521
14599
|
if (code[kidIp] !== OP_ADJ) {
|
|
13522
14600
|
const kid = link(kidIp);
|
|
13523
14601
|
if (leadingTriviaFieldAt(code, k, kidIp)) {
|
|
@@ -13542,13 +14620,13 @@ function assemble(t2, prog, cfg) {
|
|
|
13542
14620
|
const bindRunners = (start) => {
|
|
13543
14621
|
const count = Math.min(4, n - start);
|
|
13544
14622
|
const at = (offset) => runnerAt(start + offset);
|
|
13545
|
-
const
|
|
14623
|
+
const never2 = () => -1;
|
|
13546
14624
|
return runnerBlock(
|
|
13547
14625
|
count,
|
|
13548
14626
|
at(0),
|
|
13549
|
-
count > 1 ? at(1) :
|
|
13550
|
-
count > 2 ? at(2) :
|
|
13551
|
-
count > 3 ? at(3) :
|
|
14627
|
+
count > 1 ? at(1) : never2,
|
|
14628
|
+
count > 2 ? at(2) : never2,
|
|
14629
|
+
count > 3 ? at(3) : never2,
|
|
13552
14630
|
start + count < n ? bindRunners(start + count) : void 0
|
|
13553
14631
|
);
|
|
13554
14632
|
};
|
|
@@ -13585,7 +14663,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13585
14663
|
};
|
|
13586
14664
|
}
|
|
13587
14665
|
if (n === 1) {
|
|
13588
|
-
const k0 =
|
|
14666
|
+
const k0 = linkFirst();
|
|
13589
14667
|
if (fused) {
|
|
13590
14668
|
return (input, pos, ctx) => {
|
|
13591
14669
|
const v = k0(input, pos, ctx);
|
|
@@ -13607,7 +14685,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13607
14685
|
};
|
|
13608
14686
|
}
|
|
13609
14687
|
if (n === 2) {
|
|
13610
|
-
const k0 =
|
|
14688
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]);
|
|
13611
14689
|
if (fused) {
|
|
13612
14690
|
return (input, pos, ctx) => {
|
|
13613
14691
|
const v0 = k0(input, pos, ctx);
|
|
@@ -13638,7 +14716,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13638
14716
|
};
|
|
13639
14717
|
}
|
|
13640
14718
|
if (n === 3) {
|
|
13641
|
-
const k0 =
|
|
14719
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]), k2 = link(code[base + 2]);
|
|
13642
14720
|
if (fused) {
|
|
13643
14721
|
return (input, pos, ctx) => {
|
|
13644
14722
|
const v0 = k0(input, pos, ctx);
|
|
@@ -13732,7 +14810,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13732
14810
|
start + count < n ? bind(start + count) : void 0
|
|
13733
14811
|
);
|
|
13734
14812
|
};
|
|
13735
|
-
const first =
|
|
14813
|
+
const first = linkFirst();
|
|
13736
14814
|
const tail = bind(1);
|
|
13737
14815
|
const runDirectTerms = (input, pos, ctx, values) => {
|
|
13738
14816
|
const v0 = first(input, pos, ctx);
|
|
@@ -13771,6 +14849,8 @@ function assemble(t2, prog, cfg) {
|
|
|
13771
14849
|
const n = code[ip + 2];
|
|
13772
14850
|
const choiceFx = fx[code[ip + 3]];
|
|
13773
14851
|
const base = ip + 4;
|
|
14852
|
+
for (let i = 0; i < n; i++) link(code[base + i]);
|
|
14853
|
+
const armsClean = CLEAN(ip);
|
|
13774
14854
|
if (table.exclusive) {
|
|
13775
14855
|
const ascii = table.ascii;
|
|
13776
14856
|
const hi = table.hi;
|
|
@@ -13910,7 +14990,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13910
14990
|
if (n === 3) addGate(g2, 4);
|
|
13911
14991
|
return (input, pos, ctx) => {
|
|
13912
14992
|
const c = lead(input, pos);
|
|
13913
|
-
const need = markCst(ctx);
|
|
14993
|
+
const need = !armsClean && markCst(ctx);
|
|
13914
14994
|
const mRaw = MRAW;
|
|
13915
14995
|
const mTl = MTL;
|
|
13916
14996
|
const mLv = MLV;
|
|
@@ -14127,7 +15207,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14127
15207
|
if (pn !== 0) {
|
|
14128
15208
|
return (input, pos, ctx) => {
|
|
14129
15209
|
const c = lead(input, pos);
|
|
14130
|
-
const need = markCst(ctx);
|
|
15210
|
+
const need = !armsClean && markCst(ctx);
|
|
14131
15211
|
const mRaw = MRAW;
|
|
14132
15212
|
const mTl = MTL;
|
|
14133
15213
|
const mLv = MLV;
|
|
@@ -14184,7 +15264,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14184
15264
|
}
|
|
14185
15265
|
return (input, pos, ctx) => {
|
|
14186
15266
|
const c = lead(input, pos);
|
|
14187
|
-
const need = markCst(ctx);
|
|
15267
|
+
const need = !armsClean && markCst(ctx);
|
|
14188
15268
|
const mRaw = MRAW;
|
|
14189
15269
|
const mTl = MTL;
|
|
14190
15270
|
const mLv = MLV;
|
|
@@ -14232,7 +15312,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14232
15312
|
}
|
|
14233
15313
|
return (input, pos, ctx) => {
|
|
14234
15314
|
const c = lead(input, pos);
|
|
14235
|
-
const need = markCst(ctx);
|
|
15315
|
+
const need = !armsClean && markCst(ctx);
|
|
14236
15316
|
const mRaw = MRAW;
|
|
14237
15317
|
const mTl = MTL;
|
|
14238
15318
|
const mLv = MLV;
|
|
@@ -14286,6 +15366,21 @@ function assemble(t2, prog, cfg) {
|
|
|
14286
15366
|
return lit(input, pos, ctx);
|
|
14287
15367
|
};
|
|
14288
15368
|
}
|
|
15369
|
+
case OP_RGATE: {
|
|
15370
|
+
const cls = cc[code[ip + 1]];
|
|
15371
|
+
const xf = fx[code[ip + 3]];
|
|
15372
|
+
const child = link(code[ip + 2]);
|
|
15373
|
+
if (cfg.tolerant || cfg.probe) return child;
|
|
15374
|
+
return (input, pos, ctx) => {
|
|
15375
|
+
const item = ctx._routed;
|
|
15376
|
+
if (item !== void 0 && item.span.start === pos && !classHas2(cls, lead(input, item.span.end))) {
|
|
15377
|
+
ctx._fe = item.span.end;
|
|
15378
|
+
ctx._fx = xf;
|
|
15379
|
+
return FAIL;
|
|
15380
|
+
}
|
|
15381
|
+
return child(input, pos, ctx);
|
|
15382
|
+
};
|
|
15383
|
+
}
|
|
14289
15384
|
case OP_ARMGATE: {
|
|
14290
15385
|
const pred = fns[code[ip + 1]];
|
|
14291
15386
|
const child = link(code[ip + 2]);
|
|
@@ -14354,6 +15449,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14354
15449
|
const itemClass = !REC && itemClassIndex >= 0 ? cc[itemClassIndex] : void 0;
|
|
14355
15450
|
const itemMayStart = itemClass === void 0 ? void 0 : (input, pos) => classHas2(itemClass, lead(input, pos));
|
|
14356
15451
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
15452
|
+
const itemClean = sepIp < 0 && CLEAN(code[ip + 1]) && !rowNullable(code, k, code[ip + 1], NULLABLE);
|
|
14357
15453
|
if (REC) {
|
|
14358
15454
|
const itemFx2 = fx[code[ip + 6]];
|
|
14359
15455
|
const sepSent = sentinelFor(code[ip + 7]);
|
|
@@ -14450,6 +15546,8 @@ function assemble(t2, prog, cfg) {
|
|
|
14450
15546
|
const out = collect ? [] : void 0;
|
|
14451
15547
|
const hasTrivia = ctx.trivia !== void 0;
|
|
14452
15548
|
const needMark = rollbackNeeded(ctx);
|
|
15549
|
+
const markLater = needMark && (!itemClean || hasTrivia);
|
|
15550
|
+
const markFirst = needMark && (!itemClean || hasTrivia && skipBeforeFirst);
|
|
14453
15551
|
const gateItems = itemMayStart !== void 0 && ctx._probe === void 0;
|
|
14454
15552
|
let cur = pos;
|
|
14455
15553
|
let count = 0;
|
|
@@ -14457,14 +15555,15 @@ function assemble(t2, prog, cfg) {
|
|
|
14457
15555
|
if (max >= 0 && count >= max) break;
|
|
14458
15556
|
if (sep !== void 0 && count > 0 && count >= min && cur >= input.length) break;
|
|
14459
15557
|
if (count >= min && sep === void 0 && !hasTrivia && gateItems && !itemMayStart(input, cur)) break;
|
|
14460
|
-
|
|
14461
|
-
|
|
14462
|
-
const
|
|
14463
|
-
const
|
|
14464
|
-
const
|
|
14465
|
-
const
|
|
14466
|
-
const
|
|
14467
|
-
const
|
|
15558
|
+
const markIt = count > 0 ? markLater : markFirst;
|
|
15559
|
+
if (markIt) markCst(ctx);
|
|
15560
|
+
const mRaw = markIt ? MRAW : 0;
|
|
15561
|
+
const mTl = markIt ? MTL : 0;
|
|
15562
|
+
const mLv = markIt ? MLV : 0;
|
|
15563
|
+
const mFl = markIt ? ctx._fields?.length ?? 0 : 0;
|
|
15564
|
+
const mEr = markIt ? ctx._errors?.length ?? 0 : 0;
|
|
15565
|
+
const mLog = markIt ? ctx._triviaLog?.length ?? 0 : 0;
|
|
15566
|
+
const mRoot = markIt ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14468
15567
|
let itemStart = cur;
|
|
14469
15568
|
let sepEnd = -1;
|
|
14470
15569
|
const viaRepItem = sep === void 0 && count >= min && (count > 0 || skipBeforeFirst);
|
|
@@ -14476,7 +15575,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14476
15575
|
if (sepLeads) LEAD.at = cur;
|
|
14477
15576
|
const sv = sep(input, sp, ctx);
|
|
14478
15577
|
if (sv === FAIL) {
|
|
14479
|
-
if (
|
|
15578
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14480
15579
|
if (committed3(ctx)) return FAIL;
|
|
14481
15580
|
break;
|
|
14482
15581
|
}
|
|
@@ -14487,25 +15586,25 @@ function assemble(t2, prog, cfg) {
|
|
|
14487
15586
|
itemStart = skipTrivia(input, itemStart, ctx);
|
|
14488
15587
|
}
|
|
14489
15588
|
if (itemStart >= input.length && viaRepItem) {
|
|
14490
|
-
if (
|
|
15589
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14491
15590
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
14492
15591
|
break;
|
|
14493
15592
|
}
|
|
14494
15593
|
if (count >= min && gateItems && !itemMayStart(input, itemStart)) {
|
|
14495
|
-
if (
|
|
15594
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14496
15595
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
14497
15596
|
break;
|
|
14498
15597
|
}
|
|
14499
15598
|
ctx._fc = false;
|
|
14500
15599
|
const v = child(input, itemStart, ctx);
|
|
14501
15600
|
if (v === FAIL) {
|
|
14502
|
-
if (
|
|
15601
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14503
15602
|
if (committed3(ctx)) return FAIL;
|
|
14504
15603
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
14505
15604
|
break;
|
|
14506
15605
|
}
|
|
14507
15606
|
if (EC.e === itemStart && viaRepItem) {
|
|
14508
|
-
if (
|
|
15607
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14509
15608
|
break;
|
|
14510
15609
|
}
|
|
14511
15610
|
if (out !== void 0) out.push(v);
|
|
@@ -14579,7 +15678,14 @@ function assemble(t2, prog, cfg) {
|
|
|
14579
15678
|
const runArm = n === 0 ? void 0 : bindArms(0);
|
|
14580
15679
|
const runOther = other === void 0 ? void 0 : dispatchBranch(other, otherRouted);
|
|
14581
15680
|
return (input, pos, ctx) => {
|
|
14582
|
-
const
|
|
15681
|
+
const need = markCst(ctx);
|
|
15682
|
+
const mRaw = MRAW;
|
|
15683
|
+
const mTl = MTL;
|
|
15684
|
+
const mLv = MLV;
|
|
15685
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
15686
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
15687
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
15688
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14583
15689
|
const selVal = selector(input, pos, ctx);
|
|
14584
15690
|
if (selVal === FAIL) return FAIL;
|
|
14585
15691
|
const selEnd = EC.e;
|
|
@@ -14591,9 +15697,9 @@ function assemble(t2, prog, cfg) {
|
|
|
14591
15697
|
ctx._fx = expected;
|
|
14592
15698
|
return FAIL;
|
|
14593
15699
|
}
|
|
14594
|
-
return runOther(input, pos, selEnd, key,
|
|
15700
|
+
return runOther(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14595
15701
|
}
|
|
14596
|
-
return runArm(arm, input, pos, selEnd, key,
|
|
15702
|
+
return runArm(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14597
15703
|
};
|
|
14598
15704
|
}
|
|
14599
15705
|
/* ── node ────────────────────────────────────────────────────────────── */
|
|
@@ -14629,7 +15735,8 @@ function assemble(t2, prog, cfg) {
|
|
|
14629
15735
|
return nd;
|
|
14630
15736
|
};
|
|
14631
15737
|
}
|
|
14632
|
-
const child = link(code[ip + 2]);
|
|
15738
|
+
const child = NODE_BODY ?? link(code[ip + 2]);
|
|
15739
|
+
NODE_BODY = void 0;
|
|
14633
15740
|
const proj = code[ip + 4];
|
|
14634
15741
|
const buildIdx = code[ip + 1];
|
|
14635
15742
|
const type = k[code[ip + 5]];
|
|
@@ -14653,6 +15760,30 @@ function assemble(t2, prog, cfg) {
|
|
|
14653
15760
|
if (build !== void 0 && proj < 0 && flags === 18) {
|
|
14654
15761
|
return childrenOnlyFieldsBuildNode(child, build);
|
|
14655
15762
|
}
|
|
15763
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
15764
|
+
return passCollapseNode(child, build, flags === 32);
|
|
15765
|
+
}
|
|
15766
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
15767
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(closureLabels.at(code[ip + 2]).tri, trivia2);
|
|
15768
|
+
if (build !== void 0 && gated !== void 0 && triviaLead !== void 0) {
|
|
15769
|
+
const classic = flags === 32 ? collapseBuildNode(child, build) : childrenOnlyCollapseBuildNode(child, build);
|
|
15770
|
+
return gatedPassCollapseNode(
|
|
15771
|
+
[
|
|
15772
|
+
...gated.leads.map((g) => cc[code[g + 1]]),
|
|
15773
|
+
resolveClass(encodeClassSpec([
|
|
15774
|
+
...triviaLead,
|
|
15775
|
+
...gated.lits.map((i) => {
|
|
15776
|
+
const c = k[i].codePointAt(0);
|
|
15777
|
+
return { lo: c, hi: c };
|
|
15778
|
+
})
|
|
15779
|
+
]))
|
|
15780
|
+
],
|
|
15781
|
+
link(gated.last),
|
|
15782
|
+
classic,
|
|
15783
|
+
build,
|
|
15784
|
+
flags === 32
|
|
15785
|
+
);
|
|
15786
|
+
}
|
|
14656
15787
|
if (build !== void 0 && proj < 0 && flags === 32) {
|
|
14657
15788
|
return collapseBuildNode(child, build);
|
|
14658
15789
|
}
|
|
@@ -14801,6 +15932,8 @@ function assemble(t2, prog, cfg) {
|
|
|
14801
15932
|
}
|
|
14802
15933
|
const notChild = scalarTerminalNotChild(code, ip);
|
|
14803
15934
|
if (notChild >= 0) scalarFor(notChild);
|
|
15935
|
+
const peekChild = scalarTerminalPeekChild(code, ip);
|
|
15936
|
+
if (peekChild >= 0) scalarFor(peekChild);
|
|
14804
15937
|
}
|
|
14805
15938
|
const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
|
|
14806
15939
|
if (pre !== void 0) {
|
|
@@ -14860,7 +15993,8 @@ function assemble(t2, prog, cfg) {
|
|
|
14860
15993
|
t2.lexPrograms,
|
|
14861
15994
|
LEAD,
|
|
14862
15995
|
triviaFieldCapture,
|
|
14863
|
-
skipDeferredTrivia
|
|
15996
|
+
skipDeferredTrivia,
|
|
15997
|
+
collapseEmpty
|
|
14864
15998
|
);
|
|
14865
15999
|
emitReached = new Set(pre.reached);
|
|
14866
16000
|
if (emitted.ext !== void 0) HYBRID = emitted;
|
|
@@ -14946,7 +16080,8 @@ function assemble(t2, prog, cfg) {
|
|
|
14946
16080
|
t2.lexPrograms,
|
|
14947
16081
|
LEAD,
|
|
14948
16082
|
triviaFieldCapture,
|
|
14949
|
-
skipDeferredTrivia
|
|
16083
|
+
skipDeferredTrivia,
|
|
16084
|
+
collapseEmpty
|
|
14950
16085
|
);
|
|
14951
16086
|
emitReached = em.reached;
|
|
14952
16087
|
} catch (e) {
|
|
@@ -15213,7 +16348,7 @@ function emitClassPool(classes) {
|
|
|
15213
16348
|
if (classes.length < 2) return array;
|
|
15214
16349
|
const delimiter = "|/~?^`".split("").find((ch2) => classes.every((spec) => !spec.includes(ch2)));
|
|
15215
16350
|
if (delimiter === void 0) return array;
|
|
15216
|
-
const split =
|
|
16351
|
+
const split = `/* @__PURE__ */ ${jsString(classes.join(delimiter))}.split(${jsString(delimiter)})`;
|
|
15217
16352
|
return split.length < array.length ? split : array;
|
|
15218
16353
|
}
|
|
15219
16354
|
function emitConst(v) {
|
|
@@ -16820,339 +17955,85 @@ function reportDuplication(opt, analyze) {
|
|
|
16820
17955
|
if (level === "error") throw new Error(`parseman: ${duplicationFindingCount(report)} duplication/overlap finding(s)
|
|
16821
17956
|
${lines2.join("\n")}`);
|
|
16822
17957
|
for (const l of lines2) console.warn(l);
|
|
16823
|
-
}
|
|
16824
|
-
return report;
|
|
16825
|
-
}
|
|
16826
|
-
function runDuplicationDiagnostic(combinator, opt) {
|
|
16827
|
-
return reportDuplication(opt, (o) => analyzeDuplication(combinator, o));
|
|
16828
|
-
}
|
|
16829
|
-
function runDuplicationDiagnosticRules(ruleMap, opt) {
|
|
16830
|
-
return reportDuplication(opt, (o) => analyzeDuplicationRules(ruleMap, o));
|
|
16831
|
-
}
|
|
16832
|
-
|
|
16833
|
-
// src/table/compile-rule-map.ts
|
|
16834
|
-
function resolveHostMode(ruleMap, explicit) {
|
|
16835
|
-
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
16836
|
-
}
|
|
16837
|
-
function resolveTrackLines(ruleMap, explicit) {
|
|
16838
|
-
return explicit === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
16839
|
-
}
|
|
16840
|
-
function withAmbient(ruleMap, opts) {
|
|
16841
|
-
if (opts.trivia === void 0 && opts.scanSkip === void 0) return ruleMap;
|
|
16842
|
-
const wrappers = /* @__PURE__ */ new Map();
|
|
16843
|
-
return ruleMap.map(([name, rule2]) => {
|
|
16844
|
-
if (rule2._meta.isTrivia) return [name, rule2];
|
|
16845
|
-
const addTrivia = opts.trivia !== void 0 && rule2._meta.grammarTrivia === void 0;
|
|
16846
|
-
const addScanSkip = opts.scanSkip !== void 0 && rule2._meta.grammarScanSkip === void 0;
|
|
16847
|
-
if (!addTrivia && !addScanSkip) return [name, rule2];
|
|
16848
|
-
let wrapped = wrappers.get(rule2);
|
|
16849
|
-
if (wrapped === void 0) {
|
|
16850
|
-
wrapped = {
|
|
16851
|
-
...rule2,
|
|
16852
|
-
_meta: {
|
|
16853
|
-
...rule2._meta,
|
|
16854
|
-
...addTrivia ? { grammarTrivia: opts.trivia } : {},
|
|
16855
|
-
...addScanSkip ? { grammarScanSkip: opts.scanSkip } : {}
|
|
16856
|
-
}
|
|
16857
|
-
};
|
|
16858
|
-
wrappers.set(rule2, wrapped);
|
|
16859
|
-
}
|
|
16860
|
-
return [name, wrapped];
|
|
16861
|
-
});
|
|
16862
|
-
}
|
|
16863
|
-
function compileRuleMapRunnable(ruleMap, opts = {}) {
|
|
16864
|
-
const encoded = encodeForRun(ruleMap, opts);
|
|
16865
|
-
if (encoded === null) return null;
|
|
16866
|
-
const { prog, hostMode, plan } = encoded;
|
|
16867
|
-
const artifact = closureArtifact(prog);
|
|
16868
|
-
const reflection = collectGrammarReflection(ruleMap);
|
|
16869
|
-
return {
|
|
16870
|
-
keys: ruleMap.map(([key]) => key),
|
|
16871
|
-
hostMode,
|
|
16872
|
-
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule2]) => hasDirectBuildDef(rule2)),
|
|
16873
|
-
reflection,
|
|
16874
|
-
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
16875
|
-
// Reflection rides on the map's metadata prototype from birth. Only `compile()`
|
|
16876
|
-
// asks to specialise; every other caller runs the closure artifact.
|
|
16877
|
-
rules: tableRules(opts.specialise === true ? prog : artifact, { [GRAMMAR_REFLECTION]: reflection }),
|
|
16878
|
-
prog: artifact
|
|
16879
|
-
};
|
|
16880
|
-
}
|
|
16881
|
-
function encodeForRun(ruleMap, opts) {
|
|
16882
|
-
runDuplicationDiagnosticRules(ruleMap, opts.duplication);
|
|
16883
|
-
const encodeMap = withAmbient(ruleMap, opts);
|
|
16884
|
-
const plan = opts.coverage === true ? buildGrammarPlan(
|
|
16885
|
-
encodeMap.map(([, rule2]) => rule2),
|
|
16886
|
-
Object.fromEntries(encodeMap.filter(([, rule2]) => rule2._def.tag !== "lazy"))
|
|
16887
|
-
) : void 0;
|
|
16888
|
-
const hostMode = resolveHostMode(ruleMap, opts.hostMode);
|
|
16889
|
-
const settings = {
|
|
16890
|
-
hostMode,
|
|
16891
|
-
...resolveTrackLines(ruleMap, opts.trackLines) ? { trackLines: true } : {},
|
|
16892
|
-
...opts.recovery === true ? { recovery: true } : {},
|
|
16893
|
-
...plan === void 0 ? {} : { coverage: plan }
|
|
16894
|
-
};
|
|
16895
|
-
try {
|
|
16896
|
-
const { prog, fnSrcs } = encodeTableProgram(Object.fromEntries(encodeMap), settings);
|
|
16897
|
-
return { prog, fnSrcs, hostMode, plan };
|
|
16898
|
-
} catch (e) {
|
|
16899
|
-
opts.refusals?.push(e instanceof Error ? e.message : String(e));
|
|
16900
|
-
return null;
|
|
16901
|
-
}
|
|
16902
|
-
}
|
|
16903
|
-
|
|
16904
|
-
// src/compiler/value-usage.ts
|
|
16905
|
-
function markUnusedValues(root) {
|
|
16906
|
-
const seenConsumed = /* @__PURE__ */ new WeakSet();
|
|
16907
|
-
const seenUnconsumed = /* @__PURE__ */ new WeakSet();
|
|
16908
|
-
const mark = (def, consumed) => {
|
|
16909
|
-
if (consumed) def.valueUnused = false;
|
|
16910
|
-
else if (def.valueUnused !== false) def.valueUnused = true;
|
|
16911
|
-
};
|
|
16912
|
-
const visit = (c, consumed) => {
|
|
16913
|
-
const seen = consumed ? seenConsumed : seenUnconsumed;
|
|
16914
|
-
if (seen.has(c)) return;
|
|
16915
|
-
seen.add(c);
|
|
16916
|
-
const def = c._def;
|
|
16917
|
-
switch (def.tag) {
|
|
16918
|
-
case "many":
|
|
16919
|
-
case "oneOrMore":
|
|
16920
|
-
mark(def, consumed);
|
|
16921
|
-
visit(def.parser, consumed);
|
|
16922
|
-
return;
|
|
16923
|
-
case "optional":
|
|
16924
|
-
visit(def.parser, consumed);
|
|
16925
|
-
return;
|
|
16926
|
-
case "sequence":
|
|
16927
|
-
mark(def, consumed);
|
|
16928
|
-
for (const p of def.parsers) visit(p, consumed);
|
|
16929
|
-
return;
|
|
16930
|
-
case "choice":
|
|
16931
|
-
for (const p of def.parsers) visit(p, consumed);
|
|
16932
|
-
return;
|
|
16933
|
-
case "dispatch":
|
|
16934
|
-
visit(def.selector, consumed);
|
|
16935
|
-
for (const entry of def.cases) visit(entry.parser, consumed);
|
|
16936
|
-
if (def.matchers) for (const entry of def.matchers) visit(entry.parser, consumed);
|
|
16937
|
-
if (def.otherwise) visit(def.otherwise, consumed);
|
|
16938
|
-
return;
|
|
16939
|
-
case "node":
|
|
16940
|
-
visit(def.parser, false);
|
|
16941
|
-
return;
|
|
16942
|
-
case "transform":
|
|
16943
|
-
visit(def.parser, true);
|
|
16944
|
-
return;
|
|
16945
|
-
case "field":
|
|
16946
|
-
visit(def.parser, true);
|
|
16947
|
-
return;
|
|
16948
|
-
case "sepBy":
|
|
16949
|
-
visit(def.parser, true);
|
|
16950
|
-
visit(def.separator, false);
|
|
16951
|
-
return;
|
|
16952
|
-
case "not":
|
|
16953
|
-
case "peek":
|
|
16954
|
-
visit(def.parser, false);
|
|
16955
|
-
return;
|
|
16956
|
-
case "grammar":
|
|
16957
|
-
visit(def.parser, consumed);
|
|
16958
|
-
if (def.triviaParser) visit(def.triviaParser, false);
|
|
16959
|
-
return;
|
|
16960
|
-
case "recover":
|
|
16961
|
-
visit(def.parser, consumed);
|
|
16962
|
-
visit(def.sentinel, false);
|
|
16963
|
-
return;
|
|
16964
|
-
case "token":
|
|
16965
|
-
visit(def.parser, false);
|
|
16966
|
-
return;
|
|
16967
|
-
case "label":
|
|
16968
|
-
case "trivia":
|
|
16969
|
-
case "attempt":
|
|
16970
|
-
case "withCtx":
|
|
16971
|
-
case "expect":
|
|
16972
|
-
visit(def.parser, consumed);
|
|
16973
|
-
return;
|
|
16974
|
-
case "leaf":
|
|
16975
|
-
visit(def.parser, true);
|
|
16976
|
-
return;
|
|
16977
|
-
case "lazy":
|
|
16978
|
-
return;
|
|
16979
|
-
default:
|
|
16980
|
-
return;
|
|
16981
|
-
}
|
|
16982
|
-
};
|
|
16983
|
-
const resolveRoot = (c) => {
|
|
16984
|
-
const guard = /* @__PURE__ */ new Set();
|
|
16985
|
-
let cur = c;
|
|
16986
|
-
while (!guard.has(cur)) {
|
|
16987
|
-
const d = cur._def;
|
|
16988
|
-
if (d.tag === "grammar") {
|
|
16989
|
-
guard.add(cur);
|
|
16990
|
-
cur = d.parser;
|
|
16991
|
-
continue;
|
|
16992
|
-
}
|
|
16993
|
-
if (d.tag !== "lazy") return cur;
|
|
16994
|
-
guard.add(cur);
|
|
16995
|
-
try {
|
|
16996
|
-
cur = d.thunk();
|
|
16997
|
-
} catch {
|
|
16998
|
-
return c;
|
|
16999
|
-
}
|
|
17000
|
-
}
|
|
17001
|
-
return cur;
|
|
17002
|
-
};
|
|
17003
|
-
visit(resolveRoot(root), true);
|
|
17958
|
+
}
|
|
17959
|
+
return report;
|
|
17960
|
+
}
|
|
17961
|
+
function runDuplicationDiagnostic(combinator, opt) {
|
|
17962
|
+
return reportDuplication(opt, (o) => analyzeDuplication(combinator, o));
|
|
17963
|
+
}
|
|
17964
|
+
function runDuplicationDiagnosticRules(ruleMap, opt) {
|
|
17965
|
+
return reportDuplication(opt, (o) => analyzeDuplicationRules(ruleMap, o));
|
|
17004
17966
|
}
|
|
17005
17967
|
|
|
17006
|
-
// src/
|
|
17007
|
-
function
|
|
17008
|
-
|
|
17009
|
-
const errors = annotated.errors;
|
|
17010
|
-
if (errors) {
|
|
17011
|
-
;
|
|
17012
|
-
annotated.errors = errors.map((error) => ({
|
|
17013
|
-
...error,
|
|
17014
|
-
span: annotateSpan(error.span, index)
|
|
17015
|
-
}));
|
|
17016
|
-
}
|
|
17017
|
-
return annotated;
|
|
17968
|
+
// src/table/compile-rule-map.ts
|
|
17969
|
+
function resolveHostMode(ruleMap, explicit) {
|
|
17970
|
+
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
17018
17971
|
}
|
|
17019
|
-
function
|
|
17020
|
-
|
|
17021
|
-
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
17022
|
-
return { lineIndex, lineScannedTo: pos };
|
|
17972
|
+
function resolveTrackLines(ruleMap, explicit) {
|
|
17973
|
+
return explicit === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
17023
17974
|
}
|
|
17024
|
-
|
|
17025
|
-
|
|
17026
|
-
|
|
17027
|
-
|
|
17028
|
-
|
|
17029
|
-
|
|
17030
|
-
|
|
17031
|
-
|
|
17032
|
-
|
|
17033
|
-
|
|
17034
|
-
|
|
17035
|
-
|
|
17036
|
-
|
|
17037
|
-
|
|
17038
|
-
|
|
17039
|
-
|
|
17040
|
-
const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
|
|
17041
|
-
const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
|
|
17042
|
-
const rootScalar = scalarOf(root);
|
|
17043
|
-
const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
|
|
17044
|
-
const parseScalar = scalarEligible ? (input, pos, ctx) => {
|
|
17045
|
-
const savedTrivia = ctx.trivia;
|
|
17046
|
-
const savedLabels = ctx.triviaKindLabels;
|
|
17047
|
-
if (clearTrivia) {
|
|
17048
|
-
ctx.trivia = void 0;
|
|
17049
|
-
ctx.triviaKindLabels = void 0;
|
|
17050
|
-
} else if (scopeTrivia !== void 0) {
|
|
17051
|
-
ctx.trivia = scopeTrivia;
|
|
17052
|
-
ctx.triviaKindLabels = scopeLabels;
|
|
17053
|
-
}
|
|
17054
|
-
const end = rootScalar(input, pos, ctx);
|
|
17055
|
-
ctx.trivia = savedTrivia;
|
|
17056
|
-
ctx.triviaKindLabels = savedLabels;
|
|
17057
|
-
return end;
|
|
17058
|
-
} : void 0;
|
|
17059
|
-
let publicScalar;
|
|
17060
|
-
const grammar = {
|
|
17061
|
-
_tag: "grammar",
|
|
17062
|
-
_meta: {
|
|
17063
|
-
...root._meta,
|
|
17064
|
-
// Trivia classification describes this grammar's own active trivia
|
|
17065
|
-
// scope. A directly nested grammar may have classified trivia of its
|
|
17066
|
-
// own, but that must not advertise classification for this wrapper.
|
|
17067
|
-
triviaKindLabels: void 0,
|
|
17068
|
-
rootTriviaClassified: void 0,
|
|
17069
|
-
...opts.trivia?._meta?.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {},
|
|
17070
|
-
...opts.trivia?._meta?.rootTriviaClassified ? { rootTriviaClassified: true } : {}
|
|
17071
|
-
},
|
|
17072
|
-
_def: {
|
|
17073
|
-
tag: "grammar",
|
|
17074
|
-
parser: root,
|
|
17075
|
-
triviaParser: scopeTrivia,
|
|
17076
|
-
clearTrivia,
|
|
17077
|
-
...opaqueRootCapture ? { rootCapture: "opaque" } : {},
|
|
17078
|
-
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
17079
|
-
trackLines: opts.trackLines ?? false,
|
|
17080
|
-
constructionTrackLines: trackLinesPolicy,
|
|
17081
|
-
...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
|
|
17082
|
-
},
|
|
17083
|
-
_parseScalar: parseScalar,
|
|
17084
|
-
parse(input, pos, _ctx) {
|
|
17085
|
-
if (pos === void 0 && _ctx === void 0) {
|
|
17086
|
-
publicScalar ??= scalarRootOf(grammar) ?? null;
|
|
17087
|
-
if (publicScalar) {
|
|
17088
|
-
const ctx2 = createParseContext();
|
|
17089
|
-
const end = publicScalar(input, 0, ctx2);
|
|
17090
|
-
if (end < 0) {
|
|
17091
|
-
const at = ~end;
|
|
17092
|
-
return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
|
|
17093
|
-
}
|
|
17094
|
-
return { ok: true, value: ctx2._sv, span: { start: 0, end } };
|
|
17975
|
+
function withAmbient(ruleMap, opts) {
|
|
17976
|
+
if (opts.trivia === void 0 && opts.scanSkip === void 0) return ruleMap;
|
|
17977
|
+
const wrappers = /* @__PURE__ */ new Map();
|
|
17978
|
+
return ruleMap.map(([name, rule2]) => {
|
|
17979
|
+
if (rule2._meta.isTrivia) return [name, rule2];
|
|
17980
|
+
const addTrivia = opts.trivia !== void 0 && rule2._meta.grammarTrivia === void 0;
|
|
17981
|
+
const addScanSkip = opts.scanSkip !== void 0 && rule2._meta.grammarScanSkip === void 0;
|
|
17982
|
+
if (!addTrivia && !addScanSkip) return [name, rule2];
|
|
17983
|
+
let wrapped = wrappers.get(rule2);
|
|
17984
|
+
if (wrapped === void 0) {
|
|
17985
|
+
wrapped = {
|
|
17986
|
+
...rule2,
|
|
17987
|
+
_meta: {
|
|
17988
|
+
...rule2._meta,
|
|
17989
|
+
...addTrivia ? { grammarTrivia: opts.trivia } : {},
|
|
17990
|
+
...addScanSkip ? { grammarScanSkip: opts.scanSkip } : {}
|
|
17095
17991
|
}
|
|
17096
|
-
}
|
|
17097
|
-
|
|
17098
|
-
const trackLines = trackLinesOf(_ctx);
|
|
17099
|
-
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
17100
|
-
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
17101
|
-
const ctx = _ctx === void 0 ? createParseContext() : { ..._ctx };
|
|
17102
|
-
ctx.trackLines = trackLines;
|
|
17103
|
-
if (lineIndex) ctx._lineIndex = lineIndex;
|
|
17104
|
-
if (lineContext) ctx._lineScannedTo = lineContext.lineScannedTo;
|
|
17105
|
-
if (clearTrivia) {
|
|
17106
|
-
ctx.trivia = void 0;
|
|
17107
|
-
ctx.triviaKindLabels = void 0;
|
|
17108
|
-
} else if (scopeTrivia !== void 0) {
|
|
17109
|
-
ctx.trivia = scopeTrivia;
|
|
17110
|
-
if (scopeLabels) ctx.triviaKindLabels = scopeLabels;
|
|
17111
|
-
}
|
|
17112
|
-
if (forceCaptureTrivia || _ctx?.captureTrivia) ctx.captureTrivia = true;
|
|
17113
|
-
if (ownCaptureMask !== void 0) ctx._triviaCaptureMask = ownCaptureMask;
|
|
17114
|
-
else if (inheritCaptureMask) ctx._triviaCaptureMask = triviaKindMask(_ctx?.triviaKindLabels, captureKinds);
|
|
17115
|
-
if (opaqueRootCapture) ctx._rootTriviaCapture = false;
|
|
17116
|
-
const result = root.parse(input, pos ?? 0, ctx);
|
|
17117
|
-
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
17118
|
-
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
17119
|
-
}
|
|
17120
|
-
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
17992
|
+
};
|
|
17993
|
+
wrappers.set(rule2, wrapped);
|
|
17121
17994
|
}
|
|
17995
|
+
return [name, wrapped];
|
|
17996
|
+
});
|
|
17997
|
+
}
|
|
17998
|
+
function compileRuleMapRunnable(ruleMap, opts = {}) {
|
|
17999
|
+
const encoded = encodeForRun(ruleMap, opts);
|
|
18000
|
+
if (encoded === null) return null;
|
|
18001
|
+
const { prog, hostMode, plan } = encoded;
|
|
18002
|
+
const artifact = closureArtifact(prog);
|
|
18003
|
+
const reflection = collectGrammarReflection(ruleMap);
|
|
18004
|
+
return {
|
|
18005
|
+
keys: ruleMap.map(([key]) => key),
|
|
18006
|
+
hostMode,
|
|
18007
|
+
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule2]) => hasDirectBuildDef(rule2)),
|
|
18008
|
+
reflection,
|
|
18009
|
+
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
18010
|
+
// Reflection rides on the map's metadata prototype from birth. Only `compile()`
|
|
18011
|
+
// asks to specialise; every other caller runs the closure artifact.
|
|
18012
|
+
rules: tableRules(opts.specialise === true ? prog : artifact, { [GRAMMAR_REFLECTION]: reflection }),
|
|
18013
|
+
prog: artifact
|
|
17122
18014
|
};
|
|
17123
|
-
return grammar;
|
|
17124
18015
|
}
|
|
17125
|
-
|
|
17126
|
-
|
|
17127
|
-
|
|
17128
|
-
|
|
17129
|
-
|
|
17130
|
-
|
|
17131
|
-
|
|
17132
|
-
|
|
17133
|
-
|
|
17134
|
-
|
|
17135
|
-
|
|
17136
|
-
|
|
17137
|
-
|
|
17138
|
-
|
|
17139
|
-
|
|
17140
|
-
|
|
17141
|
-
|
|
17142
|
-
|
|
17143
|
-
|
|
17144
|
-
|
|
17145
|
-
if (grammarTrivia !== void 0) {
|
|
17146
|
-
ctx.trivia = grammarTrivia;
|
|
17147
|
-
if (grammarTrivia._meta.triviaKindLabels) ctx.triviaKindLabels = grammarTrivia._meta.triviaKindLabels;
|
|
18016
|
+
function encodeForRun(ruleMap, opts) {
|
|
18017
|
+
runDuplicationDiagnosticRules(ruleMap, opts.duplication);
|
|
18018
|
+
const encodeMap = withAmbient(ruleMap, opts);
|
|
18019
|
+
const plan = opts.coverage === true ? buildGrammarPlan(
|
|
18020
|
+
encodeMap.map(([, rule2]) => rule2),
|
|
18021
|
+
Object.fromEntries(encodeMap.filter(([, rule2]) => rule2._def.tag !== "lazy"))
|
|
18022
|
+
) : void 0;
|
|
18023
|
+
const hostMode = resolveHostMode(ruleMap, opts.hostMode);
|
|
18024
|
+
const settings = {
|
|
18025
|
+
hostMode,
|
|
18026
|
+
...resolveTrackLines(ruleMap, opts.trackLines) ? { trackLines: true } : {},
|
|
18027
|
+
...opts.recovery === true ? { recovery: true } : {},
|
|
18028
|
+
...plan === void 0 ? {} : { coverage: plan }
|
|
18029
|
+
};
|
|
18030
|
+
try {
|
|
18031
|
+
const { prog, fnSrcs } = encodeTableProgram(Object.fromEntries(encodeMap), settings);
|
|
18032
|
+
return { prog, fnSrcs, hostMode, plan };
|
|
18033
|
+
} catch (e) {
|
|
18034
|
+
opts.refusals?.push(e instanceof Error ? e.message : String(e));
|
|
18035
|
+
return null;
|
|
17148
18036
|
}
|
|
17149
|
-
if (grammarScanSkip !== void 0) ctx.scanSkip = grammarScanSkip;
|
|
17150
|
-
if (_errors !== void 0) ctx._errors = _errors;
|
|
17151
|
-
if (_probe !== void 0) ctx._probe = _probe;
|
|
17152
|
-
const result = combinator.parse(input, 0, ctx);
|
|
17153
|
-
if (!result.ok) return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
17154
|
-
const withErrors = _errors !== void 0 ? { ...result, errors: _errors, furthestFail: _probe?.best ?? null } : result;
|
|
17155
|
-
return lineIndex ? annotateResultLines(withErrors, normalizeLineIndex(lineIndex)) : withErrors;
|
|
17156
18037
|
}
|
|
17157
18038
|
|
|
17158
18039
|
// src/compiler/linker.ts
|
|
@@ -17252,7 +18133,7 @@ function analyzeGrammarGating(grammar, opts) {
|
|
|
17252
18133
|
}
|
|
17253
18134
|
|
|
17254
18135
|
// src/analysis/diagnose.ts
|
|
17255
|
-
var
|
|
18136
|
+
var isCombinator2 = (g) => typeof g === "object" && g !== null && "_def" in g;
|
|
17256
18137
|
var isRuleEntries = (g) => Array.isArray(g);
|
|
17257
18138
|
function diagnoseGrammar(grammar, opts) {
|
|
17258
18139
|
const depth = degradationCaptureDepth();
|
|
@@ -17273,7 +18154,7 @@ function examinedNothing(d) {
|
|
|
17273
18154
|
return d.summary.totalChoices === 0 && d.summary.unanalysable > 0;
|
|
17274
18155
|
}
|
|
17275
18156
|
function runAnalysis(grammar, opts) {
|
|
17276
|
-
if (
|
|
18157
|
+
if (isCombinator2(grammar)) return analyzeGating(grammar, opts);
|
|
17277
18158
|
if (isRuleEntries(grammar)) return analyzeGatingRules(grammar, opts);
|
|
17278
18159
|
return analyzeGrammarGating(grammar, opts);
|
|
17279
18160
|
}
|
|
@@ -18032,16 +18913,16 @@ function ownSource(fn) {
|
|
|
18032
18913
|
return typeof name === "string" && name.length > 0 && globalThis[name] === fn ? name : null;
|
|
18033
18914
|
}
|
|
18034
18915
|
function compile(target, second, third) {
|
|
18035
|
-
if (!
|
|
18916
|
+
if (!isCombinator3(target)) return compileMap(target, second);
|
|
18036
18917
|
return compileRoot(target, second, third);
|
|
18037
18918
|
}
|
|
18038
|
-
function
|
|
18919
|
+
function isCombinator3(x) {
|
|
18039
18920
|
return typeof x === "object" && x !== null && typeof x.parse === "function" && "_def" in x;
|
|
18040
18921
|
}
|
|
18041
18922
|
function compileMap(grammar, opts = {}) {
|
|
18042
18923
|
const entries = [];
|
|
18043
18924
|
for (const [key, value] of Object.entries(grammar)) {
|
|
18044
|
-
if (!
|
|
18925
|
+
if (!isCombinator3(value)) throw new TypeError(`compile: grammar entry "${key}" is not a parser`);
|
|
18045
18926
|
if (value._def.tag === "lazy") {
|
|
18046
18927
|
try {
|
|
18047
18928
|
value._def.thunk();
|
|
@@ -18355,49 +19236,6 @@ function digestValue(value, prefix = "", options) {
|
|
|
18355
19236
|
return sha.digest("hex");
|
|
18356
19237
|
}
|
|
18357
19238
|
|
|
18358
|
-
// src/combinators/attempt.ts
|
|
18359
|
-
function containOption(options) {
|
|
18360
|
-
if (options === void 0) return false;
|
|
18361
|
-
for (const key of Object.keys(options)) {
|
|
18362
|
-
if (key !== "contain") throw new TypeError(`attempt(): unknown option ${JSON.stringify(key)}`);
|
|
18363
|
-
}
|
|
18364
|
-
if (options.contain !== void 0 && typeof options.contain !== "boolean") {
|
|
18365
|
-
throw new TypeError("attempt(): `contain` must be a boolean");
|
|
18366
|
-
}
|
|
18367
|
-
return options.contain === true;
|
|
18368
|
-
}
|
|
18369
|
-
function attempt(parser2, options) {
|
|
18370
|
-
const contain = containOption(options);
|
|
18371
|
-
const guardable = parser2._meta.firstSet.kind !== "any" && !matchesEmpty(parser2);
|
|
18372
|
-
let failExpected;
|
|
18373
|
-
return {
|
|
18374
|
-
_tag: "attempt",
|
|
18375
|
-
_meta: parser2._meta,
|
|
18376
|
-
_def: contain ? { tag: "attempt", parser: parser2, contain: true } : { tag: "attempt", parser: parser2 },
|
|
18377
|
-
parse(input, pos, ctx) {
|
|
18378
|
-
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(parser2, input, pos)) {
|
|
18379
|
-
if (failExpected === void 0) {
|
|
18380
|
-
const e = deriveExpected(parser2);
|
|
18381
|
-
failExpected = e.length > 0 ? e : [parser2._tag];
|
|
18382
|
-
}
|
|
18383
|
-
return { ok: false, expected: failExpected, span: { start: pos, end: pos } };
|
|
18384
|
-
}
|
|
18385
|
-
const mark = saveCstMark(ctx);
|
|
18386
|
-
const log = ctx._triviaLog?.length;
|
|
18387
|
-
const rootLog = ctx._rootTriviaLog?.length;
|
|
18388
|
-
const split = ctx._columnsSplit;
|
|
18389
|
-
const result = parser2.parse(input, pos, ctx);
|
|
18390
|
-
if (result.ok) return result;
|
|
18391
|
-
rollbackCstCapture(ctx, mark);
|
|
18392
|
-
ctx._columnsSplit = split;
|
|
18393
|
-
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
18394
|
-
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
18395
|
-
if (result.committed && !contain) return result;
|
|
18396
|
-
return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
|
|
18397
|
-
}
|
|
18398
|
-
};
|
|
18399
|
-
}
|
|
18400
|
-
|
|
18401
19239
|
// src/combinators/not.ts
|
|
18402
19240
|
function not(combinator) {
|
|
18403
19241
|
const meta = {
|