parseman 0.55.4 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/choice-cost.d.ts.map +1 -1
- package/dist/analysis/commitment.d.ts.map +1 -1
- package/dist/analysis/diagnostics.js +3745 -3180
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/analysis/duplication.d.ts.map +1 -1
- package/dist/analysis/gating.d.ts.map +1 -1
- package/dist/cli/index.js +2182 -1617
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/attempt.d.ts.map +1 -1
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/combinators/lines.d.ts +79 -0
- package/dist/combinators/lines.d.ts.map +1 -0
- package/dist/combinators/node.d.ts +1 -1
- package/dist/combinators/trivia-skip.d.ts +1 -0
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/build-arity.d.ts +1 -1
- package/dist/compiler/build-arity.d.ts.map +1 -1
- package/dist/compiler/fields.d.ts.map +1 -1
- package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +25 -0
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/coverage.d.ts.map +1 -1
- package/dist/cst/reflection.d.ts.map +1 -1
- package/dist/cst/trivia-kinds.d.ts +9 -1
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2348 -1697
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +3 -0
- package/dist/language-service/index.js.map +1 -1
- package/dist/parse-context.d.ts.map +1 -1
- package/dist/plugin/entry-supercompiler.d.ts +1 -1
- package/dist/plugin/entry-supercompiler.d.ts.map +1 -1
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.d.ts +27 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +2360 -1314
- package/dist/plugin/index.js.map +3 -3
- package/dist/plugin/ir-eval.d.ts +2 -4
- package/dist/plugin/ir-eval.d.ts.map +1 -1
- package/dist/regex/classes.d.ts.map +1 -1
- package/dist/run/index.js +3 -0
- package/dist/run/index.js.map +1 -1
- package/dist/spec/index.js +15 -0
- package/dist/spec/index.js.map +1 -1
- package/dist/spec/model.d.ts.map +1 -1
- package/dist/table/assemble.d.ts +9 -65
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/child-slots.d.ts +4 -6
- package/dist/table/child-slots.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +14 -2
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +17 -2
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts +5 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec-baseline.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/index.js +3884 -3262
- package/dist/table/index.js.map +3 -3
- package/dist/table/line-scan.d.ts +9 -0
- package/dist/table/line-scan.d.ts.map +1 -0
- package/dist/table/ops.d.ts +9 -6
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +24 -2
- package/dist/table/program.d.ts.map +1 -1
- package/dist/table/select-hot.d.ts +6 -0
- package/dist/table/select-hot.d.ts.map +1 -0
- package/dist/table/trivia-gap.d.ts +31 -0
- package/dist/table/trivia-gap.d.ts.map +1 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +4 -1
- package/src/analysis/choice-cost.ts +1 -0
- package/src/analysis/commitment.ts +13 -0
- package/src/analysis/duplication.ts +3 -0
- package/src/analysis/gating.ts +5 -0
- package/src/analysis/rebuild.ts +2 -2
- package/src/combinators/attempt.ts +2 -0
- package/src/combinators/choice.ts +3 -0
- package/src/combinators/dispatch.ts +3 -0
- package/src/combinators/expect.ts +5 -0
- package/src/combinators/first-set.ts +9 -1
- package/src/combinators/lines.ts +244 -0
- package/src/combinators/node.ts +6 -13
- package/src/combinators/trivia-skip.ts +48 -3
- package/src/compiler/build-arity.ts +3 -3
- package/src/compiler/fields.ts +3 -0
- package/src/compiler/grammar-coverage-ids.ts +1 -0
- package/src/compiler/ir-serialize.ts +10 -0
- package/src/compiler/token-alphabet.ts +3 -1
- package/src/coverage.ts +6 -0
- package/src/cst/reflection.ts +3 -0
- package/src/cst/trivia-kinds.ts +12 -1
- package/src/index.ts +2 -0
- package/src/parse-context.ts +3 -0
- package/src/plugin/entry-supercompiler.ts +8 -9
- package/src/plugin/evaluator.ts +4 -0
- package/src/plugin/index.ts +138 -13
- package/src/plugin/ir-eval.ts +10 -1
- package/src/regex/classes.ts +3 -0
- package/src/spec/model.ts +15 -0
- package/src/table/assemble.ts +125 -33
- package/src/table/child-slots.ts +4 -6
- package/src/table/compile-rule-map.ts +55 -15
- package/src/table/emit-assembly.ts +139 -26
- package/src/table/emit.ts +13 -11
- package/src/table/encode.ts +87 -27
- package/src/table/exec-baseline.ts +1 -3
- package/src/table/exec.ts +10 -6
- package/src/table/line-scan.ts +19 -0
- package/src/table/ops.ts +9 -6
- package/src/table/program.ts +41 -2
- package/src/table/select-hot.ts +70 -0
- package/src/table/trivia-gap.ts +109 -0
- package/src/types.ts +32 -0
- package/src/version.ts +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -163,6 +163,11 @@ function matchesEmptyBody(p, seen, resolve2) {
|
|
|
163
163
|
return true;
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
+
// A run consumes at least its first line's prefix, and its body after that.
|
|
167
|
+
case "lines":
|
|
168
|
+
return me(d.first ?? d.prefix) && me(d.body);
|
|
169
|
+
case "columns":
|
|
170
|
+
return d.n === 0;
|
|
166
171
|
default:
|
|
167
172
|
return true;
|
|
168
173
|
}
|
|
@@ -277,6 +282,11 @@ function firstSetBody(p, seen, resolve2, activeTrivia) {
|
|
|
277
282
|
resolve2,
|
|
278
283
|
d.clearTrivia ? null : d.triviaParser ?? activeTrivia
|
|
279
284
|
);
|
|
285
|
+
// A run starts with its first line's prefix; a nullable prefix starts with anything.
|
|
286
|
+
case "lines": {
|
|
287
|
+
const opening = d.first ?? d.prefix;
|
|
288
|
+
return empties(opening) ? any() : fs(opening);
|
|
289
|
+
}
|
|
280
290
|
default:
|
|
281
291
|
return p._meta.firstSet;
|
|
282
292
|
}
|
|
@@ -326,6 +336,10 @@ function childrenOf(d) {
|
|
|
326
336
|
return d.triviaParser ? [d.parser, d.triviaParser] : [d.parser];
|
|
327
337
|
case "routed":
|
|
328
338
|
return d.fallback ? [d.fallback] : [];
|
|
339
|
+
case "lines":
|
|
340
|
+
return [d.prefix, d.body, ...d.first === void 0 ? [] : [d.first], ...d.lazy === void 0 ? [] : [d.lazy]];
|
|
341
|
+
case "columns":
|
|
342
|
+
return [];
|
|
329
343
|
// A `lazy` is a REFERENCE, not a subtree. Descending through it would make
|
|
330
344
|
// every rule's walk cover the whole reachable grammar — site paths become
|
|
331
345
|
// nonsense, and a structural hash includes half the grammar. Treated as a
|
|
@@ -417,6 +431,9 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
417
431
|
return walk(d.parser);
|
|
418
432
|
case "scanTo":
|
|
419
433
|
return { cause: "broad-recognizer", detail: "scanTo (any first char)" };
|
|
434
|
+
// A run opens with its first line's prefix.
|
|
435
|
+
case "lines":
|
|
436
|
+
return walk(d.first ?? d.prefix);
|
|
420
437
|
// `guard` (the `gate()` state predicate) has a genuinely-`any` first-set of
|
|
421
438
|
// its own — it is the poison. `withCtx`/`recover` FORWARD their inner
|
|
422
439
|
// first-set (see firstSetOf), so a broad result comes from the inner parser:
|
|
@@ -960,6 +977,7 @@ function literalCodePoints(frag) {
|
|
|
960
977
|
if (ch2 === "\\") {
|
|
961
978
|
const e = frag[i + 1];
|
|
962
979
|
if (e === void 0) return null;
|
|
980
|
+
if (!(e in CLASS_ESCAPES) && /\w/.test(e)) return null;
|
|
963
981
|
out.push(e in CLASS_ESCAPES ? CLASS_ESCAPES[e] : e.codePointAt(0));
|
|
964
982
|
i += 2;
|
|
965
983
|
continue;
|
|
@@ -1052,6 +1070,8 @@ function createParseContext() {
|
|
|
1052
1070
|
_triviaCaptureMask: void 0,
|
|
1053
1071
|
trackLines: false,
|
|
1054
1072
|
state: void 0,
|
|
1073
|
+
lineView: void 0,
|
|
1074
|
+
_columnsSplit: void 0,
|
|
1055
1075
|
build: void 0,
|
|
1056
1076
|
_errors: void 0,
|
|
1057
1077
|
_tolerant: void 0,
|
|
@@ -1070,6 +1090,7 @@ function createParseContext() {
|
|
|
1070
1090
|
_rootTriviaKindIndex: void 0,
|
|
1071
1091
|
_rootTriviaStrictScopes: void 0,
|
|
1072
1092
|
_rootTriviaCapture: void 0,
|
|
1093
|
+
_gap: void 0,
|
|
1073
1094
|
_cstTriviaLog: void 0,
|
|
1074
1095
|
_fields: void 0,
|
|
1075
1096
|
_cstBuf: void 0,
|
|
@@ -1552,7 +1573,10 @@ function labeledTriviaSpec(arms, minRepeats) {
|
|
|
1552
1573
|
arms,
|
|
1553
1574
|
minRepeats,
|
|
1554
1575
|
visitor: commonLabeledTriviaVisitor({ arms, minRepeats }),
|
|
1555
|
-
charArms: charArmsFor({ arms, minRepeats })
|
|
1576
|
+
charArms: charArmsFor({ arms, minRepeats }),
|
|
1577
|
+
rootKinds: void 0,
|
|
1578
|
+
rootLeaders: [],
|
|
1579
|
+
rootScan: null
|
|
1556
1580
|
};
|
|
1557
1581
|
}
|
|
1558
1582
|
function matchArmAt(input, pos, arm, state) {
|
|
@@ -1773,11 +1797,12 @@ function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
|
1773
1797
|
return result;
|
|
1774
1798
|
}
|
|
1775
1799
|
function saveLookaheadMark(ctx) {
|
|
1776
|
-
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1800
|
+
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null, split: ctx._columnsSplit };
|
|
1777
1801
|
}
|
|
1778
1802
|
function rollbackLookahead(ctx, mark) {
|
|
1779
1803
|
rollbackTrivia(ctx, mark);
|
|
1780
1804
|
if (ctx._probe) ctx._probe.best = mark.probeBest;
|
|
1805
|
+
ctx._columnsSplit = mark.split;
|
|
1781
1806
|
}
|
|
1782
1807
|
function scanWithLabels(input, cur, ctx) {
|
|
1783
1808
|
const triviaP = ctx.trivia;
|
|
@@ -2011,8 +2036,50 @@ function loopScanner(arms) {
|
|
|
2011
2036
|
function regexTriviaScanner(parser2) {
|
|
2012
2037
|
const d = parser2._def.tag === "label" ? parser2._def.parser._def : parser2._def;
|
|
2013
2038
|
if (d.tag !== "regex" || d.flags) return null;
|
|
2014
|
-
|
|
2015
|
-
|
|
2039
|
+
return sourceScanner(d.source);
|
|
2040
|
+
}
|
|
2041
|
+
function sourceScanner(source) {
|
|
2042
|
+
return classRunSource(source) ?? altStarSource(source) ?? prefixRunSource(source) ?? delimitedSource(source) ?? sharedPrefixAltSource(source);
|
|
2043
|
+
}
|
|
2044
|
+
function sharedPrefixAltSource(source) {
|
|
2045
|
+
const m = /^((?:\\.|[^\\[\]()*+?|^$.{}])+)\(\?:(.*)\)$/.exec(source);
|
|
2046
|
+
if (!m) return null;
|
|
2047
|
+
const alts = [];
|
|
2048
|
+
const body = m[2];
|
|
2049
|
+
let depth = 0;
|
|
2050
|
+
let start = 0;
|
|
2051
|
+
for (let i = 0; i < body.length; i++) {
|
|
2052
|
+
const c = body[i];
|
|
2053
|
+
if (c === "\\") {
|
|
2054
|
+
i++;
|
|
2055
|
+
continue;
|
|
2056
|
+
}
|
|
2057
|
+
if (c === "[") {
|
|
2058
|
+
while (i < body.length && body[i] !== "]") i += body[i] === "\\" ? 2 : 1;
|
|
2059
|
+
continue;
|
|
2060
|
+
}
|
|
2061
|
+
if (c === "(") depth++;
|
|
2062
|
+
else if (c === ")" && --depth < 0) return null;
|
|
2063
|
+
else if (c === "|" && depth === 0) {
|
|
2064
|
+
alts.push(body.slice(start, i));
|
|
2065
|
+
start = i + 1;
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
if (depth !== 0 || alts.length === 0) return null;
|
|
2069
|
+
alts.push(body.slice(start));
|
|
2070
|
+
const scanners = [];
|
|
2071
|
+
for (const alt of alts) {
|
|
2072
|
+
const scanner = sourceScanner(m[1] + alt);
|
|
2073
|
+
if (scanner === null) return null;
|
|
2074
|
+
scanners.push(scanner);
|
|
2075
|
+
}
|
|
2076
|
+
return (input, cur) => {
|
|
2077
|
+
for (const scanner of scanners) {
|
|
2078
|
+
const end = scanner(input, cur);
|
|
2079
|
+
if (end > cur) return end;
|
|
2080
|
+
}
|
|
2081
|
+
return cur;
|
|
2082
|
+
};
|
|
2016
2083
|
}
|
|
2017
2084
|
function bmpString(cps) {
|
|
2018
2085
|
if (!cps) return null;
|
|
@@ -2295,6 +2362,9 @@ function parserUsesRouted(parser2, seen = /* @__PURE__ */ new Set()) {
|
|
|
2295
2362
|
return parserUsesRouted(def.sentinel, seen) || def.skip.some((entry) => parserUsesRouted(entry, seen)) || def.recoverAt !== void 0 && parserUsesRouted(def.recoverAt, seen) || def.stopAt !== void 0 && parserUsesRouted(def.stopAt, seen);
|
|
2296
2363
|
case "recover":
|
|
2297
2364
|
return parserUsesRouted(def.parser, seen) || parserUsesRouted(def.sentinel, seen);
|
|
2365
|
+
// The body parses its own input, so only the checks on this one can reuse a routed head.
|
|
2366
|
+
case "lines":
|
|
2367
|
+
return [def.prefix, def.first, def.lazy].some((entry) => entry !== void 0 && parserUsesRouted(entry, seen));
|
|
2298
2368
|
case "lazy":
|
|
2299
2369
|
try {
|
|
2300
2370
|
return parserUsesRouted(def.thunk(), seen);
|
|
@@ -2485,6 +2555,12 @@ function derive(c, seen) {
|
|
|
2485
2555
|
return deriveExpected2(def.parser);
|
|
2486
2556
|
case "expect":
|
|
2487
2557
|
return def.expected;
|
|
2558
|
+
case "lines": {
|
|
2559
|
+
const opening = def.first ?? def.prefix;
|
|
2560
|
+
return matchesEmpty(opening) ? [...deriveExpected2(opening), ...deriveExpected2(def.body)] : deriveExpected2(opening);
|
|
2561
|
+
}
|
|
2562
|
+
case "columns":
|
|
2563
|
+
return [`columns(${def.n})`];
|
|
2488
2564
|
case "node":
|
|
2489
2565
|
case "grammar":
|
|
2490
2566
|
case "trivia":
|
|
@@ -3087,6 +3163,9 @@ function childrenOf2(def) {
|
|
|
3087
3163
|
];
|
|
3088
3164
|
case "routed":
|
|
3089
3165
|
return def.fallback ? [def.fallback] : [];
|
|
3166
|
+
case "lines":
|
|
3167
|
+
return [def.prefix, def.body, ...def.first === void 0 ? [] : [def.first], ...def.lazy === void 0 ? [] : [def.lazy]];
|
|
3168
|
+
case "columns":
|
|
3090
3169
|
case "literal":
|
|
3091
3170
|
case "regex":
|
|
3092
3171
|
case "keywords":
|
|
@@ -3479,7 +3558,11 @@ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActiv
|
|
|
3479
3558
|
case "leaf":
|
|
3480
3559
|
case "scanTo":
|
|
3481
3560
|
case "unknown":
|
|
3561
|
+
case "columns":
|
|
3482
3562
|
return false;
|
|
3563
|
+
// A run's prefixes are probed detached; only its body can capture.
|
|
3564
|
+
case "lines":
|
|
3565
|
+
return mayLeavePartialCapture(d.body, seen, triviaActive);
|
|
3483
3566
|
// node() captures into its own private buffers and rolls them back on
|
|
3484
3567
|
// failure (emitNode restores _ctx.* and never pushes on the !ok path).
|
|
3485
3568
|
case "node":
|
|
@@ -3599,6 +3682,10 @@ function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3599
3682
|
return capturesLeaf(d.parser, seen);
|
|
3600
3683
|
case "scanTo":
|
|
3601
3684
|
return true;
|
|
3685
|
+
case "lines":
|
|
3686
|
+
return capturesLeaf(d.body, seen);
|
|
3687
|
+
case "columns":
|
|
3688
|
+
return true;
|
|
3602
3689
|
case "lazy": {
|
|
3603
3690
|
try {
|
|
3604
3691
|
return capturesLeaf(d.thunk(), seen);
|
|
@@ -3646,6 +3733,8 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3646
3733
|
return hasNodeDef(d.parser, seen) || hasNodeDef(d.separator, seen);
|
|
3647
3734
|
case "scanTo":
|
|
3648
3735
|
return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen)) || d.recoverAt !== void 0 && hasNodeDef(d.recoverAt, seen) || d.stopAt !== void 0 && hasNodeDef(d.stopAt, seen);
|
|
3736
|
+
case "lines":
|
|
3737
|
+
return hasNodeDef(d.body, seen);
|
|
3649
3738
|
case "recover":
|
|
3650
3739
|
return hasNodeDef(d.parser, seen) || hasNodeDef(d.sentinel, seen);
|
|
3651
3740
|
case "expect":
|
|
@@ -3695,6 +3784,8 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3695
3784
|
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.separator, seen);
|
|
3696
3785
|
case "scanTo":
|
|
3697
3786
|
return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen)) || d.recoverAt !== void 0 && hasDirectBuildDef(d.recoverAt, seen) || d.stopAt !== void 0 && hasDirectBuildDef(d.stopAt, seen);
|
|
3787
|
+
case "lines":
|
|
3788
|
+
return hasDirectBuildDef(d.body, seen);
|
|
3698
3789
|
case "recover":
|
|
3699
3790
|
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.sentinel, seen);
|
|
3700
3791
|
case "routed":
|
|
@@ -3740,6 +3831,9 @@ function commitFailureSuccessors(p, resolve2) {
|
|
|
3740
3831
|
...d.recoverAt === void 0 ? NO_EDGES : [d.recoverAt],
|
|
3741
3832
|
...d.stopAt === void 0 ? NO_EDGES : [d.stopAt]
|
|
3742
3833
|
];
|
|
3834
|
+
// A run's prefixes are probed detached; a committed failure reaches it only from its body.
|
|
3835
|
+
case "lines":
|
|
3836
|
+
return [d.body];
|
|
3743
3837
|
case "lazy": {
|
|
3744
3838
|
try {
|
|
3745
3839
|
return [d.thunk()];
|
|
@@ -3945,9 +4039,11 @@ function choice(...args) {
|
|
|
3945
4039
|
for (let i = 0; i < parsers.length; i++) {
|
|
3946
4040
|
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
3947
4041
|
const mark = saveTriviaMark(ctx);
|
|
4042
|
+
const split = ctx._columnsSplit;
|
|
3948
4043
|
const result = parsers[i].parse(input, pos, ctx);
|
|
3949
4044
|
if (!result.ok) {
|
|
3950
4045
|
rollbackTrivia(ctx, mark);
|
|
4046
|
+
ctx._columnsSplit = split;
|
|
3951
4047
|
const at = result.span.start;
|
|
3952
4048
|
if (at > expectedAt) {
|
|
3953
4049
|
expectedAt = at;
|
|
@@ -4147,665 +4243,671 @@ function buildAsciiDispatch(parsers) {
|
|
|
4147
4243
|
return table;
|
|
4148
4244
|
}
|
|
4149
4245
|
|
|
4150
|
-
// src/
|
|
4151
|
-
|
|
4152
|
-
|
|
4246
|
+
// src/combinators/field-trivia.ts
|
|
4247
|
+
var LEAD = { at: -1 };
|
|
4248
|
+
var FIELD_LEADING_TRIVIA = 1;
|
|
4249
|
+
var FIELD_TRAILING_TRIVIA = 2;
|
|
4250
|
+
function triviaFieldCapture(name, value, input, start, end, leadFrom, trailEnd) {
|
|
4251
|
+
return {
|
|
4252
|
+
name,
|
|
4253
|
+
value,
|
|
4254
|
+
span: { start, end },
|
|
4255
|
+
leading: leadFrom >= 0 && leadFrom < start ? input.slice(leadFrom, start) : "",
|
|
4256
|
+
trailing: trailEnd > end ? input.slice(end, trailEnd) : ""
|
|
4257
|
+
};
|
|
4153
4258
|
}
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
`[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.`
|
|
4168
|
-
);
|
|
4259
|
+
function leadsTrivia(p) {
|
|
4260
|
+
return p._def.tag === "field" && p._def.leadingTrivia === true;
|
|
4261
|
+
}
|
|
4262
|
+
|
|
4263
|
+
// src/combinators/repeat.ts
|
|
4264
|
+
function repItem(combinator, input, cur, ctx, guardable, mandatory, rollbackNeeded) {
|
|
4265
|
+
const mark = rollbackNeeded ? saveTriviaMark(ctx) : void 0;
|
|
4266
|
+
let pos = cur;
|
|
4267
|
+
if (ctx.trivia) {
|
|
4268
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
4269
|
+
pos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
4270
|
+
} else {
|
|
4271
|
+
pos = advanceTrivia(input, cur, ctx);
|
|
4169
4272
|
}
|
|
4170
4273
|
}
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
function beginDegradationCapture() {
|
|
4175
|
-
_sinks.push(/* @__PURE__ */ new Map());
|
|
4176
|
-
}
|
|
4177
|
-
function degradationCaptureDepth() {
|
|
4178
|
-
return _sinks.length;
|
|
4179
|
-
}
|
|
4180
|
-
function unwindDegradationCapture(depth) {
|
|
4181
|
-
const found = [];
|
|
4182
|
-
while (_sinks.length > depth) {
|
|
4183
|
-
const sink = _sinks.pop();
|
|
4184
|
-
found.unshift(...sink.values());
|
|
4274
|
+
if (pos >= input.length && !mandatory) {
|
|
4275
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4276
|
+
return "stop";
|
|
4185
4277
|
}
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
const
|
|
4191
|
-
if (
|
|
4192
|
-
|
|
4278
|
+
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
4279
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4280
|
+
return "stop";
|
|
4281
|
+
}
|
|
4282
|
+
const result = combinator.parse(input, pos, ctx);
|
|
4283
|
+
if (!result.ok) {
|
|
4284
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4285
|
+
if (result.committed) return { fail: result, failPos: pos };
|
|
4286
|
+
return { fail: result, failPos: pos };
|
|
4287
|
+
}
|
|
4288
|
+
if (result.span.end === pos && !mandatory) {
|
|
4289
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4290
|
+
return "stop";
|
|
4291
|
+
}
|
|
4292
|
+
return result;
|
|
4193
4293
|
}
|
|
4194
|
-
function
|
|
4195
|
-
|
|
4294
|
+
function resolveBounds(what, opts) {
|
|
4295
|
+
const min = opts.min ?? 0;
|
|
4296
|
+
const max = opts.max ?? Infinity;
|
|
4297
|
+
const bad = (msg) => {
|
|
4298
|
+
throw new RangeError(`parseman: ${what} ${msg}`);
|
|
4299
|
+
};
|
|
4300
|
+
if (!Number.isInteger(min) || min < 0) bad(`min must be a non-negative integer (got ${String(opts.min)})`);
|
|
4301
|
+
if (max !== Infinity && (!Number.isInteger(max) || max < 1)) bad(`max must be a positive integer (got ${String(opts.max)})`);
|
|
4302
|
+
if (max < min) bad(`max (${max}) is less than min (${min}) \u2014 the combinator could never succeed`);
|
|
4303
|
+
return { min, max };
|
|
4196
4304
|
}
|
|
4197
|
-
function
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4305
|
+
function repeatScalarTail(combinator, child, input, cur, ctx, guardable, values, remaining) {
|
|
4306
|
+
while (cur < input.length && remaining > 0) {
|
|
4307
|
+
let itemPos = cur;
|
|
4308
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4309
|
+
if (itemPos >= input.length) break;
|
|
4310
|
+
if (guardable && !startsFirstSet(combinator, input, itemPos)) break;
|
|
4311
|
+
const end = child(input, itemPos, ctx);
|
|
4312
|
+
if (end <= itemPos) break;
|
|
4313
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4314
|
+
cur = end;
|
|
4315
|
+
remaining--;
|
|
4205
4316
|
}
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
if (level === "error") throw new Error(`parseman: degraded compilation path
|
|
4209
|
-
${formatDegradation(d)}`);
|
|
4210
|
-
console.warn(formatDegradation(d));
|
|
4317
|
+
ctx._sv = values;
|
|
4318
|
+
return cur;
|
|
4211
4319
|
}
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
if (
|
|
4320
|
+
function many(combinator, opts = {}) {
|
|
4321
|
+
const { min, max } = resolveBounds("many()", opts);
|
|
4322
|
+
if (min >= 1) return atLeast(combinator, min, max);
|
|
4323
|
+
const meta = {
|
|
4324
|
+
firstSet: combinator._meta.firstSet,
|
|
4325
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
4326
|
+
isTrivia: false
|
|
4215
4327
|
};
|
|
4216
|
-
const
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4328
|
+
const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max } };
|
|
4329
|
+
let expected;
|
|
4330
|
+
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4331
|
+
const scalarChild = scalarOf(combinator);
|
|
4332
|
+
const parseScalar = (input, pos, ctx) => repeatScalarTail(combinator, scalarChild, input, pos, ctx, guardable, def.valueUnused ? void 0 : [], max);
|
|
4333
|
+
return {
|
|
4334
|
+
_tag: "many",
|
|
4335
|
+
_meta: meta,
|
|
4336
|
+
_def: def,
|
|
4337
|
+
_parseScalar: parseScalar,
|
|
4338
|
+
parse(input, pos, ctx) {
|
|
4339
|
+
const values = def.valueUnused ? void 0 : [];
|
|
4340
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4341
|
+
let cur = pos;
|
|
4342
|
+
let count = 0;
|
|
4343
|
+
while (cur < input.length) {
|
|
4344
|
+
if (count >= max) break;
|
|
4345
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4346
|
+
if (item === "stop") break;
|
|
4347
|
+
if ("fail" in item) {
|
|
4348
|
+
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
4349
|
+
const sync = ctx._tolerant ? ctx._sync : void 0;
|
|
4350
|
+
if (sync === void 0) break;
|
|
4351
|
+
if (matchesAt(sync, input, item.failPos, ctx)) break;
|
|
4352
|
+
expected ??= deriveExpected(combinator);
|
|
4353
|
+
const { error, end } = recoverScan(input, item.failPos, ctx, sync, expected);
|
|
4354
|
+
if (values !== void 0) values.push(error);
|
|
4355
|
+
captureError(ctx, error);
|
|
4356
|
+
count++;
|
|
4357
|
+
cur = end;
|
|
4358
|
+
continue;
|
|
4359
|
+
}
|
|
4360
|
+
if (values !== void 0) values.push(item.value);
|
|
4361
|
+
count++;
|
|
4362
|
+
cur = item.span.end;
|
|
4363
|
+
}
|
|
4364
|
+
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4232
4365
|
}
|
|
4233
|
-
for (const l of lines) console.warn(l);
|
|
4234
4366
|
};
|
|
4235
4367
|
}
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
function cstOutputHost(build) {
|
|
4239
|
-
return build?._parsemanCstOutput === true;
|
|
4240
|
-
}
|
|
4241
|
-
var SINGLE_IDENT_ARROW_RE = /^[A-Za-z_$][\w$]*\s*=>/;
|
|
4242
|
-
var PARAM_LIST_OPEN_RE = /^(?:function\b[^(]*)?\(/;
|
|
4243
|
-
var NATIVE_CODE_RE = /\{\s*\[native code\]\s*\}/;
|
|
4244
|
-
var PARAM_HEAD_RE = /^[A-Za-z_$][\w$]*\s*\??\s*/;
|
|
4245
|
-
function confirmedBuildArity(src) {
|
|
4246
|
-
const s = src.trim();
|
|
4247
|
-
if (NATIVE_CODE_RE.test(s)) return null;
|
|
4248
|
-
if (/\barguments\b/.test(s)) return null;
|
|
4249
|
-
if (SINGLE_IDENT_ARROW_RE.test(s)) return 1;
|
|
4250
|
-
const inner = paramListText(s);
|
|
4251
|
-
if (inner === null) return null;
|
|
4252
|
-
if (inner.trim() === "") return 0;
|
|
4253
|
-
const parts = splitTopLevel(inner);
|
|
4254
|
-
if (parts === null) return null;
|
|
4255
|
-
for (const part of parts) {
|
|
4256
|
-
if (!isConfirmableParam(part.trim())) return null;
|
|
4257
|
-
}
|
|
4258
|
-
return parts.length;
|
|
4259
|
-
}
|
|
4260
|
-
function paramListText(s) {
|
|
4261
|
-
const open = PARAM_LIST_OPEN_RE.exec(s);
|
|
4262
|
-
if (!open) return null;
|
|
4263
|
-
const start = open[0].length;
|
|
4264
|
-
const end = matchingParen(s, start);
|
|
4265
|
-
if (end === null) return null;
|
|
4266
|
-
if (!s.startsWith("function") && !/^\s*=>/.test(s.slice(end + 1))) return null;
|
|
4267
|
-
return s.slice(start, end);
|
|
4368
|
+
function oneOrMore(combinator, opts = {}) {
|
|
4369
|
+
return many(combinator, { ...opts, min: opts.min ?? 1 });
|
|
4268
4370
|
}
|
|
4269
|
-
function
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4371
|
+
function atLeast(combinator, min, max) {
|
|
4372
|
+
const meta = {
|
|
4373
|
+
firstSet: combinator._meta.firstSet,
|
|
4374
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
4375
|
+
isTrivia: false
|
|
4376
|
+
};
|
|
4377
|
+
const def = { tag: "oneOrMore", parser: combinator, min, ...max === Infinity ? {} : { max } };
|
|
4378
|
+
let expected;
|
|
4379
|
+
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4380
|
+
const scalarChild = scalarOf(combinator);
|
|
4381
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4382
|
+
let cur = scalarChild(input, pos, ctx);
|
|
4383
|
+
if (cur < 0) return cur;
|
|
4384
|
+
const values = def.valueUnused ? void 0 : [ctx._sv];
|
|
4385
|
+
for (let count = 1; count < min; count++) {
|
|
4386
|
+
let itemPos = cur;
|
|
4387
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4388
|
+
const end = scalarChild(input, itemPos, ctx);
|
|
4389
|
+
if (end < 0) return ~cur;
|
|
4390
|
+
cur = end;
|
|
4391
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4285
4392
|
}
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4393
|
+
return repeatScalarTail(combinator, scalarChild, input, cur, ctx, guardable, values, max - min);
|
|
4394
|
+
};
|
|
4395
|
+
return {
|
|
4396
|
+
_tag: "oneOrMore",
|
|
4397
|
+
_meta: meta,
|
|
4398
|
+
_def: def,
|
|
4399
|
+
_parseScalar: parseScalar,
|
|
4400
|
+
parse(input, pos, ctx) {
|
|
4401
|
+
const first = combinator.parse(input, pos, ctx);
|
|
4402
|
+
if (!first.ok) return first;
|
|
4403
|
+
const values = def.valueUnused ? void 0 : [first.value];
|
|
4404
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4405
|
+
let cur = first.span.end;
|
|
4406
|
+
let count = 1;
|
|
4407
|
+
while (count < min) {
|
|
4408
|
+
const item = repItem(combinator, input, cur, ctx, guardable, true, rollbackNeeded);
|
|
4409
|
+
if (item === "stop" || "fail" in item) {
|
|
4410
|
+
if (item !== "stop" && !item.fail.ok && item.fail.committed) return item.fail;
|
|
4411
|
+
expected ??= deriveExpected(combinator);
|
|
4412
|
+
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: cur, end: cur } };
|
|
4413
|
+
}
|
|
4414
|
+
if (values !== void 0) values.push(item.value);
|
|
4415
|
+
cur = item.span.end;
|
|
4416
|
+
count++;
|
|
4417
|
+
}
|
|
4418
|
+
while (cur < input.length) {
|
|
4419
|
+
if (count >= max) break;
|
|
4420
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4421
|
+
if (item === "stop") break;
|
|
4422
|
+
if ("fail" in item) {
|
|
4423
|
+
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
4424
|
+
const sync = ctx._tolerant ? ctx._sync : void 0;
|
|
4425
|
+
if (sync === void 0) break;
|
|
4426
|
+
if (matchesAt(sync, input, item.failPos, ctx)) break;
|
|
4427
|
+
expected ??= deriveExpected(combinator);
|
|
4428
|
+
const { error, end } = recoverScan(input, item.failPos, ctx, sync, expected);
|
|
4429
|
+
if (values !== void 0) values.push(error);
|
|
4430
|
+
captureError(ctx, error);
|
|
4431
|
+
count++;
|
|
4432
|
+
cur = end;
|
|
4433
|
+
continue;
|
|
4434
|
+
}
|
|
4435
|
+
if (values !== void 0) values.push(item.value);
|
|
4436
|
+
count++;
|
|
4437
|
+
cur = item.span.end;
|
|
4438
|
+
}
|
|
4439
|
+
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4295
4440
|
}
|
|
4296
|
-
|
|
4297
|
-
}
|
|
4298
|
-
return null;
|
|
4441
|
+
};
|
|
4299
4442
|
}
|
|
4300
|
-
function
|
|
4301
|
-
const
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
const close = skipString(inner, i);
|
|
4313
|
-
if (close === null) return null;
|
|
4314
|
-
i = close;
|
|
4315
|
-
continue;
|
|
4443
|
+
function optional(combinator) {
|
|
4444
|
+
const meta = {
|
|
4445
|
+
firstSet: combinator._meta.firstSet,
|
|
4446
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
4447
|
+
isTrivia: false
|
|
4448
|
+
};
|
|
4449
|
+
const firstSetSkippable = !matchesEmpty(combinator);
|
|
4450
|
+
const scalarChild = scalarOf(combinator);
|
|
4451
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4452
|
+
if (firstSetSkippable && !startsFirstSet(combinator, input, pos)) {
|
|
4453
|
+
ctx._sv = null;
|
|
4454
|
+
return pos;
|
|
4316
4455
|
}
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4456
|
+
const end = scalarChild(input, pos, ctx);
|
|
4457
|
+
if (end >= 0) return end;
|
|
4458
|
+
ctx._sv = null;
|
|
4459
|
+
return pos;
|
|
4460
|
+
};
|
|
4461
|
+
return {
|
|
4462
|
+
_tag: "optional",
|
|
4463
|
+
_meta: meta,
|
|
4464
|
+
_def: { tag: "optional", parser: combinator },
|
|
4465
|
+
_parseScalar: parseScalar,
|
|
4466
|
+
parse(input, pos, ctx) {
|
|
4467
|
+
if (firstSetSkippable && ctx._probe === void 0 && !startsFirstSet(combinator, input, pos)) {
|
|
4468
|
+
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
4469
|
+
}
|
|
4470
|
+
const mark = saveTriviaMark(ctx);
|
|
4471
|
+
const result = combinator.parse(input, pos, ctx);
|
|
4472
|
+
if (result.ok) return result;
|
|
4473
|
+
rollbackTrivia(ctx, mark);
|
|
4474
|
+
if (result.committed) return result;
|
|
4475
|
+
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
4326
4476
|
}
|
|
4327
|
-
}
|
|
4328
|
-
if (depth !== 0 || angle !== 0) return null;
|
|
4329
|
-
parts.push(inner.slice(last));
|
|
4330
|
-
return parts;
|
|
4477
|
+
};
|
|
4331
4478
|
}
|
|
4332
|
-
function
|
|
4333
|
-
|
|
4334
|
-
if (!head) return false;
|
|
4335
|
-
const rest = part.slice(head[0].length);
|
|
4336
|
-
if (rest === "") return true;
|
|
4337
|
-
if (rest[0] !== ":") return false;
|
|
4338
|
-
return !hasDefaultAssign(rest.slice(1));
|
|
4479
|
+
function unwrapSeparator(separator) {
|
|
4480
|
+
return "_keepSeparator" in separator ? { sep: separator._keepSeparator, keep: true } : { sep: separator, keep: false };
|
|
4339
4481
|
}
|
|
4340
|
-
function
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4482
|
+
function sepBy(combinator, separatorArg, opts = {}) {
|
|
4483
|
+
const { sep: separator, keep: keepSeparators } = unwrapSeparator(separatorArg);
|
|
4484
|
+
const separatorLeads = leadsTrivia(separator);
|
|
4485
|
+
const { min, max } = resolveBounds("sepBy()", opts);
|
|
4486
|
+
const trailing = opts.trailing ?? "forbid";
|
|
4487
|
+
const meta = {
|
|
4488
|
+
firstSet: combinator._meta.firstSet,
|
|
4489
|
+
canMatchNewline: combinator._meta.canMatchNewline || separator._meta.canMatchNewline,
|
|
4490
|
+
isTrivia: false
|
|
4491
|
+
};
|
|
4492
|
+
let expected;
|
|
4493
|
+
const failAt2 = (at) => {
|
|
4494
|
+
expected ??= deriveExpected(combinator);
|
|
4495
|
+
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: at, end: at } };
|
|
4496
|
+
};
|
|
4497
|
+
const scalarExpected = deriveExpected(combinator);
|
|
4498
|
+
const scalarChild = scalarOf(combinator);
|
|
4499
|
+
const scalarSeparator = scalarOf(separator);
|
|
4500
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4501
|
+
let cur = scalarChild(input, pos, ctx);
|
|
4502
|
+
if (cur < 0) {
|
|
4503
|
+
if (min >= 1) {
|
|
4504
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
4505
|
+
return ~pos;
|
|
4506
|
+
}
|
|
4507
|
+
ctx._sv = [];
|
|
4508
|
+
return pos;
|
|
4346
4509
|
}
|
|
4347
|
-
const
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
"not-a-function": "the binding it names is not a function declaration",
|
|
4361
|
-
"unresolved-import": "its module could not be resolved or parsed",
|
|
4362
|
-
"not-found": "the name did not resolve to any binding",
|
|
4363
|
-
"computed": "it is a computed expression",
|
|
4364
|
-
"foreign-source": "it is named in a module the resolver was never told about, so its offsets index no scope tree the resolver holds",
|
|
4365
|
-
"ambiguous-source": "two distinct registered modules hold byte-identical text, so that text no longer names the module its offsets index"
|
|
4366
|
-
};
|
|
4367
|
-
function unconfirmableReason(def, src) {
|
|
4368
|
-
const declared = def.buildArityUnresolved;
|
|
4369
|
-
if (declared !== void 0 && RESOLVER_REASONS[declared]) return RESOLVER_REASONS[declared];
|
|
4370
|
-
const s = src.trim();
|
|
4371
|
-
const params = s.slice(0, s.indexOf(")") + 1);
|
|
4372
|
-
if (params.includes("...")) return RESOLVER_REASONS["rest-parameter"];
|
|
4373
|
-
if (/\barguments\b/.test(s)) return RESOLVER_REASONS["arguments"];
|
|
4374
|
-
if (/^[A-Za-z_$][\w$]*(\s*\.\s*[A-Za-z_$][\w$]*)?$/.test(s)) {
|
|
4375
|
-
return "it names a binding this build could not resolve to a function declaration";
|
|
4376
|
-
}
|
|
4377
|
-
return "its parameter list could not be parsed";
|
|
4378
|
-
}
|
|
4379
|
-
function confirmedArityForDef(def) {
|
|
4380
|
-
if (def.buildArity !== void 0) return def.buildArity;
|
|
4381
|
-
const src = buildAnalysisSrc(def);
|
|
4382
|
-
const arity = confirmedBuildArity(src);
|
|
4383
|
-
if (arity !== null) return arity;
|
|
4384
|
-
const subject = `build reducer \`${(def.buildSrc ?? "<runtime fn>").trim().split("\n")[0].slice(0, 60)}\``;
|
|
4385
|
-
recordDegradation({
|
|
4386
|
-
code: "build-arity-unconfirmed",
|
|
4387
|
-
severity: "warn",
|
|
4388
|
-
where: `node("${def.type ?? "<inferred>"}")`,
|
|
4389
|
-
subject,
|
|
4390
|
-
fellBackTo: `could not confirm its declared arity \u2014 ${unconfirmableReason(def, src)} \u2014 so this node captures children, fields and raw children, logs trivia, and clones \`_ctx.state\` on every match`,
|
|
4391
|
-
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"
|
|
4392
|
-
});
|
|
4393
|
-
return null;
|
|
4394
|
-
}
|
|
4395
|
-
function buildReadsRaw(def) {
|
|
4396
|
-
if (!def.build) return true;
|
|
4397
|
-
if (def.buildRawUnused === true) return false;
|
|
4398
|
-
const arity = confirmedArityForDef(def);
|
|
4399
|
-
if (arity === null) return true;
|
|
4400
|
-
return arity >= 4;
|
|
4401
|
-
}
|
|
4402
|
-
function buildReadsTrivia(def) {
|
|
4403
|
-
if (!def.build) return true;
|
|
4404
|
-
const arity = confirmedArityForDef(def);
|
|
4405
|
-
if (arity === null) return true;
|
|
4406
|
-
return arity >= 5;
|
|
4407
|
-
}
|
|
4408
|
-
function buildReadsState(def) {
|
|
4409
|
-
if (!def.build) return true;
|
|
4410
|
-
const arity = confirmedArityForDef(def);
|
|
4411
|
-
if (arity === null) return true;
|
|
4412
|
-
return arity >= 6;
|
|
4413
|
-
}
|
|
4414
|
-
|
|
4415
|
-
// src/compiler/fields.ts
|
|
4416
|
-
function buildReadsFields(def) {
|
|
4417
|
-
if (!def.build) return true;
|
|
4418
|
-
const arity = confirmedArityForDef(def);
|
|
4419
|
-
if (arity === null) return true;
|
|
4420
|
-
return arity >= 2;
|
|
4421
|
-
}
|
|
4422
|
-
function parserHasOwnFields(p, seen = /* @__PURE__ */ new Set()) {
|
|
4423
|
-
if (seen.has(p)) return false;
|
|
4424
|
-
seen.add(p);
|
|
4425
|
-
const d = p._def;
|
|
4426
|
-
switch (d.tag) {
|
|
4427
|
-
case "field":
|
|
4428
|
-
return true;
|
|
4429
|
-
case "node":
|
|
4430
|
-
return false;
|
|
4431
|
-
case "lazy": {
|
|
4432
|
-
try {
|
|
4433
|
-
return parserHasOwnFields(d.thunk(), seen);
|
|
4434
|
-
} catch {
|
|
4435
|
-
return false;
|
|
4510
|
+
const values = [ctx._sv];
|
|
4511
|
+
while (values.length < max && (cur < input.length || values.length < min)) {
|
|
4512
|
+
const beforeSeparator = cur;
|
|
4513
|
+
let separatorPos = cur;
|
|
4514
|
+
if (ctx.trivia) separatorPos = advanceTrivia(input, cur, ctx);
|
|
4515
|
+
const separatorEnd = scalarSeparator(input, separatorPos, ctx);
|
|
4516
|
+
if (separatorEnd < 0) break;
|
|
4517
|
+
let itemPos = separatorEnd;
|
|
4518
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, itemPos, ctx);
|
|
4519
|
+
const itemEnd = scalarChild(input, itemPos, ctx);
|
|
4520
|
+
if (itemEnd < 0) {
|
|
4521
|
+
cur = trailing === "allow" ? separatorEnd : beforeSeparator;
|
|
4522
|
+
break;
|
|
4436
4523
|
}
|
|
4524
|
+
values.push(ctx._sv);
|
|
4525
|
+
cur = itemEnd;
|
|
4437
4526
|
}
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
return
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
case "grammar":
|
|
4446
|
-
return parserHasOwnFields(d.parser, seen) || (d.triviaParser ? parserHasOwnFields(d.triviaParser, seen) : false);
|
|
4447
|
-
case "scanTo":
|
|
4448
|
-
return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen)) || d.recoverAt !== void 0 && parserHasOwnFields(d.recoverAt, seen) || d.stopAt !== void 0 && parserHasOwnFields(d.stopAt, seen);
|
|
4449
|
-
case "recover":
|
|
4450
|
-
return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.sentinel, seen);
|
|
4451
|
-
case "routed":
|
|
4452
|
-
return d.fallback ? parserHasOwnFields(d.fallback, seen) : false;
|
|
4453
|
-
case "many":
|
|
4454
|
-
case "oneOrMore":
|
|
4455
|
-
case "optional":
|
|
4456
|
-
case "attempt":
|
|
4457
|
-
case "transform":
|
|
4458
|
-
case "trivia":
|
|
4459
|
-
case "token":
|
|
4460
|
-
case "leaf":
|
|
4461
|
-
case "label":
|
|
4462
|
-
case "expect":
|
|
4463
|
-
case "withCtx":
|
|
4464
|
-
case "not":
|
|
4465
|
-
case "peek":
|
|
4466
|
-
return parserHasOwnFields(d.parser, seen);
|
|
4467
|
-
default:
|
|
4468
|
-
return false;
|
|
4469
|
-
}
|
|
4470
|
-
}
|
|
4471
|
-
function buildFieldMap(captures) {
|
|
4472
|
-
if (!captures?.length) return void 0;
|
|
4473
|
-
const out = {};
|
|
4474
|
-
for (const cap of captures) {
|
|
4475
|
-
const entry = cap.leading === void 0 ? { value: cap.value, span: cap.span } : { value: cap.value, span: cap.span, leading: cap.leading, trailing: cap.trailing };
|
|
4476
|
-
const current = out[cap.name];
|
|
4477
|
-
if (current === void 0) out[cap.name] = entry;
|
|
4478
|
-
else if (Array.isArray(current)) current.push(entry);
|
|
4479
|
-
else out[cap.name] = [current, entry];
|
|
4480
|
-
}
|
|
4481
|
-
return out;
|
|
4482
|
-
}
|
|
4483
|
-
|
|
4484
|
-
// src/combinators/field-trivia.ts
|
|
4485
|
-
var LEAD = { at: -1 };
|
|
4486
|
-
var FIELD_LEADING_TRIVIA = 1;
|
|
4487
|
-
var FIELD_TRAILING_TRIVIA = 2;
|
|
4488
|
-
function triviaFieldCapture(name, value, input, start, end, leadFrom, trailEnd) {
|
|
4527
|
+
if (values.length < min) {
|
|
4528
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
4529
|
+
return ~cur;
|
|
4530
|
+
}
|
|
4531
|
+
ctx._sv = values;
|
|
4532
|
+
return cur;
|
|
4533
|
+
};
|
|
4489
4534
|
return {
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4535
|
+
_tag: "sepBy",
|
|
4536
|
+
_meta: meta,
|
|
4537
|
+
_def: {
|
|
4538
|
+
tag: "sepBy",
|
|
4539
|
+
parser: combinator,
|
|
4540
|
+
separator,
|
|
4541
|
+
min,
|
|
4542
|
+
...max === Infinity ? {} : { max },
|
|
4543
|
+
...trailing === "forbid" ? {} : { trailing },
|
|
4544
|
+
// Carried into the IR so the COMPILED engine demotes exactly where the
|
|
4545
|
+
// interpreter does. The two engines have drifted three separate ways across
|
|
4546
|
+
// this option surface already; parity is held by test/parity, not by hope.
|
|
4547
|
+
...keepSeparators ? { keepSeparators: true } : {}
|
|
4548
|
+
},
|
|
4549
|
+
_parseScalar: keepSeparators || separatorLeads ? void 0 : parseScalar,
|
|
4550
|
+
parse(input, pos, ctx) {
|
|
4551
|
+
const first = combinator.parse(input, pos, ctx);
|
|
4552
|
+
const values = [];
|
|
4553
|
+
let cur;
|
|
4554
|
+
if (first.ok) {
|
|
4555
|
+
values.push(first.value);
|
|
4556
|
+
cur = first.span.end;
|
|
4557
|
+
} else {
|
|
4558
|
+
if (first.committed) return first;
|
|
4559
|
+
const term = ctx._tolerant ? ctx._sync : void 0;
|
|
4560
|
+
if (term === void 0 || matchesAt(term, input, pos, ctx)) {
|
|
4561
|
+
if (min >= 1) return failAt2(pos);
|
|
4562
|
+
return { ok: true, value: [], span: { start: pos, end: pos } };
|
|
4563
|
+
}
|
|
4564
|
+
expected ??= deriveExpected(combinator);
|
|
4565
|
+
const rec = recoverScan(input, pos, ctx, orSentinel(separator, term), expected);
|
|
4566
|
+
values.push(rec.error);
|
|
4567
|
+
captureError(ctx, rec.error);
|
|
4568
|
+
cur = rec.end;
|
|
4569
|
+
}
|
|
4570
|
+
while (cur < input.length || values.length < min) {
|
|
4571
|
+
if (values.length >= max) break;
|
|
4572
|
+
const loopMark = saveTriviaMark(ctx);
|
|
4573
|
+
let sepPos = cur;
|
|
4574
|
+
if (ctx.trivia) {
|
|
4575
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
4576
|
+
sepPos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
4577
|
+
} else {
|
|
4578
|
+
sepPos = advanceTrivia(input, cur, ctx);
|
|
4579
|
+
}
|
|
4580
|
+
}
|
|
4581
|
+
if (separatorLeads) LEAD.at = cur;
|
|
4582
|
+
const sep = separator.parse(input, sepPos, ctx);
|
|
4583
|
+
if (!sep.ok) {
|
|
4584
|
+
rollbackTrivia(ctx, loopMark);
|
|
4585
|
+
if (sep.committed) return sep;
|
|
4586
|
+
break;
|
|
4587
|
+
}
|
|
4588
|
+
if (!keepSeparators) demoteCapturedToRaw(ctx, loopMark.leaves);
|
|
4589
|
+
const sepMark = trailing === "forbid" ? void 0 : saveTriviaMark(ctx);
|
|
4590
|
+
let nextPos = sep.span.end;
|
|
4591
|
+
if (ctx.trivia) {
|
|
4592
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
4593
|
+
nextPos = commitTriviaScan(scanTriviaCompact(input, sep.span.end, ctx));
|
|
4594
|
+
} else {
|
|
4595
|
+
nextPos = advanceTrivia(input, sep.span.end, ctx);
|
|
4596
|
+
}
|
|
4597
|
+
}
|
|
4598
|
+
const next = combinator.parse(input, nextPos, ctx);
|
|
4599
|
+
if (!next.ok) {
|
|
4600
|
+
if (next.committed) return next;
|
|
4601
|
+
const term = ctx._tolerant ? ctx._sync : void 0;
|
|
4602
|
+
if (term !== void 0 && !matchesAt(term, input, nextPos, ctx)) {
|
|
4603
|
+
expected ??= deriveExpected(combinator);
|
|
4604
|
+
const rec = recoverScan(input, nextPos, ctx, orSentinel(separator, term), expected);
|
|
4605
|
+
values.push(rec.error);
|
|
4606
|
+
captureError(ctx, rec.error);
|
|
4607
|
+
cur = rec.end;
|
|
4608
|
+
continue;
|
|
4609
|
+
}
|
|
4610
|
+
if (sepMark !== void 0) {
|
|
4611
|
+
rollbackTrivia(ctx, sepMark);
|
|
4612
|
+
cur = sep.span.end;
|
|
4613
|
+
break;
|
|
4614
|
+
}
|
|
4615
|
+
rollbackTrivia(ctx, loopMark);
|
|
4616
|
+
break;
|
|
4617
|
+
}
|
|
4618
|
+
values.push(next.value);
|
|
4619
|
+
cur = next.span.end;
|
|
4620
|
+
}
|
|
4621
|
+
if (values.length < min) return failAt2(cur);
|
|
4622
|
+
return { ok: true, value: values, span: { start: pos, end: cur } };
|
|
4623
|
+
}
|
|
4495
4624
|
};
|
|
4496
4625
|
}
|
|
4497
|
-
function leadsTrivia(p) {
|
|
4498
|
-
return p._def.tag === "field" && p._def.leadingTrivia === true;
|
|
4499
|
-
}
|
|
4500
|
-
|
|
4501
|
-
// src/table/ops.ts
|
|
4502
|
-
var OP_LIT = 1;
|
|
4503
|
-
var OP_RX = 2;
|
|
4504
|
-
var OP_SEQ = 3;
|
|
4505
|
-
var OP_SEQV = 4;
|
|
4506
|
-
var OP_CHOICE = 5;
|
|
4507
|
-
var OP_REP = 6;
|
|
4508
|
-
var OP_REPV = 7;
|
|
4509
|
-
var OP_OPT = 8;
|
|
4510
|
-
var OP_XFORM = 9;
|
|
4511
|
-
var OP_NODE = 10;
|
|
4512
|
-
var OP_RULE = 11;
|
|
4513
|
-
var OP_GATE = 12;
|
|
4514
|
-
var OP_NOT = 13;
|
|
4515
|
-
var OP_PEEK = 14;
|
|
4516
|
-
var OP_LEAF = 15;
|
|
4517
|
-
var OP_EMPTY = 16;
|
|
4518
|
-
var OP_LIT_TRACK = 17;
|
|
4519
|
-
var OP_RX_TRACK = 18;
|
|
4520
|
-
var OP_NODE_TRACK = 19;
|
|
4521
|
-
var OP_SCOPE = 20;
|
|
4522
|
-
var OP_EXPECT = 21;
|
|
4523
|
-
var OP_SEQX = 22;
|
|
4524
|
-
var OP_SCAN = 23;
|
|
4525
|
-
var OP_FIELD = 24;
|
|
4526
|
-
var OP_LIT_CI = 27;
|
|
4527
|
-
var OP_LIT_CI_TRACK = 28;
|
|
4528
|
-
var OP_TOKEN = 29;
|
|
4529
|
-
var OP_SCOPE_CAP = 30;
|
|
4530
|
-
var OP_WITHCTX = 31;
|
|
4531
|
-
var OP_GUARD = 32;
|
|
4532
|
-
var OP_ADJ = 33;
|
|
4533
|
-
var OP_GREEDY = 34;
|
|
4534
|
-
var OP_REJECT = 35;
|
|
4535
|
-
var OP_ARMGATE = 36;
|
|
4536
|
-
var OP_LIVE = 37;
|
|
4537
|
-
var OP_ATTEMPT = 38;
|
|
4538
|
-
var OP_LABEL = 39;
|
|
4539
|
-
var OP_COV = 40;
|
|
4540
|
-
var OP_SCOPE_PLAIN = 41;
|
|
4541
|
-
var OP_LEX_BODY = 42;
|
|
4542
|
-
var OP_LEX_PROGRAM = 43;
|
|
4543
|
-
var OP_SOURCE_LEAF = 44;
|
|
4544
|
-
var OP_DISPATCH = 25;
|
|
4545
|
-
var OP_ROUTED = 26;
|
|
4546
|
-
var OP_NAMES = {
|
|
4547
|
-
[OP_LIT]: "LIT",
|
|
4548
|
-
[OP_RX]: "RX",
|
|
4549
|
-
[OP_SEQ]: "SEQ",
|
|
4550
|
-
[OP_SEQV]: "SEQV",
|
|
4551
|
-
[OP_CHOICE]: "CHOICE",
|
|
4552
|
-
[OP_REP]: "REP",
|
|
4553
|
-
[OP_REPV]: "REPV",
|
|
4554
|
-
[OP_OPT]: "OPT",
|
|
4555
|
-
[OP_XFORM]: "XFORM",
|
|
4556
|
-
[OP_NODE]: "NODE",
|
|
4557
|
-
[OP_RULE]: "RULE",
|
|
4558
|
-
[OP_GATE]: "GATE",
|
|
4559
|
-
[OP_NOT]: "NOT",
|
|
4560
|
-
[OP_PEEK]: "PEEK",
|
|
4561
|
-
[OP_LEAF]: "LEAF",
|
|
4562
|
-
[OP_SOURCE_LEAF]: "SOURCE_LEAF",
|
|
4563
|
-
[OP_EMPTY]: "EMPTY",
|
|
4564
|
-
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
4565
|
-
[OP_RX_TRACK]: "RX_TRACK",
|
|
4566
|
-
[OP_NODE_TRACK]: "NODE_TRACK",
|
|
4567
|
-
[OP_SCOPE]: "SCOPE",
|
|
4568
|
-
[OP_EXPECT]: "EXPECT",
|
|
4569
|
-
[OP_SEQX]: "SEQX",
|
|
4570
|
-
[OP_SCAN]: "SCAN",
|
|
4571
|
-
[OP_FIELD]: "FIELD",
|
|
4572
|
-
[OP_LIT_CI]: "LIT_CI",
|
|
4573
|
-
[OP_LIT_CI_TRACK]: "LIT_CI_TRACK",
|
|
4574
|
-
[OP_DISPATCH]: "DISPATCH",
|
|
4575
|
-
[OP_ROUTED]: "ROUTED",
|
|
4576
|
-
[OP_TOKEN]: "TOKEN",
|
|
4577
|
-
[OP_SCOPE_CAP]: "SCOPE_CAP",
|
|
4578
|
-
[OP_WITHCTX]: "WITHCTX",
|
|
4579
|
-
[OP_GUARD]: "GUARD",
|
|
4580
|
-
[OP_ADJ]: "ADJ",
|
|
4581
|
-
[OP_GREEDY]: "GREEDY",
|
|
4582
|
-
[OP_REJECT]: "REJECT",
|
|
4583
|
-
[OP_ARMGATE]: "ARMGATE",
|
|
4584
|
-
[OP_LIVE]: "LIVE",
|
|
4585
|
-
[OP_ATTEMPT]: "ATTEMPT",
|
|
4586
|
-
[OP_LABEL]: "LABEL",
|
|
4587
|
-
[OP_COV]: "COV",
|
|
4588
|
-
[OP_SCOPE_PLAIN]: "SCOPE_PLAIN",
|
|
4589
|
-
[OP_LEX_BODY]: "LEX_BODY",
|
|
4590
|
-
[OP_LEX_PROGRAM]: "LEX_PROGRAM"
|
|
4591
|
-
};
|
|
4592
4626
|
|
|
4593
|
-
// src/combinators/
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4627
|
+
// src/combinators/map.ts
|
|
4628
|
+
var JSON_STRING_BODY = String.raw`(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*`;
|
|
4629
|
+
function transform(combinator, fn) {
|
|
4630
|
+
const observesSpan = fn.length > 1;
|
|
4631
|
+
const sequenceDef = combinator._def.tag === "sequence" ? combinator._def : void 0;
|
|
4632
|
+
const terms = sequenceDef?.parsers;
|
|
4633
|
+
const inner = terms?.[1];
|
|
4634
|
+
const fused = terms?.length === 3 && terms[0]._def.tag === "literal" && terms[0]._def.value === '"' && !terms[0]._def.caseInsensitive && inner._def.tag === "regex" && inner._def.source === JSON_STRING_BODY && inner._def.flags === "" && terms[2]._def.tag === "literal" && terms[2]._def.value === '"' && !terms[2]._def.caseInsensitive && inner._stickyRegex !== void 0;
|
|
4635
|
+
const child = scalarOf(combinator);
|
|
4636
|
+
const parseScalar = fused ? (() => {
|
|
4637
|
+
const body = inner._stickyRegex;
|
|
4638
|
+
const tuple = ['"', "", '"'];
|
|
4639
|
+
const expected = [JSON.stringify('"')];
|
|
4640
|
+
return (input, pos, ctx) => {
|
|
4641
|
+
if (ctx.trivia !== void 0) {
|
|
4642
|
+
const end2 = child(input, pos, ctx);
|
|
4643
|
+
if (end2 < 0) return end2;
|
|
4644
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end: end2 }) : fn(ctx._sv);
|
|
4645
|
+
return end2;
|
|
4646
|
+
}
|
|
4647
|
+
if (input.charCodeAt(pos) !== 34) {
|
|
4648
|
+
ctx._fx = expected;
|
|
4649
|
+
return ~pos;
|
|
4650
|
+
}
|
|
4651
|
+
body.lastIndex = pos + 1;
|
|
4652
|
+
const match = body.exec(input);
|
|
4653
|
+
const close = pos + 1 + match[0].length;
|
|
4654
|
+
if (input.charCodeAt(close) !== 34) {
|
|
4655
|
+
ctx._fx = expected;
|
|
4656
|
+
return ~close;
|
|
4657
|
+
}
|
|
4658
|
+
tuple[1] = match[0];
|
|
4659
|
+
const end = close + 1;
|
|
4660
|
+
ctx._sv = observesSpan ? fn(tuple, { start: pos, end }) : fn(tuple);
|
|
4661
|
+
return end;
|
|
4662
|
+
};
|
|
4663
|
+
})() : /* @__PURE__ */ (() => {
|
|
4664
|
+
return (input, pos, ctx) => {
|
|
4665
|
+
const end = child(input, pos, ctx);
|
|
4666
|
+
if (end < 0) return end;
|
|
4667
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end }) : fn(ctx._sv);
|
|
4668
|
+
return end;
|
|
4669
|
+
};
|
|
4670
|
+
})();
|
|
4671
|
+
return {
|
|
4672
|
+
_tag: "transform",
|
|
4673
|
+
_meta: combinator._meta,
|
|
4674
|
+
_def: { tag: "transform", parser: combinator, fn },
|
|
4675
|
+
_parseScalar: parseScalar,
|
|
4676
|
+
parse(input, pos, ctx) {
|
|
4677
|
+
const result = combinator.parse(input, pos, ctx);
|
|
4678
|
+
if (!result.ok) return result;
|
|
4679
|
+
return { ok: true, value: fn(result.value, result.span), span: result.span };
|
|
4680
|
+
}
|
|
4681
|
+
};
|
|
4612
4682
|
}
|
|
4613
|
-
function
|
|
4614
|
-
|
|
4683
|
+
function trivia(combinator) {
|
|
4684
|
+
const labeled = analyzeLabeledTrivia(combinator);
|
|
4685
|
+
const kindLabels = labeled?.labels;
|
|
4686
|
+
return {
|
|
4687
|
+
_tag: combinator._tag,
|
|
4688
|
+
_meta: {
|
|
4689
|
+
...combinator._meta,
|
|
4690
|
+
isTrivia: true,
|
|
4691
|
+
triviaScanner: fastTriviaScanner(combinator),
|
|
4692
|
+
// Every labeled scan of this trivia reads its spec; the module's four-slot
|
|
4693
|
+
// memo alone thrashes on a grammar with more than four trivia tables.
|
|
4694
|
+
labeledTriviaSpec: labeled,
|
|
4695
|
+
...kindLabels ? { triviaKindLabels: kindLabels } : {}
|
|
4696
|
+
},
|
|
4697
|
+
_def: { tag: "trivia", parser: combinator },
|
|
4698
|
+
_parseScalar: scalarOf(combinator),
|
|
4699
|
+
parse: combinator.parse.bind(combinator)
|
|
4700
|
+
};
|
|
4615
4701
|
}
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4702
|
+
function classifiedTrivia(arms) {
|
|
4703
|
+
const entries = Object.entries(arms);
|
|
4704
|
+
if (entries.length === 0) {
|
|
4705
|
+
throw new TypeError("classifiedTrivia() requires at least one named trivia arm.");
|
|
4706
|
+
}
|
|
4707
|
+
for (let i = 0; i < entries.length; i++) {
|
|
4708
|
+
const [name, arm] = entries[i];
|
|
4709
|
+
const first = arm._meta.firstSet;
|
|
4710
|
+
if (matchesEmpty(arm) || first.kind !== "ranges" || first.ranges.length === 0) {
|
|
4711
|
+
throw new TypeError(
|
|
4712
|
+
`classifiedTrivia(): ${JSON.stringify(name)} must be non-nullable with a concrete finite first set.`
|
|
4713
|
+
);
|
|
4714
|
+
}
|
|
4715
|
+
}
|
|
4716
|
+
const labeledArms = entries.map(([name, arm]) => label(name, arm));
|
|
4717
|
+
const result = trivia(oneOrMore(choice(...labeledArms)));
|
|
4718
|
+
result._meta.rootTriviaClassified = true;
|
|
4719
|
+
return result;
|
|
4619
4720
|
}
|
|
4620
|
-
function
|
|
4621
|
-
const meta = {
|
|
4622
|
-
// Zero-width and never leading (sequence() rejects index 0), so it contributes
|
|
4623
|
-
// no first char. `isZeroWidthAssertion` drops it from a sequence's first-set
|
|
4624
|
-
// rather than letting `any` poison the enclosing choice's dispatch.
|
|
4625
|
-
firstSet: { kind: "any" },
|
|
4626
|
-
canMatchNewline: false,
|
|
4627
|
-
isTrivia: false
|
|
4628
|
-
};
|
|
4721
|
+
function label(name, combinator) {
|
|
4629
4722
|
return {
|
|
4630
|
-
_tag:
|
|
4631
|
-
_meta:
|
|
4632
|
-
_def:
|
|
4633
|
-
parse() {
|
|
4634
|
-
|
|
4723
|
+
_tag: combinator._tag,
|
|
4724
|
+
_meta: combinator._meta,
|
|
4725
|
+
_def: { tag: "label", label: name, parser: combinator },
|
|
4726
|
+
parse(input, pos, ctx) {
|
|
4727
|
+
const result = combinator.parse(input, pos, ctx);
|
|
4728
|
+
if (!result.ok) return { ok: false, expected: [name], span: result.span };
|
|
4729
|
+
return result;
|
|
4635
4730
|
}
|
|
4636
4731
|
};
|
|
4637
4732
|
}
|
|
4638
|
-
function
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4733
|
+
function field(name, combinator, opts) {
|
|
4734
|
+
const leadingTrivia = opts?.leadingTrivia === true;
|
|
4735
|
+
const trailingTrivia = opts?.trailingTrivia === true;
|
|
4736
|
+
if (!leadingTrivia && !trailingTrivia) {
|
|
4737
|
+
return {
|
|
4738
|
+
_tag: combinator._tag,
|
|
4739
|
+
_meta: combinator._meta,
|
|
4740
|
+
_def: { tag: "field", name, parser: combinator },
|
|
4741
|
+
parse(input, pos, ctx) {
|
|
4742
|
+
const result = combinator.parse(input, pos, ctx);
|
|
4743
|
+
if (!result.ok) return result;
|
|
4744
|
+
ctx._fields?.push({ name, value: result.value, span: result.span });
|
|
4745
|
+
return result;
|
|
4650
4746
|
}
|
|
4651
|
-
}
|
|
4747
|
+
};
|
|
4652
4748
|
}
|
|
4653
|
-
return
|
|
4654
|
-
|
|
4655
|
-
|
|
4749
|
+
return {
|
|
4750
|
+
_tag: combinator._tag,
|
|
4751
|
+
_meta: combinator._meta,
|
|
4752
|
+
_def: {
|
|
4753
|
+
tag: "field",
|
|
4754
|
+
name,
|
|
4755
|
+
parser: combinator,
|
|
4756
|
+
...leadingTrivia ? { leadingTrivia: true } : {},
|
|
4757
|
+
...trailingTrivia ? { trailingTrivia: true } : {}
|
|
4758
|
+
},
|
|
4759
|
+
parse(input, pos, ctx) {
|
|
4760
|
+
const leadFrom = LEAD.at;
|
|
4761
|
+
LEAD.at = -1;
|
|
4762
|
+
const result = combinator.parse(input, pos, ctx);
|
|
4763
|
+
if (!result.ok) return result;
|
|
4764
|
+
const end = result.span.end;
|
|
4765
|
+
const trailEnd = trailingTrivia && ctx.trivia ? consumeTrivia(input, end, ctx) : end;
|
|
4766
|
+
ctx._fields?.push(triviaFieldCapture(name, result.value, input, result.span.start, end, leadingTrivia ? leadFrom : -1, trailEnd));
|
|
4767
|
+
return trailEnd === end ? result : { ok: true, value: result.value, span: { start: result.span.start, end: trailEnd } };
|
|
4768
|
+
}
|
|
4769
|
+
};
|
|
4656
4770
|
}
|
|
4657
4771
|
|
|
4658
|
-
// src/combinators/
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
}
|
|
4665
|
-
function missingInferredType() {
|
|
4666
|
-
throw new Error('node(): inferred node type requires a rules() key; pass node("Type", parser) outside rules()');
|
|
4667
|
-
}
|
|
4668
|
-
function normalizeBuildArity(arity) {
|
|
4669
|
-
if (arity === void 0) return void 0;
|
|
4670
|
-
if (!Number.isInteger(arity) || arity < 0 || arity > 6) {
|
|
4671
|
-
throw new Error("node() buildArity must be an integer 0..6 (children, fields, span, rawChildren, triviaLog, state)");
|
|
4772
|
+
// src/combinators/regex.ts
|
|
4773
|
+
var SCAN_BAIL_AT = 64;
|
|
4774
|
+
function inRanges3(cp, ranges) {
|
|
4775
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
4776
|
+
const [lo, hi] = ranges[i];
|
|
4777
|
+
if (cp >= lo && cp <= hi) return true;
|
|
4672
4778
|
}
|
|
4673
|
-
return
|
|
4779
|
+
return false;
|
|
4674
4780
|
}
|
|
4675
|
-
function
|
|
4676
|
-
if (
|
|
4677
|
-
|
|
4678
|
-
throw new Error("node() project child must be a non-negative integer");
|
|
4679
|
-
}
|
|
4680
|
-
return project;
|
|
4781
|
+
function readClassRanges(body) {
|
|
4782
|
+
if (body.startsWith("^")) return null;
|
|
4783
|
+
return parseClassRanges(body);
|
|
4681
4784
|
}
|
|
4682
|
-
function
|
|
4683
|
-
if (
|
|
4684
|
-
|
|
4785
|
+
function shortScanner(source, flags) {
|
|
4786
|
+
if (/[imsuvy]/.test(flags)) return null;
|
|
4787
|
+
let ranges = null;
|
|
4788
|
+
let quant = "";
|
|
4789
|
+
if (source[0] === "[") {
|
|
4790
|
+
let end = 1;
|
|
4791
|
+
while (end < source.length && source[end] !== "]") {
|
|
4792
|
+
if (source[end] === "\\") end += 2;
|
|
4793
|
+
else end++;
|
|
4794
|
+
}
|
|
4795
|
+
if (source[end] !== "]") return null;
|
|
4796
|
+
ranges = readClassRanges(source.slice(1, end));
|
|
4797
|
+
quant = source.slice(end + 1);
|
|
4798
|
+
} else if (source[0] === "\\" && (source[1] === "d" || source[1] === "w" || source[1] === "s")) {
|
|
4799
|
+
ranges = shorthandRanges(source[1]);
|
|
4800
|
+
quant = source.slice(2);
|
|
4685
4801
|
}
|
|
4686
|
-
|
|
4802
|
+
if (!ranges || quant !== "+" && quant !== "*") return null;
|
|
4803
|
+
const minOne = quant === "+";
|
|
4804
|
+
return (input, pos) => {
|
|
4805
|
+
let end = pos;
|
|
4806
|
+
while (end < input.length && inRanges3(input.charCodeAt(end), ranges)) {
|
|
4807
|
+
end++;
|
|
4808
|
+
if (end - pos >= SCAN_BAIL_AT) return void 0;
|
|
4809
|
+
}
|
|
4810
|
+
return minOne && end === pos ? null : end;
|
|
4811
|
+
};
|
|
4687
4812
|
}
|
|
4688
|
-
function
|
|
4689
|
-
|
|
4690
|
-
const
|
|
4691
|
-
const
|
|
4692
|
-
|
|
4693
|
-
const build = typeof buildArg === "function" ? buildArg : void 0;
|
|
4694
|
-
const opts = typeof buildArg === "function" ? maybeOpts : buildArg ?? maybeOpts;
|
|
4695
|
-
const project = normalizeProject(opts?.project);
|
|
4696
|
-
if (project !== void 0 && build !== void 0) {
|
|
4697
|
-
throw new Error("node() options cannot combine project with a build callback");
|
|
4698
|
-
}
|
|
4699
|
-
const baseDef = { tag: "node", parser: combinator, ...type === void 0 ? {} : { type }, ...build === void 0 ? {} : { build } };
|
|
4700
|
-
const meta = {
|
|
4701
|
-
firstSet: combinator._meta.firstSet,
|
|
4702
|
-
canMatchNewline: combinator._meta.canMatchNewline,
|
|
4703
|
-
isTrivia: false
|
|
4813
|
+
function asciiCaseFold(fs) {
|
|
4814
|
+
if (fs.kind !== "ranges") return fs;
|
|
4815
|
+
const ranges = fs.ranges.map((r) => ({ lo: r.lo, hi: r.hi }));
|
|
4816
|
+
const add = (lo, hi) => {
|
|
4817
|
+
if (lo <= hi) ranges.push({ lo, hi });
|
|
4704
4818
|
};
|
|
4705
|
-
const
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
const buildArity = normalizeBuildArity(opts?.buildArity);
|
|
4711
|
-
if (unwrap && collapse) {
|
|
4712
|
-
throw new Error("node() options cannot set both unwrap and collapse");
|
|
4819
|
+
for (const r of fs.ranges) {
|
|
4820
|
+
const uLo = Math.max(r.lo, 65), uHi = Math.min(r.hi, 90);
|
|
4821
|
+
add(uLo + 32, uHi + 32);
|
|
4822
|
+
const lLo = Math.max(r.lo, 97), lHi = Math.min(r.hi, 122);
|
|
4823
|
+
add(lLo - 32, lHi - 32);
|
|
4713
4824
|
}
|
|
4714
|
-
|
|
4715
|
-
|
|
4825
|
+
ranges.sort((a, b) => a.lo - b.lo);
|
|
4826
|
+
const merged = [];
|
|
4827
|
+
for (const r of ranges) {
|
|
4828
|
+
const last = merged[merged.length - 1];
|
|
4829
|
+
if (last && r.lo <= last.hi + 1) last.hi = Math.max(last.hi, r.hi);
|
|
4830
|
+
else merged.push({ lo: r.lo, hi: r.hi });
|
|
4716
4831
|
}
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
const
|
|
4721
|
-
const
|
|
4722
|
-
const
|
|
4723
|
-
|
|
4832
|
+
return { kind: "ranges", ranges: merged };
|
|
4833
|
+
}
|
|
4834
|
+
function regex(pattern, flags = "") {
|
|
4835
|
+
const source = typeof pattern === "string" ? pattern : pattern.source;
|
|
4836
|
+
const resolvedFlags = typeof pattern === "string" ? flags : pattern.flags;
|
|
4837
|
+
const anchored = new RegExp(source, "y" + resolvedFlags.replace(/[gy]/g, ""));
|
|
4838
|
+
const scan = shortScanner(source, resolvedFlags);
|
|
4839
|
+
const raw = firstSetFromRegex(source);
|
|
4840
|
+
const firstSet2 = !resolvedFlags.includes("i") ? raw.firstSet : resolvedFlags.includes("u") || resolvedFlags.includes("v") ? any() : asciiCaseFold(raw.firstSet);
|
|
4841
|
+
const canMatchNewline = raw.canMatchNewline;
|
|
4842
|
+
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
4843
|
+
const def = { tag: "regex", source, flags: resolvedFlags };
|
|
4844
|
+
const expected = directTerminalFailureExpected(def);
|
|
4845
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4846
|
+
const scanEnd = scan?.(input, pos);
|
|
4847
|
+
if (scanEnd !== void 0) {
|
|
4848
|
+
if (scanEnd === null) {
|
|
4849
|
+
ctx._fx = expected;
|
|
4850
|
+
return ~pos;
|
|
4851
|
+
}
|
|
4852
|
+
ctx._sv = input.slice(pos, scanEnd);
|
|
4853
|
+
return scanEnd;
|
|
4854
|
+
}
|
|
4855
|
+
anchored.lastIndex = pos;
|
|
4856
|
+
const match = anchored.exec(input);
|
|
4857
|
+
if (match === null) {
|
|
4858
|
+
ctx._fx = expected;
|
|
4859
|
+
return ~pos;
|
|
4860
|
+
}
|
|
4861
|
+
ctx._sv = match[0];
|
|
4862
|
+
return pos + match[0].length;
|
|
4863
|
+
};
|
|
4724
4864
|
return {
|
|
4725
|
-
_tag: "
|
|
4865
|
+
_tag: "regex",
|
|
4726
4866
|
_meta: meta,
|
|
4727
4867
|
_def: def,
|
|
4868
|
+
_stickyRegex: anchored,
|
|
4869
|
+
_parseScalar: parseScalar,
|
|
4728
4870
|
parse(input, pos, ctx) {
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
}
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
const
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
const
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
ctx._fields = savedFields;
|
|
4757
|
-
ctx._triviaCaptureMask = savedMask;
|
|
4758
|
-
const { children: children2, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
|
|
4759
|
-
if (!r.ok) return r;
|
|
4760
|
-
const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
4761
|
-
const nodeType = def.type ?? missingInferredType();
|
|
4762
|
-
const cstOutput = cstOutputHost(ctx.build);
|
|
4763
|
-
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
4764
|
-
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
4765
|
-
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : (cstOutput || !build && project === void 0) && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
4766
|
-
const rawEntry2 = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
|
|
4767
|
-
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
4768
|
-
pushCstChild(ctx, built, rawEntry2);
|
|
4769
|
-
}
|
|
4770
|
-
return { ok: true, value: built, span };
|
|
4771
|
-
}
|
|
4772
|
-
};
|
|
4773
|
-
}
|
|
4774
|
-
|
|
4775
|
-
// src/combinators/trivia-boundary.ts
|
|
4776
|
-
var MAX_DEPTH = 12;
|
|
4777
|
-
function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
4778
|
-
if (depth === 0) return true;
|
|
4779
|
-
const d = p._def;
|
|
4780
|
-
switch (d.tag) {
|
|
4781
|
-
// Multi-term forms: the gaps BETWEEN terms are the ambient-trivia positions.
|
|
4782
|
-
case "sequence":
|
|
4783
|
-
return d.parsers.length > 1;
|
|
4784
|
-
case "many":
|
|
4785
|
-
case "oneOrMore":
|
|
4786
|
-
case "sepBy":
|
|
4787
|
-
return true;
|
|
4788
|
-
// Transparent wrappers — they add no position, so ask what they wrap.
|
|
4789
|
-
case "node":
|
|
4790
|
-
case "transform":
|
|
4791
|
-
case "leaf":
|
|
4792
|
-
case "label":
|
|
4793
|
-
case "field":
|
|
4794
|
-
case "token":
|
|
4795
|
-
case "attempt":
|
|
4796
|
-
case "optional":
|
|
4797
|
-
case "expect":
|
|
4798
|
-
case "withCtx":
|
|
4799
|
-
case "recover":
|
|
4800
|
-
case "trivia":
|
|
4801
|
-
return hasOwnTriviaBoundary(d.parser, depth - 1);
|
|
4802
|
-
// An alternation adds no position either, but ONE arm that has one is enough
|
|
4803
|
-
// to make the scope meaningful for this rule.
|
|
4804
|
-
case "choice":
|
|
4805
|
-
return d.parsers.some((a) => hasOwnTriviaBoundary(a, depth - 1));
|
|
4806
|
-
default:
|
|
4807
|
-
return false;
|
|
4871
|
+
const scanEnd = scan?.(input, pos);
|
|
4872
|
+
if (scanEnd !== void 0) {
|
|
4873
|
+
if (scanEnd === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
4874
|
+
const value = input.slice(pos, scanEnd);
|
|
4875
|
+
const span2 = { start: pos, end: scanEnd };
|
|
4876
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, scanEnd);
|
|
4877
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
4878
|
+
return { ok: true, value, span: span2 };
|
|
4879
|
+
}
|
|
4880
|
+
anchored.lastIndex = pos;
|
|
4881
|
+
const m = anchored.exec(input);
|
|
4882
|
+
if (m === null) {
|
|
4883
|
+
return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
4884
|
+
}
|
|
4885
|
+
const span = { start: pos, end: pos + m[0].length };
|
|
4886
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
4887
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
4888
|
+
return { ok: true, value: m[0], span };
|
|
4889
|
+
}
|
|
4890
|
+
};
|
|
4891
|
+
}
|
|
4892
|
+
|
|
4893
|
+
// src/table/lex-body.ts
|
|
4894
|
+
function buildLexBodyRecognizer(spec, constants) {
|
|
4895
|
+
const raw = constants[spec[0]];
|
|
4896
|
+
if (!(raw instanceof RegExp)) {
|
|
4897
|
+
throw new TypeError("table lexical body does not reference a RegExp constant");
|
|
4808
4898
|
}
|
|
4899
|
+
if (!Number.isInteger(spec[1]) || spec[1] < -1 || spec[1] > 65535) {
|
|
4900
|
+
throw new TypeError("table lexical body suffix is not absent or one UTF-16 code unit");
|
|
4901
|
+
}
|
|
4902
|
+
const re = raw.sticky ? new RegExp(raw.source, raw.flags) : new RegExp(raw.source, `${raw.flags.replace(/[gy]/g, "")}y`);
|
|
4903
|
+
const suffix = spec[1];
|
|
4904
|
+
return (input, pos) => {
|
|
4905
|
+
re.lastIndex = pos;
|
|
4906
|
+
if (!re.test(input)) return -1;
|
|
4907
|
+
const end = re.lastIndex;
|
|
4908
|
+
if (suffix < 0) return end * 2;
|
|
4909
|
+
return input.charCodeAt(end) === suffix ? (end + 1) * 2 + 1 : end * 2;
|
|
4910
|
+
};
|
|
4809
4911
|
}
|
|
4810
4912
|
|
|
4811
4913
|
// src/table/lex-program.ts
|
|
@@ -5186,888 +5288,900 @@ function buildLexProgramRunner(spec, matchers, classes, expected) {
|
|
|
5186
5288
|
};
|
|
5187
5289
|
}
|
|
5188
5290
|
|
|
5189
|
-
// src/
|
|
5190
|
-
function
|
|
5191
|
-
|
|
5192
|
-
let pos = cur;
|
|
5193
|
-
if (ctx.trivia) {
|
|
5194
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
5195
|
-
pos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
5196
|
-
} else {
|
|
5197
|
-
pos = advanceTrivia(input, cur, ctx);
|
|
5198
|
-
}
|
|
5199
|
-
}
|
|
5200
|
-
if (pos >= input.length && !mandatory) {
|
|
5201
|
-
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
5202
|
-
return "stop";
|
|
5203
|
-
}
|
|
5204
|
-
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
5205
|
-
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
5206
|
-
return "stop";
|
|
5207
|
-
}
|
|
5208
|
-
const result = combinator.parse(input, pos, ctx);
|
|
5209
|
-
if (!result.ok) {
|
|
5210
|
-
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
5211
|
-
if (result.committed) return { fail: result, failPos: pos };
|
|
5212
|
-
return { fail: result, failPos: pos };
|
|
5213
|
-
}
|
|
5214
|
-
if (result.span.end === pos && !mandatory) {
|
|
5215
|
-
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
5216
|
-
return "stop";
|
|
5217
|
-
}
|
|
5218
|
-
return result;
|
|
5291
|
+
// src/table/program.ts
|
|
5292
|
+
function closureArtifact(prog) {
|
|
5293
|
+
return { ...prog, asm: [] };
|
|
5219
5294
|
}
|
|
5220
|
-
function
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5295
|
+
function covKindCode(kind) {
|
|
5296
|
+
switch (kind) {
|
|
5297
|
+
case "rule":
|
|
5298
|
+
return 0;
|
|
5299
|
+
case "choice-arm":
|
|
5300
|
+
return 1;
|
|
5301
|
+
case "dispatch-arm":
|
|
5302
|
+
return 2;
|
|
5303
|
+
case "label":
|
|
5304
|
+
return 3;
|
|
5305
|
+
}
|
|
5230
5306
|
}
|
|
5231
|
-
function
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
remaining--;
|
|
5307
|
+
function covKindName(code) {
|
|
5308
|
+
switch (code) {
|
|
5309
|
+
case 0:
|
|
5310
|
+
return "rule";
|
|
5311
|
+
case 1:
|
|
5312
|
+
return "choice-arm";
|
|
5313
|
+
case 2:
|
|
5314
|
+
return "dispatch-arm";
|
|
5315
|
+
case 3:
|
|
5316
|
+
return "label";
|
|
5242
5317
|
}
|
|
5243
|
-
ctx._sv = values;
|
|
5244
|
-
return cur;
|
|
5245
5318
|
}
|
|
5246
|
-
function
|
|
5247
|
-
|
|
5248
|
-
if (min >= 1) return atLeast(combinator, min, max);
|
|
5249
|
-
const meta = {
|
|
5250
|
-
firstSet: combinator._meta.firstSet,
|
|
5251
|
-
canMatchNewline: combinator._meta.canMatchNewline,
|
|
5252
|
-
isTrivia: false
|
|
5253
|
-
};
|
|
5254
|
-
const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max } };
|
|
5255
|
-
let expected;
|
|
5256
|
-
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
5257
|
-
const scalarChild = scalarOf(combinator);
|
|
5258
|
-
const parseScalar = (input, pos, ctx) => repeatScalarTail(combinator, scalarChild, input, pos, ctx, guardable, def.valueUnused ? void 0 : [], max);
|
|
5259
|
-
return {
|
|
5260
|
-
_tag: "many",
|
|
5261
|
-
_meta: meta,
|
|
5262
|
-
_def: def,
|
|
5263
|
-
_parseScalar: parseScalar,
|
|
5264
|
-
parse(input, pos, ctx) {
|
|
5265
|
-
const values = def.valueUnused ? void 0 : [];
|
|
5266
|
-
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
5267
|
-
let cur = pos;
|
|
5268
|
-
let count = 0;
|
|
5269
|
-
while (cur < input.length) {
|
|
5270
|
-
if (count >= max) break;
|
|
5271
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
5272
|
-
if (item === "stop") break;
|
|
5273
|
-
if ("fail" in item) {
|
|
5274
|
-
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
5275
|
-
const sync = ctx._tolerant ? ctx._sync : void 0;
|
|
5276
|
-
if (sync === void 0) break;
|
|
5277
|
-
if (matchesAt(sync, input, item.failPos, ctx)) break;
|
|
5278
|
-
expected ??= deriveExpected(combinator);
|
|
5279
|
-
const { error, end } = recoverScan(input, item.failPos, ctx, sync, expected);
|
|
5280
|
-
if (values !== void 0) values.push(error);
|
|
5281
|
-
captureError(ctx, error);
|
|
5282
|
-
count++;
|
|
5283
|
-
cur = end;
|
|
5284
|
-
continue;
|
|
5285
|
-
}
|
|
5286
|
-
if (values !== void 0) values.push(item.value);
|
|
5287
|
-
count++;
|
|
5288
|
-
cur = item.span.end;
|
|
5289
|
-
}
|
|
5290
|
-
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
5291
|
-
}
|
|
5292
|
-
};
|
|
5319
|
+
function covDefinitions(prog) {
|
|
5320
|
+
return (prog.cov ?? []).map(([id, kind]) => ({ id, kind: covKindName(kind) }));
|
|
5293
5321
|
}
|
|
5294
|
-
function
|
|
5295
|
-
|
|
5322
|
+
function scanRefs(s) {
|
|
5323
|
+
const refs = [];
|
|
5324
|
+
for (const r of [s.sentinel, s.recoverAt, s.stopAt, s.prefix, s.body, s.first, s.lazy]) if (r !== void 0) refs.push(r);
|
|
5325
|
+
refs.push(...s.skip);
|
|
5326
|
+
return refs;
|
|
5296
5327
|
}
|
|
5297
|
-
function
|
|
5298
|
-
const
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
}
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
if (!first.ok) return first;
|
|
5329
|
-
const values = def.valueUnused ? void 0 : [first.value];
|
|
5330
|
-
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
5331
|
-
let cur = first.span.end;
|
|
5332
|
-
let count = 1;
|
|
5333
|
-
while (count < min) {
|
|
5334
|
-
const item = repItem(combinator, input, cur, ctx, guardable, true, rollbackNeeded);
|
|
5335
|
-
if (item === "stop" || "fail" in item) {
|
|
5336
|
-
if (item !== "stop" && !item.fail.ok && item.fail.committed) return item.fail;
|
|
5337
|
-
expected ??= deriveExpected(combinator);
|
|
5338
|
-
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: cur, end: cur } };
|
|
5339
|
-
}
|
|
5340
|
-
if (values !== void 0) values.push(item.value);
|
|
5341
|
-
cur = item.span.end;
|
|
5342
|
-
count++;
|
|
5343
|
-
}
|
|
5344
|
-
while (cur < input.length) {
|
|
5345
|
-
if (count >= max) break;
|
|
5346
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
5347
|
-
if (item === "stop") break;
|
|
5348
|
-
if ("fail" in item) {
|
|
5349
|
-
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
5350
|
-
const sync = ctx._tolerant ? ctx._sync : void 0;
|
|
5351
|
-
if (sync === void 0) break;
|
|
5352
|
-
if (matchesAt(sync, input, item.failPos, ctx)) break;
|
|
5353
|
-
expected ??= deriveExpected(combinator);
|
|
5354
|
-
const { error, end } = recoverScan(input, item.failPos, ctx, sync, expected);
|
|
5355
|
-
if (values !== void 0) values.push(error);
|
|
5356
|
-
captureError(ctx, error);
|
|
5357
|
-
count++;
|
|
5358
|
-
cur = end;
|
|
5359
|
-
continue;
|
|
5360
|
-
}
|
|
5361
|
-
if (values !== void 0) values.push(item.value);
|
|
5362
|
-
count++;
|
|
5363
|
-
cur = item.span.end;
|
|
5364
|
-
}
|
|
5365
|
-
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
5366
|
-
}
|
|
5367
|
-
};
|
|
5328
|
+
function assemblyExtraIps(prog) {
|
|
5329
|
+
const ips = [];
|
|
5330
|
+
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) ips.push(r[0]);
|
|
5331
|
+
for (const set of prog.scanSkip ?? []) for (const r of set) ips.push(r[0]);
|
|
5332
|
+
return ips;
|
|
5333
|
+
}
|
|
5334
|
+
function expandCompact(p) {
|
|
5335
|
+
if ("code" in p) return p;
|
|
5336
|
+
return ownTableProgram({
|
|
5337
|
+
code: p.c,
|
|
5338
|
+
k: p.k,
|
|
5339
|
+
cc: p.x,
|
|
5340
|
+
fx: p.e,
|
|
5341
|
+
disp: p.d,
|
|
5342
|
+
rules: p.r,
|
|
5343
|
+
fns: p.f,
|
|
5344
|
+
lines: p.l ?? 0,
|
|
5345
|
+
dsp: p.p ?? [],
|
|
5346
|
+
...p.lx === void 0 ? {} : { lex: p.lx },
|
|
5347
|
+
...p.lp === void 0 ? {} : { lexPrograms: p.lp },
|
|
5348
|
+
...p.lb === void 0 ? {} : { labels: p.lb },
|
|
5349
|
+
...p.rc === void 0 ? {} : { classified: p.rc },
|
|
5350
|
+
...p.h === void 0 ? {} : { hostMode: p.h },
|
|
5351
|
+
...p.tv === void 0 ? {} : { triviaSpecs: p.tv },
|
|
5352
|
+
...p.sc === void 0 ? {} : { scans: p.sc },
|
|
5353
|
+
...p.ss === void 0 ? {} : { scanSkip: p.ss },
|
|
5354
|
+
...p.so === void 0 ? {} : { scanSkipOf: p.so },
|
|
5355
|
+
...p.rv === void 0 ? {} : { rec: p.rv },
|
|
5356
|
+
...p.cv === void 0 ? {} : { cov: p.cv },
|
|
5357
|
+
...p.a === void 0 ? {} : { asm: p.a }
|
|
5358
|
+
});
|
|
5368
5359
|
}
|
|
5369
|
-
function
|
|
5370
|
-
const
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
isTrivia: false
|
|
5374
|
-
};
|
|
5375
|
-
const firstSetSkippable = !matchesEmpty(combinator);
|
|
5376
|
-
const scalarChild = scalarOf(combinator);
|
|
5377
|
-
const parseScalar = (input, pos, ctx) => {
|
|
5378
|
-
if (firstSetSkippable && !startsFirstSet(combinator, input, pos)) {
|
|
5379
|
-
ctx._sv = null;
|
|
5380
|
-
return pos;
|
|
5381
|
-
}
|
|
5382
|
-
const end = scalarChild(input, pos, ctx);
|
|
5383
|
-
if (end >= 0) return end;
|
|
5384
|
-
ctx._sv = null;
|
|
5385
|
-
return pos;
|
|
5360
|
+
function validateDispatchSpec(spec, arity, fallbackRouted) {
|
|
5361
|
+
const invalid = (arms) => {
|
|
5362
|
+
for (const arm of arms) if (!Number.isInteger(arm) || arm < 0 || arm >= arity) return true;
|
|
5363
|
+
return false;
|
|
5386
5364
|
};
|
|
5365
|
+
if (spec === void 0 || !Number.isInteger(arity) || arity < 0 || fallbackRouted !== 0 && fallbackRouted !== 1 || spec.routed.length !== arity || spec.routed.some((value) => value !== 0 && value !== 1) || invalid(spec.byKey.values()) || invalid(spec.byFold.values()) || spec.match.some((matcher) => invalid([matcher[3]]))) {
|
|
5366
|
+
throw new TypeError("table: malformed dispatch");
|
|
5367
|
+
}
|
|
5368
|
+
}
|
|
5369
|
+
var TABLE_RUNTIME = /* @__PURE__ */ Symbol("parseman.tableRuntime");
|
|
5370
|
+
function ownTableProgram(prog, resolved, caches = {}) {
|
|
5371
|
+
const runtime = prog[TABLE_RUNTIME];
|
|
5387
5372
|
return {
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
5395
|
-
}
|
|
5396
|
-
const mark = saveTriviaMark(ctx);
|
|
5397
|
-
const result = combinator.parse(input, pos, ctx);
|
|
5398
|
-
if (result.ok) return result;
|
|
5399
|
-
rollbackTrivia(ctx, mark);
|
|
5400
|
-
if (result.committed) return result;
|
|
5401
|
-
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
5373
|
+
...prog,
|
|
5374
|
+
[TABLE_RUNTIME]: {
|
|
5375
|
+
resolved,
|
|
5376
|
+
choiceRollbackMasks: caches.choiceRollbackMasks ?? runtime?.choiceRollbackMasks,
|
|
5377
|
+
nonCommittingChoiceSites: caches.nonCommittingChoiceSites ?? runtime?.nonCommittingChoiceSites,
|
|
5378
|
+
failureRollbackCleanSites: caches.failureRollbackCleanSites ?? runtime?.failureRollbackCleanSites
|
|
5402
5379
|
}
|
|
5403
5380
|
};
|
|
5404
5381
|
}
|
|
5405
|
-
function
|
|
5406
|
-
return
|
|
5382
|
+
function choiceRollbackMask(prog, ip) {
|
|
5383
|
+
return prog[TABLE_RUNTIME]?.choiceRollbackMasks?.get(ip);
|
|
5407
5384
|
}
|
|
5408
|
-
function
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
expected ??= deriveExpected(combinator);
|
|
5421
|
-
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: at, end: at } };
|
|
5422
|
-
};
|
|
5423
|
-
const scalarExpected = deriveExpected(combinator);
|
|
5424
|
-
const scalarChild = scalarOf(combinator);
|
|
5425
|
-
const scalarSeparator = scalarOf(separator);
|
|
5426
|
-
const parseScalar = (input, pos, ctx) => {
|
|
5427
|
-
let cur = scalarChild(input, pos, ctx);
|
|
5428
|
-
if (cur < 0) {
|
|
5429
|
-
if (min >= 1) {
|
|
5430
|
-
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
5431
|
-
return ~pos;
|
|
5432
|
-
}
|
|
5433
|
-
ctx._sv = [];
|
|
5434
|
-
return pos;
|
|
5435
|
-
}
|
|
5436
|
-
const values = [ctx._sv];
|
|
5437
|
-
while (values.length < max && (cur < input.length || values.length < min)) {
|
|
5438
|
-
const beforeSeparator = cur;
|
|
5439
|
-
let separatorPos = cur;
|
|
5440
|
-
if (ctx.trivia) separatorPos = advanceTrivia(input, cur, ctx);
|
|
5441
|
-
const separatorEnd = scalarSeparator(input, separatorPos, ctx);
|
|
5442
|
-
if (separatorEnd < 0) break;
|
|
5443
|
-
let itemPos = separatorEnd;
|
|
5444
|
-
if (ctx.trivia) itemPos = advanceTrivia(input, itemPos, ctx);
|
|
5445
|
-
const itemEnd = scalarChild(input, itemPos, ctx);
|
|
5446
|
-
if (itemEnd < 0) {
|
|
5447
|
-
cur = trailing === "allow" ? separatorEnd : beforeSeparator;
|
|
5448
|
-
break;
|
|
5449
|
-
}
|
|
5450
|
-
values.push(ctx._sv);
|
|
5451
|
-
cur = itemEnd;
|
|
5385
|
+
function choiceCannotCommit(prog, ip) {
|
|
5386
|
+
return prog[TABLE_RUNTIME]?.nonCommittingChoiceSites?.has(ip) === true;
|
|
5387
|
+
}
|
|
5388
|
+
function failureRollbackClean(prog, ip) {
|
|
5389
|
+
return prog[TABLE_RUNTIME]?.failureRollbackCleanSites?.has(ip) === true;
|
|
5390
|
+
}
|
|
5391
|
+
var WIDE_CLASS_PREFIX_LO = 65535;
|
|
5392
|
+
var WIDE_CLASS_PREFIX_HI = 0;
|
|
5393
|
+
function validateClassRange(lo, hi) {
|
|
5394
|
+
for (const cp of [lo, hi]) {
|
|
5395
|
+
if (!Number.isInteger(cp) || cp < 0 || cp > 1114111) {
|
|
5396
|
+
throw new TypeError(`table char-class endpoint is outside Unicode: ${cp}`);
|
|
5452
5397
|
}
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5398
|
+
}
|
|
5399
|
+
if (lo > hi) {
|
|
5400
|
+
throw new TypeError(`table char-class range is descending: ${lo} > ${hi}`);
|
|
5401
|
+
}
|
|
5402
|
+
}
|
|
5403
|
+
function encodeClassSpec(ranges) {
|
|
5404
|
+
let wide = false;
|
|
5405
|
+
for (const range of ranges) {
|
|
5406
|
+
validateClassRange(range.lo, range.hi);
|
|
5407
|
+
if (range.hi > 65535) wide = true;
|
|
5408
|
+
}
|
|
5409
|
+
if (!wide) {
|
|
5410
|
+
let spec2 = "";
|
|
5411
|
+
for (const range of ranges) spec2 += String.fromCharCode(range.lo, range.hi);
|
|
5412
|
+
return spec2;
|
|
5413
|
+
}
|
|
5414
|
+
let spec = String.fromCharCode(WIDE_CLASS_PREFIX_LO, WIDE_CLASS_PREFIX_HI);
|
|
5415
|
+
for (const range of ranges) {
|
|
5416
|
+
spec += String.fromCharCode(
|
|
5417
|
+
range.lo >>> 16,
|
|
5418
|
+
range.lo & 65535,
|
|
5419
|
+
range.hi >>> 16,
|
|
5420
|
+
range.hi & 65535
|
|
5421
|
+
);
|
|
5422
|
+
}
|
|
5423
|
+
return spec;
|
|
5424
|
+
}
|
|
5425
|
+
function decodeClassSpec(spec) {
|
|
5426
|
+
if (spec.charCodeAt(0) === WIDE_CLASS_PREFIX_LO && spec.charCodeAt(1) === WIDE_CLASS_PREFIX_HI) {
|
|
5427
|
+
if ((spec.length - 2) % 4 !== 0) throw new TypeError("table char-class spec has a truncated wide range");
|
|
5428
|
+
if (spec.length === 2) throw new TypeError("table char-class spec has a wide prefix but no ranges");
|
|
5429
|
+
const ranges2 = [];
|
|
5430
|
+
for (let i = 2; i < spec.length; i += 4) {
|
|
5431
|
+
const lo = spec.charCodeAt(i) * 65536 + spec.charCodeAt(i + 1);
|
|
5432
|
+
const hi = spec.charCodeAt(i + 2) * 65536 + spec.charCodeAt(i + 3);
|
|
5433
|
+
validateClassRange(lo, hi);
|
|
5434
|
+
ranges2.push({ lo, hi });
|
|
5456
5435
|
}
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
sepPos = advanceTrivia(input, cur, ctx);
|
|
5505
|
-
}
|
|
5506
|
-
}
|
|
5507
|
-
if (separatorLeads) LEAD.at = cur;
|
|
5508
|
-
const sep = separator.parse(input, sepPos, ctx);
|
|
5509
|
-
if (!sep.ok) {
|
|
5510
|
-
rollbackTrivia(ctx, loopMark);
|
|
5511
|
-
if (sep.committed) return sep;
|
|
5512
|
-
break;
|
|
5513
|
-
}
|
|
5514
|
-
if (!keepSeparators) demoteCapturedToRaw(ctx, loopMark.leaves);
|
|
5515
|
-
const sepMark = trailing === "forbid" ? void 0 : saveTriviaMark(ctx);
|
|
5516
|
-
let nextPos = sep.span.end;
|
|
5517
|
-
if (ctx.trivia) {
|
|
5518
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
5519
|
-
nextPos = commitTriviaScan(scanTriviaCompact(input, sep.span.end, ctx));
|
|
5520
|
-
} else {
|
|
5521
|
-
nextPos = advanceTrivia(input, sep.span.end, ctx);
|
|
5522
|
-
}
|
|
5523
|
-
}
|
|
5524
|
-
const next = combinator.parse(input, nextPos, ctx);
|
|
5525
|
-
if (!next.ok) {
|
|
5526
|
-
if (next.committed) return next;
|
|
5527
|
-
const term = ctx._tolerant ? ctx._sync : void 0;
|
|
5528
|
-
if (term !== void 0 && !matchesAt(term, input, nextPos, ctx)) {
|
|
5529
|
-
expected ??= deriveExpected(combinator);
|
|
5530
|
-
const rec = recoverScan(input, nextPos, ctx, orSentinel(separator, term), expected);
|
|
5531
|
-
values.push(rec.error);
|
|
5532
|
-
captureError(ctx, rec.error);
|
|
5533
|
-
cur = rec.end;
|
|
5534
|
-
continue;
|
|
5535
|
-
}
|
|
5536
|
-
if (sepMark !== void 0) {
|
|
5537
|
-
rollbackTrivia(ctx, sepMark);
|
|
5538
|
-
cur = sep.span.end;
|
|
5539
|
-
break;
|
|
5540
|
-
}
|
|
5541
|
-
rollbackTrivia(ctx, loopMark);
|
|
5542
|
-
break;
|
|
5543
|
-
}
|
|
5544
|
-
values.push(next.value);
|
|
5545
|
-
cur = next.span.end;
|
|
5546
|
-
}
|
|
5547
|
-
if (values.length < min) return failAt2(cur);
|
|
5548
|
-
return { ok: true, value: values, span: { start: pos, end: cur } };
|
|
5436
|
+
return ranges2;
|
|
5437
|
+
}
|
|
5438
|
+
if (spec.length % 2 !== 0) throw new TypeError("table char-class spec has an unmatched range endpoint");
|
|
5439
|
+
const ranges = [];
|
|
5440
|
+
for (let i = 0; i < spec.length; i += 2) {
|
|
5441
|
+
const lo = spec.charCodeAt(i);
|
|
5442
|
+
const hi = spec.charCodeAt(i + 1);
|
|
5443
|
+
validateClassRange(lo, hi);
|
|
5444
|
+
ranges.push({ lo, hi });
|
|
5445
|
+
}
|
|
5446
|
+
return ranges;
|
|
5447
|
+
}
|
|
5448
|
+
function resolveClass(spec) {
|
|
5449
|
+
const ascii = new Uint8Array(128);
|
|
5450
|
+
const hi = [];
|
|
5451
|
+
for (const { lo, hi: up } of decodeClassSpec(spec)) {
|
|
5452
|
+
if (lo < 128) for (let c = lo; c <= Math.min(up, 127); c++) ascii[c] = 1;
|
|
5453
|
+
if (up >= 128) hi.push(Math.max(lo, 128), up);
|
|
5454
|
+
}
|
|
5455
|
+
return { ascii, hi };
|
|
5456
|
+
}
|
|
5457
|
+
function classHas2(cls, code) {
|
|
5458
|
+
if (code < 0) return false;
|
|
5459
|
+
if (code < 128) return cls.ascii[code] === 1;
|
|
5460
|
+
const hi = cls.hi;
|
|
5461
|
+
for (let i = 0; i < hi.length; i += 2) if (code >= hi[i] && code <= hi[i + 1]) return true;
|
|
5462
|
+
return false;
|
|
5463
|
+
}
|
|
5464
|
+
function dispatchIsExclusive(arms, cc) {
|
|
5465
|
+
const resolved = [];
|
|
5466
|
+
for (const ci of arms) if (ci >= 0) resolved[ci] = resolveClass(cc[ci]);
|
|
5467
|
+
return resolveDispatch(arms, resolved).exclusive;
|
|
5468
|
+
}
|
|
5469
|
+
function resolveDispatch(arms, cc) {
|
|
5470
|
+
const ascii = new Uint8Array(128);
|
|
5471
|
+
const hi = [];
|
|
5472
|
+
const open = [];
|
|
5473
|
+
const armCls = [];
|
|
5474
|
+
let exclusive = true;
|
|
5475
|
+
let hiOwners = 0;
|
|
5476
|
+
for (let a = 0; a < arms.length; a++) {
|
|
5477
|
+
const ci = arms[a];
|
|
5478
|
+
if (ci < 0) {
|
|
5479
|
+
open.push(a);
|
|
5480
|
+
armCls.push(null);
|
|
5481
|
+
exclusive = false;
|
|
5482
|
+
continue;
|
|
5549
5483
|
}
|
|
5484
|
+
const cls = cc[ci];
|
|
5485
|
+
armCls.push(cls);
|
|
5486
|
+
for (let c = 0; c < 128; c++) {
|
|
5487
|
+
if (cls.ascii[c] !== 1) continue;
|
|
5488
|
+
if (ascii[c] === 0) ascii[c] = a + 1;
|
|
5489
|
+
else exclusive = false;
|
|
5490
|
+
}
|
|
5491
|
+
if (cls.hi.length > 0 && ++hiOwners > 1) exclusive = false;
|
|
5492
|
+
for (let i = 0; i < cls.hi.length; i += 2) hi.push(cls.hi[i], cls.hi[i + 1], a);
|
|
5493
|
+
}
|
|
5494
|
+
return { ascii, hi, open, armCls, exclusive };
|
|
5495
|
+
}
|
|
5496
|
+
function buildTrivia(spec) {
|
|
5497
|
+
if (spec.live !== void 0) return spec.live;
|
|
5498
|
+
if (spec.plain !== void 0) return trivia(regex(new RegExp(spec.plain[0], spec.plain[1])));
|
|
5499
|
+
if (spec.alts !== void 0) {
|
|
5500
|
+
const [head, ...rest] = spec.alts.map(([source, flags]) => regex(new RegExp(source, flags)));
|
|
5501
|
+
if (head === void 0) throw new TypeError("trivia spec has an EMPTY alternation, which matches nothing");
|
|
5502
|
+
const body = rest.length === 0 ? head : choice(head, ...rest);
|
|
5503
|
+
return trivia(many(body, { min: spec.min ?? 1 }));
|
|
5504
|
+
}
|
|
5505
|
+
const arms = {};
|
|
5506
|
+
for (const [name, source, flags] of spec.arms) arms[name] = regex(new RegExp(source, flags));
|
|
5507
|
+
return classifiedTrivia(arms);
|
|
5508
|
+
}
|
|
5509
|
+
function resolveTable(prog) {
|
|
5510
|
+
const owner = prog[TABLE_RUNTIME];
|
|
5511
|
+
const hit = owner?.resolved;
|
|
5512
|
+
if (hit !== void 0) return hit;
|
|
5513
|
+
const cc = prog.cc.map(resolveClass);
|
|
5514
|
+
const triviaBuilt = (prog.triviaSpecs ?? []).map(buildTrivia);
|
|
5515
|
+
const lex = (prog.lex ?? []).map((spec) => buildLexBodyRecognizer(spec, prog.k));
|
|
5516
|
+
const built = {
|
|
5517
|
+
prog,
|
|
5518
|
+
code: Int32Array.from(prog.code),
|
|
5519
|
+
k: prog.k,
|
|
5520
|
+
fns: prog.fns,
|
|
5521
|
+
cc,
|
|
5522
|
+
fx: prog.fx,
|
|
5523
|
+
disp: prog.disp.map((d) => resolveDispatch(d, cc)),
|
|
5524
|
+
trivia: triviaBuilt,
|
|
5525
|
+
triviaScan: triviaBuilt.map(fastTriviaScanner),
|
|
5526
|
+
triviaLabelled: triviaBuilt.map((t2) => t2._meta.triviaKindLabels !== void 0),
|
|
5527
|
+
dsp: prog.dsp.map((d) => ({
|
|
5528
|
+
byKey: new Map(d.key.map((x, i) => [x, d.keyArm[i]])),
|
|
5529
|
+
byFold: new Map(d.fold.map((x, i) => [x, d.foldArm[i]])),
|
|
5530
|
+
match: d.match,
|
|
5531
|
+
routed: d.routed,
|
|
5532
|
+
expected: d.expected
|
|
5533
|
+
})),
|
|
5534
|
+
lex,
|
|
5535
|
+
lexPrograms: (prog.lexPrograms ?? []).map((spec) => buildLexProgramRunner(spec, lex, cc, prog.fx)),
|
|
5536
|
+
rules: prog.rules
|
|
5550
5537
|
};
|
|
5538
|
+
if (owner !== void 0) owner.resolved = built;
|
|
5539
|
+
return built;
|
|
5551
5540
|
}
|
|
5552
5541
|
|
|
5553
|
-
// src/
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
const
|
|
5560
|
-
const
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
}
|
|
5573
|
-
if (input.charCodeAt(pos) !== 34) {
|
|
5574
|
-
ctx._fx = expected;
|
|
5575
|
-
return ~pos;
|
|
5576
|
-
}
|
|
5577
|
-
body.lastIndex = pos + 1;
|
|
5578
|
-
const match = body.exec(input);
|
|
5579
|
-
const close = pos + 1 + match[0].length;
|
|
5580
|
-
if (input.charCodeAt(close) !== 34) {
|
|
5581
|
-
ctx._fx = expected;
|
|
5582
|
-
return ~close;
|
|
5583
|
-
}
|
|
5584
|
-
tuple[1] = match[0];
|
|
5585
|
-
const end = close + 1;
|
|
5586
|
-
ctx._sv = observesSpan ? fn(tuple, { start: pos, end }) : fn(tuple);
|
|
5587
|
-
return end;
|
|
5588
|
-
};
|
|
5589
|
-
})() : /* @__PURE__ */ (() => {
|
|
5590
|
-
return (input, pos, ctx) => {
|
|
5591
|
-
const end = child(input, pos, ctx);
|
|
5592
|
-
if (end < 0) return end;
|
|
5593
|
-
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end }) : fn(ctx._sv);
|
|
5594
|
-
return end;
|
|
5595
|
-
};
|
|
5596
|
-
})();
|
|
5597
|
-
return {
|
|
5598
|
-
_tag: "transform",
|
|
5599
|
-
_meta: combinator._meta,
|
|
5600
|
-
_def: { tag: "transform", parser: combinator, fn },
|
|
5601
|
-
_parseScalar: parseScalar,
|
|
5602
|
-
parse(input, pos, ctx) {
|
|
5603
|
-
const result = combinator.parse(input, pos, ctx);
|
|
5604
|
-
if (!result.ok) return result;
|
|
5605
|
-
return { ok: true, value: fn(result.value, result.span), span: result.span };
|
|
5542
|
+
// src/compiler/degradation.ts
|
|
5543
|
+
function formatDegradation(d) {
|
|
5544
|
+
return `[parseman] degraded [${d.code}] ${d.where}: ${d.subject} \u2014 ${d.fellBackTo}; otherwise ${d.otherwise}`;
|
|
5545
|
+
}
|
|
5546
|
+
var DETAIL_CAP = 8;
|
|
5547
|
+
function formatDegradations(list) {
|
|
5548
|
+
const byCode = /* @__PURE__ */ new Map();
|
|
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
|
+
);
|
|
5606
5561
|
}
|
|
5607
|
-
}
|
|
5562
|
+
}
|
|
5563
|
+
return out;
|
|
5608
5564
|
}
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5565
|
+
var _sinks = [];
|
|
5566
|
+
function beginDegradationCapture() {
|
|
5567
|
+
_sinks.push(/* @__PURE__ */ new Map());
|
|
5568
|
+
}
|
|
5569
|
+
function degradationCaptureDepth() {
|
|
5570
|
+
return _sinks.length;
|
|
5571
|
+
}
|
|
5572
|
+
function unwindDegradationCapture(depth) {
|
|
5573
|
+
const found = [];
|
|
5574
|
+
while (_sinks.length > depth) {
|
|
5575
|
+
const sink = _sinks.pop();
|
|
5576
|
+
found.unshift(...sink.values());
|
|
5577
|
+
}
|
|
5578
|
+
return found;
|
|
5579
|
+
}
|
|
5580
|
+
function resolveDegradationLevel(explicit) {
|
|
5581
|
+
if (explicit !== void 0) return explicit;
|
|
5582
|
+
const env = typeof process !== "undefined" ? process.env?.PARSEMAN_DEGRADATION : void 0;
|
|
5583
|
+
if (env === "off" || env === "warn" || env === "error") return env;
|
|
5584
|
+
return "warn";
|
|
5585
|
+
}
|
|
5586
|
+
function degradationKey(d) {
|
|
5587
|
+
return JSON.stringify([d.code, d.where, d.subject]);
|
|
5588
|
+
}
|
|
5589
|
+
function recordDegradation(d) {
|
|
5590
|
+
const level = resolveDegradationLevel();
|
|
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));
|
|
5603
|
+
}
|
|
5604
|
+
var _immediate = /* @__PURE__ */ new Set();
|
|
5605
|
+
function beginCompileDegradationDrain() {
|
|
5606
|
+
if (resolveDegradationLevel() === "off" || _sinks.length > 0) return () => {
|
|
5607
|
+
};
|
|
5608
|
+
const depth = degradationCaptureDepth();
|
|
5609
|
+
beginDegradationCapture();
|
|
5610
|
+
return (report) => {
|
|
5611
|
+
const found = unwindDegradationCapture(depth);
|
|
5612
|
+
if (!report || found.length === 0) return;
|
|
5613
|
+
const fresh = found.filter((d) => {
|
|
5614
|
+
const k = degradationKey(d);
|
|
5615
|
+
if (_immediate.has(k)) return false;
|
|
5616
|
+
_immediate.add(k);
|
|
5617
|
+
return true;
|
|
5618
|
+
});
|
|
5619
|
+
if (fresh.length === 0) return;
|
|
5620
|
+
const lines2 = formatDegradations(fresh);
|
|
5621
|
+
if (resolveDegradationLevel() === "error") {
|
|
5622
|
+
throw new Error(`parseman: ${fresh.length} degraded compilation path(s)
|
|
5623
|
+
${lines2.join("\n")}`);
|
|
5624
|
+
}
|
|
5625
|
+
for (const l of lines2) console.warn(l);
|
|
5626
5626
|
};
|
|
5627
5627
|
}
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5628
|
+
|
|
5629
|
+
// src/compiler/build-arity.ts
|
|
5630
|
+
function cstOutputHost(build) {
|
|
5631
|
+
return build?._parsemanCstOutput === true;
|
|
5632
|
+
}
|
|
5633
|
+
var SINGLE_IDENT_ARROW_RE = /^[A-Za-z_$][\w$]*\s*=>/;
|
|
5634
|
+
var PARAM_LIST_OPEN_RE = /^(?:function\b[^(]*)?\(/;
|
|
5635
|
+
var NATIVE_CODE_RE = /\{\s*\[native code\]\s*\}/;
|
|
5636
|
+
var PARAM_HEAD_RE = /^[A-Za-z_$][\w$]*\s*\??\s*/;
|
|
5637
|
+
function confirmedBuildArity(src) {
|
|
5638
|
+
const s = src.trim();
|
|
5639
|
+
if (NATIVE_CODE_RE.test(s)) return null;
|
|
5640
|
+
if (/\barguments\b/.test(s)) return null;
|
|
5641
|
+
if (SINGLE_IDENT_ARROW_RE.test(s)) return 1;
|
|
5642
|
+
const inner = paramListText(s);
|
|
5643
|
+
if (inner === null) return null;
|
|
5644
|
+
if (inner.trim() === "") return 0;
|
|
5645
|
+
const parts = splitTopLevel(inner);
|
|
5646
|
+
if (parts === null) return null;
|
|
5647
|
+
for (const part of parts) {
|
|
5648
|
+
if (!isConfirmableParam(part.trim())) return null;
|
|
5632
5649
|
}
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5650
|
+
return parts.length;
|
|
5651
|
+
}
|
|
5652
|
+
function paramListText(s) {
|
|
5653
|
+
const open = PARAM_LIST_OPEN_RE.exec(s);
|
|
5654
|
+
if (!open) return null;
|
|
5655
|
+
const start = open[0].length;
|
|
5656
|
+
const end = matchingParen(s, start);
|
|
5657
|
+
if (end === null) return null;
|
|
5658
|
+
if (!s.startsWith("function") && !/^\s*=>/.test(s.slice(end + 1))) return null;
|
|
5659
|
+
return s.slice(start, end);
|
|
5660
|
+
}
|
|
5661
|
+
function matchingParen(s, start) {
|
|
5662
|
+
let depth = 0;
|
|
5663
|
+
for (let i = start; i < s.length; i++) {
|
|
5664
|
+
const c = s[i];
|
|
5665
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
5666
|
+
const close = skipString(s, i);
|
|
5667
|
+
if (close === null) return null;
|
|
5668
|
+
i = close;
|
|
5669
|
+
continue;
|
|
5670
|
+
}
|
|
5671
|
+
if (c === "(" || c === "[" || c === "{") depth++;
|
|
5672
|
+
else if (c === "]" || c === "}") {
|
|
5673
|
+
if (--depth < 0) return null;
|
|
5674
|
+
} else if (c === ")") {
|
|
5675
|
+
if (depth === 0) return i;
|
|
5676
|
+
depth--;
|
|
5640
5677
|
}
|
|
5641
5678
|
}
|
|
5642
|
-
|
|
5643
|
-
const result = trivia(oneOrMore(choice(...labeledArms)));
|
|
5644
|
-
result._meta.rootTriviaClassified = true;
|
|
5645
|
-
return result;
|
|
5679
|
+
return null;
|
|
5646
5680
|
}
|
|
5647
|
-
function
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
const result = combinator.parse(input, pos, ctx);
|
|
5654
|
-
if (!result.ok) return { ok: false, expected: [name], span: result.span };
|
|
5655
|
-
return result;
|
|
5681
|
+
function skipString(s, open) {
|
|
5682
|
+
const quote = s[open];
|
|
5683
|
+
for (let i = open + 1; i < s.length; i++) {
|
|
5684
|
+
if (s[i] === "\\") {
|
|
5685
|
+
i++;
|
|
5686
|
+
continue;
|
|
5656
5687
|
}
|
|
5657
|
-
|
|
5658
|
-
}
|
|
5659
|
-
function field(name, combinator, opts) {
|
|
5660
|
-
const leadingTrivia = opts?.leadingTrivia === true;
|
|
5661
|
-
const trailingTrivia = opts?.trailingTrivia === true;
|
|
5662
|
-
if (!leadingTrivia && !trailingTrivia) {
|
|
5663
|
-
return {
|
|
5664
|
-
_tag: combinator._tag,
|
|
5665
|
-
_meta: combinator._meta,
|
|
5666
|
-
_def: { tag: "field", name, parser: combinator },
|
|
5667
|
-
parse(input, pos, ctx) {
|
|
5668
|
-
const result = combinator.parse(input, pos, ctx);
|
|
5669
|
-
if (!result.ok) return result;
|
|
5670
|
-
ctx._fields?.push({ name, value: result.value, span: result.span });
|
|
5671
|
-
return result;
|
|
5672
|
-
}
|
|
5673
|
-
};
|
|
5688
|
+
if (s[i] === quote) return i;
|
|
5674
5689
|
}
|
|
5675
|
-
return
|
|
5676
|
-
_tag: combinator._tag,
|
|
5677
|
-
_meta: combinator._meta,
|
|
5678
|
-
_def: {
|
|
5679
|
-
tag: "field",
|
|
5680
|
-
name,
|
|
5681
|
-
parser: combinator,
|
|
5682
|
-
...leadingTrivia ? { leadingTrivia: true } : {},
|
|
5683
|
-
...trailingTrivia ? { trailingTrivia: true } : {}
|
|
5684
|
-
},
|
|
5685
|
-
parse(input, pos, ctx) {
|
|
5686
|
-
const leadFrom = LEAD.at;
|
|
5687
|
-
LEAD.at = -1;
|
|
5688
|
-
const result = combinator.parse(input, pos, ctx);
|
|
5689
|
-
if (!result.ok) return result;
|
|
5690
|
-
const end = result.span.end;
|
|
5691
|
-
const trailEnd = trailingTrivia && ctx.trivia ? consumeTrivia(input, end, ctx) : end;
|
|
5692
|
-
ctx._fields?.push(triviaFieldCapture(name, result.value, input, result.span.start, end, leadingTrivia ? leadFrom : -1, trailEnd));
|
|
5693
|
-
return trailEnd === end ? result : { ok: true, value: result.value, span: { start: result.span.start, end: trailEnd } };
|
|
5694
|
-
}
|
|
5695
|
-
};
|
|
5690
|
+
return null;
|
|
5696
5691
|
}
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5692
|
+
function splitTopLevel(inner) {
|
|
5693
|
+
const parts = [];
|
|
5694
|
+
let depth = 0;
|
|
5695
|
+
let angle = 0;
|
|
5696
|
+
let last = 0;
|
|
5697
|
+
for (let i = 0; i < inner.length; i++) {
|
|
5698
|
+
const c = inner[i];
|
|
5699
|
+
if (c === "=" && inner[i + 1] === ">") {
|
|
5700
|
+
i++;
|
|
5701
|
+
continue;
|
|
5702
|
+
}
|
|
5703
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
5704
|
+
const close = skipString(inner, i);
|
|
5705
|
+
if (close === null) return null;
|
|
5706
|
+
i = close;
|
|
5707
|
+
continue;
|
|
5708
|
+
}
|
|
5709
|
+
if (c === "(" || c === "[" || c === "{") depth++;
|
|
5710
|
+
else if (c === ")" || c === "]" || c === "}") {
|
|
5711
|
+
if (--depth < 0) return null;
|
|
5712
|
+
} else if (c === "<") angle++;
|
|
5713
|
+
else if (c === ">") {
|
|
5714
|
+
if (--angle < 0) return null;
|
|
5715
|
+
} else if (c === "," && depth === 0 && angle === 0) {
|
|
5716
|
+
parts.push(inner.slice(last, i));
|
|
5717
|
+
last = i + 1;
|
|
5718
|
+
}
|
|
5704
5719
|
}
|
|
5705
|
-
return
|
|
5720
|
+
if (depth !== 0 || angle !== 0) return null;
|
|
5721
|
+
parts.push(inner.slice(last));
|
|
5722
|
+
return parts;
|
|
5706
5723
|
}
|
|
5707
|
-
function
|
|
5708
|
-
|
|
5709
|
-
|
|
5724
|
+
function isConfirmableParam(part) {
|
|
5725
|
+
const head = PARAM_HEAD_RE.exec(part);
|
|
5726
|
+
if (!head) return false;
|
|
5727
|
+
const rest = part.slice(head[0].length);
|
|
5728
|
+
if (rest === "") return true;
|
|
5729
|
+
if (rest[0] !== ":") return false;
|
|
5730
|
+
return !hasDefaultAssign(rest.slice(1));
|
|
5710
5731
|
}
|
|
5711
|
-
function
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
while (end < source.length && source[end] !== "]") {
|
|
5718
|
-
if (source[end] === "\\") end += 2;
|
|
5719
|
-
else end++;
|
|
5732
|
+
function hasDefaultAssign(annotation) {
|
|
5733
|
+
for (let i = 0; i < annotation.length; i++) {
|
|
5734
|
+
if (annotation[i] !== "=") continue;
|
|
5735
|
+
if (annotation[i + 1] === ">" || annotation[i + 1] === "=") {
|
|
5736
|
+
i++;
|
|
5737
|
+
continue;
|
|
5720
5738
|
}
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
} else if (source[0] === "\\" && (source[1] === "d" || source[1] === "w" || source[1] === "s")) {
|
|
5725
|
-
ranges = shorthandRanges(source[1]);
|
|
5726
|
-
quant = source.slice(2);
|
|
5739
|
+
const prev = annotation[i - 1];
|
|
5740
|
+
if (prev === "<" || prev === ">" || prev === "!" || prev === "=") continue;
|
|
5741
|
+
return true;
|
|
5727
5742
|
}
|
|
5728
|
-
|
|
5729
|
-
const minOne = quant === "+";
|
|
5730
|
-
return (input, pos) => {
|
|
5731
|
-
let end = pos;
|
|
5732
|
-
while (end < input.length && inRanges3(input.charCodeAt(end), ranges)) {
|
|
5733
|
-
end++;
|
|
5734
|
-
if (end - pos >= SCAN_BAIL_AT) return void 0;
|
|
5735
|
-
}
|
|
5736
|
-
return minOne && end === pos ? null : end;
|
|
5737
|
-
};
|
|
5743
|
+
return false;
|
|
5738
5744
|
}
|
|
5739
|
-
function
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5745
|
+
function buildAnalysisSrc(def) {
|
|
5746
|
+
return def.buildSigSrc ?? def.buildSrc ?? def.build.toString();
|
|
5747
|
+
}
|
|
5748
|
+
var RESOLVER_REASONS = {
|
|
5749
|
+
"rest-parameter": "its parameter list uses a rest parameter, so the declared arity is unbounded",
|
|
5750
|
+
"arguments": "its body references `arguments`",
|
|
5751
|
+
"reassigned": "the binding it names is reassigned, so the function read here is not decidable",
|
|
5752
|
+
"not-a-function": "the binding it names is not a function declaration",
|
|
5753
|
+
"unresolved-import": "its module could not be resolved or parsed",
|
|
5754
|
+
"not-found": "the name did not resolve to any binding",
|
|
5755
|
+
"computed": "it is a computed expression",
|
|
5756
|
+
"foreign-source": "it is named in a module the resolver was never told about, so its offsets index no scope tree the resolver holds",
|
|
5757
|
+
"ambiguous-source": "two distinct registered modules hold byte-identical text, so that text no longer names the module its offsets index"
|
|
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";
|
|
5757
5768
|
}
|
|
5758
|
-
return
|
|
5769
|
+
return "its parameter list could not be parsed";
|
|
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;
|
|
5799
|
+
}
|
|
5800
|
+
function buildReadsState(def) {
|
|
5801
|
+
if (!def.build) return true;
|
|
5802
|
+
const arity = confirmedArityForDef(def);
|
|
5803
|
+
if (arity === null) return true;
|
|
5804
|
+
return arity >= 6;
|
|
5759
5805
|
}
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
const
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
const
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
const match = anchored.exec(input);
|
|
5783
|
-
if (match === null) {
|
|
5784
|
-
ctx._fx = expected;
|
|
5785
|
-
return ~pos;
|
|
5786
|
-
}
|
|
5787
|
-
ctx._sv = match[0];
|
|
5788
|
-
return pos + match[0].length;
|
|
5789
|
-
};
|
|
5790
|
-
return {
|
|
5791
|
-
_tag: "regex",
|
|
5792
|
-
_meta: meta,
|
|
5793
|
-
_def: def,
|
|
5794
|
-
_stickyRegex: anchored,
|
|
5795
|
-
_parseScalar: parseScalar,
|
|
5796
|
-
parse(input, pos, ctx) {
|
|
5797
|
-
const scanEnd = scan?.(input, pos);
|
|
5798
|
-
if (scanEnd !== void 0) {
|
|
5799
|
-
if (scanEnd === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
5800
|
-
const value = input.slice(pos, scanEnd);
|
|
5801
|
-
const span2 = { start: pos, end: scanEnd };
|
|
5802
|
-
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, scanEnd);
|
|
5803
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
5804
|
-
return { ok: true, value, span: span2 };
|
|
5805
|
-
}
|
|
5806
|
-
anchored.lastIndex = pos;
|
|
5807
|
-
const m = anchored.exec(input);
|
|
5808
|
-
if (m === null) {
|
|
5809
|
-
return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
5806
|
+
|
|
5807
|
+
// src/compiler/fields.ts
|
|
5808
|
+
function buildReadsFields(def) {
|
|
5809
|
+
if (!def.build) return true;
|
|
5810
|
+
const arity = confirmedArityForDef(def);
|
|
5811
|
+
if (arity === null) return true;
|
|
5812
|
+
return arity >= 2;
|
|
5813
|
+
}
|
|
5814
|
+
function parserHasOwnFields(p, seen = /* @__PURE__ */ new Set()) {
|
|
5815
|
+
if (seen.has(p)) return false;
|
|
5816
|
+
seen.add(p);
|
|
5817
|
+
const d = p._def;
|
|
5818
|
+
switch (d.tag) {
|
|
5819
|
+
case "field":
|
|
5820
|
+
return true;
|
|
5821
|
+
case "node":
|
|
5822
|
+
return false;
|
|
5823
|
+
case "lazy": {
|
|
5824
|
+
try {
|
|
5825
|
+
return parserHasOwnFields(d.thunk(), seen);
|
|
5826
|
+
} catch {
|
|
5827
|
+
return false;
|
|
5810
5828
|
}
|
|
5811
|
-
const span = { start: pos, end: pos + m[0].length };
|
|
5812
|
-
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
5813
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
5814
|
-
return { ok: true, value: m[0], span };
|
|
5815
5829
|
}
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5830
|
+
case "sequence":
|
|
5831
|
+
case "choice":
|
|
5832
|
+
return d.parsers.some((x) => parserHasOwnFields(x, seen));
|
|
5833
|
+
case "dispatch":
|
|
5834
|
+
return parserHasOwnFields(d.selector, seen) || d.cases.some((x) => parserHasOwnFields(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => parserHasOwnFields(entry.parser, seen)) : false) || (d.otherwise ? parserHasOwnFields(d.otherwise, seen) : false);
|
|
5835
|
+
case "sepBy":
|
|
5836
|
+
return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.separator, seen);
|
|
5837
|
+
case "grammar":
|
|
5838
|
+
return parserHasOwnFields(d.parser, seen) || (d.triviaParser ? parserHasOwnFields(d.triviaParser, seen) : false);
|
|
5839
|
+
case "scanTo":
|
|
5840
|
+
return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen)) || d.recoverAt !== void 0 && parserHasOwnFields(d.recoverAt, seen) || d.stopAt !== void 0 && parserHasOwnFields(d.stopAt, seen);
|
|
5841
|
+
case "recover":
|
|
5842
|
+
return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.sentinel, seen);
|
|
5843
|
+
case "lines":
|
|
5844
|
+
return parserHasOwnFields(d.body, seen);
|
|
5845
|
+
case "routed":
|
|
5846
|
+
return d.fallback ? parserHasOwnFields(d.fallback, seen) : false;
|
|
5847
|
+
case "many":
|
|
5848
|
+
case "oneOrMore":
|
|
5849
|
+
case "optional":
|
|
5850
|
+
case "attempt":
|
|
5851
|
+
case "transform":
|
|
5852
|
+
case "trivia":
|
|
5853
|
+
case "token":
|
|
5854
|
+
case "leaf":
|
|
5855
|
+
case "label":
|
|
5856
|
+
case "expect":
|
|
5857
|
+
case "withCtx":
|
|
5858
|
+
case "not":
|
|
5859
|
+
case "peek":
|
|
5860
|
+
return parserHasOwnFields(d.parser, seen);
|
|
5861
|
+
default:
|
|
5862
|
+
return false;
|
|
5824
5863
|
}
|
|
5825
|
-
|
|
5826
|
-
|
|
5864
|
+
}
|
|
5865
|
+
function buildFieldMap(captures) {
|
|
5866
|
+
if (!captures?.length) return void 0;
|
|
5867
|
+
const out = {};
|
|
5868
|
+
for (const cap of captures) {
|
|
5869
|
+
const entry = cap.leading === void 0 ? { value: cap.value, span: cap.span } : { value: cap.value, span: cap.span, leading: cap.leading, trailing: cap.trailing };
|
|
5870
|
+
const current = out[cap.name];
|
|
5871
|
+
if (current === void 0) out[cap.name] = entry;
|
|
5872
|
+
else if (Array.isArray(current)) current.push(entry);
|
|
5873
|
+
else out[cap.name] = [current, entry];
|
|
5827
5874
|
}
|
|
5828
|
-
|
|
5829
|
-
const suffix = spec[1];
|
|
5830
|
-
return (input, pos) => {
|
|
5831
|
-
re.lastIndex = pos;
|
|
5832
|
-
if (!re.test(input)) return -1;
|
|
5833
|
-
const end = re.lastIndex;
|
|
5834
|
-
if (suffix < 0) return end * 2;
|
|
5835
|
-
return input.charCodeAt(end) === suffix ? (end + 1) * 2 + 1 : end * 2;
|
|
5836
|
-
};
|
|
5875
|
+
return out;
|
|
5837
5876
|
}
|
|
5838
5877
|
|
|
5839
|
-
// src/table/
|
|
5840
|
-
|
|
5841
|
-
|
|
5878
|
+
// src/table/ops.ts
|
|
5879
|
+
var OP_LIT = 1;
|
|
5880
|
+
var OP_RX = 2;
|
|
5881
|
+
var OP_SEQ = 3;
|
|
5882
|
+
var OP_SEQV = 4;
|
|
5883
|
+
var OP_CHOICE = 5;
|
|
5884
|
+
var OP_REP = 6;
|
|
5885
|
+
var OP_REPV = 7;
|
|
5886
|
+
var OP_OPT = 8;
|
|
5887
|
+
var OP_XFORM = 9;
|
|
5888
|
+
var OP_NODE = 10;
|
|
5889
|
+
var OP_RULE = 11;
|
|
5890
|
+
var OP_GATE = 12;
|
|
5891
|
+
var OP_NOT = 13;
|
|
5892
|
+
var OP_PEEK = 14;
|
|
5893
|
+
var OP_LEAF = 15;
|
|
5894
|
+
var OP_EMPTY = 16;
|
|
5895
|
+
var OP_LIT_TRACK = 17;
|
|
5896
|
+
var OP_RX_TRACK = 18;
|
|
5897
|
+
var OP_NODE_TRACK = 19;
|
|
5898
|
+
var OP_SCOPE = 20;
|
|
5899
|
+
var OP_EXPECT = 21;
|
|
5900
|
+
var OP_SEQX = 22;
|
|
5901
|
+
var OP_SCAN = 23;
|
|
5902
|
+
var OP_FIELD = 24;
|
|
5903
|
+
var OP_LIT_CI = 27;
|
|
5904
|
+
var OP_LIT_CI_TRACK = 28;
|
|
5905
|
+
var OP_TOKEN = 29;
|
|
5906
|
+
var OP_SCOPE_CAP = 30;
|
|
5907
|
+
var OP_WITHCTX = 31;
|
|
5908
|
+
var OP_GUARD = 32;
|
|
5909
|
+
var OP_ADJ = 33;
|
|
5910
|
+
var OP_GREEDY = 34;
|
|
5911
|
+
var OP_REJECT = 35;
|
|
5912
|
+
var OP_ARMGATE = 36;
|
|
5913
|
+
var OP_LIVE = 37;
|
|
5914
|
+
var OP_ATTEMPT = 38;
|
|
5915
|
+
var OP_LABEL = 39;
|
|
5916
|
+
var OP_COV = 40;
|
|
5917
|
+
var OP_SCOPE_PLAIN = 41;
|
|
5918
|
+
var OP_LEX_BODY = 42;
|
|
5919
|
+
var OP_LEX_PROGRAM = 43;
|
|
5920
|
+
var OP_SOURCE_LEAF = 44;
|
|
5921
|
+
var OP_DISPATCH = 25;
|
|
5922
|
+
var OP_ROUTED = 26;
|
|
5923
|
+
var OP_NAMES = {
|
|
5924
|
+
[OP_LIT]: "LIT",
|
|
5925
|
+
[OP_RX]: "RX",
|
|
5926
|
+
[OP_SEQ]: "SEQ",
|
|
5927
|
+
[OP_SEQV]: "SEQV",
|
|
5928
|
+
[OP_CHOICE]: "CHOICE",
|
|
5929
|
+
[OP_REP]: "REP",
|
|
5930
|
+
[OP_REPV]: "REPV",
|
|
5931
|
+
[OP_OPT]: "OPT",
|
|
5932
|
+
[OP_XFORM]: "XFORM",
|
|
5933
|
+
[OP_NODE]: "NODE",
|
|
5934
|
+
[OP_RULE]: "RULE",
|
|
5935
|
+
[OP_GATE]: "GATE",
|
|
5936
|
+
[OP_NOT]: "NOT",
|
|
5937
|
+
[OP_PEEK]: "PEEK",
|
|
5938
|
+
[OP_LEAF]: "LEAF",
|
|
5939
|
+
[OP_SOURCE_LEAF]: "SOURCE_LEAF",
|
|
5940
|
+
[OP_EMPTY]: "EMPTY",
|
|
5941
|
+
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
5942
|
+
[OP_RX_TRACK]: "RX_TRACK",
|
|
5943
|
+
[OP_NODE_TRACK]: "NODE_TRACK",
|
|
5944
|
+
[OP_SCOPE]: "SCOPE",
|
|
5945
|
+
[OP_EXPECT]: "EXPECT",
|
|
5946
|
+
[OP_SEQX]: "SEQX",
|
|
5947
|
+
[OP_SCAN]: "SCAN",
|
|
5948
|
+
[OP_FIELD]: "FIELD",
|
|
5949
|
+
[OP_LIT_CI]: "LIT_CI",
|
|
5950
|
+
[OP_LIT_CI_TRACK]: "LIT_CI_TRACK",
|
|
5951
|
+
[OP_DISPATCH]: "DISPATCH",
|
|
5952
|
+
[OP_ROUTED]: "ROUTED",
|
|
5953
|
+
[OP_TOKEN]: "TOKEN",
|
|
5954
|
+
[OP_SCOPE_CAP]: "SCOPE_CAP",
|
|
5955
|
+
[OP_WITHCTX]: "WITHCTX",
|
|
5956
|
+
[OP_GUARD]: "GUARD",
|
|
5957
|
+
[OP_ADJ]: "ADJ",
|
|
5958
|
+
[OP_GREEDY]: "GREEDY",
|
|
5959
|
+
[OP_REJECT]: "REJECT",
|
|
5960
|
+
[OP_ARMGATE]: "ARMGATE",
|
|
5961
|
+
[OP_LIVE]: "LIVE",
|
|
5962
|
+
[OP_ATTEMPT]: "ATTEMPT",
|
|
5963
|
+
[OP_LABEL]: "LABEL",
|
|
5964
|
+
[OP_COV]: "COV",
|
|
5965
|
+
[OP_SCOPE_PLAIN]: "SCOPE_PLAIN",
|
|
5966
|
+
[OP_LEX_BODY]: "LEX_BODY",
|
|
5967
|
+
[OP_LEX_PROGRAM]: "LEX_PROGRAM"
|
|
5968
|
+
};
|
|
5969
|
+
|
|
5970
|
+
// src/combinators/adjacency.ts
|
|
5971
|
+
function adjacencyOf(p) {
|
|
5972
|
+
return p._def.tag === "adjacency" ? p._def : null;
|
|
5842
5973
|
}
|
|
5843
|
-
function
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
case "dispatch-arm":
|
|
5850
|
-
return 2;
|
|
5851
|
-
case "label":
|
|
5852
|
-
return 3;
|
|
5853
|
-
}
|
|
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);
|
|
5854
5980
|
}
|
|
5855
|
-
function
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
case 3:
|
|
5864
|
-
return "label";
|
|
5865
|
-
}
|
|
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;
|
|
5866
5989
|
}
|
|
5867
|
-
function
|
|
5868
|
-
return
|
|
5990
|
+
function adjacencyFail(pos, def) {
|
|
5991
|
+
return { ok: false, expected: [adjacencyExpected(def)], span: { start: pos, end: pos } };
|
|
5869
5992
|
}
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
return
|
|
5873
|
-
code: p.c,
|
|
5874
|
-
k: p.k,
|
|
5875
|
-
cc: p.x,
|
|
5876
|
-
fx: p.e,
|
|
5877
|
-
disp: p.d,
|
|
5878
|
-
rules: p.r,
|
|
5879
|
-
fns: p.f,
|
|
5880
|
-
lines: p.l ?? 0,
|
|
5881
|
-
dsp: p.p ?? [],
|
|
5882
|
-
...p.lx === void 0 ? {} : { lex: p.lx },
|
|
5883
|
-
...p.lp === void 0 ? {} : { lexPrograms: p.lp },
|
|
5884
|
-
...p.lb === void 0 ? {} : { labels: p.lb },
|
|
5885
|
-
...p.rc === void 0 ? {} : { classified: p.rc },
|
|
5886
|
-
...p.h === void 0 ? {} : { hostMode: p.h },
|
|
5887
|
-
...p.tv === void 0 ? {} : { triviaSpecs: p.tv },
|
|
5888
|
-
...p.sc === void 0 ? {} : { scans: p.sc },
|
|
5889
|
-
...p.ss === void 0 ? {} : { scanSkip: p.ss },
|
|
5890
|
-
...p.so === void 0 ? {} : { scanSkipOf: p.so },
|
|
5891
|
-
...p.rv === void 0 ? {} : { rec: p.rv },
|
|
5892
|
-
...p.cv === void 0 ? {} : { cov: p.cv },
|
|
5893
|
-
...p.a === void 0 ? {} : { asm: p.a }
|
|
5894
|
-
});
|
|
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}`);
|
|
5895
5996
|
}
|
|
5896
|
-
function
|
|
5897
|
-
const
|
|
5898
|
-
|
|
5899
|
-
|
|
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
|
|
5900
6005
|
};
|
|
5901
|
-
if (spec === void 0 || !Number.isInteger(arity) || arity < 0 || fallbackRouted !== 0 && fallbackRouted !== 1 || spec.routed.length !== arity || spec.routed.some((value) => value !== 0 && value !== 1) || invalid(spec.byKey.values()) || invalid(spec.byFold.values()) || spec.match.some((matcher) => invalid([matcher[3]]))) {
|
|
5902
|
-
throw new TypeError("table: malformed dispatch");
|
|
5903
|
-
}
|
|
5904
|
-
}
|
|
5905
|
-
var TABLE_RUNTIME = /* @__PURE__ */ Symbol("parseman.tableRuntime");
|
|
5906
|
-
function ownTableProgram(prog, resolved, caches = {}) {
|
|
5907
|
-
const runtime = prog[TABLE_RUNTIME];
|
|
5908
6006
|
return {
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
failureRollbackCleanSites: caches.failureRollbackCleanSites ?? runtime?.failureRollbackCleanSites
|
|
6007
|
+
_tag: "adjacency",
|
|
6008
|
+
_meta: meta,
|
|
6009
|
+
_def: def,
|
|
6010
|
+
parse() {
|
|
6011
|
+
throw adjacencyMisuse(def.polarity);
|
|
5915
6012
|
}
|
|
5916
6013
|
};
|
|
5917
6014
|
}
|
|
5918
|
-
function
|
|
5919
|
-
return
|
|
5920
|
-
}
|
|
5921
|
-
function choiceCannotCommit(prog, ip) {
|
|
5922
|
-
return prog[TABLE_RUNTIME]?.nonCommittingChoiceSites?.has(ip) === true;
|
|
5923
|
-
}
|
|
5924
|
-
function failureRollbackClean(prog, ip) {
|
|
5925
|
-
return prog[TABLE_RUNTIME]?.failureRollbackCleanSites?.has(ip) === true;
|
|
6015
|
+
function adjacent() {
|
|
6016
|
+
return adjacencyCombinator({ tag: "adjacency", polarity: "adjacent" });
|
|
5926
6017
|
}
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
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
|
+
}
|
|
5933
6028
|
}
|
|
5934
6029
|
}
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
6030
|
+
return adjacencyCombinator(
|
|
6031
|
+
kinds === void 0 ? { tag: "adjacency", polarity: "notAdjacent" } : { tag: "adjacency", polarity: "notAdjacent", kinds: [...kinds] }
|
|
6032
|
+
);
|
|
5938
6033
|
}
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
6034
|
+
|
|
6035
|
+
// src/combinators/node.ts
|
|
6036
|
+
function unwrapChild(child) {
|
|
6037
|
+
return child !== null && typeof child === "object" && child._tag === "leaf" ? child.value : child;
|
|
6038
|
+
}
|
|
6039
|
+
function isCstChild(value) {
|
|
6040
|
+
return typeof value === "object" && value !== null && (value._tag === "node" || value._tag === "leaf" || value._tag === "parseError");
|
|
6041
|
+
}
|
|
6042
|
+
function missingInferredType() {
|
|
6043
|
+
throw new Error('node(): inferred node type requires a rules() key; pass node("Type", parser) outside rules()');
|
|
6044
|
+
}
|
|
6045
|
+
function normalizeBuildArity(arity) {
|
|
6046
|
+
if (arity === void 0) return void 0;
|
|
6047
|
+
if (!Number.isInteger(arity) || arity < 0 || arity > 6) {
|
|
6048
|
+
throw new Error("node() buildArity must be an integer 0..6 (children, fields, span, rawChildren, triviaLog, state)");
|
|
5944
6049
|
}
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
6050
|
+
return arity;
|
|
6051
|
+
}
|
|
6052
|
+
function normalizeProject(project) {
|
|
6053
|
+
if (project === void 0) return void 0;
|
|
6054
|
+
if (!Number.isInteger(project) || project < 0) {
|
|
6055
|
+
throw new Error("node() project child must be a non-negative integer");
|
|
5949
6056
|
}
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
range.hi >>> 16,
|
|
5956
|
-
range.hi & 65535
|
|
5957
|
-
);
|
|
6057
|
+
return project;
|
|
6058
|
+
}
|
|
6059
|
+
function projectChild(children2, project, type) {
|
|
6060
|
+
if (!(project in children2)) {
|
|
6061
|
+
throw new Error(`node(${JSON.stringify(type)}) project child ${project} was not captured`);
|
|
5958
6062
|
}
|
|
5959
|
-
return
|
|
6063
|
+
return unwrapChild(children2[project]);
|
|
5960
6064
|
}
|
|
5961
|
-
function
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
}
|
|
5972
|
-
return ranges2;
|
|
6065
|
+
function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
6066
|
+
const hasExplicitType = typeof typeOrCombinator === "string";
|
|
6067
|
+
const type = hasExplicitType ? typeOrCombinator : void 0;
|
|
6068
|
+
const combinator = hasExplicitType ? combinatorOrBuild : typeOrCombinator;
|
|
6069
|
+
const buildArg = hasExplicitType ? buildOrOpts : combinatorOrBuild;
|
|
6070
|
+
const build = typeof buildArg === "function" ? buildArg : void 0;
|
|
6071
|
+
const opts = typeof buildArg === "function" ? maybeOpts : buildArg ?? maybeOpts;
|
|
6072
|
+
const project = normalizeProject(opts?.project);
|
|
6073
|
+
if (project !== void 0 && build !== void 0) {
|
|
6074
|
+
throw new Error("node() options cannot combine project with a build callback");
|
|
5973
6075
|
}
|
|
5974
|
-
|
|
5975
|
-
const
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
6076
|
+
const baseDef = { tag: "node", parser: combinator, ...type === void 0 ? {} : { type }, ...build === void 0 ? {} : { build } };
|
|
6077
|
+
const meta = {
|
|
6078
|
+
firstSet: combinator._meta.firstSet,
|
|
6079
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
6080
|
+
isTrivia: false
|
|
6081
|
+
};
|
|
6082
|
+
const unwrap = opts?.unwrap === true;
|
|
6083
|
+
const collapse = opts?.collapse === true;
|
|
6084
|
+
const captureTrivia = opts?.captureTrivia === true;
|
|
6085
|
+
const trailingTrivia = opts?.trailingTrivia === true;
|
|
6086
|
+
const tags = opts?.tags;
|
|
6087
|
+
const buildArity = normalizeBuildArity(opts?.buildArity);
|
|
6088
|
+
if (unwrap && collapse) {
|
|
6089
|
+
throw new Error("node() options cannot set both unwrap and collapse");
|
|
5981
6090
|
}
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
function resolveClass(spec) {
|
|
5985
|
-
const ascii = new Uint8Array(128);
|
|
5986
|
-
const hi = [];
|
|
5987
|
-
for (const { lo, hi: up } of decodeClassSpec(spec)) {
|
|
5988
|
-
if (lo < 128) for (let c = lo; c <= Math.min(up, 127); c++) ascii[c] = 1;
|
|
5989
|
-
if (up >= 128) hi.push(Math.max(lo, 128), up);
|
|
6091
|
+
if (project !== void 0 && (unwrap || collapse)) {
|
|
6092
|
+
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
5990
6093
|
}
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
const
|
|
5997
|
-
|
|
5998
|
-
return
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6094
|
+
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || buildArity !== void 0 || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...buildArity !== void 0 ? { buildArity } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
|
|
6095
|
+
const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
6096
|
+
const readsState = build ? buildReadsState(def) : project === void 0;
|
|
6097
|
+
const hasOwnFields = parserHasOwnFields(combinator);
|
|
6098
|
+
const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
|
|
6099
|
+
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
6100
|
+
let failExpected;
|
|
6101
|
+
return {
|
|
6102
|
+
_tag: "node",
|
|
6103
|
+
_meta: meta,
|
|
6104
|
+
_def: def,
|
|
6105
|
+
parse(input, pos, ctx) {
|
|
6106
|
+
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
6107
|
+
if (failExpected === void 0) {
|
|
6108
|
+
const e = deriveExpected(combinator);
|
|
6109
|
+
failExpected = e.length > 0 ? e : [combinator._tag];
|
|
6110
|
+
}
|
|
6111
|
+
return { ok: false, expected: failExpected, span: { start: pos, end: pos } };
|
|
6112
|
+
}
|
|
6113
|
+
const hasDirectValue = build !== void 0 || project !== void 0;
|
|
6114
|
+
const hostCst = hasDirectValue && cstOutputHost(ctx.build);
|
|
6115
|
+
const structural = !hasDirectValue;
|
|
6116
|
+
const hostCapturesThisType = structural && def.type !== void 0 && ctx.build?._parsemanCaptureTrivia !== void 0 ? ctx.build._parsemanCaptureTrivia(def.type) : void 0;
|
|
6117
|
+
const effTrivia = structural ? captureTrivia || trailingTrivia || hostCapturesThisType !== false : capturesTrivia || hostCst;
|
|
6118
|
+
const effFields = capturesFields || hostCst && hasOwnFields;
|
|
6119
|
+
const saved = beginCstNodeCapture(ctx);
|
|
6120
|
+
const savedFields = ctx._fields;
|
|
6121
|
+
ctx._fields = effFields ? [] : void 0;
|
|
6122
|
+
const savedMask = ctx._triviaCaptureMask;
|
|
6123
|
+
if (build === void 0 && project === void 0 && ctx.build?._parsemanTriviaKinds !== void 0 && def.type !== void 0) {
|
|
6124
|
+
ctx._triviaCaptureMask = ctx.build._parsemanTriviaKinds(def.type);
|
|
6125
|
+
}
|
|
6126
|
+
if (!effTrivia) ctx.captureTrivia = false;
|
|
6127
|
+
let r = combinator.parse(input, pos, ctx);
|
|
6128
|
+
if (r.ok && trailingTrivia && ctx.trivia) {
|
|
6129
|
+
const end = consumeTrivia(input, r.span.end, ctx);
|
|
6130
|
+
r = { ...r, span: { start: r.span.start, end } };
|
|
6131
|
+
}
|
|
6132
|
+
const fields = effFields ? buildFieldMap(ctx._fields) : void 0;
|
|
6133
|
+
ctx._fields = savedFields;
|
|
6134
|
+
ctx._triviaCaptureMask = savedMask;
|
|
6135
|
+
const { children: children2, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
|
|
6136
|
+
if (!r.ok) return r;
|
|
6137
|
+
const st = readsState ? ctx.state : void 0;
|
|
6138
|
+
const nodeType = def.type ?? missingInferredType();
|
|
6139
|
+
const cstOutput = cstOutputHost(ctx.build);
|
|
6140
|
+
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
6141
|
+
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : (cstOutput || !build && project === void 0) && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, ctx.state, tags) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, ctx.state, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
6142
|
+
const rawEntry2 = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
|
|
6143
|
+
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
6144
|
+
pushCstChild(ctx, built, rawEntry2);
|
|
6145
|
+
}
|
|
6146
|
+
return { ok: true, value: built, span };
|
|
6021
6147
|
}
|
|
6022
|
-
|
|
6023
|
-
for (let i = 0; i < cls.hi.length; i += 2) hi.push(cls.hi[i], cls.hi[i + 1], a);
|
|
6024
|
-
}
|
|
6025
|
-
return { ascii, hi, open, armCls, exclusive };
|
|
6148
|
+
};
|
|
6026
6149
|
}
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6150
|
+
|
|
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;
|
|
6035
6184
|
}
|
|
6036
|
-
const arms = {};
|
|
6037
|
-
for (const [name, source, flags] of spec.arms) arms[name] = regex(new RegExp(source, flags));
|
|
6038
|
-
return classifiedTrivia(arms);
|
|
6039
|
-
}
|
|
6040
|
-
function resolveTable(prog) {
|
|
6041
|
-
const owner = prog[TABLE_RUNTIME];
|
|
6042
|
-
const hit = owner?.resolved;
|
|
6043
|
-
if (hit !== void 0) return hit;
|
|
6044
|
-
const cc = prog.cc.map(resolveClass);
|
|
6045
|
-
const triviaBuilt = (prog.triviaSpecs ?? []).map(buildTrivia);
|
|
6046
|
-
const lex = (prog.lex ?? []).map((spec) => buildLexBodyRecognizer(spec, prog.k));
|
|
6047
|
-
const built = {
|
|
6048
|
-
prog,
|
|
6049
|
-
code: Int32Array.from(prog.code),
|
|
6050
|
-
k: prog.k,
|
|
6051
|
-
fns: prog.fns,
|
|
6052
|
-
cc,
|
|
6053
|
-
fx: prog.fx,
|
|
6054
|
-
disp: prog.disp.map((d) => resolveDispatch(d, cc)),
|
|
6055
|
-
trivia: triviaBuilt,
|
|
6056
|
-
triviaScan: triviaBuilt.map(fastTriviaScanner),
|
|
6057
|
-
triviaLabelled: triviaBuilt.map((t2) => t2._meta.triviaKindLabels !== void 0),
|
|
6058
|
-
dsp: prog.dsp.map((d) => ({
|
|
6059
|
-
byKey: new Map(d.key.map((x, i) => [x, d.keyArm[i]])),
|
|
6060
|
-
byFold: new Map(d.fold.map((x, i) => [x, d.foldArm[i]])),
|
|
6061
|
-
match: d.match,
|
|
6062
|
-
routed: d.routed,
|
|
6063
|
-
expected: d.expected
|
|
6064
|
-
})),
|
|
6065
|
-
lex,
|
|
6066
|
-
lexPrograms: (prog.lexPrograms ?? []).map((spec) => buildLexProgramRunner(spec, lex, cc, prog.fx)),
|
|
6067
|
-
rules: prog.rules
|
|
6068
|
-
};
|
|
6069
|
-
if (owner !== void 0) owner.resolved = built;
|
|
6070
|
-
return built;
|
|
6071
6185
|
}
|
|
6072
6186
|
|
|
6073
6187
|
// src/compiler/direct-projection.ts
|
|
@@ -6618,6 +6732,7 @@ var Encoder = class {
|
|
|
6618
6732
|
case "expect":
|
|
6619
6733
|
case "recover":
|
|
6620
6734
|
case "scanTo":
|
|
6735
|
+
case "lines":
|
|
6621
6736
|
case "unknown":
|
|
6622
6737
|
return true;
|
|
6623
6738
|
case "lazy": {
|
|
@@ -6634,6 +6749,33 @@ var Encoder = class {
|
|
|
6634
6749
|
return childrenOf(def);
|
|
6635
6750
|
}
|
|
6636
6751
|
}
|
|
6752
|
+
/**
|
|
6753
|
+
* THE FIRST-CHARACTER GATE OF AN `optional`, `not` OR `peek` CHILD.
|
|
6754
|
+
*
|
|
6755
|
+
* A non-nullable child cannot match at a character outside its first set, so
|
|
6756
|
+
* the wrapper's outcome there is already decided: `optional` yields `null`,
|
|
6757
|
+
* `not` succeeds, `peek` fails with its own set. The interpreter's `optional`
|
|
6758
|
+
* makes that test itself (`repeat.ts` `startsFirstSet`); the table entered the
|
|
6759
|
+
* child — a rollback mark, the call, the child's own failure — to learn it.
|
|
6760
|
+
*
|
|
6761
|
+
* The gate is an `OP_GATE` row around the child, so every engine runs it
|
|
6762
|
+
* unchanged, a probe or tolerant parse forwards through it as for a node's
|
|
6763
|
+
* gate, and the wrapper's row keeps its layout. The engines test the class
|
|
6764
|
+
* before taking the wrapper's mark. The first set is resolved through
|
|
6765
|
+
* `winners`, the analysis a choice arm's gate uses, so a composed rule's set
|
|
6766
|
+
* is the merged one. A scalar `not` child stays bare: `scalarTerminalNotChild`
|
|
6767
|
+
* already reduces it to one recognizer call.
|
|
6768
|
+
*/
|
|
6769
|
+
lookaheadGate(p, child) {
|
|
6770
|
+
const op = this.code[child];
|
|
6771
|
+
if (op === OP_GATE || op === OP_LIT || op === OP_LIT_CI || op === OP_LIT_TRACK || op === OP_LIT_CI_TRACK || op === OP_RX || op === OP_RX_TRACK) return child;
|
|
6772
|
+
const rr = this.refResolver();
|
|
6773
|
+
if (matchesEmpty(p, /* @__PURE__ */ new Set(), rr)) return child;
|
|
6774
|
+
const cls = this.charClass(firstSetOf(p, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
6775
|
+
if (cls < 0) return child;
|
|
6776
|
+
const e = deriveExpected(p);
|
|
6777
|
+
return this.emit(OP_GATE, cls, child, this.expected(e.length > 0 ? e : [p._tag]));
|
|
6778
|
+
}
|
|
6637
6779
|
/** A first set becomes a char class string, or −1 for `any`. */
|
|
6638
6780
|
charClass(fs) {
|
|
6639
6781
|
if (fs.kind !== "ranges" || fs.ranges.length === 0) return -1;
|
|
@@ -6645,12 +6787,19 @@ var Encoder = class {
|
|
|
6645
6787
|
this.ccIndex.set(spec, i);
|
|
6646
6788
|
return i;
|
|
6647
6789
|
}
|
|
6648
|
-
/**
|
|
6649
|
-
*
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6790
|
+
/**
|
|
6791
|
+
* The first set a node's or an attempt's fail-fast gate tests. A bare
|
|
6792
|
+
* cross-rule ref resolves through `winners` (a compose OVERRIDE may widen
|
|
6793
|
+
* it). Any other body keeps its construction-time `_meta.firstSet`, except
|
|
6794
|
+
* where that is `any`: under `compose()` a body that reaches a rule of
|
|
6795
|
+
* another piece is built before that rule exists, so its cached set is
|
|
6796
|
+
* `any` and the node got NO gate (jess's `CompoundSelector` was entered at
|
|
6797
|
+
* `{`, `Call` at `}`). The resolved set is the one a choice arm's gate uses,
|
|
6798
|
+
* over the final merged map.
|
|
6799
|
+
*/
|
|
6800
|
+
gateFirstSet(p) {
|
|
6801
|
+
const cached = p._meta.firstSet;
|
|
6802
|
+
return p._def.tag === "lazy" || cached.kind === "any" ? firstSetOf(p, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : cached;
|
|
6654
6803
|
}
|
|
6655
6804
|
/**
|
|
6656
6805
|
* Wrap one choice arm in its `autoNot` checks (`OP_REJECT`).
|
|
@@ -6838,6 +6987,18 @@ var Encoder = class {
|
|
|
6838
6987
|
open: bal.open,
|
|
6839
6988
|
close: bal.close
|
|
6840
6989
|
}));
|
|
6990
|
+
if (d.tag === "lines") {
|
|
6991
|
+
return this.emit(OP_SCAN, this.scanSlot({
|
|
6992
|
+
kind: 2,
|
|
6993
|
+
flags: 0,
|
|
6994
|
+
skip: [],
|
|
6995
|
+
prefix: this.subtree(d.prefix),
|
|
6996
|
+
body: this.subtree(d.body),
|
|
6997
|
+
...d.first === void 0 ? {} : { first: this.subtree(d.first) },
|
|
6998
|
+
...d.lazy === void 0 ? {} : { lazy: this.subtree(d.lazy) }
|
|
6999
|
+
}));
|
|
7000
|
+
}
|
|
7001
|
+
if (d.tag === "columns") return this.emit(OP_SCAN, this.scanSlot({ kind: 3, flags: 0, skip: [], n: d.n }));
|
|
6841
7002
|
if (d.tag === "scanTo") {
|
|
6842
7003
|
const sentDef = d.sentinel._def;
|
|
6843
7004
|
return this.emit(OP_SCAN, this.scanSlot({
|
|
@@ -6943,6 +7104,12 @@ var Encoder = class {
|
|
|
6943
7104
|
if (transactionalFirst[i] !== void 0) classes[i] = -1;
|
|
6944
7105
|
}
|
|
6945
7106
|
}
|
|
7107
|
+
if (d.gates.some((g) => g !== null && g !== void 0) && !dispatchIsExclusive(classes, this.cc)) {
|
|
7108
|
+
for (let k = 0; k < classes.length; k++) {
|
|
7109
|
+
const gate = d.gates[order[k]];
|
|
7110
|
+
if (gate !== null && gate !== void 0) classes[k] = -1;
|
|
7111
|
+
}
|
|
7112
|
+
}
|
|
6946
7113
|
const dispIdx = this.disp.length;
|
|
6947
7114
|
this.disp.push(classes);
|
|
6948
7115
|
let rollbackMask = kids.length > 31 ? -1 : 0;
|
|
@@ -6972,7 +7139,7 @@ var Encoder = class {
|
|
|
6972
7139
|
case "oneOrMore": {
|
|
6973
7140
|
const child = this.node(d.parser).ip;
|
|
6974
7141
|
const rr = this.refResolver();
|
|
6975
|
-
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.
|
|
7142
|
+
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.charClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
6976
7143
|
const op = d.valueUnused ? OP_REPV : OP_REP;
|
|
6977
7144
|
const min = d.tag === "many" ? 0 : d.min;
|
|
6978
7145
|
return this.rec ? this.emit(op, child, min, d.max ?? -1, -1, 0, this.expected(deriveExpected(d.parser)), itemClass) : this.emit(op, child, min, d.max ?? -1, -1, 0);
|
|
@@ -6996,7 +7163,7 @@ var Encoder = class {
|
|
|
6996
7163
|
return d.min >= 2 ? this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags, this.expected(deriveExpected(d.parser))) : this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags);
|
|
6997
7164
|
}
|
|
6998
7165
|
case "optional": {
|
|
6999
|
-
const head = this.emit(OP_OPT, this.node(d.parser).ip);
|
|
7166
|
+
const head = this.emit(OP_OPT, this.lookaheadGate(d.parser, this.node(d.parser).ip));
|
|
7000
7167
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(head);
|
|
7001
7168
|
return head;
|
|
7002
7169
|
}
|
|
@@ -7044,8 +7211,8 @@ var Encoder = class {
|
|
|
7044
7211
|
// every CST node, so this is load-bearing, not reflection trivia.
|
|
7045
7212
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
7046
7213
|
);
|
|
7047
|
-
if (matchesEmpty(d.parser)) return body;
|
|
7048
|
-
const fs =
|
|
7214
|
+
if (matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return body;
|
|
7215
|
+
const fs = this.gateFirstSet(d.parser);
|
|
7049
7216
|
if (fs.kind === "any") return body;
|
|
7050
7217
|
const cls = this.charClass(fs);
|
|
7051
7218
|
if (cls < 0) return body;
|
|
@@ -7137,7 +7304,7 @@ var Encoder = class {
|
|
|
7137
7304
|
// other engine reported `['not(literal)']`. It hid because `expected` is a
|
|
7138
7305
|
// TOP-LEVEL field on `RunResult` and is NOT part of the identity digest.
|
|
7139
7306
|
case "not":
|
|
7140
|
-
return this.emit(OP_NOT, this.node(d.parser).ip, this.expected(assertionFailureExpected(false, d.parser._tag)));
|
|
7307
|
+
return this.emit(OP_NOT, this.lookaheadGate(d.parser, this.node(d.parser).ip), this.expected(assertionFailureExpected(false, d.parser._tag)));
|
|
7141
7308
|
case "guard":
|
|
7142
7309
|
return this.emit(OP_GUARD, this.fn(d.predicate, d.predSrc ?? null), this.expected(["gate"]));
|
|
7143
7310
|
case "adjacency":
|
|
@@ -7158,14 +7325,14 @@ var Encoder = class {
|
|
|
7158
7325
|
return this.emit(OP_WITHCTX, this.constant(d.extra), this.node(d.parser).ip);
|
|
7159
7326
|
}
|
|
7160
7327
|
case "peek":
|
|
7161
|
-
return this.emit(OP_PEEK, this.node(d.parser).ip, this.expected(assertionFailureExpected(true, d.parser._tag)));
|
|
7328
|
+
return this.emit(OP_PEEK, this.lookaheadGate(d.parser, this.node(d.parser).ip), this.expected(assertionFailureExpected(true, d.parser._tag)));
|
|
7162
7329
|
// A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
|
|
7163
7330
|
// lowering was correct only for a choice arm.
|
|
7164
7331
|
case "attempt": {
|
|
7165
7332
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
|
|
7166
7333
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
7167
|
-
const fs =
|
|
7168
|
-
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
7334
|
+
const fs = this.gateFirstSet(d.parser);
|
|
7335
|
+
if (fs.kind === "any" || matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return inner;
|
|
7169
7336
|
const cls = this.charClass(fs);
|
|
7170
7337
|
if (cls < 0) return inner;
|
|
7171
7338
|
const e = deriveExpected(d.parser);
|
|
@@ -7284,12 +7451,7 @@ var Encoder = class {
|
|
|
7284
7451
|
};
|
|
7285
7452
|
const seen = /* @__PURE__ */ new Set();
|
|
7286
7453
|
const refs = [];
|
|
7287
|
-
for (const s of this.scans)
|
|
7288
|
-
if (s.sentinel !== void 0) refs.push(s.sentinel);
|
|
7289
|
-
if (s.recoverAt !== void 0) refs.push(s.recoverAt);
|
|
7290
|
-
if (s.stopAt !== void 0) refs.push(s.stopAt);
|
|
7291
|
-
refs.push(...s.skip);
|
|
7292
|
-
}
|
|
7454
|
+
for (const s of this.scans) refs.push(...scanRefs(s));
|
|
7293
7455
|
for (const set of this.scanSkipSets) refs.push(...set);
|
|
7294
7456
|
const stack = [...Object.values(this.rules), ...refs.map((r) => r[0])];
|
|
7295
7457
|
while (stack.length > 0) {
|
|
@@ -7309,7 +7471,11 @@ var Encoder = class {
|
|
|
7309
7471
|
skip: s.skip.map(res),
|
|
7310
7472
|
...s.sentinel === void 0 ? {} : { sentinel: res(s.sentinel) },
|
|
7311
7473
|
...s.recoverAt === void 0 ? {} : { recoverAt: res(s.recoverAt) },
|
|
7312
|
-
...s.stopAt === void 0 ? {} : { stopAt: res(s.stopAt) }
|
|
7474
|
+
...s.stopAt === void 0 ? {} : { stopAt: res(s.stopAt) },
|
|
7475
|
+
...s.prefix === void 0 ? {} : { prefix: res(s.prefix) },
|
|
7476
|
+
...s.body === void 0 ? {} : { body: res(s.body) },
|
|
7477
|
+
...s.first === void 0 ? {} : { first: res(s.first) },
|
|
7478
|
+
...s.lazy === void 0 ? {} : { lazy: res(s.lazy) }
|
|
7313
7479
|
}));
|
|
7314
7480
|
this.scanSkipSets = this.scanSkipSets.map((set) => set.map(res));
|
|
7315
7481
|
}
|
|
@@ -8151,7 +8317,7 @@ function emitShapeMatch(shape, start, mint, ind, firstChar) {
|
|
|
8151
8317
|
if (shape.kind === "alt") {
|
|
8152
8318
|
const okV = mint("_ok");
|
|
8153
8319
|
const endV2 = mint("_end");
|
|
8154
|
-
const
|
|
8320
|
+
const lines2 = [`${ind}let ${okV} = false`, `${ind}let ${endV2} = ${start}`];
|
|
8155
8321
|
if (shape.arms.length >= 2 && shape.arms.every((a) => a.kind === "litFold" && a.open.length >= 1)) {
|
|
8156
8322
|
const groups = /* @__PURE__ */ new Map();
|
|
8157
8323
|
for (const a of shape.arms) {
|
|
@@ -8160,60 +8326,60 @@ function emitShapeMatch(shape, start, mint, ind, firstChar) {
|
|
|
8160
8326
|
const lower = f >= 65 && f <= 90 ? f + 32 : f;
|
|
8161
8327
|
(groups.get(lower) ?? groups.set(lower, []).get(lower)).push(open);
|
|
8162
8328
|
}
|
|
8163
|
-
|
|
8329
|
+
lines2.push(`${ind}if (${start} < input.length) switch (${codeAt(start, firstChar)}) {`);
|
|
8164
8330
|
for (const [lower, arms] of groups) {
|
|
8165
8331
|
const labels = lower >= 97 && lower <= 122 ? `case ${lower}: case ${lower - 32}:` : `case ${lower}:`;
|
|
8166
|
-
|
|
8332
|
+
lines2.push(`${ind} ${labels} {`);
|
|
8167
8333
|
for (const open of arms) {
|
|
8168
8334
|
const tail = open.slice(1).map((cp, i) => foldEq(`input.charCodeAt(${start} + ${i + 1})`, cp));
|
|
8169
8335
|
const cond = tail.length ? ` && ${tail.join(" && ")}` : "";
|
|
8170
|
-
|
|
8336
|
+
lines2.push(`${ind} if (${start} + ${open.length} <= input.length${cond}) { ${okV} = true; ${endV2} = ${start} + ${open.length}; break }`);
|
|
8171
8337
|
}
|
|
8172
|
-
|
|
8173
|
-
|
|
8338
|
+
lines2.push(`${ind} break`);
|
|
8339
|
+
lines2.push(`${ind} }`);
|
|
8174
8340
|
}
|
|
8175
|
-
|
|
8176
|
-
return { setup:
|
|
8341
|
+
lines2.push(`${ind}}`);
|
|
8342
|
+
return { setup: lines2, ok: okV, end: endV2 };
|
|
8177
8343
|
}
|
|
8178
8344
|
if (shape.disjoint) {
|
|
8179
8345
|
const plan = planAltSwitch(shape.firsts);
|
|
8180
8346
|
if (plan.kind === "switch") {
|
|
8181
|
-
|
|
8347
|
+
lines2.push(`${ind}if (${start} < input.length) switch (${codeAt(start, firstChar)}) {`);
|
|
8182
8348
|
shape.arms.forEach((arm, k) => {
|
|
8183
8349
|
const labels = plan.cases[k].map((cp) => `case ${cp}:`).join(" ");
|
|
8184
8350
|
const m = emitShapeMatch(arm, start, mint, `${ind} `, firstChar);
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8351
|
+
lines2.push(`${ind} ${labels} {`);
|
|
8352
|
+
lines2.push(...m.setup);
|
|
8353
|
+
lines2.push(`${ind} ${okV} = ${m.ok}`);
|
|
8354
|
+
lines2.push(`${ind} ${endV2} = ${m.ok} ? ${m.end} : ${start}`);
|
|
8355
|
+
lines2.push(`${ind} break`);
|
|
8356
|
+
lines2.push(`${ind} }`);
|
|
8191
8357
|
});
|
|
8192
|
-
|
|
8358
|
+
lines2.push(`${ind}}`);
|
|
8193
8359
|
} else {
|
|
8194
8360
|
const c0 = codeAt(start, firstChar);
|
|
8195
8361
|
shape.arms.forEach((arm, k) => {
|
|
8196
8362
|
const fs = shape.firsts[k];
|
|
8197
8363
|
const cond = fs.negated ? `!(${classCond(c0, fs.ranges)})` : `(${classCond(c0, fs.ranges)})`;
|
|
8198
8364
|
const m = emitShapeMatch(arm, start, mint, `${ind} `, firstChar);
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8365
|
+
lines2.push(`${ind}${k === 0 ? "if" : "else if"} (${start} < input.length && ${cond}) {`);
|
|
8366
|
+
lines2.push(...m.setup);
|
|
8367
|
+
lines2.push(`${ind} ${okV} = ${m.ok}`);
|
|
8368
|
+
lines2.push(`${ind} ${endV2} = ${m.ok} ? ${m.end} : ${start}`);
|
|
8369
|
+
lines2.push(`${ind}}`);
|
|
8204
8370
|
});
|
|
8205
8371
|
}
|
|
8206
8372
|
} else {
|
|
8207
8373
|
const lbl = mint("_alt");
|
|
8208
|
-
|
|
8374
|
+
lines2.push(`${ind}${lbl}: {`);
|
|
8209
8375
|
for (const arm of shape.arms) {
|
|
8210
8376
|
const m = emitShapeMatch(arm, start, mint, `${ind} `, firstChar);
|
|
8211
|
-
|
|
8212
|
-
|
|
8377
|
+
lines2.push(...m.setup);
|
|
8378
|
+
lines2.push(`${ind} if (${m.ok}) { ${okV} = true; ${endV2} = ${m.end}; break ${lbl} }`);
|
|
8213
8379
|
}
|
|
8214
|
-
|
|
8380
|
+
lines2.push(`${ind}}`);
|
|
8215
8381
|
}
|
|
8216
|
-
return { setup:
|
|
8382
|
+
return { setup: lines2, ok: okV, end: endV2 };
|
|
8217
8383
|
}
|
|
8218
8384
|
if (shape.kind === "chars") {
|
|
8219
8385
|
const cur = mint("_e");
|
|
@@ -8248,64 +8414,64 @@ function emitShapeMatch(shape, start, mint, ind, firstChar) {
|
|
|
8248
8414
|
const c = classCond(`input.charCodeAt(${at})`, p.ranges);
|
|
8249
8415
|
return p.negated ? `!(${c})` : `(${c})`;
|
|
8250
8416
|
};
|
|
8251
|
-
const
|
|
8417
|
+
const lines2 = [`${ind}let ${endV2} = ${start}`, `${ind}let ${okV} = false`, `${ind}do {`];
|
|
8252
8418
|
let first = true;
|
|
8253
8419
|
for (const p of shape.parts) {
|
|
8254
8420
|
if (p.part === "lit") {
|
|
8255
8421
|
const L = p.cps.length;
|
|
8256
8422
|
const cond = litCond(endV2, p.cps, first ? firstChar : void 0);
|
|
8257
8423
|
if (p.optional) {
|
|
8258
|
-
|
|
8424
|
+
lines2.push(`${ind} if (${endV2} + ${L} <= input.length && (${cond})) ${endV2} += ${L}`);
|
|
8259
8425
|
} else {
|
|
8260
|
-
|
|
8261
|
-
|
|
8426
|
+
lines2.push(`${ind} if (!(${endV2} + ${L} <= input.length && (${cond}))) break`);
|
|
8427
|
+
lines2.push(`${ind} ${endV2} += ${L}`);
|
|
8262
8428
|
}
|
|
8263
8429
|
} else if (p.part === "run" && p.max === Infinity) {
|
|
8264
8430
|
const s = mint("_s");
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
if (p.min === 1)
|
|
8268
|
-
else if (p.min > 1)
|
|
8431
|
+
lines2.push(`${ind} const ${s} = ${endV2}`);
|
|
8432
|
+
lines2.push(`${ind} while (${endV2} < input.length && ${runCond(p, endV2)}) ${endV2}++`);
|
|
8433
|
+
if (p.min === 1) lines2.push(`${ind} if (${endV2} === ${s}) break`);
|
|
8434
|
+
else if (p.min > 1) lines2.push(`${ind} if (${endV2} - ${s} < ${p.min}) break`);
|
|
8269
8435
|
} else if (p.part === "run" && p.max === 1) {
|
|
8270
8436
|
if (p.min === 1) {
|
|
8271
|
-
|
|
8272
|
-
|
|
8437
|
+
lines2.push(`${ind} if (!(${endV2} < input.length && ${runCond(p, endV2)})) break`);
|
|
8438
|
+
lines2.push(`${ind} ${endV2}++`);
|
|
8273
8439
|
} else {
|
|
8274
|
-
|
|
8440
|
+
lines2.push(`${ind} if (${endV2} < input.length && ${runCond(p, endV2)}) ${endV2}++`);
|
|
8275
8441
|
}
|
|
8276
8442
|
} else if (p.part === "run") {
|
|
8277
8443
|
const s = mint("_s");
|
|
8278
|
-
|
|
8279
|
-
|
|
8280
|
-
if (p.min > 0)
|
|
8444
|
+
lines2.push(`${ind} const ${s} = ${endV2}`);
|
|
8445
|
+
lines2.push(`${ind} while (${endV2} - ${s} < ${p.max} && ${endV2} < input.length && ${runCond(p, endV2)}) ${endV2}++`);
|
|
8446
|
+
if (p.min > 0) lines2.push(`${ind} if (${endV2} - ${s} < ${p.min}) break`);
|
|
8281
8447
|
} else {
|
|
8282
8448
|
const inner = emitShapeMatch(p.inner, endV2, mint, `${ind} `, first ? firstChar : void 0);
|
|
8283
8449
|
if (!p.unbounded) {
|
|
8284
|
-
|
|
8450
|
+
lines2.push(...inner.setup);
|
|
8285
8451
|
if (p.min === 1) {
|
|
8286
|
-
|
|
8287
|
-
|
|
8452
|
+
lines2.push(`${ind} if (!(${inner.ok})) break`);
|
|
8453
|
+
lines2.push(`${ind} ${endV2} = ${inner.end}`);
|
|
8288
8454
|
} else {
|
|
8289
|
-
|
|
8455
|
+
lines2.push(`${ind} if (${inner.ok}) ${endV2} = ${inner.end}`);
|
|
8290
8456
|
}
|
|
8291
8457
|
} else {
|
|
8292
8458
|
const progV = mint("_prog");
|
|
8293
|
-
|
|
8294
|
-
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
if (p.min === 1)
|
|
8459
|
+
lines2.push(`${ind} let ${progV} = false`);
|
|
8460
|
+
lines2.push(`${ind} while (true) {`);
|
|
8461
|
+
lines2.push(...inner.setup);
|
|
8462
|
+
lines2.push(`${ind} if (!(${inner.ok})) break`);
|
|
8463
|
+
lines2.push(`${ind} ${endV2} = ${inner.end}`);
|
|
8464
|
+
lines2.push(`${ind} ${progV} = true`);
|
|
8465
|
+
lines2.push(`${ind} }`);
|
|
8466
|
+
if (p.min === 1) lines2.push(`${ind} if (!${progV}) break`);
|
|
8301
8467
|
}
|
|
8302
8468
|
}
|
|
8303
8469
|
first = false;
|
|
8304
8470
|
}
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
8308
|
-
return { setup:
|
|
8471
|
+
lines2.push(`${ind} ${okV} = true`);
|
|
8472
|
+
lines2.push(`${ind}} while (false)`);
|
|
8473
|
+
lines2.push(`${ind}if (!${okV}) ${endV2} = ${start}`);
|
|
8474
|
+
return { setup: lines2, ok: okV, end: endV2 };
|
|
8309
8475
|
}
|
|
8310
8476
|
if (shape.kind === "litFold") {
|
|
8311
8477
|
const openLen2 = shape.open.length;
|
|
@@ -8891,7 +9057,10 @@ var EMITTED_PARAMS = [
|
|
|
8891
9057
|
// Appended for trivia-attributing fields (`field(…, { leadingTrivia })`);
|
|
8892
9058
|
// old factories ignore them.
|
|
8893
9059
|
"LEAD",
|
|
8894
|
-
"triviaFieldCapture"
|
|
9060
|
+
"triviaFieldCapture",
|
|
9061
|
+
// Appended for the deferred-commit trivia skip (`trivia-gap.ts`); old
|
|
9062
|
+
// factories ignore it.
|
|
9063
|
+
"skipDeferredTrivia"
|
|
8895
9064
|
];
|
|
8896
9065
|
var RUNTIME_PRELUDE = `
|
|
8897
9066
|
let _pfScan=null
|
|
@@ -8912,7 +9081,7 @@ function _skipTrivia(input,cur,ctx){
|
|
|
8912
9081
|
const s=_pfScan
|
|
8913
9082
|
if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
|
|
8914
9083
|
if(s!==null)return skipTriviaScanned(s,input,cur,ctx)
|
|
8915
|
-
if(needsDeferredTriviaCommit(ctx))return
|
|
9084
|
+
if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
|
|
8916
9085
|
return advanceTrivia(input,cur,ctx)
|
|
8917
9086
|
}
|
|
8918
9087
|
function _pushLeaf(ctx,value,s,e){pushCstLeaf(ctx,{_tag:'leaf',value,span:{start:s,end:e}})}
|
|
@@ -9119,7 +9288,7 @@ function rebuildPools(cc, fx, disp, plan) {
|
|
|
9119
9288
|
})
|
|
9120
9289
|
};
|
|
9121
9290
|
}
|
|
9122
|
-
function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false) {
|
|
9291
|
+
function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false, select) {
|
|
9123
9292
|
const { code, k, fx, disp, dsp, triviaLabelled } = t2;
|
|
9124
9293
|
const swapLegal = !cfg.trackLines;
|
|
9125
9294
|
const hostCst = cfg.hostCst;
|
|
@@ -9218,6 +9387,8 @@ function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
9218
9387
|
};
|
|
9219
9388
|
const bodies = [];
|
|
9220
9389
|
const byIp = /* @__PURE__ */ new Map();
|
|
9390
|
+
const externals = [];
|
|
9391
|
+
const siteBytes = /* @__PURE__ */ new Map();
|
|
9221
9392
|
const reached = /* @__PURE__ */ new Set();
|
|
9222
9393
|
const prelude = [];
|
|
9223
9394
|
const skipDefs = [];
|
|
@@ -9353,6 +9524,18 @@ return 1
|
|
|
9353
9524
|
tokenDecisionRefs.set(dispatchIp, made);
|
|
9354
9525
|
return made;
|
|
9355
9526
|
}
|
|
9527
|
+
function gateMissTest(gip) {
|
|
9528
|
+
const resolved = t2.cc[code[gip + 1]];
|
|
9529
|
+
const ci = classes.push([resolved]) - 1;
|
|
9530
|
+
classPlan.push([code[gip + 1]]);
|
|
9531
|
+
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
9532
|
+
return isAsciiOnlyClass(resolved) ? `${cls}.ascii[input.charCodeAt(pos)]!==1` : `!classHas(${cls},lead(input,pos))`;
|
|
9533
|
+
}
|
|
9534
|
+
function lookaheadMiss(child, miss) {
|
|
9535
|
+
if (code[child] !== OP_GATE || cfg.tolerant || cfg.probe) return "";
|
|
9536
|
+
return `if(${gateMissTest(child)}){${miss}}
|
|
9537
|
+
`;
|
|
9538
|
+
}
|
|
9356
9539
|
function skipFor(l) {
|
|
9357
9540
|
if (l.tri < 0) return "_skipTrivia";
|
|
9358
9541
|
const ki = l.tri;
|
|
@@ -9363,8 +9546,8 @@ return 1
|
|
|
9363
9546
|
const nm = `_sk${skipPool.size}`;
|
|
9364
9547
|
skipPool.set(key, nm);
|
|
9365
9548
|
if (!hasScan) {
|
|
9366
|
-
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return
|
|
9367
|
-
if(needsDeferredTriviaCommit(ctx))return
|
|
9549
|
+
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return skipDeferredTrivia(input,cur,ctx)}` : `function ${nm}(input,cur,ctx){
|
|
9550
|
+
if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
|
|
9368
9551
|
return advanceTrivia(input,cur,ctx)}`);
|
|
9369
9552
|
return nm;
|
|
9370
9553
|
}
|
|
@@ -9409,9 +9592,17 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
9409
9592
|
const target = resolveAlias(ip);
|
|
9410
9593
|
const done = byIp.get(target);
|
|
9411
9594
|
if (done !== void 0) return done;
|
|
9595
|
+
if (select !== void 0 && !select.has(target)) {
|
|
9596
|
+
const ext = `_px${target}`;
|
|
9597
|
+
byIp.set(target, ext);
|
|
9598
|
+
externals.push(target);
|
|
9599
|
+
return ext;
|
|
9600
|
+
}
|
|
9412
9601
|
const fname = `_pf${target}`;
|
|
9413
9602
|
byIp.set(target, fname);
|
|
9414
|
-
|
|
9603
|
+
const body = lower(target, fname);
|
|
9604
|
+
siteBytes.set(target, body.length);
|
|
9605
|
+
bodies.push(body);
|
|
9415
9606
|
return fname;
|
|
9416
9607
|
}
|
|
9417
9608
|
function resolveAlias(ip) {
|
|
@@ -9551,14 +9742,28 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
9551
9742
|
return `${head}EC.e=pos;return ''}`;
|
|
9552
9743
|
case OP_GATE: {
|
|
9553
9744
|
const child = link(code[ip + 2]);
|
|
9554
|
-
const resolved = t2.cc[code[ip + 1]];
|
|
9555
|
-
const ci = classes.push([resolved]) - 1;
|
|
9556
|
-
classPlan.push([code[ip + 1]]);
|
|
9557
|
-
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
9558
9745
|
const xf = fxRef(code[ip + 3]);
|
|
9559
9746
|
return `${head}
|
|
9560
|
-
if(${
|
|
9747
|
+
if(${gateMissTest(ip)}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
9561
9748
|
return ${child}(input,pos,ctx)
|
|
9749
|
+
}`;
|
|
9750
|
+
}
|
|
9751
|
+
case OP_ARMGATE: {
|
|
9752
|
+
const pred = fnRef(code[ip + 1]);
|
|
9753
|
+
const child = link(code[ip + 2]);
|
|
9754
|
+
const xf = fxRef(code[ip + 3]);
|
|
9755
|
+
return `${head}
|
|
9756
|
+
if(!${pred}(ctx.state)){ctx._fc=false;ctx._fe=-1;ctx._fx=${xf};return FAIL}
|
|
9757
|
+
return ${child}(input,pos,ctx)
|
|
9758
|
+
}`;
|
|
9759
|
+
}
|
|
9760
|
+
case OP_WITHCTX: {
|
|
9761
|
+
const ki = code[ip + 1];
|
|
9762
|
+
const child = link(code[ip + 2]);
|
|
9763
|
+
return `${head}
|
|
9764
|
+
const saved=ctx.state
|
|
9765
|
+
ctx.state=${ki < 0 ? `${fnRef(~ki)}(saved)` : kRef(ki)}
|
|
9766
|
+
try{return ${child}(input,pos,ctx)}finally{ctx.state=saved}
|
|
9562
9767
|
}`;
|
|
9563
9768
|
}
|
|
9564
9769
|
case OP_XFORM: {
|
|
@@ -9814,7 +10019,7 @@ return FAIL
|
|
|
9814
10019
|
const xf = fxRef(code[ip + 2]);
|
|
9815
10020
|
const p = tmp();
|
|
9816
10021
|
return `${head}
|
|
9817
|
-
${emitMark(p, L.buf, L.raw, sinks)}
|
|
10022
|
+
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${emitMark(p, L.buf, L.raw, sinks)}
|
|
9818
10023
|
const v=${child}(input,pos,ctx)
|
|
9819
10024
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
9820
10025
|
if(v===FAIL){EC.e=pos;return null}
|
|
@@ -9828,7 +10033,7 @@ return FAIL
|
|
|
9828
10033
|
const xf = fxRef(code[ip + 2]);
|
|
9829
10034
|
const p = tmp();
|
|
9830
10035
|
return `${head}
|
|
9831
|
-
${emitMark(p, L.buf, L.raw, sinks)}
|
|
10036
|
+
${lookaheadMiss(code[ip + 1], `ctx._fe=pos;ctx._fx=${xf};return FAIL`)}${emitMark(p, L.buf, L.raw, sinks)}
|
|
9832
10037
|
const v=${child}(input,pos,ctx)
|
|
9833
10038
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
9834
10039
|
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
@@ -9841,7 +10046,7 @@ return null
|
|
|
9841
10046
|
const clean = !REC && failureRollbackClean(prog, ip);
|
|
9842
10047
|
const p = tmp();
|
|
9843
10048
|
return `${head}
|
|
9844
|
-
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
10049
|
+
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
9845
10050
|
ctx._fc=false
|
|
9846
10051
|
const v=${child}(input,pos,ctx)
|
|
9847
10052
|
if(v===FAIL){
|
|
@@ -9922,7 +10127,7 @@ return v
|
|
|
9922
10127
|
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
9923
10128
|
const hiArr = table.hi;
|
|
9924
10129
|
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
9925
|
-
const directAscii =
|
|
10130
|
+
const directAscii = table.hi.length === 0;
|
|
9926
10131
|
return `${head}
|
|
9927
10132
|
const c=${directAscii ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
9928
10133
|
let arm=-1
|
|
@@ -9949,7 +10154,7 @@ return FAIL
|
|
|
9949
10154
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
9950
10155
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
9951
10156
|
const maskable = n <= 32;
|
|
9952
|
-
const directAsciiMask =
|
|
10157
|
+
const directAsciiMask = maskable && gates.every(isAsciiOnlyClass);
|
|
9953
10158
|
const gateRefs = directAsciiMask ? [] : Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
9954
10159
|
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
9955
10160
|
const pretests = Array.from({ length: n }, (_, i) => {
|
|
@@ -9991,7 +10196,7 @@ return FAIL
|
|
|
9991
10196
|
if (choiceCannotCommit(prog, ip) && !startFailureExact) {
|
|
9992
10197
|
const deepAt = Array.from({ length: n }, () => tmp());
|
|
9993
10198
|
const deepFx = Array.from({ length: n }, () => tmp());
|
|
9994
|
-
const
|
|
10199
|
+
const remember2 = (i, at, expectedSet) => `${deepAt[i]}=${at};${deepFx[i]}=${expectedSet}`;
|
|
9995
10200
|
const lazyArms = (ascii) => arms.map((arm, i) => {
|
|
9996
10201
|
const pretest = pretests[i];
|
|
9997
10202
|
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
@@ -10003,13 +10208,13 @@ return FAIL
|
|
|
10003
10208
|
if(${decision}===0){
|
|
10004
10209
|
ctx._fc=false
|
|
10005
10210
|
{const at=_pfTokEnd
|
|
10006
|
-
${
|
|
10211
|
+
${remember2(i, "at", pretest.token.expected)}}
|
|
10007
10212
|
}`;
|
|
10008
10213
|
const sequenceMiss = pretest?.sequence === void 0 ? "" : `
|
|
10009
10214
|
else if(${ascii ? `(bits&${1 << i})!==0&&` : ""}${decision}<0){
|
|
10010
10215
|
ctx._fc=false
|
|
10011
10216
|
{const at=_pfSeqEnd
|
|
10012
|
-
${
|
|
10217
|
+
${remember2(i, "at", pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("") + pretest.sequence.expected.at(-1))}}
|
|
10013
10218
|
}`;
|
|
10014
10219
|
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
10015
10220
|
`}if(${gate}){
|
|
@@ -10017,7 +10222,7 @@ ctx._fc=false
|
|
|
10017
10222
|
{const v=${arm}(input,pos,ctx)
|
|
10018
10223
|
if(v!==FAIL)return v}
|
|
10019
10224
|
{const at=ctx._fe??pos
|
|
10020
|
-
${
|
|
10225
|
+
${remember2(i, "at", "ctx._fx")}}
|
|
10021
10226
|
${rollbackFor(i)}
|
|
10022
10227
|
}${routeMiss}${sequenceMiss}`;
|
|
10023
10228
|
}).join("\n");
|
|
@@ -10130,7 +10335,7 @@ const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
|
10130
10335
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
10131
10336
|
${startFailureExact ? "" : "let prev=0"}
|
|
10132
10337
|
${maskArms}
|
|
10133
|
-
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${n},prev,acc)`}
|
|
10338
|
+
${startFailureExact ? "" : `if(best===pos&&prev!==0)acc=${catchName}(${n},prev,acc)`}
|
|
10134
10339
|
ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
|
|
10135
10340
|
return FAIL
|
|
10136
10341
|
}
|
|
@@ -10229,7 +10434,7 @@ return [key,v]
|
|
|
10229
10434
|
const ci = classes.push([resolved]) - 1;
|
|
10230
10435
|
classPlan.push([itemClassIndex]);
|
|
10231
10436
|
itemCls = hoist("ri", `CLS[${ci}][0]`);
|
|
10232
|
-
itemAscii =
|
|
10437
|
+
itemAscii = isAsciiOnlyClass(resolved);
|
|
10233
10438
|
}
|
|
10234
10439
|
}
|
|
10235
10440
|
const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
|
|
@@ -10455,7 +10660,7 @@ return nd
|
|
|
10455
10660
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
10456
10661
|
const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
|
|
10457
10662
|
const ty = q(type);
|
|
10458
|
-
const stArg =
|
|
10663
|
+
const stArg = "ctx.state";
|
|
10459
10664
|
const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
|
|
10460
10665
|
let value;
|
|
10461
10666
|
if (proj >= 0) {
|
|
@@ -10516,7 +10721,7 @@ ctx.captureTrivia=sCap
|
|
|
10516
10721
|
if(v===FAIL)return FAIL
|
|
10517
10722
|
const end=EC.e
|
|
10518
10723
|
const span=${tracked ? "spanLines(ctx,pos,end)" : "{start:pos,end}"}
|
|
10519
|
-
const st=${readsState ? "
|
|
10724
|
+
const st=${readsState ? "ctx.state" : "undefined"}
|
|
10520
10725
|
let nd
|
|
10521
10726
|
${unwrap ? "if(kids.length===1)nd=unwrapChild(kids[0])\nelse " : ""}${collapse ? "if(kids.length===1)nd=kids[0]\nelse " : ""}${collapsible ? `if(_pfHost!==undefined&&_pfHost._parsemanCstCollapse!==undefined&&kids.length===1&&rawKids.length===1&&_pfHost._parsemanCstCollapse(${ty},kids[0],kids,rawKids))nd=kids[0]
|
|
10522
10727
|
else ` : ""}{${value}}
|
|
@@ -10529,21 +10734,51 @@ return nd
|
|
|
10529
10734
|
throw new Unemittable(`OP_${OP_NAMES[op] ?? String(op)}`);
|
|
10530
10735
|
}
|
|
10531
10736
|
}
|
|
10737
|
+
const served = (ip) => select === void 0 || select.has(resolveAlias(ip));
|
|
10532
10738
|
const ruleEntries = [];
|
|
10533
10739
|
for (const [rname, entryIp] of Object.entries(prog.rules)) {
|
|
10740
|
+
if (!served(entryIp)) continue;
|
|
10534
10741
|
const target = link(entryIp);
|
|
10535
10742
|
const rn = `_r_${rname.replace(/[^A-Za-z0-9_$]/g, "_")}`;
|
|
10536
10743
|
bodies.push(`const ${rn}=${target}`);
|
|
10537
10744
|
ruleEntries.push(`${q(rname)}:${rn}`);
|
|
10538
10745
|
}
|
|
10539
10746
|
const extra = [];
|
|
10540
|
-
|
|
10747
|
+
const exported = /* @__PURE__ */ new Set();
|
|
10748
|
+
for (const ip of extraIps) {
|
|
10749
|
+
if (!served(ip)) continue;
|
|
10750
|
+
exported.add(ip);
|
|
10751
|
+
extra.push(`${ip}:${link(ip)}`);
|
|
10752
|
+
}
|
|
10753
|
+
if (select !== void 0) {
|
|
10754
|
+
const kids = [];
|
|
10755
|
+
for (const ip of reachable) {
|
|
10756
|
+
if (select.has(resolveAlias(ip))) continue;
|
|
10757
|
+
kids.length = 0;
|
|
10758
|
+
childSlots(code, ip, kids);
|
|
10759
|
+
for (const kid of kids) {
|
|
10760
|
+
const target = resolveAlias(kid);
|
|
10761
|
+
if (!select.has(target) || exported.has(target)) continue;
|
|
10762
|
+
exported.add(target);
|
|
10763
|
+
extra.push(`${target}:${link(target)}`);
|
|
10764
|
+
}
|
|
10765
|
+
}
|
|
10766
|
+
}
|
|
10767
|
+
const hybrid = select === void 0 ? "" : `,
|
|
10768
|
+
ext:[${externals.join(",")}],
|
|
10769
|
+
bind:function(xs,ps){_xScan=xs
|
|
10770
|
+
${externals.map((ip, i) => `_xp${ip}=ps[${i}]`).join("\n")}},
|
|
10771
|
+
scan:function(s){const o=_pfScan;_pfScan=s;return o}`;
|
|
10772
|
+
const externalDefs = select === void 0 ? "" : `let _xScan
|
|
10773
|
+
${externals.map((ip) => `let _xp${ip}
|
|
10774
|
+
function _px${ip}(input,pos,ctx){const o=_xScan(_pfScan);const v=_xp${ip}(input,pos,ctx);_xScan(o);return v}`).join("\n")}
|
|
10775
|
+
`;
|
|
10541
10776
|
const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
|
|
10542
10777
|
${prelude.join("\n")}
|
|
10543
10778
|
${skipDefs.join("\n")}
|
|
10544
10779
|
${choiceDefs.join("\n")}
|
|
10545
10780
|
${bodies.join("\n")}
|
|
10546
|
-
function _begin(ctx){
|
|
10781
|
+
${externalDefs}function _begin(ctx){
|
|
10547
10782
|
const host=ctx.build
|
|
10548
10783
|
if(_pfDepth>0)_pfFrames.push([_pfScan,_pfHost,EC.e])
|
|
10549
10784
|
_pfDepth++
|
|
@@ -10570,7 +10805,7 @@ pieces:{${ruleEntries.join(",")}},
|
|
|
10570
10805
|
byIp:{${extra.join(",")}},
|
|
10571
10806
|
end:function(){return EC.e},
|
|
10572
10807
|
begin:_begin,
|
|
10573
|
-
finish:_finish
|
|
10808
|
+
finish:_finish${hybrid}
|
|
10574
10809
|
}`;
|
|
10575
10810
|
return {
|
|
10576
10811
|
source,
|
|
@@ -10578,10 +10813,193 @@ finish:_finish
|
|
|
10578
10813
|
masks,
|
|
10579
10814
|
classes,
|
|
10580
10815
|
armExpected,
|
|
10816
|
+
siteBytes,
|
|
10581
10817
|
plan: { classes: classPlan, armExpected: armExpectedPlan, masks: maskPlan }
|
|
10582
10818
|
};
|
|
10583
10819
|
}
|
|
10584
10820
|
|
|
10821
|
+
// src/combinators/lines.ts
|
|
10822
|
+
function lineIndexAt(view, offset) {
|
|
10823
|
+
const lines2 = view.lines;
|
|
10824
|
+
let lo = 0, hi = lines2.length - 1;
|
|
10825
|
+
while (lo < hi) {
|
|
10826
|
+
const mid = lo + hi + 1 >> 1;
|
|
10827
|
+
if (lines2[mid].offset <= offset) lo = mid;
|
|
10828
|
+
else hi = mid - 1;
|
|
10829
|
+
}
|
|
10830
|
+
return lo;
|
|
10831
|
+
}
|
|
10832
|
+
var lineAt = (view, offset) => view.lines[lineIndexAt(view, offset)];
|
|
10833
|
+
function sourceOffset(view, offset) {
|
|
10834
|
+
const line = lineAt(view, offset);
|
|
10835
|
+
return line === void 0 ? offset : line.source + (offset - line.offset);
|
|
10836
|
+
}
|
|
10837
|
+
function columnAt(input, pos, ctx) {
|
|
10838
|
+
const view = ctx.lineView;
|
|
10839
|
+
let start, column, split;
|
|
10840
|
+
const line = view === void 0 ? void 0 : lineAt(view, pos);
|
|
10841
|
+
if (line !== void 0 && pos >= line.offset) {
|
|
10842
|
+
start = line.offset;
|
|
10843
|
+
column = line.column;
|
|
10844
|
+
split = line.split;
|
|
10845
|
+
} else {
|
|
10846
|
+
start = input.lastIndexOf("\n", pos - 1) + 1;
|
|
10847
|
+
column = 0;
|
|
10848
|
+
split = 0;
|
|
10849
|
+
}
|
|
10850
|
+
for (let i = start; i < pos; i++) {
|
|
10851
|
+
if (input.charCodeAt(i) === 9) {
|
|
10852
|
+
const width = 4 - (column - (i === start ? split : 0)) % 4 - (i === start ? split : 0);
|
|
10853
|
+
column += width;
|
|
10854
|
+
} else column++;
|
|
10855
|
+
split = 0;
|
|
10856
|
+
}
|
|
10857
|
+
return { column, split: pos === start ? split : 0 };
|
|
10858
|
+
}
|
|
10859
|
+
function columns(n) {
|
|
10860
|
+
if (!Number.isInteger(n) || n < 0) throw new TypeError(`columns(n) needs a non-negative integer, got ${n}`);
|
|
10861
|
+
const expected = [`columns(${n})`];
|
|
10862
|
+
const meta = {
|
|
10863
|
+
firstSet: n === 0 ? any() : { kind: "ranges", ranges: [{ lo: 9, hi: 9 }, { lo: 32, hi: 32 }] },
|
|
10864
|
+
canMatchNewline: false,
|
|
10865
|
+
isTrivia: false
|
|
10866
|
+
};
|
|
10867
|
+
return {
|
|
10868
|
+
_tag: "columns",
|
|
10869
|
+
_meta: meta,
|
|
10870
|
+
_def: { tag: "columns", n },
|
|
10871
|
+
parse(input, pos, ctx) {
|
|
10872
|
+
const c = ctx;
|
|
10873
|
+
let { column, split } = columnAt(input, pos, c);
|
|
10874
|
+
const goal = column + n;
|
|
10875
|
+
let at = pos;
|
|
10876
|
+
while (column < goal) {
|
|
10877
|
+
const code = input.charCodeAt(at);
|
|
10878
|
+
if (code === 32) {
|
|
10879
|
+
column++;
|
|
10880
|
+
split = 0;
|
|
10881
|
+
at++;
|
|
10882
|
+
continue;
|
|
10883
|
+
}
|
|
10884
|
+
if (code !== 9) return { ok: false, expected, span: { start: at, end: at } };
|
|
10885
|
+
const width = 4 - (column - split) % 4 - split;
|
|
10886
|
+
if (column + width > goal) {
|
|
10887
|
+
c._columnsSplit = { at, split: split + (goal - column) };
|
|
10888
|
+
return { ok: true, value: input.slice(pos, at), span: { start: pos, end: at } };
|
|
10889
|
+
}
|
|
10890
|
+
column += width;
|
|
10891
|
+
split = 0;
|
|
10892
|
+
at++;
|
|
10893
|
+
}
|
|
10894
|
+
return { ok: true, value: input.slice(pos, at), span: { start: pos, end: at } };
|
|
10895
|
+
}
|
|
10896
|
+
};
|
|
10897
|
+
}
|
|
10898
|
+
function lines(prefix, body, options = {}) {
|
|
10899
|
+
const { first, lazy } = options;
|
|
10900
|
+
const opening = first ?? prefix;
|
|
10901
|
+
const meta = {
|
|
10902
|
+
// An opening that matches empty starts a run at any character.
|
|
10903
|
+
firstSet: matchesEmpty(opening) ? any() : opening._meta.firstSet,
|
|
10904
|
+
canMatchNewline: true,
|
|
10905
|
+
isTrivia: false
|
|
10906
|
+
};
|
|
10907
|
+
return {
|
|
10908
|
+
_tag: "lines",
|
|
10909
|
+
_meta: meta,
|
|
10910
|
+
_def: { tag: "lines", prefix, body, ...first === void 0 ? {} : { first }, ...lazy === void 0 ? {} : { lazy } },
|
|
10911
|
+
parse(input, pos, ctx) {
|
|
10912
|
+
const c = ctx;
|
|
10913
|
+
const probe = createDetachedParseContext(false, ctx.state);
|
|
10914
|
+
probe.lineView = c.lineView;
|
|
10915
|
+
const run = [];
|
|
10916
|
+
const parts = [];
|
|
10917
|
+
let offset = 0;
|
|
10918
|
+
for (let start = pos; start < input.length || start === pos; ) {
|
|
10919
|
+
let end2 = input.indexOf("\n", start);
|
|
10920
|
+
if (end2 < 0) end2 = input.length;
|
|
10921
|
+
probe._columnsSplit = void 0;
|
|
10922
|
+
const head = (run.length === 0 ? opening : prefix).parse(input, start, probe);
|
|
10923
|
+
let content;
|
|
10924
|
+
let joined;
|
|
10925
|
+
if (head.ok && head.span.end <= end2) {
|
|
10926
|
+
content = head.span.end;
|
|
10927
|
+
joined = "prefix";
|
|
10928
|
+
} else if (run.length === 0) {
|
|
10929
|
+
return { ok: false, expected: head.ok ? ["line prefix"] : head.expected, span: { start, end: start } };
|
|
10930
|
+
} else if (lazy !== void 0 && lazy.parse(input, start, probe).ok) {
|
|
10931
|
+
content = start;
|
|
10932
|
+
joined = "lazy";
|
|
10933
|
+
} else break;
|
|
10934
|
+
const mark = probe._columnsSplit;
|
|
10935
|
+
const here = columnAt(input, content, c);
|
|
10936
|
+
const split = joined === "prefix" && mark !== void 0 && mark.at === content ? mark.split : here.split;
|
|
10937
|
+
run.push({ offset, source: content, end: end2, column: here.column + (split - here.split), split, lazy: joined === "lazy" });
|
|
10938
|
+
const text = input.slice(content, end2);
|
|
10939
|
+
const newline = end2 < input.length;
|
|
10940
|
+
parts.push(newline ? `${text}
|
|
10941
|
+
` : text);
|
|
10942
|
+
offset += text.length + (newline ? 1 : 0);
|
|
10943
|
+
start = end2 + 1;
|
|
10944
|
+
if (!newline) break;
|
|
10945
|
+
}
|
|
10946
|
+
const view = { lines: run, parent: c.lineView };
|
|
10947
|
+
const saved = c.lineView, starts = c._lineStarts, lineIndex = c._lineIndex, scanned = c._lineScannedTo, probing = c._probe;
|
|
10948
|
+
const errors = c._errors?.length ?? 0;
|
|
10949
|
+
let cursor = -1;
|
|
10950
|
+
if (probing !== void 0) for (const line2 of run) {
|
|
10951
|
+
if (probing.offset >= line2.source && probing.offset <= line2.end) {
|
|
10952
|
+
cursor = line2.offset + probing.offset - line2.source;
|
|
10953
|
+
break;
|
|
10954
|
+
}
|
|
10955
|
+
}
|
|
10956
|
+
const inner = cursor < 0 ? void 0 : { offset: cursor, best: null };
|
|
10957
|
+
c.lineView = view;
|
|
10958
|
+
c._lineStarts = void 0;
|
|
10959
|
+
c._lineIndex = void 0;
|
|
10960
|
+
c._lineScannedTo = void 0;
|
|
10961
|
+
c._probe = inner;
|
|
10962
|
+
let result;
|
|
10963
|
+
try {
|
|
10964
|
+
result = body.parse(parts.join(""), 0, ctx);
|
|
10965
|
+
} finally {
|
|
10966
|
+
c.lineView = saved;
|
|
10967
|
+
c._lineStarts = starts;
|
|
10968
|
+
c._lineIndex = lineIndex;
|
|
10969
|
+
c._lineScannedTo = scanned;
|
|
10970
|
+
c._probe = probing;
|
|
10971
|
+
}
|
|
10972
|
+
if (inner?.best) failAt(c, inner.best.expected, sourceOffset(view, inner.best.span.start));
|
|
10973
|
+
if (c._errors !== void 0) for (let i = errors; i < c._errors.length; i++) {
|
|
10974
|
+
const error = c._errors[i];
|
|
10975
|
+
error.span = { start: sourceOffset(view, error.span.start), end: sourceOffset(view, error.span.end) };
|
|
10976
|
+
}
|
|
10977
|
+
if (!result.ok) {
|
|
10978
|
+
const at = sourceOffset(view, result.span.start);
|
|
10979
|
+
return { ...result, span: { start: at, end: at } };
|
|
10980
|
+
}
|
|
10981
|
+
const stop = result.span.end;
|
|
10982
|
+
const index = lineIndexAt(view, stop);
|
|
10983
|
+
const line = run[index];
|
|
10984
|
+
const end = stop === line.offset && index > 0 ? run[index - 1].end + 1 : stop - line.offset > line.end - line.source ? line.end + 1 : line.source + (stop - line.offset);
|
|
10985
|
+
recordLineRangeFromContext(c, input, pos, end);
|
|
10986
|
+
return { ok: true, value: result.value, span: { start: pos, end } };
|
|
10987
|
+
}
|
|
10988
|
+
};
|
|
10989
|
+
}
|
|
10990
|
+
|
|
10991
|
+
// src/table/line-scan.ts
|
|
10992
|
+
function rebuildLineScan(s, subtree) {
|
|
10993
|
+
if (s.kind === 2) {
|
|
10994
|
+
return lines(subtree(s.prefix), subtree(s.body), {
|
|
10995
|
+
...s.first === void 0 ? {} : { first: subtree(s.first) },
|
|
10996
|
+
...s.lazy === void 0 ? {} : { lazy: subtree(s.lazy) }
|
|
10997
|
+
});
|
|
10998
|
+
}
|
|
10999
|
+
if (s.kind === 3) return columns(s.n);
|
|
11000
|
+
return void 0;
|
|
11001
|
+
}
|
|
11002
|
+
|
|
10585
11003
|
// src/combinators/literal.ts
|
|
10586
11004
|
function asciiFoldEq(a, b) {
|
|
10587
11005
|
if (a.length !== b.length) return false;
|
|
@@ -11229,6 +11647,70 @@ function escapeClassChar(ch2) {
|
|
|
11229
11647
|
return ch2.replace(/[\\\]^-]/g, "\\$&");
|
|
11230
11648
|
}
|
|
11231
11649
|
|
|
11650
|
+
// src/table/trivia-gap.ts
|
|
11651
|
+
function skipDeferredTrivia(input, cur, ctx) {
|
|
11652
|
+
const triviaP = ctx.trivia;
|
|
11653
|
+
const plain2 = ctx.trackLines !== true && ctx.captureTrivia !== true;
|
|
11654
|
+
const gap = ctx._gap;
|
|
11655
|
+
if (plain2 && gap !== void 0 && cur === gap.at && input === gap.input && triviaP === gap.of && ctx._rootTriviaCapture === gap.root && ctx.state === gap.state && ctx._rootTriviaKindIndex === gap.rootKinds && ctx._triviaLog === gap.log) return gap.end;
|
|
11656
|
+
const end = clearRunEnd(input, cur, ctx, triviaP, plain2);
|
|
11657
|
+
if (end >= 0) {
|
|
11658
|
+
remember(cur, end, ctx, input, triviaP);
|
|
11659
|
+
return end;
|
|
11660
|
+
}
|
|
11661
|
+
const scan = scanTriviaCompact(input, cur, ctx);
|
|
11662
|
+
if (typeof scan !== "number") return commitTriviaScan(scan);
|
|
11663
|
+
if (plain2) remember(cur, scan, ctx, input, triviaP);
|
|
11664
|
+
return scan;
|
|
11665
|
+
}
|
|
11666
|
+
function clearRunEnd(input, cur, ctx, triviaP, plain2) {
|
|
11667
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
11668
|
+
const spec = triviaP?._meta.labeledTriviaSpec;
|
|
11669
|
+
if (!plain2 || triviaP === void 0 || spec == null || rootKinds === void 0 || ctx._triviaLog !== void 0) return -1;
|
|
11670
|
+
if (spec.rootKinds !== rootKinds) prime(spec, triviaP, rootKinds);
|
|
11671
|
+
const fast = spec.rootScan;
|
|
11672
|
+
if (fast === null) return -1;
|
|
11673
|
+
const end = fast(input, cur);
|
|
11674
|
+
return ctx._rootTriviaCapture === false || clearOf(spec.rootLeaders, input, cur, end) ? end : -1;
|
|
11675
|
+
}
|
|
11676
|
+
function remember(cur, end, ctx, input, triviaP) {
|
|
11677
|
+
const gap = ctx._gap;
|
|
11678
|
+
if (gap === void 0) {
|
|
11679
|
+
ctx._gap = { at: cur, end, input, of: triviaP, root: ctx._rootTriviaCapture, rootKinds: ctx._rootTriviaKindIndex, log: ctx._triviaLog, state: ctx.state };
|
|
11680
|
+
return;
|
|
11681
|
+
}
|
|
11682
|
+
gap.at = cur;
|
|
11683
|
+
gap.end = end;
|
|
11684
|
+
gap.input = input;
|
|
11685
|
+
gap.of = triviaP;
|
|
11686
|
+
gap.root = ctx._rootTriviaCapture;
|
|
11687
|
+
gap.rootKinds = ctx._rootTriviaKindIndex;
|
|
11688
|
+
gap.log = ctx._triviaLog;
|
|
11689
|
+
gap.state = ctx.state;
|
|
11690
|
+
}
|
|
11691
|
+
function prime(spec, triviaP, rootKinds) {
|
|
11692
|
+
const ranges = [];
|
|
11693
|
+
let bounded = true;
|
|
11694
|
+
for (const arm of spec.arms) {
|
|
11695
|
+
if (rootKinds[arm.label] === void 0) continue;
|
|
11696
|
+
const fs = arm.parser._meta.firstSet;
|
|
11697
|
+
if (fs.kind === "any") bounded = false;
|
|
11698
|
+
else if (fs.kind === "ranges") ranges.push(...fs.ranges);
|
|
11699
|
+
}
|
|
11700
|
+
const classified = triviaP._meta.triviaScanner;
|
|
11701
|
+
spec.rootKinds = rootKinds;
|
|
11702
|
+
spec.rootLeaders = ranges;
|
|
11703
|
+
spec.rootScan = !bounded ? null : classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
11704
|
+
}
|
|
11705
|
+
function clearOf(ranges, input, from, to) {
|
|
11706
|
+
for (let i = from; i < to; i++) {
|
|
11707
|
+
const c = input.charCodeAt(i);
|
|
11708
|
+
if (c >= 55296 && c <= 57343) return false;
|
|
11709
|
+
for (const r of ranges) if (c >= r.lo && c <= r.hi) return false;
|
|
11710
|
+
}
|
|
11711
|
+
return true;
|
|
11712
|
+
}
|
|
11713
|
+
|
|
11232
11714
|
// src/table/run-support.ts
|
|
11233
11715
|
function lineCol(ctx, offset) {
|
|
11234
11716
|
const starts = ctx._lineStarts ?? [0];
|
|
@@ -11297,7 +11779,7 @@ function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(pr
|
|
|
11297
11779
|
...prog.labels === void 0 ? {} : { triviaKindLabels: prog.labels },
|
|
11298
11780
|
...prog.classified === 1 ? { rootTriviaClassified: true } : {}
|
|
11299
11781
|
};
|
|
11300
|
-
const
|
|
11782
|
+
const lines2 = prog.lines === 1;
|
|
11301
11783
|
const mode = prog.hostMode ?? "ast";
|
|
11302
11784
|
const elided = mode === "ast" && hasDirectBuilder(prog);
|
|
11303
11785
|
const coverageDefinitions = prog.cov === void 0 ? void 0 : Object.freeze(covDefinitions(prog).map(Object.freeze));
|
|
@@ -11325,7 +11807,7 @@ function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(pr
|
|
|
11325
11807
|
ctx._fe = -1;
|
|
11326
11808
|
ctx._fx = EMPTY_FX;
|
|
11327
11809
|
ctx._fc = false;
|
|
11328
|
-
if (
|
|
11810
|
+
if (lines2 && ctx._lineStarts === void 0) {
|
|
11329
11811
|
ctx._lineStarts = [0];
|
|
11330
11812
|
ctx._lineScannedTo = 0;
|
|
11331
11813
|
}
|
|
@@ -11333,10 +11815,10 @@ function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(pr
|
|
|
11333
11815
|
if (end < 0) {
|
|
11334
11816
|
const fe = ctx._fe;
|
|
11335
11817
|
const at = fe === void 0 || fe < 0 ? pos : fe;
|
|
11336
|
-
const fspan =
|
|
11818
|
+
const fspan = lines2 ? spanLines(ctx, at, at) : { start: at, end: at };
|
|
11337
11819
|
return committed2(ctx) ? { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan, committed: true } : { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan };
|
|
11338
11820
|
}
|
|
11339
|
-
return { ok: true, value: d.lastValue(), span:
|
|
11821
|
+
return { ok: true, value: d.lastValue(), span: lines2 ? spanLines(ctx, pos, end) : { start: pos, end } };
|
|
11340
11822
|
};
|
|
11341
11823
|
const ownTrivia = triviaOfRule(prog.rules[name]);
|
|
11342
11824
|
const meta = ownTrivia === void 0 ? baseMeta : { ...baseMeta, grammarTrivia: ownTrivia };
|
|
@@ -11427,6 +11909,9 @@ function assemble(t2, prog, cfg) {
|
|
|
11427
11909
|
const EC = newEndCell();
|
|
11428
11910
|
const scalarRecognizers = [];
|
|
11429
11911
|
const rawScalarSpecs = /* @__PURE__ */ new Set();
|
|
11912
|
+
function lookaheadClass(child) {
|
|
11913
|
+
return code[child] === OP_GATE && !cfg.tolerant && !cfg.probe ? cc[code[child + 1]] : null;
|
|
11914
|
+
}
|
|
11430
11915
|
function scalarFor(child) {
|
|
11431
11916
|
const spec = code[child + 1];
|
|
11432
11917
|
let recognize = scalarRecognizers[spec];
|
|
@@ -11436,20 +11921,23 @@ function assemble(t2, prog, cfg) {
|
|
|
11436
11921
|
}
|
|
11437
11922
|
return recognize;
|
|
11438
11923
|
}
|
|
11439
|
-
const labelExtraIps =
|
|
11440
|
-
for (const s of prog.scans ?? []) {
|
|
11441
|
-
for (const r of s.skip) labelExtraIps.push(r[0]);
|
|
11442
|
-
if (s.sentinel !== void 0) labelExtraIps.push(s.sentinel[0]);
|
|
11443
|
-
if (s.recoverAt !== void 0) labelExtraIps.push(s.recoverAt[0]);
|
|
11444
|
-
if (s.stopAt !== void 0) labelExtraIps.push(s.stopAt[0]);
|
|
11445
|
-
}
|
|
11446
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
|
|
11924
|
+
const labelExtraIps = assemblyExtraIps(prog);
|
|
11447
11925
|
const closureLabels = computeSiteLabels(
|
|
11448
11926
|
code,
|
|
11449
11927
|
[...Object.values(prog.rules), ...labelExtraIps],
|
|
11450
11928
|
hostCst
|
|
11451
11929
|
);
|
|
11452
11930
|
let SCAN = null;
|
|
11931
|
+
let HYBRID;
|
|
11932
|
+
function hybridPiece(piece) {
|
|
11933
|
+
const setScan = HYBRID.scan;
|
|
11934
|
+
return (input, pos, ctx) => {
|
|
11935
|
+
const saved = setScan(SCAN);
|
|
11936
|
+
const value = piece(input, pos, ctx);
|
|
11937
|
+
setScan(saved);
|
|
11938
|
+
return value;
|
|
11939
|
+
};
|
|
11940
|
+
}
|
|
11453
11941
|
const memo = /* @__PURE__ */ new Map();
|
|
11454
11942
|
const reached = /* @__PURE__ */ new Set();
|
|
11455
11943
|
function pushLeaf(ctx, value, s, e) {
|
|
@@ -11741,9 +12229,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11741
12229
|
return s(input, cur);
|
|
11742
12230
|
}
|
|
11743
12231
|
if (s !== null) return skipTriviaScanned(s, input, cur, ctx);
|
|
11744
|
-
if (needsDeferredTriviaCommit(ctx))
|
|
11745
|
-
return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
11746
|
-
}
|
|
12232
|
+
if (needsDeferredTriviaCommit(ctx)) return skipDeferredTrivia(input, cur, ctx);
|
|
11747
12233
|
return advanceTrivia(input, cur, ctx);
|
|
11748
12234
|
}
|
|
11749
12235
|
let TERMV;
|
|
@@ -11913,7 +12399,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11913
12399
|
if (next !== void 0) {
|
|
11914
12400
|
return next(input, pos, ctx, bits, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
11915
12401
|
}
|
|
11916
|
-
if (best === pos) acc = through(total, prev, acc);
|
|
12402
|
+
if (best === pos && prev !== 0) acc = through(total, prev, acc);
|
|
11917
12403
|
ctx._fe = pos;
|
|
11918
12404
|
ctx._fx = acc ?? choiceFx;
|
|
11919
12405
|
return FAIL;
|
|
@@ -11996,7 +12482,7 @@ function assemble(t2, prog, cfg) {
|
|
|
11996
12482
|
if (next !== void 0) {
|
|
11997
12483
|
return next(input, pos, ctx, c, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
11998
12484
|
}
|
|
11999
|
-
if (best === pos) acc = through(total, prev, acc);
|
|
12485
|
+
if (best === pos && prev !== 0) acc = through(total, prev, acc);
|
|
12000
12486
|
ctx._fe = pos;
|
|
12001
12487
|
ctx._fx = acc ?? choiceFx;
|
|
12002
12488
|
return FAIL;
|
|
@@ -12075,6 +12561,13 @@ function assemble(t2, prog, cfg) {
|
|
|
12075
12561
|
if (done !== void 0) return done;
|
|
12076
12562
|
const flight = inFlight.get(ip);
|
|
12077
12563
|
if (flight !== void 0) return flight.fwd;
|
|
12564
|
+
const selected = HYBRID?.byIp[ip];
|
|
12565
|
+
if (selected !== void 0) {
|
|
12566
|
+
const piece2 = hybridPiece(selected);
|
|
12567
|
+
memo.set(ip, piece2);
|
|
12568
|
+
reached.add(ip);
|
|
12569
|
+
return piece2;
|
|
12570
|
+
}
|
|
12078
12571
|
let target;
|
|
12079
12572
|
const fwd = (input, pos, ctx) => target(input, pos, ctx);
|
|
12080
12573
|
const holder = { fwd, set: (p) => {
|
|
@@ -12082,7 +12575,7 @@ function assemble(t2, prog, cfg) {
|
|
|
12082
12575
|
} };
|
|
12083
12576
|
inFlight.set(ip, holder);
|
|
12084
12577
|
const op = code[ip];
|
|
12085
|
-
const piece = (op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[ip + 3] === 0) && code[ip + 1] >= 0 && closureLabels.at(ip).tri === code[ip + 1] ? link(code[ip + 2]) : lower(ip);
|
|
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);
|
|
12086
12579
|
inFlight.delete(ip);
|
|
12087
12580
|
holder.set(piece);
|
|
12088
12581
|
memo.set(ip, piece);
|
|
@@ -12619,7 +13112,12 @@ function assemble(t2, prog, cfg) {
|
|
|
12619
13112
|
}
|
|
12620
13113
|
const child = link(code[ip + 1]);
|
|
12621
13114
|
const xf = fx[code[ip + 2]];
|
|
13115
|
+
const gate = lookaheadClass(code[ip + 1]);
|
|
12622
13116
|
return (input, pos, ctx) => {
|
|
13117
|
+
if (gate !== null && !classHas2(gate, lead(input, pos))) {
|
|
13118
|
+
EC.e = pos;
|
|
13119
|
+
return null;
|
|
13120
|
+
}
|
|
12623
13121
|
const need = markCst(ctx);
|
|
12624
13122
|
const mRaw = MRAW;
|
|
12625
13123
|
const mTl = MTL;
|
|
@@ -12642,7 +13140,13 @@ function assemble(t2, prog, cfg) {
|
|
|
12642
13140
|
case OP_PEEK: {
|
|
12643
13141
|
const child = link(code[ip + 1]);
|
|
12644
13142
|
const xf = fx[code[ip + 2]];
|
|
13143
|
+
const gate = lookaheadClass(code[ip + 1]);
|
|
12645
13144
|
return (input, pos, ctx) => {
|
|
13145
|
+
if (gate !== null && !classHas2(gate, lead(input, pos))) {
|
|
13146
|
+
ctx._fe = pos;
|
|
13147
|
+
ctx._fx = xf;
|
|
13148
|
+
return FAIL;
|
|
13149
|
+
}
|
|
12646
13150
|
const need = markCst(ctx);
|
|
12647
13151
|
const mRaw = MRAW;
|
|
12648
13152
|
const mTl = MTL;
|
|
@@ -12664,7 +13168,12 @@ function assemble(t2, prog, cfg) {
|
|
|
12664
13168
|
}
|
|
12665
13169
|
case OP_OPT: {
|
|
12666
13170
|
const child = link(code[ip + 1]);
|
|
13171
|
+
const gate = lookaheadClass(code[ip + 1]);
|
|
12667
13172
|
return (input, pos, ctx) => {
|
|
13173
|
+
if (gate !== null && !classHas2(gate, lead(input, pos))) {
|
|
13174
|
+
EC.e = pos;
|
|
13175
|
+
return null;
|
|
13176
|
+
}
|
|
12668
13177
|
const need = markCst(ctx);
|
|
12669
13178
|
const mRaw = MRAW;
|
|
12670
13179
|
const mTl = MTL;
|
|
@@ -13471,6 +13980,11 @@ function assemble(t2, prog, cfg) {
|
|
|
13471
13980
|
}
|
|
13472
13981
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13473
13982
|
}
|
|
13983
|
+
if (prev === 0) {
|
|
13984
|
+
ctx._fe = pos;
|
|
13985
|
+
ctx._fx = choiceFx;
|
|
13986
|
+
return FAIL;
|
|
13987
|
+
}
|
|
13474
13988
|
if (best === pos && prev < 1) acc = accSet(e0, acc);
|
|
13475
13989
|
if (best === pos && prev < 2) acc = accSet(e1, acc);
|
|
13476
13990
|
if (best === pos && n === 3 && prev < 3) acc = accSet(e2, acc);
|
|
@@ -13779,7 +14293,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13779
14293
|
return (input, pos, ctx) => {
|
|
13780
14294
|
if (!pred(ctx.state)) {
|
|
13781
14295
|
ctx._fc = false;
|
|
13782
|
-
ctx._fe =
|
|
14296
|
+
ctx._fe = -1;
|
|
13783
14297
|
ctx._fx = xf;
|
|
13784
14298
|
return FAIL;
|
|
13785
14299
|
}
|
|
@@ -14185,7 +14699,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14185
14699
|
if (v === FAIL) return FAIL;
|
|
14186
14700
|
const end = EC.e;
|
|
14187
14701
|
const span = tracked ? spanLines(ctx, pos, end) : { start: pos, end };
|
|
14188
|
-
const st = readsState
|
|
14702
|
+
const st = readsState ? ctx.state : void 0;
|
|
14189
14703
|
let nd;
|
|
14190
14704
|
if (unwrap && kids.length === 1) {
|
|
14191
14705
|
nd = unwrapChild(kids[0]);
|
|
@@ -14198,10 +14712,10 @@ function assemble(t2, prog, cfg) {
|
|
|
14198
14712
|
) {
|
|
14199
14713
|
nd = kids[0];
|
|
14200
14714
|
} else if (proj >= 0) {
|
|
14201
|
-
nd = hostCst && host !== void 0 ? host(type, kids, fieldMap, span, rawKids, tlog,
|
|
14715
|
+
nd = hostCst && host !== void 0 ? host(type, kids, fieldMap, span, rawKids, tlog, ctx.state, tags) : projectChild(kids, proj, type);
|
|
14202
14716
|
} else if (build !== void 0) {
|
|
14203
14717
|
if (hostCst && host !== void 0) {
|
|
14204
|
-
nd = host(type, kids, fieldMap, span, rawKids, tlog,
|
|
14718
|
+
nd = host(type, kids, fieldMap, span, rawKids, tlog, ctx.state, tags);
|
|
14205
14719
|
} else {
|
|
14206
14720
|
nd = build(kids, fieldMap, span, rawKids, captureWide ? tlog : EMPTY_TL2, st);
|
|
14207
14721
|
}
|
|
@@ -14252,14 +14766,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14252
14766
|
let emitRefusal;
|
|
14253
14767
|
let emitReached;
|
|
14254
14768
|
{
|
|
14255
|
-
const extraIps =
|
|
14256
|
-
for (const s of prog.scans ?? []) {
|
|
14257
|
-
for (const r of s.skip) extraIps.push(r[0]);
|
|
14258
|
-
if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
|
|
14259
|
-
if (s.recoverAt !== void 0) extraIps.push(s.recoverAt[0]);
|
|
14260
|
-
if (s.stopAt !== void 0) extraIps.push(s.stopAt[0]);
|
|
14261
|
-
}
|
|
14262
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
14769
|
+
const extraIps = assemblyExtraIps(prog);
|
|
14263
14770
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
14264
14771
|
for (const ip of reachableSites(code, roots)) {
|
|
14265
14772
|
if (code[ip] === OP_DISPATCH) {
|
|
@@ -14352,9 +14859,11 @@ function assemble(t2, prog, cfg) {
|
|
|
14352
14859
|
adjacencyHolds,
|
|
14353
14860
|
t2.lexPrograms,
|
|
14354
14861
|
LEAD,
|
|
14355
|
-
triviaFieldCapture
|
|
14862
|
+
triviaFieldCapture,
|
|
14863
|
+
skipDeferredTrivia
|
|
14356
14864
|
);
|
|
14357
14865
|
emitReached = new Set(pre.reached);
|
|
14866
|
+
if (emitted.ext !== void 0) HYBRID = emitted;
|
|
14358
14867
|
}
|
|
14359
14868
|
try {
|
|
14360
14869
|
if (emitted !== void 0) throw new ServedByBuild();
|
|
@@ -14436,7 +14945,8 @@ function assemble(t2, prog, cfg) {
|
|
|
14436
14945
|
adjacencyHolds,
|
|
14437
14946
|
t2.lexPrograms,
|
|
14438
14947
|
LEAD,
|
|
14439
|
-
triviaFieldCapture
|
|
14948
|
+
triviaFieldCapture,
|
|
14949
|
+
skipDeferredTrivia
|
|
14440
14950
|
);
|
|
14441
14951
|
emitReached = em.reached;
|
|
14442
14952
|
} catch (e) {
|
|
@@ -14447,7 +14957,7 @@ function assemble(t2, prog, cfg) {
|
|
|
14447
14957
|
}
|
|
14448
14958
|
function pieceAt(ip) {
|
|
14449
14959
|
const em = emitted;
|
|
14450
|
-
if (em !== void 0) {
|
|
14960
|
+
if (em !== void 0 && HYBRID === void 0) {
|
|
14451
14961
|
const p = em.byIp[ip];
|
|
14452
14962
|
if (p === void 0) throw new Error(`table emitter: no emitted body for site ${ip}`);
|
|
14453
14963
|
return p;
|
|
@@ -14455,6 +14965,11 @@ function assemble(t2, prog, cfg) {
|
|
|
14455
14965
|
return link(ip);
|
|
14456
14966
|
}
|
|
14457
14967
|
for (const s of prog.scans ?? []) {
|
|
14968
|
+
const rebuilt = rebuildLineScan(s, subtreeComb);
|
|
14969
|
+
if (rebuilt !== void 0) {
|
|
14970
|
+
scansArr.push(rebuilt);
|
|
14971
|
+
continue;
|
|
14972
|
+
}
|
|
14458
14973
|
const skip = s.skip.map((r) => subtreeComb(r));
|
|
14459
14974
|
const raw = (s.flags & 1) !== 0;
|
|
14460
14975
|
if (s.kind === 1) {
|
|
@@ -14472,6 +14987,37 @@ function assemble(t2, prog, cfg) {
|
|
|
14472
14987
|
}
|
|
14473
14988
|
const scans = scansArr;
|
|
14474
14989
|
const scanSkip = (prog.scanSkip ?? []).map((set) => set.map((r) => subtreeComb(r)));
|
|
14990
|
+
if (HYBRID !== void 0) {
|
|
14991
|
+
const em = HYBRID;
|
|
14992
|
+
em.bind(
|
|
14993
|
+
(s) => {
|
|
14994
|
+
const saved = SCAN;
|
|
14995
|
+
SCAN = s;
|
|
14996
|
+
return saved;
|
|
14997
|
+
},
|
|
14998
|
+
em.ext.map((ip) => link(ip))
|
|
14999
|
+
);
|
|
15000
|
+
const pieces2 = {};
|
|
15001
|
+
for (const [name, entryIp] of Object.entries(prog.rules)) {
|
|
15002
|
+
pieces2[name] = em.pieces[name] ?? link(entryIp);
|
|
15003
|
+
}
|
|
15004
|
+
for (const ip of emitReached) reached.add(ip);
|
|
15005
|
+
return {
|
|
15006
|
+
pieces: pieces2,
|
|
15007
|
+
end: () => EC.e,
|
|
15008
|
+
begin: (ctx) => {
|
|
15009
|
+
begin(ctx);
|
|
15010
|
+
em.begin(ctx);
|
|
15011
|
+
},
|
|
15012
|
+
finish: () => {
|
|
15013
|
+
em.finish();
|
|
15014
|
+
finish();
|
|
15015
|
+
},
|
|
15016
|
+
scanSkip,
|
|
15017
|
+
reached,
|
|
15018
|
+
emitRefusal: void 0
|
|
15019
|
+
};
|
|
15020
|
+
}
|
|
14475
15021
|
if (emitted !== void 0) {
|
|
14476
15022
|
const em = emitted;
|
|
14477
15023
|
return {
|
|
@@ -14507,6 +15053,15 @@ function assemble(t2, prog, cfg) {
|
|
|
14507
15053
|
}
|
|
14508
15054
|
return { pieces, end: () => EC.e, begin, finish, scanSkip, reached, emitRefusal };
|
|
14509
15055
|
}
|
|
15056
|
+
var SITE_COUNTS;
|
|
15057
|
+
function countedPiece(piece, ip) {
|
|
15058
|
+
const counts = SITE_COUNTS;
|
|
15059
|
+
if (counts === void 0) return piece;
|
|
15060
|
+
return (input, pos, ctx) => {
|
|
15061
|
+
counts[ip]++;
|
|
15062
|
+
return piece(input, pos, ctx);
|
|
15063
|
+
};
|
|
15064
|
+
}
|
|
14510
15065
|
var AssemblyCache = class {
|
|
14511
15066
|
t;
|
|
14512
15067
|
prog;
|
|
@@ -14696,6 +15251,11 @@ function emitScanSpec(s) {
|
|
|
14696
15251
|
if (s.sent !== void 0) parts.push(`sent:${s.sent === null ? "null" : jsString(s.sent)}`);
|
|
14697
15252
|
if (s.open !== void 0) parts.push(`open:${jsString(s.open)}`);
|
|
14698
15253
|
if (s.close !== void 0) parts.push(`close:${jsString(s.close)}`);
|
|
15254
|
+
for (const key of ["prefix", "body", "first", "lazy"]) {
|
|
15255
|
+
const r = s[key];
|
|
15256
|
+
if (r !== void 0) parts.push(`${key}:${emitRef(r)}`);
|
|
15257
|
+
}
|
|
15258
|
+
if (s.n !== void 0) parts.push(`n:${s.n}`);
|
|
14699
15259
|
return `{${parts.join(",")}}`;
|
|
14700
15260
|
}
|
|
14701
15261
|
function emitDispatchSpec(d) {
|
|
@@ -14704,14 +15264,7 @@ function emitDispatchSpec(d) {
|
|
|
14704
15264
|
function emitAssemblies(prog, cfgs) {
|
|
14705
15265
|
if (cfgs.length === 0) return ["a:[],"];
|
|
14706
15266
|
const t2 = resolveTable(prog);
|
|
14707
|
-
const extraIps =
|
|
14708
|
-
for (const s of prog.scans ?? []) {
|
|
14709
|
-
for (const r of s.skip) extraIps.push(r[0]);
|
|
14710
|
-
if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
|
|
14711
|
-
if (s.recoverAt !== void 0) extraIps.push(s.recoverAt[0]);
|
|
14712
|
-
if (s.stopAt !== void 0) extraIps.push(s.stopAt[0]);
|
|
14713
|
-
}
|
|
14714
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
15267
|
+
const extraIps = assemblyExtraIps(prog);
|
|
14715
15268
|
const out = [];
|
|
14716
15269
|
const seen = /* @__PURE__ */ new Set();
|
|
14717
15270
|
for (const cfg of cfgs) {
|
|
@@ -14720,7 +15273,7 @@ function emitAssemblies(prog, cfgs) {
|
|
|
14720
15273
|
seen.add(key);
|
|
14721
15274
|
let em;
|
|
14722
15275
|
try {
|
|
14723
|
-
em = emitAssemblySource(t2, prog, cfg, extraIps, true);
|
|
15276
|
+
em = emitAssemblySource(t2, prog, cfg, extraIps, true, cfg.select);
|
|
14724
15277
|
} catch (e) {
|
|
14725
15278
|
if (e instanceof Unemittable) continue;
|
|
14726
15279
|
throw e;
|
|
@@ -14862,6 +15415,8 @@ function children(def, winners) {
|
|
|
14862
15415
|
...def.recoverAt === void 0 ? [] : [def.recoverAt],
|
|
14863
15416
|
...def.stopAt === void 0 ? [] : [def.stopAt]
|
|
14864
15417
|
];
|
|
15418
|
+
case "lines":
|
|
15419
|
+
return [def.prefix, def.body, ...def.first === void 0 ? [] : [def.first], ...def.lazy === void 0 ? [] : [def.lazy]];
|
|
14865
15420
|
case "lazy": {
|
|
14866
15421
|
let resolved;
|
|
14867
15422
|
try {
|
|
@@ -15005,6 +15560,10 @@ function payloadKey(p, d) {
|
|
|
15005
15560
|
return `expect\0${d.label ?? ""}\0${d.expected.join("")}`;
|
|
15006
15561
|
case "scanTo":
|
|
15007
15562
|
return `scanTo\0${d.raw}\0${d.orEOF}\0${d.recoverAt !== void 0}\0${d.stopAt !== void 0}`;
|
|
15563
|
+
case "lines":
|
|
15564
|
+
return `lines\0${d.first !== void 0}\0${d.lazy !== void 0}`;
|
|
15565
|
+
case "columns":
|
|
15566
|
+
return `columns\0${d.n}`;
|
|
15008
15567
|
case "guard":
|
|
15009
15568
|
return `guard\0${fnKey(d.predSrc, d.predicate)}`;
|
|
15010
15569
|
case "adjacency":
|
|
@@ -15125,6 +15684,8 @@ function segment(d, index) {
|
|
|
15125
15684
|
if (d.recoverAt !== void 0 && index === d.skip.length + 1) return "scanTo.recoverAt";
|
|
15126
15685
|
return "scanTo.stopAt";
|
|
15127
15686
|
}
|
|
15687
|
+
case "lines":
|
|
15688
|
+
return ["lines.prefix", "lines.body", d.first === void 0 ? "lines.lazy" : "lines.first", "lines.lazy"][index] ?? "lines";
|
|
15128
15689
|
default:
|
|
15129
15690
|
return d.tag;
|
|
15130
15691
|
}
|
|
@@ -16167,60 +16728,60 @@ function findKeywordRegexes(visited) {
|
|
|
16167
16728
|
var sitesLine = (sites) => sites.slice(0, 6).map(siteToString).join("\n ") + (sites.length > 6 ? `
|
|
16168
16729
|
\u2026 and ${sites.length - 6} more` : "");
|
|
16169
16730
|
function formatDuplicationFindings(report) {
|
|
16170
|
-
const
|
|
16731
|
+
const lines2 = [];
|
|
16171
16732
|
for (const f of report.structureLoss) {
|
|
16172
|
-
|
|
16173
|
-
|
|
16174
|
-
|
|
16175
|
-
|
|
16176
|
-
|
|
16733
|
+
lines2.push(`parseman BUG [structure-loss] @ ${siteToString(f.site)}: arm[${f.earlier}] flattens \`${f.nodeType}\` where arm[${f.later}] structures it, on ${firstSetToString(f.on)}`);
|
|
16734
|
+
lines2.push(` flat: ${f.earlierShape}`);
|
|
16735
|
+
lines2.push(` rich: ${f.laterShape}`);
|
|
16736
|
+
lines2.push(` lost: ${f.lostNodeTypes.map((t2) => `\`${t2}\``).join(", ")}`);
|
|
16737
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16177
16738
|
}
|
|
16178
16739
|
for (const f of report.rewrites) {
|
|
16179
|
-
|
|
16180
|
-
|
|
16181
|
-
|
|
16182
|
-
|
|
16183
|
-
if (f.perf !== "")
|
|
16740
|
+
lines2.push(`parseman ${f.bug ? "BUG" : "rewrite"} [${f.rewrite}${f.sepByVerdict === void 0 ? "" : `/${f.sepByVerdict}`}] @ ${siteToString(f.site)}${f.astNeutral ? "" : " (candidate \u2014 verify AST identity)"}`);
|
|
16741
|
+
lines2.push(` from: ${f.from}`);
|
|
16742
|
+
lines2.push(` to: ${f.to}`);
|
|
16743
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16744
|
+
if (f.perf !== "") lines2.push(` perf: ${f.perf}`);
|
|
16184
16745
|
}
|
|
16185
16746
|
for (const f of report.divergentNodes) {
|
|
16186
|
-
|
|
16187
|
-
for (const p of f.productions)
|
|
16747
|
+
lines2.push(`parseman divergent-node: \`${f.nodeType}\` is built by ${f.count} different productions sharing ${f.sharedTerms.length} term(s): ${f.sharedTerms.map((t2) => `\`${t2}\``).join(", ")}`);
|
|
16748
|
+
for (const p of f.productions) lines2.push(` ${siteToString(p.site)}
|
|
16188
16749
|
${p.shape}
|
|
16189
16750
|
unique to it: ${p.distinctTerms.length === 0 ? "(none)" : p.distinctTerms.map((t2) => `\`${t2}\``).join(", ")}`);
|
|
16190
|
-
|
|
16751
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16191
16752
|
}
|
|
16192
16753
|
for (const f of report.keywordRegexes) {
|
|
16193
16754
|
const src = f.source.length > 90 ? `${f.source.slice(0, 88)}\u2026` : f.source;
|
|
16194
|
-
|
|
16195
|
-
|
|
16755
|
+
lines2.push(`parseman ${f.bug ? "BUG " : ""}keyword-regex @ ${siteToString(f.site)}: /${src}/${f.flags}${f.vocabulary ? ` [${f.words.length} literal words${f.longestFirst ? "" : ", NOT longest-first"}]` : ""}${f.hazards.length > 0 ? ` [${f.hazards.length} prefix hazard(s)${f.bug ? ", UNRESCUED" : ""}]` : ""}${f.caseFoldRisk ? " [CASE-FOLD RISK]" : ""}`);
|
|
16756
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16196
16757
|
}
|
|
16197
16758
|
for (const f of report.duplicates) {
|
|
16198
|
-
|
|
16199
|
-
|
|
16200
|
-
|
|
16759
|
+
lines2.push(`parseman duplication: ${f.count}\xD7 identical ${f.size}-node shape (saves ${f.savings} nodes) \u2014 ${f.shape}`);
|
|
16760
|
+
lines2.push(` at: ${sitesLine(f.sites)}`);
|
|
16761
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16201
16762
|
}
|
|
16202
16763
|
for (const f of report.nearDuplicates) {
|
|
16203
|
-
|
|
16204
|
-
|
|
16205
|
-
|
|
16206
|
-
|
|
16764
|
+
lines2.push(`parseman near-duplication: ${f.count} clones of a ${f.sharedSize}-node shape differing at ONE slot (saves ${f.savings} nodes) \u2014 ${f.shape}`);
|
|
16765
|
+
lines2.push(` slot: ${f.slotPath} \u2208 { ${f.variants.join(" | ")} }`);
|
|
16766
|
+
lines2.push(` at: ${sitesLine(f.sites)}`);
|
|
16767
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16207
16768
|
}
|
|
16208
16769
|
for (const f of report.regexFragments) {
|
|
16209
|
-
|
|
16210
|
-
|
|
16211
|
-
|
|
16770
|
+
lines2.push(`parseman regex-fragment: \`${f.fragment}\` (${f.branches} branches) re-spelled in ${f.count} regex() terminals`);
|
|
16771
|
+
lines2.push(` at: ${sitesLine(f.sites)}`);
|
|
16772
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16212
16773
|
}
|
|
16213
16774
|
for (const f of report.regexClasses) {
|
|
16214
|
-
|
|
16215
|
-
for (const v of f.variants)
|
|
16775
|
+
lines2.push(`parseman regex-class${f.drifted ? " DRIFT" : ""}: [${f.canonical}] across ${f.count} regex() terminals${f.bmpCeiling ? " [BMP ceiling]" : ""}`);
|
|
16776
|
+
for (const v of f.variants) lines2.push(` [${v.source}] \xD7${v.count} ${v.delta}
|
|
16216
16777
|
${sitesLine(v.sites)}`);
|
|
16217
|
-
|
|
16778
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16218
16779
|
}
|
|
16219
16780
|
for (const f of report.overlaps) {
|
|
16220
|
-
|
|
16221
|
-
|
|
16781
|
+
lines2.push(`parseman overlap @ ${siteToString(f.site)}: arm[${f.a}] \u2229 arm[${f.b}] on ${firstSetToString(f.on)}${f.sharedPrefix === null ? "" : ` \u2014 shared prefix: ${f.sharedPrefix}`}${f.handledByStrategy ? " [sharedPrefix strategy already handles this]" : ""}`);
|
|
16782
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16222
16783
|
}
|
|
16223
|
-
return
|
|
16784
|
+
return lines2;
|
|
16224
16785
|
}
|
|
16225
16786
|
function duplicationFindingCount(report) {
|
|
16226
16787
|
return report.duplicates.length + report.nearDuplicates.length + report.regexFragments.length + report.regexClasses.length + report.overlaps.length + report.rewrites.length + report.divergentNodes.length + report.structureLoss.length + report.keywordRegexes.length;
|
|
@@ -16254,11 +16815,11 @@ function reportDuplication(opt, analyze) {
|
|
|
16254
16815
|
);
|
|
16255
16816
|
return void 0;
|
|
16256
16817
|
}
|
|
16257
|
-
const
|
|
16258
|
-
if (
|
|
16818
|
+
const lines2 = formatDuplicationFindings(report);
|
|
16819
|
+
if (lines2.length > 0) {
|
|
16259
16820
|
if (level === "error") throw new Error(`parseman: ${duplicationFindingCount(report)} duplication/overlap finding(s)
|
|
16260
|
-
${
|
|
16261
|
-
for (const l of
|
|
16821
|
+
${lines2.join("\n")}`);
|
|
16822
|
+
for (const l of lines2) console.warn(l);
|
|
16262
16823
|
}
|
|
16263
16824
|
return report;
|
|
16264
16825
|
}
|
|
@@ -16874,7 +17435,7 @@ function cellsOf(line) {
|
|
|
16874
17435
|
}
|
|
16875
17436
|
return cells;
|
|
16876
17437
|
}
|
|
16877
|
-
var plain = (
|
|
17438
|
+
var plain = (lines2) => lines2.map((l) => cellsOf(l).map((c) => c.text).join("")).join("\n");
|
|
16878
17439
|
var CODE_CACHE = /* @__PURE__ */ new Map();
|
|
16879
17440
|
function codesFor(style) {
|
|
16880
17441
|
if (style === void 0) return { pre: "", post: "" };
|
|
@@ -16935,10 +17496,10 @@ function linked(text, path) {
|
|
|
16935
17496
|
const trail = text.slice(body.length);
|
|
16936
17497
|
return `${tpl.pre}${path}${tpl.mid}${body}${tpl.post}${trail}`;
|
|
16937
17498
|
}
|
|
16938
|
-
function render2(
|
|
16939
|
-
if (target.color !== true) return plain(
|
|
17499
|
+
function render2(lines2, target = {}) {
|
|
17500
|
+
if (target.color !== true) return plain(lines2);
|
|
16940
17501
|
const wantLinks = target.links !== false;
|
|
16941
|
-
return
|
|
17502
|
+
return lines2.map((line) => {
|
|
16942
17503
|
if (line.length === 1 && line[0].raw === true) return line[0].text;
|
|
16943
17504
|
return cellsOf(line).map((c) => {
|
|
16944
17505
|
const { pre, post } = codesFor(c.style);
|
|
@@ -17824,9 +18385,11 @@ function attempt(parser2, options) {
|
|
|
17824
18385
|
const mark = saveCstMark(ctx);
|
|
17825
18386
|
const log = ctx._triviaLog?.length;
|
|
17826
18387
|
const rootLog = ctx._rootTriviaLog?.length;
|
|
18388
|
+
const split = ctx._columnsSplit;
|
|
17827
18389
|
const result = parser2.parse(input, pos, ctx);
|
|
17828
18390
|
if (result.ok) return result;
|
|
17829
18391
|
rollbackCstCapture(ctx, mark);
|
|
18392
|
+
ctx._columnsSplit = split;
|
|
17830
18393
|
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
17831
18394
|
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
17832
18395
|
if (result.committed && !contain) return result;
|
|
@@ -17872,7 +18435,9 @@ var FROZEN_TAGS = /* @__PURE__ */ new Set([
|
|
|
17872
18435
|
"withCtx",
|
|
17873
18436
|
"routed",
|
|
17874
18437
|
"trivia",
|
|
17875
|
-
"unknown"
|
|
18438
|
+
"unknown",
|
|
18439
|
+
"lines",
|
|
18440
|
+
"columns"
|
|
17876
18441
|
]);
|
|
17877
18442
|
var CARRIED_META = [
|
|
17878
18443
|
"grammarTrivia",
|
|
@@ -17901,7 +18466,7 @@ function subtreeContains(p, targets) {
|
|
|
17901
18466
|
const kids = [];
|
|
17902
18467
|
if (Array.isArray(rec.parsers)) kids.push(...rec.parsers);
|
|
17903
18468
|
if (Array.isArray(rec.skip)) kids.push(...rec.skip);
|
|
17904
|
-
for (const k of ["parser", "main", "skipped", "separator", "sentinel", "recoverAt", "stopAt", "selector", "otherwise", "fallback", "triviaParser"])
|
|
18469
|
+
for (const k of ["parser", "main", "skipped", "separator", "sentinel", "recoverAt", "stopAt", "selector", "otherwise", "fallback", "triviaParser", "prefix", "body", "first", "lazy"])
|
|
17905
18470
|
if (rec[k]) kids.push(rec[k]);
|
|
17906
18471
|
if (d.tag === "dispatch") {
|
|
17907
18472
|
for (const c2 of d.cases) kids.push(c2.parser);
|
|
@@ -18708,9 +19273,9 @@ function locatedLines(l, opts) {
|
|
|
18708
19273
|
t(l.id, TONE.ident)
|
|
18709
19274
|
]);
|
|
18710
19275
|
out.push([t(" here ", TONE.faint), t(l.site, TONE.quiet)]);
|
|
18711
|
-
const
|
|
18712
|
-
out.push([t(" why ", TONE.quiet), t(
|
|
18713
|
-
for (const x of
|
|
19276
|
+
const lines2 = wrap(`No change can be offered here: ${l.reason}`, width - 12, "");
|
|
19277
|
+
out.push([t(" why ", TONE.quiet), t(lines2[0] ?? "", TONE.warn)]);
|
|
19278
|
+
for (const x of lines2.slice(1)) out.push([t(" "), t(x, TONE.warn)]);
|
|
18714
19279
|
return out;
|
|
18715
19280
|
}
|
|
18716
19281
|
|