parseman 0.50.0 → 0.50.3
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/README.md +14 -10
- package/dist/analysis/diagnostics.js +455 -226
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +445 -191
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/keywords.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/ref.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/repeat.d.ts.map +1 -1
- package/dist/combinators/scalar.d.ts +6 -0
- package/dist/combinators/scalar.d.ts.map +1 -0
- package/dist/combinators/sequence.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +2 -0
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +0 -3
- package/dist/compiler/token-capability.js.map +2 -2
- package/dist/index.js +446 -192
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +68 -172
- package/dist/language-service/index.js.map +3 -3
- package/dist/parse-context.d.ts.map +1 -1
- package/dist/plugin/index.js +491 -306
- package/dist/plugin/index.js.map +3 -3
- package/dist/run/index.js +1 -0
- package/dist/run/index.js.map +1 -1
- package/dist/spec/index.js +399 -277
- package/dist/spec/index.js.map +3 -3
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/index.js +331 -188
- package/dist/table/index.js.map +3 -3
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +4 -2
- package/src/combinators/choice.ts +34 -1
- package/src/combinators/grammar.ts +39 -0
- package/src/combinators/keywords.ts +14 -3
- package/src/combinators/literal.ts +26 -0
- package/src/combinators/map.ts +60 -0
- package/src/combinators/ref.ts +26 -7
- package/src/combinators/regex.ts +23 -0
- package/src/combinators/repeat.ts +109 -16
- package/src/combinators/scalar.ts +30 -0
- package/src/combinators/sequence.ts +76 -161
- package/src/combinators/trivia-skip.ts +14 -1
- package/src/parse-context.ts +1 -0
- package/src/table/emit-assembly.ts +39 -16
- package/src/table/encode.ts +30 -10
- package/src/types.ts +8 -0
- package/src/version.ts +1 -1
|
@@ -615,16 +615,26 @@ function keywords(words, opts = {}) {
|
|
|
615
615
|
caseInsensitive: opts.caseInsensitive ?? false,
|
|
616
616
|
boundary: opts.boundary
|
|
617
617
|
};
|
|
618
|
+
const expected = directTerminalFailureExpected(def);
|
|
619
|
+
const parseScalar = (input, pos, ctx) => {
|
|
620
|
+
re.lastIndex = pos;
|
|
621
|
+
const m = re.exec(input);
|
|
622
|
+
if (m === null) {
|
|
623
|
+
ctx._fx = expected;
|
|
624
|
+
return ~pos;
|
|
625
|
+
}
|
|
626
|
+
ctx._sv = m[0];
|
|
627
|
+
return pos + m[0].length;
|
|
628
|
+
};
|
|
618
629
|
return {
|
|
619
630
|
_tag: "keywords",
|
|
620
631
|
_meta: meta,
|
|
621
632
|
_def: def,
|
|
633
|
+
_parseScalar: parseScalar,
|
|
622
634
|
parse(input, pos, ctx) {
|
|
623
635
|
re.lastIndex = pos;
|
|
624
636
|
const m = re.exec(input);
|
|
625
|
-
if (m === null
|
|
626
|
-
return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
627
|
-
}
|
|
637
|
+
if (m === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
628
638
|
const value = m[0];
|
|
629
639
|
const span = { start: pos, end: pos + value.length };
|
|
630
640
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
@@ -768,6 +778,7 @@ function createParseContext() {
|
|
|
768
778
|
_fe: void 0,
|
|
769
779
|
_fx: void 0,
|
|
770
780
|
_fc: void 0,
|
|
781
|
+
_sv: void 0,
|
|
771
782
|
_probe: void 0,
|
|
772
783
|
_cstChildren: void 0,
|
|
773
784
|
_cstLeaves: void 0,
|
|
@@ -1468,6 +1479,9 @@ var fastScanner3;
|
|
|
1468
1479
|
function needsDeferredTriviaCommit(ctx) {
|
|
1469
1480
|
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
1470
1481
|
}
|
|
1482
|
+
function needsTriviaRollback(ctx) {
|
|
1483
|
+
return ctx._cstBuf !== void 0 || ctx._cstLeaves !== void 0 || ctx._cstRawChildren !== void 0 || ctx._cstTriviaLog !== void 0 || ctx._fields !== void 0 || ctx._errors !== void 0 || ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0;
|
|
1484
|
+
}
|
|
1471
1485
|
function saveTriviaMark(ctx) {
|
|
1472
1486
|
const m = saveCstMark(ctx);
|
|
1473
1487
|
return {
|
|
@@ -1584,7 +1598,8 @@ function advanceTrivia(input, cur, ctx) {
|
|
|
1584
1598
|
const triviaP = ctx.trivia;
|
|
1585
1599
|
if (!triviaP) return cur;
|
|
1586
1600
|
if (!ctx.trackLines) {
|
|
1587
|
-
const
|
|
1601
|
+
const classified = triviaP._meta.triviaScanner;
|
|
1602
|
+
const fast2 = classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
1588
1603
|
if (fast2) return fast2(input, cur);
|
|
1589
1604
|
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
1590
1605
|
const tr2 = triviaP.parse(input, cur, createDetachedParseContext(ctx.trackLines, ctx.state));
|
|
@@ -2151,6 +2166,28 @@ function refuseUnclassifiedRootScope(strict) {
|
|
|
2151
2166
|
if (strict === true) throw new TypeError(ROOT_TRIVIA_SCOPE_REFUSAL);
|
|
2152
2167
|
}
|
|
2153
2168
|
|
|
2169
|
+
// src/combinators/scalar.ts
|
|
2170
|
+
var SCALAR_TAG = /^(?:literal|regex|keywords|sequence|choice|many|oneOrMore|optional|transform|trivia|grammar|sepBy|lazy)$/;
|
|
2171
|
+
function scalarOf(combinator) {
|
|
2172
|
+
return combinator._parseScalar;
|
|
2173
|
+
}
|
|
2174
|
+
function scalarTree(parser2, seen) {
|
|
2175
|
+
if (seen.has(parser2)) return true;
|
|
2176
|
+
if (parser2._parseScalar === void 0) return false;
|
|
2177
|
+
seen.add(parser2);
|
|
2178
|
+
const def = parser2._def;
|
|
2179
|
+
if (!SCALAR_TAG.test(def.tag)) return false;
|
|
2180
|
+
if ("parsers" in def && !def.parsers.every((child) => scalarTree(child, seen))) return false;
|
|
2181
|
+
if ("parser" in def && !scalarTree(def.parser, seen)) return false;
|
|
2182
|
+
if ("separator" in def && !scalarTree(def.separator, seen)) return false;
|
|
2183
|
+
return def.tag !== "lazy" || scalarTree(def.thunk(), seen);
|
|
2184
|
+
}
|
|
2185
|
+
function scalarRootOf(combinator) {
|
|
2186
|
+
const scalar = combinator._parseScalar;
|
|
2187
|
+
const def = combinator._def;
|
|
2188
|
+
return scalar !== void 0 && def.tag === "grammar" && scalarTree(def.parser, /* @__PURE__ */ new Set()) ? scalar : void 0;
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2154
2191
|
// src/combinators/grammar.ts
|
|
2155
2192
|
function annotateResultLines(result, index) {
|
|
2156
2193
|
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
@@ -2187,6 +2224,24 @@ function parser(opts, root) {
|
|
|
2187
2224
|
const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
|
|
2188
2225
|
const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
|
|
2189
2226
|
const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
|
|
2227
|
+
const rootScalar = scalarOf(root);
|
|
2228
|
+
const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
|
|
2229
|
+
const parseScalar = scalarEligible ? (input, pos, ctx) => {
|
|
2230
|
+
const savedTrivia = ctx.trivia;
|
|
2231
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
2232
|
+
if (clearTrivia) {
|
|
2233
|
+
ctx.trivia = void 0;
|
|
2234
|
+
ctx.triviaKindLabels = void 0;
|
|
2235
|
+
} else if (scopeTrivia !== void 0) {
|
|
2236
|
+
ctx.trivia = scopeTrivia;
|
|
2237
|
+
ctx.triviaKindLabels = scopeLabels;
|
|
2238
|
+
}
|
|
2239
|
+
const end = rootScalar(input, pos, ctx);
|
|
2240
|
+
ctx.trivia = savedTrivia;
|
|
2241
|
+
ctx.triviaKindLabels = savedLabels;
|
|
2242
|
+
return end;
|
|
2243
|
+
} : void 0;
|
|
2244
|
+
let publicScalar;
|
|
2190
2245
|
const grammar = {
|
|
2191
2246
|
_tag: "grammar",
|
|
2192
2247
|
_meta: {
|
|
@@ -2210,7 +2265,20 @@ function parser(opts, root) {
|
|
|
2210
2265
|
constructionTrackLines: trackLinesPolicy,
|
|
2211
2266
|
...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
|
|
2212
2267
|
},
|
|
2268
|
+
_parseScalar: parseScalar,
|
|
2213
2269
|
parse(input, pos, _ctx) {
|
|
2270
|
+
if (pos === void 0 && _ctx === void 0) {
|
|
2271
|
+
publicScalar ??= scalarRootOf(grammar) ?? null;
|
|
2272
|
+
if (publicScalar) {
|
|
2273
|
+
const ctx2 = createParseContext();
|
|
2274
|
+
const end = publicScalar(input, 0, ctx2);
|
|
2275
|
+
if (end < 0) {
|
|
2276
|
+
const at = ~end;
|
|
2277
|
+
return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
|
|
2278
|
+
}
|
|
2279
|
+
return { ok: true, value: ctx2._sv, span: { start: 0, end } };
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2214
2282
|
if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
|
|
2215
2283
|
const trackLines = trackLinesOf(_ctx);
|
|
2216
2284
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
@@ -2245,6 +2313,9 @@ function parse(combinator, input, opts = {}) {
|
|
|
2245
2313
|
_analyzed.add(combinator);
|
|
2246
2314
|
markUnusedValues(combinator);
|
|
2247
2315
|
}
|
|
2316
|
+
if (!opts.trackLines && !opts.recover && combinator._def.tag === "grammar" && combinator._meta.grammarScanSkip === void 0) {
|
|
2317
|
+
return combinator.parse(input);
|
|
2318
|
+
}
|
|
2248
2319
|
const trackLines = opts.trackLines ?? combinator._meta.grammarTrackLines ?? false;
|
|
2249
2320
|
const lineContext = trackLines ? createParseLineContext(input, 0) : void 0;
|
|
2250
2321
|
const lineIndex = lineContext?.lineIndex;
|
|
@@ -3410,7 +3481,8 @@ function choice(...args) {
|
|
|
3410
3481
|
disjoint
|
|
3411
3482
|
};
|
|
3412
3483
|
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
3413
|
-
const
|
|
3484
|
+
const ordered = strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix";
|
|
3485
|
+
const autoNot = !disjoint && !hasGates && ordered ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
3414
3486
|
let greedyLitMap = null;
|
|
3415
3487
|
let sortedParsers = null;
|
|
3416
3488
|
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
@@ -3424,6 +3496,37 @@ function choice(...args) {
|
|
|
3424
3496
|
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
3425
3497
|
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
3426
3498
|
}
|
|
3499
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
3500
|
+
const scalarEligible = !hasGates && parsers.every((p) => p._parseScalar !== void 0) && (disjoint || ordered);
|
|
3501
|
+
const scalarExpected = parsers.flatMap(deriveExpected);
|
|
3502
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3503
|
+
if (disjoint) {
|
|
3504
|
+
const code = pos < input.length ? input.codePointAt(pos) : -1;
|
|
3505
|
+
let idx = code >= 0 && code < 128 ? asciiDispatch[code] : -1;
|
|
3506
|
+
if (idx < 0 && code >= 0) {
|
|
3507
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
3508
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
3509
|
+
idx = i;
|
|
3510
|
+
break;
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3513
|
+
}
|
|
3514
|
+
if (idx >= 0) {
|
|
3515
|
+
const gate = gates[idx];
|
|
3516
|
+
if (!gate || gate(ctx.state)) return scalarParsers[idx](input, pos, ctx);
|
|
3517
|
+
ctx._fx = deriveExpected(parsers[idx]);
|
|
3518
|
+
return ~pos;
|
|
3519
|
+
}
|
|
3520
|
+
} else {
|
|
3521
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
3522
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
3523
|
+
const end = scalarParsers[i](input, pos, ctx);
|
|
3524
|
+
if (end >= 0 && (!autoNot[i] || !autoNotFires(input, end, autoNot[i]))) return end;
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3527
|
+
ctx._fx = scalarExpected;
|
|
3528
|
+
return ~pos;
|
|
3529
|
+
};
|
|
3427
3530
|
return {
|
|
3428
3531
|
_tag: "choice",
|
|
3429
3532
|
_meta: meta,
|
|
@@ -3435,6 +3538,7 @@ function choice(...args) {
|
|
|
3435
3538
|
strategy: strategy ?? { tag: "firstMatch" },
|
|
3436
3539
|
autoNot
|
|
3437
3540
|
},
|
|
3541
|
+
_parseScalar: scalarEligible ? parseScalar : void 0,
|
|
3438
3542
|
parse(input, pos, ctx) {
|
|
3439
3543
|
const expected = [];
|
|
3440
3544
|
let expectedAt = pos;
|
|
@@ -4774,8 +4878,8 @@ function buildLexProgramRunner(spec, matchers, classes, expected) {
|
|
|
4774
4878
|
}
|
|
4775
4879
|
|
|
4776
4880
|
// src/combinators/repeat.ts
|
|
4777
|
-
function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
4778
|
-
const mark = saveTriviaMark(ctx);
|
|
4881
|
+
function repItem(combinator, input, cur, ctx, guardable, mandatory, rollbackNeeded) {
|
|
4882
|
+
const mark = rollbackNeeded ? saveTriviaMark(ctx) : void 0;
|
|
4779
4883
|
let pos = cur;
|
|
4780
4884
|
if (ctx.trivia) {
|
|
4781
4885
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -4785,24 +4889,24 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
|
4785
4889
|
}
|
|
4786
4890
|
}
|
|
4787
4891
|
if (pos >= input.length && !mandatory) {
|
|
4788
|
-
rollbackTrivia(ctx, mark);
|
|
4892
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4789
4893
|
return "stop";
|
|
4790
4894
|
}
|
|
4791
4895
|
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
4792
|
-
rollbackTrivia(ctx, mark);
|
|
4896
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4793
4897
|
return "stop";
|
|
4794
4898
|
}
|
|
4795
4899
|
const result = combinator.parse(input, pos, ctx);
|
|
4796
4900
|
if (!result.ok) {
|
|
4797
|
-
rollbackTrivia(ctx, mark);
|
|
4901
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4798
4902
|
if (result.committed) return { fail: result, failPos: pos };
|
|
4799
4903
|
return { fail: result, failPos: pos };
|
|
4800
4904
|
}
|
|
4801
4905
|
if (result.span.end === pos && !mandatory) {
|
|
4802
|
-
rollbackTrivia(ctx, mark);
|
|
4906
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4803
4907
|
return "stop";
|
|
4804
4908
|
}
|
|
4805
|
-
return
|
|
4909
|
+
return result;
|
|
4806
4910
|
}
|
|
4807
4911
|
function resolveBounds(what, opts) {
|
|
4808
4912
|
const min = opts.min ?? 0;
|
|
@@ -4815,6 +4919,21 @@ function resolveBounds(what, opts) {
|
|
|
4815
4919
|
if (max < min) bad(`max (${max}) is less than min (${min}) \u2014 the combinator could never succeed`);
|
|
4816
4920
|
return { min, max };
|
|
4817
4921
|
}
|
|
4922
|
+
function repeatScalarTail(combinator, child, input, cur, ctx, guardable, values, remaining) {
|
|
4923
|
+
while (cur < input.length && remaining > 0) {
|
|
4924
|
+
let itemPos = cur;
|
|
4925
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4926
|
+
if (itemPos >= input.length) break;
|
|
4927
|
+
if (guardable && !startsFirstSet(combinator, input, itemPos)) break;
|
|
4928
|
+
const end = child(input, itemPos, ctx);
|
|
4929
|
+
if (end <= itemPos) break;
|
|
4930
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4931
|
+
cur = end;
|
|
4932
|
+
remaining--;
|
|
4933
|
+
}
|
|
4934
|
+
ctx._sv = values;
|
|
4935
|
+
return cur;
|
|
4936
|
+
}
|
|
4818
4937
|
function many(combinator, opts = {}) {
|
|
4819
4938
|
const { min, max } = resolveBounds("many()", opts);
|
|
4820
4939
|
if (min >= 1) return atLeast(combinator, min, max);
|
|
@@ -4826,17 +4945,21 @@ function many(combinator, opts = {}) {
|
|
|
4826
4945
|
const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max } };
|
|
4827
4946
|
let expected;
|
|
4828
4947
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4948
|
+
const scalarChild = scalarOf(combinator);
|
|
4949
|
+
const parseScalar = (input, pos, ctx) => repeatScalarTail(combinator, scalarChild, input, pos, ctx, guardable, def.valueUnused ? void 0 : [], max);
|
|
4829
4950
|
return {
|
|
4830
4951
|
_tag: "many",
|
|
4831
4952
|
_meta: meta,
|
|
4832
4953
|
_def: def,
|
|
4954
|
+
_parseScalar: parseScalar,
|
|
4833
4955
|
parse(input, pos, ctx) {
|
|
4834
4956
|
const values = def.valueUnused ? void 0 : [];
|
|
4957
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4835
4958
|
let cur = pos;
|
|
4836
4959
|
let count = 0;
|
|
4837
4960
|
while (cur < input.length) {
|
|
4838
4961
|
if (count >= max) break;
|
|
4839
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
4962
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4840
4963
|
if (item === "stop") break;
|
|
4841
4964
|
if ("fail" in item) {
|
|
4842
4965
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -4853,7 +4976,7 @@ function many(combinator, opts = {}) {
|
|
|
4853
4976
|
}
|
|
4854
4977
|
if (values !== void 0) values.push(item.value);
|
|
4855
4978
|
count++;
|
|
4856
|
-
cur = item.end;
|
|
4979
|
+
cur = item.span.end;
|
|
4857
4980
|
}
|
|
4858
4981
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4859
4982
|
}
|
|
@@ -4871,30 +4994,47 @@ function atLeast(combinator, min, max) {
|
|
|
4871
4994
|
const def = { tag: "oneOrMore", parser: combinator, min, ...max === Infinity ? {} : { max } };
|
|
4872
4995
|
let expected;
|
|
4873
4996
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4997
|
+
const scalarChild = scalarOf(combinator);
|
|
4998
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4999
|
+
let cur = scalarChild(input, pos, ctx);
|
|
5000
|
+
if (cur < 0) return cur;
|
|
5001
|
+
const values = def.valueUnused ? void 0 : [ctx._sv];
|
|
5002
|
+
for (let count = 1; count < min; count++) {
|
|
5003
|
+
let itemPos = cur;
|
|
5004
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
5005
|
+
const end = scalarChild(input, itemPos, ctx);
|
|
5006
|
+
if (end < 0) return ~cur;
|
|
5007
|
+
cur = end;
|
|
5008
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
5009
|
+
}
|
|
5010
|
+
return repeatScalarTail(combinator, scalarChild, input, cur, ctx, guardable, values, max - min);
|
|
5011
|
+
};
|
|
4874
5012
|
return {
|
|
4875
5013
|
_tag: "oneOrMore",
|
|
4876
5014
|
_meta: meta,
|
|
4877
5015
|
_def: def,
|
|
5016
|
+
_parseScalar: parseScalar,
|
|
4878
5017
|
parse(input, pos, ctx) {
|
|
4879
5018
|
const first = combinator.parse(input, pos, ctx);
|
|
4880
5019
|
if (!first.ok) return first;
|
|
4881
5020
|
const values = def.valueUnused ? void 0 : [first.value];
|
|
5021
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4882
5022
|
let cur = first.span.end;
|
|
4883
5023
|
let count = 1;
|
|
4884
5024
|
while (count < min) {
|
|
4885
|
-
const item = repItem(combinator, input, cur, ctx, guardable, true);
|
|
5025
|
+
const item = repItem(combinator, input, cur, ctx, guardable, true, rollbackNeeded);
|
|
4886
5026
|
if (item === "stop" || "fail" in item) {
|
|
4887
5027
|
if (item !== "stop" && !item.fail.ok && item.fail.committed) return item.fail;
|
|
4888
5028
|
expected ??= deriveExpected(combinator);
|
|
4889
5029
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: cur, end: cur } };
|
|
4890
5030
|
}
|
|
4891
5031
|
if (values !== void 0) values.push(item.value);
|
|
4892
|
-
cur = item.end;
|
|
5032
|
+
cur = item.span.end;
|
|
4893
5033
|
count++;
|
|
4894
5034
|
}
|
|
4895
5035
|
while (cur < input.length) {
|
|
4896
5036
|
if (count >= max) break;
|
|
4897
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
5037
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4898
5038
|
if (item === "stop") break;
|
|
4899
5039
|
if ("fail" in item) {
|
|
4900
5040
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -4911,7 +5051,7 @@ function atLeast(combinator, min, max) {
|
|
|
4911
5051
|
}
|
|
4912
5052
|
if (values !== void 0) values.push(item.value);
|
|
4913
5053
|
count++;
|
|
4914
|
-
cur = item.end;
|
|
5054
|
+
cur = item.span.end;
|
|
4915
5055
|
}
|
|
4916
5056
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4917
5057
|
}
|
|
@@ -4924,10 +5064,22 @@ function optional(combinator) {
|
|
|
4924
5064
|
isTrivia: false
|
|
4925
5065
|
};
|
|
4926
5066
|
const firstSetSkippable = !matchesEmpty(combinator);
|
|
5067
|
+
const scalarChild = scalarOf(combinator);
|
|
5068
|
+
const parseScalar = (input, pos, ctx) => {
|
|
5069
|
+
if (firstSetSkippable && !startsFirstSet(combinator, input, pos)) {
|
|
5070
|
+
ctx._sv = null;
|
|
5071
|
+
return pos;
|
|
5072
|
+
}
|
|
5073
|
+
const end = scalarChild(input, pos, ctx);
|
|
5074
|
+
if (end >= 0) return end;
|
|
5075
|
+
ctx._sv = null;
|
|
5076
|
+
return pos;
|
|
5077
|
+
};
|
|
4927
5078
|
return {
|
|
4928
5079
|
_tag: "optional",
|
|
4929
5080
|
_meta: meta,
|
|
4930
5081
|
_def: { tag: "optional", parser: combinator },
|
|
5082
|
+
_parseScalar: parseScalar,
|
|
4931
5083
|
parse(input, pos, ctx) {
|
|
4932
5084
|
if (firstSetSkippable && ctx._probe === void 0 && !startsFirstSet(combinator, input, pos)) {
|
|
4933
5085
|
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
@@ -4958,6 +5110,43 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4958
5110
|
expected ??= deriveExpected(combinator);
|
|
4959
5111
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: at, end: at } };
|
|
4960
5112
|
};
|
|
5113
|
+
const scalarExpected = deriveExpected(combinator);
|
|
5114
|
+
const scalarChild = scalarOf(combinator);
|
|
5115
|
+
const scalarSeparator = scalarOf(separator);
|
|
5116
|
+
const parseScalar = (input, pos, ctx) => {
|
|
5117
|
+
let cur = scalarChild(input, pos, ctx);
|
|
5118
|
+
if (cur < 0) {
|
|
5119
|
+
if (min >= 1) {
|
|
5120
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
5121
|
+
return ~pos;
|
|
5122
|
+
}
|
|
5123
|
+
ctx._sv = [];
|
|
5124
|
+
return pos;
|
|
5125
|
+
}
|
|
5126
|
+
const values = [ctx._sv];
|
|
5127
|
+
while (values.length < max && (cur < input.length || values.length < min)) {
|
|
5128
|
+
const beforeSeparator = cur;
|
|
5129
|
+
let separatorPos = cur;
|
|
5130
|
+
if (ctx.trivia) separatorPos = advanceTrivia(input, cur, ctx);
|
|
5131
|
+
const separatorEnd = scalarSeparator(input, separatorPos, ctx);
|
|
5132
|
+
if (separatorEnd < 0) break;
|
|
5133
|
+
let itemPos = separatorEnd;
|
|
5134
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, itemPos, ctx);
|
|
5135
|
+
const itemEnd = scalarChild(input, itemPos, ctx);
|
|
5136
|
+
if (itemEnd < 0) {
|
|
5137
|
+
cur = trailing === "allow" ? separatorEnd : beforeSeparator;
|
|
5138
|
+
break;
|
|
5139
|
+
}
|
|
5140
|
+
values.push(ctx._sv);
|
|
5141
|
+
cur = itemEnd;
|
|
5142
|
+
}
|
|
5143
|
+
if (values.length < min) {
|
|
5144
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
5145
|
+
return ~cur;
|
|
5146
|
+
}
|
|
5147
|
+
ctx._sv = values;
|
|
5148
|
+
return cur;
|
|
5149
|
+
};
|
|
4961
5150
|
return {
|
|
4962
5151
|
_tag: "sepBy",
|
|
4963
5152
|
_meta: meta,
|
|
@@ -4973,6 +5162,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4973
5162
|
// this option surface already; parity is held by test/parity, not by hope.
|
|
4974
5163
|
...keepSeparators ? { keepSeparators: true } : {}
|
|
4975
5164
|
},
|
|
5165
|
+
_parseScalar: keepSeparators ? void 0 : parseScalar,
|
|
4976
5166
|
parse(input, pos, ctx) {
|
|
4977
5167
|
const first = combinator.parse(input, pos, ctx);
|
|
4978
5168
|
const values = [];
|
|
@@ -5050,11 +5240,54 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
5050
5240
|
}
|
|
5051
5241
|
|
|
5052
5242
|
// src/combinators/map.ts
|
|
5243
|
+
var JSON_STRING_BODY = String.raw`(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*`;
|
|
5053
5244
|
function transform(combinator, fn) {
|
|
5245
|
+
const observesSpan = fn.length > 1;
|
|
5246
|
+
const sequenceDef = combinator._def.tag === "sequence" ? combinator._def : void 0;
|
|
5247
|
+
const terms = sequenceDef?.parsers;
|
|
5248
|
+
const inner = terms?.[1];
|
|
5249
|
+
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;
|
|
5250
|
+
const child = scalarOf(combinator);
|
|
5251
|
+
const parseScalar = fused ? (() => {
|
|
5252
|
+
const body = inner._stickyRegex;
|
|
5253
|
+
const tuple = ['"', "", '"'];
|
|
5254
|
+
const expected = [JSON.stringify('"')];
|
|
5255
|
+
return (input, pos, ctx) => {
|
|
5256
|
+
if (ctx.trivia !== void 0) {
|
|
5257
|
+
const end2 = child(input, pos, ctx);
|
|
5258
|
+
if (end2 < 0) return end2;
|
|
5259
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end: end2 }) : fn(ctx._sv);
|
|
5260
|
+
return end2;
|
|
5261
|
+
}
|
|
5262
|
+
if (input.charCodeAt(pos) !== 34) {
|
|
5263
|
+
ctx._fx = expected;
|
|
5264
|
+
return ~pos;
|
|
5265
|
+
}
|
|
5266
|
+
body.lastIndex = pos + 1;
|
|
5267
|
+
const match = body.exec(input);
|
|
5268
|
+
const close = pos + 1 + match[0].length;
|
|
5269
|
+
if (input.charCodeAt(close) !== 34) {
|
|
5270
|
+
ctx._fx = expected;
|
|
5271
|
+
return ~close;
|
|
5272
|
+
}
|
|
5273
|
+
tuple[1] = match[0];
|
|
5274
|
+
const end = close + 1;
|
|
5275
|
+
ctx._sv = observesSpan ? fn(tuple, { start: pos, end }) : fn(tuple);
|
|
5276
|
+
return end;
|
|
5277
|
+
};
|
|
5278
|
+
})() : /* @__PURE__ */ (() => {
|
|
5279
|
+
return (input, pos, ctx) => {
|
|
5280
|
+
const end = child(input, pos, ctx);
|
|
5281
|
+
if (end < 0) return end;
|
|
5282
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end }) : fn(ctx._sv);
|
|
5283
|
+
return end;
|
|
5284
|
+
};
|
|
5285
|
+
})();
|
|
5054
5286
|
return {
|
|
5055
5287
|
_tag: "transform",
|
|
5056
5288
|
_meta: combinator._meta,
|
|
5057
5289
|
_def: { tag: "transform", parser: combinator, fn },
|
|
5290
|
+
_parseScalar: parseScalar,
|
|
5058
5291
|
parse(input, pos, ctx) {
|
|
5059
5292
|
const result = combinator.parse(input, pos, ctx);
|
|
5060
5293
|
if (!result.ok) return result;
|
|
@@ -5069,9 +5302,11 @@ function trivia(combinator) {
|
|
|
5069
5302
|
_meta: {
|
|
5070
5303
|
...combinator._meta,
|
|
5071
5304
|
isTrivia: true,
|
|
5305
|
+
triviaScanner: fastTriviaScanner(combinator),
|
|
5072
5306
|
...kindLabels ? { triviaKindLabels: kindLabels } : {}
|
|
5073
5307
|
},
|
|
5074
5308
|
_def: { tag: "trivia", parser: combinator },
|
|
5309
|
+
_parseScalar: scalarOf(combinator),
|
|
5075
5310
|
parse: combinator.parse.bind(combinator)
|
|
5076
5311
|
};
|
|
5077
5312
|
}
|
|
@@ -5192,10 +5427,32 @@ function regex(pattern, flags = "") {
|
|
|
5192
5427
|
const canMatchNewline = raw.canMatchNewline;
|
|
5193
5428
|
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
5194
5429
|
const def = { tag: "regex", source, flags: resolvedFlags };
|
|
5430
|
+
const expected = directTerminalFailureExpected(def);
|
|
5431
|
+
const parseScalar = (input, pos, ctx) => {
|
|
5432
|
+
const scanEnd = scan?.(input, pos);
|
|
5433
|
+
if (scanEnd !== void 0) {
|
|
5434
|
+
if (scanEnd === null) {
|
|
5435
|
+
ctx._fx = expected;
|
|
5436
|
+
return ~pos;
|
|
5437
|
+
}
|
|
5438
|
+
ctx._sv = input.slice(pos, scanEnd);
|
|
5439
|
+
return scanEnd;
|
|
5440
|
+
}
|
|
5441
|
+
anchored.lastIndex = pos;
|
|
5442
|
+
const match = anchored.exec(input);
|
|
5443
|
+
if (match === null) {
|
|
5444
|
+
ctx._fx = expected;
|
|
5445
|
+
return ~pos;
|
|
5446
|
+
}
|
|
5447
|
+
ctx._sv = match[0];
|
|
5448
|
+
return pos + match[0].length;
|
|
5449
|
+
};
|
|
5195
5450
|
return {
|
|
5196
5451
|
_tag: "regex",
|
|
5197
5452
|
_meta: meta,
|
|
5198
5453
|
_def: def,
|
|
5454
|
+
_stickyRegex: anchored,
|
|
5455
|
+
_parseScalar: parseScalar,
|
|
5199
5456
|
parse(input, pos, ctx) {
|
|
5200
5457
|
const scanEnd = scan?.(input, pos);
|
|
5201
5458
|
if (scanEnd !== void 0) {
|
|
@@ -5884,6 +6141,22 @@ var Encoder = class {
|
|
|
5884
6141
|
choiceRollbackMasks = /* @__PURE__ */ new Map();
|
|
5885
6142
|
nonCommittingChoiceSites = /* @__PURE__ */ new Set();
|
|
5886
6143
|
failureRollbackCleanSites = /* @__PURE__ */ new Set();
|
|
6144
|
+
/**
|
|
6145
|
+
* `hasSideWriter` memo for `failureNeedsRollback`, shared across every call
|
|
6146
|
+
* for the lifetime of this `Encoder`. A cached entry is written only when
|
|
6147
|
+
* `complete` is true, which means the answer is a path-independent fact
|
|
6148
|
+
* about that combinator node — it does not depend on which root's traversal
|
|
6149
|
+
* asked, only on the node's own reachable subgraph. Scoping the memo per call
|
|
6150
|
+
* (as a local inside `failureNeedsRollback`) was correct but discarded that
|
|
6151
|
+
* fact after every arm, so a grammar with many ordered-choice arms / optional
|
|
6152
|
+
* / attempt sites re-walked the SAME shared rule graph from scratch for each
|
|
6153
|
+
* site — O(sites × graph size) instead of O(graph size). Measured on the
|
|
6154
|
+
* scss-parser grammar (composed CSS-base superset, the deepest/largest of the
|
|
6155
|
+
* four grammars): 47-50s for one `compileRuleMap` with the per-call memo,
|
|
6156
|
+
* versus the whole macro transform completing in under a second once this
|
|
6157
|
+
* memo is hoisted here.
|
|
6158
|
+
*/
|
|
6159
|
+
sideWriterMemo = /* @__PURE__ */ new Map();
|
|
5887
6160
|
labels = void 0;
|
|
5888
6161
|
/** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
|
|
5889
6162
|
activeTrivia = void 0;
|
|
@@ -6309,13 +6582,13 @@ var Encoder = class {
|
|
|
6309
6582
|
const refName = p._ruleName;
|
|
6310
6583
|
const winner = refName === void 0 ? void 0 : this.winners?.[refName];
|
|
6311
6584
|
const root = winner !== void 0 && !winnerWrapsReference2(winner, p) ? winner : p;
|
|
6312
|
-
const sideWriterMemo =
|
|
6313
|
-
const
|
|
6585
|
+
const sideWriterMemo = this.sideWriterMemo;
|
|
6586
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6587
|
+
const hasSideWriter = (current) => {
|
|
6314
6588
|
const cached = sideWriterMemo.get(current);
|
|
6315
6589
|
if (cached !== void 0) return { found: cached, complete: true };
|
|
6316
6590
|
if (seen.has(current)) return { found: false, complete: false };
|
|
6317
|
-
|
|
6318
|
-
next.add(current);
|
|
6591
|
+
seen.add(current);
|
|
6319
6592
|
const def = current._def;
|
|
6320
6593
|
let result;
|
|
6321
6594
|
switch (def.tag) {
|
|
@@ -6330,11 +6603,11 @@ var Encoder = class {
|
|
|
6330
6603
|
const name = current._ruleName;
|
|
6331
6604
|
const resolvedWinner = name === void 0 ? void 0 : this.winners?.[name];
|
|
6332
6605
|
if (resolvedWinner !== void 0 && !winnerWrapsReference2(resolvedWinner, current)) {
|
|
6333
|
-
result = hasSideWriter(resolvedWinner
|
|
6606
|
+
result = hasSideWriter(resolvedWinner);
|
|
6334
6607
|
break;
|
|
6335
6608
|
}
|
|
6336
6609
|
try {
|
|
6337
|
-
result = hasSideWriter(def.thunk()
|
|
6610
|
+
result = hasSideWriter(def.thunk());
|
|
6338
6611
|
} catch {
|
|
6339
6612
|
result = { found: true, complete: true };
|
|
6340
6613
|
}
|
|
@@ -6344,7 +6617,7 @@ var Encoder = class {
|
|
|
6344
6617
|
let complete = true;
|
|
6345
6618
|
result = { found: false, complete: true };
|
|
6346
6619
|
for (const child of childrenOf(def)) {
|
|
6347
|
-
const childResult = hasSideWriter(child
|
|
6620
|
+
const childResult = hasSideWriter(child);
|
|
6348
6621
|
if (childResult.found) {
|
|
6349
6622
|
result = { found: true, complete: true };
|
|
6350
6623
|
break;
|
|
@@ -6354,6 +6627,7 @@ var Encoder = class {
|
|
|
6354
6627
|
if (!result.found) result = { found: false, complete };
|
|
6355
6628
|
}
|
|
6356
6629
|
}
|
|
6630
|
+
seen.delete(current);
|
|
6357
6631
|
if (result.found || result.complete) sideWriterMemo.set(current, result.found);
|
|
6358
6632
|
return result;
|
|
6359
6633
|
};
|
|
@@ -6788,7 +7062,7 @@ var Encoder = class {
|
|
|
6788
7062
|
const dispCovIds = this.plan?.dispatches.get(p);
|
|
6789
7063
|
let dispCov = 0;
|
|
6790
7064
|
const arms = [];
|
|
6791
|
-
const
|
|
7065
|
+
const routed = [];
|
|
6792
7066
|
const key = [], keyArm = [];
|
|
6793
7067
|
const fold = [], foldArm = [];
|
|
6794
7068
|
const match = [];
|
|
@@ -6796,7 +7070,7 @@ var Encoder = class {
|
|
|
6796
7070
|
for (const c of d.cases) {
|
|
6797
7071
|
const arm = arms.length;
|
|
6798
7072
|
arms.push(this.covWrap(this.node(c.parser).ip, dispCovIds?.[dispCov++], 1));
|
|
6799
|
-
|
|
7073
|
+
routed.push(branchUsesRouted(c) ? 1 : 0);
|
|
6800
7074
|
for (const kk of c.keys) {
|
|
6801
7075
|
expected.push(JSON.stringify(kk));
|
|
6802
7076
|
if (c.caseInsensitive) {
|
|
@@ -6812,7 +7086,7 @@ var Encoder = class {
|
|
|
6812
7086
|
for (const m of d.matchers ?? []) {
|
|
6813
7087
|
const arm = arms.length;
|
|
6814
7088
|
arms.push(this.covWrap(this.node(m.parser).ip, dispCovIds?.[dispCov++], 1));
|
|
6815
|
-
|
|
7089
|
+
routed.push(branchUsesRouted(m) ? 1 : 0);
|
|
6816
7090
|
if (!m.caseInsensitive) {
|
|
6817
7091
|
match.push([KIND[m.kind], m.value, m.flags ?? "", arm]);
|
|
6818
7092
|
continue;
|
|
@@ -6826,7 +7100,7 @@ var Encoder = class {
|
|
|
6826
7100
|
}
|
|
6827
7101
|
const other = d.otherwise === void 0 ? -1 : this.covWrap(this.node(d.otherwise).ip, dispCovIds?.[dispCov++], 1);
|
|
6828
7102
|
const dspIdx = this.dsp.length;
|
|
6829
|
-
this.dsp.push({ key, keyArm, fold, foldArm, match, routed
|
|
7103
|
+
this.dsp.push({ key, keyArm, fold, foldArm, match, routed, expected });
|
|
6830
7104
|
const head = this.emitHead(OP_DISPATCH, 5 + arms.length);
|
|
6831
7105
|
this.code[head + 1] = sel;
|
|
6832
7106
|
this.code[head + 2] = dspIdx;
|
|
@@ -8698,6 +8972,9 @@ if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTrivi
|
|
|
8698
8972
|
function q(s) {
|
|
8699
8973
|
return JSON.stringify(s);
|
|
8700
8974
|
}
|
|
8975
|
+
function isAsciiOnlyClass(cls) {
|
|
8976
|
+
return cls !== null && cls !== void 0 && cls.hi.length === 0;
|
|
8977
|
+
}
|
|
8701
8978
|
var NO_SINKS = { fd: false, er: false };
|
|
8702
8979
|
function sinkSlots(t2, s) {
|
|
8703
8980
|
return `${s.fd ? `,${t2}fd=0` : ""}${s.er ? `,${t2}er=0` : ""}`;
|
|
@@ -9244,12 +9521,13 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
9244
9521
|
return `${head}EC.e=pos;return ''}`;
|
|
9245
9522
|
case OP_GATE: {
|
|
9246
9523
|
const child = link(code[ip + 2]);
|
|
9247
|
-
const
|
|
9524
|
+
const resolved = t2.cc[code[ip + 1]];
|
|
9525
|
+
const ci = classes.push([resolved]) - 1;
|
|
9248
9526
|
classPlan.push([code[ip + 1]]);
|
|
9249
9527
|
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
9250
9528
|
const xf = fxRef(code[ip + 3]);
|
|
9251
9529
|
return `${head}
|
|
9252
|
-
if(
|
|
9530
|
+
if(${staticBuild && isAsciiOnlyClass(resolved) ? `${cls}.ascii[input.charCodeAt(pos)]!==1` : `!classHas(${cls},lead(input,pos))`}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
9253
9531
|
return ${child}(input,pos,ctx)
|
|
9254
9532
|
}`;
|
|
9255
9533
|
}
|
|
@@ -9592,10 +9870,11 @@ return v
|
|
|
9592
9870
|
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
9593
9871
|
const hiArr = table.hi;
|
|
9594
9872
|
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
9873
|
+
const directAscii = staticBuild && table.hi.length === 0;
|
|
9595
9874
|
return `${head}
|
|
9596
|
-
const c
|
|
9875
|
+
const c=${directAscii ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
9597
9876
|
let arm=-1
|
|
9598
|
-
if(c>=0&&c<128){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
9877
|
+
if(${directAscii ? "c<128" : "c>=0&&c<128"}){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
9599
9878
|
${hiArr.length === 0 ? "" : `else if(c>=128){const h=${hoist("hi", `DISP[${di}].hi`)}
|
|
9600
9879
|
for(let i=0;i<h.length;i+=3){if(c>=h[i]&&c<=h[i+1]){arm=h[i+2];break}}}`}
|
|
9601
9880
|
if(arm>=0){
|
|
@@ -9617,7 +9896,9 @@ return FAIL
|
|
|
9617
9896
|
const di = code[ip + 1];
|
|
9618
9897
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
9619
9898
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
9620
|
-
const
|
|
9899
|
+
const maskable = n <= 32;
|
|
9900
|
+
const directAsciiMask = staticBuild && maskable && gates.every(isAsciiOnlyClass);
|
|
9901
|
+
const gateRefs = directAsciiMask ? [] : Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
9621
9902
|
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
9622
9903
|
const pretests = Array.from({ length: n }, (_, i) => {
|
|
9623
9904
|
if (tokenCandidate?.arm === i) {
|
|
@@ -9637,7 +9918,6 @@ return FAIL
|
|
|
9637
9918
|
const sequence6 = largeChoiceScalarSequences.get(code[base + i]);
|
|
9638
9919
|
return sequence6 === void 0 ? void 0 : { sequence: scalarSequenceRef(sequence6) };
|
|
9639
9920
|
});
|
|
9640
|
-
const maskable = n <= 32;
|
|
9641
9921
|
const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
|
|
9642
9922
|
if (maskable) maskPlan.push(~di);
|
|
9643
9923
|
const p = tmp();
|
|
@@ -9699,16 +9979,16 @@ ${merge}
|
|
|
9699
9979
|
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
9700
9980
|
return FAIL`;
|
|
9701
9981
|
return `${head}
|
|
9702
|
-
const c
|
|
9982
|
+
const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
9703
9983
|
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
9704
9984
|
${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
|
|
9705
9985
|
${maskable ? `if(c<128){
|
|
9706
|
-
const bits=${maskName}[c<0?128:c]
|
|
9986
|
+
const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
9707
9987
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
9708
9988
|
${lazyArms(true)}
|
|
9709
|
-
}else{
|
|
9989
|
+
}${directAsciiMask ? "" : `else{
|
|
9710
9990
|
${lazyArms(false)}
|
|
9711
|
-
}
|
|
9991
|
+
}`}
|
|
9712
9992
|
` : lazyArms(false)}
|
|
9713
9993
|
${finish}
|
|
9714
9994
|
}`;
|
|
@@ -9759,7 +10039,7 @@ if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0
|
|
|
9759
10039
|
${rollbackFor(i)}
|
|
9760
10040
|
}${routeMiss}${sequenceMiss}`;
|
|
9761
10041
|
}).join("\n") : "";
|
|
9762
|
-
const generalArms = arms.map((arm, i) => {
|
|
10042
|
+
const generalArms = directAsciiMask ? "" : arms.map((arm, i) => {
|
|
9763
10043
|
const pretest = pretests[i];
|
|
9764
10044
|
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
9765
10045
|
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
@@ -9789,12 +10069,12 @@ ${rollbackFor(i)}
|
|
|
9789
10069
|
}${miss}`;
|
|
9790
10070
|
}).join("\n");
|
|
9791
10071
|
return `${head}
|
|
9792
|
-
const c
|
|
10072
|
+
const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
9793
10073
|
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
9794
10074
|
let acc
|
|
9795
10075
|
let best=pos
|
|
9796
10076
|
${maskable ? `if(c<128){
|
|
9797
|
-
const bits=${maskName}[c<0?128:c]
|
|
10077
|
+
const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
9798
10078
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
9799
10079
|
${startFailureExact ? "" : "let prev=0"}
|
|
9800
10080
|
${maskArms}
|
|
@@ -9889,14 +10169,18 @@ return [key,v]
|
|
|
9889
10169
|
const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
|
|
9890
10170
|
const collect = op === OP_REP;
|
|
9891
10171
|
let itemCls;
|
|
10172
|
+
let itemAscii = false;
|
|
9892
10173
|
if (!REC) {
|
|
9893
10174
|
const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
|
|
9894
10175
|
if (itemClassIndex >= 0) {
|
|
9895
|
-
const
|
|
10176
|
+
const resolved = t2.cc[itemClassIndex];
|
|
10177
|
+
const ci = classes.push([resolved]) - 1;
|
|
9896
10178
|
classPlan.push([itemClassIndex]);
|
|
9897
10179
|
itemCls = hoist("ri", `CLS[${ci}][0]`);
|
|
10180
|
+
itemAscii = staticBuild && isAsciiOnlyClass(resolved);
|
|
9898
10181
|
}
|
|
9899
10182
|
}
|
|
10183
|
+
const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
|
|
9900
10184
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
9901
10185
|
const p = tmp();
|
|
9902
10186
|
const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
|
|
@@ -9956,7 +10240,7 @@ let count=0
|
|
|
9956
10240
|
for(;;){
|
|
9957
10241
|
${max >= 0 ? `if(count>=${max})break
|
|
9958
10242
|
` : ""}${sep !== void 0 ? `if(count>0&&count>=${min}&&cur>=input.length)break
|
|
9959
|
-
` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}
|
|
10243
|
+
` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}&&${itemMiss("cur")})break
|
|
9960
10244
|
` : ""}let ${p}raw=0,${p}tl=0,${p}lv=0,${p}lg=0,${p}rt=0${sinks.fd ? `,${p}fd=0` : ""}${sinks.er ? `,${p}er=0` : ""}
|
|
9961
10245
|
${markBody}
|
|
9962
10246
|
let itemStart=cur
|
|
@@ -9981,7 +10265,7 @@ itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(inp
|
|
|
9981
10265
|
${rb}
|
|
9982
10266
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
9983
10267
|
}
|
|
9984
|
-
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate
|
|
10268
|
+
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&${itemMiss("itemStart")}){
|
|
9985
10269
|
${rb}
|
|
9986
10270
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
9987
10271
|
}
|
|
@@ -10265,6 +10549,28 @@ function literal(value, opts = {}) {
|
|
|
10265
10549
|
isTrivia: false
|
|
10266
10550
|
};
|
|
10267
10551
|
const canMatchNewline = meta.canMatchNewline;
|
|
10552
|
+
const parseScalar = !caseInsensitive && value.length === 1 ? (() => {
|
|
10553
|
+
const code = value.charCodeAt(0);
|
|
10554
|
+
return (input, pos, ctx) => {
|
|
10555
|
+
if (input.charCodeAt(pos) === code) {
|
|
10556
|
+
ctx._sv = value;
|
|
10557
|
+
return pos + 1;
|
|
10558
|
+
}
|
|
10559
|
+
ctx._fx = expected;
|
|
10560
|
+
return ~pos;
|
|
10561
|
+
};
|
|
10562
|
+
})() : (input, pos, ctx) => {
|
|
10563
|
+
const end = pos + value.length;
|
|
10564
|
+
if (end <= input.length) {
|
|
10565
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
10566
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
10567
|
+
ctx._sv = matchedValue;
|
|
10568
|
+
return end;
|
|
10569
|
+
}
|
|
10570
|
+
}
|
|
10571
|
+
ctx._fx = expected;
|
|
10572
|
+
return ~pos;
|
|
10573
|
+
};
|
|
10268
10574
|
if (caseInsensitive) {
|
|
10269
10575
|
const upper = value.toUpperCase();
|
|
10270
10576
|
const lower = value.toLowerCase();
|
|
@@ -10305,6 +10611,7 @@ function literal(value, opts = {}) {
|
|
|
10305
10611
|
_tag: "literal",
|
|
10306
10612
|
_meta: meta,
|
|
10307
10613
|
_def: { tag: "literal", value, caseInsensitive },
|
|
10614
|
+
_parseScalar: parseScalar,
|
|
10308
10615
|
parse: parse2
|
|
10309
10616
|
};
|
|
10310
10617
|
}
|
|
@@ -10324,6 +10631,7 @@ function sequence(...parsers) {
|
|
|
10324
10631
|
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
10325
10632
|
}
|
|
10326
10633
|
const hasAdjacency = adjacency !== null;
|
|
10634
|
+
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
10327
10635
|
const meta = {
|
|
10328
10636
|
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
10329
10637
|
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
@@ -10332,165 +10640,96 @@ function sequence(...parsers) {
|
|
|
10332
10640
|
isTrivia: false
|
|
10333
10641
|
};
|
|
10334
10642
|
const def = { tag: "sequence", parsers };
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
10338
|
-
const fs = parsers.slice(i + 1).reduce(
|
|
10339
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
10340
|
-
{ kind: "empty" }
|
|
10341
|
-
);
|
|
10342
|
-
return firstSetSentinel(fs);
|
|
10343
|
-
});
|
|
10344
|
-
const values = def.valueUnused ? void 0 : [];
|
|
10643
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
10644
|
+
const parseScalar = (input, pos, ctx) => {
|
|
10345
10645
|
let cur = pos;
|
|
10346
|
-
|
|
10347
|
-
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
|
|
10355
|
-
|
|
10356
|
-
|
|
10357
|
-
const mTlog = cstTlLen(ctx);
|
|
10358
|
-
const mLog = ctx._triviaLog?.length ?? 0;
|
|
10359
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
10360
|
-
let scanEnd;
|
|
10361
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
10362
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
10363
|
-
} else {
|
|
10364
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
10365
|
-
}
|
|
10366
|
-
const scanTlog = cstTlLen(ctx);
|
|
10367
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
10368
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
10369
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
10370
|
-
if (!result2.ok) return result2;
|
|
10371
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
10372
|
-
else rollbackScannedTriviaAt(
|
|
10373
|
-
ctx,
|
|
10374
|
-
mTlog,
|
|
10375
|
-
scanTlog,
|
|
10376
|
-
mLog,
|
|
10377
|
-
scanLog,
|
|
10378
|
-
mRootLog,
|
|
10379
|
-
scanRootLog
|
|
10380
|
-
);
|
|
10381
|
-
if (values !== void 0) values.push(result2.value);
|
|
10382
|
-
continue;
|
|
10383
|
-
}
|
|
10384
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
10385
|
-
if (!result.ok) return result;
|
|
10386
|
-
if (values !== void 0) values.push(result.value);
|
|
10387
|
-
cur = result.span.end;
|
|
10646
|
+
if (strictArity !== 0) {
|
|
10647
|
+
cur = scalarParsers[0](input, cur, ctx);
|
|
10648
|
+
if (cur < 0) return cur;
|
|
10649
|
+
const first = ctx._sv;
|
|
10650
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
10651
|
+
cur = scalarParsers[1](input, cur, ctx);
|
|
10652
|
+
if (cur < 0) return cur;
|
|
10653
|
+
const second = ctx._sv;
|
|
10654
|
+
if (strictArity === 2) {
|
|
10655
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second];
|
|
10656
|
+
return cur;
|
|
10388
10657
|
}
|
|
10389
|
-
|
|
10390
|
-
|
|
10658
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
10659
|
+
cur = scalarParsers[2](input, cur, ctx);
|
|
10660
|
+
if (cur < 0) return cur;
|
|
10661
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second, ctx._sv];
|
|
10662
|
+
return cur;
|
|
10391
10663
|
}
|
|
10392
|
-
return {
|
|
10393
|
-
ok: true,
|
|
10394
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
10395
|
-
value: values ?? void 0,
|
|
10396
|
-
span: { start: pos, end: cur }
|
|
10397
|
-
};
|
|
10398
|
-
}
|
|
10399
|
-
function parseAdjacent(input, pos, ctx) {
|
|
10400
10664
|
const values = def.valueUnused ? void 0 : [];
|
|
10401
|
-
let
|
|
10402
|
-
|
|
10403
|
-
|
|
10404
|
-
|
|
10405
|
-
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10409
|
-
|
|
10410
|
-
|
|
10411
|
-
|
|
10412
|
-
|
|
10413
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
10414
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
10415
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
10416
|
-
} else {
|
|
10417
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
10418
|
-
}
|
|
10419
|
-
const scanTlog = cstTlLen(ctx);
|
|
10420
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
10421
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
10422
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
10423
|
-
if (!result2.ok) return result2;
|
|
10424
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
10425
|
-
else rollbackScannedTriviaAt(
|
|
10426
|
-
ctx,
|
|
10427
|
-
mTlog,
|
|
10428
|
-
scanTlog,
|
|
10429
|
-
mLog,
|
|
10430
|
-
scanLog,
|
|
10431
|
-
mRootLog,
|
|
10432
|
-
scanRootLog
|
|
10433
|
-
);
|
|
10434
|
-
if (values !== void 0) values.push(result2.value);
|
|
10435
|
-
continue;
|
|
10436
|
-
}
|
|
10437
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
10438
|
-
if (!result.ok) return result;
|
|
10439
|
-
if (values !== void 0) values.push(result.value);
|
|
10440
|
-
cur = result.span.end;
|
|
10441
|
-
}
|
|
10442
|
-
return {
|
|
10443
|
-
ok: true,
|
|
10444
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
10445
|
-
value: values ?? void 0,
|
|
10446
|
-
span: { start: pos, end: cur }
|
|
10447
|
-
};
|
|
10448
|
-
}
|
|
10665
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
10666
|
+
let termPos = cur;
|
|
10667
|
+
if (i > 0 && ctx.trivia) termPos = advanceTrivia(input, cur, ctx);
|
|
10668
|
+
const end = scalarParsers[i](input, termPos, ctx);
|
|
10669
|
+
if (end < 0) return end;
|
|
10670
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
10671
|
+
if (end > termPos || termPos === cur) cur = end;
|
|
10672
|
+
}
|
|
10673
|
+
ctx._sv = values;
|
|
10674
|
+
return cur;
|
|
10675
|
+
};
|
|
10676
|
+
let followSentinels;
|
|
10449
10677
|
return {
|
|
10450
10678
|
_tag: "sequence",
|
|
10451
10679
|
_meta: meta,
|
|
10452
10680
|
_def: def,
|
|
10681
|
+
_parseScalar: hasAdjacency ? void 0 : parseScalar,
|
|
10453
10682
|
parse(input, pos, ctx) {
|
|
10454
|
-
|
|
10455
|
-
if (
|
|
10683
|
+
const tolerant = ctx._tolerant === true;
|
|
10684
|
+
if (tolerant) {
|
|
10685
|
+
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
10686
|
+
parsers.slice(i + 1).reduce(
|
|
10687
|
+
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
10688
|
+
{ kind: "empty" }
|
|
10689
|
+
)
|
|
10690
|
+
));
|
|
10691
|
+
}
|
|
10692
|
+
const inheritedSync = ctx._sync;
|
|
10693
|
+
const deferredTrivia = needsDeferredTriviaCommit(ctx);
|
|
10456
10694
|
const values = def.valueUnused ? void 0 : [];
|
|
10457
10695
|
let cur = pos;
|
|
10458
|
-
|
|
10459
|
-
|
|
10460
|
-
|
|
10461
|
-
const
|
|
10462
|
-
|
|
10463
|
-
|
|
10464
|
-
|
|
10465
|
-
|
|
10466
|
-
} else {
|
|
10467
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
10696
|
+
try {
|
|
10697
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
10698
|
+
if (tolerant) ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
10699
|
+
const assertion = adjacency?.[i];
|
|
10700
|
+
if (assertion) {
|
|
10701
|
+
if (!holdsAdjacency(input, cur, ctx, assertion)) return adjacencyFail(cur, assertion);
|
|
10702
|
+
if (values !== void 0) values.push(null);
|
|
10703
|
+
continue;
|
|
10468
10704
|
}
|
|
10469
|
-
|
|
10470
|
-
const
|
|
10471
|
-
const
|
|
10472
|
-
const
|
|
10473
|
-
if (
|
|
10474
|
-
|
|
10475
|
-
|
|
10476
|
-
|
|
10705
|
+
let termPos = cur;
|
|
10706
|
+
const markTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
10707
|
+
const markLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
10708
|
+
const markRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
10709
|
+
if (ctx.trivia && i > 0) {
|
|
10710
|
+
termPos = deferredTrivia ? commitTriviaScan(scanTriviaCompact(input, cur, ctx)) : advanceTrivia(input, cur, ctx);
|
|
10711
|
+
}
|
|
10712
|
+
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
10713
|
+
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
10714
|
+
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
10715
|
+
const result = parsers[i].parse(input, termPos, ctx);
|
|
10716
|
+
if (!result.ok) return result;
|
|
10717
|
+
if (values !== void 0) values.push(result.value);
|
|
10718
|
+
if (result.span.end > termPos || termPos === cur) cur = result.span.end;
|
|
10719
|
+
else if (deferredTrivia) {
|
|
10477
10720
|
rollbackScannedTriviaAt(
|
|
10478
10721
|
ctx,
|
|
10479
|
-
|
|
10722
|
+
markTlog,
|
|
10480
10723
|
scanTlog,
|
|
10481
|
-
|
|
10724
|
+
markLog,
|
|
10482
10725
|
scanLog,
|
|
10483
|
-
|
|
10726
|
+
markRootLog,
|
|
10484
10727
|
scanRootLog
|
|
10485
10728
|
);
|
|
10486
10729
|
}
|
|
10487
|
-
if (values !== void 0) values.push(result2.value);
|
|
10488
|
-
continue;
|
|
10489
10730
|
}
|
|
10490
|
-
|
|
10491
|
-
if (
|
|
10492
|
-
if (values !== void 0) values.push(result.value);
|
|
10493
|
-
cur = result.span.end;
|
|
10731
|
+
} finally {
|
|
10732
|
+
if (tolerant) ctx._sync = inheritedSync;
|
|
10494
10733
|
}
|
|
10495
10734
|
return {
|
|
10496
10735
|
ok: true,
|
|
@@ -10503,8 +10742,20 @@ function sequence(...parsers) {
|
|
|
10503
10742
|
}
|
|
10504
10743
|
|
|
10505
10744
|
// src/combinators/ref.ts
|
|
10745
|
+
function withRuleTrivia(trivia2, ctx, run) {
|
|
10746
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
10747
|
+
ctx.trivia = trivia2;
|
|
10748
|
+
ctx.triviaKindLabels = trivia2._meta.triviaKindLabels;
|
|
10749
|
+
try {
|
|
10750
|
+
return run();
|
|
10751
|
+
} finally {
|
|
10752
|
+
ctx.trivia = void 0;
|
|
10753
|
+
ctx.triviaKindLabels = savedLabels;
|
|
10754
|
+
}
|
|
10755
|
+
}
|
|
10506
10756
|
function ref() {
|
|
10507
10757
|
let resolved = null;
|
|
10758
|
+
let resolvedScalar = null;
|
|
10508
10759
|
let ownBoundary = false;
|
|
10509
10760
|
const meta = {
|
|
10510
10761
|
firstSet: any(),
|
|
@@ -10521,25 +10772,28 @@ function ref() {
|
|
|
10521
10772
|
return resolved;
|
|
10522
10773
|
}
|
|
10523
10774
|
},
|
|
10775
|
+
_parseScalar(input, pos, ctx) {
|
|
10776
|
+
const scalar = resolvedScalar;
|
|
10777
|
+
if (!scalar) throw new Error("ref<T>() used before .define() was called");
|
|
10778
|
+
const gt = meta.grammarTrivia;
|
|
10779
|
+
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
10780
|
+
return withRuleTrivia(gt, ctx, () => scalar(input, pos, ctx));
|
|
10781
|
+
}
|
|
10782
|
+
return scalar(input, pos, ctx);
|
|
10783
|
+
},
|
|
10524
10784
|
parse(input, pos, ctx) {
|
|
10525
|
-
|
|
10785
|
+
const parser2 = resolved;
|
|
10786
|
+
if (!parser2) throw new Error("ref<T>() used before .define() was called");
|
|
10526
10787
|
const gt = meta.grammarTrivia;
|
|
10527
10788
|
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
10528
|
-
|
|
10529
|
-
ctx.trivia = gt;
|
|
10530
|
-
ctx.triviaKindLabels = gt._meta.triviaKindLabels;
|
|
10531
|
-
try {
|
|
10532
|
-
return resolved.parse(input, pos, ctx);
|
|
10533
|
-
} finally {
|
|
10534
|
-
ctx.trivia = void 0;
|
|
10535
|
-
ctx.triviaKindLabels = savedLabels;
|
|
10536
|
-
}
|
|
10789
|
+
return withRuleTrivia(gt, ctx, () => parser2.parse(input, pos, ctx));
|
|
10537
10790
|
}
|
|
10538
|
-
return
|
|
10791
|
+
return parser2.parse(input, pos, ctx);
|
|
10539
10792
|
},
|
|
10540
10793
|
define(p) {
|
|
10541
10794
|
if (resolved) throw new Error("ref<T>() already defined");
|
|
10542
10795
|
resolved = p;
|
|
10796
|
+
resolvedScalar = scalarOf(p);
|
|
10543
10797
|
ownBoundary = hasOwnTriviaBoundary(p);
|
|
10544
10798
|
meta.firstSet = p._meta.firstSet;
|
|
10545
10799
|
meta.canMatchNewline = p._meta.canMatchNewline;
|
|
@@ -13444,10 +13698,10 @@ function assemble(t2, prog, cfg) {
|
|
|
13444
13698
|
const hasFold = spec.byFold.size > 0;
|
|
13445
13699
|
const match = spec.match;
|
|
13446
13700
|
const matchN = match.length;
|
|
13447
|
-
const
|
|
13701
|
+
const routed = spec.routed;
|
|
13448
13702
|
const expected = spec.expected;
|
|
13449
13703
|
const validArm = (arm) => Number.isInteger(arm) && arm >= 0 && arm < n;
|
|
13450
|
-
if (
|
|
13704
|
+
if (routed.length !== n) throw new TypeError("table assembler: malformed dispatch routed arity");
|
|
13451
13705
|
for (const arm of byKey.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch exact arm");
|
|
13452
13706
|
for (const arm of byFold.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch folded arm");
|
|
13453
13707
|
for (const m of match) if (!validArm(m[3])) throw new TypeError("table assembler: malformed dispatch matcher arm");
|
|
@@ -13472,7 +13726,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13472
13726
|
const classify = hasFold ? matchBlock === void 0 ? (key) => byKey.get(key) ?? byFold.get(asciiFoldKey(key)) : (key) => byKey.get(key) ?? byFold.get(asciiFoldKey(key)) ?? matchBlock(key) : matchBlock === void 0 ? (key) => byKey.get(key) : (key) => byKey.get(key) ?? matchBlock(key);
|
|
13473
13727
|
const neverBranch = () => FAIL;
|
|
13474
13728
|
const bindArms = (start) => {
|
|
13475
|
-
const branch = (i) => i < n ? dispatchBranch(link(code[armBase + i]),
|
|
13729
|
+
const branch = (i) => i < n ? dispatchBranch(link(code[armBase + i]), routed[i] === 1) : neverBranch;
|
|
13476
13730
|
const next = start + 4 < n ? bindArms(start + 4) : void 0;
|
|
13477
13731
|
return dispatchArmBlock(
|
|
13478
13732
|
start,
|
|
@@ -14291,7 +14545,7 @@ function buildGrammarPlan(entry, winners) {
|
|
|
14291
14545
|
const dispatches = /* @__PURE__ */ new Map();
|
|
14292
14546
|
const attempts = /* @__PURE__ */ new Map();
|
|
14293
14547
|
const labels = /* @__PURE__ */ new Map();
|
|
14294
|
-
const
|
|
14548
|
+
const rules = /* @__PURE__ */ new Map();
|
|
14295
14549
|
const winnerNames = /* @__PURE__ */ new Map();
|
|
14296
14550
|
if (winners) {
|
|
14297
14551
|
for (const [name, winner] of Object.entries(winners)) {
|
|
@@ -14312,7 +14566,7 @@ function buildGrammarPlan(entry, winners) {
|
|
|
14312
14566
|
if (rule2 && (winnerNames.has(parser2) || parser2._def.tag !== "lazy")) {
|
|
14313
14567
|
const id = `rule:${rule2}`;
|
|
14314
14568
|
definitions.set(id, { id, kind: "rule" });
|
|
14315
|
-
|
|
14569
|
+
rules.set(parser2, id);
|
|
14316
14570
|
}
|
|
14317
14571
|
if (parser2._def.tag === "choice") {
|
|
14318
14572
|
const ids = parser2._def.parsers.map((_, index) => `choice:${path}/arm:${index}`);
|
|
@@ -14336,7 +14590,7 @@ function buildGrammarPlan(entry, winners) {
|
|
|
14336
14590
|
for (const root of roots) {
|
|
14337
14591
|
visit(root, winnerNames.get(root) ?? root._ruleName ?? "entry");
|
|
14338
14592
|
}
|
|
14339
|
-
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules
|
|
14593
|
+
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules };
|
|
14340
14594
|
}
|
|
14341
14595
|
|
|
14342
14596
|
// src/analysis/duplication.ts
|
|
@@ -17004,31 +17258,6 @@ function locatedLines(l, opts) {
|
|
|
17004
17258
|
return out;
|
|
17005
17259
|
}
|
|
17006
17260
|
|
|
17007
|
-
// src/compiler/linker.ts
|
|
17008
|
-
function normalizeCstCollapse(collapse) {
|
|
17009
|
-
if (collapse === true) return () => true;
|
|
17010
|
-
if (Array.isArray(collapse)) {
|
|
17011
|
-
const types = new Set(collapse);
|
|
17012
|
-
return (type) => types.has(type);
|
|
17013
|
-
}
|
|
17014
|
-
return typeof collapse === "function" ? collapse : void 0;
|
|
17015
|
-
}
|
|
17016
|
-
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
17017
|
-
return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children2] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
17018
|
-
}
|
|
17019
|
-
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
17020
|
-
if (typeof typeOrOptions === "string") {
|
|
17021
|
-
return buildCstNode(typeOrOptions, children2 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
17022
|
-
}
|
|
17023
|
-
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
17024
|
-
const materializeTags = typeOrOptions?.tags === true;
|
|
17025
|
-
const host = (type, children3, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children3 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
17026
|
-
host._parsemanCstOutput = true;
|
|
17027
|
-
if (collapse) host._parsemanCstCollapse = collapse;
|
|
17028
|
-
return host;
|
|
17029
|
-
}
|
|
17030
|
-
cstBuildHost._parsemanCstOutput = true;
|
|
17031
|
-
|
|
17032
17261
|
// src/analysis/diagnose.ts
|
|
17033
17262
|
function examinedNothing(d) {
|
|
17034
17263
|
return d.summary.totalChoices === 0 && d.summary.unanalysable > 0;
|