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
package/dist/plugin/index.js
CHANGED
|
@@ -314,9 +314,43 @@ function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
+
// src/combinators/scalar.ts
|
|
318
|
+
var SCALAR_TAG = /^(?:literal|regex|keywords|sequence|choice|many|oneOrMore|optional|transform|trivia|grammar|sepBy|lazy)$/;
|
|
319
|
+
function scalarOf(combinator) {
|
|
320
|
+
return combinator._parseScalar;
|
|
321
|
+
}
|
|
322
|
+
function scalarTree(parser2, seen) {
|
|
323
|
+
if (seen.has(parser2)) return true;
|
|
324
|
+
if (parser2._parseScalar === void 0) return false;
|
|
325
|
+
seen.add(parser2);
|
|
326
|
+
const def = parser2._def;
|
|
327
|
+
if (!SCALAR_TAG.test(def.tag)) return false;
|
|
328
|
+
if ("parsers" in def && !def.parsers.every((child) => scalarTree(child, seen))) return false;
|
|
329
|
+
if ("parser" in def && !scalarTree(def.parser, seen)) return false;
|
|
330
|
+
if ("separator" in def && !scalarTree(def.separator, seen)) return false;
|
|
331
|
+
return def.tag !== "lazy" || scalarTree(def.thunk(), seen);
|
|
332
|
+
}
|
|
333
|
+
function scalarRootOf(combinator) {
|
|
334
|
+
const scalar = combinator._parseScalar;
|
|
335
|
+
const def = combinator._def;
|
|
336
|
+
return scalar !== void 0 && def.tag === "grammar" && scalarTree(def.parser, /* @__PURE__ */ new Set()) ? scalar : void 0;
|
|
337
|
+
}
|
|
338
|
+
|
|
317
339
|
// src/combinators/ref.ts
|
|
340
|
+
function withRuleTrivia(trivia2, ctx, run) {
|
|
341
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
342
|
+
ctx.trivia = trivia2;
|
|
343
|
+
ctx.triviaKindLabels = trivia2._meta.triviaKindLabels;
|
|
344
|
+
try {
|
|
345
|
+
return run();
|
|
346
|
+
} finally {
|
|
347
|
+
ctx.trivia = void 0;
|
|
348
|
+
ctx.triviaKindLabels = savedLabels;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
318
351
|
function ref() {
|
|
319
352
|
let resolved = null;
|
|
353
|
+
let resolvedScalar = null;
|
|
320
354
|
let ownBoundary = false;
|
|
321
355
|
const meta = {
|
|
322
356
|
firstSet: any(),
|
|
@@ -333,25 +367,28 @@ function ref() {
|
|
|
333
367
|
return resolved;
|
|
334
368
|
}
|
|
335
369
|
},
|
|
370
|
+
_parseScalar(input, pos, ctx) {
|
|
371
|
+
const scalar = resolvedScalar;
|
|
372
|
+
if (!scalar) throw new Error("ref<T>() used before .define() was called");
|
|
373
|
+
const gt = meta.grammarTrivia;
|
|
374
|
+
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
375
|
+
return withRuleTrivia(gt, ctx, () => scalar(input, pos, ctx));
|
|
376
|
+
}
|
|
377
|
+
return scalar(input, pos, ctx);
|
|
378
|
+
},
|
|
336
379
|
parse(input, pos, ctx) {
|
|
337
|
-
|
|
380
|
+
const parser2 = resolved;
|
|
381
|
+
if (!parser2) throw new Error("ref<T>() used before .define() was called");
|
|
338
382
|
const gt = meta.grammarTrivia;
|
|
339
383
|
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
340
|
-
|
|
341
|
-
ctx.trivia = gt;
|
|
342
|
-
ctx.triviaKindLabels = gt._meta.triviaKindLabels;
|
|
343
|
-
try {
|
|
344
|
-
return resolved.parse(input, pos, ctx);
|
|
345
|
-
} finally {
|
|
346
|
-
ctx.trivia = void 0;
|
|
347
|
-
ctx.triviaKindLabels = savedLabels;
|
|
348
|
-
}
|
|
384
|
+
return withRuleTrivia(gt, ctx, () => parser2.parse(input, pos, ctx));
|
|
349
385
|
}
|
|
350
|
-
return
|
|
386
|
+
return parser2.parse(input, pos, ctx);
|
|
351
387
|
},
|
|
352
388
|
define(p) {
|
|
353
389
|
if (resolved) throw new Error("ref<T>() already defined");
|
|
354
390
|
resolved = p;
|
|
391
|
+
resolvedScalar = scalarOf(p);
|
|
355
392
|
ownBoundary = hasOwnTriviaBoundary(p);
|
|
356
393
|
meta.firstSet = p._meta.firstSet;
|
|
357
394
|
meta.canMatchNewline = p._meta.canMatchNewline;
|
|
@@ -737,6 +774,7 @@ function createParseContext() {
|
|
|
737
774
|
_fe: void 0,
|
|
738
775
|
_fx: void 0,
|
|
739
776
|
_fc: void 0,
|
|
777
|
+
_sv: void 0,
|
|
740
778
|
_probe: void 0,
|
|
741
779
|
_cstChildren: void 0,
|
|
742
780
|
_cstLeaves: void 0,
|
|
@@ -1574,6 +1612,24 @@ function parser(opts, root) {
|
|
|
1574
1612
|
const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
|
|
1575
1613
|
const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
|
|
1576
1614
|
const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
|
|
1615
|
+
const rootScalar = scalarOf(root);
|
|
1616
|
+
const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
|
|
1617
|
+
const parseScalar = scalarEligible ? (input, pos, ctx) => {
|
|
1618
|
+
const savedTrivia = ctx.trivia;
|
|
1619
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
1620
|
+
if (clearTrivia) {
|
|
1621
|
+
ctx.trivia = void 0;
|
|
1622
|
+
ctx.triviaKindLabels = void 0;
|
|
1623
|
+
} else if (scopeTrivia !== void 0) {
|
|
1624
|
+
ctx.trivia = scopeTrivia;
|
|
1625
|
+
ctx.triviaKindLabels = scopeLabels;
|
|
1626
|
+
}
|
|
1627
|
+
const end = rootScalar(input, pos, ctx);
|
|
1628
|
+
ctx.trivia = savedTrivia;
|
|
1629
|
+
ctx.triviaKindLabels = savedLabels;
|
|
1630
|
+
return end;
|
|
1631
|
+
} : void 0;
|
|
1632
|
+
let publicScalar;
|
|
1577
1633
|
const grammar = {
|
|
1578
1634
|
_tag: "grammar",
|
|
1579
1635
|
_meta: {
|
|
@@ -1597,7 +1653,20 @@ function parser(opts, root) {
|
|
|
1597
1653
|
constructionTrackLines: trackLinesPolicy,
|
|
1598
1654
|
...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
|
|
1599
1655
|
},
|
|
1656
|
+
_parseScalar: parseScalar,
|
|
1600
1657
|
parse(input, pos, _ctx) {
|
|
1658
|
+
if (pos === void 0 && _ctx === void 0) {
|
|
1659
|
+
publicScalar ??= scalarRootOf(grammar) ?? null;
|
|
1660
|
+
if (publicScalar) {
|
|
1661
|
+
const ctx2 = createParseContext();
|
|
1662
|
+
const end = publicScalar(input, 0, ctx2);
|
|
1663
|
+
if (end < 0) {
|
|
1664
|
+
const at = ~end;
|
|
1665
|
+
return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
|
|
1666
|
+
}
|
|
1667
|
+
return { ok: true, value: ctx2._sv, span: { start: 0, end } };
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1601
1670
|
if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
|
|
1602
1671
|
const trackLines = trackLinesOf(_ctx);
|
|
1603
1672
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
@@ -1889,6 +1958,28 @@ function literal(value, opts = {}) {
|
|
|
1889
1958
|
isTrivia: false
|
|
1890
1959
|
};
|
|
1891
1960
|
const canMatchNewline = meta.canMatchNewline;
|
|
1961
|
+
const parseScalar = !caseInsensitive && value.length === 1 ? (() => {
|
|
1962
|
+
const code = value.charCodeAt(0);
|
|
1963
|
+
return (input, pos, ctx) => {
|
|
1964
|
+
if (input.charCodeAt(pos) === code) {
|
|
1965
|
+
ctx._sv = value;
|
|
1966
|
+
return pos + 1;
|
|
1967
|
+
}
|
|
1968
|
+
ctx._fx = expected;
|
|
1969
|
+
return ~pos;
|
|
1970
|
+
};
|
|
1971
|
+
})() : (input, pos, ctx) => {
|
|
1972
|
+
const end = pos + value.length;
|
|
1973
|
+
if (end <= input.length) {
|
|
1974
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
1975
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
1976
|
+
ctx._sv = matchedValue;
|
|
1977
|
+
return end;
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
ctx._fx = expected;
|
|
1981
|
+
return ~pos;
|
|
1982
|
+
};
|
|
1892
1983
|
if (caseInsensitive) {
|
|
1893
1984
|
const upper = value.toUpperCase();
|
|
1894
1985
|
const lower = value.toLowerCase();
|
|
@@ -1929,6 +2020,7 @@ function literal(value, opts = {}) {
|
|
|
1929
2020
|
_tag: "literal",
|
|
1930
2021
|
_meta: meta,
|
|
1931
2022
|
_def: { tag: "literal", value, caseInsensitive },
|
|
2023
|
+
_parseScalar: parseScalar,
|
|
1932
2024
|
parse: parse2
|
|
1933
2025
|
};
|
|
1934
2026
|
}
|
|
@@ -2268,10 +2360,32 @@ function regex(pattern, flags = "") {
|
|
|
2268
2360
|
const canMatchNewline = raw.canMatchNewline;
|
|
2269
2361
|
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
2270
2362
|
const def = { tag: "regex", source, flags: resolvedFlags };
|
|
2363
|
+
const expected = directTerminalFailureExpected(def);
|
|
2364
|
+
const parseScalar = (input, pos, ctx) => {
|
|
2365
|
+
const scanEnd = scan?.(input, pos);
|
|
2366
|
+
if (scanEnd !== void 0) {
|
|
2367
|
+
if (scanEnd === null) {
|
|
2368
|
+
ctx._fx = expected;
|
|
2369
|
+
return ~pos;
|
|
2370
|
+
}
|
|
2371
|
+
ctx._sv = input.slice(pos, scanEnd);
|
|
2372
|
+
return scanEnd;
|
|
2373
|
+
}
|
|
2374
|
+
anchored.lastIndex = pos;
|
|
2375
|
+
const match = anchored.exec(input);
|
|
2376
|
+
if (match === null) {
|
|
2377
|
+
ctx._fx = expected;
|
|
2378
|
+
return ~pos;
|
|
2379
|
+
}
|
|
2380
|
+
ctx._sv = match[0];
|
|
2381
|
+
return pos + match[0].length;
|
|
2382
|
+
};
|
|
2271
2383
|
return {
|
|
2272
2384
|
_tag: "regex",
|
|
2273
2385
|
_meta: meta,
|
|
2274
2386
|
_def: def,
|
|
2387
|
+
_stickyRegex: anchored,
|
|
2388
|
+
_parseScalar: parseScalar,
|
|
2275
2389
|
parse(input, pos, ctx) {
|
|
2276
2390
|
const scanEnd = scan?.(input, pos);
|
|
2277
2391
|
if (scanEnd !== void 0) {
|
|
@@ -2363,16 +2477,26 @@ function keywords(words, opts = {}) {
|
|
|
2363
2477
|
caseInsensitive: opts.caseInsensitive ?? false,
|
|
2364
2478
|
boundary: opts.boundary
|
|
2365
2479
|
};
|
|
2480
|
+
const expected = directTerminalFailureExpected(def);
|
|
2481
|
+
const parseScalar = (input, pos, ctx) => {
|
|
2482
|
+
re.lastIndex = pos;
|
|
2483
|
+
const m = re.exec(input);
|
|
2484
|
+
if (m === null) {
|
|
2485
|
+
ctx._fx = expected;
|
|
2486
|
+
return ~pos;
|
|
2487
|
+
}
|
|
2488
|
+
ctx._sv = m[0];
|
|
2489
|
+
return pos + m[0].length;
|
|
2490
|
+
};
|
|
2366
2491
|
return {
|
|
2367
2492
|
_tag: "keywords",
|
|
2368
2493
|
_meta: meta,
|
|
2369
2494
|
_def: def,
|
|
2495
|
+
_parseScalar: parseScalar,
|
|
2370
2496
|
parse(input, pos, ctx) {
|
|
2371
2497
|
re.lastIndex = pos;
|
|
2372
2498
|
const m = re.exec(input);
|
|
2373
|
-
if (m === null
|
|
2374
|
-
return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
2375
|
-
}
|
|
2499
|
+
if (m === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
2376
2500
|
const value = m[0];
|
|
2377
2501
|
const span = { start: pos, end: pos + value.length };
|
|
2378
2502
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
@@ -2403,6 +2527,9 @@ var fastScanner3;
|
|
|
2403
2527
|
function needsDeferredTriviaCommit(ctx) {
|
|
2404
2528
|
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
2405
2529
|
}
|
|
2530
|
+
function needsTriviaRollback(ctx) {
|
|
2531
|
+
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;
|
|
2532
|
+
}
|
|
2406
2533
|
function saveTriviaMark(ctx) {
|
|
2407
2534
|
const m = saveCstMark(ctx);
|
|
2408
2535
|
return {
|
|
@@ -2519,7 +2646,8 @@ function advanceTrivia(input, cur, ctx) {
|
|
|
2519
2646
|
const triviaP = ctx.trivia;
|
|
2520
2647
|
if (!triviaP) return cur;
|
|
2521
2648
|
if (!ctx.trackLines) {
|
|
2522
|
-
const
|
|
2649
|
+
const classified = triviaP._meta.triviaScanner;
|
|
2650
|
+
const fast2 = classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
2523
2651
|
if (fast2) return fast2(input, cur);
|
|
2524
2652
|
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
2525
2653
|
const tr2 = triviaP.parse(input, cur, createDetachedParseContext(ctx.trackLines, ctx.state));
|
|
@@ -3124,6 +3252,7 @@ function sequence(...parsers) {
|
|
|
3124
3252
|
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
3125
3253
|
}
|
|
3126
3254
|
const hasAdjacency = adjacency !== null;
|
|
3255
|
+
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
3127
3256
|
const meta = {
|
|
3128
3257
|
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
3129
3258
|
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
@@ -3132,165 +3261,96 @@ function sequence(...parsers) {
|
|
|
3132
3261
|
isTrivia: false
|
|
3133
3262
|
};
|
|
3134
3263
|
const def = { tag: "sequence", parsers };
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
3138
|
-
const fs3 = parsers.slice(i + 1).reduce(
|
|
3139
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
3140
|
-
{ kind: "empty" }
|
|
3141
|
-
);
|
|
3142
|
-
return firstSetSentinel(fs3);
|
|
3143
|
-
});
|
|
3144
|
-
const values = def.valueUnused ? void 0 : [];
|
|
3264
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
3265
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3145
3266
|
let cur = pos;
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
const mTlog = cstTlLen(ctx);
|
|
3158
|
-
const mLog = ctx._triviaLog?.length ?? 0;
|
|
3159
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3160
|
-
let scanEnd;
|
|
3161
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
3162
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
3163
|
-
} else {
|
|
3164
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
3165
|
-
}
|
|
3166
|
-
const scanTlog = cstTlLen(ctx);
|
|
3167
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
3168
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3169
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
3170
|
-
if (!result2.ok) return result2;
|
|
3171
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
3172
|
-
else rollbackScannedTriviaAt(
|
|
3173
|
-
ctx,
|
|
3174
|
-
mTlog,
|
|
3175
|
-
scanTlog,
|
|
3176
|
-
mLog,
|
|
3177
|
-
scanLog,
|
|
3178
|
-
mRootLog,
|
|
3179
|
-
scanRootLog
|
|
3180
|
-
);
|
|
3181
|
-
if (values !== void 0) values.push(result2.value);
|
|
3182
|
-
continue;
|
|
3183
|
-
}
|
|
3184
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
3185
|
-
if (!result.ok) return result;
|
|
3186
|
-
if (values !== void 0) values.push(result.value);
|
|
3187
|
-
cur = result.span.end;
|
|
3267
|
+
if (strictArity !== 0) {
|
|
3268
|
+
cur = scalarParsers[0](input, cur, ctx);
|
|
3269
|
+
if (cur < 0) return cur;
|
|
3270
|
+
const first = ctx._sv;
|
|
3271
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
3272
|
+
cur = scalarParsers[1](input, cur, ctx);
|
|
3273
|
+
if (cur < 0) return cur;
|
|
3274
|
+
const second = ctx._sv;
|
|
3275
|
+
if (strictArity === 2) {
|
|
3276
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second];
|
|
3277
|
+
return cur;
|
|
3188
3278
|
}
|
|
3189
|
-
|
|
3190
|
-
|
|
3279
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
3280
|
+
cur = scalarParsers[2](input, cur, ctx);
|
|
3281
|
+
if (cur < 0) return cur;
|
|
3282
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second, ctx._sv];
|
|
3283
|
+
return cur;
|
|
3191
3284
|
}
|
|
3192
|
-
return {
|
|
3193
|
-
ok: true,
|
|
3194
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
3195
|
-
value: values ?? void 0,
|
|
3196
|
-
span: { start: pos, end: cur }
|
|
3197
|
-
};
|
|
3198
|
-
}
|
|
3199
|
-
function parseAdjacent(input, pos, ctx) {
|
|
3200
3285
|
const values = def.valueUnused ? void 0 : [];
|
|
3201
|
-
let
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3214
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
3215
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
3216
|
-
} else {
|
|
3217
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
3218
|
-
}
|
|
3219
|
-
const scanTlog = cstTlLen(ctx);
|
|
3220
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
3221
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3222
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
3223
|
-
if (!result2.ok) return result2;
|
|
3224
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
3225
|
-
else rollbackScannedTriviaAt(
|
|
3226
|
-
ctx,
|
|
3227
|
-
mTlog,
|
|
3228
|
-
scanTlog,
|
|
3229
|
-
mLog,
|
|
3230
|
-
scanLog,
|
|
3231
|
-
mRootLog,
|
|
3232
|
-
scanRootLog
|
|
3233
|
-
);
|
|
3234
|
-
if (values !== void 0) values.push(result2.value);
|
|
3235
|
-
continue;
|
|
3236
|
-
}
|
|
3237
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
3238
|
-
if (!result.ok) return result;
|
|
3239
|
-
if (values !== void 0) values.push(result.value);
|
|
3240
|
-
cur = result.span.end;
|
|
3241
|
-
}
|
|
3242
|
-
return {
|
|
3243
|
-
ok: true,
|
|
3244
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
3245
|
-
value: values ?? void 0,
|
|
3246
|
-
span: { start: pos, end: cur }
|
|
3247
|
-
};
|
|
3248
|
-
}
|
|
3286
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
3287
|
+
let termPos = cur;
|
|
3288
|
+
if (i > 0 && ctx.trivia) termPos = advanceTrivia(input, cur, ctx);
|
|
3289
|
+
const end = scalarParsers[i](input, termPos, ctx);
|
|
3290
|
+
if (end < 0) return end;
|
|
3291
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
3292
|
+
if (end > termPos || termPos === cur) cur = end;
|
|
3293
|
+
}
|
|
3294
|
+
ctx._sv = values;
|
|
3295
|
+
return cur;
|
|
3296
|
+
};
|
|
3297
|
+
let followSentinels;
|
|
3249
3298
|
return {
|
|
3250
3299
|
_tag: "sequence",
|
|
3251
3300
|
_meta: meta,
|
|
3252
3301
|
_def: def,
|
|
3302
|
+
_parseScalar: hasAdjacency ? void 0 : parseScalar,
|
|
3253
3303
|
parse(input, pos, ctx) {
|
|
3254
|
-
|
|
3255
|
-
if (
|
|
3304
|
+
const tolerant = ctx._tolerant === true;
|
|
3305
|
+
if (tolerant) {
|
|
3306
|
+
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
3307
|
+
parsers.slice(i + 1).reduce(
|
|
3308
|
+
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
3309
|
+
{ kind: "empty" }
|
|
3310
|
+
)
|
|
3311
|
+
));
|
|
3312
|
+
}
|
|
3313
|
+
const inheritedSync = ctx._sync;
|
|
3314
|
+
const deferredTrivia = needsDeferredTriviaCommit(ctx);
|
|
3256
3315
|
const values = def.valueUnused ? void 0 : [];
|
|
3257
3316
|
let cur = pos;
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
const
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
} else {
|
|
3267
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
3317
|
+
try {
|
|
3318
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
3319
|
+
if (tolerant) ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
3320
|
+
const assertion = adjacency?.[i];
|
|
3321
|
+
if (assertion) {
|
|
3322
|
+
if (!holdsAdjacency(input, cur, ctx, assertion)) return adjacencyFail(cur, assertion);
|
|
3323
|
+
if (values !== void 0) values.push(null);
|
|
3324
|
+
continue;
|
|
3268
3325
|
}
|
|
3269
|
-
|
|
3270
|
-
const
|
|
3271
|
-
const
|
|
3272
|
-
const
|
|
3273
|
-
if (
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3326
|
+
let termPos = cur;
|
|
3327
|
+
const markTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
3328
|
+
const markLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
3329
|
+
const markRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
3330
|
+
if (ctx.trivia && i > 0) {
|
|
3331
|
+
termPos = deferredTrivia ? commitTriviaScan(scanTriviaCompact(input, cur, ctx)) : advanceTrivia(input, cur, ctx);
|
|
3332
|
+
}
|
|
3333
|
+
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
3334
|
+
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
3335
|
+
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
3336
|
+
const result = parsers[i].parse(input, termPos, ctx);
|
|
3337
|
+
if (!result.ok) return result;
|
|
3338
|
+
if (values !== void 0) values.push(result.value);
|
|
3339
|
+
if (result.span.end > termPos || termPos === cur) cur = result.span.end;
|
|
3340
|
+
else if (deferredTrivia) {
|
|
3277
3341
|
rollbackScannedTriviaAt(
|
|
3278
3342
|
ctx,
|
|
3279
|
-
|
|
3343
|
+
markTlog,
|
|
3280
3344
|
scanTlog,
|
|
3281
|
-
|
|
3345
|
+
markLog,
|
|
3282
3346
|
scanLog,
|
|
3283
|
-
|
|
3347
|
+
markRootLog,
|
|
3284
3348
|
scanRootLog
|
|
3285
3349
|
);
|
|
3286
3350
|
}
|
|
3287
|
-
if (values !== void 0) values.push(result2.value);
|
|
3288
|
-
continue;
|
|
3289
3351
|
}
|
|
3290
|
-
|
|
3291
|
-
if (
|
|
3292
|
-
if (values !== void 0) values.push(result.value);
|
|
3293
|
-
cur = result.span.end;
|
|
3352
|
+
} finally {
|
|
3353
|
+
if (tolerant) ctx._sync = inheritedSync;
|
|
3294
3354
|
}
|
|
3295
3355
|
return {
|
|
3296
3356
|
ok: true,
|
|
@@ -3422,7 +3482,8 @@ function choice(...args) {
|
|
|
3422
3482
|
disjoint
|
|
3423
3483
|
};
|
|
3424
3484
|
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
3425
|
-
const
|
|
3485
|
+
const ordered = strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix";
|
|
3486
|
+
const autoNot = !disjoint && !hasGates && ordered ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
3426
3487
|
let greedyLitMap = null;
|
|
3427
3488
|
let sortedParsers = null;
|
|
3428
3489
|
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
@@ -3436,6 +3497,37 @@ function choice(...args) {
|
|
|
3436
3497
|
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
3437
3498
|
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
3438
3499
|
}
|
|
3500
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
3501
|
+
const scalarEligible = !hasGates && parsers.every((p) => p._parseScalar !== void 0) && (disjoint || ordered);
|
|
3502
|
+
const scalarExpected = parsers.flatMap(deriveExpected);
|
|
3503
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3504
|
+
if (disjoint) {
|
|
3505
|
+
const code = pos < input.length ? input.codePointAt(pos) : -1;
|
|
3506
|
+
let idx = code >= 0 && code < 128 ? asciiDispatch[code] : -1;
|
|
3507
|
+
if (idx < 0 && code >= 0) {
|
|
3508
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
3509
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
3510
|
+
idx = i;
|
|
3511
|
+
break;
|
|
3512
|
+
}
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
if (idx >= 0) {
|
|
3516
|
+
const gate2 = gates[idx];
|
|
3517
|
+
if (!gate2 || gate2(ctx.state)) return scalarParsers[idx](input, pos, ctx);
|
|
3518
|
+
ctx._fx = deriveExpected(parsers[idx]);
|
|
3519
|
+
return ~pos;
|
|
3520
|
+
}
|
|
3521
|
+
} else {
|
|
3522
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
3523
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
3524
|
+
const end = scalarParsers[i](input, pos, ctx);
|
|
3525
|
+
if (end >= 0 && (!autoNot[i] || !autoNotFires(input, end, autoNot[i]))) return end;
|
|
3526
|
+
}
|
|
3527
|
+
}
|
|
3528
|
+
ctx._fx = scalarExpected;
|
|
3529
|
+
return ~pos;
|
|
3530
|
+
};
|
|
3439
3531
|
return {
|
|
3440
3532
|
_tag: "choice",
|
|
3441
3533
|
_meta: meta,
|
|
@@ -3447,6 +3539,7 @@ function choice(...args) {
|
|
|
3447
3539
|
strategy: strategy ?? { tag: "firstMatch" },
|
|
3448
3540
|
autoNot
|
|
3449
3541
|
},
|
|
3542
|
+
_parseScalar: scalarEligible ? parseScalar : void 0,
|
|
3450
3543
|
parse(input, pos, ctx) {
|
|
3451
3544
|
const expected = [];
|
|
3452
3545
|
let expectedAt = pos;
|
|
@@ -3978,8 +4071,8 @@ function attempt(parser2) {
|
|
|
3978
4071
|
}
|
|
3979
4072
|
|
|
3980
4073
|
// src/combinators/repeat.ts
|
|
3981
|
-
function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
3982
|
-
const mark = saveTriviaMark(ctx);
|
|
4074
|
+
function repItem(combinator, input, cur, ctx, guardable, mandatory, rollbackNeeded) {
|
|
4075
|
+
const mark = rollbackNeeded ? saveTriviaMark(ctx) : void 0;
|
|
3983
4076
|
let pos = cur;
|
|
3984
4077
|
if (ctx.trivia) {
|
|
3985
4078
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -3989,24 +4082,24 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
|
3989
4082
|
}
|
|
3990
4083
|
}
|
|
3991
4084
|
if (pos >= input.length && !mandatory) {
|
|
3992
|
-
rollbackTrivia(ctx, mark);
|
|
4085
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3993
4086
|
return "stop";
|
|
3994
4087
|
}
|
|
3995
4088
|
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
3996
|
-
rollbackTrivia(ctx, mark);
|
|
4089
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3997
4090
|
return "stop";
|
|
3998
4091
|
}
|
|
3999
4092
|
const result = combinator.parse(input, pos, ctx);
|
|
4000
4093
|
if (!result.ok) {
|
|
4001
|
-
rollbackTrivia(ctx, mark);
|
|
4094
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4002
4095
|
if (result.committed) return { fail: result, failPos: pos };
|
|
4003
4096
|
return { fail: result, failPos: pos };
|
|
4004
4097
|
}
|
|
4005
4098
|
if (result.span.end === pos && !mandatory) {
|
|
4006
|
-
rollbackTrivia(ctx, mark);
|
|
4099
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4007
4100
|
return "stop";
|
|
4008
4101
|
}
|
|
4009
|
-
return
|
|
4102
|
+
return result;
|
|
4010
4103
|
}
|
|
4011
4104
|
function resolveBounds(what, opts) {
|
|
4012
4105
|
const min = opts.min ?? 0;
|
|
@@ -4019,6 +4112,21 @@ function resolveBounds(what, opts) {
|
|
|
4019
4112
|
if (max < min) bad(`max (${max}) is less than min (${min}) \u2014 the combinator could never succeed`);
|
|
4020
4113
|
return { min, max };
|
|
4021
4114
|
}
|
|
4115
|
+
function repeatScalarTail(combinator, child, input, cur, ctx, guardable, values, remaining) {
|
|
4116
|
+
while (cur < input.length && remaining > 0) {
|
|
4117
|
+
let itemPos = cur;
|
|
4118
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4119
|
+
if (itemPos >= input.length) break;
|
|
4120
|
+
if (guardable && !startsFirstSet(combinator, input, itemPos)) break;
|
|
4121
|
+
const end = child(input, itemPos, ctx);
|
|
4122
|
+
if (end <= itemPos) break;
|
|
4123
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4124
|
+
cur = end;
|
|
4125
|
+
remaining--;
|
|
4126
|
+
}
|
|
4127
|
+
ctx._sv = values;
|
|
4128
|
+
return cur;
|
|
4129
|
+
}
|
|
4022
4130
|
function many(combinator, opts = {}) {
|
|
4023
4131
|
const { min, max } = resolveBounds("many()", opts);
|
|
4024
4132
|
if (min >= 1) return atLeast(combinator, min, max);
|
|
@@ -4030,17 +4138,21 @@ function many(combinator, opts = {}) {
|
|
|
4030
4138
|
const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max } };
|
|
4031
4139
|
let expected;
|
|
4032
4140
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4141
|
+
const scalarChild = scalarOf(combinator);
|
|
4142
|
+
const parseScalar = (input, pos, ctx) => repeatScalarTail(combinator, scalarChild, input, pos, ctx, guardable, def.valueUnused ? void 0 : [], max);
|
|
4033
4143
|
return {
|
|
4034
4144
|
_tag: "many",
|
|
4035
4145
|
_meta: meta,
|
|
4036
4146
|
_def: def,
|
|
4147
|
+
_parseScalar: parseScalar,
|
|
4037
4148
|
parse(input, pos, ctx) {
|
|
4038
4149
|
const values = def.valueUnused ? void 0 : [];
|
|
4150
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4039
4151
|
let cur = pos;
|
|
4040
4152
|
let count = 0;
|
|
4041
4153
|
while (cur < input.length) {
|
|
4042
4154
|
if (count >= max) break;
|
|
4043
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
4155
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4044
4156
|
if (item === "stop") break;
|
|
4045
4157
|
if ("fail" in item) {
|
|
4046
4158
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -4057,7 +4169,7 @@ function many(combinator, opts = {}) {
|
|
|
4057
4169
|
}
|
|
4058
4170
|
if (values !== void 0) values.push(item.value);
|
|
4059
4171
|
count++;
|
|
4060
|
-
cur = item.end;
|
|
4172
|
+
cur = item.span.end;
|
|
4061
4173
|
}
|
|
4062
4174
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4063
4175
|
}
|
|
@@ -4075,30 +4187,47 @@ function atLeast(combinator, min, max) {
|
|
|
4075
4187
|
const def = { tag: "oneOrMore", parser: combinator, min, ...max === Infinity ? {} : { max } };
|
|
4076
4188
|
let expected;
|
|
4077
4189
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4190
|
+
const scalarChild = scalarOf(combinator);
|
|
4191
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4192
|
+
let cur = scalarChild(input, pos, ctx);
|
|
4193
|
+
if (cur < 0) return cur;
|
|
4194
|
+
const values = def.valueUnused ? void 0 : [ctx._sv];
|
|
4195
|
+
for (let count = 1; count < min; count++) {
|
|
4196
|
+
let itemPos = cur;
|
|
4197
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4198
|
+
const end = scalarChild(input, itemPos, ctx);
|
|
4199
|
+
if (end < 0) return ~cur;
|
|
4200
|
+
cur = end;
|
|
4201
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4202
|
+
}
|
|
4203
|
+
return repeatScalarTail(combinator, scalarChild, input, cur, ctx, guardable, values, max - min);
|
|
4204
|
+
};
|
|
4078
4205
|
return {
|
|
4079
4206
|
_tag: "oneOrMore",
|
|
4080
4207
|
_meta: meta,
|
|
4081
4208
|
_def: def,
|
|
4209
|
+
_parseScalar: parseScalar,
|
|
4082
4210
|
parse(input, pos, ctx) {
|
|
4083
4211
|
const first = combinator.parse(input, pos, ctx);
|
|
4084
4212
|
if (!first.ok) return first;
|
|
4085
4213
|
const values = def.valueUnused ? void 0 : [first.value];
|
|
4214
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4086
4215
|
let cur = first.span.end;
|
|
4087
4216
|
let count = 1;
|
|
4088
4217
|
while (count < min) {
|
|
4089
|
-
const item = repItem(combinator, input, cur, ctx, guardable, true);
|
|
4218
|
+
const item = repItem(combinator, input, cur, ctx, guardable, true, rollbackNeeded);
|
|
4090
4219
|
if (item === "stop" || "fail" in item) {
|
|
4091
4220
|
if (item !== "stop" && !item.fail.ok && item.fail.committed) return item.fail;
|
|
4092
4221
|
expected ??= deriveExpected(combinator);
|
|
4093
4222
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: cur, end: cur } };
|
|
4094
4223
|
}
|
|
4095
4224
|
if (values !== void 0) values.push(item.value);
|
|
4096
|
-
cur = item.end;
|
|
4225
|
+
cur = item.span.end;
|
|
4097
4226
|
count++;
|
|
4098
4227
|
}
|
|
4099
4228
|
while (cur < input.length) {
|
|
4100
4229
|
if (count >= max) break;
|
|
4101
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
4230
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4102
4231
|
if (item === "stop") break;
|
|
4103
4232
|
if ("fail" in item) {
|
|
4104
4233
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -4115,7 +4244,7 @@ function atLeast(combinator, min, max) {
|
|
|
4115
4244
|
}
|
|
4116
4245
|
if (values !== void 0) values.push(item.value);
|
|
4117
4246
|
count++;
|
|
4118
|
-
cur = item.end;
|
|
4247
|
+
cur = item.span.end;
|
|
4119
4248
|
}
|
|
4120
4249
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4121
4250
|
}
|
|
@@ -4128,10 +4257,22 @@ function optional(combinator) {
|
|
|
4128
4257
|
isTrivia: false
|
|
4129
4258
|
};
|
|
4130
4259
|
const firstSetSkippable = !matchesEmpty(combinator);
|
|
4260
|
+
const scalarChild = scalarOf(combinator);
|
|
4261
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4262
|
+
if (firstSetSkippable && !startsFirstSet(combinator, input, pos)) {
|
|
4263
|
+
ctx._sv = null;
|
|
4264
|
+
return pos;
|
|
4265
|
+
}
|
|
4266
|
+
const end = scalarChild(input, pos, ctx);
|
|
4267
|
+
if (end >= 0) return end;
|
|
4268
|
+
ctx._sv = null;
|
|
4269
|
+
return pos;
|
|
4270
|
+
};
|
|
4131
4271
|
return {
|
|
4132
4272
|
_tag: "optional",
|
|
4133
4273
|
_meta: meta,
|
|
4134
4274
|
_def: { tag: "optional", parser: combinator },
|
|
4275
|
+
_parseScalar: parseScalar,
|
|
4135
4276
|
parse(input, pos, ctx) {
|
|
4136
4277
|
if (firstSetSkippable && ctx._probe === void 0 && !startsFirstSet(combinator, input, pos)) {
|
|
4137
4278
|
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
@@ -4168,6 +4309,43 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4168
4309
|
expected ??= deriveExpected(combinator);
|
|
4169
4310
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: at, end: at } };
|
|
4170
4311
|
};
|
|
4312
|
+
const scalarExpected = deriveExpected(combinator);
|
|
4313
|
+
const scalarChild = scalarOf(combinator);
|
|
4314
|
+
const scalarSeparator = scalarOf(separator);
|
|
4315
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4316
|
+
let cur = scalarChild(input, pos, ctx);
|
|
4317
|
+
if (cur < 0) {
|
|
4318
|
+
if (min >= 1) {
|
|
4319
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
4320
|
+
return ~pos;
|
|
4321
|
+
}
|
|
4322
|
+
ctx._sv = [];
|
|
4323
|
+
return pos;
|
|
4324
|
+
}
|
|
4325
|
+
const values = [ctx._sv];
|
|
4326
|
+
while (values.length < max && (cur < input.length || values.length < min)) {
|
|
4327
|
+
const beforeSeparator = cur;
|
|
4328
|
+
let separatorPos = cur;
|
|
4329
|
+
if (ctx.trivia) separatorPos = advanceTrivia(input, cur, ctx);
|
|
4330
|
+
const separatorEnd = scalarSeparator(input, separatorPos, ctx);
|
|
4331
|
+
if (separatorEnd < 0) break;
|
|
4332
|
+
let itemPos = separatorEnd;
|
|
4333
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, itemPos, ctx);
|
|
4334
|
+
const itemEnd = scalarChild(input, itemPos, ctx);
|
|
4335
|
+
if (itemEnd < 0) {
|
|
4336
|
+
cur = trailing === "allow" ? separatorEnd : beforeSeparator;
|
|
4337
|
+
break;
|
|
4338
|
+
}
|
|
4339
|
+
values.push(ctx._sv);
|
|
4340
|
+
cur = itemEnd;
|
|
4341
|
+
}
|
|
4342
|
+
if (values.length < min) {
|
|
4343
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
4344
|
+
return ~cur;
|
|
4345
|
+
}
|
|
4346
|
+
ctx._sv = values;
|
|
4347
|
+
return cur;
|
|
4348
|
+
};
|
|
4171
4349
|
return {
|
|
4172
4350
|
_tag: "sepBy",
|
|
4173
4351
|
_meta: meta,
|
|
@@ -4183,6 +4361,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4183
4361
|
// this option surface already; parity is held by test/parity, not by hope.
|
|
4184
4362
|
...keepSeparators ? { keepSeparators: true } : {}
|
|
4185
4363
|
},
|
|
4364
|
+
_parseScalar: keepSeparators ? void 0 : parseScalar,
|
|
4186
4365
|
parse(input, pos, ctx) {
|
|
4187
4366
|
const first = combinator.parse(input, pos, ctx);
|
|
4188
4367
|
const values = [];
|
|
@@ -4798,11 +4977,54 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
4798
4977
|
}
|
|
4799
4978
|
|
|
4800
4979
|
// src/combinators/map.ts
|
|
4980
|
+
var JSON_STRING_BODY = String.raw`(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*`;
|
|
4801
4981
|
function transform(combinator, fn) {
|
|
4982
|
+
const observesSpan = fn.length > 1;
|
|
4983
|
+
const sequenceDef = combinator._def.tag === "sequence" ? combinator._def : void 0;
|
|
4984
|
+
const terms = sequenceDef?.parsers;
|
|
4985
|
+
const inner = terms?.[1];
|
|
4986
|
+
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;
|
|
4987
|
+
const child = scalarOf(combinator);
|
|
4988
|
+
const parseScalar = fused ? (() => {
|
|
4989
|
+
const body = inner._stickyRegex;
|
|
4990
|
+
const tuple = ['"', "", '"'];
|
|
4991
|
+
const expected = [JSON.stringify('"')];
|
|
4992
|
+
return (input, pos, ctx) => {
|
|
4993
|
+
if (ctx.trivia !== void 0) {
|
|
4994
|
+
const end2 = child(input, pos, ctx);
|
|
4995
|
+
if (end2 < 0) return end2;
|
|
4996
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end: end2 }) : fn(ctx._sv);
|
|
4997
|
+
return end2;
|
|
4998
|
+
}
|
|
4999
|
+
if (input.charCodeAt(pos) !== 34) {
|
|
5000
|
+
ctx._fx = expected;
|
|
5001
|
+
return ~pos;
|
|
5002
|
+
}
|
|
5003
|
+
body.lastIndex = pos + 1;
|
|
5004
|
+
const match = body.exec(input);
|
|
5005
|
+
const close = pos + 1 + match[0].length;
|
|
5006
|
+
if (input.charCodeAt(close) !== 34) {
|
|
5007
|
+
ctx._fx = expected;
|
|
5008
|
+
return ~close;
|
|
5009
|
+
}
|
|
5010
|
+
tuple[1] = match[0];
|
|
5011
|
+
const end = close + 1;
|
|
5012
|
+
ctx._sv = observesSpan ? fn(tuple, { start: pos, end }) : fn(tuple);
|
|
5013
|
+
return end;
|
|
5014
|
+
};
|
|
5015
|
+
})() : /* @__PURE__ */ (() => {
|
|
5016
|
+
return (input, pos, ctx) => {
|
|
5017
|
+
const end = child(input, pos, ctx);
|
|
5018
|
+
if (end < 0) return end;
|
|
5019
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end }) : fn(ctx._sv);
|
|
5020
|
+
return end;
|
|
5021
|
+
};
|
|
5022
|
+
})();
|
|
4802
5023
|
return {
|
|
4803
5024
|
_tag: "transform",
|
|
4804
5025
|
_meta: combinator._meta,
|
|
4805
5026
|
_def: { tag: "transform", parser: combinator, fn },
|
|
5027
|
+
_parseScalar: parseScalar,
|
|
4806
5028
|
parse(input, pos, ctx) {
|
|
4807
5029
|
const result = combinator.parse(input, pos, ctx);
|
|
4808
5030
|
if (!result.ok) return result;
|
|
@@ -4817,9 +5039,11 @@ function trivia(combinator) {
|
|
|
4817
5039
|
_meta: {
|
|
4818
5040
|
...combinator._meta,
|
|
4819
5041
|
isTrivia: true,
|
|
5042
|
+
triviaScanner: fastTriviaScanner(combinator),
|
|
4820
5043
|
...kindLabels ? { triviaKindLabels: kindLabels } : {}
|
|
4821
5044
|
},
|
|
4822
5045
|
_def: { tag: "trivia", parser: combinator },
|
|
5046
|
+
_parseScalar: scalarOf(combinator),
|
|
4823
5047
|
parse: combinator.parse.bind(combinator)
|
|
4824
5048
|
};
|
|
4825
5049
|
}
|
|
@@ -5774,7 +5998,7 @@ function buildLexProgramRunner(spec, matchers, classes, expected) {
|
|
|
5774
5998
|
if (!Number.isInteger(spec[2]) || spec[2] < 0) {
|
|
5775
5999
|
throw new TypeError("table balanced lexical program has an invalid scan reference");
|
|
5776
6000
|
}
|
|
5777
|
-
const
|
|
6001
|
+
const run = (_input, _pos, ctx, scan) => {
|
|
5778
6002
|
if (scan === void 0) throw new TypeError("table balanced lexical program lost its scan body");
|
|
5779
6003
|
const result = scan.parse(_input, _pos, ctx);
|
|
5780
6004
|
if (!result.ok) {
|
|
@@ -5784,7 +6008,7 @@ function buildLexProgramRunner(spec, matchers, classes, expected) {
|
|
|
5784
6008
|
}
|
|
5785
6009
|
return result.span.end;
|
|
5786
6010
|
};
|
|
5787
|
-
return Object.assign(
|
|
6011
|
+
return Object.assign(run, { scan: spec[2] });
|
|
5788
6012
|
}
|
|
5789
6013
|
if (spec[0] === 2) return fixedTreeRunner(spec.slice(2), matchers, classes, expected);
|
|
5790
6014
|
if (spec[0] === 1) {
|
|
@@ -6540,6 +6764,22 @@ var Encoder = class {
|
|
|
6540
6764
|
choiceRollbackMasks = /* @__PURE__ */ new Map();
|
|
6541
6765
|
nonCommittingChoiceSites = /* @__PURE__ */ new Set();
|
|
6542
6766
|
failureRollbackCleanSites = /* @__PURE__ */ new Set();
|
|
6767
|
+
/**
|
|
6768
|
+
* `hasSideWriter` memo for `failureNeedsRollback`, shared across every call
|
|
6769
|
+
* for the lifetime of this `Encoder`. A cached entry is written only when
|
|
6770
|
+
* `complete` is true, which means the answer is a path-independent fact
|
|
6771
|
+
* about that combinator node — it does not depend on which root's traversal
|
|
6772
|
+
* asked, only on the node's own reachable subgraph. Scoping the memo per call
|
|
6773
|
+
* (as a local inside `failureNeedsRollback`) was correct but discarded that
|
|
6774
|
+
* fact after every arm, so a grammar with many ordered-choice arms / optional
|
|
6775
|
+
* / attempt sites re-walked the SAME shared rule graph from scratch for each
|
|
6776
|
+
* site — O(sites × graph size) instead of O(graph size). Measured on the
|
|
6777
|
+
* scss-parser grammar (composed CSS-base superset, the deepest/largest of the
|
|
6778
|
+
* four grammars): 47-50s for one `compileRuleMap` with the per-call memo,
|
|
6779
|
+
* versus the whole macro transform completing in under a second once this
|
|
6780
|
+
* memo is hoisted here.
|
|
6781
|
+
*/
|
|
6782
|
+
sideWriterMemo = /* @__PURE__ */ new Map();
|
|
6543
6783
|
labels = void 0;
|
|
6544
6784
|
/** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
|
|
6545
6785
|
activeTrivia = void 0;
|
|
@@ -6965,13 +7205,13 @@ var Encoder = class {
|
|
|
6965
7205
|
const refName = p._ruleName;
|
|
6966
7206
|
const winner = refName === void 0 ? void 0 : this.winners?.[refName];
|
|
6967
7207
|
const root = winner !== void 0 && !winnerWrapsReference2(winner, p) ? winner : p;
|
|
6968
|
-
const sideWriterMemo =
|
|
6969
|
-
const
|
|
7208
|
+
const sideWriterMemo = this.sideWriterMemo;
|
|
7209
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7210
|
+
const hasSideWriter = (current) => {
|
|
6970
7211
|
const cached = sideWriterMemo.get(current);
|
|
6971
7212
|
if (cached !== void 0) return { found: cached, complete: true };
|
|
6972
7213
|
if (seen.has(current)) return { found: false, complete: false };
|
|
6973
|
-
|
|
6974
|
-
next.add(current);
|
|
7214
|
+
seen.add(current);
|
|
6975
7215
|
const def = current._def;
|
|
6976
7216
|
let result;
|
|
6977
7217
|
switch (def.tag) {
|
|
@@ -6986,11 +7226,11 @@ var Encoder = class {
|
|
|
6986
7226
|
const name = current._ruleName;
|
|
6987
7227
|
const resolvedWinner = name === void 0 ? void 0 : this.winners?.[name];
|
|
6988
7228
|
if (resolvedWinner !== void 0 && !winnerWrapsReference2(resolvedWinner, current)) {
|
|
6989
|
-
result = hasSideWriter(resolvedWinner
|
|
7229
|
+
result = hasSideWriter(resolvedWinner);
|
|
6990
7230
|
break;
|
|
6991
7231
|
}
|
|
6992
7232
|
try {
|
|
6993
|
-
result = hasSideWriter(def.thunk()
|
|
7233
|
+
result = hasSideWriter(def.thunk());
|
|
6994
7234
|
} catch {
|
|
6995
7235
|
result = { found: true, complete: true };
|
|
6996
7236
|
}
|
|
@@ -7000,7 +7240,7 @@ var Encoder = class {
|
|
|
7000
7240
|
let complete = true;
|
|
7001
7241
|
result = { found: false, complete: true };
|
|
7002
7242
|
for (const child of childrenOf2(def)) {
|
|
7003
|
-
const childResult = hasSideWriter(child
|
|
7243
|
+
const childResult = hasSideWriter(child);
|
|
7004
7244
|
if (childResult.found) {
|
|
7005
7245
|
result = { found: true, complete: true };
|
|
7006
7246
|
break;
|
|
@@ -7010,6 +7250,7 @@ var Encoder = class {
|
|
|
7010
7250
|
if (!result.found) result = { found: false, complete };
|
|
7011
7251
|
}
|
|
7012
7252
|
}
|
|
7253
|
+
seen.delete(current);
|
|
7013
7254
|
if (result.found || result.complete) sideWriterMemo.set(current, result.found);
|
|
7014
7255
|
return result;
|
|
7015
7256
|
};
|
|
@@ -7783,15 +8024,15 @@ function parseStringShape(source) {
|
|
|
7783
8024
|
if (source.length < 3 || source[source.length - 1] !== q2) return null;
|
|
7784
8025
|
const inner = source.slice(1, -1);
|
|
7785
8026
|
const CLS = String.raw`\[\^((?:\\.|[^\]])+)\]`;
|
|
7786
|
-
const
|
|
8027
|
+
const ESC = String.raw`\\\\(\.|\[\\s\\S\]|\[\\S\\s\])`;
|
|
7787
8028
|
let body;
|
|
7788
8029
|
let esc;
|
|
7789
|
-
let m = new RegExp(`^\\((?:\\?:)?${CLS}\\|${
|
|
8030
|
+
let m = new RegExp(`^\\((?:\\?:)?${CLS}\\|${ESC}\\)\\*$`).exec(inner);
|
|
7790
8031
|
if (m) {
|
|
7791
8032
|
body = m[1];
|
|
7792
8033
|
esc = m[2];
|
|
7793
8034
|
} else {
|
|
7794
|
-
m = new RegExp(`^\\((?:\\?:)?${
|
|
8035
|
+
m = new RegExp(`^\\((?:\\?:)?${ESC}\\|${CLS}\\)\\*$`).exec(inner);
|
|
7795
8036
|
if (m) {
|
|
7796
8037
|
esc = m[1];
|
|
7797
8038
|
body = m[2];
|
|
@@ -9354,6 +9595,9 @@ if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTrivi
|
|
|
9354
9595
|
function q(s) {
|
|
9355
9596
|
return JSON.stringify(s);
|
|
9356
9597
|
}
|
|
9598
|
+
function isAsciiOnlyClass(cls) {
|
|
9599
|
+
return cls !== null && cls !== void 0 && cls.hi.length === 0;
|
|
9600
|
+
}
|
|
9357
9601
|
var NO_SINKS = { fd: false, er: false };
|
|
9358
9602
|
function sinkSlots(t, s) {
|
|
9359
9603
|
return `${s.fd ? `,${t}fd=0` : ""}${s.er ? `,${t}er=0` : ""}`;
|
|
@@ -9464,7 +9708,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
9464
9708
|
const { code, k, fx, disp, dsp, triviaLabelled } = t;
|
|
9465
9709
|
const swapLegal = !cfg.trackLines;
|
|
9466
9710
|
const hostCst = cfg.hostCst;
|
|
9467
|
-
const
|
|
9711
|
+
const REC = prog.rec === 1 && cfg.tolerant;
|
|
9468
9712
|
if (cfg.coverage) throw new Unemittable("a coverage assembly");
|
|
9469
9713
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
9470
9714
|
const reachable = [...reachableSites(code, roots)];
|
|
@@ -9543,7 +9787,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
9543
9787
|
const op = code[ip];
|
|
9544
9788
|
sinkBits.set(
|
|
9545
9789
|
ip,
|
|
9546
|
-
op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT ||
|
|
9790
|
+
op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC && (op === OP_REP || op === OP_REPV) ? 2 : 0)
|
|
9547
9791
|
);
|
|
9548
9792
|
}
|
|
9549
9793
|
const sinkKids = [];
|
|
@@ -9900,12 +10144,13 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
9900
10144
|
return `${head}EC.e=pos;return ''}`;
|
|
9901
10145
|
case OP_GATE: {
|
|
9902
10146
|
const child = link(code[ip + 2]);
|
|
9903
|
-
const
|
|
10147
|
+
const resolved = t.cc[code[ip + 1]];
|
|
10148
|
+
const ci = classes.push([resolved]) - 1;
|
|
9904
10149
|
classPlan.push([code[ip + 1]]);
|
|
9905
10150
|
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
9906
10151
|
const xf = fxRef(code[ip + 3]);
|
|
9907
10152
|
return `${head}
|
|
9908
|
-
if(
|
|
10153
|
+
if(${staticBuild && isAsciiOnlyClass(resolved) ? `${cls}.ascii[input.charCodeAt(pos)]!==1` : `!classHas(${cls},lead(input,pos))`}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
9909
10154
|
return ${child}(input,pos,ctx)
|
|
9910
10155
|
}`;
|
|
9911
10156
|
}
|
|
@@ -9947,7 +10192,7 @@ if(v!==FAIL)return v
|
|
|
9947
10192
|
const err={_tag:'parseError',span:${prog.lines === 1 ? "spanLines(ctx,pos,pos)" : "{start:pos,end:pos}"},expected:${xf}}
|
|
9948
10193
|
const es=ctx._errors
|
|
9949
10194
|
if(es!==undefined)es.push(err)
|
|
9950
|
-
${
|
|
10195
|
+
${REC ? "if(ctx._tolerant===true)captureError(ctx,err)\n" : ""}ctx._fc=false
|
|
9951
10196
|
EC.e=pos
|
|
9952
10197
|
return err
|
|
9953
10198
|
}`;
|
|
@@ -10066,7 +10311,7 @@ return v
|
|
|
10066
10311
|
}
|
|
10067
10312
|
case OP_LEX_PROGRAM: {
|
|
10068
10313
|
const programId = code[ip + 1];
|
|
10069
|
-
const
|
|
10314
|
+
const run = hoist("lexProgram", `LEXPROG[${programId}]`);
|
|
10070
10315
|
const scanId = t.lexPrograms[programId].scan;
|
|
10071
10316
|
if (scanId !== void 0) return `${head}
|
|
10072
10317
|
const sTri=ctx.trivia,sKinds=ctx.triviaKindLabels,sScan=_pfScan
|
|
@@ -10084,7 +10329,7 @@ ctx._cstTriviaLog=undefined
|
|
|
10084
10329
|
ctx._triviaLog=undefined
|
|
10085
10330
|
ctx._rootTriviaLog=undefined
|
|
10086
10331
|
let e
|
|
10087
|
-
try{e=${
|
|
10332
|
+
try{e=${run}(input,pos,ctx,SCANS[${scanId}])}finally{
|
|
10088
10333
|
_pfScan=sScan
|
|
10089
10334
|
ctx.trivia=sTri
|
|
10090
10335
|
ctx.triviaKindLabels=sKinds
|
|
@@ -10103,7 +10348,7 @@ EC.e=e
|
|
|
10103
10348
|
return v
|
|
10104
10349
|
}`;
|
|
10105
10350
|
return `${head}
|
|
10106
|
-
const e=${
|
|
10351
|
+
const e=${run}(input,pos,ctx)
|
|
10107
10352
|
if(e<0)return FAIL
|
|
10108
10353
|
const v=input.slice(pos,e)
|
|
10109
10354
|
if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
|
|
@@ -10114,7 +10359,7 @@ return v
|
|
|
10114
10359
|
/* ── transaction ─────────────────────────────────────────────────────── */
|
|
10115
10360
|
case OP_ATTEMPT: {
|
|
10116
10361
|
const child = link(code[ip + 1]);
|
|
10117
|
-
const clean = !
|
|
10362
|
+
const clean = !REC && failureRollbackClean(prog, ip);
|
|
10118
10363
|
const p = tmp();
|
|
10119
10364
|
return `${head}
|
|
10120
10365
|
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
@@ -10167,7 +10412,7 @@ return null
|
|
|
10167
10412
|
}
|
|
10168
10413
|
case OP_OPT: {
|
|
10169
10414
|
const child = link(code[ip + 1]);
|
|
10170
|
-
const clean = !
|
|
10415
|
+
const clean = !REC && failureRollbackClean(prog, ip);
|
|
10171
10416
|
const p = tmp();
|
|
10172
10417
|
return `${head}
|
|
10173
10418
|
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
@@ -10197,15 +10442,15 @@ return v
|
|
|
10197
10442
|
const childIp = code[base + i];
|
|
10198
10443
|
kids.push(code[childIp] === OP_ADJ ? "" : link(childIp));
|
|
10199
10444
|
}
|
|
10200
|
-
const sy =
|
|
10445
|
+
const sy = REC ? `${tmp()}sy` : "";
|
|
10201
10446
|
const pub = (i) => {
|
|
10202
10447
|
const s = sentRef(code[base + n + i]);
|
|
10203
10448
|
return s === "undefined" ? `ctx._sync=${sy}` : `ctx._sync=${s}??${sy}`;
|
|
10204
10449
|
};
|
|
10205
10450
|
const parts = [head];
|
|
10206
|
-
if (
|
|
10451
|
+
if (REC) parts.push(`const ${sy}=ctx._sync`, "try{", pub(0));
|
|
10207
10452
|
parts.push(`const v0=${kids[0]}(input,pos,ctx)`, "if(v0===FAIL)return FAIL");
|
|
10208
|
-
const close = () =>
|
|
10453
|
+
const close = () => REC ? `${parts.join("\n")}
|
|
10209
10454
|
}finally{ctx._sync=${sy}}
|
|
10210
10455
|
}` : `${parts.join("\n")}
|
|
10211
10456
|
}`;
|
|
@@ -10218,7 +10463,7 @@ return v
|
|
|
10218
10463
|
for (let i = 1; i < n; i++) {
|
|
10219
10464
|
const vn = `v${i}`;
|
|
10220
10465
|
parts.push(`let ${vn}`);
|
|
10221
|
-
if (
|
|
10466
|
+
if (REC) parts.push(pub(i));
|
|
10222
10467
|
const childIp = code[base + i];
|
|
10223
10468
|
if (code[childIp] === OP_ADJ) {
|
|
10224
10469
|
const negated = code[childIp + 1] === 1;
|
|
@@ -10248,10 +10493,11 @@ return v
|
|
|
10248
10493
|
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
10249
10494
|
const hiArr = table.hi;
|
|
10250
10495
|
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
10496
|
+
const directAscii = staticBuild && table.hi.length === 0;
|
|
10251
10497
|
return `${head}
|
|
10252
|
-
const c
|
|
10498
|
+
const c=${directAscii ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
10253
10499
|
let arm=-1
|
|
10254
|
-
if(c>=0&&c<128){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
10500
|
+
if(${directAscii ? "c<128" : "c>=0&&c<128"}){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
10255
10501
|
${hiArr.length === 0 ? "" : `else if(c>=128){const h=${hoist("hi", `DISP[${di}].hi`)}
|
|
10256
10502
|
for(let i=0;i<h.length;i+=3){if(c>=h[i]&&c<=h[i+1]){arm=h[i+2];break}}}`}
|
|
10257
10503
|
if(arm>=0){
|
|
@@ -10273,7 +10519,9 @@ return FAIL
|
|
|
10273
10519
|
const di = code[ip + 1];
|
|
10274
10520
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
10275
10521
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
10276
|
-
const
|
|
10522
|
+
const maskable = n <= 32;
|
|
10523
|
+
const directAsciiMask = staticBuild && maskable && gates.every(isAsciiOnlyClass);
|
|
10524
|
+
const gateRefs = directAsciiMask ? [] : Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
10277
10525
|
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
10278
10526
|
const pretests = Array.from({ length: n }, (_, i) => {
|
|
10279
10527
|
if (tokenCandidate?.arm === i) {
|
|
@@ -10293,12 +10541,11 @@ return FAIL
|
|
|
10293
10541
|
const sequence6 = largeChoiceScalarSequences.get(code[base + i]);
|
|
10294
10542
|
return sequence6 === void 0 ? void 0 : { sequence: scalarSequenceRef(sequence6) };
|
|
10295
10543
|
});
|
|
10296
|
-
const maskable = n <= 32;
|
|
10297
10544
|
const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
|
|
10298
10545
|
if (maskable) maskPlan.push(~di);
|
|
10299
10546
|
const p = tmp();
|
|
10300
10547
|
const encodedRollbackMask = choiceRollbackMask(prog, ip) ?? -1;
|
|
10301
|
-
const rollbackMask =
|
|
10548
|
+
const rollbackMask = REC ? -1 : encodedRollbackMask;
|
|
10302
10549
|
const hasRollback = rollbackMask !== 0;
|
|
10303
10550
|
const startFailureExact = arms.every((_arm, i) => {
|
|
10304
10551
|
const terminal = leadingScalarTerminal(code, code[base + i], 0, false);
|
|
@@ -10355,16 +10602,16 @@ ${merge}
|
|
|
10355
10602
|
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
10356
10603
|
return FAIL`;
|
|
10357
10604
|
return `${head}
|
|
10358
|
-
const c
|
|
10605
|
+
const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
10359
10606
|
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
10360
10607
|
${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
|
|
10361
10608
|
${maskable ? `if(c<128){
|
|
10362
|
-
const bits=${maskName}[c<0?128:c]
|
|
10609
|
+
const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
10363
10610
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
10364
10611
|
${lazyArms(true)}
|
|
10365
|
-
}else{
|
|
10612
|
+
}${directAsciiMask ? "" : `else{
|
|
10366
10613
|
${lazyArms(false)}
|
|
10367
|
-
}
|
|
10614
|
+
}`}
|
|
10368
10615
|
` : lazyArms(false)}
|
|
10369
10616
|
${finish}
|
|
10370
10617
|
}`;
|
|
@@ -10415,7 +10662,7 @@ if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0
|
|
|
10415
10662
|
${rollbackFor(i)}
|
|
10416
10663
|
}${routeMiss}${sequenceMiss}`;
|
|
10417
10664
|
}).join("\n") : "";
|
|
10418
|
-
const generalArms = arms.map((arm, i) => {
|
|
10665
|
+
const generalArms = directAsciiMask ? "" : arms.map((arm, i) => {
|
|
10419
10666
|
const pretest = pretests[i];
|
|
10420
10667
|
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
10421
10668
|
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("||")})`;
|
|
@@ -10445,12 +10692,12 @@ ${rollbackFor(i)}
|
|
|
10445
10692
|
}${miss}`;
|
|
10446
10693
|
}).join("\n");
|
|
10447
10694
|
return `${head}
|
|
10448
|
-
const c
|
|
10695
|
+
const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
10449
10696
|
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
10450
10697
|
let acc
|
|
10451
10698
|
let best=pos
|
|
10452
10699
|
${maskable ? `if(c<128){
|
|
10453
|
-
const bits=${maskName}[c<0?128:c]
|
|
10700
|
+
const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
10454
10701
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
10455
10702
|
${startFailureExact ? "" : "let prev=0"}
|
|
10456
10703
|
${maskArms}
|
|
@@ -10545,14 +10792,18 @@ return [key,v]
|
|
|
10545
10792
|
const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
|
|
10546
10793
|
const collect = op === OP_REP;
|
|
10547
10794
|
let itemCls;
|
|
10548
|
-
|
|
10795
|
+
let itemAscii = false;
|
|
10796
|
+
if (!REC) {
|
|
10549
10797
|
const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
|
|
10550
10798
|
if (itemClassIndex >= 0) {
|
|
10551
|
-
const
|
|
10799
|
+
const resolved = t.cc[itemClassIndex];
|
|
10800
|
+
const ci = classes.push([resolved]) - 1;
|
|
10552
10801
|
classPlan.push([itemClassIndex]);
|
|
10553
10802
|
itemCls = hoist("ri", `CLS[${ci}][0]`);
|
|
10803
|
+
itemAscii = staticBuild && isAsciiOnlyClass(resolved);
|
|
10554
10804
|
}
|
|
10555
10805
|
}
|
|
10806
|
+
const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
|
|
10556
10807
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
10557
10808
|
const p = tmp();
|
|
10558
10809
|
const via = sep2 !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
|
|
@@ -10590,11 +10841,11 @@ ${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
|
10590
10841
|
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}
|
|
10591
10842
|
}`;
|
|
10592
10843
|
const my = `${p}my`;
|
|
10593
|
-
const recFx =
|
|
10594
|
-
const sepSent =
|
|
10844
|
+
const recFx = REC ? fxRef(code[ip + 6]) : "";
|
|
10845
|
+
const sepSent = REC ? sentRef(code[ip + 7]) : "undefined";
|
|
10595
10846
|
const recSent = sep2 === void 0 ? my : sepSent === "undefined" ? `orSentinel(${my},undefined)` : `orSentinel(${sepSent}??${my},${sepSent}===undefined?undefined:${my})`;
|
|
10596
10847
|
const recGate = sep2 !== void 0 || min === 0 ? "" : `count>=${min}&&`;
|
|
10597
|
-
const recBranch = !
|
|
10848
|
+
const recBranch = !REC ? "" : `if(ctx._tolerant===true&&${my}!==undefined&&${recGate}!matchesAt(${my},input,itemStart,ctx)){
|
|
10598
10849
|
${sep2 === void 0 ? `${rb}
|
|
10599
10850
|
` : ""}const rr=recoverScan(input,itemStart,ctx,${recSent},${recFx})
|
|
10600
10851
|
${collect ? "out.push(rr.error)\n" : ""}captureError(ctx,rr.error)
|
|
@@ -10605,14 +10856,14 @@ continue
|
|
|
10605
10856
|
`;
|
|
10606
10857
|
return `${head}
|
|
10607
10858
|
const out=${collect ? "[]" : "undefined"}
|
|
10608
|
-
${knownTrivia === void 0 ? "const hasTrivia=ctx.trivia!==undefined\n" : ""}${L.buf ? "" : "const needMark=_rollbackNeeded(ctx)\n"}${
|
|
10859
|
+
${knownTrivia === void 0 ? "const hasTrivia=ctx.trivia!==undefined\n" : ""}${L.buf ? "" : "const needMark=_rollbackNeeded(ctx)\n"}${REC ? `const ${my}=ctx._sync
|
|
10609
10860
|
` : ""}${itemCls === void 0 ? "" : `const ${p}gate=ctx._probe===undefined
|
|
10610
10861
|
`}let cur=pos
|
|
10611
10862
|
let count=0
|
|
10612
10863
|
for(;;){
|
|
10613
10864
|
${max >= 0 ? `if(count>=${max})break
|
|
10614
10865
|
` : ""}${sep2 !== void 0 ? `if(count>0&&count>=${min}&&cur>=input.length)break
|
|
10615
|
-
` : ""}${itemCls !== void 0 && sep2 === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}
|
|
10866
|
+
` : ""}${itemCls !== void 0 && sep2 === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}&&${itemMiss("cur")})break
|
|
10616
10867
|
` : ""}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` : ""}
|
|
10617
10868
|
${markBody}
|
|
10618
10869
|
let itemStart=cur
|
|
@@ -10637,14 +10888,14 @@ itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(inp
|
|
|
10637
10888
|
${rb}
|
|
10638
10889
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
10639
10890
|
}
|
|
10640
|
-
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate
|
|
10891
|
+
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&${itemMiss("itemStart")}){
|
|
10641
10892
|
${rb}
|
|
10642
10893
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
10643
10894
|
}
|
|
10644
10895
|
`}ctx._fc=false
|
|
10645
10896
|
const v=${child}(input,itemStart,ctx)
|
|
10646
10897
|
if(v===FAIL){
|
|
10647
|
-
${
|
|
10898
|
+
${REC ? `if(ctx._fc===true){
|
|
10648
10899
|
${rb}
|
|
10649
10900
|
return FAIL
|
|
10650
10901
|
}
|
|
@@ -11215,7 +11466,7 @@ function assemble(t, prog, cfg) {
|
|
|
11215
11466
|
const triviaScan = t.triviaScan;
|
|
11216
11467
|
const swapLegal = !cfg.trackLines;
|
|
11217
11468
|
const hostCst = cfg.hostCst;
|
|
11218
|
-
const
|
|
11469
|
+
const REC = prog.rec === 1 && cfg.tolerant;
|
|
11219
11470
|
const sentinels = /* @__PURE__ */ new Map();
|
|
11220
11471
|
function sentinelFor(cls) {
|
|
11221
11472
|
if (cls < 0) return void 0;
|
|
@@ -12216,7 +12467,7 @@ function assemble(t, prog, cfg) {
|
|
|
12216
12467
|
const child = link(code[ip + 1]);
|
|
12217
12468
|
const xf = fx[code[ip + 2]];
|
|
12218
12469
|
const expectSpan = (ctx, pos) => prog.lines === 1 ? spanLines(ctx, pos, pos) : { start: pos, end: pos };
|
|
12219
|
-
if (
|
|
12470
|
+
if (REC) {
|
|
12220
12471
|
return (input, pos, ctx) => {
|
|
12221
12472
|
const v = child(input, pos, ctx);
|
|
12222
12473
|
if (v !== FAIL) return v;
|
|
@@ -12523,8 +12774,8 @@ function assemble(t, prog, cfg) {
|
|
|
12523
12774
|
};
|
|
12524
12775
|
}
|
|
12525
12776
|
case OP_LEX_PROGRAM: {
|
|
12526
|
-
const
|
|
12527
|
-
const scanId =
|
|
12777
|
+
const run = t.lexPrograms[code[ip + 1]];
|
|
12778
|
+
const scanId = run.scan;
|
|
12528
12779
|
if (scanId !== void 0) {
|
|
12529
12780
|
return (input, pos, ctx) => {
|
|
12530
12781
|
const sTrivia = ctx.trivia, sKinds = ctx.triviaKindLabels;
|
|
@@ -12545,7 +12796,7 @@ function assemble(t, prog, cfg) {
|
|
|
12545
12796
|
ctx._rootTriviaLog = void 0;
|
|
12546
12797
|
let end;
|
|
12547
12798
|
try {
|
|
12548
|
-
end =
|
|
12799
|
+
end = run(input, pos, ctx, scans[scanId]);
|
|
12549
12800
|
} finally {
|
|
12550
12801
|
SCAN = sScan;
|
|
12551
12802
|
ctx.trivia = sTrivia;
|
|
@@ -12566,7 +12817,7 @@ function assemble(t, prog, cfg) {
|
|
|
12566
12817
|
};
|
|
12567
12818
|
}
|
|
12568
12819
|
return (input, pos, ctx) => {
|
|
12569
|
-
const end =
|
|
12820
|
+
const end = run(input, pos, ctx);
|
|
12570
12821
|
if (end < 0) return FAIL;
|
|
12571
12822
|
const value = input.slice(pos, end);
|
|
12572
12823
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
|
|
@@ -12663,7 +12914,7 @@ function assemble(t, prog, cfg) {
|
|
|
12663
12914
|
return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
|
|
12664
12915
|
};
|
|
12665
12916
|
};
|
|
12666
|
-
if (
|
|
12917
|
+
if (REC) {
|
|
12667
12918
|
const first2 = link(code[base]);
|
|
12668
12919
|
const firstSync = sentinelFor(code[base + n]);
|
|
12669
12920
|
const runnerAt = (i) => {
|
|
@@ -13120,7 +13371,7 @@ function assemble(t, prog, cfg) {
|
|
|
13120
13371
|
if (n === 2 || n === 3) {
|
|
13121
13372
|
const a0 = link(code[base]), a1 = link(code[base + 1]);
|
|
13122
13373
|
const a2 = n === 3 ? link(code[base + 2]) : void 0;
|
|
13123
|
-
const predecide = !hostCst && !
|
|
13374
|
+
const predecide = !hostCst && !REC && !cfg.probe && !cfg.coverage && !cfg.trackLines;
|
|
13124
13375
|
const p0ip = predecide ? leadingScalarTerminal(code, code[base], 2, true, true) : -1;
|
|
13125
13376
|
const p1ip = predecide ? leadingScalarTerminal(code, code[base + 1], 2, true, true) : -1;
|
|
13126
13377
|
const p2ip = predecide && n === 3 ? leadingScalarTerminal(code, code[base + 2], 2, true, true) : -1;
|
|
@@ -13511,10 +13762,10 @@ function assemble(t, prog, cfg) {
|
|
|
13511
13762
|
const itemFx = reportItem ? fx[code[ip + 6]] : EMPTY_FX2;
|
|
13512
13763
|
const collect = op === OP_REP;
|
|
13513
13764
|
const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
|
|
13514
|
-
const itemClass = !
|
|
13765
|
+
const itemClass = !REC && itemClassIndex >= 0 ? cc[itemClassIndex] : void 0;
|
|
13515
13766
|
const itemMayStart = itemClass === void 0 ? void 0 : (input, pos) => classHas2(itemClass, lead(input, pos));
|
|
13516
13767
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
13517
|
-
if (
|
|
13768
|
+
if (REC) {
|
|
13518
13769
|
const itemFx2 = fx[code[ip + 6]];
|
|
13519
13770
|
const sepSent = sentinelFor(code[ip + 7]);
|
|
13520
13771
|
return (input, pos, ctx) => {
|
|
@@ -14021,7 +14272,7 @@ function assemble(t, prog, cfg) {
|
|
|
14021
14272
|
lead,
|
|
14022
14273
|
asciiFoldKey,
|
|
14023
14274
|
ROUTED_FX,
|
|
14024
|
-
|
|
14275
|
+
REC ? prog.cc.map((_, i) => sentinelFor(i)) : EMPTY_SENTS,
|
|
14025
14276
|
matchesAt,
|
|
14026
14277
|
recoverScan,
|
|
14027
14278
|
orSentinel,
|
|
@@ -14103,7 +14354,7 @@ function assemble(t, prog, cfg) {
|
|
|
14103
14354
|
// — a strict one emits no reader — and through the SAME `sentinelFor` memo
|
|
14104
14355
|
// the closure pieces use, so both engines resync to the same combinator
|
|
14105
14356
|
// object rather than to two separately constructed ones.
|
|
14106
|
-
|
|
14357
|
+
REC ? prog.cc.map((_, i) => sentinelFor(i)) : EMPTY_SENTS,
|
|
14107
14358
|
matchesAt,
|
|
14108
14359
|
recoverScan,
|
|
14109
14360
|
orSentinel,
|
|
@@ -15136,36 +15387,36 @@ function findRegexFragments(visited) {
|
|
|
15136
15387
|
if (branches.length >= 2) runs.add(branches.join("|"));
|
|
15137
15388
|
for (let i = 0; i < branches.length; i++) {
|
|
15138
15389
|
for (let n = 2; n <= Math.min(MAX_RUN, branches.length - i); n++) {
|
|
15139
|
-
const
|
|
15140
|
-
if (
|
|
15141
|
-
runs.add(
|
|
15390
|
+
const run = branches.slice(i, i + n).join("|");
|
|
15391
|
+
if (run.length < 4) continue;
|
|
15392
|
+
runs.add(run);
|
|
15142
15393
|
}
|
|
15143
15394
|
}
|
|
15144
15395
|
}
|
|
15145
|
-
for (const
|
|
15146
|
-
let e = byRun.get(
|
|
15396
|
+
for (const run of runs) {
|
|
15397
|
+
let e = byRun.get(run);
|
|
15147
15398
|
if (e === void 0) {
|
|
15148
|
-
e = { occ: [], nodes: /* @__PURE__ */ new Set(), branches:
|
|
15149
|
-
byRun.set(
|
|
15399
|
+
e = { occ: [], nodes: /* @__PURE__ */ new Set(), branches: run.split("|").length };
|
|
15400
|
+
byRun.set(run, e);
|
|
15150
15401
|
}
|
|
15151
15402
|
if (e.nodes.has(v.p)) continue;
|
|
15152
15403
|
e.nodes.add(v.p);
|
|
15153
15404
|
e.occ.push({ site: v.site, source: d.source });
|
|
15154
15405
|
}
|
|
15155
15406
|
}
|
|
15156
|
-
const candidates = [...byRun.entries()].filter(([, e]) => e.occ.length >= 2).map(([
|
|
15407
|
+
const candidates = [...byRun.entries()].filter(([, e]) => e.occ.length >= 2).map(([run, e]) => ({ run, e, savings: (e.occ.length - 1) * run.length })).sort((a, b) => b.e.occ.length - a.e.occ.length || b.savings - a.savings || b.run.length - a.run.length);
|
|
15157
15408
|
const kept = [];
|
|
15158
15409
|
for (const c of candidates) {
|
|
15159
15410
|
if (kept.some((k) => k.e.occ.length >= c.e.occ.length && `|${k.run}|`.includes(`|${c.run}|`))) continue;
|
|
15160
15411
|
kept.push(c);
|
|
15161
15412
|
}
|
|
15162
|
-
return kept.map(({ run
|
|
15413
|
+
return kept.map(({ run, e }) => ({
|
|
15163
15414
|
kind: "regex-fragment",
|
|
15164
|
-
id: `regex-fragment:${
|
|
15165
|
-
fragment:
|
|
15415
|
+
id: `regex-fragment:${run}`,
|
|
15416
|
+
fragment: run,
|
|
15166
15417
|
branches: e.branches,
|
|
15167
15418
|
count: e.occ.length,
|
|
15168
|
-
savings: (e.occ.length - 1) *
|
|
15419
|
+
savings: (e.occ.length - 1) * run.length,
|
|
15169
15420
|
sources: e.occ.map((o) => `/${o.source}/`),
|
|
15170
15421
|
sites: e.occ.map((o) => o.site),
|
|
15171
15422
|
suggestion: `this ${e.branches}-branch alternation is re-spelled in ${e.occ.length} DISTINCT regex() terminals. Hoist it to one shared source string and interpolate it (\`new RegExp(\\\`\u2026\\\${OP}\u2026\\\`)\`) or lift the shared part into its own terminal \u2014 an edit to the operator set currently has to land in ${e.occ.length} places, and the analysis cannot tell you when one of them drifts.`
|
|
@@ -16675,7 +16926,7 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
16675
16926
|
}
|
|
16676
16927
|
|
|
16677
16928
|
// src/version.ts
|
|
16678
|
-
var PARSEMAN_VERSION = "0.50.
|
|
16929
|
+
var PARSEMAN_VERSION = "0.50.3";
|
|
16679
16930
|
|
|
16680
16931
|
// src/compiler/compile-linkable-table.ts
|
|
16681
16932
|
function isLocal(rule) {
|
|
@@ -16768,72 +17019,6 @@ function cstBuildHost(typeOrOptions, children3, _fields, span, rawChildren, triv
|
|
|
16768
17019
|
cstBuildHost._parsemanCstOutput = true;
|
|
16769
17020
|
var COMPOSED_PIECES = /* @__PURE__ */ Symbol.for("parseman.composedPieces");
|
|
16770
17021
|
|
|
16771
|
-
// src/cst/trivia-entries.ts
|
|
16772
|
-
var EMPTY_INDICES = Object.freeze([]);
|
|
16773
|
-
var EMPTY_GAPS = Object.freeze([]);
|
|
16774
|
-
|
|
16775
|
-
// src/functional/run.ts
|
|
16776
|
-
var SELECT_EXAMPLE = "run(entry, input, { rootTrivia: { select: ['blockComment', 'lineComment'] } })";
|
|
16777
|
-
var REMOVED_RUN_RESULT_FIELDS = [
|
|
16778
|
-
[
|
|
16779
|
-
"triviaMap",
|
|
16780
|
-
`It was a dense root-trivia index built on every parse; root trivia is now an OPT-IN sparse capture, because most grammars paid for an index they never read. Migration: name the trivia labels your grammar defines \u2014 ${SELECT_EXAMPLE} \u2014 and read \`RunResult.rootTrivia\`, whose \`.index\` carries the labels and gap lookups \`triviaMap\` exposed.`
|
|
16781
|
-
],
|
|
16782
|
-
[
|
|
16783
|
-
"triviaLog",
|
|
16784
|
-
`It was the flat \`start, end[, kindIndex]\` log every other trivia view was derived from, and it is no longer allocated at all \u2014 not empty, absent. Migration: request the labels you need \u2014 ${SELECT_EXAMPLE} \u2014 and read \`RunResult.rootTrivia.rows\`. Do NOT reuse a stride-2/3 reader: rows are a different width and a different unit (one row per SELECTED marker, not one per trivia chunk), so an old loop reads confidently wrong offsets rather than failing.`
|
|
16785
|
-
],
|
|
16786
|
-
[
|
|
16787
|
-
"triviaKindLabels",
|
|
16788
|
-
`It was already optional, so nothing ever flagged its disappearance \u2014 and \`triviaKindMask(undefined, \u2026)\` means "capture everything", so reading it now silently WIDENS capture instead of erroring. Migration: request labels \u2014 ${SELECT_EXAMPLE} \u2014 then the set you asked for is \`RunResult.rootTrivia.select\` and the resolved table is \`RunResult.rootTrivia.index.labels\`.`
|
|
16789
|
-
]
|
|
16790
|
-
];
|
|
16791
|
-
var RunResultRecord = class {
|
|
16792
|
-
constructor(ok, value, span, expected, errors, unconsumedFrom) {
|
|
16793
|
-
this.ok = ok;
|
|
16794
|
-
this.value = value;
|
|
16795
|
-
this.span = span;
|
|
16796
|
-
this.expected = expected;
|
|
16797
|
-
this.errors = errors;
|
|
16798
|
-
this.unconsumedFrom = unconsumedFrom;
|
|
16799
|
-
}
|
|
16800
|
-
};
|
|
16801
|
-
var RunResultWithRootTrivia = class {
|
|
16802
|
-
constructor(ok, value, span, expected, errors, rootTrivia, unconsumedFrom) {
|
|
16803
|
-
this.ok = ok;
|
|
16804
|
-
this.value = value;
|
|
16805
|
-
this.span = span;
|
|
16806
|
-
this.expected = expected;
|
|
16807
|
-
this.errors = errors;
|
|
16808
|
-
this.rootTrivia = rootTrivia;
|
|
16809
|
-
this.unconsumedFrom = unconsumedFrom;
|
|
16810
|
-
}
|
|
16811
|
-
};
|
|
16812
|
-
for (const proto of [RunResultRecord.prototype, RunResultWithRootTrivia.prototype]) {
|
|
16813
|
-
for (const [name, detail] of REMOVED_RUN_RESULT_FIELDS) {
|
|
16814
|
-
Object.defineProperty(proto, name, {
|
|
16815
|
-
configurable: true,
|
|
16816
|
-
enumerable: false,
|
|
16817
|
-
get() {
|
|
16818
|
-
throw new TypeError(
|
|
16819
|
-
`RunResult.${name} was REMOVED in parseman 0.44.0 and has no default replacement. ${detail}`
|
|
16820
|
-
);
|
|
16821
|
-
}
|
|
16822
|
-
});
|
|
16823
|
-
}
|
|
16824
|
-
}
|
|
16825
|
-
|
|
16826
|
-
// src/analysis/choice-cost-render.ts
|
|
16827
|
-
var ESC = "\x1B";
|
|
16828
|
-
var ANSI = {
|
|
16829
|
-
dim: `${ESC}[2m`,
|
|
16830
|
-
bold: `${ESC}[1m`,
|
|
16831
|
-
red: `${ESC}[31m`,
|
|
16832
|
-
yellow: `${ESC}[33m`,
|
|
16833
|
-
cyan: `${ESC}[36m`,
|
|
16834
|
-
reset: `${ESC}[0m`
|
|
16835
|
-
};
|
|
16836
|
-
|
|
16837
17022
|
// src/combinators/gate.ts
|
|
16838
17023
|
function gate(predicate) {
|
|
16839
17024
|
const meta = {
|