parseman 0.50.1 → 0.50.4
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 -229
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +445 -194
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/first-set.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 +22 -11
- package/dist/compiler/token-capability.js.map +2 -2
- package/dist/index.js +446 -195
- 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 -309
- 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 +421 -285
- 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 -191
- 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 +5 -3
- package/src/combinators/choice.ts +34 -1
- package/src/combinators/first-set.ts +33 -7
- 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 +14 -2
- package/src/types.ts +8 -0
- package/src/version.ts +1 -1
package/dist/spec/index.js
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
// src/combinators/first-set.ts
|
|
2
|
-
function
|
|
2
|
+
function winnerForRef(p, resolve) {
|
|
3
3
|
if (resolve === void 0) return void 0;
|
|
4
4
|
const name = p._ruleName;
|
|
5
|
-
|
|
5
|
+
const w = name === void 0 ? void 0 : resolve(name);
|
|
6
|
+
if (w === void 0 || w === p) return void 0;
|
|
7
|
+
let cur = w;
|
|
8
|
+
for (const seen = /* @__PURE__ */ new Set(); !seen.has(cur); ) {
|
|
9
|
+
if (cur === p) return void 0;
|
|
10
|
+
seen.add(cur);
|
|
11
|
+
const cd = cur._def;
|
|
12
|
+
if (cd.tag !== "grammar" && cd.tag !== "trivia") return w;
|
|
13
|
+
cur = cd.parser;
|
|
14
|
+
}
|
|
15
|
+
return w;
|
|
6
16
|
}
|
|
7
17
|
function union(a, b) {
|
|
8
18
|
if (a.kind === "any" || b.kind === "any") return { kind: "any" };
|
|
@@ -100,13 +110,15 @@ function matchesEmptyBody(p, seen, resolve) {
|
|
|
100
110
|
case "grammar":
|
|
101
111
|
case "recover":
|
|
102
112
|
return me(d.parser);
|
|
103
|
-
case "lazy":
|
|
113
|
+
case "lazy": {
|
|
114
|
+
const w = winnerForRef(p, resolve);
|
|
115
|
+
if (w !== void 0) return me(w);
|
|
104
116
|
try {
|
|
105
117
|
return me(d.thunk());
|
|
106
118
|
} catch {
|
|
107
|
-
|
|
108
|
-
return t ? me(t) : true;
|
|
119
|
+
return true;
|
|
109
120
|
}
|
|
121
|
+
}
|
|
110
122
|
default:
|
|
111
123
|
return true;
|
|
112
124
|
}
|
|
@@ -170,13 +182,15 @@ function firstSetBody(p, seen, resolve) {
|
|
|
170
182
|
// terminals: no refs, cached set is exact
|
|
171
183
|
case "dispatch":
|
|
172
184
|
return fs(d.selector);
|
|
173
|
-
case "lazy":
|
|
185
|
+
case "lazy": {
|
|
186
|
+
const w = winnerForRef(p, resolve);
|
|
187
|
+
if (w !== void 0) return fs(w);
|
|
174
188
|
try {
|
|
175
189
|
return fs(d.thunk());
|
|
176
190
|
} catch {
|
|
177
|
-
|
|
178
|
-
return t ? fs(t) : any();
|
|
191
|
+
return any();
|
|
179
192
|
}
|
|
193
|
+
}
|
|
180
194
|
case "choice": {
|
|
181
195
|
let out = empty();
|
|
182
196
|
for (const arm of d.parsers) out = union(out, fs(arm));
|
|
@@ -270,9 +284,43 @@ function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
|
270
284
|
}
|
|
271
285
|
}
|
|
272
286
|
|
|
287
|
+
// src/combinators/scalar.ts
|
|
288
|
+
var SCALAR_TAG = /^(?:literal|regex|keywords|sequence|choice|many|oneOrMore|optional|transform|trivia|grammar|sepBy|lazy)$/;
|
|
289
|
+
function scalarOf(combinator) {
|
|
290
|
+
return combinator._parseScalar;
|
|
291
|
+
}
|
|
292
|
+
function scalarTree(parser2, seen) {
|
|
293
|
+
if (seen.has(parser2)) return true;
|
|
294
|
+
if (parser2._parseScalar === void 0) return false;
|
|
295
|
+
seen.add(parser2);
|
|
296
|
+
const def = parser2._def;
|
|
297
|
+
if (!SCALAR_TAG.test(def.tag)) return false;
|
|
298
|
+
if ("parsers" in def && !def.parsers.every((child) => scalarTree(child, seen))) return false;
|
|
299
|
+
if ("parser" in def && !scalarTree(def.parser, seen)) return false;
|
|
300
|
+
if ("separator" in def && !scalarTree(def.separator, seen)) return false;
|
|
301
|
+
return def.tag !== "lazy" || scalarTree(def.thunk(), seen);
|
|
302
|
+
}
|
|
303
|
+
function scalarRootOf(combinator) {
|
|
304
|
+
const scalar = combinator._parseScalar;
|
|
305
|
+
const def = combinator._def;
|
|
306
|
+
return scalar !== void 0 && def.tag === "grammar" && scalarTree(def.parser, /* @__PURE__ */ new Set()) ? scalar : void 0;
|
|
307
|
+
}
|
|
308
|
+
|
|
273
309
|
// src/combinators/ref.ts
|
|
310
|
+
function withRuleTrivia(trivia2, ctx, run) {
|
|
311
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
312
|
+
ctx.trivia = trivia2;
|
|
313
|
+
ctx.triviaKindLabels = trivia2._meta.triviaKindLabels;
|
|
314
|
+
try {
|
|
315
|
+
return run();
|
|
316
|
+
} finally {
|
|
317
|
+
ctx.trivia = void 0;
|
|
318
|
+
ctx.triviaKindLabels = savedLabels;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
274
321
|
function ref() {
|
|
275
322
|
let resolved = null;
|
|
323
|
+
let resolvedScalar = null;
|
|
276
324
|
let ownBoundary = false;
|
|
277
325
|
const meta = {
|
|
278
326
|
firstSet: any(),
|
|
@@ -289,25 +337,28 @@ function ref() {
|
|
|
289
337
|
return resolved;
|
|
290
338
|
}
|
|
291
339
|
},
|
|
340
|
+
_parseScalar(input, pos, ctx) {
|
|
341
|
+
const scalar = resolvedScalar;
|
|
342
|
+
if (!scalar) throw new Error("ref<T>() used before .define() was called");
|
|
343
|
+
const gt = meta.grammarTrivia;
|
|
344
|
+
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
345
|
+
return withRuleTrivia(gt, ctx, () => scalar(input, pos, ctx));
|
|
346
|
+
}
|
|
347
|
+
return scalar(input, pos, ctx);
|
|
348
|
+
},
|
|
292
349
|
parse(input, pos, ctx) {
|
|
293
|
-
|
|
350
|
+
const parser2 = resolved;
|
|
351
|
+
if (!parser2) throw new Error("ref<T>() used before .define() was called");
|
|
294
352
|
const gt = meta.grammarTrivia;
|
|
295
353
|
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
|
-
}
|
|
354
|
+
return withRuleTrivia(gt, ctx, () => parser2.parse(input, pos, ctx));
|
|
305
355
|
}
|
|
306
|
-
return
|
|
356
|
+
return parser2.parse(input, pos, ctx);
|
|
307
357
|
},
|
|
308
358
|
define(p) {
|
|
309
359
|
if (resolved) throw new Error("ref<T>() already defined");
|
|
310
360
|
resolved = p;
|
|
361
|
+
resolvedScalar = scalarOf(p);
|
|
311
362
|
ownBoundary = hasOwnTriviaBoundary(p);
|
|
312
363
|
meta.firstSet = p._meta.firstSet;
|
|
313
364
|
meta.canMatchNewline = p._meta.canMatchNewline;
|
|
@@ -530,7 +581,7 @@ function pushCstLeaf(ctx, leaf2) {
|
|
|
530
581
|
const annotated = leaf2 && typeof leaf2 === "object" && leaf2.span ? { ...leaf2, span: annotateSpanFromLineContext(leaf2.span, ctx) } : leaf2;
|
|
531
582
|
pushCstChild(ctx, annotated, annotated);
|
|
532
583
|
}
|
|
533
|
-
function pushCstChild(ctx, built,
|
|
584
|
+
function pushCstChild(ctx, built, rawEntry) {
|
|
534
585
|
const b = ctx._cstBuf;
|
|
535
586
|
if (b) {
|
|
536
587
|
if (b.rawOnly !== true) {
|
|
@@ -541,16 +592,16 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
541
592
|
} else b.single = built;
|
|
542
593
|
}
|
|
543
594
|
if (b.noRaw === true) b.rawLen = (b.rawLen ?? 0) + 1;
|
|
544
|
-
else if (b.raw) b.raw.push(
|
|
595
|
+
else if (b.raw) b.raw.push(rawEntry);
|
|
545
596
|
else if (b.rawSingle !== void 0) {
|
|
546
|
-
b.raw = [b.rawSingle,
|
|
597
|
+
b.raw = [b.rawSingle, rawEntry];
|
|
547
598
|
b.rawSingle = void 0;
|
|
548
|
-
} else b.rawSingle =
|
|
599
|
+
} else b.rawSingle = rawEntry;
|
|
549
600
|
return;
|
|
550
601
|
}
|
|
551
602
|
if (ctx._cstChildren) ctx._cstChildren.push(built);
|
|
552
603
|
else if (ctx._cstLeaves) ctx._cstLeaves.push(built);
|
|
553
|
-
if (ctx._cstRawChildren) ctx._cstRawChildren.push(
|
|
604
|
+
if (ctx._cstRawChildren) ctx._cstRawChildren.push(rawEntry);
|
|
554
605
|
}
|
|
555
606
|
function cstRawLen(ctx) {
|
|
556
607
|
const b = ctx._cstBuf;
|
|
@@ -693,6 +744,7 @@ function createParseContext() {
|
|
|
693
744
|
_fe: void 0,
|
|
694
745
|
_fx: void 0,
|
|
695
746
|
_fc: void 0,
|
|
747
|
+
_sv: void 0,
|
|
696
748
|
_probe: void 0,
|
|
697
749
|
_cstChildren: void 0,
|
|
698
750
|
_cstLeaves: void 0,
|
|
@@ -1530,6 +1582,24 @@ function parser(opts, root) {
|
|
|
1530
1582
|
const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
|
|
1531
1583
|
const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
|
|
1532
1584
|
const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
|
|
1585
|
+
const rootScalar = scalarOf(root);
|
|
1586
|
+
const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
|
|
1587
|
+
const parseScalar = scalarEligible ? (input, pos, ctx) => {
|
|
1588
|
+
const savedTrivia = ctx.trivia;
|
|
1589
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
1590
|
+
if (clearTrivia) {
|
|
1591
|
+
ctx.trivia = void 0;
|
|
1592
|
+
ctx.triviaKindLabels = void 0;
|
|
1593
|
+
} else if (scopeTrivia !== void 0) {
|
|
1594
|
+
ctx.trivia = scopeTrivia;
|
|
1595
|
+
ctx.triviaKindLabels = scopeLabels;
|
|
1596
|
+
}
|
|
1597
|
+
const end = rootScalar(input, pos, ctx);
|
|
1598
|
+
ctx.trivia = savedTrivia;
|
|
1599
|
+
ctx.triviaKindLabels = savedLabels;
|
|
1600
|
+
return end;
|
|
1601
|
+
} : void 0;
|
|
1602
|
+
let publicScalar;
|
|
1533
1603
|
const grammar = {
|
|
1534
1604
|
_tag: "grammar",
|
|
1535
1605
|
_meta: {
|
|
@@ -1553,7 +1623,20 @@ function parser(opts, root) {
|
|
|
1553
1623
|
constructionTrackLines: trackLinesPolicy,
|
|
1554
1624
|
...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
|
|
1555
1625
|
},
|
|
1626
|
+
_parseScalar: parseScalar,
|
|
1556
1627
|
parse(input, pos, _ctx) {
|
|
1628
|
+
if (pos === void 0 && _ctx === void 0) {
|
|
1629
|
+
publicScalar ??= scalarRootOf(grammar) ?? null;
|
|
1630
|
+
if (publicScalar) {
|
|
1631
|
+
const ctx2 = createParseContext();
|
|
1632
|
+
const end = publicScalar(input, 0, ctx2);
|
|
1633
|
+
if (end < 0) {
|
|
1634
|
+
const at = ~end;
|
|
1635
|
+
return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
|
|
1636
|
+
}
|
|
1637
|
+
return { ok: true, value: ctx2._sv, span: { start: 0, end } };
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1557
1640
|
if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
|
|
1558
1641
|
const trackLines = trackLinesOf(_ctx);
|
|
1559
1642
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
@@ -2146,10 +2229,32 @@ function regex(pattern, flags = "") {
|
|
|
2146
2229
|
const canMatchNewline = raw.canMatchNewline;
|
|
2147
2230
|
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
2148
2231
|
const def = { tag: "regex", source, flags: resolvedFlags };
|
|
2232
|
+
const expected = directTerminalFailureExpected(def);
|
|
2233
|
+
const parseScalar = (input, pos, ctx) => {
|
|
2234
|
+
const scanEnd = scan?.(input, pos);
|
|
2235
|
+
if (scanEnd !== void 0) {
|
|
2236
|
+
if (scanEnd === null) {
|
|
2237
|
+
ctx._fx = expected;
|
|
2238
|
+
return ~pos;
|
|
2239
|
+
}
|
|
2240
|
+
ctx._sv = input.slice(pos, scanEnd);
|
|
2241
|
+
return scanEnd;
|
|
2242
|
+
}
|
|
2243
|
+
anchored.lastIndex = pos;
|
|
2244
|
+
const match = anchored.exec(input);
|
|
2245
|
+
if (match === null) {
|
|
2246
|
+
ctx._fx = expected;
|
|
2247
|
+
return ~pos;
|
|
2248
|
+
}
|
|
2249
|
+
ctx._sv = match[0];
|
|
2250
|
+
return pos + match[0].length;
|
|
2251
|
+
};
|
|
2149
2252
|
return {
|
|
2150
2253
|
_tag: "regex",
|
|
2151
2254
|
_meta: meta,
|
|
2152
2255
|
_def: def,
|
|
2256
|
+
_stickyRegex: anchored,
|
|
2257
|
+
_parseScalar: parseScalar,
|
|
2153
2258
|
parse(input, pos, ctx) {
|
|
2154
2259
|
const scanEnd = scan?.(input, pos);
|
|
2155
2260
|
if (scanEnd !== void 0) {
|
|
@@ -2194,6 +2299,28 @@ function literal(value, opts = {}) {
|
|
|
2194
2299
|
isTrivia: false
|
|
2195
2300
|
};
|
|
2196
2301
|
const canMatchNewline = meta.canMatchNewline;
|
|
2302
|
+
const parseScalar = !caseInsensitive && value.length === 1 ? (() => {
|
|
2303
|
+
const code = value.charCodeAt(0);
|
|
2304
|
+
return (input, pos, ctx) => {
|
|
2305
|
+
if (input.charCodeAt(pos) === code) {
|
|
2306
|
+
ctx._sv = value;
|
|
2307
|
+
return pos + 1;
|
|
2308
|
+
}
|
|
2309
|
+
ctx._fx = expected;
|
|
2310
|
+
return ~pos;
|
|
2311
|
+
};
|
|
2312
|
+
})() : (input, pos, ctx) => {
|
|
2313
|
+
const end = pos + value.length;
|
|
2314
|
+
if (end <= input.length) {
|
|
2315
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
2316
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
2317
|
+
ctx._sv = matchedValue;
|
|
2318
|
+
return end;
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
ctx._fx = expected;
|
|
2322
|
+
return ~pos;
|
|
2323
|
+
};
|
|
2197
2324
|
if (caseInsensitive) {
|
|
2198
2325
|
const upper = value.toUpperCase();
|
|
2199
2326
|
const lower = value.toLowerCase();
|
|
@@ -2234,6 +2361,7 @@ function literal(value, opts = {}) {
|
|
|
2234
2361
|
_tag: "literal",
|
|
2235
2362
|
_meta: meta,
|
|
2236
2363
|
_def: { tag: "literal", value, caseInsensitive },
|
|
2364
|
+
_parseScalar: parseScalar,
|
|
2237
2365
|
parse
|
|
2238
2366
|
};
|
|
2239
2367
|
}
|
|
@@ -2301,16 +2429,26 @@ function keywords(words, opts = {}) {
|
|
|
2301
2429
|
caseInsensitive: opts.caseInsensitive ?? false,
|
|
2302
2430
|
boundary: opts.boundary
|
|
2303
2431
|
};
|
|
2432
|
+
const expected = directTerminalFailureExpected(def);
|
|
2433
|
+
const parseScalar = (input, pos, ctx) => {
|
|
2434
|
+
re.lastIndex = pos;
|
|
2435
|
+
const m = re.exec(input);
|
|
2436
|
+
if (m === null) {
|
|
2437
|
+
ctx._fx = expected;
|
|
2438
|
+
return ~pos;
|
|
2439
|
+
}
|
|
2440
|
+
ctx._sv = m[0];
|
|
2441
|
+
return pos + m[0].length;
|
|
2442
|
+
};
|
|
2304
2443
|
return {
|
|
2305
2444
|
_tag: "keywords",
|
|
2306
2445
|
_meta: meta,
|
|
2307
2446
|
_def: def,
|
|
2447
|
+
_parseScalar: parseScalar,
|
|
2308
2448
|
parse(input, pos, ctx) {
|
|
2309
2449
|
re.lastIndex = pos;
|
|
2310
2450
|
const m = re.exec(input);
|
|
2311
|
-
if (m === null
|
|
2312
|
-
return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
2313
|
-
}
|
|
2451
|
+
if (m === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
2314
2452
|
const value = m[0];
|
|
2315
2453
|
const span = { start: pos, end: pos + value.length };
|
|
2316
2454
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
@@ -2341,6 +2479,9 @@ var fastScanner3;
|
|
|
2341
2479
|
function needsDeferredTriviaCommit(ctx) {
|
|
2342
2480
|
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
2343
2481
|
}
|
|
2482
|
+
function needsTriviaRollback(ctx) {
|
|
2483
|
+
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;
|
|
2484
|
+
}
|
|
2344
2485
|
function saveTriviaMark(ctx) {
|
|
2345
2486
|
const m = saveCstMark(ctx);
|
|
2346
2487
|
return {
|
|
@@ -2452,7 +2593,8 @@ function advanceTrivia(input, cur, ctx) {
|
|
|
2452
2593
|
const triviaP = ctx.trivia;
|
|
2453
2594
|
if (!triviaP) return cur;
|
|
2454
2595
|
if (!ctx.trackLines) {
|
|
2455
|
-
const
|
|
2596
|
+
const classified = triviaP._meta.triviaScanner;
|
|
2597
|
+
const fast2 = classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
2456
2598
|
if (fast2) return fast2(input, cur);
|
|
2457
2599
|
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
2458
2600
|
const tr2 = triviaP.parse(input, cur, createDetachedParseContext(ctx.trackLines, ctx.state));
|
|
@@ -3043,6 +3185,7 @@ function sequence(...parsers) {
|
|
|
3043
3185
|
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
3044
3186
|
}
|
|
3045
3187
|
const hasAdjacency = adjacency !== null;
|
|
3188
|
+
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
3046
3189
|
const meta = {
|
|
3047
3190
|
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
3048
3191
|
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
@@ -3051,165 +3194,96 @@ function sequence(...parsers) {
|
|
|
3051
3194
|
isTrivia: false
|
|
3052
3195
|
};
|
|
3053
3196
|
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 : [];
|
|
3197
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
3198
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3064
3199
|
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;
|
|
3200
|
+
if (strictArity !== 0) {
|
|
3201
|
+
cur = scalarParsers[0](input, cur, ctx);
|
|
3202
|
+
if (cur < 0) return cur;
|
|
3203
|
+
const first = ctx._sv;
|
|
3204
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
3205
|
+
cur = scalarParsers[1](input, cur, ctx);
|
|
3206
|
+
if (cur < 0) return cur;
|
|
3207
|
+
const second = ctx._sv;
|
|
3208
|
+
if (strictArity === 2) {
|
|
3209
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second];
|
|
3210
|
+
return cur;
|
|
3107
3211
|
}
|
|
3108
|
-
|
|
3109
|
-
|
|
3212
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
3213
|
+
cur = scalarParsers[2](input, cur, ctx);
|
|
3214
|
+
if (cur < 0) return cur;
|
|
3215
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second, ctx._sv];
|
|
3216
|
+
return cur;
|
|
3110
3217
|
}
|
|
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
3218
|
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
|
-
}
|
|
3219
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
3220
|
+
let termPos = cur;
|
|
3221
|
+
if (i > 0 && ctx.trivia) termPos = advanceTrivia(input, cur, ctx);
|
|
3222
|
+
const end = scalarParsers[i](input, termPos, ctx);
|
|
3223
|
+
if (end < 0) return end;
|
|
3224
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
3225
|
+
if (end > termPos || termPos === cur) cur = end;
|
|
3226
|
+
}
|
|
3227
|
+
ctx._sv = values;
|
|
3228
|
+
return cur;
|
|
3229
|
+
};
|
|
3230
|
+
let followSentinels;
|
|
3168
3231
|
return {
|
|
3169
3232
|
_tag: "sequence",
|
|
3170
3233
|
_meta: meta,
|
|
3171
3234
|
_def: def,
|
|
3235
|
+
_parseScalar: hasAdjacency ? void 0 : parseScalar,
|
|
3172
3236
|
parse(input, pos, ctx) {
|
|
3173
|
-
|
|
3174
|
-
if (
|
|
3237
|
+
const tolerant = ctx._tolerant === true;
|
|
3238
|
+
if (tolerant) {
|
|
3239
|
+
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
3240
|
+
parsers.slice(i + 1).reduce(
|
|
3241
|
+
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
3242
|
+
{ kind: "empty" }
|
|
3243
|
+
)
|
|
3244
|
+
));
|
|
3245
|
+
}
|
|
3246
|
+
const inheritedSync = ctx._sync;
|
|
3247
|
+
const deferredTrivia = needsDeferredTriviaCommit(ctx);
|
|
3175
3248
|
const values = def.valueUnused ? void 0 : [];
|
|
3176
3249
|
let cur = pos;
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
const
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
} else {
|
|
3186
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
3250
|
+
try {
|
|
3251
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
3252
|
+
if (tolerant) ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
3253
|
+
const assertion = adjacency?.[i];
|
|
3254
|
+
if (assertion) {
|
|
3255
|
+
if (!holdsAdjacency(input, cur, ctx, assertion)) return adjacencyFail(cur, assertion);
|
|
3256
|
+
if (values !== void 0) values.push(null);
|
|
3257
|
+
continue;
|
|
3187
3258
|
}
|
|
3188
|
-
|
|
3189
|
-
const
|
|
3190
|
-
const
|
|
3191
|
-
const
|
|
3192
|
-
if (
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3259
|
+
let termPos = cur;
|
|
3260
|
+
const markTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
3261
|
+
const markLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
3262
|
+
const markRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
3263
|
+
if (ctx.trivia && i > 0) {
|
|
3264
|
+
termPos = deferredTrivia ? commitTriviaScan(scanTriviaCompact(input, cur, ctx)) : advanceTrivia(input, cur, ctx);
|
|
3265
|
+
}
|
|
3266
|
+
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
3267
|
+
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
3268
|
+
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
3269
|
+
const result = parsers[i].parse(input, termPos, ctx);
|
|
3270
|
+
if (!result.ok) return result;
|
|
3271
|
+
if (values !== void 0) values.push(result.value);
|
|
3272
|
+
if (result.span.end > termPos || termPos === cur) cur = result.span.end;
|
|
3273
|
+
else if (deferredTrivia) {
|
|
3196
3274
|
rollbackScannedTriviaAt(
|
|
3197
3275
|
ctx,
|
|
3198
|
-
|
|
3276
|
+
markTlog,
|
|
3199
3277
|
scanTlog,
|
|
3200
|
-
|
|
3278
|
+
markLog,
|
|
3201
3279
|
scanLog,
|
|
3202
|
-
|
|
3280
|
+
markRootLog,
|
|
3203
3281
|
scanRootLog
|
|
3204
3282
|
);
|
|
3205
3283
|
}
|
|
3206
|
-
if (values !== void 0) values.push(result2.value);
|
|
3207
|
-
continue;
|
|
3208
3284
|
}
|
|
3209
|
-
|
|
3210
|
-
if (
|
|
3211
|
-
if (values !== void 0) values.push(result.value);
|
|
3212
|
-
cur = result.span.end;
|
|
3285
|
+
} finally {
|
|
3286
|
+
if (tolerant) ctx._sync = inheritedSync;
|
|
3213
3287
|
}
|
|
3214
3288
|
return {
|
|
3215
3289
|
ok: true,
|
|
@@ -3341,7 +3415,8 @@ function choice(...args) {
|
|
|
3341
3415
|
disjoint
|
|
3342
3416
|
};
|
|
3343
3417
|
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
3344
|
-
const
|
|
3418
|
+
const ordered = strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix";
|
|
3419
|
+
const autoNot = !disjoint && !hasGates && ordered ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
3345
3420
|
let greedyLitMap = null;
|
|
3346
3421
|
let sortedParsers = null;
|
|
3347
3422
|
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
@@ -3355,6 +3430,37 @@ function choice(...args) {
|
|
|
3355
3430
|
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
3356
3431
|
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
3357
3432
|
}
|
|
3433
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
3434
|
+
const scalarEligible = !hasGates && parsers.every((p) => p._parseScalar !== void 0) && (disjoint || ordered);
|
|
3435
|
+
const scalarExpected = parsers.flatMap(deriveExpected);
|
|
3436
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3437
|
+
if (disjoint) {
|
|
3438
|
+
const code = pos < input.length ? input.codePointAt(pos) : -1;
|
|
3439
|
+
let idx = code >= 0 && code < 128 ? asciiDispatch[code] : -1;
|
|
3440
|
+
if (idx < 0 && code >= 0) {
|
|
3441
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
3442
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
3443
|
+
idx = i;
|
|
3444
|
+
break;
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
if (idx >= 0) {
|
|
3449
|
+
const gate = gates[idx];
|
|
3450
|
+
if (!gate || gate(ctx.state)) return scalarParsers[idx](input, pos, ctx);
|
|
3451
|
+
ctx._fx = deriveExpected(parsers[idx]);
|
|
3452
|
+
return ~pos;
|
|
3453
|
+
}
|
|
3454
|
+
} else {
|
|
3455
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
3456
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
3457
|
+
const end = scalarParsers[i](input, pos, ctx);
|
|
3458
|
+
if (end >= 0 && (!autoNot[i] || !autoNotFires(input, end, autoNot[i]))) return end;
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
ctx._fx = scalarExpected;
|
|
3462
|
+
return ~pos;
|
|
3463
|
+
};
|
|
3358
3464
|
return {
|
|
3359
3465
|
_tag: "choice",
|
|
3360
3466
|
_meta: meta,
|
|
@@ -3366,6 +3472,7 @@ function choice(...args) {
|
|
|
3366
3472
|
strategy: strategy ?? { tag: "firstMatch" },
|
|
3367
3473
|
autoNot
|
|
3368
3474
|
},
|
|
3475
|
+
_parseScalar: scalarEligible ? parseScalar : void 0,
|
|
3369
3476
|
parse(input, pos, ctx) {
|
|
3370
3477
|
const expected = [];
|
|
3371
3478
|
let expectedAt = pos;
|
|
@@ -3897,8 +4004,8 @@ function attempt(parser2) {
|
|
|
3897
4004
|
}
|
|
3898
4005
|
|
|
3899
4006
|
// src/combinators/repeat.ts
|
|
3900
|
-
function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
3901
|
-
const mark = saveTriviaMark(ctx);
|
|
4007
|
+
function repItem(combinator, input, cur, ctx, guardable, mandatory, rollbackNeeded) {
|
|
4008
|
+
const mark = rollbackNeeded ? saveTriviaMark(ctx) : void 0;
|
|
3902
4009
|
let pos = cur;
|
|
3903
4010
|
if (ctx.trivia) {
|
|
3904
4011
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -3908,24 +4015,24 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
|
3908
4015
|
}
|
|
3909
4016
|
}
|
|
3910
4017
|
if (pos >= input.length && !mandatory) {
|
|
3911
|
-
rollbackTrivia(ctx, mark);
|
|
4018
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3912
4019
|
return "stop";
|
|
3913
4020
|
}
|
|
3914
4021
|
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
3915
|
-
rollbackTrivia(ctx, mark);
|
|
4022
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3916
4023
|
return "stop";
|
|
3917
4024
|
}
|
|
3918
4025
|
const result = combinator.parse(input, pos, ctx);
|
|
3919
4026
|
if (!result.ok) {
|
|
3920
|
-
rollbackTrivia(ctx, mark);
|
|
4027
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3921
4028
|
if (result.committed) return { fail: result, failPos: pos };
|
|
3922
4029
|
return { fail: result, failPos: pos };
|
|
3923
4030
|
}
|
|
3924
4031
|
if (result.span.end === pos && !mandatory) {
|
|
3925
|
-
rollbackTrivia(ctx, mark);
|
|
4032
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3926
4033
|
return "stop";
|
|
3927
4034
|
}
|
|
3928
|
-
return
|
|
4035
|
+
return result;
|
|
3929
4036
|
}
|
|
3930
4037
|
function resolveBounds(what, opts) {
|
|
3931
4038
|
const min = opts.min ?? 0;
|
|
@@ -3938,6 +4045,21 @@ function resolveBounds(what, opts) {
|
|
|
3938
4045
|
if (max < min) bad(`max (${max}) is less than min (${min}) \u2014 the combinator could never succeed`);
|
|
3939
4046
|
return { min, max };
|
|
3940
4047
|
}
|
|
4048
|
+
function repeatScalarTail(combinator, child, input, cur, ctx, guardable, values, remaining) {
|
|
4049
|
+
while (cur < input.length && remaining > 0) {
|
|
4050
|
+
let itemPos = cur;
|
|
4051
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4052
|
+
if (itemPos >= input.length) break;
|
|
4053
|
+
if (guardable && !startsFirstSet(combinator, input, itemPos)) break;
|
|
4054
|
+
const end = child(input, itemPos, ctx);
|
|
4055
|
+
if (end <= itemPos) break;
|
|
4056
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4057
|
+
cur = end;
|
|
4058
|
+
remaining--;
|
|
4059
|
+
}
|
|
4060
|
+
ctx._sv = values;
|
|
4061
|
+
return cur;
|
|
4062
|
+
}
|
|
3941
4063
|
function many(combinator, opts = {}) {
|
|
3942
4064
|
const { min, max } = resolveBounds("many()", opts);
|
|
3943
4065
|
if (min >= 1) return atLeast(combinator, min, max);
|
|
@@ -3949,17 +4071,21 @@ function many(combinator, opts = {}) {
|
|
|
3949
4071
|
const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max } };
|
|
3950
4072
|
let expected;
|
|
3951
4073
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4074
|
+
const scalarChild = scalarOf(combinator);
|
|
4075
|
+
const parseScalar = (input, pos, ctx) => repeatScalarTail(combinator, scalarChild, input, pos, ctx, guardable, def.valueUnused ? void 0 : [], max);
|
|
3952
4076
|
return {
|
|
3953
4077
|
_tag: "many",
|
|
3954
4078
|
_meta: meta,
|
|
3955
4079
|
_def: def,
|
|
4080
|
+
_parseScalar: parseScalar,
|
|
3956
4081
|
parse(input, pos, ctx) {
|
|
3957
4082
|
const values = def.valueUnused ? void 0 : [];
|
|
4083
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
3958
4084
|
let cur = pos;
|
|
3959
4085
|
let count = 0;
|
|
3960
4086
|
while (cur < input.length) {
|
|
3961
4087
|
if (count >= max) break;
|
|
3962
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
4088
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
3963
4089
|
if (item === "stop") break;
|
|
3964
4090
|
if ("fail" in item) {
|
|
3965
4091
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -3976,7 +4102,7 @@ function many(combinator, opts = {}) {
|
|
|
3976
4102
|
}
|
|
3977
4103
|
if (values !== void 0) values.push(item.value);
|
|
3978
4104
|
count++;
|
|
3979
|
-
cur = item.end;
|
|
4105
|
+
cur = item.span.end;
|
|
3980
4106
|
}
|
|
3981
4107
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
3982
4108
|
}
|
|
@@ -3994,30 +4120,47 @@ function atLeast(combinator, min, max) {
|
|
|
3994
4120
|
const def = { tag: "oneOrMore", parser: combinator, min, ...max === Infinity ? {} : { max } };
|
|
3995
4121
|
let expected;
|
|
3996
4122
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4123
|
+
const scalarChild = scalarOf(combinator);
|
|
4124
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4125
|
+
let cur = scalarChild(input, pos, ctx);
|
|
4126
|
+
if (cur < 0) return cur;
|
|
4127
|
+
const values = def.valueUnused ? void 0 : [ctx._sv];
|
|
4128
|
+
for (let count = 1; count < min; count++) {
|
|
4129
|
+
let itemPos = cur;
|
|
4130
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4131
|
+
const end = scalarChild(input, itemPos, ctx);
|
|
4132
|
+
if (end < 0) return ~cur;
|
|
4133
|
+
cur = end;
|
|
4134
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4135
|
+
}
|
|
4136
|
+
return repeatScalarTail(combinator, scalarChild, input, cur, ctx, guardable, values, max - min);
|
|
4137
|
+
};
|
|
3997
4138
|
return {
|
|
3998
4139
|
_tag: "oneOrMore",
|
|
3999
4140
|
_meta: meta,
|
|
4000
4141
|
_def: def,
|
|
4142
|
+
_parseScalar: parseScalar,
|
|
4001
4143
|
parse(input, pos, ctx) {
|
|
4002
4144
|
const first = combinator.parse(input, pos, ctx);
|
|
4003
4145
|
if (!first.ok) return first;
|
|
4004
4146
|
const values = def.valueUnused ? void 0 : [first.value];
|
|
4147
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4005
4148
|
let cur = first.span.end;
|
|
4006
4149
|
let count = 1;
|
|
4007
4150
|
while (count < min) {
|
|
4008
|
-
const item = repItem(combinator, input, cur, ctx, guardable, true);
|
|
4151
|
+
const item = repItem(combinator, input, cur, ctx, guardable, true, rollbackNeeded);
|
|
4009
4152
|
if (item === "stop" || "fail" in item) {
|
|
4010
4153
|
if (item !== "stop" && !item.fail.ok && item.fail.committed) return item.fail;
|
|
4011
4154
|
expected ??= deriveExpected(combinator);
|
|
4012
4155
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: cur, end: cur } };
|
|
4013
4156
|
}
|
|
4014
4157
|
if (values !== void 0) values.push(item.value);
|
|
4015
|
-
cur = item.end;
|
|
4158
|
+
cur = item.span.end;
|
|
4016
4159
|
count++;
|
|
4017
4160
|
}
|
|
4018
4161
|
while (cur < input.length) {
|
|
4019
4162
|
if (count >= max) break;
|
|
4020
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
4163
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4021
4164
|
if (item === "stop") break;
|
|
4022
4165
|
if ("fail" in item) {
|
|
4023
4166
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -4034,7 +4177,7 @@ function atLeast(combinator, min, max) {
|
|
|
4034
4177
|
}
|
|
4035
4178
|
if (values !== void 0) values.push(item.value);
|
|
4036
4179
|
count++;
|
|
4037
|
-
cur = item.end;
|
|
4180
|
+
cur = item.span.end;
|
|
4038
4181
|
}
|
|
4039
4182
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4040
4183
|
}
|
|
@@ -4047,10 +4190,22 @@ function optional(combinator) {
|
|
|
4047
4190
|
isTrivia: false
|
|
4048
4191
|
};
|
|
4049
4192
|
const firstSetSkippable = !matchesEmpty(combinator);
|
|
4193
|
+
const scalarChild = scalarOf(combinator);
|
|
4194
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4195
|
+
if (firstSetSkippable && !startsFirstSet(combinator, input, pos)) {
|
|
4196
|
+
ctx._sv = null;
|
|
4197
|
+
return pos;
|
|
4198
|
+
}
|
|
4199
|
+
const end = scalarChild(input, pos, ctx);
|
|
4200
|
+
if (end >= 0) return end;
|
|
4201
|
+
ctx._sv = null;
|
|
4202
|
+
return pos;
|
|
4203
|
+
};
|
|
4050
4204
|
return {
|
|
4051
4205
|
_tag: "optional",
|
|
4052
4206
|
_meta: meta,
|
|
4053
4207
|
_def: { tag: "optional", parser: combinator },
|
|
4208
|
+
_parseScalar: parseScalar,
|
|
4054
4209
|
parse(input, pos, ctx) {
|
|
4055
4210
|
if (firstSetSkippable && ctx._probe === void 0 && !startsFirstSet(combinator, input, pos)) {
|
|
4056
4211
|
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
@@ -4084,6 +4239,43 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4084
4239
|
expected ??= deriveExpected(combinator);
|
|
4085
4240
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: at, end: at } };
|
|
4086
4241
|
};
|
|
4242
|
+
const scalarExpected = deriveExpected(combinator);
|
|
4243
|
+
const scalarChild = scalarOf(combinator);
|
|
4244
|
+
const scalarSeparator = scalarOf(separator);
|
|
4245
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4246
|
+
let cur = scalarChild(input, pos, ctx);
|
|
4247
|
+
if (cur < 0) {
|
|
4248
|
+
if (min >= 1) {
|
|
4249
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
4250
|
+
return ~pos;
|
|
4251
|
+
}
|
|
4252
|
+
ctx._sv = [];
|
|
4253
|
+
return pos;
|
|
4254
|
+
}
|
|
4255
|
+
const values = [ctx._sv];
|
|
4256
|
+
while (values.length < max && (cur < input.length || values.length < min)) {
|
|
4257
|
+
const beforeSeparator = cur;
|
|
4258
|
+
let separatorPos = cur;
|
|
4259
|
+
if (ctx.trivia) separatorPos = advanceTrivia(input, cur, ctx);
|
|
4260
|
+
const separatorEnd = scalarSeparator(input, separatorPos, ctx);
|
|
4261
|
+
if (separatorEnd < 0) break;
|
|
4262
|
+
let itemPos = separatorEnd;
|
|
4263
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, itemPos, ctx);
|
|
4264
|
+
const itemEnd = scalarChild(input, itemPos, ctx);
|
|
4265
|
+
if (itemEnd < 0) {
|
|
4266
|
+
cur = trailing === "allow" ? separatorEnd : beforeSeparator;
|
|
4267
|
+
break;
|
|
4268
|
+
}
|
|
4269
|
+
values.push(ctx._sv);
|
|
4270
|
+
cur = itemEnd;
|
|
4271
|
+
}
|
|
4272
|
+
if (values.length < min) {
|
|
4273
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
4274
|
+
return ~cur;
|
|
4275
|
+
}
|
|
4276
|
+
ctx._sv = values;
|
|
4277
|
+
return cur;
|
|
4278
|
+
};
|
|
4087
4279
|
return {
|
|
4088
4280
|
_tag: "sepBy",
|
|
4089
4281
|
_meta: meta,
|
|
@@ -4099,6 +4291,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4099
4291
|
// this option surface already; parity is held by test/parity, not by hope.
|
|
4100
4292
|
...keepSeparators ? { keepSeparators: true } : {}
|
|
4101
4293
|
},
|
|
4294
|
+
_parseScalar: keepSeparators ? void 0 : parseScalar,
|
|
4102
4295
|
parse(input, pos, ctx) {
|
|
4103
4296
|
const first = combinator.parse(input, pos, ctx);
|
|
4104
4297
|
const values = [];
|
|
@@ -4608,9 +4801,9 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
4608
4801
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
4609
4802
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
4610
4803
|
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
|
|
4804
|
+
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
4805
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
4613
|
-
pushCstChild(ctx, built,
|
|
4806
|
+
pushCstChild(ctx, built, rawEntry);
|
|
4614
4807
|
}
|
|
4615
4808
|
return { ok: true, value: built, span };
|
|
4616
4809
|
}
|
|
@@ -4618,11 +4811,54 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
4618
4811
|
}
|
|
4619
4812
|
|
|
4620
4813
|
// src/combinators/map.ts
|
|
4814
|
+
var JSON_STRING_BODY = String.raw`(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*`;
|
|
4621
4815
|
function transform(combinator, fn) {
|
|
4816
|
+
const observesSpan = fn.length > 1;
|
|
4817
|
+
const sequenceDef = combinator._def.tag === "sequence" ? combinator._def : void 0;
|
|
4818
|
+
const terms = sequenceDef?.parsers;
|
|
4819
|
+
const inner = terms?.[1];
|
|
4820
|
+
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;
|
|
4821
|
+
const child = scalarOf(combinator);
|
|
4822
|
+
const parseScalar = fused ? (() => {
|
|
4823
|
+
const body = inner._stickyRegex;
|
|
4824
|
+
const tuple = ['"', "", '"'];
|
|
4825
|
+
const expected = [JSON.stringify('"')];
|
|
4826
|
+
return (input, pos, ctx) => {
|
|
4827
|
+
if (ctx.trivia !== void 0) {
|
|
4828
|
+
const end2 = child(input, pos, ctx);
|
|
4829
|
+
if (end2 < 0) return end2;
|
|
4830
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end: end2 }) : fn(ctx._sv);
|
|
4831
|
+
return end2;
|
|
4832
|
+
}
|
|
4833
|
+
if (input.charCodeAt(pos) !== 34) {
|
|
4834
|
+
ctx._fx = expected;
|
|
4835
|
+
return ~pos;
|
|
4836
|
+
}
|
|
4837
|
+
body.lastIndex = pos + 1;
|
|
4838
|
+
const match = body.exec(input);
|
|
4839
|
+
const close = pos + 1 + match[0].length;
|
|
4840
|
+
if (input.charCodeAt(close) !== 34) {
|
|
4841
|
+
ctx._fx = expected;
|
|
4842
|
+
return ~close;
|
|
4843
|
+
}
|
|
4844
|
+
tuple[1] = match[0];
|
|
4845
|
+
const end = close + 1;
|
|
4846
|
+
ctx._sv = observesSpan ? fn(tuple, { start: pos, end }) : fn(tuple);
|
|
4847
|
+
return end;
|
|
4848
|
+
};
|
|
4849
|
+
})() : /* @__PURE__ */ (() => {
|
|
4850
|
+
return (input, pos, ctx) => {
|
|
4851
|
+
const end = child(input, pos, ctx);
|
|
4852
|
+
if (end < 0) return end;
|
|
4853
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end }) : fn(ctx._sv);
|
|
4854
|
+
return end;
|
|
4855
|
+
};
|
|
4856
|
+
})();
|
|
4622
4857
|
return {
|
|
4623
4858
|
_tag: "transform",
|
|
4624
4859
|
_meta: combinator._meta,
|
|
4625
4860
|
_def: { tag: "transform", parser: combinator, fn },
|
|
4861
|
+
_parseScalar: parseScalar,
|
|
4626
4862
|
parse(input, pos, ctx) {
|
|
4627
4863
|
const result = combinator.parse(input, pos, ctx);
|
|
4628
4864
|
if (!result.ok) return result;
|
|
@@ -4637,9 +4873,11 @@ function trivia(combinator) {
|
|
|
4637
4873
|
_meta: {
|
|
4638
4874
|
...combinator._meta,
|
|
4639
4875
|
isTrivia: true,
|
|
4876
|
+
triviaScanner: fastTriviaScanner(combinator),
|
|
4640
4877
|
...kindLabels ? { triviaKindLabels: kindLabels } : {}
|
|
4641
4878
|
},
|
|
4642
4879
|
_def: { tag: "trivia", parser: combinator },
|
|
4880
|
+
_parseScalar: scalarOf(combinator),
|
|
4643
4881
|
parse: combinator.parse.bind(combinator)
|
|
4644
4882
|
};
|
|
4645
4883
|
}
|
|
@@ -5113,108 +5351,6 @@ function evalRuleMapIR(ir) {
|
|
|
5113
5351
|
return Object.entries(map);
|
|
5114
5352
|
}
|
|
5115
5353
|
|
|
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
5354
|
// src/compiler/linker.ts
|
|
5219
5355
|
function normalizeCstCollapse(collapse) {
|
|
5220
5356
|
if (collapse === true) return () => true;
|