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
|
@@ -35,10 +35,20 @@ function classifyFinalChoice(arms, resolve) {
|
|
|
35
35
|
}
|
|
36
36
|
return { exclusive, firstSets, nullable: nullable2 };
|
|
37
37
|
}
|
|
38
|
-
function
|
|
38
|
+
function winnerForRef(p, resolve) {
|
|
39
39
|
if (resolve === void 0) return void 0;
|
|
40
40
|
const name = p._ruleName;
|
|
41
|
-
|
|
41
|
+
const w = name === void 0 ? void 0 : resolve(name);
|
|
42
|
+
if (w === void 0 || w === p) return void 0;
|
|
43
|
+
let cur = w;
|
|
44
|
+
for (const seen = /* @__PURE__ */ new Set(); !seen.has(cur); ) {
|
|
45
|
+
if (cur === p) return void 0;
|
|
46
|
+
seen.add(cur);
|
|
47
|
+
const cd = cur._def;
|
|
48
|
+
if (cd.tag !== "grammar" && cd.tag !== "trivia") return w;
|
|
49
|
+
cur = cd.parser;
|
|
50
|
+
}
|
|
51
|
+
return w;
|
|
42
52
|
}
|
|
43
53
|
function union(a, b) {
|
|
44
54
|
if (a.kind === "any" || b.kind === "any") return { kind: "any" };
|
|
@@ -136,13 +146,15 @@ function matchesEmptyBody(p, seen, resolve) {
|
|
|
136
146
|
case "grammar":
|
|
137
147
|
case "recover":
|
|
138
148
|
return me(d.parser);
|
|
139
|
-
case "lazy":
|
|
149
|
+
case "lazy": {
|
|
150
|
+
const w = winnerForRef(p, resolve);
|
|
151
|
+
if (w !== void 0) return me(w);
|
|
140
152
|
try {
|
|
141
153
|
return me(d.thunk());
|
|
142
154
|
} catch {
|
|
143
|
-
|
|
144
|
-
return t2 ? me(t2) : true;
|
|
155
|
+
return true;
|
|
145
156
|
}
|
|
157
|
+
}
|
|
146
158
|
default:
|
|
147
159
|
return true;
|
|
148
160
|
}
|
|
@@ -206,13 +218,15 @@ function firstSetBody(p, seen, resolve) {
|
|
|
206
218
|
// terminals: no refs, cached set is exact
|
|
207
219
|
case "dispatch":
|
|
208
220
|
return fs(d.selector);
|
|
209
|
-
case "lazy":
|
|
221
|
+
case "lazy": {
|
|
222
|
+
const w = winnerForRef(p, resolve);
|
|
223
|
+
if (w !== void 0) return fs(w);
|
|
210
224
|
try {
|
|
211
225
|
return fs(d.thunk());
|
|
212
226
|
} catch {
|
|
213
|
-
|
|
214
|
-
return t2 ? fs(t2) : any();
|
|
227
|
+
return any();
|
|
215
228
|
}
|
|
229
|
+
}
|
|
216
230
|
case "choice": {
|
|
217
231
|
let out = empty();
|
|
218
232
|
for (const arm of d.parsers) out = union(out, fs(arm));
|
|
@@ -615,16 +629,26 @@ function keywords(words, opts = {}) {
|
|
|
615
629
|
caseInsensitive: opts.caseInsensitive ?? false,
|
|
616
630
|
boundary: opts.boundary
|
|
617
631
|
};
|
|
632
|
+
const expected = directTerminalFailureExpected(def);
|
|
633
|
+
const parseScalar = (input, pos, ctx) => {
|
|
634
|
+
re.lastIndex = pos;
|
|
635
|
+
const m = re.exec(input);
|
|
636
|
+
if (m === null) {
|
|
637
|
+
ctx._fx = expected;
|
|
638
|
+
return ~pos;
|
|
639
|
+
}
|
|
640
|
+
ctx._sv = m[0];
|
|
641
|
+
return pos + m[0].length;
|
|
642
|
+
};
|
|
618
643
|
return {
|
|
619
644
|
_tag: "keywords",
|
|
620
645
|
_meta: meta,
|
|
621
646
|
_def: def,
|
|
647
|
+
_parseScalar: parseScalar,
|
|
622
648
|
parse(input, pos, ctx) {
|
|
623
649
|
re.lastIndex = pos;
|
|
624
650
|
const m = re.exec(input);
|
|
625
|
-
if (m === null
|
|
626
|
-
return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
627
|
-
}
|
|
651
|
+
if (m === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
628
652
|
const value = m[0];
|
|
629
653
|
const span = { start: pos, end: pos + value.length };
|
|
630
654
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
@@ -768,6 +792,7 @@ function createParseContext() {
|
|
|
768
792
|
_fe: void 0,
|
|
769
793
|
_fx: void 0,
|
|
770
794
|
_fc: void 0,
|
|
795
|
+
_sv: void 0,
|
|
771
796
|
_probe: void 0,
|
|
772
797
|
_cstChildren: void 0,
|
|
773
798
|
_cstLeaves: void 0,
|
|
@@ -1468,6 +1493,9 @@ var fastScanner3;
|
|
|
1468
1493
|
function needsDeferredTriviaCommit(ctx) {
|
|
1469
1494
|
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
1470
1495
|
}
|
|
1496
|
+
function needsTriviaRollback(ctx) {
|
|
1497
|
+
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;
|
|
1498
|
+
}
|
|
1471
1499
|
function saveTriviaMark(ctx) {
|
|
1472
1500
|
const m = saveCstMark(ctx);
|
|
1473
1501
|
return {
|
|
@@ -1584,7 +1612,8 @@ function advanceTrivia(input, cur, ctx) {
|
|
|
1584
1612
|
const triviaP = ctx.trivia;
|
|
1585
1613
|
if (!triviaP) return cur;
|
|
1586
1614
|
if (!ctx.trackLines) {
|
|
1587
|
-
const
|
|
1615
|
+
const classified = triviaP._meta.triviaScanner;
|
|
1616
|
+
const fast2 = classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
1588
1617
|
if (fast2) return fast2(input, cur);
|
|
1589
1618
|
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
1590
1619
|
const tr2 = triviaP.parse(input, cur, createDetachedParseContext(ctx.trackLines, ctx.state));
|
|
@@ -2151,6 +2180,28 @@ function refuseUnclassifiedRootScope(strict) {
|
|
|
2151
2180
|
if (strict === true) throw new TypeError(ROOT_TRIVIA_SCOPE_REFUSAL);
|
|
2152
2181
|
}
|
|
2153
2182
|
|
|
2183
|
+
// src/combinators/scalar.ts
|
|
2184
|
+
var SCALAR_TAG = /^(?:literal|regex|keywords|sequence|choice|many|oneOrMore|optional|transform|trivia|grammar|sepBy|lazy)$/;
|
|
2185
|
+
function scalarOf(combinator) {
|
|
2186
|
+
return combinator._parseScalar;
|
|
2187
|
+
}
|
|
2188
|
+
function scalarTree(parser2, seen) {
|
|
2189
|
+
if (seen.has(parser2)) return true;
|
|
2190
|
+
if (parser2._parseScalar === void 0) return false;
|
|
2191
|
+
seen.add(parser2);
|
|
2192
|
+
const def = parser2._def;
|
|
2193
|
+
if (!SCALAR_TAG.test(def.tag)) return false;
|
|
2194
|
+
if ("parsers" in def && !def.parsers.every((child) => scalarTree(child, seen))) return false;
|
|
2195
|
+
if ("parser" in def && !scalarTree(def.parser, seen)) return false;
|
|
2196
|
+
if ("separator" in def && !scalarTree(def.separator, seen)) return false;
|
|
2197
|
+
return def.tag !== "lazy" || scalarTree(def.thunk(), seen);
|
|
2198
|
+
}
|
|
2199
|
+
function scalarRootOf(combinator) {
|
|
2200
|
+
const scalar = combinator._parseScalar;
|
|
2201
|
+
const def = combinator._def;
|
|
2202
|
+
return scalar !== void 0 && def.tag === "grammar" && scalarTree(def.parser, /* @__PURE__ */ new Set()) ? scalar : void 0;
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2154
2205
|
// src/combinators/grammar.ts
|
|
2155
2206
|
function annotateResultLines(result, index) {
|
|
2156
2207
|
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
@@ -2187,6 +2238,24 @@ function parser(opts, root) {
|
|
|
2187
2238
|
const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
|
|
2188
2239
|
const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
|
|
2189
2240
|
const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
|
|
2241
|
+
const rootScalar = scalarOf(root);
|
|
2242
|
+
const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
|
|
2243
|
+
const parseScalar = scalarEligible ? (input, pos, ctx) => {
|
|
2244
|
+
const savedTrivia = ctx.trivia;
|
|
2245
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
2246
|
+
if (clearTrivia) {
|
|
2247
|
+
ctx.trivia = void 0;
|
|
2248
|
+
ctx.triviaKindLabels = void 0;
|
|
2249
|
+
} else if (scopeTrivia !== void 0) {
|
|
2250
|
+
ctx.trivia = scopeTrivia;
|
|
2251
|
+
ctx.triviaKindLabels = scopeLabels;
|
|
2252
|
+
}
|
|
2253
|
+
const end = rootScalar(input, pos, ctx);
|
|
2254
|
+
ctx.trivia = savedTrivia;
|
|
2255
|
+
ctx.triviaKindLabels = savedLabels;
|
|
2256
|
+
return end;
|
|
2257
|
+
} : void 0;
|
|
2258
|
+
let publicScalar;
|
|
2190
2259
|
const grammar = {
|
|
2191
2260
|
_tag: "grammar",
|
|
2192
2261
|
_meta: {
|
|
@@ -2210,7 +2279,20 @@ function parser(opts, root) {
|
|
|
2210
2279
|
constructionTrackLines: trackLinesPolicy,
|
|
2211
2280
|
...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
|
|
2212
2281
|
},
|
|
2282
|
+
_parseScalar: parseScalar,
|
|
2213
2283
|
parse(input, pos, _ctx) {
|
|
2284
|
+
if (pos === void 0 && _ctx === void 0) {
|
|
2285
|
+
publicScalar ??= scalarRootOf(grammar) ?? null;
|
|
2286
|
+
if (publicScalar) {
|
|
2287
|
+
const ctx2 = createParseContext();
|
|
2288
|
+
const end = publicScalar(input, 0, ctx2);
|
|
2289
|
+
if (end < 0) {
|
|
2290
|
+
const at = ~end;
|
|
2291
|
+
return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
|
|
2292
|
+
}
|
|
2293
|
+
return { ok: true, value: ctx2._sv, span: { start: 0, end } };
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2214
2296
|
if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
|
|
2215
2297
|
const trackLines = trackLinesOf(_ctx);
|
|
2216
2298
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
@@ -2245,6 +2327,9 @@ function parse(combinator, input, opts = {}) {
|
|
|
2245
2327
|
_analyzed.add(combinator);
|
|
2246
2328
|
markUnusedValues(combinator);
|
|
2247
2329
|
}
|
|
2330
|
+
if (!opts.trackLines && !opts.recover && combinator._def.tag === "grammar" && combinator._meta.grammarScanSkip === void 0) {
|
|
2331
|
+
return combinator.parse(input);
|
|
2332
|
+
}
|
|
2248
2333
|
const trackLines = opts.trackLines ?? combinator._meta.grammarTrackLines ?? false;
|
|
2249
2334
|
const lineContext = trackLines ? createParseLineContext(input, 0) : void 0;
|
|
2250
2335
|
const lineIndex = lineContext?.lineIndex;
|
|
@@ -3410,7 +3495,8 @@ function choice(...args) {
|
|
|
3410
3495
|
disjoint
|
|
3411
3496
|
};
|
|
3412
3497
|
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
3413
|
-
const
|
|
3498
|
+
const ordered = strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix";
|
|
3499
|
+
const autoNot = !disjoint && !hasGates && ordered ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
3414
3500
|
let greedyLitMap = null;
|
|
3415
3501
|
let sortedParsers = null;
|
|
3416
3502
|
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
@@ -3424,6 +3510,37 @@ function choice(...args) {
|
|
|
3424
3510
|
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
3425
3511
|
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
3426
3512
|
}
|
|
3513
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
3514
|
+
const scalarEligible = !hasGates && parsers.every((p) => p._parseScalar !== void 0) && (disjoint || ordered);
|
|
3515
|
+
const scalarExpected = parsers.flatMap(deriveExpected);
|
|
3516
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3517
|
+
if (disjoint) {
|
|
3518
|
+
const code = pos < input.length ? input.codePointAt(pos) : -1;
|
|
3519
|
+
let idx = code >= 0 && code < 128 ? asciiDispatch[code] : -1;
|
|
3520
|
+
if (idx < 0 && code >= 0) {
|
|
3521
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
3522
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
3523
|
+
idx = i;
|
|
3524
|
+
break;
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3527
|
+
}
|
|
3528
|
+
if (idx >= 0) {
|
|
3529
|
+
const gate = gates[idx];
|
|
3530
|
+
if (!gate || gate(ctx.state)) return scalarParsers[idx](input, pos, ctx);
|
|
3531
|
+
ctx._fx = deriveExpected(parsers[idx]);
|
|
3532
|
+
return ~pos;
|
|
3533
|
+
}
|
|
3534
|
+
} else {
|
|
3535
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
3536
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
3537
|
+
const end = scalarParsers[i](input, pos, ctx);
|
|
3538
|
+
if (end >= 0 && (!autoNot[i] || !autoNotFires(input, end, autoNot[i]))) return end;
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3541
|
+
ctx._fx = scalarExpected;
|
|
3542
|
+
return ~pos;
|
|
3543
|
+
};
|
|
3427
3544
|
return {
|
|
3428
3545
|
_tag: "choice",
|
|
3429
3546
|
_meta: meta,
|
|
@@ -3435,6 +3552,7 @@ function choice(...args) {
|
|
|
3435
3552
|
strategy: strategy ?? { tag: "firstMatch" },
|
|
3436
3553
|
autoNot
|
|
3437
3554
|
},
|
|
3555
|
+
_parseScalar: scalarEligible ? parseScalar : void 0,
|
|
3438
3556
|
parse(input, pos, ctx) {
|
|
3439
3557
|
const expected = [];
|
|
3440
3558
|
let expectedAt = pos;
|
|
@@ -4774,8 +4892,8 @@ function buildLexProgramRunner(spec, matchers, classes, expected) {
|
|
|
4774
4892
|
}
|
|
4775
4893
|
|
|
4776
4894
|
// src/combinators/repeat.ts
|
|
4777
|
-
function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
4778
|
-
const mark = saveTriviaMark(ctx);
|
|
4895
|
+
function repItem(combinator, input, cur, ctx, guardable, mandatory, rollbackNeeded) {
|
|
4896
|
+
const mark = rollbackNeeded ? saveTriviaMark(ctx) : void 0;
|
|
4779
4897
|
let pos = cur;
|
|
4780
4898
|
if (ctx.trivia) {
|
|
4781
4899
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -4785,24 +4903,24 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
|
4785
4903
|
}
|
|
4786
4904
|
}
|
|
4787
4905
|
if (pos >= input.length && !mandatory) {
|
|
4788
|
-
rollbackTrivia(ctx, mark);
|
|
4906
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4789
4907
|
return "stop";
|
|
4790
4908
|
}
|
|
4791
4909
|
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
4792
|
-
rollbackTrivia(ctx, mark);
|
|
4910
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4793
4911
|
return "stop";
|
|
4794
4912
|
}
|
|
4795
4913
|
const result = combinator.parse(input, pos, ctx);
|
|
4796
4914
|
if (!result.ok) {
|
|
4797
|
-
rollbackTrivia(ctx, mark);
|
|
4915
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4798
4916
|
if (result.committed) return { fail: result, failPos: pos };
|
|
4799
4917
|
return { fail: result, failPos: pos };
|
|
4800
4918
|
}
|
|
4801
4919
|
if (result.span.end === pos && !mandatory) {
|
|
4802
|
-
rollbackTrivia(ctx, mark);
|
|
4920
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4803
4921
|
return "stop";
|
|
4804
4922
|
}
|
|
4805
|
-
return
|
|
4923
|
+
return result;
|
|
4806
4924
|
}
|
|
4807
4925
|
function resolveBounds(what, opts) {
|
|
4808
4926
|
const min = opts.min ?? 0;
|
|
@@ -4815,6 +4933,21 @@ function resolveBounds(what, opts) {
|
|
|
4815
4933
|
if (max < min) bad(`max (${max}) is less than min (${min}) \u2014 the combinator could never succeed`);
|
|
4816
4934
|
return { min, max };
|
|
4817
4935
|
}
|
|
4936
|
+
function repeatScalarTail(combinator, child, input, cur, ctx, guardable, values, remaining) {
|
|
4937
|
+
while (cur < input.length && remaining > 0) {
|
|
4938
|
+
let itemPos = cur;
|
|
4939
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4940
|
+
if (itemPos >= input.length) break;
|
|
4941
|
+
if (guardable && !startsFirstSet(combinator, input, itemPos)) break;
|
|
4942
|
+
const end = child(input, itemPos, ctx);
|
|
4943
|
+
if (end <= itemPos) break;
|
|
4944
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4945
|
+
cur = end;
|
|
4946
|
+
remaining--;
|
|
4947
|
+
}
|
|
4948
|
+
ctx._sv = values;
|
|
4949
|
+
return cur;
|
|
4950
|
+
}
|
|
4818
4951
|
function many(combinator, opts = {}) {
|
|
4819
4952
|
const { min, max } = resolveBounds("many()", opts);
|
|
4820
4953
|
if (min >= 1) return atLeast(combinator, min, max);
|
|
@@ -4826,17 +4959,21 @@ function many(combinator, opts = {}) {
|
|
|
4826
4959
|
const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max } };
|
|
4827
4960
|
let expected;
|
|
4828
4961
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4962
|
+
const scalarChild = scalarOf(combinator);
|
|
4963
|
+
const parseScalar = (input, pos, ctx) => repeatScalarTail(combinator, scalarChild, input, pos, ctx, guardable, def.valueUnused ? void 0 : [], max);
|
|
4829
4964
|
return {
|
|
4830
4965
|
_tag: "many",
|
|
4831
4966
|
_meta: meta,
|
|
4832
4967
|
_def: def,
|
|
4968
|
+
_parseScalar: parseScalar,
|
|
4833
4969
|
parse(input, pos, ctx) {
|
|
4834
4970
|
const values = def.valueUnused ? void 0 : [];
|
|
4971
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4835
4972
|
let cur = pos;
|
|
4836
4973
|
let count = 0;
|
|
4837
4974
|
while (cur < input.length) {
|
|
4838
4975
|
if (count >= max) break;
|
|
4839
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
4976
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4840
4977
|
if (item === "stop") break;
|
|
4841
4978
|
if ("fail" in item) {
|
|
4842
4979
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -4853,7 +4990,7 @@ function many(combinator, opts = {}) {
|
|
|
4853
4990
|
}
|
|
4854
4991
|
if (values !== void 0) values.push(item.value);
|
|
4855
4992
|
count++;
|
|
4856
|
-
cur = item.end;
|
|
4993
|
+
cur = item.span.end;
|
|
4857
4994
|
}
|
|
4858
4995
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4859
4996
|
}
|
|
@@ -4871,30 +5008,47 @@ function atLeast(combinator, min, max) {
|
|
|
4871
5008
|
const def = { tag: "oneOrMore", parser: combinator, min, ...max === Infinity ? {} : { max } };
|
|
4872
5009
|
let expected;
|
|
4873
5010
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
5011
|
+
const scalarChild = scalarOf(combinator);
|
|
5012
|
+
const parseScalar = (input, pos, ctx) => {
|
|
5013
|
+
let cur = scalarChild(input, pos, ctx);
|
|
5014
|
+
if (cur < 0) return cur;
|
|
5015
|
+
const values = def.valueUnused ? void 0 : [ctx._sv];
|
|
5016
|
+
for (let count = 1; count < min; count++) {
|
|
5017
|
+
let itemPos = cur;
|
|
5018
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
5019
|
+
const end = scalarChild(input, itemPos, ctx);
|
|
5020
|
+
if (end < 0) return ~cur;
|
|
5021
|
+
cur = end;
|
|
5022
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
5023
|
+
}
|
|
5024
|
+
return repeatScalarTail(combinator, scalarChild, input, cur, ctx, guardable, values, max - min);
|
|
5025
|
+
};
|
|
4874
5026
|
return {
|
|
4875
5027
|
_tag: "oneOrMore",
|
|
4876
5028
|
_meta: meta,
|
|
4877
5029
|
_def: def,
|
|
5030
|
+
_parseScalar: parseScalar,
|
|
4878
5031
|
parse(input, pos, ctx) {
|
|
4879
5032
|
const first = combinator.parse(input, pos, ctx);
|
|
4880
5033
|
if (!first.ok) return first;
|
|
4881
5034
|
const values = def.valueUnused ? void 0 : [first.value];
|
|
5035
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4882
5036
|
let cur = first.span.end;
|
|
4883
5037
|
let count = 1;
|
|
4884
5038
|
while (count < min) {
|
|
4885
|
-
const item = repItem(combinator, input, cur, ctx, guardable, true);
|
|
5039
|
+
const item = repItem(combinator, input, cur, ctx, guardable, true, rollbackNeeded);
|
|
4886
5040
|
if (item === "stop" || "fail" in item) {
|
|
4887
5041
|
if (item !== "stop" && !item.fail.ok && item.fail.committed) return item.fail;
|
|
4888
5042
|
expected ??= deriveExpected(combinator);
|
|
4889
5043
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: cur, end: cur } };
|
|
4890
5044
|
}
|
|
4891
5045
|
if (values !== void 0) values.push(item.value);
|
|
4892
|
-
cur = item.end;
|
|
5046
|
+
cur = item.span.end;
|
|
4893
5047
|
count++;
|
|
4894
5048
|
}
|
|
4895
5049
|
while (cur < input.length) {
|
|
4896
5050
|
if (count >= max) break;
|
|
4897
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
5051
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4898
5052
|
if (item === "stop") break;
|
|
4899
5053
|
if ("fail" in item) {
|
|
4900
5054
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -4911,7 +5065,7 @@ function atLeast(combinator, min, max) {
|
|
|
4911
5065
|
}
|
|
4912
5066
|
if (values !== void 0) values.push(item.value);
|
|
4913
5067
|
count++;
|
|
4914
|
-
cur = item.end;
|
|
5068
|
+
cur = item.span.end;
|
|
4915
5069
|
}
|
|
4916
5070
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4917
5071
|
}
|
|
@@ -4924,10 +5078,22 @@ function optional(combinator) {
|
|
|
4924
5078
|
isTrivia: false
|
|
4925
5079
|
};
|
|
4926
5080
|
const firstSetSkippable = !matchesEmpty(combinator);
|
|
5081
|
+
const scalarChild = scalarOf(combinator);
|
|
5082
|
+
const parseScalar = (input, pos, ctx) => {
|
|
5083
|
+
if (firstSetSkippable && !startsFirstSet(combinator, input, pos)) {
|
|
5084
|
+
ctx._sv = null;
|
|
5085
|
+
return pos;
|
|
5086
|
+
}
|
|
5087
|
+
const end = scalarChild(input, pos, ctx);
|
|
5088
|
+
if (end >= 0) return end;
|
|
5089
|
+
ctx._sv = null;
|
|
5090
|
+
return pos;
|
|
5091
|
+
};
|
|
4927
5092
|
return {
|
|
4928
5093
|
_tag: "optional",
|
|
4929
5094
|
_meta: meta,
|
|
4930
5095
|
_def: { tag: "optional", parser: combinator },
|
|
5096
|
+
_parseScalar: parseScalar,
|
|
4931
5097
|
parse(input, pos, ctx) {
|
|
4932
5098
|
if (firstSetSkippable && ctx._probe === void 0 && !startsFirstSet(combinator, input, pos)) {
|
|
4933
5099
|
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
@@ -4958,6 +5124,43 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4958
5124
|
expected ??= deriveExpected(combinator);
|
|
4959
5125
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: at, end: at } };
|
|
4960
5126
|
};
|
|
5127
|
+
const scalarExpected = deriveExpected(combinator);
|
|
5128
|
+
const scalarChild = scalarOf(combinator);
|
|
5129
|
+
const scalarSeparator = scalarOf(separator);
|
|
5130
|
+
const parseScalar = (input, pos, ctx) => {
|
|
5131
|
+
let cur = scalarChild(input, pos, ctx);
|
|
5132
|
+
if (cur < 0) {
|
|
5133
|
+
if (min >= 1) {
|
|
5134
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
5135
|
+
return ~pos;
|
|
5136
|
+
}
|
|
5137
|
+
ctx._sv = [];
|
|
5138
|
+
return pos;
|
|
5139
|
+
}
|
|
5140
|
+
const values = [ctx._sv];
|
|
5141
|
+
while (values.length < max && (cur < input.length || values.length < min)) {
|
|
5142
|
+
const beforeSeparator = cur;
|
|
5143
|
+
let separatorPos = cur;
|
|
5144
|
+
if (ctx.trivia) separatorPos = advanceTrivia(input, cur, ctx);
|
|
5145
|
+
const separatorEnd = scalarSeparator(input, separatorPos, ctx);
|
|
5146
|
+
if (separatorEnd < 0) break;
|
|
5147
|
+
let itemPos = separatorEnd;
|
|
5148
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, itemPos, ctx);
|
|
5149
|
+
const itemEnd = scalarChild(input, itemPos, ctx);
|
|
5150
|
+
if (itemEnd < 0) {
|
|
5151
|
+
cur = trailing === "allow" ? separatorEnd : beforeSeparator;
|
|
5152
|
+
break;
|
|
5153
|
+
}
|
|
5154
|
+
values.push(ctx._sv);
|
|
5155
|
+
cur = itemEnd;
|
|
5156
|
+
}
|
|
5157
|
+
if (values.length < min) {
|
|
5158
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
5159
|
+
return ~cur;
|
|
5160
|
+
}
|
|
5161
|
+
ctx._sv = values;
|
|
5162
|
+
return cur;
|
|
5163
|
+
};
|
|
4961
5164
|
return {
|
|
4962
5165
|
_tag: "sepBy",
|
|
4963
5166
|
_meta: meta,
|
|
@@ -4973,6 +5176,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4973
5176
|
// this option surface already; parity is held by test/parity, not by hope.
|
|
4974
5177
|
...keepSeparators ? { keepSeparators: true } : {}
|
|
4975
5178
|
},
|
|
5179
|
+
_parseScalar: keepSeparators ? void 0 : parseScalar,
|
|
4976
5180
|
parse(input, pos, ctx) {
|
|
4977
5181
|
const first = combinator.parse(input, pos, ctx);
|
|
4978
5182
|
const values = [];
|
|
@@ -5050,11 +5254,54 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
5050
5254
|
}
|
|
5051
5255
|
|
|
5052
5256
|
// src/combinators/map.ts
|
|
5257
|
+
var JSON_STRING_BODY = String.raw`(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*`;
|
|
5053
5258
|
function transform(combinator, fn) {
|
|
5259
|
+
const observesSpan = fn.length > 1;
|
|
5260
|
+
const sequenceDef = combinator._def.tag === "sequence" ? combinator._def : void 0;
|
|
5261
|
+
const terms = sequenceDef?.parsers;
|
|
5262
|
+
const inner = terms?.[1];
|
|
5263
|
+
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;
|
|
5264
|
+
const child = scalarOf(combinator);
|
|
5265
|
+
const parseScalar = fused ? (() => {
|
|
5266
|
+
const body = inner._stickyRegex;
|
|
5267
|
+
const tuple = ['"', "", '"'];
|
|
5268
|
+
const expected = [JSON.stringify('"')];
|
|
5269
|
+
return (input, pos, ctx) => {
|
|
5270
|
+
if (ctx.trivia !== void 0) {
|
|
5271
|
+
const end2 = child(input, pos, ctx);
|
|
5272
|
+
if (end2 < 0) return end2;
|
|
5273
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end: end2 }) : fn(ctx._sv);
|
|
5274
|
+
return end2;
|
|
5275
|
+
}
|
|
5276
|
+
if (input.charCodeAt(pos) !== 34) {
|
|
5277
|
+
ctx._fx = expected;
|
|
5278
|
+
return ~pos;
|
|
5279
|
+
}
|
|
5280
|
+
body.lastIndex = pos + 1;
|
|
5281
|
+
const match = body.exec(input);
|
|
5282
|
+
const close = pos + 1 + match[0].length;
|
|
5283
|
+
if (input.charCodeAt(close) !== 34) {
|
|
5284
|
+
ctx._fx = expected;
|
|
5285
|
+
return ~close;
|
|
5286
|
+
}
|
|
5287
|
+
tuple[1] = match[0];
|
|
5288
|
+
const end = close + 1;
|
|
5289
|
+
ctx._sv = observesSpan ? fn(tuple, { start: pos, end }) : fn(tuple);
|
|
5290
|
+
return end;
|
|
5291
|
+
};
|
|
5292
|
+
})() : /* @__PURE__ */ (() => {
|
|
5293
|
+
return (input, pos, ctx) => {
|
|
5294
|
+
const end = child(input, pos, ctx);
|
|
5295
|
+
if (end < 0) return end;
|
|
5296
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end }) : fn(ctx._sv);
|
|
5297
|
+
return end;
|
|
5298
|
+
};
|
|
5299
|
+
})();
|
|
5054
5300
|
return {
|
|
5055
5301
|
_tag: "transform",
|
|
5056
5302
|
_meta: combinator._meta,
|
|
5057
5303
|
_def: { tag: "transform", parser: combinator, fn },
|
|
5304
|
+
_parseScalar: parseScalar,
|
|
5058
5305
|
parse(input, pos, ctx) {
|
|
5059
5306
|
const result = combinator.parse(input, pos, ctx);
|
|
5060
5307
|
if (!result.ok) return result;
|
|
@@ -5069,9 +5316,11 @@ function trivia(combinator) {
|
|
|
5069
5316
|
_meta: {
|
|
5070
5317
|
...combinator._meta,
|
|
5071
5318
|
isTrivia: true,
|
|
5319
|
+
triviaScanner: fastTriviaScanner(combinator),
|
|
5072
5320
|
...kindLabels ? { triviaKindLabels: kindLabels } : {}
|
|
5073
5321
|
},
|
|
5074
5322
|
_def: { tag: "trivia", parser: combinator },
|
|
5323
|
+
_parseScalar: scalarOf(combinator),
|
|
5075
5324
|
parse: combinator.parse.bind(combinator)
|
|
5076
5325
|
};
|
|
5077
5326
|
}
|
|
@@ -5192,10 +5441,32 @@ function regex(pattern, flags = "") {
|
|
|
5192
5441
|
const canMatchNewline = raw.canMatchNewline;
|
|
5193
5442
|
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
5194
5443
|
const def = { tag: "regex", source, flags: resolvedFlags };
|
|
5444
|
+
const expected = directTerminalFailureExpected(def);
|
|
5445
|
+
const parseScalar = (input, pos, ctx) => {
|
|
5446
|
+
const scanEnd = scan?.(input, pos);
|
|
5447
|
+
if (scanEnd !== void 0) {
|
|
5448
|
+
if (scanEnd === null) {
|
|
5449
|
+
ctx._fx = expected;
|
|
5450
|
+
return ~pos;
|
|
5451
|
+
}
|
|
5452
|
+
ctx._sv = input.slice(pos, scanEnd);
|
|
5453
|
+
return scanEnd;
|
|
5454
|
+
}
|
|
5455
|
+
anchored.lastIndex = pos;
|
|
5456
|
+
const match = anchored.exec(input);
|
|
5457
|
+
if (match === null) {
|
|
5458
|
+
ctx._fx = expected;
|
|
5459
|
+
return ~pos;
|
|
5460
|
+
}
|
|
5461
|
+
ctx._sv = match[0];
|
|
5462
|
+
return pos + match[0].length;
|
|
5463
|
+
};
|
|
5195
5464
|
return {
|
|
5196
5465
|
_tag: "regex",
|
|
5197
5466
|
_meta: meta,
|
|
5198
5467
|
_def: def,
|
|
5468
|
+
_stickyRegex: anchored,
|
|
5469
|
+
_parseScalar: parseScalar,
|
|
5199
5470
|
parse(input, pos, ctx) {
|
|
5200
5471
|
const scanEnd = scan?.(input, pos);
|
|
5201
5472
|
if (scanEnd !== void 0) {
|
|
@@ -6785,7 +7056,7 @@ var Encoder = class {
|
|
|
6785
7056
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
6786
7057
|
);
|
|
6787
7058
|
if (matchesEmpty(d.parser)) return body;
|
|
6788
|
-
const fs = d.parser._meta.firstSet;
|
|
7059
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
6789
7060
|
if (fs.kind === "any") return body;
|
|
6790
7061
|
const cls = this.charClass(fs);
|
|
6791
7062
|
if (cls < 0) return body;
|
|
@@ -6805,7 +7076,7 @@ var Encoder = class {
|
|
|
6805
7076
|
const dispCovIds = this.plan?.dispatches.get(p);
|
|
6806
7077
|
let dispCov = 0;
|
|
6807
7078
|
const arms = [];
|
|
6808
|
-
const
|
|
7079
|
+
const routed = [];
|
|
6809
7080
|
const key = [], keyArm = [];
|
|
6810
7081
|
const fold = [], foldArm = [];
|
|
6811
7082
|
const match = [];
|
|
@@ -6813,7 +7084,7 @@ var Encoder = class {
|
|
|
6813
7084
|
for (const c of d.cases) {
|
|
6814
7085
|
const arm = arms.length;
|
|
6815
7086
|
arms.push(this.covWrap(this.node(c.parser).ip, dispCovIds?.[dispCov++], 1));
|
|
6816
|
-
|
|
7087
|
+
routed.push(branchUsesRouted(c) ? 1 : 0);
|
|
6817
7088
|
for (const kk of c.keys) {
|
|
6818
7089
|
expected.push(JSON.stringify(kk));
|
|
6819
7090
|
if (c.caseInsensitive) {
|
|
@@ -6829,7 +7100,7 @@ var Encoder = class {
|
|
|
6829
7100
|
for (const m of d.matchers ?? []) {
|
|
6830
7101
|
const arm = arms.length;
|
|
6831
7102
|
arms.push(this.covWrap(this.node(m.parser).ip, dispCovIds?.[dispCov++], 1));
|
|
6832
|
-
|
|
7103
|
+
routed.push(branchUsesRouted(m) ? 1 : 0);
|
|
6833
7104
|
if (!m.caseInsensitive) {
|
|
6834
7105
|
match.push([KIND[m.kind], m.value, m.flags ?? "", arm]);
|
|
6835
7106
|
continue;
|
|
@@ -6843,7 +7114,7 @@ var Encoder = class {
|
|
|
6843
7114
|
}
|
|
6844
7115
|
const other = d.otherwise === void 0 ? -1 : this.covWrap(this.node(d.otherwise).ip, dispCovIds?.[dispCov++], 1);
|
|
6845
7116
|
const dspIdx = this.dsp.length;
|
|
6846
|
-
this.dsp.push({ key, keyArm, fold, foldArm, match, routed
|
|
7117
|
+
this.dsp.push({ key, keyArm, fold, foldArm, match, routed, expected });
|
|
6847
7118
|
const head = this.emitHead(OP_DISPATCH, 5 + arms.length);
|
|
6848
7119
|
this.code[head + 1] = sel;
|
|
6849
7120
|
this.code[head + 2] = dspIdx;
|
|
@@ -6899,7 +7170,7 @@ var Encoder = class {
|
|
|
6899
7170
|
case "attempt": {
|
|
6900
7171
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
|
|
6901
7172
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
6902
|
-
const fs = d.parser._meta.firstSet;
|
|
7173
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
6903
7174
|
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
6904
7175
|
const cls = this.charClass(fs);
|
|
6905
7176
|
if (cls < 0) return inner;
|
|
@@ -8715,6 +8986,9 @@ if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTrivi
|
|
|
8715
8986
|
function q(s) {
|
|
8716
8987
|
return JSON.stringify(s);
|
|
8717
8988
|
}
|
|
8989
|
+
function isAsciiOnlyClass(cls) {
|
|
8990
|
+
return cls !== null && cls !== void 0 && cls.hi.length === 0;
|
|
8991
|
+
}
|
|
8718
8992
|
var NO_SINKS = { fd: false, er: false };
|
|
8719
8993
|
function sinkSlots(t2, s) {
|
|
8720
8994
|
return `${s.fd ? `,${t2}fd=0` : ""}${s.er ? `,${t2}er=0` : ""}`;
|
|
@@ -9261,12 +9535,13 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
9261
9535
|
return `${head}EC.e=pos;return ''}`;
|
|
9262
9536
|
case OP_GATE: {
|
|
9263
9537
|
const child = link(code[ip + 2]);
|
|
9264
|
-
const
|
|
9538
|
+
const resolved = t2.cc[code[ip + 1]];
|
|
9539
|
+
const ci = classes.push([resolved]) - 1;
|
|
9265
9540
|
classPlan.push([code[ip + 1]]);
|
|
9266
9541
|
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
9267
9542
|
const xf = fxRef(code[ip + 3]);
|
|
9268
9543
|
return `${head}
|
|
9269
|
-
if(
|
|
9544
|
+
if(${staticBuild && isAsciiOnlyClass(resolved) ? `${cls}.ascii[input.charCodeAt(pos)]!==1` : `!classHas(${cls},lead(input,pos))`}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
9270
9545
|
return ${child}(input,pos,ctx)
|
|
9271
9546
|
}`;
|
|
9272
9547
|
}
|
|
@@ -9609,10 +9884,11 @@ return v
|
|
|
9609
9884
|
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
9610
9885
|
const hiArr = table.hi;
|
|
9611
9886
|
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
9887
|
+
const directAscii = staticBuild && table.hi.length === 0;
|
|
9612
9888
|
return `${head}
|
|
9613
|
-
const c
|
|
9889
|
+
const c=${directAscii ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
9614
9890
|
let arm=-1
|
|
9615
|
-
if(c>=0&&c<128){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
9891
|
+
if(${directAscii ? "c<128" : "c>=0&&c<128"}){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
9616
9892
|
${hiArr.length === 0 ? "" : `else if(c>=128){const h=${hoist("hi", `DISP[${di}].hi`)}
|
|
9617
9893
|
for(let i=0;i<h.length;i+=3){if(c>=h[i]&&c<=h[i+1]){arm=h[i+2];break}}}`}
|
|
9618
9894
|
if(arm>=0){
|
|
@@ -9634,7 +9910,9 @@ return FAIL
|
|
|
9634
9910
|
const di = code[ip + 1];
|
|
9635
9911
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
9636
9912
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
9637
|
-
const
|
|
9913
|
+
const maskable = n <= 32;
|
|
9914
|
+
const directAsciiMask = staticBuild && maskable && gates.every(isAsciiOnlyClass);
|
|
9915
|
+
const gateRefs = directAsciiMask ? [] : Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
9638
9916
|
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
9639
9917
|
const pretests = Array.from({ length: n }, (_, i) => {
|
|
9640
9918
|
if (tokenCandidate?.arm === i) {
|
|
@@ -9654,7 +9932,6 @@ return FAIL
|
|
|
9654
9932
|
const sequence6 = largeChoiceScalarSequences.get(code[base + i]);
|
|
9655
9933
|
return sequence6 === void 0 ? void 0 : { sequence: scalarSequenceRef(sequence6) };
|
|
9656
9934
|
});
|
|
9657
|
-
const maskable = n <= 32;
|
|
9658
9935
|
const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
|
|
9659
9936
|
if (maskable) maskPlan.push(~di);
|
|
9660
9937
|
const p = tmp();
|
|
@@ -9716,16 +9993,16 @@ ${merge}
|
|
|
9716
9993
|
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
9717
9994
|
return FAIL`;
|
|
9718
9995
|
return `${head}
|
|
9719
|
-
const c
|
|
9996
|
+
const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
9720
9997
|
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
9721
9998
|
${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
|
|
9722
9999
|
${maskable ? `if(c<128){
|
|
9723
|
-
const bits=${maskName}[c<0?128:c]
|
|
10000
|
+
const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
9724
10001
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
9725
10002
|
${lazyArms(true)}
|
|
9726
|
-
}else{
|
|
10003
|
+
}${directAsciiMask ? "" : `else{
|
|
9727
10004
|
${lazyArms(false)}
|
|
9728
|
-
}
|
|
10005
|
+
}`}
|
|
9729
10006
|
` : lazyArms(false)}
|
|
9730
10007
|
${finish}
|
|
9731
10008
|
}`;
|
|
@@ -9776,7 +10053,7 @@ if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0
|
|
|
9776
10053
|
${rollbackFor(i)}
|
|
9777
10054
|
}${routeMiss}${sequenceMiss}`;
|
|
9778
10055
|
}).join("\n") : "";
|
|
9779
|
-
const generalArms = arms.map((arm, i) => {
|
|
10056
|
+
const generalArms = directAsciiMask ? "" : arms.map((arm, i) => {
|
|
9780
10057
|
const pretest = pretests[i];
|
|
9781
10058
|
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
9782
10059
|
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
@@ -9806,12 +10083,12 @@ ${rollbackFor(i)}
|
|
|
9806
10083
|
}${miss}`;
|
|
9807
10084
|
}).join("\n");
|
|
9808
10085
|
return `${head}
|
|
9809
|
-
const c
|
|
10086
|
+
const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
9810
10087
|
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
9811
10088
|
let acc
|
|
9812
10089
|
let best=pos
|
|
9813
10090
|
${maskable ? `if(c<128){
|
|
9814
|
-
const bits=${maskName}[c<0?128:c]
|
|
10091
|
+
const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
9815
10092
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
9816
10093
|
${startFailureExact ? "" : "let prev=0"}
|
|
9817
10094
|
${maskArms}
|
|
@@ -9906,14 +10183,18 @@ return [key,v]
|
|
|
9906
10183
|
const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
|
|
9907
10184
|
const collect = op === OP_REP;
|
|
9908
10185
|
let itemCls;
|
|
10186
|
+
let itemAscii = false;
|
|
9909
10187
|
if (!REC) {
|
|
9910
10188
|
const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
|
|
9911
10189
|
if (itemClassIndex >= 0) {
|
|
9912
|
-
const
|
|
10190
|
+
const resolved = t2.cc[itemClassIndex];
|
|
10191
|
+
const ci = classes.push([resolved]) - 1;
|
|
9913
10192
|
classPlan.push([itemClassIndex]);
|
|
9914
10193
|
itemCls = hoist("ri", `CLS[${ci}][0]`);
|
|
10194
|
+
itemAscii = staticBuild && isAsciiOnlyClass(resolved);
|
|
9915
10195
|
}
|
|
9916
10196
|
}
|
|
10197
|
+
const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
|
|
9917
10198
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
9918
10199
|
const p = tmp();
|
|
9919
10200
|
const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
|
|
@@ -9973,7 +10254,7 @@ let count=0
|
|
|
9973
10254
|
for(;;){
|
|
9974
10255
|
${max >= 0 ? `if(count>=${max})break
|
|
9975
10256
|
` : ""}${sep !== void 0 ? `if(count>0&&count>=${min}&&cur>=input.length)break
|
|
9976
|
-
` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}
|
|
10257
|
+
` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}&&${itemMiss("cur")})break
|
|
9977
10258
|
` : ""}let ${p}raw=0,${p}tl=0,${p}lv=0,${p}lg=0,${p}rt=0${sinks.fd ? `,${p}fd=0` : ""}${sinks.er ? `,${p}er=0` : ""}
|
|
9978
10259
|
${markBody}
|
|
9979
10260
|
let itemStart=cur
|
|
@@ -9998,7 +10279,7 @@ itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(inp
|
|
|
9998
10279
|
${rb}
|
|
9999
10280
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
10000
10281
|
}
|
|
10001
|
-
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate
|
|
10282
|
+
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&${itemMiss("itemStart")}){
|
|
10002
10283
|
${rb}
|
|
10003
10284
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
10004
10285
|
}
|
|
@@ -10282,6 +10563,28 @@ function literal(value, opts = {}) {
|
|
|
10282
10563
|
isTrivia: false
|
|
10283
10564
|
};
|
|
10284
10565
|
const canMatchNewline = meta.canMatchNewline;
|
|
10566
|
+
const parseScalar = !caseInsensitive && value.length === 1 ? (() => {
|
|
10567
|
+
const code = value.charCodeAt(0);
|
|
10568
|
+
return (input, pos, ctx) => {
|
|
10569
|
+
if (input.charCodeAt(pos) === code) {
|
|
10570
|
+
ctx._sv = value;
|
|
10571
|
+
return pos + 1;
|
|
10572
|
+
}
|
|
10573
|
+
ctx._fx = expected;
|
|
10574
|
+
return ~pos;
|
|
10575
|
+
};
|
|
10576
|
+
})() : (input, pos, ctx) => {
|
|
10577
|
+
const end = pos + value.length;
|
|
10578
|
+
if (end <= input.length) {
|
|
10579
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
10580
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
10581
|
+
ctx._sv = matchedValue;
|
|
10582
|
+
return end;
|
|
10583
|
+
}
|
|
10584
|
+
}
|
|
10585
|
+
ctx._fx = expected;
|
|
10586
|
+
return ~pos;
|
|
10587
|
+
};
|
|
10285
10588
|
if (caseInsensitive) {
|
|
10286
10589
|
const upper = value.toUpperCase();
|
|
10287
10590
|
const lower = value.toLowerCase();
|
|
@@ -10322,6 +10625,7 @@ function literal(value, opts = {}) {
|
|
|
10322
10625
|
_tag: "literal",
|
|
10323
10626
|
_meta: meta,
|
|
10324
10627
|
_def: { tag: "literal", value, caseInsensitive },
|
|
10628
|
+
_parseScalar: parseScalar,
|
|
10325
10629
|
parse: parse2
|
|
10326
10630
|
};
|
|
10327
10631
|
}
|
|
@@ -10341,6 +10645,7 @@ function sequence(...parsers) {
|
|
|
10341
10645
|
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
10342
10646
|
}
|
|
10343
10647
|
const hasAdjacency = adjacency !== null;
|
|
10648
|
+
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
10344
10649
|
const meta = {
|
|
10345
10650
|
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
10346
10651
|
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
@@ -10349,165 +10654,96 @@ function sequence(...parsers) {
|
|
|
10349
10654
|
isTrivia: false
|
|
10350
10655
|
};
|
|
10351
10656
|
const def = { tag: "sequence", parsers };
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
10355
|
-
const fs = parsers.slice(i + 1).reduce(
|
|
10356
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
10357
|
-
{ kind: "empty" }
|
|
10358
|
-
);
|
|
10359
|
-
return firstSetSentinel(fs);
|
|
10360
|
-
});
|
|
10361
|
-
const values = def.valueUnused ? void 0 : [];
|
|
10657
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
10658
|
+
const parseScalar = (input, pos, ctx) => {
|
|
10362
10659
|
let cur = pos;
|
|
10363
|
-
|
|
10364
|
-
|
|
10365
|
-
|
|
10366
|
-
|
|
10367
|
-
|
|
10368
|
-
|
|
10369
|
-
|
|
10370
|
-
|
|
10371
|
-
|
|
10372
|
-
|
|
10373
|
-
|
|
10374
|
-
const mTlog = cstTlLen(ctx);
|
|
10375
|
-
const mLog = ctx._triviaLog?.length ?? 0;
|
|
10376
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
10377
|
-
let scanEnd;
|
|
10378
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
10379
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
10380
|
-
} else {
|
|
10381
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
10382
|
-
}
|
|
10383
|
-
const scanTlog = cstTlLen(ctx);
|
|
10384
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
10385
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
10386
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
10387
|
-
if (!result2.ok) return result2;
|
|
10388
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
10389
|
-
else rollbackScannedTriviaAt(
|
|
10390
|
-
ctx,
|
|
10391
|
-
mTlog,
|
|
10392
|
-
scanTlog,
|
|
10393
|
-
mLog,
|
|
10394
|
-
scanLog,
|
|
10395
|
-
mRootLog,
|
|
10396
|
-
scanRootLog
|
|
10397
|
-
);
|
|
10398
|
-
if (values !== void 0) values.push(result2.value);
|
|
10399
|
-
continue;
|
|
10400
|
-
}
|
|
10401
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
10402
|
-
if (!result.ok) return result;
|
|
10403
|
-
if (values !== void 0) values.push(result.value);
|
|
10404
|
-
cur = result.span.end;
|
|
10660
|
+
if (strictArity !== 0) {
|
|
10661
|
+
cur = scalarParsers[0](input, cur, ctx);
|
|
10662
|
+
if (cur < 0) return cur;
|
|
10663
|
+
const first = ctx._sv;
|
|
10664
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
10665
|
+
cur = scalarParsers[1](input, cur, ctx);
|
|
10666
|
+
if (cur < 0) return cur;
|
|
10667
|
+
const second = ctx._sv;
|
|
10668
|
+
if (strictArity === 2) {
|
|
10669
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second];
|
|
10670
|
+
return cur;
|
|
10405
10671
|
}
|
|
10406
|
-
|
|
10407
|
-
|
|
10672
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
10673
|
+
cur = scalarParsers[2](input, cur, ctx);
|
|
10674
|
+
if (cur < 0) return cur;
|
|
10675
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second, ctx._sv];
|
|
10676
|
+
return cur;
|
|
10408
10677
|
}
|
|
10409
|
-
return {
|
|
10410
|
-
ok: true,
|
|
10411
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
10412
|
-
value: values ?? void 0,
|
|
10413
|
-
span: { start: pos, end: cur }
|
|
10414
|
-
};
|
|
10415
|
-
}
|
|
10416
|
-
function parseAdjacent(input, pos, ctx) {
|
|
10417
10678
|
const values = def.valueUnused ? void 0 : [];
|
|
10418
|
-
let
|
|
10419
|
-
|
|
10420
|
-
|
|
10421
|
-
|
|
10422
|
-
|
|
10423
|
-
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
|
|
10428
|
-
|
|
10429
|
-
|
|
10430
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
10431
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
10432
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
10433
|
-
} else {
|
|
10434
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
10435
|
-
}
|
|
10436
|
-
const scanTlog = cstTlLen(ctx);
|
|
10437
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
10438
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
10439
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
10440
|
-
if (!result2.ok) return result2;
|
|
10441
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
10442
|
-
else rollbackScannedTriviaAt(
|
|
10443
|
-
ctx,
|
|
10444
|
-
mTlog,
|
|
10445
|
-
scanTlog,
|
|
10446
|
-
mLog,
|
|
10447
|
-
scanLog,
|
|
10448
|
-
mRootLog,
|
|
10449
|
-
scanRootLog
|
|
10450
|
-
);
|
|
10451
|
-
if (values !== void 0) values.push(result2.value);
|
|
10452
|
-
continue;
|
|
10453
|
-
}
|
|
10454
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
10455
|
-
if (!result.ok) return result;
|
|
10456
|
-
if (values !== void 0) values.push(result.value);
|
|
10457
|
-
cur = result.span.end;
|
|
10458
|
-
}
|
|
10459
|
-
return {
|
|
10460
|
-
ok: true,
|
|
10461
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
10462
|
-
value: values ?? void 0,
|
|
10463
|
-
span: { start: pos, end: cur }
|
|
10464
|
-
};
|
|
10465
|
-
}
|
|
10679
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
10680
|
+
let termPos = cur;
|
|
10681
|
+
if (i > 0 && ctx.trivia) termPos = advanceTrivia(input, cur, ctx);
|
|
10682
|
+
const end = scalarParsers[i](input, termPos, ctx);
|
|
10683
|
+
if (end < 0) return end;
|
|
10684
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
10685
|
+
if (end > termPos || termPos === cur) cur = end;
|
|
10686
|
+
}
|
|
10687
|
+
ctx._sv = values;
|
|
10688
|
+
return cur;
|
|
10689
|
+
};
|
|
10690
|
+
let followSentinels;
|
|
10466
10691
|
return {
|
|
10467
10692
|
_tag: "sequence",
|
|
10468
10693
|
_meta: meta,
|
|
10469
10694
|
_def: def,
|
|
10695
|
+
_parseScalar: hasAdjacency ? void 0 : parseScalar,
|
|
10470
10696
|
parse(input, pos, ctx) {
|
|
10471
|
-
|
|
10472
|
-
if (
|
|
10697
|
+
const tolerant = ctx._tolerant === true;
|
|
10698
|
+
if (tolerant) {
|
|
10699
|
+
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
10700
|
+
parsers.slice(i + 1).reduce(
|
|
10701
|
+
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
10702
|
+
{ kind: "empty" }
|
|
10703
|
+
)
|
|
10704
|
+
));
|
|
10705
|
+
}
|
|
10706
|
+
const inheritedSync = ctx._sync;
|
|
10707
|
+
const deferredTrivia = needsDeferredTriviaCommit(ctx);
|
|
10473
10708
|
const values = def.valueUnused ? void 0 : [];
|
|
10474
10709
|
let cur = pos;
|
|
10475
|
-
|
|
10476
|
-
|
|
10477
|
-
|
|
10478
|
-
const
|
|
10479
|
-
|
|
10480
|
-
|
|
10481
|
-
|
|
10482
|
-
|
|
10483
|
-
} else {
|
|
10484
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
10710
|
+
try {
|
|
10711
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
10712
|
+
if (tolerant) ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
10713
|
+
const assertion = adjacency?.[i];
|
|
10714
|
+
if (assertion) {
|
|
10715
|
+
if (!holdsAdjacency(input, cur, ctx, assertion)) return adjacencyFail(cur, assertion);
|
|
10716
|
+
if (values !== void 0) values.push(null);
|
|
10717
|
+
continue;
|
|
10485
10718
|
}
|
|
10486
|
-
|
|
10487
|
-
const
|
|
10488
|
-
const
|
|
10489
|
-
const
|
|
10490
|
-
if (
|
|
10491
|
-
|
|
10492
|
-
|
|
10493
|
-
|
|
10719
|
+
let termPos = cur;
|
|
10720
|
+
const markTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
10721
|
+
const markLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
10722
|
+
const markRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
10723
|
+
if (ctx.trivia && i > 0) {
|
|
10724
|
+
termPos = deferredTrivia ? commitTriviaScan(scanTriviaCompact(input, cur, ctx)) : advanceTrivia(input, cur, ctx);
|
|
10725
|
+
}
|
|
10726
|
+
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
10727
|
+
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
10728
|
+
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
10729
|
+
const result = parsers[i].parse(input, termPos, ctx);
|
|
10730
|
+
if (!result.ok) return result;
|
|
10731
|
+
if (values !== void 0) values.push(result.value);
|
|
10732
|
+
if (result.span.end > termPos || termPos === cur) cur = result.span.end;
|
|
10733
|
+
else if (deferredTrivia) {
|
|
10494
10734
|
rollbackScannedTriviaAt(
|
|
10495
10735
|
ctx,
|
|
10496
|
-
|
|
10736
|
+
markTlog,
|
|
10497
10737
|
scanTlog,
|
|
10498
|
-
|
|
10738
|
+
markLog,
|
|
10499
10739
|
scanLog,
|
|
10500
|
-
|
|
10740
|
+
markRootLog,
|
|
10501
10741
|
scanRootLog
|
|
10502
10742
|
);
|
|
10503
10743
|
}
|
|
10504
|
-
if (values !== void 0) values.push(result2.value);
|
|
10505
|
-
continue;
|
|
10506
10744
|
}
|
|
10507
|
-
|
|
10508
|
-
if (
|
|
10509
|
-
if (values !== void 0) values.push(result.value);
|
|
10510
|
-
cur = result.span.end;
|
|
10745
|
+
} finally {
|
|
10746
|
+
if (tolerant) ctx._sync = inheritedSync;
|
|
10511
10747
|
}
|
|
10512
10748
|
return {
|
|
10513
10749
|
ok: true,
|
|
@@ -10520,8 +10756,20 @@ function sequence(...parsers) {
|
|
|
10520
10756
|
}
|
|
10521
10757
|
|
|
10522
10758
|
// src/combinators/ref.ts
|
|
10759
|
+
function withRuleTrivia(trivia2, ctx, run) {
|
|
10760
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
10761
|
+
ctx.trivia = trivia2;
|
|
10762
|
+
ctx.triviaKindLabels = trivia2._meta.triviaKindLabels;
|
|
10763
|
+
try {
|
|
10764
|
+
return run();
|
|
10765
|
+
} finally {
|
|
10766
|
+
ctx.trivia = void 0;
|
|
10767
|
+
ctx.triviaKindLabels = savedLabels;
|
|
10768
|
+
}
|
|
10769
|
+
}
|
|
10523
10770
|
function ref() {
|
|
10524
10771
|
let resolved = null;
|
|
10772
|
+
let resolvedScalar = null;
|
|
10525
10773
|
let ownBoundary = false;
|
|
10526
10774
|
const meta = {
|
|
10527
10775
|
firstSet: any(),
|
|
@@ -10538,25 +10786,28 @@ function ref() {
|
|
|
10538
10786
|
return resolved;
|
|
10539
10787
|
}
|
|
10540
10788
|
},
|
|
10789
|
+
_parseScalar(input, pos, ctx) {
|
|
10790
|
+
const scalar = resolvedScalar;
|
|
10791
|
+
if (!scalar) throw new Error("ref<T>() used before .define() was called");
|
|
10792
|
+
const gt = meta.grammarTrivia;
|
|
10793
|
+
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
10794
|
+
return withRuleTrivia(gt, ctx, () => scalar(input, pos, ctx));
|
|
10795
|
+
}
|
|
10796
|
+
return scalar(input, pos, ctx);
|
|
10797
|
+
},
|
|
10541
10798
|
parse(input, pos, ctx) {
|
|
10542
|
-
|
|
10799
|
+
const parser2 = resolved;
|
|
10800
|
+
if (!parser2) throw new Error("ref<T>() used before .define() was called");
|
|
10543
10801
|
const gt = meta.grammarTrivia;
|
|
10544
10802
|
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
10545
|
-
|
|
10546
|
-
ctx.trivia = gt;
|
|
10547
|
-
ctx.triviaKindLabels = gt._meta.triviaKindLabels;
|
|
10548
|
-
try {
|
|
10549
|
-
return resolved.parse(input, pos, ctx);
|
|
10550
|
-
} finally {
|
|
10551
|
-
ctx.trivia = void 0;
|
|
10552
|
-
ctx.triviaKindLabels = savedLabels;
|
|
10553
|
-
}
|
|
10803
|
+
return withRuleTrivia(gt, ctx, () => parser2.parse(input, pos, ctx));
|
|
10554
10804
|
}
|
|
10555
|
-
return
|
|
10805
|
+
return parser2.parse(input, pos, ctx);
|
|
10556
10806
|
},
|
|
10557
10807
|
define(p) {
|
|
10558
10808
|
if (resolved) throw new Error("ref<T>() already defined");
|
|
10559
10809
|
resolved = p;
|
|
10810
|
+
resolvedScalar = scalarOf(p);
|
|
10560
10811
|
ownBoundary = hasOwnTriviaBoundary(p);
|
|
10561
10812
|
meta.firstSet = p._meta.firstSet;
|
|
10562
10813
|
meta.canMatchNewline = p._meta.canMatchNewline;
|
|
@@ -13461,10 +13712,10 @@ function assemble(t2, prog, cfg) {
|
|
|
13461
13712
|
const hasFold = spec.byFold.size > 0;
|
|
13462
13713
|
const match = spec.match;
|
|
13463
13714
|
const matchN = match.length;
|
|
13464
|
-
const
|
|
13715
|
+
const routed = spec.routed;
|
|
13465
13716
|
const expected = spec.expected;
|
|
13466
13717
|
const validArm = (arm) => Number.isInteger(arm) && arm >= 0 && arm < n;
|
|
13467
|
-
if (
|
|
13718
|
+
if (routed.length !== n) throw new TypeError("table assembler: malformed dispatch routed arity");
|
|
13468
13719
|
for (const arm of byKey.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch exact arm");
|
|
13469
13720
|
for (const arm of byFold.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch folded arm");
|
|
13470
13721
|
for (const m of match) if (!validArm(m[3])) throw new TypeError("table assembler: malformed dispatch matcher arm");
|
|
@@ -13489,7 +13740,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13489
13740
|
const classify = hasFold ? matchBlock === void 0 ? (key) => byKey.get(key) ?? byFold.get(asciiFoldKey(key)) : (key) => byKey.get(key) ?? byFold.get(asciiFoldKey(key)) ?? matchBlock(key) : matchBlock === void 0 ? (key) => byKey.get(key) : (key) => byKey.get(key) ?? matchBlock(key);
|
|
13490
13741
|
const neverBranch = () => FAIL;
|
|
13491
13742
|
const bindArms = (start) => {
|
|
13492
|
-
const branch = (i) => i < n ? dispatchBranch(link(code[armBase + i]),
|
|
13743
|
+
const branch = (i) => i < n ? dispatchBranch(link(code[armBase + i]), routed[i] === 1) : neverBranch;
|
|
13493
13744
|
const next = start + 4 < n ? bindArms(start + 4) : void 0;
|
|
13494
13745
|
return dispatchArmBlock(
|
|
13495
13746
|
start,
|
|
@@ -14308,7 +14559,7 @@ function buildGrammarPlan(entry, winners) {
|
|
|
14308
14559
|
const dispatches = /* @__PURE__ */ new Map();
|
|
14309
14560
|
const attempts = /* @__PURE__ */ new Map();
|
|
14310
14561
|
const labels = /* @__PURE__ */ new Map();
|
|
14311
|
-
const
|
|
14562
|
+
const rules = /* @__PURE__ */ new Map();
|
|
14312
14563
|
const winnerNames = /* @__PURE__ */ new Map();
|
|
14313
14564
|
if (winners) {
|
|
14314
14565
|
for (const [name, winner] of Object.entries(winners)) {
|
|
@@ -14329,7 +14580,7 @@ function buildGrammarPlan(entry, winners) {
|
|
|
14329
14580
|
if (rule2 && (winnerNames.has(parser2) || parser2._def.tag !== "lazy")) {
|
|
14330
14581
|
const id = `rule:${rule2}`;
|
|
14331
14582
|
definitions.set(id, { id, kind: "rule" });
|
|
14332
|
-
|
|
14583
|
+
rules.set(parser2, id);
|
|
14333
14584
|
}
|
|
14334
14585
|
if (parser2._def.tag === "choice") {
|
|
14335
14586
|
const ids = parser2._def.parsers.map((_, index) => `choice:${path}/arm:${index}`);
|
|
@@ -14353,7 +14604,7 @@ function buildGrammarPlan(entry, winners) {
|
|
|
14353
14604
|
for (const root of roots) {
|
|
14354
14605
|
visit(root, winnerNames.get(root) ?? root._ruleName ?? "entry");
|
|
14355
14606
|
}
|
|
14356
|
-
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules
|
|
14607
|
+
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules };
|
|
14357
14608
|
}
|
|
14358
14609
|
|
|
14359
14610
|
// src/analysis/duplication.ts
|
|
@@ -17021,31 +17272,6 @@ function locatedLines(l, opts) {
|
|
|
17021
17272
|
return out;
|
|
17022
17273
|
}
|
|
17023
17274
|
|
|
17024
|
-
// src/compiler/linker.ts
|
|
17025
|
-
function normalizeCstCollapse(collapse) {
|
|
17026
|
-
if (collapse === true) return () => true;
|
|
17027
|
-
if (Array.isArray(collapse)) {
|
|
17028
|
-
const types = new Set(collapse);
|
|
17029
|
-
return (type) => types.has(type);
|
|
17030
|
-
}
|
|
17031
|
-
return typeof collapse === "function" ? collapse : void 0;
|
|
17032
|
-
}
|
|
17033
|
-
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
17034
|
-
return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children2] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
17035
|
-
}
|
|
17036
|
-
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
17037
|
-
if (typeof typeOrOptions === "string") {
|
|
17038
|
-
return buildCstNode(typeOrOptions, children2 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
17039
|
-
}
|
|
17040
|
-
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
17041
|
-
const materializeTags = typeOrOptions?.tags === true;
|
|
17042
|
-
const host = (type, children3, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children3 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
17043
|
-
host._parsemanCstOutput = true;
|
|
17044
|
-
if (collapse) host._parsemanCstCollapse = collapse;
|
|
17045
|
-
return host;
|
|
17046
|
-
}
|
|
17047
|
-
cstBuildHost._parsemanCstOutput = true;
|
|
17048
|
-
|
|
17049
17275
|
// src/analysis/diagnose.ts
|
|
17050
17276
|
function examinedNothing(d) {
|
|
17051
17277
|
return d.summary.totalChoices === 0 && d.summary.unanalysable > 0;
|