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/spec/index.js
CHANGED
|
@@ -270,9 +270,43 @@ function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
+
// src/combinators/scalar.ts
|
|
274
|
+
var SCALAR_TAG = /^(?:literal|regex|keywords|sequence|choice|many|oneOrMore|optional|transform|trivia|grammar|sepBy|lazy)$/;
|
|
275
|
+
function scalarOf(combinator) {
|
|
276
|
+
return combinator._parseScalar;
|
|
277
|
+
}
|
|
278
|
+
function scalarTree(parser2, seen) {
|
|
279
|
+
if (seen.has(parser2)) return true;
|
|
280
|
+
if (parser2._parseScalar === void 0) return false;
|
|
281
|
+
seen.add(parser2);
|
|
282
|
+
const def = parser2._def;
|
|
283
|
+
if (!SCALAR_TAG.test(def.tag)) return false;
|
|
284
|
+
if ("parsers" in def && !def.parsers.every((child) => scalarTree(child, seen))) return false;
|
|
285
|
+
if ("parser" in def && !scalarTree(def.parser, seen)) return false;
|
|
286
|
+
if ("separator" in def && !scalarTree(def.separator, seen)) return false;
|
|
287
|
+
return def.tag !== "lazy" || scalarTree(def.thunk(), seen);
|
|
288
|
+
}
|
|
289
|
+
function scalarRootOf(combinator) {
|
|
290
|
+
const scalar = combinator._parseScalar;
|
|
291
|
+
const def = combinator._def;
|
|
292
|
+
return scalar !== void 0 && def.tag === "grammar" && scalarTree(def.parser, /* @__PURE__ */ new Set()) ? scalar : void 0;
|
|
293
|
+
}
|
|
294
|
+
|
|
273
295
|
// src/combinators/ref.ts
|
|
296
|
+
function withRuleTrivia(trivia2, ctx, run) {
|
|
297
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
298
|
+
ctx.trivia = trivia2;
|
|
299
|
+
ctx.triviaKindLabels = trivia2._meta.triviaKindLabels;
|
|
300
|
+
try {
|
|
301
|
+
return run();
|
|
302
|
+
} finally {
|
|
303
|
+
ctx.trivia = void 0;
|
|
304
|
+
ctx.triviaKindLabels = savedLabels;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
274
307
|
function ref() {
|
|
275
308
|
let resolved = null;
|
|
309
|
+
let resolvedScalar = null;
|
|
276
310
|
let ownBoundary = false;
|
|
277
311
|
const meta = {
|
|
278
312
|
firstSet: any(),
|
|
@@ -289,25 +323,28 @@ function ref() {
|
|
|
289
323
|
return resolved;
|
|
290
324
|
}
|
|
291
325
|
},
|
|
326
|
+
_parseScalar(input, pos, ctx) {
|
|
327
|
+
const scalar = resolvedScalar;
|
|
328
|
+
if (!scalar) throw new Error("ref<T>() used before .define() was called");
|
|
329
|
+
const gt = meta.grammarTrivia;
|
|
330
|
+
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
331
|
+
return withRuleTrivia(gt, ctx, () => scalar(input, pos, ctx));
|
|
332
|
+
}
|
|
333
|
+
return scalar(input, pos, ctx);
|
|
334
|
+
},
|
|
292
335
|
parse(input, pos, ctx) {
|
|
293
|
-
|
|
336
|
+
const parser2 = resolved;
|
|
337
|
+
if (!parser2) throw new Error("ref<T>() used before .define() was called");
|
|
294
338
|
const gt = meta.grammarTrivia;
|
|
295
339
|
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
296
|
-
|
|
297
|
-
ctx.trivia = gt;
|
|
298
|
-
ctx.triviaKindLabels = gt._meta.triviaKindLabels;
|
|
299
|
-
try {
|
|
300
|
-
return resolved.parse(input, pos, ctx);
|
|
301
|
-
} finally {
|
|
302
|
-
ctx.trivia = void 0;
|
|
303
|
-
ctx.triviaKindLabels = savedLabels;
|
|
304
|
-
}
|
|
340
|
+
return withRuleTrivia(gt, ctx, () => parser2.parse(input, pos, ctx));
|
|
305
341
|
}
|
|
306
|
-
return
|
|
342
|
+
return parser2.parse(input, pos, ctx);
|
|
307
343
|
},
|
|
308
344
|
define(p) {
|
|
309
345
|
if (resolved) throw new Error("ref<T>() already defined");
|
|
310
346
|
resolved = p;
|
|
347
|
+
resolvedScalar = scalarOf(p);
|
|
311
348
|
ownBoundary = hasOwnTriviaBoundary(p);
|
|
312
349
|
meta.firstSet = p._meta.firstSet;
|
|
313
350
|
meta.canMatchNewline = p._meta.canMatchNewline;
|
|
@@ -530,7 +567,7 @@ function pushCstLeaf(ctx, leaf2) {
|
|
|
530
567
|
const annotated = leaf2 && typeof leaf2 === "object" && leaf2.span ? { ...leaf2, span: annotateSpanFromLineContext(leaf2.span, ctx) } : leaf2;
|
|
531
568
|
pushCstChild(ctx, annotated, annotated);
|
|
532
569
|
}
|
|
533
|
-
function pushCstChild(ctx, built,
|
|
570
|
+
function pushCstChild(ctx, built, rawEntry) {
|
|
534
571
|
const b = ctx._cstBuf;
|
|
535
572
|
if (b) {
|
|
536
573
|
if (b.rawOnly !== true) {
|
|
@@ -541,16 +578,16 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
541
578
|
} else b.single = built;
|
|
542
579
|
}
|
|
543
580
|
if (b.noRaw === true) b.rawLen = (b.rawLen ?? 0) + 1;
|
|
544
|
-
else if (b.raw) b.raw.push(
|
|
581
|
+
else if (b.raw) b.raw.push(rawEntry);
|
|
545
582
|
else if (b.rawSingle !== void 0) {
|
|
546
|
-
b.raw = [b.rawSingle,
|
|
583
|
+
b.raw = [b.rawSingle, rawEntry];
|
|
547
584
|
b.rawSingle = void 0;
|
|
548
|
-
} else b.rawSingle =
|
|
585
|
+
} else b.rawSingle = rawEntry;
|
|
549
586
|
return;
|
|
550
587
|
}
|
|
551
588
|
if (ctx._cstChildren) ctx._cstChildren.push(built);
|
|
552
589
|
else if (ctx._cstLeaves) ctx._cstLeaves.push(built);
|
|
553
|
-
if (ctx._cstRawChildren) ctx._cstRawChildren.push(
|
|
590
|
+
if (ctx._cstRawChildren) ctx._cstRawChildren.push(rawEntry);
|
|
554
591
|
}
|
|
555
592
|
function cstRawLen(ctx) {
|
|
556
593
|
const b = ctx._cstBuf;
|
|
@@ -693,6 +730,7 @@ function createParseContext() {
|
|
|
693
730
|
_fe: void 0,
|
|
694
731
|
_fx: void 0,
|
|
695
732
|
_fc: void 0,
|
|
733
|
+
_sv: void 0,
|
|
696
734
|
_probe: void 0,
|
|
697
735
|
_cstChildren: void 0,
|
|
698
736
|
_cstLeaves: void 0,
|
|
@@ -1530,6 +1568,24 @@ function parser(opts, root) {
|
|
|
1530
1568
|
const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
|
|
1531
1569
|
const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
|
|
1532
1570
|
const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
|
|
1571
|
+
const rootScalar = scalarOf(root);
|
|
1572
|
+
const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
|
|
1573
|
+
const parseScalar = scalarEligible ? (input, pos, ctx) => {
|
|
1574
|
+
const savedTrivia = ctx.trivia;
|
|
1575
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
1576
|
+
if (clearTrivia) {
|
|
1577
|
+
ctx.trivia = void 0;
|
|
1578
|
+
ctx.triviaKindLabels = void 0;
|
|
1579
|
+
} else if (scopeTrivia !== void 0) {
|
|
1580
|
+
ctx.trivia = scopeTrivia;
|
|
1581
|
+
ctx.triviaKindLabels = scopeLabels;
|
|
1582
|
+
}
|
|
1583
|
+
const end = rootScalar(input, pos, ctx);
|
|
1584
|
+
ctx.trivia = savedTrivia;
|
|
1585
|
+
ctx.triviaKindLabels = savedLabels;
|
|
1586
|
+
return end;
|
|
1587
|
+
} : void 0;
|
|
1588
|
+
let publicScalar;
|
|
1533
1589
|
const grammar = {
|
|
1534
1590
|
_tag: "grammar",
|
|
1535
1591
|
_meta: {
|
|
@@ -1553,7 +1609,20 @@ function parser(opts, root) {
|
|
|
1553
1609
|
constructionTrackLines: trackLinesPolicy,
|
|
1554
1610
|
...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
|
|
1555
1611
|
},
|
|
1612
|
+
_parseScalar: parseScalar,
|
|
1556
1613
|
parse(input, pos, _ctx) {
|
|
1614
|
+
if (pos === void 0 && _ctx === void 0) {
|
|
1615
|
+
publicScalar ??= scalarRootOf(grammar) ?? null;
|
|
1616
|
+
if (publicScalar) {
|
|
1617
|
+
const ctx2 = createParseContext();
|
|
1618
|
+
const end = publicScalar(input, 0, ctx2);
|
|
1619
|
+
if (end < 0) {
|
|
1620
|
+
const at = ~end;
|
|
1621
|
+
return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
|
|
1622
|
+
}
|
|
1623
|
+
return { ok: true, value: ctx2._sv, span: { start: 0, end } };
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1557
1626
|
if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
|
|
1558
1627
|
const trackLines = trackLinesOf(_ctx);
|
|
1559
1628
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
@@ -2146,10 +2215,32 @@ function regex(pattern, flags = "") {
|
|
|
2146
2215
|
const canMatchNewline = raw.canMatchNewline;
|
|
2147
2216
|
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
2148
2217
|
const def = { tag: "regex", source, flags: resolvedFlags };
|
|
2218
|
+
const expected = directTerminalFailureExpected(def);
|
|
2219
|
+
const parseScalar = (input, pos, ctx) => {
|
|
2220
|
+
const scanEnd = scan?.(input, pos);
|
|
2221
|
+
if (scanEnd !== void 0) {
|
|
2222
|
+
if (scanEnd === null) {
|
|
2223
|
+
ctx._fx = expected;
|
|
2224
|
+
return ~pos;
|
|
2225
|
+
}
|
|
2226
|
+
ctx._sv = input.slice(pos, scanEnd);
|
|
2227
|
+
return scanEnd;
|
|
2228
|
+
}
|
|
2229
|
+
anchored.lastIndex = pos;
|
|
2230
|
+
const match = anchored.exec(input);
|
|
2231
|
+
if (match === null) {
|
|
2232
|
+
ctx._fx = expected;
|
|
2233
|
+
return ~pos;
|
|
2234
|
+
}
|
|
2235
|
+
ctx._sv = match[0];
|
|
2236
|
+
return pos + match[0].length;
|
|
2237
|
+
};
|
|
2149
2238
|
return {
|
|
2150
2239
|
_tag: "regex",
|
|
2151
2240
|
_meta: meta,
|
|
2152
2241
|
_def: def,
|
|
2242
|
+
_stickyRegex: anchored,
|
|
2243
|
+
_parseScalar: parseScalar,
|
|
2153
2244
|
parse(input, pos, ctx) {
|
|
2154
2245
|
const scanEnd = scan?.(input, pos);
|
|
2155
2246
|
if (scanEnd !== void 0) {
|
|
@@ -2194,6 +2285,28 @@ function literal(value, opts = {}) {
|
|
|
2194
2285
|
isTrivia: false
|
|
2195
2286
|
};
|
|
2196
2287
|
const canMatchNewline = meta.canMatchNewline;
|
|
2288
|
+
const parseScalar = !caseInsensitive && value.length === 1 ? (() => {
|
|
2289
|
+
const code = value.charCodeAt(0);
|
|
2290
|
+
return (input, pos, ctx) => {
|
|
2291
|
+
if (input.charCodeAt(pos) === code) {
|
|
2292
|
+
ctx._sv = value;
|
|
2293
|
+
return pos + 1;
|
|
2294
|
+
}
|
|
2295
|
+
ctx._fx = expected;
|
|
2296
|
+
return ~pos;
|
|
2297
|
+
};
|
|
2298
|
+
})() : (input, pos, ctx) => {
|
|
2299
|
+
const end = pos + value.length;
|
|
2300
|
+
if (end <= input.length) {
|
|
2301
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
2302
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
2303
|
+
ctx._sv = matchedValue;
|
|
2304
|
+
return end;
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
ctx._fx = expected;
|
|
2308
|
+
return ~pos;
|
|
2309
|
+
};
|
|
2197
2310
|
if (caseInsensitive) {
|
|
2198
2311
|
const upper = value.toUpperCase();
|
|
2199
2312
|
const lower = value.toLowerCase();
|
|
@@ -2234,6 +2347,7 @@ function literal(value, opts = {}) {
|
|
|
2234
2347
|
_tag: "literal",
|
|
2235
2348
|
_meta: meta,
|
|
2236
2349
|
_def: { tag: "literal", value, caseInsensitive },
|
|
2350
|
+
_parseScalar: parseScalar,
|
|
2237
2351
|
parse
|
|
2238
2352
|
};
|
|
2239
2353
|
}
|
|
@@ -2301,16 +2415,26 @@ function keywords(words, opts = {}) {
|
|
|
2301
2415
|
caseInsensitive: opts.caseInsensitive ?? false,
|
|
2302
2416
|
boundary: opts.boundary
|
|
2303
2417
|
};
|
|
2418
|
+
const expected = directTerminalFailureExpected(def);
|
|
2419
|
+
const parseScalar = (input, pos, ctx) => {
|
|
2420
|
+
re.lastIndex = pos;
|
|
2421
|
+
const m = re.exec(input);
|
|
2422
|
+
if (m === null) {
|
|
2423
|
+
ctx._fx = expected;
|
|
2424
|
+
return ~pos;
|
|
2425
|
+
}
|
|
2426
|
+
ctx._sv = m[0];
|
|
2427
|
+
return pos + m[0].length;
|
|
2428
|
+
};
|
|
2304
2429
|
return {
|
|
2305
2430
|
_tag: "keywords",
|
|
2306
2431
|
_meta: meta,
|
|
2307
2432
|
_def: def,
|
|
2433
|
+
_parseScalar: parseScalar,
|
|
2308
2434
|
parse(input, pos, ctx) {
|
|
2309
2435
|
re.lastIndex = pos;
|
|
2310
2436
|
const m = re.exec(input);
|
|
2311
|
-
if (m === null
|
|
2312
|
-
return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
2313
|
-
}
|
|
2437
|
+
if (m === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
2314
2438
|
const value = m[0];
|
|
2315
2439
|
const span = { start: pos, end: pos + value.length };
|
|
2316
2440
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
@@ -2341,6 +2465,9 @@ var fastScanner3;
|
|
|
2341
2465
|
function needsDeferredTriviaCommit(ctx) {
|
|
2342
2466
|
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
2343
2467
|
}
|
|
2468
|
+
function needsTriviaRollback(ctx) {
|
|
2469
|
+
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;
|
|
2470
|
+
}
|
|
2344
2471
|
function saveTriviaMark(ctx) {
|
|
2345
2472
|
const m = saveCstMark(ctx);
|
|
2346
2473
|
return {
|
|
@@ -2452,7 +2579,8 @@ function advanceTrivia(input, cur, ctx) {
|
|
|
2452
2579
|
const triviaP = ctx.trivia;
|
|
2453
2580
|
if (!triviaP) return cur;
|
|
2454
2581
|
if (!ctx.trackLines) {
|
|
2455
|
-
const
|
|
2582
|
+
const classified = triviaP._meta.triviaScanner;
|
|
2583
|
+
const fast2 = classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
2456
2584
|
if (fast2) return fast2(input, cur);
|
|
2457
2585
|
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
2458
2586
|
const tr2 = triviaP.parse(input, cur, createDetachedParseContext(ctx.trackLines, ctx.state));
|
|
@@ -3043,6 +3171,7 @@ function sequence(...parsers) {
|
|
|
3043
3171
|
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
3044
3172
|
}
|
|
3045
3173
|
const hasAdjacency = adjacency !== null;
|
|
3174
|
+
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
3046
3175
|
const meta = {
|
|
3047
3176
|
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
3048
3177
|
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
@@ -3051,165 +3180,96 @@ function sequence(...parsers) {
|
|
|
3051
3180
|
isTrivia: false
|
|
3052
3181
|
};
|
|
3053
3182
|
const def = { tag: "sequence", parsers };
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
3057
|
-
const fs = parsers.slice(i + 1).reduce(
|
|
3058
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
3059
|
-
{ kind: "empty" }
|
|
3060
|
-
);
|
|
3061
|
-
return firstSetSentinel(fs);
|
|
3062
|
-
});
|
|
3063
|
-
const values = def.valueUnused ? void 0 : [];
|
|
3183
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
3184
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3064
3185
|
let cur = pos;
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
const mTlog = cstTlLen(ctx);
|
|
3077
|
-
const mLog = ctx._triviaLog?.length ?? 0;
|
|
3078
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3079
|
-
let scanEnd;
|
|
3080
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
3081
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
3082
|
-
} else {
|
|
3083
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
3084
|
-
}
|
|
3085
|
-
const scanTlog = cstTlLen(ctx);
|
|
3086
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
3087
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3088
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
3089
|
-
if (!result2.ok) return result2;
|
|
3090
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
3091
|
-
else rollbackScannedTriviaAt(
|
|
3092
|
-
ctx,
|
|
3093
|
-
mTlog,
|
|
3094
|
-
scanTlog,
|
|
3095
|
-
mLog,
|
|
3096
|
-
scanLog,
|
|
3097
|
-
mRootLog,
|
|
3098
|
-
scanRootLog
|
|
3099
|
-
);
|
|
3100
|
-
if (values !== void 0) values.push(result2.value);
|
|
3101
|
-
continue;
|
|
3102
|
-
}
|
|
3103
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
3104
|
-
if (!result.ok) return result;
|
|
3105
|
-
if (values !== void 0) values.push(result.value);
|
|
3106
|
-
cur = result.span.end;
|
|
3186
|
+
if (strictArity !== 0) {
|
|
3187
|
+
cur = scalarParsers[0](input, cur, ctx);
|
|
3188
|
+
if (cur < 0) return cur;
|
|
3189
|
+
const first = ctx._sv;
|
|
3190
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
3191
|
+
cur = scalarParsers[1](input, cur, ctx);
|
|
3192
|
+
if (cur < 0) return cur;
|
|
3193
|
+
const second = ctx._sv;
|
|
3194
|
+
if (strictArity === 2) {
|
|
3195
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second];
|
|
3196
|
+
return cur;
|
|
3107
3197
|
}
|
|
3108
|
-
|
|
3109
|
-
|
|
3198
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
3199
|
+
cur = scalarParsers[2](input, cur, ctx);
|
|
3200
|
+
if (cur < 0) return cur;
|
|
3201
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second, ctx._sv];
|
|
3202
|
+
return cur;
|
|
3110
3203
|
}
|
|
3111
|
-
return {
|
|
3112
|
-
ok: true,
|
|
3113
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
3114
|
-
value: values ?? void 0,
|
|
3115
|
-
span: { start: pos, end: cur }
|
|
3116
|
-
};
|
|
3117
|
-
}
|
|
3118
|
-
function parseAdjacent(input, pos, ctx) {
|
|
3119
3204
|
const values = def.valueUnused ? void 0 : [];
|
|
3120
|
-
let
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3133
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
3134
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
3135
|
-
} else {
|
|
3136
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
3137
|
-
}
|
|
3138
|
-
const scanTlog = cstTlLen(ctx);
|
|
3139
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
3140
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3141
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
3142
|
-
if (!result2.ok) return result2;
|
|
3143
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
3144
|
-
else rollbackScannedTriviaAt(
|
|
3145
|
-
ctx,
|
|
3146
|
-
mTlog,
|
|
3147
|
-
scanTlog,
|
|
3148
|
-
mLog,
|
|
3149
|
-
scanLog,
|
|
3150
|
-
mRootLog,
|
|
3151
|
-
scanRootLog
|
|
3152
|
-
);
|
|
3153
|
-
if (values !== void 0) values.push(result2.value);
|
|
3154
|
-
continue;
|
|
3155
|
-
}
|
|
3156
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
3157
|
-
if (!result.ok) return result;
|
|
3158
|
-
if (values !== void 0) values.push(result.value);
|
|
3159
|
-
cur = result.span.end;
|
|
3160
|
-
}
|
|
3161
|
-
return {
|
|
3162
|
-
ok: true,
|
|
3163
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
3164
|
-
value: values ?? void 0,
|
|
3165
|
-
span: { start: pos, end: cur }
|
|
3166
|
-
};
|
|
3167
|
-
}
|
|
3205
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
3206
|
+
let termPos = cur;
|
|
3207
|
+
if (i > 0 && ctx.trivia) termPos = advanceTrivia(input, cur, ctx);
|
|
3208
|
+
const end = scalarParsers[i](input, termPos, ctx);
|
|
3209
|
+
if (end < 0) return end;
|
|
3210
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
3211
|
+
if (end > termPos || termPos === cur) cur = end;
|
|
3212
|
+
}
|
|
3213
|
+
ctx._sv = values;
|
|
3214
|
+
return cur;
|
|
3215
|
+
};
|
|
3216
|
+
let followSentinels;
|
|
3168
3217
|
return {
|
|
3169
3218
|
_tag: "sequence",
|
|
3170
3219
|
_meta: meta,
|
|
3171
3220
|
_def: def,
|
|
3221
|
+
_parseScalar: hasAdjacency ? void 0 : parseScalar,
|
|
3172
3222
|
parse(input, pos, ctx) {
|
|
3173
|
-
|
|
3174
|
-
if (
|
|
3223
|
+
const tolerant = ctx._tolerant === true;
|
|
3224
|
+
if (tolerant) {
|
|
3225
|
+
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
3226
|
+
parsers.slice(i + 1).reduce(
|
|
3227
|
+
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
3228
|
+
{ kind: "empty" }
|
|
3229
|
+
)
|
|
3230
|
+
));
|
|
3231
|
+
}
|
|
3232
|
+
const inheritedSync = ctx._sync;
|
|
3233
|
+
const deferredTrivia = needsDeferredTriviaCommit(ctx);
|
|
3175
3234
|
const values = def.valueUnused ? void 0 : [];
|
|
3176
3235
|
let cur = pos;
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
const
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
} else {
|
|
3186
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
3236
|
+
try {
|
|
3237
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
3238
|
+
if (tolerant) ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
3239
|
+
const assertion = adjacency?.[i];
|
|
3240
|
+
if (assertion) {
|
|
3241
|
+
if (!holdsAdjacency(input, cur, ctx, assertion)) return adjacencyFail(cur, assertion);
|
|
3242
|
+
if (values !== void 0) values.push(null);
|
|
3243
|
+
continue;
|
|
3187
3244
|
}
|
|
3188
|
-
|
|
3189
|
-
const
|
|
3190
|
-
const
|
|
3191
|
-
const
|
|
3192
|
-
if (
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3245
|
+
let termPos = cur;
|
|
3246
|
+
const markTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
3247
|
+
const markLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
3248
|
+
const markRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
3249
|
+
if (ctx.trivia && i > 0) {
|
|
3250
|
+
termPos = deferredTrivia ? commitTriviaScan(scanTriviaCompact(input, cur, ctx)) : advanceTrivia(input, cur, ctx);
|
|
3251
|
+
}
|
|
3252
|
+
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
3253
|
+
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
3254
|
+
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
3255
|
+
const result = parsers[i].parse(input, termPos, ctx);
|
|
3256
|
+
if (!result.ok) return result;
|
|
3257
|
+
if (values !== void 0) values.push(result.value);
|
|
3258
|
+
if (result.span.end > termPos || termPos === cur) cur = result.span.end;
|
|
3259
|
+
else if (deferredTrivia) {
|
|
3196
3260
|
rollbackScannedTriviaAt(
|
|
3197
3261
|
ctx,
|
|
3198
|
-
|
|
3262
|
+
markTlog,
|
|
3199
3263
|
scanTlog,
|
|
3200
|
-
|
|
3264
|
+
markLog,
|
|
3201
3265
|
scanLog,
|
|
3202
|
-
|
|
3266
|
+
markRootLog,
|
|
3203
3267
|
scanRootLog
|
|
3204
3268
|
);
|
|
3205
3269
|
}
|
|
3206
|
-
if (values !== void 0) values.push(result2.value);
|
|
3207
|
-
continue;
|
|
3208
3270
|
}
|
|
3209
|
-
|
|
3210
|
-
if (
|
|
3211
|
-
if (values !== void 0) values.push(result.value);
|
|
3212
|
-
cur = result.span.end;
|
|
3271
|
+
} finally {
|
|
3272
|
+
if (tolerant) ctx._sync = inheritedSync;
|
|
3213
3273
|
}
|
|
3214
3274
|
return {
|
|
3215
3275
|
ok: true,
|
|
@@ -3341,7 +3401,8 @@ function choice(...args) {
|
|
|
3341
3401
|
disjoint
|
|
3342
3402
|
};
|
|
3343
3403
|
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
3344
|
-
const
|
|
3404
|
+
const ordered = strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix";
|
|
3405
|
+
const autoNot = !disjoint && !hasGates && ordered ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
3345
3406
|
let greedyLitMap = null;
|
|
3346
3407
|
let sortedParsers = null;
|
|
3347
3408
|
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
@@ -3355,6 +3416,37 @@ function choice(...args) {
|
|
|
3355
3416
|
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
3356
3417
|
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
3357
3418
|
}
|
|
3419
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
3420
|
+
const scalarEligible = !hasGates && parsers.every((p) => p._parseScalar !== void 0) && (disjoint || ordered);
|
|
3421
|
+
const scalarExpected = parsers.flatMap(deriveExpected);
|
|
3422
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3423
|
+
if (disjoint) {
|
|
3424
|
+
const code = pos < input.length ? input.codePointAt(pos) : -1;
|
|
3425
|
+
let idx = code >= 0 && code < 128 ? asciiDispatch[code] : -1;
|
|
3426
|
+
if (idx < 0 && code >= 0) {
|
|
3427
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
3428
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
3429
|
+
idx = i;
|
|
3430
|
+
break;
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
if (idx >= 0) {
|
|
3435
|
+
const gate = gates[idx];
|
|
3436
|
+
if (!gate || gate(ctx.state)) return scalarParsers[idx](input, pos, ctx);
|
|
3437
|
+
ctx._fx = deriveExpected(parsers[idx]);
|
|
3438
|
+
return ~pos;
|
|
3439
|
+
}
|
|
3440
|
+
} else {
|
|
3441
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
3442
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
3443
|
+
const end = scalarParsers[i](input, pos, ctx);
|
|
3444
|
+
if (end >= 0 && (!autoNot[i] || !autoNotFires(input, end, autoNot[i]))) return end;
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
ctx._fx = scalarExpected;
|
|
3448
|
+
return ~pos;
|
|
3449
|
+
};
|
|
3358
3450
|
return {
|
|
3359
3451
|
_tag: "choice",
|
|
3360
3452
|
_meta: meta,
|
|
@@ -3366,6 +3458,7 @@ function choice(...args) {
|
|
|
3366
3458
|
strategy: strategy ?? { tag: "firstMatch" },
|
|
3367
3459
|
autoNot
|
|
3368
3460
|
},
|
|
3461
|
+
_parseScalar: scalarEligible ? parseScalar : void 0,
|
|
3369
3462
|
parse(input, pos, ctx) {
|
|
3370
3463
|
const expected = [];
|
|
3371
3464
|
let expectedAt = pos;
|
|
@@ -3897,8 +3990,8 @@ function attempt(parser2) {
|
|
|
3897
3990
|
}
|
|
3898
3991
|
|
|
3899
3992
|
// src/combinators/repeat.ts
|
|
3900
|
-
function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
3901
|
-
const mark = saveTriviaMark(ctx);
|
|
3993
|
+
function repItem(combinator, input, cur, ctx, guardable, mandatory, rollbackNeeded) {
|
|
3994
|
+
const mark = rollbackNeeded ? saveTriviaMark(ctx) : void 0;
|
|
3902
3995
|
let pos = cur;
|
|
3903
3996
|
if (ctx.trivia) {
|
|
3904
3997
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -3908,24 +4001,24 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
|
3908
4001
|
}
|
|
3909
4002
|
}
|
|
3910
4003
|
if (pos >= input.length && !mandatory) {
|
|
3911
|
-
rollbackTrivia(ctx, mark);
|
|
4004
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3912
4005
|
return "stop";
|
|
3913
4006
|
}
|
|
3914
4007
|
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
3915
|
-
rollbackTrivia(ctx, mark);
|
|
4008
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3916
4009
|
return "stop";
|
|
3917
4010
|
}
|
|
3918
4011
|
const result = combinator.parse(input, pos, ctx);
|
|
3919
4012
|
if (!result.ok) {
|
|
3920
|
-
rollbackTrivia(ctx, mark);
|
|
4013
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3921
4014
|
if (result.committed) return { fail: result, failPos: pos };
|
|
3922
4015
|
return { fail: result, failPos: pos };
|
|
3923
4016
|
}
|
|
3924
4017
|
if (result.span.end === pos && !mandatory) {
|
|
3925
|
-
rollbackTrivia(ctx, mark);
|
|
4018
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3926
4019
|
return "stop";
|
|
3927
4020
|
}
|
|
3928
|
-
return
|
|
4021
|
+
return result;
|
|
3929
4022
|
}
|
|
3930
4023
|
function resolveBounds(what, opts) {
|
|
3931
4024
|
const min = opts.min ?? 0;
|
|
@@ -3938,6 +4031,21 @@ function resolveBounds(what, opts) {
|
|
|
3938
4031
|
if (max < min) bad(`max (${max}) is less than min (${min}) \u2014 the combinator could never succeed`);
|
|
3939
4032
|
return { min, max };
|
|
3940
4033
|
}
|
|
4034
|
+
function repeatScalarTail(combinator, child, input, cur, ctx, guardable, values, remaining) {
|
|
4035
|
+
while (cur < input.length && remaining > 0) {
|
|
4036
|
+
let itemPos = cur;
|
|
4037
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4038
|
+
if (itemPos >= input.length) break;
|
|
4039
|
+
if (guardable && !startsFirstSet(combinator, input, itemPos)) break;
|
|
4040
|
+
const end = child(input, itemPos, ctx);
|
|
4041
|
+
if (end <= itemPos) break;
|
|
4042
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4043
|
+
cur = end;
|
|
4044
|
+
remaining--;
|
|
4045
|
+
}
|
|
4046
|
+
ctx._sv = values;
|
|
4047
|
+
return cur;
|
|
4048
|
+
}
|
|
3941
4049
|
function many(combinator, opts = {}) {
|
|
3942
4050
|
const { min, max } = resolveBounds("many()", opts);
|
|
3943
4051
|
if (min >= 1) return atLeast(combinator, min, max);
|
|
@@ -3949,17 +4057,21 @@ function many(combinator, opts = {}) {
|
|
|
3949
4057
|
const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max } };
|
|
3950
4058
|
let expected;
|
|
3951
4059
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4060
|
+
const scalarChild = scalarOf(combinator);
|
|
4061
|
+
const parseScalar = (input, pos, ctx) => repeatScalarTail(combinator, scalarChild, input, pos, ctx, guardable, def.valueUnused ? void 0 : [], max);
|
|
3952
4062
|
return {
|
|
3953
4063
|
_tag: "many",
|
|
3954
4064
|
_meta: meta,
|
|
3955
4065
|
_def: def,
|
|
4066
|
+
_parseScalar: parseScalar,
|
|
3956
4067
|
parse(input, pos, ctx) {
|
|
3957
4068
|
const values = def.valueUnused ? void 0 : [];
|
|
4069
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
3958
4070
|
let cur = pos;
|
|
3959
4071
|
let count = 0;
|
|
3960
4072
|
while (cur < input.length) {
|
|
3961
4073
|
if (count >= max) break;
|
|
3962
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
4074
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
3963
4075
|
if (item === "stop") break;
|
|
3964
4076
|
if ("fail" in item) {
|
|
3965
4077
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -3976,7 +4088,7 @@ function many(combinator, opts = {}) {
|
|
|
3976
4088
|
}
|
|
3977
4089
|
if (values !== void 0) values.push(item.value);
|
|
3978
4090
|
count++;
|
|
3979
|
-
cur = item.end;
|
|
4091
|
+
cur = item.span.end;
|
|
3980
4092
|
}
|
|
3981
4093
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
3982
4094
|
}
|
|
@@ -3994,30 +4106,47 @@ function atLeast(combinator, min, max) {
|
|
|
3994
4106
|
const def = { tag: "oneOrMore", parser: combinator, min, ...max === Infinity ? {} : { max } };
|
|
3995
4107
|
let expected;
|
|
3996
4108
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4109
|
+
const scalarChild = scalarOf(combinator);
|
|
4110
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4111
|
+
let cur = scalarChild(input, pos, ctx);
|
|
4112
|
+
if (cur < 0) return cur;
|
|
4113
|
+
const values = def.valueUnused ? void 0 : [ctx._sv];
|
|
4114
|
+
for (let count = 1; count < min; count++) {
|
|
4115
|
+
let itemPos = cur;
|
|
4116
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4117
|
+
const end = scalarChild(input, itemPos, ctx);
|
|
4118
|
+
if (end < 0) return ~cur;
|
|
4119
|
+
cur = end;
|
|
4120
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4121
|
+
}
|
|
4122
|
+
return repeatScalarTail(combinator, scalarChild, input, cur, ctx, guardable, values, max - min);
|
|
4123
|
+
};
|
|
3997
4124
|
return {
|
|
3998
4125
|
_tag: "oneOrMore",
|
|
3999
4126
|
_meta: meta,
|
|
4000
4127
|
_def: def,
|
|
4128
|
+
_parseScalar: parseScalar,
|
|
4001
4129
|
parse(input, pos, ctx) {
|
|
4002
4130
|
const first = combinator.parse(input, pos, ctx);
|
|
4003
4131
|
if (!first.ok) return first;
|
|
4004
4132
|
const values = def.valueUnused ? void 0 : [first.value];
|
|
4133
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4005
4134
|
let cur = first.span.end;
|
|
4006
4135
|
let count = 1;
|
|
4007
4136
|
while (count < min) {
|
|
4008
|
-
const item = repItem(combinator, input, cur, ctx, guardable, true);
|
|
4137
|
+
const item = repItem(combinator, input, cur, ctx, guardable, true, rollbackNeeded);
|
|
4009
4138
|
if (item === "stop" || "fail" in item) {
|
|
4010
4139
|
if (item !== "stop" && !item.fail.ok && item.fail.committed) return item.fail;
|
|
4011
4140
|
expected ??= deriveExpected(combinator);
|
|
4012
4141
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: cur, end: cur } };
|
|
4013
4142
|
}
|
|
4014
4143
|
if (values !== void 0) values.push(item.value);
|
|
4015
|
-
cur = item.end;
|
|
4144
|
+
cur = item.span.end;
|
|
4016
4145
|
count++;
|
|
4017
4146
|
}
|
|
4018
4147
|
while (cur < input.length) {
|
|
4019
4148
|
if (count >= max) break;
|
|
4020
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
4149
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4021
4150
|
if (item === "stop") break;
|
|
4022
4151
|
if ("fail" in item) {
|
|
4023
4152
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -4034,7 +4163,7 @@ function atLeast(combinator, min, max) {
|
|
|
4034
4163
|
}
|
|
4035
4164
|
if (values !== void 0) values.push(item.value);
|
|
4036
4165
|
count++;
|
|
4037
|
-
cur = item.end;
|
|
4166
|
+
cur = item.span.end;
|
|
4038
4167
|
}
|
|
4039
4168
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4040
4169
|
}
|
|
@@ -4047,10 +4176,22 @@ function optional(combinator) {
|
|
|
4047
4176
|
isTrivia: false
|
|
4048
4177
|
};
|
|
4049
4178
|
const firstSetSkippable = !matchesEmpty(combinator);
|
|
4179
|
+
const scalarChild = scalarOf(combinator);
|
|
4180
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4181
|
+
if (firstSetSkippable && !startsFirstSet(combinator, input, pos)) {
|
|
4182
|
+
ctx._sv = null;
|
|
4183
|
+
return pos;
|
|
4184
|
+
}
|
|
4185
|
+
const end = scalarChild(input, pos, ctx);
|
|
4186
|
+
if (end >= 0) return end;
|
|
4187
|
+
ctx._sv = null;
|
|
4188
|
+
return pos;
|
|
4189
|
+
};
|
|
4050
4190
|
return {
|
|
4051
4191
|
_tag: "optional",
|
|
4052
4192
|
_meta: meta,
|
|
4053
4193
|
_def: { tag: "optional", parser: combinator },
|
|
4194
|
+
_parseScalar: parseScalar,
|
|
4054
4195
|
parse(input, pos, ctx) {
|
|
4055
4196
|
if (firstSetSkippable && ctx._probe === void 0 && !startsFirstSet(combinator, input, pos)) {
|
|
4056
4197
|
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
@@ -4084,6 +4225,43 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4084
4225
|
expected ??= deriveExpected(combinator);
|
|
4085
4226
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: at, end: at } };
|
|
4086
4227
|
};
|
|
4228
|
+
const scalarExpected = deriveExpected(combinator);
|
|
4229
|
+
const scalarChild = scalarOf(combinator);
|
|
4230
|
+
const scalarSeparator = scalarOf(separator);
|
|
4231
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4232
|
+
let cur = scalarChild(input, pos, ctx);
|
|
4233
|
+
if (cur < 0) {
|
|
4234
|
+
if (min >= 1) {
|
|
4235
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
4236
|
+
return ~pos;
|
|
4237
|
+
}
|
|
4238
|
+
ctx._sv = [];
|
|
4239
|
+
return pos;
|
|
4240
|
+
}
|
|
4241
|
+
const values = [ctx._sv];
|
|
4242
|
+
while (values.length < max && (cur < input.length || values.length < min)) {
|
|
4243
|
+
const beforeSeparator = cur;
|
|
4244
|
+
let separatorPos = cur;
|
|
4245
|
+
if (ctx.trivia) separatorPos = advanceTrivia(input, cur, ctx);
|
|
4246
|
+
const separatorEnd = scalarSeparator(input, separatorPos, ctx);
|
|
4247
|
+
if (separatorEnd < 0) break;
|
|
4248
|
+
let itemPos = separatorEnd;
|
|
4249
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, itemPos, ctx);
|
|
4250
|
+
const itemEnd = scalarChild(input, itemPos, ctx);
|
|
4251
|
+
if (itemEnd < 0) {
|
|
4252
|
+
cur = trailing === "allow" ? separatorEnd : beforeSeparator;
|
|
4253
|
+
break;
|
|
4254
|
+
}
|
|
4255
|
+
values.push(ctx._sv);
|
|
4256
|
+
cur = itemEnd;
|
|
4257
|
+
}
|
|
4258
|
+
if (values.length < min) {
|
|
4259
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
4260
|
+
return ~cur;
|
|
4261
|
+
}
|
|
4262
|
+
ctx._sv = values;
|
|
4263
|
+
return cur;
|
|
4264
|
+
};
|
|
4087
4265
|
return {
|
|
4088
4266
|
_tag: "sepBy",
|
|
4089
4267
|
_meta: meta,
|
|
@@ -4099,6 +4277,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4099
4277
|
// this option surface already; parity is held by test/parity, not by hope.
|
|
4100
4278
|
...keepSeparators ? { keepSeparators: true } : {}
|
|
4101
4279
|
},
|
|
4280
|
+
_parseScalar: keepSeparators ? void 0 : parseScalar,
|
|
4102
4281
|
parse(input, pos, ctx) {
|
|
4103
4282
|
const first = combinator.parse(input, pos, ctx);
|
|
4104
4283
|
const values = [];
|
|
@@ -4608,9 +4787,9 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
4608
4787
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
4609
4788
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
4610
4789
|
const built = unwrap && children.length === 1 ? unwrapChild(children[0]) : collapse && children.length === 1 ? children[0] : (cstOutput || !build && project === void 0) && ctx.build?._parsemanCstCollapse && children.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children[0], children, rawChildren) ? children[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children, fields, span, rawChildren, triviaLog, hostState, tags) : projectChild(children, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children, fields, span, rawChildren, triviaLog, hostState, tags) : build(children, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children };
|
|
4611
|
-
const
|
|
4790
|
+
const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
|
|
4612
4791
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
4613
|
-
pushCstChild(ctx, built,
|
|
4792
|
+
pushCstChild(ctx, built, rawEntry);
|
|
4614
4793
|
}
|
|
4615
4794
|
return { ok: true, value: built, span };
|
|
4616
4795
|
}
|
|
@@ -4618,11 +4797,54 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
4618
4797
|
}
|
|
4619
4798
|
|
|
4620
4799
|
// src/combinators/map.ts
|
|
4800
|
+
var JSON_STRING_BODY = String.raw`(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*`;
|
|
4621
4801
|
function transform(combinator, fn) {
|
|
4802
|
+
const observesSpan = fn.length > 1;
|
|
4803
|
+
const sequenceDef = combinator._def.tag === "sequence" ? combinator._def : void 0;
|
|
4804
|
+
const terms = sequenceDef?.parsers;
|
|
4805
|
+
const inner = terms?.[1];
|
|
4806
|
+
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;
|
|
4807
|
+
const child = scalarOf(combinator);
|
|
4808
|
+
const parseScalar = fused ? (() => {
|
|
4809
|
+
const body = inner._stickyRegex;
|
|
4810
|
+
const tuple = ['"', "", '"'];
|
|
4811
|
+
const expected = [JSON.stringify('"')];
|
|
4812
|
+
return (input, pos, ctx) => {
|
|
4813
|
+
if (ctx.trivia !== void 0) {
|
|
4814
|
+
const end2 = child(input, pos, ctx);
|
|
4815
|
+
if (end2 < 0) return end2;
|
|
4816
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end: end2 }) : fn(ctx._sv);
|
|
4817
|
+
return end2;
|
|
4818
|
+
}
|
|
4819
|
+
if (input.charCodeAt(pos) !== 34) {
|
|
4820
|
+
ctx._fx = expected;
|
|
4821
|
+
return ~pos;
|
|
4822
|
+
}
|
|
4823
|
+
body.lastIndex = pos + 1;
|
|
4824
|
+
const match = body.exec(input);
|
|
4825
|
+
const close = pos + 1 + match[0].length;
|
|
4826
|
+
if (input.charCodeAt(close) !== 34) {
|
|
4827
|
+
ctx._fx = expected;
|
|
4828
|
+
return ~close;
|
|
4829
|
+
}
|
|
4830
|
+
tuple[1] = match[0];
|
|
4831
|
+
const end = close + 1;
|
|
4832
|
+
ctx._sv = observesSpan ? fn(tuple, { start: pos, end }) : fn(tuple);
|
|
4833
|
+
return end;
|
|
4834
|
+
};
|
|
4835
|
+
})() : /* @__PURE__ */ (() => {
|
|
4836
|
+
return (input, pos, ctx) => {
|
|
4837
|
+
const end = child(input, pos, ctx);
|
|
4838
|
+
if (end < 0) return end;
|
|
4839
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end }) : fn(ctx._sv);
|
|
4840
|
+
return end;
|
|
4841
|
+
};
|
|
4842
|
+
})();
|
|
4622
4843
|
return {
|
|
4623
4844
|
_tag: "transform",
|
|
4624
4845
|
_meta: combinator._meta,
|
|
4625
4846
|
_def: { tag: "transform", parser: combinator, fn },
|
|
4847
|
+
_parseScalar: parseScalar,
|
|
4626
4848
|
parse(input, pos, ctx) {
|
|
4627
4849
|
const result = combinator.parse(input, pos, ctx);
|
|
4628
4850
|
if (!result.ok) return result;
|
|
@@ -4637,9 +4859,11 @@ function trivia(combinator) {
|
|
|
4637
4859
|
_meta: {
|
|
4638
4860
|
...combinator._meta,
|
|
4639
4861
|
isTrivia: true,
|
|
4862
|
+
triviaScanner: fastTriviaScanner(combinator),
|
|
4640
4863
|
...kindLabels ? { triviaKindLabels: kindLabels } : {}
|
|
4641
4864
|
},
|
|
4642
4865
|
_def: { tag: "trivia", parser: combinator },
|
|
4866
|
+
_parseScalar: scalarOf(combinator),
|
|
4643
4867
|
parse: combinator.parse.bind(combinator)
|
|
4644
4868
|
};
|
|
4645
4869
|
}
|
|
@@ -5113,108 +5337,6 @@ function evalRuleMapIR(ir) {
|
|
|
5113
5337
|
return Object.entries(map);
|
|
5114
5338
|
}
|
|
5115
5339
|
|
|
5116
|
-
// src/table/ops.ts
|
|
5117
|
-
var OP_LIT = 1;
|
|
5118
|
-
var OP_RX = 2;
|
|
5119
|
-
var OP_SEQ = 3;
|
|
5120
|
-
var OP_SEQV = 4;
|
|
5121
|
-
var OP_CHOICE = 5;
|
|
5122
|
-
var OP_REP = 6;
|
|
5123
|
-
var OP_REPV = 7;
|
|
5124
|
-
var OP_OPT = 8;
|
|
5125
|
-
var OP_XFORM = 9;
|
|
5126
|
-
var OP_NODE = 10;
|
|
5127
|
-
var OP_RULE = 11;
|
|
5128
|
-
var OP_GATE = 12;
|
|
5129
|
-
var OP_NOT = 13;
|
|
5130
|
-
var OP_PEEK = 14;
|
|
5131
|
-
var OP_LEAF = 15;
|
|
5132
|
-
var OP_EMPTY = 16;
|
|
5133
|
-
var OP_LIT_TRACK = 17;
|
|
5134
|
-
var OP_RX_TRACK = 18;
|
|
5135
|
-
var OP_NODE_TRACK = 19;
|
|
5136
|
-
var OP_SCOPE = 20;
|
|
5137
|
-
var OP_EXPECT = 21;
|
|
5138
|
-
var OP_SEQX = 22;
|
|
5139
|
-
var OP_SCAN = 23;
|
|
5140
|
-
var OP_FIELD = 24;
|
|
5141
|
-
var OP_LIT_CI = 27;
|
|
5142
|
-
var OP_LIT_CI_TRACK = 28;
|
|
5143
|
-
var OP_TOKEN = 29;
|
|
5144
|
-
var OP_SCOPE_CAP = 30;
|
|
5145
|
-
var OP_WITHCTX = 31;
|
|
5146
|
-
var OP_GUARD = 32;
|
|
5147
|
-
var OP_ADJ = 33;
|
|
5148
|
-
var OP_GREEDY = 34;
|
|
5149
|
-
var OP_REJECT = 35;
|
|
5150
|
-
var OP_ARMGATE = 36;
|
|
5151
|
-
var OP_LIVE = 37;
|
|
5152
|
-
var OP_ATTEMPT = 38;
|
|
5153
|
-
var OP_LABEL = 39;
|
|
5154
|
-
var OP_COV = 40;
|
|
5155
|
-
var OP_SCOPE_PLAIN = 41;
|
|
5156
|
-
var OP_LEX_BODY = 42;
|
|
5157
|
-
var OP_LEX_PROGRAM = 43;
|
|
5158
|
-
var OP_DISPATCH = 25;
|
|
5159
|
-
var OP_ROUTED = 26;
|
|
5160
|
-
var OP_NAMES = {
|
|
5161
|
-
[OP_LIT]: "LIT",
|
|
5162
|
-
[OP_RX]: "RX",
|
|
5163
|
-
[OP_SEQ]: "SEQ",
|
|
5164
|
-
[OP_SEQV]: "SEQV",
|
|
5165
|
-
[OP_CHOICE]: "CHOICE",
|
|
5166
|
-
[OP_REP]: "REP",
|
|
5167
|
-
[OP_REPV]: "REPV",
|
|
5168
|
-
[OP_OPT]: "OPT",
|
|
5169
|
-
[OP_XFORM]: "XFORM",
|
|
5170
|
-
[OP_NODE]: "NODE",
|
|
5171
|
-
[OP_RULE]: "RULE",
|
|
5172
|
-
[OP_GATE]: "GATE",
|
|
5173
|
-
[OP_NOT]: "NOT",
|
|
5174
|
-
[OP_PEEK]: "PEEK",
|
|
5175
|
-
[OP_LEAF]: "LEAF",
|
|
5176
|
-
[OP_EMPTY]: "EMPTY",
|
|
5177
|
-
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
5178
|
-
[OP_RX_TRACK]: "RX_TRACK",
|
|
5179
|
-
[OP_NODE_TRACK]: "NODE_TRACK",
|
|
5180
|
-
[OP_SCOPE]: "SCOPE",
|
|
5181
|
-
[OP_EXPECT]: "EXPECT",
|
|
5182
|
-
[OP_SEQX]: "SEQX",
|
|
5183
|
-
[OP_SCAN]: "SCAN",
|
|
5184
|
-
[OP_FIELD]: "FIELD",
|
|
5185
|
-
[OP_LIT_CI]: "LIT_CI",
|
|
5186
|
-
[OP_LIT_CI_TRACK]: "LIT_CI_TRACK",
|
|
5187
|
-
[OP_DISPATCH]: "DISPATCH",
|
|
5188
|
-
[OP_ROUTED]: "ROUTED",
|
|
5189
|
-
[OP_TOKEN]: "TOKEN",
|
|
5190
|
-
[OP_SCOPE_CAP]: "SCOPE_CAP",
|
|
5191
|
-
[OP_WITHCTX]: "WITHCTX",
|
|
5192
|
-
[OP_GUARD]: "GUARD",
|
|
5193
|
-
[OP_ADJ]: "ADJ",
|
|
5194
|
-
[OP_GREEDY]: "GREEDY",
|
|
5195
|
-
[OP_REJECT]: "REJECT",
|
|
5196
|
-
[OP_ARMGATE]: "ARMGATE",
|
|
5197
|
-
[OP_LIVE]: "LIVE",
|
|
5198
|
-
[OP_ATTEMPT]: "ATTEMPT",
|
|
5199
|
-
[OP_LABEL]: "LABEL",
|
|
5200
|
-
[OP_COV]: "COV",
|
|
5201
|
-
[OP_SCOPE_PLAIN]: "SCOPE_PLAIN",
|
|
5202
|
-
[OP_LEX_BODY]: "LEX_BODY",
|
|
5203
|
-
[OP_LEX_PROGRAM]: "LEX_PROGRAM"
|
|
5204
|
-
};
|
|
5205
|
-
|
|
5206
|
-
// src/table/scan-shapes.ts
|
|
5207
|
-
var META2 = new Set("()[]{}*+?|^$.".split(""));
|
|
5208
|
-
|
|
5209
|
-
// src/table/assemble.ts
|
|
5210
|
-
var EMIT_ENABLED = globalThis.process?.env?.PM_TABLE_EMIT !== "0";
|
|
5211
|
-
var EMPTY_TL2 = Object.freeze([]);
|
|
5212
|
-
var EMPTY_SENTS = Object.freeze([]);
|
|
5213
|
-
|
|
5214
|
-
// src/analysis/duplication.ts
|
|
5215
|
-
var WORD_RE_SRC = "-?[A-Za-z][A-Za-z0-9_-]*";
|
|
5216
|
-
var WORDS_RE = new RegExp(`^${WORD_RE_SRC}(?:\\|${WORD_RE_SRC})*$`);
|
|
5217
|
-
|
|
5218
5340
|
// src/compiler/linker.ts
|
|
5219
5341
|
function normalizeCstCollapse(collapse) {
|
|
5220
5342
|
if (collapse === true) return () => true;
|