parseman 0.59.2 → 0.60.0
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/dist/analysis/commitment.d.ts +1 -1
- package/dist/analysis/diagnostics.js +877 -191
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +877 -191
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/completions.d.ts +3 -3
- package/dist/combinators/completions.d.ts.map +1 -1
- package/dist/combinators/dispatch.d.ts +13 -1
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/combinators/first-set.d.ts +35 -2
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/combinators/gate.d.ts +1 -1
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/trivia-boundary.d.ts +11 -0
- package/dist/combinators/trivia-boundary.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +1 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/compile-linkable-table.d.ts +2 -3
- package/dist/compiler/compile-linkable-table.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts +2 -0
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +65 -53
- package/dist/compiler/token-capability.js.map +2 -2
- package/dist/cst/host-mode.d.ts +1 -1
- package/dist/cst/root-trivia-scope.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +897 -200
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.d.ts +1 -1
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/entry-supercompiler.d.ts.map +1 -1
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.d.ts +3 -7
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +904 -202
- package/dist/plugin/index.js.map +3 -3
- package/dist/regex/first-set.d.ts +19 -0
- package/dist/regex/first-set.d.ts.map +1 -1
- package/dist/spec/index.js.map +1 -1
- package/dist/table/assemble.d.ts +16 -3
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/child-slots.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +3 -2
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/compile.d.ts +2 -2
- package/dist/table/emit-assembly.d.ts +8 -2
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts +8 -8
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts +6 -7
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/factor-choice.d.ts +27 -0
- package/dist/table/factor-choice.d.ts.map +1 -1
- package/dist/table/gap-gate.d.ts +11 -0
- package/dist/table/gap-gate.d.ts.map +1 -0
- package/dist/table/index.js +927 -202
- package/dist/table/index.js.map +3 -3
- package/dist/table/lex-program.d.ts.map +1 -1
- package/dist/table/ops.d.ts +48 -20
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +13 -8
- package/dist/table/program.d.ts.map +1 -1
- package/dist/types.d.ts +17 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +6 -6
- package/package.json +1 -1
- package/src/analysis/commitment.ts +1 -1
- package/src/analysis/duplication.ts +1 -1
- package/src/analysis/terminal.ts +1 -1
- package/src/combinators/attempt.ts +1 -1
- package/src/combinators/choice.ts +1 -1
- package/src/combinators/completions.ts +3 -3
- package/src/combinators/dispatch.ts +30 -6
- package/src/combinators/first-set.ts +55 -12
- package/src/combinators/gate.ts +1 -1
- package/src/combinators/node.ts +1 -1
- package/src/combinators/regex.ts +9 -4
- package/src/combinators/repeat.ts +6 -6
- package/src/combinators/sequence.ts +1 -1
- package/src/combinators/trivia-boundary.ts +18 -0
- package/src/combinators/trivia-skip.ts +1 -1
- package/src/compiler/compile-linkable-table.ts +2 -3
- package/src/compiler/degradation.ts +2 -2
- package/src/compiler/ir-serialize.ts +1 -1
- package/src/compiler/linker.ts +5 -3
- package/src/compiler/token-alphabet.ts +3 -1
- package/src/coverage.ts +1 -1
- package/src/cst/capture-buffer.ts +2 -2
- package/src/cst/host-mode.ts +1 -1
- package/src/cst/root-trivia-scope.ts +1 -1
- package/src/index.ts +1 -1
- package/src/language-service/index.ts +1 -1
- package/src/plugin/entry-supercompiler.ts +2 -1
- package/src/plugin/evaluator.ts +8 -3
- package/src/plugin/index.ts +11 -16
- package/src/regex/first-set.ts +37 -3
- package/src/table/assemble.ts +180 -35
- package/src/table/child-slots.ts +8 -3
- package/src/table/compile-rule-map.ts +10 -6
- package/src/table/compile.ts +3 -3
- package/src/table/emit-assembly.ts +186 -35
- package/src/table/emit.ts +19 -18
- package/src/table/encode.ts +482 -88
- package/src/table/exec.ts +42 -18
- package/src/table/factor-choice.ts +62 -0
- package/src/table/fail-clean.ts +2 -2
- package/src/table/gap-gate.ts +55 -0
- package/src/table/hold-gap.ts +2 -2
- package/src/table/lex-program.ts +15 -6
- package/src/table/ops.ts +51 -20
- package/src/table/program.ts +14 -9
- package/src/table/select-hot.ts +7 -2
- package/src/table/stamp.ts +1 -1
- package/src/types.ts +13 -6
- package/src/version.ts +6 -6
package/dist/table/index.js
CHANGED
|
@@ -27,15 +27,56 @@ function implicitLeadsDropped(ranges) {
|
|
|
27
27
|
return out;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// src/combinators/trivia-boundary.ts
|
|
31
|
+
var MAX_DEPTH = 12;
|
|
32
|
+
function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
33
|
+
if (depth === 0) return true;
|
|
34
|
+
const d = p._def;
|
|
35
|
+
switch (d.tag) {
|
|
36
|
+
// Multi-term forms: the gaps BETWEEN terms are the ambient-trivia positions.
|
|
37
|
+
case "sequence":
|
|
38
|
+
return d.parsers.length > 1;
|
|
39
|
+
case "many":
|
|
40
|
+
case "oneOrMore":
|
|
41
|
+
case "sepBy":
|
|
42
|
+
return true;
|
|
43
|
+
// Transparent wrappers — they add no position, so ask what they wrap.
|
|
44
|
+
case "node":
|
|
45
|
+
case "transform":
|
|
46
|
+
case "leaf":
|
|
47
|
+
case "label":
|
|
48
|
+
case "field":
|
|
49
|
+
case "token":
|
|
50
|
+
case "attempt":
|
|
51
|
+
case "optional":
|
|
52
|
+
case "expect":
|
|
53
|
+
case "withCtx":
|
|
54
|
+
case "recover":
|
|
55
|
+
case "trivia":
|
|
56
|
+
return hasOwnTriviaBoundary(d.parser, depth - 1);
|
|
57
|
+
// An alternation adds no position either, but ONE arm that has one is enough
|
|
58
|
+
// to make the scope meaningful for this rule.
|
|
59
|
+
case "choice":
|
|
60
|
+
return d.parsers.some((a) => hasOwnTriviaBoundary(a, depth - 1));
|
|
61
|
+
default:
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function triviaThroughRef(ref2, target, trivia2) {
|
|
66
|
+
if (trivia2 !== void 0 && trivia2 !== null) return trivia2;
|
|
67
|
+
const amb = ref2._meta.grammarTrivia ?? target._meta.grammarTrivia;
|
|
68
|
+
return amb !== void 0 && hasOwnTriviaBoundary(target) ? amb : trivia2;
|
|
69
|
+
}
|
|
70
|
+
|
|
30
71
|
// src/combinators/first-set.ts
|
|
31
|
-
function classifyFinalChoice(arms, resolve, activeTrivia) {
|
|
72
|
+
function classifyFinalChoice(arms, resolve, activeTrivia, consuming = true, constructionSets = false) {
|
|
32
73
|
const firstSets = [];
|
|
33
74
|
const nullable2 = [];
|
|
34
75
|
let exclusive = true;
|
|
35
76
|
for (const arm of arms) {
|
|
36
77
|
const empty2 = matchesEmpty(arm, /* @__PURE__ */ new Set(), resolve);
|
|
37
78
|
nullable2.push(empty2);
|
|
38
|
-
firstSets.push(empty2 ? { kind: "any" } : firstSetOf(arm, /* @__PURE__ */ new Set(), resolve, activeTrivia));
|
|
79
|
+
firstSets.push(empty2 ? { kind: "any" } : constructionSets ? arm._meta.firstSet : firstSetOf(arm, /* @__PURE__ */ new Set(), resolve, activeTrivia, consuming));
|
|
39
80
|
if (empty2) exclusive = false;
|
|
40
81
|
}
|
|
41
82
|
if (exclusive) {
|
|
@@ -220,7 +261,7 @@ function narrowBy(acc, constraint) {
|
|
|
220
261
|
function applyAssertion(fs, assertion) {
|
|
221
262
|
return assertion === null ? fs : fs.kind === "empty" ? assertion : narrowBy(fs, assertion);
|
|
222
263
|
}
|
|
223
|
-
function sequenceSet(parsers, fs, empties, trivia2) {
|
|
264
|
+
function sequenceSet(parsers, fs, empties, trivia2, consuming = true) {
|
|
224
265
|
const afterBoundary = (i) => {
|
|
225
266
|
const rest = at(i);
|
|
226
267
|
return trivia2 ? union(rest, fs(trivia2)) : rest;
|
|
@@ -236,24 +277,24 @@ function sequenceSet(parsers, fs, empties, trivia2) {
|
|
|
236
277
|
}
|
|
237
278
|
const first = fs(p);
|
|
238
279
|
if (!empties(p) || i + 1 === parsers.length) return first;
|
|
239
|
-
return union(first, afterBoundary(i + 1));
|
|
280
|
+
return union((consuming ? p._meta.consumingFirstSet : void 0) ?? first, afterBoundary(i + 1));
|
|
240
281
|
};
|
|
241
282
|
return at(0);
|
|
242
283
|
}
|
|
243
284
|
function sequenceFirstSet(parsers) {
|
|
244
|
-
return sequenceSet(parsers, (p) => p._meta.firstSet, matchesEmpty);
|
|
285
|
+
return sequenceSet(parsers, (p) => p._meta.firstSet, matchesEmpty, void 0, false);
|
|
245
286
|
}
|
|
246
|
-
function firstSetOf(p, seen = /* @__PURE__ */ new Set(), resolve, activeTrivia) {
|
|
287
|
+
function firstSetOf(p, seen = /* @__PURE__ */ new Set(), resolve, activeTrivia, consuming = true) {
|
|
247
288
|
if (seen.has(p)) return any();
|
|
248
289
|
seen.add(p);
|
|
249
290
|
try {
|
|
250
|
-
return firstSetBody(p, seen, resolve, activeTrivia);
|
|
291
|
+
return firstSetBody(p, seen, resolve, activeTrivia, consuming);
|
|
251
292
|
} finally {
|
|
252
293
|
seen.delete(p);
|
|
253
294
|
}
|
|
254
295
|
}
|
|
255
|
-
function firstSetBody(p, seen, resolve, activeTrivia) {
|
|
256
|
-
const fs = (c) => firstSetOf(c, seen, resolve, activeTrivia);
|
|
296
|
+
function firstSetBody(p, seen, resolve, activeTrivia, consuming) {
|
|
297
|
+
const fs = (c) => firstSetOf(c, seen, resolve, activeTrivia, consuming);
|
|
257
298
|
const empties = (c) => matchesEmpty(c, /* @__PURE__ */ new Set(), resolve);
|
|
258
299
|
const d = p._def;
|
|
259
300
|
switch (d.tag) {
|
|
@@ -265,13 +306,16 @@ function firstSetBody(p, seen, resolve, activeTrivia) {
|
|
|
265
306
|
case "dispatch":
|
|
266
307
|
return fs(d.selector);
|
|
267
308
|
case "lazy": {
|
|
268
|
-
|
|
269
|
-
if (
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
309
|
+
let target = winnerForRef(p, resolve);
|
|
310
|
+
if (target === void 0) {
|
|
311
|
+
try {
|
|
312
|
+
target = d.thunk();
|
|
313
|
+
} catch {
|
|
314
|
+
return any();
|
|
315
|
+
}
|
|
274
316
|
}
|
|
317
|
+
const through = activeTrivia === null && resolve !== void 0;
|
|
318
|
+
return firstSetOf(target, seen, resolve, through ? triviaThroughRef(p, target, null) : activeTrivia, consuming);
|
|
275
319
|
}
|
|
276
320
|
case "choice": {
|
|
277
321
|
let out = empty();
|
|
@@ -279,7 +323,7 @@ function firstSetBody(p, seen, resolve, activeTrivia) {
|
|
|
279
323
|
return out;
|
|
280
324
|
}
|
|
281
325
|
case "sequence": {
|
|
282
|
-
return sequenceSet(d.parsers, fs, empties, activeTrivia);
|
|
326
|
+
return sequenceSet(d.parsers, fs, empties, activeTrivia, consuming);
|
|
283
327
|
}
|
|
284
328
|
case "peek": {
|
|
285
329
|
const inner = d.parser;
|
|
@@ -291,7 +335,6 @@ function firstSetBody(p, seen, resolve, activeTrivia) {
|
|
|
291
335
|
case "transform":
|
|
292
336
|
case "label":
|
|
293
337
|
case "trivia":
|
|
294
|
-
case "token":
|
|
295
338
|
case "leaf":
|
|
296
339
|
case "node":
|
|
297
340
|
case "sepBy":
|
|
@@ -301,12 +344,16 @@ function firstSetBody(p, seen, resolve, activeTrivia) {
|
|
|
301
344
|
// with a rule reference — resolve through it like any other wrapper.
|
|
302
345
|
case "attempt":
|
|
303
346
|
return fs(d.parser);
|
|
347
|
+
// A token runs its body with trivia cleared (`token.ts`).
|
|
348
|
+
case "token":
|
|
349
|
+
return firstSetOf(d.parser, seen, resolve, activeTrivia === void 0 ? void 0 : null, consuming);
|
|
304
350
|
case "grammar":
|
|
305
351
|
return firstSetOf(
|
|
306
352
|
d.parser,
|
|
307
353
|
seen,
|
|
308
354
|
resolve,
|
|
309
|
-
d.clearTrivia ? null : d.triviaParser ?? activeTrivia
|
|
355
|
+
d.clearTrivia ? null : d.triviaParser ?? activeTrivia,
|
|
356
|
+
consuming
|
|
310
357
|
);
|
|
311
358
|
// A run starts with its first line's prefix; a nullable prefix starts with anything.
|
|
312
359
|
case "lines": {
|
|
@@ -2018,10 +2065,6 @@ function scanTriviaCompact(input, cur, ctx) {
|
|
|
2018
2065
|
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
2019
2066
|
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
2020
2067
|
}
|
|
2021
|
-
function scanTrivia(input, cur, ctx) {
|
|
2022
|
-
const scan = scanTriviaCompact(input, cur, ctx);
|
|
2023
|
-
return typeof scan === "number" ? { end: scan, commit: NOOP_COMMIT } : scan;
|
|
2024
|
-
}
|
|
2025
2068
|
function skipTriviaScanned(s, input, cur, ctx) {
|
|
2026
2069
|
const end = s(input, cur);
|
|
2027
2070
|
if (end !== cur) {
|
|
@@ -2837,9 +2880,9 @@ function many(combinator, opts = {}) {
|
|
|
2837
2880
|
canMatchNewline: combinator._meta.canMatchNewline,
|
|
2838
2881
|
isTrivia: false
|
|
2839
2882
|
};
|
|
2840
|
-
const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max } };
|
|
2841
|
-
let expected;
|
|
2842
2883
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
2884
|
+
const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max }, ...guardable ? { guarded: true } : {} };
|
|
2885
|
+
let expected;
|
|
2843
2886
|
const scalarChild = scalarOf(combinator);
|
|
2844
2887
|
const parseScalar = (input, pos, ctx) => repeatScalarTail(combinator, scalarChild, input, pos, ctx, guardable, def.valueUnused ? void 0 : [], max);
|
|
2845
2888
|
return {
|
|
@@ -2886,9 +2929,9 @@ function atLeast(combinator, min, max) {
|
|
|
2886
2929
|
canMatchNewline: combinator._meta.canMatchNewline,
|
|
2887
2930
|
isTrivia: false
|
|
2888
2931
|
};
|
|
2889
|
-
const def = { tag: "oneOrMore", parser: combinator, min, ...max === Infinity ? {} : { max } };
|
|
2890
|
-
let expected;
|
|
2891
2932
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
2933
|
+
const def = { tag: "oneOrMore", parser: combinator, min, ...max === Infinity ? {} : { max }, ...guardable ? { guarded: true } : {} };
|
|
2934
|
+
let expected;
|
|
2892
2935
|
const scalarChild = scalarOf(combinator);
|
|
2893
2936
|
const parseScalar = (input, pos, ctx) => {
|
|
2894
2937
|
let cur = scalarChild(input, pos, ctx);
|
|
@@ -2952,6 +2995,42 @@ function atLeast(combinator, min, max) {
|
|
|
2952
2995
|
}
|
|
2953
2996
|
};
|
|
2954
2997
|
}
|
|
2998
|
+
function optional(combinator) {
|
|
2999
|
+
const meta = {
|
|
3000
|
+
firstSet: combinator._meta.firstSet,
|
|
3001
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
3002
|
+
isTrivia: false
|
|
3003
|
+
};
|
|
3004
|
+
const firstSetSkippable = !matchesEmpty(combinator);
|
|
3005
|
+
const scalarChild = scalarOf(combinator);
|
|
3006
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3007
|
+
if (firstSetSkippable && !startsFirstSet(combinator, input, pos)) {
|
|
3008
|
+
ctx._sv = null;
|
|
3009
|
+
return pos;
|
|
3010
|
+
}
|
|
3011
|
+
const end = scalarChild(input, pos, ctx);
|
|
3012
|
+
if (end >= 0) return end;
|
|
3013
|
+
ctx._sv = null;
|
|
3014
|
+
return pos;
|
|
3015
|
+
};
|
|
3016
|
+
return {
|
|
3017
|
+
_tag: "optional",
|
|
3018
|
+
_meta: meta,
|
|
3019
|
+
_def: { tag: "optional", parser: combinator },
|
|
3020
|
+
_parseScalar: parseScalar,
|
|
3021
|
+
parse(input, pos, ctx) {
|
|
3022
|
+
if (firstSetSkippable && ctx._probe === void 0 && !startsFirstSet(combinator, input, pos)) {
|
|
3023
|
+
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
3024
|
+
}
|
|
3025
|
+
const mark = saveTriviaMark(ctx);
|
|
3026
|
+
const result = combinator.parse(input, pos, ctx);
|
|
3027
|
+
if (result.ok) return result;
|
|
3028
|
+
rollbackTrivia(ctx, mark);
|
|
3029
|
+
if (result.committed) return result;
|
|
3030
|
+
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
3031
|
+
}
|
|
3032
|
+
};
|
|
3033
|
+
}
|
|
2955
3034
|
|
|
2956
3035
|
// src/combinators/map.ts
|
|
2957
3036
|
var JSON_STRING_BODY = String.raw`(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*`;
|
|
@@ -3155,10 +3234,12 @@ function parseRegex(src, unicode = false, sets = false) {
|
|
|
3155
3234
|
const parseGroup = () => {
|
|
3156
3235
|
i++;
|
|
3157
3236
|
let lookaround = false;
|
|
3237
|
+
let lookahead = false;
|
|
3158
3238
|
if (src[i] === "?") {
|
|
3159
3239
|
const c1 = src[i + 1];
|
|
3160
3240
|
if (c1 === ":") i += 2;
|
|
3161
3241
|
else if (c1 === "=" || c1 === "!") {
|
|
3242
|
+
lookahead = c1 === "=";
|
|
3162
3243
|
i += 2;
|
|
3163
3244
|
lookaround = true;
|
|
3164
3245
|
} else if (c1 === "<") {
|
|
@@ -3176,7 +3257,8 @@ function parseRegex(src, unicode = false, sets = false) {
|
|
|
3176
3257
|
const inner = parseAlt();
|
|
3177
3258
|
if (src[i] !== ")") throw BAIL;
|
|
3178
3259
|
i++;
|
|
3179
|
-
|
|
3260
|
+
if (lookaround) return lookahead ? { t: "empty", look: inner } : EMPTY;
|
|
3261
|
+
return inner;
|
|
3180
3262
|
};
|
|
3181
3263
|
const parseClass = () => {
|
|
3182
3264
|
let k = i + 1;
|
|
@@ -3369,6 +3451,13 @@ function regexCanMatchEmpty(source) {
|
|
|
3369
3451
|
return true;
|
|
3370
3452
|
}
|
|
3371
3453
|
}
|
|
3454
|
+
function consumingFirstSetFromRegex(source, flags = "") {
|
|
3455
|
+
try {
|
|
3456
|
+
return firstSet(parseRegex(source, flags.includes("u") || flags.includes("v"), flags.includes("v")));
|
|
3457
|
+
} catch {
|
|
3458
|
+
return any();
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3372
3461
|
function firstSetFromRegex(source, flags = "") {
|
|
3373
3462
|
let ast;
|
|
3374
3463
|
try {
|
|
@@ -3379,6 +3468,20 @@ function firstSetFromRegex(source, flags = "") {
|
|
|
3379
3468
|
if (nullable(ast)) return { firstSet: any(), canMatchNewline: canConsumeNewline(ast) };
|
|
3380
3469
|
return { firstSet: firstSet(ast), canMatchNewline: canConsumeNewline(ast) };
|
|
3381
3470
|
}
|
|
3471
|
+
function regexFirstTwo(source, flags = "") {
|
|
3472
|
+
let ast;
|
|
3473
|
+
try {
|
|
3474
|
+
ast = parseRegex(source, flags.includes("u") || flags.includes("v"), flags.includes("v"));
|
|
3475
|
+
} catch {
|
|
3476
|
+
return void 0;
|
|
3477
|
+
}
|
|
3478
|
+
const parts = ast.t === "seq" ? ast.parts : [ast];
|
|
3479
|
+
const a = parts[0];
|
|
3480
|
+
const b = parts[1];
|
|
3481
|
+
if (a === void 0 || a.t !== "char" || a.set.kind !== "ranges" || b === void 0) return void 0;
|
|
3482
|
+
const second = b.t === "char" ? b.set : b.t === "empty" && b.look !== void 0 && !nullable(b.look) ? firstSet(b.look) : void 0;
|
|
3483
|
+
return second !== void 0 && second.kind === "ranges" ? { first: a.set, second } : void 0;
|
|
3484
|
+
}
|
|
3382
3485
|
|
|
3383
3486
|
// src/combinators/regex.ts
|
|
3384
3487
|
import { PlainLeaf as PlainLeaf2, PlainSpan as PlainSpan4 } from "../cst/plain.js";
|
|
@@ -3459,9 +3562,14 @@ function regex(pattern, flags = "") {
|
|
|
3459
3562
|
const anchored = new RegExp(source, "y" + resolvedFlags.replace(/[gy]/g, ""));
|
|
3460
3563
|
const scan = shortScanner(source, resolvedFlags);
|
|
3461
3564
|
const raw = firstSetFromRegex(source, resolvedFlags);
|
|
3462
|
-
const
|
|
3565
|
+
const forFlags = (fs) => !resolvedFlags.includes("i") ? fs : resolvedFlags.includes("u") || resolvedFlags.includes("v") ? any() : asciiCaseFold(fs);
|
|
3566
|
+
const firstSet2 = forFlags(raw.firstSet);
|
|
3463
3567
|
const canMatchNewline = raw.canMatchNewline;
|
|
3464
3568
|
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
3569
|
+
if (firstSet2.kind === "any" && regexCanMatchEmpty(source)) {
|
|
3570
|
+
const consuming = forFlags(consumingFirstSetFromRegex(source, resolvedFlags));
|
|
3571
|
+
if (consuming.kind !== "any") meta.consumingFirstSet = consuming;
|
|
3572
|
+
}
|
|
3465
3573
|
const def = { tag: "regex", source, flags: resolvedFlags };
|
|
3466
3574
|
const expected = directTerminalFailureExpected(def);
|
|
3467
3575
|
const parseScalar = (input, pos, ctx) => {
|
|
@@ -3736,14 +3844,15 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
3736
3844
|
return end < 0 ? next(input, pos) : end;
|
|
3737
3845
|
};
|
|
3738
3846
|
}
|
|
3739
|
-
let tail = (
|
|
3847
|
+
let tail = (input, pos, ctx, _lead, acc, _best, entered) => {
|
|
3848
|
+
if (!entered && ctx._probe !== void 0) for (const arm of arms) arm.run(input, pos, ctx);
|
|
3740
3849
|
ctx._fe = pos;
|
|
3741
3850
|
ctx._fx = acc ?? choiceExpected;
|
|
3742
3851
|
return -1;
|
|
3743
3852
|
};
|
|
3744
3853
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
3745
3854
|
const armRun = arms[i].run, cls = classes[i], staticExpected = armExpected[i], next = tail;
|
|
3746
|
-
tail = (input, pos, ctx, lead2, acc, best) => {
|
|
3855
|
+
tail = (input, pos, ctx, lead2, acc, best, entered) => {
|
|
3747
3856
|
if (cls !== void 0 && !classHas(cls, lead2)) {
|
|
3748
3857
|
return next(
|
|
3749
3858
|
input,
|
|
@@ -3751,7 +3860,8 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
3751
3860
|
ctx,
|
|
3752
3861
|
lead2,
|
|
3753
3862
|
best === pos ? appendExpected(acc, staticExpected) : acc,
|
|
3754
|
-
best
|
|
3863
|
+
best,
|
|
3864
|
+
entered
|
|
3755
3865
|
);
|
|
3756
3866
|
}
|
|
3757
3867
|
ctx._fc = false;
|
|
@@ -3767,7 +3877,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
3767
3877
|
if (nextAcc !== void 0) ctx._fx = nextAcc;
|
|
3768
3878
|
return -1;
|
|
3769
3879
|
}
|
|
3770
|
-
return next(input, pos, ctx, lead2, nextAcc, best);
|
|
3880
|
+
return next(input, pos, ctx, lead2, nextAcc, best, true);
|
|
3771
3881
|
};
|
|
3772
3882
|
}
|
|
3773
3883
|
return {
|
|
@@ -3778,7 +3888,8 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
3778
3888
|
ctx,
|
|
3779
3889
|
pos < input.length ? input.codePointAt(pos) : -1,
|
|
3780
3890
|
void 0,
|
|
3781
|
-
pos
|
|
3891
|
+
pos,
|
|
3892
|
+
false
|
|
3782
3893
|
)
|
|
3783
3894
|
};
|
|
3784
3895
|
}
|
|
@@ -3816,6 +3927,7 @@ function exclusiveChoiceNode(arms, classes, choiceFx) {
|
|
|
3816
3927
|
return -1;
|
|
3817
3928
|
}
|
|
3818
3929
|
}
|
|
3930
|
+
if (arm < 0 && ctx._probe !== void 0) for (const a of arms) a.run(input, pos, ctx);
|
|
3819
3931
|
ctx._fe = pos;
|
|
3820
3932
|
ctx._fx = choiceFx;
|
|
3821
3933
|
return -1;
|
|
@@ -3862,10 +3974,10 @@ function repeatNode(item, min, max) {
|
|
|
3862
3974
|
let count = 0;
|
|
3863
3975
|
for (; ; ) {
|
|
3864
3976
|
if (max >= 0 && count >= max) break;
|
|
3865
|
-
const
|
|
3866
|
-
if (
|
|
3977
|
+
const optional2 = count >= min && (count > 0 || min === 0);
|
|
3978
|
+
if (optional2 && cur >= input.length) break;
|
|
3867
3979
|
const end = itemMatch(input, cur);
|
|
3868
|
-
if (end < 0 ||
|
|
3980
|
+
if (end < 0 || optional2 && end === cur) break;
|
|
3869
3981
|
cur = end;
|
|
3870
3982
|
count++;
|
|
3871
3983
|
}
|
|
@@ -3876,15 +3988,15 @@ function repeatNode(item, min, max) {
|
|
|
3876
3988
|
let count = 0;
|
|
3877
3989
|
for (; ; ) {
|
|
3878
3990
|
if (max >= 0 && count >= max) break;
|
|
3879
|
-
const
|
|
3880
|
-
if (
|
|
3991
|
+
const optional2 = count >= min && (count > 0 || min === 0);
|
|
3992
|
+
if (optional2 && cur >= input.length) break;
|
|
3881
3993
|
ctx._fc = false;
|
|
3882
3994
|
const end = itemRun(input, cur, ctx);
|
|
3883
3995
|
if (end < 0) {
|
|
3884
3996
|
if (committed(ctx)) return -1;
|
|
3885
3997
|
break;
|
|
3886
3998
|
}
|
|
3887
|
-
if (
|
|
3999
|
+
if (optional2 && end === cur) break;
|
|
3888
4000
|
cur = end;
|
|
3889
4001
|
count++;
|
|
3890
4002
|
}
|
|
@@ -4040,6 +4152,7 @@ function buildLexProgramRunner(spec, matchers, classes, expected) {
|
|
|
4040
4152
|
if (!classHas(cls, lead2)) {
|
|
4041
4153
|
ctx._fe = pos;
|
|
4042
4154
|
ctx._fx = choiceFx.slice();
|
|
4155
|
+
if (ctx._probe !== void 0) failAt(ctx, [...x0, ...x1, ...x2, ...x3], pos);
|
|
4043
4156
|
return -1;
|
|
4044
4157
|
}
|
|
4045
4158
|
let acc;
|
|
@@ -4151,7 +4264,7 @@ function validateDispatchSpec(spec, arity, fallbackRouted) {
|
|
|
4151
4264
|
for (const arm of arms) if (!Number.isInteger(arm) || arm < 0 || arm >= arity) return true;
|
|
4152
4265
|
return false;
|
|
4153
4266
|
};
|
|
4154
|
-
if (spec === void 0 || !Number.isInteger(arity) || arity < 0 || fallbackRouted
|
|
4267
|
+
if (spec === void 0 || !Number.isInteger(arity) || arity < 0 || !Number.isInteger(fallbackRouted) || fallbackRouted < 0 || fallbackRouted > 3 || spec.routed.length !== arity || spec.routed.some((value) => value !== 0 && value !== 1) || invalid(spec.byKey.values()) || invalid(spec.byFold.values()) || spec.match.some((matcher) => invalid([matcher[3]]))) {
|
|
4155
4268
|
throw new TypeError("table: malformed dispatch");
|
|
4156
4269
|
}
|
|
4157
4270
|
}
|
|
@@ -4636,7 +4749,7 @@ function sequence(...parsers) {
|
|
|
4636
4749
|
if (tolerant) {
|
|
4637
4750
|
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
4638
4751
|
parsers.slice(i + 1).reduce(
|
|
4639
|
-
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
4752
|
+
(set, parser2) => union(set, firstSetOf(parser2, /* @__PURE__ */ new Set(), void 0, void 0, false)),
|
|
4640
4753
|
{ kind: "empty" }
|
|
4641
4754
|
)
|
|
4642
4755
|
));
|
|
@@ -4694,42 +4807,6 @@ function sequence(...parsers) {
|
|
|
4694
4807
|
};
|
|
4695
4808
|
}
|
|
4696
4809
|
|
|
4697
|
-
// src/combinators/trivia-boundary.ts
|
|
4698
|
-
var MAX_DEPTH = 12;
|
|
4699
|
-
function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
4700
|
-
if (depth === 0) return true;
|
|
4701
|
-
const d = p._def;
|
|
4702
|
-
switch (d.tag) {
|
|
4703
|
-
// Multi-term forms: the gaps BETWEEN terms are the ambient-trivia positions.
|
|
4704
|
-
case "sequence":
|
|
4705
|
-
return d.parsers.length > 1;
|
|
4706
|
-
case "many":
|
|
4707
|
-
case "oneOrMore":
|
|
4708
|
-
case "sepBy":
|
|
4709
|
-
return true;
|
|
4710
|
-
// Transparent wrappers — they add no position, so ask what they wrap.
|
|
4711
|
-
case "node":
|
|
4712
|
-
case "transform":
|
|
4713
|
-
case "leaf":
|
|
4714
|
-
case "label":
|
|
4715
|
-
case "field":
|
|
4716
|
-
case "token":
|
|
4717
|
-
case "attempt":
|
|
4718
|
-
case "optional":
|
|
4719
|
-
case "expect":
|
|
4720
|
-
case "withCtx":
|
|
4721
|
-
case "recover":
|
|
4722
|
-
case "trivia":
|
|
4723
|
-
return hasOwnTriviaBoundary(d.parser, depth - 1);
|
|
4724
|
-
// An alternation adds no position either, but ONE arm that has one is enough
|
|
4725
|
-
// to make the scope meaningful for this rule.
|
|
4726
|
-
case "choice":
|
|
4727
|
-
return d.parsers.some((a) => hasOwnTriviaBoundary(a, depth - 1));
|
|
4728
|
-
default:
|
|
4729
|
-
return false;
|
|
4730
|
-
}
|
|
4731
|
-
}
|
|
4732
|
-
|
|
4733
4810
|
// src/combinators/ref.ts
|
|
4734
4811
|
function withRuleTrivia(trivia2, ctx, run) {
|
|
4735
4812
|
const savedLabels = ctx.triviaKindLabels;
|
|
@@ -5650,6 +5727,9 @@ function projectChild(children2, project, type) {
|
|
|
5650
5727
|
return unwrapChild(children2[project]);
|
|
5651
5728
|
}
|
|
5652
5729
|
|
|
5730
|
+
// src/version.ts
|
|
5731
|
+
var PARSEMAN_VERSION = "0.60.0";
|
|
5732
|
+
|
|
5653
5733
|
// src/table/assemble.ts
|
|
5654
5734
|
import { PlainBuf as PlainBuf2, PlainField, PlainLeaf as PlainLeaf8, PlainNode as PlainNode2, PlainSpan as PlainSpan9 } from "../cst/plain.js";
|
|
5655
5735
|
|
|
@@ -5697,6 +5777,9 @@ var OP_LEX_BODY = 42;
|
|
|
5697
5777
|
var OP_LEX_PROGRAM = 43;
|
|
5698
5778
|
var OP_SOURCE_LEAF = 44;
|
|
5699
5779
|
var OP_RGATE = 45;
|
|
5780
|
+
var OP_GAPGATE = 46;
|
|
5781
|
+
var OP_RGATE2 = 47;
|
|
5782
|
+
var OP_STRICT = 48;
|
|
5700
5783
|
var OP_DISPATCH = 25;
|
|
5701
5784
|
var OP_ROUTED = 26;
|
|
5702
5785
|
var OP_NAMES = {
|
|
@@ -5744,7 +5827,10 @@ var OP_NAMES = {
|
|
|
5744
5827
|
[OP_COV]: "COV",
|
|
5745
5828
|
[OP_SCOPE_PLAIN]: "SCOPE_PLAIN",
|
|
5746
5829
|
[OP_LEX_BODY]: "LEX_BODY",
|
|
5747
|
-
[OP_LEX_PROGRAM]: "LEX_PROGRAM"
|
|
5830
|
+
[OP_LEX_PROGRAM]: "LEX_PROGRAM",
|
|
5831
|
+
[OP_GAPGATE]: "GAPGATE",
|
|
5832
|
+
[OP_RGATE2]: "RGATE2",
|
|
5833
|
+
[OP_STRICT]: "STRICT"
|
|
5748
5834
|
};
|
|
5749
5835
|
|
|
5750
5836
|
// src/table/scan-shapes.ts
|
|
@@ -6791,6 +6877,7 @@ function childSlots(code, ip, out) {
|
|
|
6791
6877
|
case OP_LABEL:
|
|
6792
6878
|
case OP_COV:
|
|
6793
6879
|
case OP_REJECT:
|
|
6880
|
+
case OP_GAPGATE:
|
|
6794
6881
|
out.push(code[ip + 1]);
|
|
6795
6882
|
return true;
|
|
6796
6883
|
// Single child at `ip + 2`.
|
|
@@ -6807,8 +6894,13 @@ function childSlots(code, ip, out) {
|
|
|
6807
6894
|
case OP_SOURCE_LEAF:
|
|
6808
6895
|
case OP_ARMGATE:
|
|
6809
6896
|
case OP_RGATE:
|
|
6897
|
+
case OP_RGATE2:
|
|
6810
6898
|
out.push(code[ip + 2]);
|
|
6811
6899
|
return true;
|
|
6900
|
+
// `STRICT strict tolerant` — both encodings are reachable; an assembly keeps one.
|
|
6901
|
+
case OP_STRICT:
|
|
6902
|
+
out.push(code[ip + 1], code[ip + 2]);
|
|
6903
|
+
return true;
|
|
6812
6904
|
// `ROUTED fallback` — the operand is an offset or −1. The routed token itself is
|
|
6813
6905
|
// data the enclosing `dispatch()` already consumed, so the only edge is the
|
|
6814
6906
|
// fallback.
|
|
@@ -7256,7 +7348,8 @@ var WRAPPERS = /* @__PURE__ */ new Set([
|
|
|
7256
7348
|
OP_WITHCTX,
|
|
7257
7349
|
OP_RULE,
|
|
7258
7350
|
OP_ATTEMPT,
|
|
7259
|
-
OP_COV
|
|
7351
|
+
OP_COV,
|
|
7352
|
+
OP_GAPGATE
|
|
7260
7353
|
]);
|
|
7261
7354
|
function rowNullable(code, k, ip, memo) {
|
|
7262
7355
|
const hit = memo.get(ip);
|
|
@@ -7293,7 +7386,31 @@ function holdsGap(code, k, base, n, i, memo) {
|
|
|
7293
7386
|
return !rowNullable(code, k, next, memo);
|
|
7294
7387
|
}
|
|
7295
7388
|
|
|
7389
|
+
// src/table/gap-gate.ts
|
|
7390
|
+
function newGapSlot() {
|
|
7391
|
+
return { row: -1, at: -1, end: -1, input: void 0 };
|
|
7392
|
+
}
|
|
7393
|
+
function gapRows(code, roots) {
|
|
7394
|
+
const rows = /* @__PURE__ */ new Set();
|
|
7395
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7396
|
+
const stack = [...roots];
|
|
7397
|
+
const kids = [];
|
|
7398
|
+
while (stack.length > 0) {
|
|
7399
|
+
const ip = stack.pop();
|
|
7400
|
+
if (seen.has(ip)) continue;
|
|
7401
|
+
seen.add(ip);
|
|
7402
|
+
if (code[ip] === OP_GAPGATE) rows.add(code[ip + 2]);
|
|
7403
|
+
kids.length = 0;
|
|
7404
|
+
childSlots(code, ip, kids);
|
|
7405
|
+
for (const c of kids) stack.push(c);
|
|
7406
|
+
}
|
|
7407
|
+
return rows;
|
|
7408
|
+
}
|
|
7409
|
+
|
|
7296
7410
|
// src/table/emit-assembly.ts
|
|
7411
|
+
function gapRegexLowers(re) {
|
|
7412
|
+
return re instanceof RegExp && scanShapeFromRegex(re.source, re.flags) !== null;
|
|
7413
|
+
}
|
|
7297
7414
|
var Unemittable = class extends Error {
|
|
7298
7415
|
construct;
|
|
7299
7416
|
constructor(construct) {
|
|
@@ -7312,7 +7429,6 @@ var EMITTED_PARAMS = [
|
|
|
7312
7429
|
"CLS",
|
|
7313
7430
|
"AFX",
|
|
7314
7431
|
"TRIVIA",
|
|
7315
|
-
"TRIVIALABELS",
|
|
7316
7432
|
"TRIVIASCAN",
|
|
7317
7433
|
"SCANS",
|
|
7318
7434
|
"DISP",
|
|
@@ -7336,7 +7452,6 @@ var EMITTED_PARAMS = [
|
|
|
7336
7452
|
"cstLeavesLen",
|
|
7337
7453
|
"skipTriviaScanned",
|
|
7338
7454
|
"needsDeferredTriviaCommit",
|
|
7339
|
-
"scanTrivia",
|
|
7340
7455
|
"advanceTrivia",
|
|
7341
7456
|
"refuseUnclassifiedRootScope",
|
|
7342
7457
|
"spanLines",
|
|
@@ -7356,34 +7471,31 @@ var EMITTED_PARAMS = [
|
|
|
7356
7471
|
"orSentinel",
|
|
7357
7472
|
"captureError",
|
|
7358
7473
|
// Pure scalar terminal recognizers, indexed by the terminal's existing const
|
|
7359
|
-
// operand
|
|
7474
|
+
// operand; selected lexical bodies; the adjacency test.
|
|
7360
7475
|
"RECOG",
|
|
7361
|
-
// Appended so precompiled factories produced by earlier runtimes keep every
|
|
7362
|
-
// positional helper binding. Older factories ignore this trailing argument.
|
|
7363
|
-
"commitTriviaScan",
|
|
7364
|
-
"scanTriviaCompact",
|
|
7365
7476
|
"LEX",
|
|
7366
|
-
// Appended for old precompiled-factory ABI: old factories ignore it.
|
|
7367
7477
|
"adjacencyHolds",
|
|
7368
|
-
//
|
|
7478
|
+
// Selected composite lexical programs.
|
|
7369
7479
|
"LEXPROG",
|
|
7370
|
-
//
|
|
7371
|
-
// old factories ignore them.
|
|
7480
|
+
// Trivia-attributing fields (`field(…, { leadingTrivia })`).
|
|
7372
7481
|
"LEAD",
|
|
7373
7482
|
"triviaFieldCapture",
|
|
7374
|
-
//
|
|
7375
|
-
// factories ignore it.
|
|
7483
|
+
// The deferred-commit trivia skip (`trivia-gap.ts`).
|
|
7376
7484
|
"skipDeferredTrivia",
|
|
7377
|
-
//
|
|
7378
|
-
// ignore it.
|
|
7485
|
+
// The pass-through collapse (`run-support.ts`).
|
|
7379
7486
|
"collapseEmpty",
|
|
7380
|
-
//
|
|
7381
|
-
//
|
|
7487
|
+
// Constructor-built tree objects (`cst/plain.d.ts`): a `new` call has no
|
|
7488
|
+
// allocation site, so V8 cannot pretenure them.
|
|
7382
7489
|
"_SP",
|
|
7383
7490
|
"_LF",
|
|
7384
7491
|
"_ND",
|
|
7385
7492
|
"_FC",
|
|
7386
|
-
"_BUF"
|
|
7493
|
+
"_BUF",
|
|
7494
|
+
// The gap gate's slot (`gap-gate.ts`).
|
|
7495
|
+
"GAP"
|
|
7496
|
+
// Artifacts are version-locked (docs/design/artifact-format.md): a factory is
|
|
7497
|
+
// only ever called by the runtime that emitted it, so a name nothing emitted
|
|
7498
|
+
// reads is removed rather than kept for an older factory's positions.
|
|
7387
7499
|
];
|
|
7388
7500
|
var RUNTIME_PRELUDE = `
|
|
7389
7501
|
let _pfScan=null
|
|
@@ -7634,7 +7746,7 @@ function rebuildPools(cc, fx, disp, plan) {
|
|
|
7634
7746
|
})
|
|
7635
7747
|
};
|
|
7636
7748
|
}
|
|
7637
|
-
function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, select, scanSinkNeutral = false) {
|
|
7749
|
+
function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, select, scanSinkNeutral = false, gapNeutral = false) {
|
|
7638
7750
|
const { code, k, fx, disp, dsp, triviaLabelled } = t;
|
|
7639
7751
|
const swapLegal = !cfg.trackLines;
|
|
7640
7752
|
const hostCst = cfg.hostCst;
|
|
@@ -7642,6 +7754,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, se
|
|
|
7642
7754
|
if (cfg.coverage) throw new Unemittable("a coverage assembly");
|
|
7643
7755
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
7644
7756
|
const reachable = [...reachableSites(code, roots)];
|
|
7757
|
+
const GAP_ROWS = gapNeutral ? /* @__PURE__ */ new Set() : new Set([...gapRows(code, roots)].filter((row) => !gapRegexLowers(k[code[row + 1]])));
|
|
7645
7758
|
const labels = computeSiteLabels(code, roots, hostCst);
|
|
7646
7759
|
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
7647
7760
|
const nullable2 = /* @__PURE__ */ new Map();
|
|
@@ -7979,13 +8092,15 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
7979
8092
|
function aliasOf(ip) {
|
|
7980
8093
|
const op = code[ip];
|
|
7981
8094
|
if (op === OP_GATE && (cfg.tolerant || cfg.probe)) return code[ip + 2];
|
|
7982
|
-
if (op === OP_RULE) return code[ip + 1];
|
|
8095
|
+
if (op === OP_RULE || op === OP_GAPGATE) return code[ip + 1];
|
|
8096
|
+
if (op === OP_STRICT) return code[cfg.tolerant || cfg.probe ? ip + 2 : ip + 1];
|
|
7983
8097
|
if (scopeIsIdentity(code, ip, labels.at(ip))) return code[ip + 2];
|
|
7984
8098
|
return void 0;
|
|
7985
8099
|
}
|
|
7986
8100
|
function lower(ip, fname) {
|
|
7987
8101
|
const op = code[ip];
|
|
7988
8102
|
const head = `function ${fname}(input,pos,ctx){`;
|
|
8103
|
+
const outerHead = head;
|
|
7989
8104
|
const L = labels.at(ip);
|
|
7990
8105
|
const sinks = sinksAt(ip);
|
|
7991
8106
|
const pushLeaf = L.buf && !cfg.trackLines ? L.raw === RAW_OMIT ? "_pushLeafNoRawBuf" : L.raw === RAW_CAPTURE ? "_pushLeafBuf" : "_pushLeaf" : "_pushLeaf";
|
|
@@ -8061,9 +8176,27 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
8061
8176
|
case OP_RX_TRACK: {
|
|
8062
8177
|
const xf = fxRef(code[ip + 2]);
|
|
8063
8178
|
const track = op === OP_RX_TRACK;
|
|
8179
|
+
if (GAP_ROWS.has(ip)) {
|
|
8180
|
+
const re2 = hoist("gx", `K[${code[ip + 1]}]`);
|
|
8181
|
+
return `${outerHead}
|
|
8182
|
+
let e
|
|
8183
|
+
if(GAP.row===${ip}&&GAP.at===pos&&GAP.input===input)e=GAP.end
|
|
8184
|
+
else{${re2}.lastIndex=pos;e=${re2}.test(input)?${re2}.lastIndex:-1}
|
|
8185
|
+
if(e>=0){
|
|
8186
|
+
const v=input.slice(pos,e)
|
|
8187
|
+
${captureLeaf("v")}
|
|
8188
|
+
${track ? "_trackLines(ctx,input,e)\n" : ""}EC.e=e
|
|
8189
|
+
return v
|
|
8190
|
+
}
|
|
8191
|
+
ctx._fe=pos;ctx._fx=${xf}
|
|
8192
|
+
${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
8193
|
+
` : ""}return FAIL
|
|
8194
|
+
}`;
|
|
8195
|
+
}
|
|
8196
|
+
const head2 = outerHead;
|
|
8064
8197
|
if (!track && scalarSpecs.has(code[ip + 1])) {
|
|
8065
8198
|
const recognize = recognizerRef(code[ip + 1]);
|
|
8066
|
-
return `${
|
|
8199
|
+
return `${head2}
|
|
8067
8200
|
const e=${recognize}(input,pos)
|
|
8068
8201
|
if(e>=0){
|
|
8069
8202
|
const v=input.slice(pos,e)
|
|
@@ -8076,11 +8209,11 @@ return FAIL
|
|
|
8076
8209
|
}`;
|
|
8077
8210
|
}
|
|
8078
8211
|
const scanned = emitScan(code[ip + 1], xf, track, captureLeaf);
|
|
8079
|
-
if (scanned !== void 0) return `${
|
|
8212
|
+
if (scanned !== void 0) return `${head2}${scanned}}`;
|
|
8080
8213
|
const rxk = k[code[ip + 1]];
|
|
8081
8214
|
if (!(rxk instanceof RegExp) || !rxk.sticky) throw new Unemittable("a non-sticky regex row");
|
|
8082
8215
|
const re = kRef(code[ip + 1]);
|
|
8083
|
-
return `${
|
|
8216
|
+
return `${head2}
|
|
8084
8217
|
${re}.lastIndex=pos
|
|
8085
8218
|
if(${re}.test(input)){
|
|
8086
8219
|
const e=${re}.lastIndex
|
|
@@ -8118,6 +8251,28 @@ return ${child}(input,pos,ctx)
|
|
|
8118
8251
|
const it=ctx._routed
|
|
8119
8252
|
if(it!==undefined&&it.span.start===pos&&!classHas(${cls},lead(input,it.span.end))){ctx._fe=it.span.end;ctx._fx=${xf};return FAIL}
|
|
8120
8253
|
return ${child}(input,pos,ctx)
|
|
8254
|
+
}`;
|
|
8255
|
+
}
|
|
8256
|
+
case OP_RGATE2: {
|
|
8257
|
+
const child = link(code[ip + 2]);
|
|
8258
|
+
if (cfg.tolerant || cfg.probe) return `${head}
|
|
8259
|
+
return ${child}(input,pos,ctx)
|
|
8260
|
+
}`;
|
|
8261
|
+
const idxs = [code[ip + 1], code[ip + 4], code[ip + 5]];
|
|
8262
|
+
const ascii = idxs.every((i) => isAsciiOnlyClass(t.cc[i]));
|
|
8263
|
+
const ref2 = (idx, tag) => {
|
|
8264
|
+
const ci = classes.push([t.cc[idx]]) - 1;
|
|
8265
|
+
classPlan.push([idx]);
|
|
8266
|
+
return hoist(tag, `CLS[${ci}][0]`);
|
|
8267
|
+
};
|
|
8268
|
+
const [cls, first, second] = [ref2(idxs[0], "cl"), ref2(idxs[1], "c1"), ref2(idxs[2], "c2")];
|
|
8269
|
+
const has = (c, at) => ascii ? `${c}.ascii[${at}]===1` : `classHas(${c},${at})`;
|
|
8270
|
+
const xf = fxRef(code[ip + 3]);
|
|
8271
|
+
return `${head}
|
|
8272
|
+
const it=ctx._routed
|
|
8273
|
+
if(it!==undefined&&it.span.start===pos){const e=it.span.end;const c=${ascii ? "input.charCodeAt(e)" : "lead(input,e)"}
|
|
8274
|
+
if(!(${has(cls, "c")})||(${has(first, "c")}&&!(${has(second, ascii ? "input.charCodeAt(e+1)" : "lead(input,e+1)")}))){ctx._fe=e;ctx._fx=${xf};return FAIL}}
|
|
8275
|
+
return ${child}(input,pos,ctx)
|
|
8121
8276
|
}`;
|
|
8122
8277
|
}
|
|
8123
8278
|
case OP_ARMGATE: {
|
|
@@ -8527,7 +8682,27 @@ if(ctx._fc===true)return FAIL
|
|
|
8527
8682
|
const af=ctx._fx
|
|
8528
8683
|
if(af!==undefined&&af.length>0){ctx._fe=pos;return FAIL}
|
|
8529
8684
|
}
|
|
8530
|
-
|
|
8685
|
+
${cfg.probe ? `if(arm<0){${arms.map((a) => `${a}(input,pos,ctx)`).join(";")}}
|
|
8686
|
+
` : ""}ctx._fe=pos;ctx._fx=${choiceFx}
|
|
8687
|
+
return FAIL
|
|
8688
|
+
}`;
|
|
8689
|
+
}
|
|
8690
|
+
if (cfg.probe) {
|
|
8691
|
+
const p = tmp();
|
|
8692
|
+
return `${head}
|
|
8693
|
+
${emitMark(p, L.buf, L.raw, sinks)}
|
|
8694
|
+
let acc
|
|
8695
|
+
let best=pos
|
|
8696
|
+
${arms.map((arm) => `{ctx._fc=false
|
|
8697
|
+
const v=${arm}(input,pos,ctx)
|
|
8698
|
+
if(v!==FAIL)return v
|
|
8699
|
+
const at=ctx._fe??pos
|
|
8700
|
+
if(at>best){best=at;acc=undefined}
|
|
8701
|
+
if(at===best)acc=_accSet(ctx._fx,acc)
|
|
8702
|
+
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
8703
|
+
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
8704
|
+
}`).join("\n")}
|
|
8705
|
+
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
8531
8706
|
return FAIL
|
|
8532
8707
|
}`;
|
|
8533
8708
|
}
|
|
@@ -8734,7 +8909,8 @@ return FAIL
|
|
|
8734
8909
|
const selector = link(code[ip + 1]);
|
|
8735
8910
|
const otherIp = code[ip + 3];
|
|
8736
8911
|
const other = otherIp >= 0 ? link(otherIp) : void 0;
|
|
8737
|
-
const otherRouted = code[ip + 4] === 1;
|
|
8912
|
+
const otherRouted = (code[ip + 4] & 1) === 1;
|
|
8913
|
+
const otherCommits = (code[ip + 4] & 2) === 0;
|
|
8738
8914
|
const n = code[ip + 5];
|
|
8739
8915
|
validateDispatchSpec(spec, n, code[ip + 4]);
|
|
8740
8916
|
const armBase = ip + 6;
|
|
@@ -8788,7 +8964,7 @@ ${fallbackCase}
|
|
|
8788
8964
|
}
|
|
8789
8965
|
if(v===FAIL){
|
|
8790
8966
|
${emitRollback(m2, L.buf, L.raw, sinks)}
|
|
8791
|
-
ctx._fc=true
|
|
8967
|
+
${other !== void 0 && !otherCommits ? "if(arm!==undefined)" : ""}ctx._fc=true
|
|
8792
8968
|
return FAIL
|
|
8793
8969
|
}
|
|
8794
8970
|
return [key,v]
|
|
@@ -8820,6 +8996,63 @@ return [key,v]
|
|
|
8820
8996
|
}
|
|
8821
8997
|
}
|
|
8822
8998
|
const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
|
|
8999
|
+
let sepCls;
|
|
9000
|
+
let sepAscii = false;
|
|
9001
|
+
if (!REC && sepIp >= 0 && (code[ip + 5] & 8) !== 0 && !leadingTriviaFieldAt(code, k, sepIp) && !rowNullable(code, k, sepIp, nullable2)) {
|
|
9002
|
+
const resolved = t.cc[code[ip + 8]];
|
|
9003
|
+
const ci = classes.push([resolved]) - 1;
|
|
9004
|
+
classPlan.push([code[ip + 8]]);
|
|
9005
|
+
sepCls = hoist("rs", `CLS[${ci}][0]`);
|
|
9006
|
+
sepAscii = isAsciiOnlyClass(resolved);
|
|
9007
|
+
}
|
|
9008
|
+
const gapIp = !gapNeutral && sepIp < 0 && min === 0 && !REC && code[code[ip + 1]] === OP_GAPGATE ? code[ip + 1] : -1;
|
|
9009
|
+
let gapCode = (_rb) => "";
|
|
9010
|
+
if (gapIp >= 0) {
|
|
9011
|
+
const row = code[gapIp + 2];
|
|
9012
|
+
const rx = k[code[row + 1]];
|
|
9013
|
+
const shape = gapRegexLowers(rx) ? scanShapeFromRegex(rx.source, rx.flags) : null;
|
|
9014
|
+
const cls = (idx) => {
|
|
9015
|
+
const resolved = t.cc[idx];
|
|
9016
|
+
const ci = classes.push([resolved]) - 1;
|
|
9017
|
+
classPlan.push([idx]);
|
|
9018
|
+
const ref2 = hoist("gc", `CLS[${ci}][0]`);
|
|
9019
|
+
return isAsciiOnlyClass(resolved) ? `${ref2}.ascii[input.charCodeAt(${"@"})]!==1` : `!classHas(${ref2},lead(input,${"@"}))`;
|
|
9020
|
+
};
|
|
9021
|
+
const follow = cls(code[gapIp + 3]).replaceAll("@", "gq");
|
|
9022
|
+
const other = code[gapIp + 4] >= 0 ? cls(code[gapIp + 4]).replaceAll("@", "itemStart") : "true";
|
|
9023
|
+
if (shape !== null) {
|
|
9024
|
+
let n = 0;
|
|
9025
|
+
const q2 = tmp();
|
|
9026
|
+
const m = emitShapeMatch(shape, "itemStart", (prefix = "_v") => `${q2}${prefix}${n++}`, "");
|
|
9027
|
+
gapCode = (rbCode) => `let gapped=false
|
|
9028
|
+
if(ctx._probe===undefined){
|
|
9029
|
+
${m.setup.join("\n")}
|
|
9030
|
+
const gq=${m.ok}?${m.end}:-1
|
|
9031
|
+
if((gq<0||${follow})&&${other}){
|
|
9032
|
+
${rbCode}
|
|
9033
|
+
break
|
|
9034
|
+
}
|
|
9035
|
+
}
|
|
9036
|
+
`;
|
|
9037
|
+
} else {
|
|
9038
|
+
const re = hoist("gr", `K[${code[row + 1]}]`);
|
|
9039
|
+
gapCode = (rbCode) => `let gapped=false
|
|
9040
|
+
if(ctx._probe===undefined){
|
|
9041
|
+
${re}.lastIndex=itemStart
|
|
9042
|
+
const gq=${re}.test(input)?${re}.lastIndex:-1
|
|
9043
|
+
if((gq<0||${follow})&&${other}){
|
|
9044
|
+
${rbCode}
|
|
9045
|
+
break
|
|
9046
|
+
}
|
|
9047
|
+
if(gq>=0){
|
|
9048
|
+
GAP.row=${row};GAP.at=itemStart;GAP.end=gq;GAP.input=input
|
|
9049
|
+
gapped=true
|
|
9050
|
+
}
|
|
9051
|
+
}
|
|
9052
|
+
`;
|
|
9053
|
+
}
|
|
9054
|
+
}
|
|
9055
|
+
const sepMiss = (at) => sepAscii ? `${sepCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${sepCls},lead(input,${at}))`;
|
|
8823
9056
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
8824
9057
|
const p = tmp();
|
|
8825
9058
|
const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
|
|
@@ -8857,7 +9090,7 @@ ${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
|
8857
9090
|
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}
|
|
8858
9091
|
}`;
|
|
8859
9092
|
const my = `${p}my`;
|
|
8860
|
-
const recFx = REC ? fxRef(code[ip + 6])
|
|
9093
|
+
const recFx = !REC ? "" : (flags & 16) !== 0 ? "[]" : fxRef(code[ip + 6]);
|
|
8861
9094
|
const sepSent = REC ? sentRef(code[ip + 7]) : "undefined";
|
|
8862
9095
|
const recSent = sep === void 0 ? my : sepSent === "undefined" ? `orSentinel(${my},undefined)` : `orSentinel(${sepSent}??${my},${sepSent}===undefined?undefined:${my})`;
|
|
8863
9096
|
const recGate = sep !== void 0 || min === 0 ? "" : `count>=${min}&&`;
|
|
@@ -8873,7 +9106,7 @@ continue
|
|
|
8873
9106
|
return `${head}
|
|
8874
9107
|
const out=${collect ? "[]" : "undefined"}
|
|
8875
9108
|
${knownTrivia === void 0 ? "const hasTrivia=ctx.trivia!==undefined\n" : ""}${L.buf ? "" : "const needMark=_rollbackNeeded(ctx)\n"}${REC ? `const ${my}=ctx._sync
|
|
8876
|
-
` : ""}${itemCls === void 0 ? "" : `const ${p}gate=ctx._probe===undefined
|
|
9109
|
+
` : ""}${itemCls === void 0 && sepCls === void 0 ? "" : `const ${p}gate=ctx._probe===undefined
|
|
8877
9110
|
`}let cur=pos
|
|
8878
9111
|
let count=0
|
|
8879
9112
|
for(;;){
|
|
@@ -8889,6 +9122,10 @@ const lb=cstLeavesLen(ctx)
|
|
|
8889
9122
|
let sp=cur
|
|
8890
9123
|
${hasTrivia === "false" ? "" : hasTrivia === "true" ? `sp=${skip}(input,sp,ctx)
|
|
8891
9124
|
` : `if(hasTrivia)sp=${skip}(input,sp,ctx)
|
|
9125
|
+
`}${sepCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&${sepMiss("sp")}){
|
|
9126
|
+
${rb}
|
|
9127
|
+
break
|
|
9128
|
+
}
|
|
8892
9129
|
`}ctx._fc=false
|
|
8893
9130
|
${sepIp >= 0 && leadingTriviaFieldAt(code, k, sepIp) ? "LEAD.at=cur\n" : ""}const sv=${sep}(input,sp,ctx)
|
|
8894
9131
|
if(sv===FAIL){
|
|
@@ -8904,13 +9141,13 @@ itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(inp
|
|
|
8904
9141
|
${rb}
|
|
8905
9142
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
8906
9143
|
}
|
|
8907
|
-
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&${itemMiss("itemStart")}){
|
|
9144
|
+
${itemCls === void 0 || sep === void 0 && hasTrivia === "false" ? "" : `if(count>=${min}&&${p}gate&&${sep === void 0 && hasTrivia === "hasTrivia" ? "hasTrivia&&" : ""}${itemMiss("itemStart")}){
|
|
8908
9145
|
${rb}
|
|
8909
9146
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
8910
9147
|
}
|
|
8911
|
-
`}ctx._fc=false
|
|
9148
|
+
`}${gapCode(rb)}ctx._fc=false
|
|
8912
9149
|
const v=${child}(input,itemStart,ctx)
|
|
8913
|
-
if(v===FAIL){
|
|
9150
|
+
${gapIp >= 0 ? "if(gapped)GAP.at=-1\n" : ""}if(v===FAIL){
|
|
8914
9151
|
${REC ? `if(ctx._fc===true){
|
|
8915
9152
|
${rb}
|
|
8916
9153
|
return FAIL
|
|
@@ -9233,6 +9470,7 @@ function passChild(code, ip) {
|
|
|
9233
9470
|
case OP_LABEL:
|
|
9234
9471
|
case OP_COV:
|
|
9235
9472
|
case OP_TOKEN:
|
|
9473
|
+
case OP_GAPGATE:
|
|
9236
9474
|
return code[ip + 1];
|
|
9237
9475
|
case OP_GATE:
|
|
9238
9476
|
case OP_NODE:
|
|
@@ -9505,6 +9743,13 @@ function cfgKeyOf(hostCst, trackLines, tolerant, coverage, probe, hostReadsChild
|
|
|
9505
9743
|
function cfgKey(c) {
|
|
9506
9744
|
return cfgKeyOf(c.hostCst, c.trackLines, c.tolerant, c.coverage, c.probe, c.hostReadsChildren);
|
|
9507
9745
|
}
|
|
9746
|
+
function assertFactoryArity(pre) {
|
|
9747
|
+
if (pre.arity === EMITTED_PARAMS.length) return;
|
|
9748
|
+
const printed = pre.arity === void 0 ? "carries no helper count, so it was printed before parseman 0.60.0" : `takes ${pre.arity} helpers, but parseman ${PARSEMAN_VERSION} passes ${EMITTED_PARAMS.length}: it was printed by an older or newer parseman`;
|
|
9749
|
+
throw new Error(
|
|
9750
|
+
`parseman: this parser's printed assembly ${printed}. Reprint the parser with parseman ${PARSEMAN_VERSION}, or run it on the parseman version that printed it.`
|
|
9751
|
+
);
|
|
9752
|
+
}
|
|
9508
9753
|
function assemble(t, prog, cfg) {
|
|
9509
9754
|
const { code, k, fns, cc, fx, disp, dsp, trivia: trivia2, triviaLabelled } = t;
|
|
9510
9755
|
const triviaScan = t.triviaScan;
|
|
@@ -9539,6 +9784,8 @@ function assemble(t, prog, cfg) {
|
|
|
9539
9784
|
return recognize;
|
|
9540
9785
|
}
|
|
9541
9786
|
const labelExtraIps = assemblyExtraIps(prog);
|
|
9787
|
+
const GAP_ROWS = gapRows(code, [...Object.values(prog.rules), ...labelExtraIps]);
|
|
9788
|
+
const GAP = newGapSlot();
|
|
9542
9789
|
const closureLabels = computeSiteLabels(
|
|
9543
9790
|
code,
|
|
9544
9791
|
[...Object.values(prog.rules), ...labelExtraIps],
|
|
@@ -9757,6 +10004,27 @@ function assemble(t, prog, cfg) {
|
|
|
9757
10004
|
return node;
|
|
9758
10005
|
};
|
|
9759
10006
|
}
|
|
10007
|
+
function gapRegexPiece(row, re, xf, track) {
|
|
10008
|
+
return (input, pos, ctx) => {
|
|
10009
|
+
let e;
|
|
10010
|
+
if (GAP.row === row && GAP.at === pos && GAP.input === input) e = GAP.end;
|
|
10011
|
+
else {
|
|
10012
|
+
re.lastIndex = pos;
|
|
10013
|
+
e = re.test(input) ? re.lastIndex : -1;
|
|
10014
|
+
}
|
|
10015
|
+
if (e >= 0) {
|
|
10016
|
+
const v = input.slice(pos, e);
|
|
10017
|
+
if (cstCaptureActive(ctx)) pushLeaf(ctx, v, pos, e);
|
|
10018
|
+
if (track) trackLinesInto(ctx, input, e);
|
|
10019
|
+
EC.e = e;
|
|
10020
|
+
return v;
|
|
10021
|
+
}
|
|
10022
|
+
ctx._fe = pos;
|
|
10023
|
+
ctx._fx = xf;
|
|
10024
|
+
if (ctx._probe !== void 0) failAt(ctx, xf, pos);
|
|
10025
|
+
return FAIL;
|
|
10026
|
+
};
|
|
10027
|
+
}
|
|
9760
10028
|
function passCollapseNode(child, build, readsRaw) {
|
|
9761
10029
|
return (input, pos, ctx) => {
|
|
9762
10030
|
const v = child(input, pos, ctx);
|
|
@@ -10159,7 +10427,7 @@ function assemble(t, prog, cfg) {
|
|
|
10159
10427
|
return next?.(key);
|
|
10160
10428
|
};
|
|
10161
10429
|
}
|
|
10162
|
-
function dispatchBranch(child, usesRouted) {
|
|
10430
|
+
function dispatchBranch(child, usesRouted, commits = true) {
|
|
10163
10431
|
if (!usesRouted) {
|
|
10164
10432
|
return (input, _pos, selEnd, key, ctx) => {
|
|
10165
10433
|
const need = markCst(ctx);
|
|
@@ -10173,7 +10441,7 @@ function assemble(t, prog, cfg) {
|
|
|
10173
10441
|
const v = child(input, selEnd, ctx);
|
|
10174
10442
|
if (v === FAIL) {
|
|
10175
10443
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
10176
|
-
ctx._fc = true;
|
|
10444
|
+
if (commits) ctx._fc = true;
|
|
10177
10445
|
return FAIL;
|
|
10178
10446
|
}
|
|
10179
10447
|
return [key, v];
|
|
@@ -10191,7 +10459,7 @@ function assemble(t, prog, cfg) {
|
|
|
10191
10459
|
}
|
|
10192
10460
|
if (v === FAIL) {
|
|
10193
10461
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
10194
|
-
ctx._fc = true;
|
|
10462
|
+
if (commits) ctx._fc = true;
|
|
10195
10463
|
return FAIL;
|
|
10196
10464
|
}
|
|
10197
10465
|
return [key, v];
|
|
@@ -10432,6 +10700,7 @@ function assemble(t, prog, cfg) {
|
|
|
10432
10700
|
case OP_RX: {
|
|
10433
10701
|
const re = k[code[ip + 1]];
|
|
10434
10702
|
const xf = fx[code[ip + 2]];
|
|
10703
|
+
if (GAP_ROWS.has(ip)) return gapRegexPiece(ip, re, xf, false);
|
|
10435
10704
|
const shared = rawScalarSpecs.has(code[ip + 1]) ? scalarFor(ip) : void 0;
|
|
10436
10705
|
if (shared !== void 0) {
|
|
10437
10706
|
return (input, pos, ctx) => {
|
|
@@ -10466,6 +10735,7 @@ function assemble(t, prog, cfg) {
|
|
|
10466
10735
|
case OP_RX_TRACK: {
|
|
10467
10736
|
const re = k[code[ip + 1]];
|
|
10468
10737
|
const xf = fx[code[ip + 2]];
|
|
10738
|
+
if (GAP_ROWS.has(ip)) return gapRegexPiece(ip, re, xf, true);
|
|
10469
10739
|
return (input, pos, ctx) => {
|
|
10470
10740
|
re.lastIndex = pos;
|
|
10471
10741
|
if (re.test(input)) {
|
|
@@ -10596,6 +10866,12 @@ function assemble(t, prog, cfg) {
|
|
|
10596
10866
|
return v;
|
|
10597
10867
|
};
|
|
10598
10868
|
}
|
|
10869
|
+
// Transparent: only the repeat holding it reads its operands.
|
|
10870
|
+
case OP_GAPGATE:
|
|
10871
|
+
return link(code[ip + 1]);
|
|
10872
|
+
// One encoding per assembly: strict, or the construct as written.
|
|
10873
|
+
case OP_STRICT:
|
|
10874
|
+
return link(code[cfg.tolerant || cfg.probe ? ip + 2 : ip + 1]);
|
|
10599
10875
|
case OP_RULE:
|
|
10600
10876
|
return link(code[ip + 1]);
|
|
10601
10877
|
case OP_LIVE: {
|
|
@@ -11521,7 +11797,7 @@ function assemble(t, prog, cfg) {
|
|
|
11521
11797
|
if (table.exclusive) {
|
|
11522
11798
|
const ascii = table.ascii;
|
|
11523
11799
|
const hi = table.hi;
|
|
11524
|
-
if (n === 2) {
|
|
11800
|
+
if (n === 2 && !cfg.probe) {
|
|
11525
11801
|
const a0 = link(code[base]), a1 = link(code[base + 1]);
|
|
11526
11802
|
return (input, pos, ctx) => {
|
|
11527
11803
|
const c = lead(input, pos);
|
|
@@ -11553,7 +11829,7 @@ function assemble(t, prog, cfg) {
|
|
|
11553
11829
|
return FAIL;
|
|
11554
11830
|
};
|
|
11555
11831
|
}
|
|
11556
|
-
if (n === 3) {
|
|
11832
|
+
if (n === 3 && !cfg.probe) {
|
|
11557
11833
|
const a0 = link(code[base]), a1 = link(code[base + 1]), a2 = link(code[base + 2]);
|
|
11558
11834
|
return (input, pos, ctx) => {
|
|
11559
11835
|
const c = lead(input, pos);
|
|
@@ -11598,6 +11874,7 @@ function assemble(t, prog, cfg) {
|
|
|
11598
11874
|
);
|
|
11599
11875
|
};
|
|
11600
11876
|
const selected = bindExclusive(0);
|
|
11877
|
+
const probeArms = cfg.probe ? Array.from({ length: n }, (_, i) => link(code[base + i])) : void 0;
|
|
11601
11878
|
return (input, pos, ctx) => {
|
|
11602
11879
|
const c = lead(input, pos);
|
|
11603
11880
|
let arm = -1;
|
|
@@ -11623,12 +11900,13 @@ function assemble(t, prog, cfg) {
|
|
|
11623
11900
|
return FAIL;
|
|
11624
11901
|
}
|
|
11625
11902
|
}
|
|
11903
|
+
if (arm < 0 && probeArms !== void 0) for (const a of probeArms) a(input, pos, ctx);
|
|
11626
11904
|
ctx._fe = pos;
|
|
11627
11905
|
ctx._fx = choiceFx;
|
|
11628
11906
|
return FAIL;
|
|
11629
11907
|
};
|
|
11630
11908
|
}
|
|
11631
|
-
const armCls = table.armCls;
|
|
11909
|
+
const armCls = cfg.probe ? table.armCls.map(() => null) : table.armCls;
|
|
11632
11910
|
if (n === 2 || n === 3) {
|
|
11633
11911
|
const a0 = link(code[base]), a1 = link(code[base + 1]);
|
|
11634
11912
|
const a2 = n === 3 ? link(code[base + 2]) : void 0;
|
|
@@ -12048,6 +12326,43 @@ function assemble(t, prog, cfg) {
|
|
|
12048
12326
|
return child(input, pos, ctx);
|
|
12049
12327
|
};
|
|
12050
12328
|
}
|
|
12329
|
+
case OP_RGATE2: {
|
|
12330
|
+
const cls = cc[code[ip + 1]];
|
|
12331
|
+
const xf = fx[code[ip + 3]];
|
|
12332
|
+
const first = cc[code[ip + 4]];
|
|
12333
|
+
const second = cc[code[ip + 5]];
|
|
12334
|
+
const child = link(code[ip + 2]);
|
|
12335
|
+
if (cfg.tolerant || cfg.probe) return child;
|
|
12336
|
+
if (cls.hi.length === 0 && first.hi.length === 0 && second.hi.length === 0) {
|
|
12337
|
+
const a0 = cls.ascii, a1 = first.ascii, a2 = second.ascii;
|
|
12338
|
+
return (input, pos, ctx) => {
|
|
12339
|
+
const item = ctx._routed;
|
|
12340
|
+
if (item !== void 0 && item.span.start === pos) {
|
|
12341
|
+
const e = item.span.end;
|
|
12342
|
+
const c = input.charCodeAt(e);
|
|
12343
|
+
if (a0[c] !== 1 || a1[c] === 1 && a2[input.charCodeAt(e + 1)] !== 1) {
|
|
12344
|
+
ctx._fe = e;
|
|
12345
|
+
ctx._fx = xf;
|
|
12346
|
+
return FAIL;
|
|
12347
|
+
}
|
|
12348
|
+
}
|
|
12349
|
+
return child(input, pos, ctx);
|
|
12350
|
+
};
|
|
12351
|
+
}
|
|
12352
|
+
return (input, pos, ctx) => {
|
|
12353
|
+
const item = ctx._routed;
|
|
12354
|
+
if (item !== void 0 && item.span.start === pos) {
|
|
12355
|
+
const e = item.span.end;
|
|
12356
|
+
const c = lead(input, e);
|
|
12357
|
+
if (!classHas2(cls, c) || classHas2(first, c) && !classHas2(second, lead(input, e + 1))) {
|
|
12358
|
+
ctx._fe = e;
|
|
12359
|
+
ctx._fx = xf;
|
|
12360
|
+
return FAIL;
|
|
12361
|
+
}
|
|
12362
|
+
}
|
|
12363
|
+
return child(input, pos, ctx);
|
|
12364
|
+
};
|
|
12365
|
+
}
|
|
12051
12366
|
case OP_ARMGATE: {
|
|
12052
12367
|
const pred = fns[code[ip + 1]];
|
|
12053
12368
|
const child = link(code[ip + 2]);
|
|
@@ -12115,10 +12430,18 @@ function assemble(t, prog, cfg) {
|
|
|
12115
12430
|
const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
|
|
12116
12431
|
const itemClass = !REC && itemClassIndex >= 0 ? cc[itemClassIndex] : void 0;
|
|
12117
12432
|
const itemMayStart = itemClass === void 0 ? void 0 : (input, pos) => classHas2(itemClass, lead(input, pos));
|
|
12433
|
+
const sepClassIndex = sepIp >= 0 && !sepLeads && (flags & 8) !== 0 ? code[ip + 8] : -1;
|
|
12434
|
+
const sepClass = !REC && sepClassIndex >= 0 && !rowNullable(code, k, sepIp, NULLABLE) ? cc[sepClassIndex] : void 0;
|
|
12435
|
+
const gapIp = sepIp < 0 && min === 0 && !REC && code[code[ip + 1]] === OP_GAPGATE ? code[ip + 1] : -1;
|
|
12436
|
+
const gapRow = gapIp >= 0 ? code[gapIp + 2] : -1;
|
|
12437
|
+
const gapRe = gapIp >= 0 ? k[code[gapRow + 1]] : void 0;
|
|
12438
|
+
const gapFollow = gapIp >= 0 ? cc[code[gapIp + 3]] : void 0;
|
|
12439
|
+
const gapOther = gapIp >= 0 && code[gapIp + 4] >= 0 ? cc[code[gapIp + 4]] : void 0;
|
|
12118
12440
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
12119
12441
|
const itemClean = sepIp < 0 && CLEAN(code[ip + 1]) && !rowNullable(code, k, code[ip + 1], NULLABLE);
|
|
12120
12442
|
if (REC) {
|
|
12121
12443
|
const itemFx2 = fx[code[ip + 6]];
|
|
12444
|
+
const recFx = (flags & 16) !== 0 ? EMPTY_FX2 : itemFx2;
|
|
12122
12445
|
const sepSent = sentinelFor(code[ip + 7]);
|
|
12123
12446
|
return (input, pos, ctx) => {
|
|
12124
12447
|
const out = collect ? [] : void 0;
|
|
@@ -12178,7 +12501,7 @@ function assemble(t, prog, cfg) {
|
|
|
12178
12501
|
itemStart,
|
|
12179
12502
|
ctx,
|
|
12180
12503
|
sep === void 0 ? mySync : orSentinel(sepSent ?? mySync, sepSent === void 0 ? void 0 : mySync),
|
|
12181
|
-
|
|
12504
|
+
recFx
|
|
12182
12505
|
);
|
|
12183
12506
|
if (out !== void 0) out.push(rr.error);
|
|
12184
12507
|
captureError(ctx, rr.error);
|
|
@@ -12216,6 +12539,7 @@ function assemble(t, prog, cfg) {
|
|
|
12216
12539
|
const markLater = needMark && (!itemClean || hasTrivia);
|
|
12217
12540
|
const markFirst = needMark && (!itemClean || hasTrivia && skipBeforeFirst);
|
|
12218
12541
|
const gateItems = itemMayStart !== void 0 && ctx._probe === void 0;
|
|
12542
|
+
const gateSep = sepClass !== void 0 && ctx._probe === void 0;
|
|
12219
12543
|
let cur = pos;
|
|
12220
12544
|
let count = 0;
|
|
12221
12545
|
for (; ; ) {
|
|
@@ -12238,6 +12562,10 @@ function assemble(t, prog, cfg) {
|
|
|
12238
12562
|
const leavesBefore = cstLeavesLen(ctx);
|
|
12239
12563
|
let sp = cur;
|
|
12240
12564
|
if (hasTrivia) sp = skipTrivia(input, sp, ctx);
|
|
12565
|
+
if (count >= min && gateSep && !classHas2(sepClass, lead(input, sp))) {
|
|
12566
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12567
|
+
break;
|
|
12568
|
+
}
|
|
12241
12569
|
ctx._fc = false;
|
|
12242
12570
|
if (sepLeads) LEAD.at = cur;
|
|
12243
12571
|
const sv = sep(input, sp, ctx);
|
|
@@ -12257,13 +12585,30 @@ function assemble(t, prog, cfg) {
|
|
|
12257
12585
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
12258
12586
|
break;
|
|
12259
12587
|
}
|
|
12260
|
-
if (count >= min && gateItems && !itemMayStart(input, itemStart)) {
|
|
12588
|
+
if (count >= min && gateItems && (sep !== void 0 || hasTrivia) && !itemMayStart(input, itemStart)) {
|
|
12261
12589
|
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12262
12590
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
12263
12591
|
break;
|
|
12264
12592
|
}
|
|
12593
|
+
let gapped = false;
|
|
12594
|
+
if (gapRe !== void 0 && ctx._probe === void 0) {
|
|
12595
|
+
gapRe.lastIndex = itemStart;
|
|
12596
|
+
const q2 = gapRe.test(input) ? gapRe.lastIndex : -1;
|
|
12597
|
+
if ((q2 < 0 || !classHas2(gapFollow, lead(input, q2))) && (gapOther === void 0 || !classHas2(gapOther, lead(input, itemStart)))) {
|
|
12598
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12599
|
+
break;
|
|
12600
|
+
}
|
|
12601
|
+
if (q2 >= 0) {
|
|
12602
|
+
GAP.row = gapRow;
|
|
12603
|
+
GAP.at = itemStart;
|
|
12604
|
+
GAP.end = q2;
|
|
12605
|
+
GAP.input = input;
|
|
12606
|
+
gapped = true;
|
|
12607
|
+
}
|
|
12608
|
+
}
|
|
12265
12609
|
ctx._fc = false;
|
|
12266
12610
|
const v = child(input, itemStart, ctx);
|
|
12611
|
+
if (gapped) GAP.at = -1;
|
|
12267
12612
|
if (v === FAIL) {
|
|
12268
12613
|
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12269
12614
|
if (committed3(ctx)) return FAIL;
|
|
@@ -12295,7 +12640,8 @@ function assemble(t, prog, cfg) {
|
|
|
12295
12640
|
const selector = link(code[ip + 1]);
|
|
12296
12641
|
const otherIp = code[ip + 3];
|
|
12297
12642
|
const other = otherIp >= 0 ? link(otherIp) : void 0;
|
|
12298
|
-
const otherRouted = code[ip + 4] === 1;
|
|
12643
|
+
const otherRouted = (code[ip + 4] & 1) === 1;
|
|
12644
|
+
const otherCommits = (code[ip + 4] & 2) === 0;
|
|
12299
12645
|
const n = code[ip + 5];
|
|
12300
12646
|
const armBase = ip + 6;
|
|
12301
12647
|
const byKey = spec.byKey;
|
|
@@ -12343,7 +12689,7 @@ function assemble(t, prog, cfg) {
|
|
|
12343
12689
|
);
|
|
12344
12690
|
};
|
|
12345
12691
|
const runArm = n === 0 ? void 0 : bindArms(0);
|
|
12346
|
-
const runOther = other === void 0 ? void 0 : dispatchBranch(other, otherRouted);
|
|
12692
|
+
const runOther = other === void 0 ? void 0 : dispatchBranch(other, otherRouted, otherCommits);
|
|
12347
12693
|
return (input, pos, ctx) => {
|
|
12348
12694
|
const need = markCst(ctx);
|
|
12349
12695
|
const mRaw = MRAW;
|
|
@@ -12604,6 +12950,7 @@ function assemble(t, prog, cfg) {
|
|
|
12604
12950
|
}
|
|
12605
12951
|
const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
|
|
12606
12952
|
if (pre !== void 0) {
|
|
12953
|
+
assertFactoryArity(pre);
|
|
12607
12954
|
const pools = rebuildPools(t.cc, t.fx, t.disp, pre.plan);
|
|
12608
12955
|
emitted = pre.factory(
|
|
12609
12956
|
EC,
|
|
@@ -12615,7 +12962,6 @@ function assemble(t, prog, cfg) {
|
|
|
12615
12962
|
pools.classes,
|
|
12616
12963
|
pools.armExpected,
|
|
12617
12964
|
trivia2,
|
|
12618
|
-
trivia2.map((tv) => tv?._meta.triviaKindLabels),
|
|
12619
12965
|
triviaScan,
|
|
12620
12966
|
scansArr,
|
|
12621
12967
|
disp,
|
|
@@ -12639,7 +12985,6 @@ function assemble(t, prog, cfg) {
|
|
|
12639
12985
|
cstLeavesLen,
|
|
12640
12986
|
skipTriviaScanned,
|
|
12641
12987
|
needsDeferredTriviaCommit,
|
|
12642
|
-
scanTrivia,
|
|
12643
12988
|
advanceTrivia,
|
|
12644
12989
|
refuseUnclassifiedRootScope,
|
|
12645
12990
|
spanLines,
|
|
@@ -12653,8 +12998,6 @@ function assemble(t, prog, cfg) {
|
|
|
12653
12998
|
orSentinel,
|
|
12654
12999
|
captureError,
|
|
12655
13000
|
scalarRecognizers,
|
|
12656
|
-
commitTriviaScan,
|
|
12657
|
-
scanTriviaCompact,
|
|
12658
13001
|
t.lex,
|
|
12659
13002
|
adjacencyHolds,
|
|
12660
13003
|
t.lexPrograms,
|
|
@@ -12666,7 +13009,8 @@ function assemble(t, prog, cfg) {
|
|
|
12666
13009
|
PlainLeaf8,
|
|
12667
13010
|
PlainNode2,
|
|
12668
13011
|
PlainField,
|
|
12669
|
-
PlainBuf2
|
|
13012
|
+
PlainBuf2,
|
|
13013
|
+
GAP
|
|
12670
13014
|
);
|
|
12671
13015
|
emitReached = new Set(pre.reached);
|
|
12672
13016
|
if (emitted.ext !== void 0) HYBRID = emitted;
|
|
@@ -12702,7 +13046,6 @@ function assemble(t, prog, cfg) {
|
|
|
12702
13046
|
em.classes,
|
|
12703
13047
|
em.armExpected,
|
|
12704
13048
|
trivia2,
|
|
12705
|
-
trivia2.map((tv) => tv?._meta.triviaKindLabels),
|
|
12706
13049
|
triviaScan,
|
|
12707
13050
|
scansArr,
|
|
12708
13051
|
disp,
|
|
@@ -12726,7 +13069,6 @@ function assemble(t, prog, cfg) {
|
|
|
12726
13069
|
cstLeavesLen,
|
|
12727
13070
|
skipTriviaScanned,
|
|
12728
13071
|
needsDeferredTriviaCommit,
|
|
12729
|
-
scanTrivia,
|
|
12730
13072
|
advanceTrivia,
|
|
12731
13073
|
refuseUnclassifiedRootScope,
|
|
12732
13074
|
spanLines,
|
|
@@ -12745,8 +13087,6 @@ function assemble(t, prog, cfg) {
|
|
|
12745
13087
|
orSentinel,
|
|
12746
13088
|
captureError,
|
|
12747
13089
|
scalarRecognizers,
|
|
12748
|
-
commitTriviaScan,
|
|
12749
|
-
scanTriviaCompact,
|
|
12750
13090
|
t.lex,
|
|
12751
13091
|
adjacencyHolds,
|
|
12752
13092
|
t.lexPrograms,
|
|
@@ -12758,7 +13098,8 @@ function assemble(t, prog, cfg) {
|
|
|
12758
13098
|
PlainLeaf8,
|
|
12759
13099
|
PlainNode2,
|
|
12760
13100
|
PlainField,
|
|
12761
|
-
PlainBuf2
|
|
13101
|
+
PlainBuf2,
|
|
13102
|
+
GAP
|
|
12762
13103
|
);
|
|
12763
13104
|
emitReached = em.reached;
|
|
12764
13105
|
} catch (e) {
|
|
@@ -13157,7 +13498,7 @@ function attempt(parser2, options) {
|
|
|
13157
13498
|
return {
|
|
13158
13499
|
_tag: "attempt",
|
|
13159
13500
|
_meta: parser2._meta,
|
|
13160
|
-
_def:
|
|
13501
|
+
_def: { tag: "attempt", parser: parser2, ...contain ? { contain: true } : {}, ...guardable ? { guarded: true } : {} },
|
|
13161
13502
|
parse(input, pos, ctx) {
|
|
13162
13503
|
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(parser2, input, pos)) {
|
|
13163
13504
|
if (failExpected === void 0) {
|
|
@@ -13650,6 +13991,7 @@ function reachesMarked(root, successors, memo) {
|
|
|
13650
13991
|
}
|
|
13651
13992
|
|
|
13652
13993
|
// src/table/factor-choice.ts
|
|
13994
|
+
var factoredChoices = /* @__PURE__ */ new WeakSet();
|
|
13653
13995
|
var DERIVED = /* @__PURE__ */ new Set(["_tag", "_meta", "_def", "_parseScalar", "_stickyRegex", "parse"]);
|
|
13654
13996
|
function isCombinator(v) {
|
|
13655
13997
|
return typeof v === "object" && v !== null && "_def" in v && "_meta" in v;
|
|
@@ -13741,6 +14083,7 @@ function factorSharedEnds(d) {
|
|
|
13741
14083
|
for (let i = at + 1; i < n; i++) if (!never(first.terms[i])) return void 0;
|
|
13742
14084
|
if (arms.some((a) => mayCommitFailure(a))) return void 0;
|
|
13743
14085
|
const middle = choice(...shapes.map((s) => s.terms[at]));
|
|
14086
|
+
factoredChoices.add(middle);
|
|
13744
14087
|
if (middle._def.tag === "choice" && middle._def.autoNot.some((a) => a !== null)) return void 0;
|
|
13745
14088
|
const st = middle._def.tag === "choice" ? middle._def.strategy : void 0;
|
|
13746
14089
|
if (st === void 0 || st.tag !== "firstMatch" && st.tag !== "sharedPrefix" && !(st.tag === "literalsLongestFirst" && st.sortedIndices.every((x, i) => x === i))) return void 0;
|
|
@@ -13753,6 +14096,37 @@ function factorSharedEnds(d) {
|
|
|
13753
14096
|
for (let j = first.wrappers.length - 1; j >= 0 && out !== void 0; j--) out = rewrap(first.wrappers[j], out);
|
|
13754
14097
|
return out === void 0 ? void 0 : attempt(out);
|
|
13755
14098
|
}
|
|
14099
|
+
function factorPrefixArms(d) {
|
|
14100
|
+
const arms = d.parsers;
|
|
14101
|
+
if (arms.length < 2) return void 0;
|
|
14102
|
+
if (d.strategy.tag !== "firstMatch" && d.strategy.tag !== "sharedPrefix") return void 0;
|
|
14103
|
+
if (d.gates.some((g) => g !== null) || d.autoNot.some((a) => a !== null)) return void 0;
|
|
14104
|
+
const out = [...arms];
|
|
14105
|
+
let changed = false;
|
|
14106
|
+
for (let i = 0; i + 1 < arms.length; i++) {
|
|
14107
|
+
const arm = arms[i];
|
|
14108
|
+
if (arm._def.tag !== "sequence" || arm._def.valueUnused !== true) continue;
|
|
14109
|
+
const terms = arm._def.parsers;
|
|
14110
|
+
const next = arms[i + 1];
|
|
14111
|
+
const prefix = next._def.tag === "sequence" && next._def.valueUnused === true ? next._def.parsers : [next];
|
|
14112
|
+
if (prefix.length >= terms.length) continue;
|
|
14113
|
+
if (!prefix.every((t, j) => sameComb(t, terms[j], 0))) continue;
|
|
14114
|
+
const rest = terms.slice(prefix.length);
|
|
14115
|
+
if (rest.every(never)) continue;
|
|
14116
|
+
const tail = rest.length === 1 ? rest[0] : sequence(...rest);
|
|
14117
|
+
if (tail !== rest[0]) tail._def.valueUnused = true;
|
|
14118
|
+
const parts = [...terms.slice(0, prefix.length), optional(tail)];
|
|
14119
|
+
const seq = sequence(...parts);
|
|
14120
|
+
seq._def.valueUnused = true;
|
|
14121
|
+
out[i] = seq;
|
|
14122
|
+
changed = true;
|
|
14123
|
+
}
|
|
14124
|
+
if (!changed) return void 0;
|
|
14125
|
+
const rebuilt = choice(...out);
|
|
14126
|
+
factoredChoices.add(rebuilt);
|
|
14127
|
+
const st = rebuilt._def.tag === "choice" ? rebuilt._def.strategy : void 0;
|
|
14128
|
+
return st !== void 0 && (st.tag === "firstMatch" || st.tag === "sharedPrefix") ? rebuilt : void 0;
|
|
14129
|
+
}
|
|
13756
14130
|
|
|
13757
14131
|
// src/compiler/direct-projection.ts
|
|
13758
14132
|
function directArrayProjection(fn, fnSrc, arity) {
|
|
@@ -13854,9 +14228,9 @@ function directOptionalSuffixTokenBody(parser2, resolve) {
|
|
|
13854
14228
|
baseParser = resolvedLazyTarget(baseParser, resolve);
|
|
13855
14229
|
}
|
|
13856
14230
|
const base = baseParser?._def;
|
|
13857
|
-
const
|
|
13858
|
-
if (base?.tag !== "regex" ||
|
|
13859
|
-
const suffix =
|
|
14231
|
+
const optional2 = sequence6.parsers[1]?._def;
|
|
14232
|
+
if (base?.tag !== "regex" || optional2?.tag !== "optional") return void 0;
|
|
14233
|
+
const suffix = optional2.parser._def;
|
|
13860
14234
|
if (suffix.tag !== "literal" || suffix.caseInsensitive || suffix.value.length !== 1) return void 0;
|
|
13861
14235
|
const selected = selectOptionalSuffixLexBody({
|
|
13862
14236
|
kind: "sequence",
|
|
@@ -13875,7 +14249,7 @@ function directOptionalSuffixTokenBody(parser2, resolve) {
|
|
|
13875
14249
|
return selected.strategy === "token" ? {
|
|
13876
14250
|
...selected.body,
|
|
13877
14251
|
baseCanMatchNewline: baseParser._meta.canMatchNewline,
|
|
13878
|
-
suffixCanMatchNewline:
|
|
14252
|
+
suffixCanMatchNewline: optional2.parser._meta.canMatchNewline,
|
|
13879
14253
|
expected: directTerminalFailureExpected(base)
|
|
13880
14254
|
} : void 0;
|
|
13881
14255
|
}
|
|
@@ -14053,6 +14427,7 @@ function directFixedLexNode(parser2, resolve, active, pureOnly = false, cleared
|
|
|
14053
14427
|
arms,
|
|
14054
14428
|
parsers: def.parsers,
|
|
14055
14429
|
cleared,
|
|
14430
|
+
disjoint: def.disjoint,
|
|
14056
14431
|
armExpected: def.parsers.map(deriveExpected),
|
|
14057
14432
|
expected: def.parsers.flatMap(deriveExpected)
|
|
14058
14433
|
};
|
|
@@ -14162,6 +14537,29 @@ var UnsupportedConstruct = class extends Error {
|
|
|
14162
14537
|
this.tag = tag;
|
|
14163
14538
|
}
|
|
14164
14539
|
};
|
|
14540
|
+
function firstTwo(p) {
|
|
14541
|
+
const d = p._def;
|
|
14542
|
+
if (d.tag === "label" || d.tag === "grammar") return firstTwo(d.parser);
|
|
14543
|
+
let two;
|
|
14544
|
+
if (d.tag === "literal" && d.value.length >= 2 && d.caseInsensitive !== true) {
|
|
14545
|
+
const second = d.value.codePointAt(1);
|
|
14546
|
+
two = { first: { kind: "ranges", ranges: [{ lo: d.value.charCodeAt(0), hi: d.value.charCodeAt(0) }] }, second: { kind: "ranges", ranges: [{ lo: second, hi: second }] } };
|
|
14547
|
+
} else if (d.tag === "regex" && !d.flags.includes("i")) {
|
|
14548
|
+
const units = regexFirstTwo(d.source, d.flags);
|
|
14549
|
+
if (units !== void 0) two = units;
|
|
14550
|
+
}
|
|
14551
|
+
if (two === void 0 || two.first.kind !== "ranges") return void 0;
|
|
14552
|
+
return two.first.ranges.every((r) => r.hi < 55296 || r.lo > 57343 && r.hi <= 65535) ? two : void 0;
|
|
14553
|
+
}
|
|
14554
|
+
var GAP_CHARS = /* @__PURE__ */ new Set([9, 10, 12, 13, 32, 47]);
|
|
14555
|
+
function isGap(p) {
|
|
14556
|
+
if (matchesEmpty(p)) return true;
|
|
14557
|
+
const fs = p._meta.firstSet;
|
|
14558
|
+
return fs.kind === "ranges" && fs.ranges.every((r) => {
|
|
14559
|
+
for (let c = r.lo; c <= r.hi; c++) if (!GAP_CHARS.has(c)) return false;
|
|
14560
|
+
return true;
|
|
14561
|
+
});
|
|
14562
|
+
}
|
|
14165
14563
|
var Encoder = class {
|
|
14166
14564
|
code = [];
|
|
14167
14565
|
k = [];
|
|
@@ -14209,8 +14607,33 @@ var Encoder = class {
|
|
|
14209
14607
|
*/
|
|
14210
14608
|
commitFailureMemo = /* @__PURE__ */ new Map();
|
|
14211
14609
|
labels = void 0;
|
|
14610
|
+
/** The choice being encoded as written, for `OP_STRICT`'s tolerant child. */
|
|
14611
|
+
unfactoredChoice = void 0;
|
|
14212
14612
|
/** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
|
|
14213
14613
|
activeTrivia = void 0;
|
|
14614
|
+
/**
|
|
14615
|
+
* Is the trivia live at this row known? It is not in the body of an entry
|
|
14616
|
+
* that installs none of its own: that body runs under whatever trivia its
|
|
14617
|
+
* caller has (a compiled rule inside another grammar, `run({ trivia })`).
|
|
14618
|
+
* Every scope (`parser({ trivia })`, `noTrivia`, `token()`, a rule's install)
|
|
14619
|
+
* makes it known again.
|
|
14620
|
+
*/
|
|
14621
|
+
triviaKnown = true;
|
|
14622
|
+
/**
|
|
14623
|
+
* The trivia a gate's first set is derived under: the live table, `null` for a
|
|
14624
|
+
* scope known to have none, or `undefined` where it is not known.
|
|
14625
|
+
*/
|
|
14626
|
+
gateTrivia() {
|
|
14627
|
+
return this.activeTrivia ?? (this.triviaKnown ? null : void 0);
|
|
14628
|
+
}
|
|
14629
|
+
/**
|
|
14630
|
+
* Whether a gate may read a nullable pad through its non-empty matches
|
|
14631
|
+
* (`firstSetOf`'s `consuming`): only where the trivia that may follow the pad
|
|
14632
|
+
* is known. Elsewhere a gate reads first sets as 0.58.0 did.
|
|
14633
|
+
*/
|
|
14634
|
+
gateConsuming() {
|
|
14635
|
+
return this.activeTrivia !== void 0 || this.triviaKnown;
|
|
14636
|
+
}
|
|
14214
14637
|
classified = false;
|
|
14215
14638
|
scans = [];
|
|
14216
14639
|
/** Ambient `scanSkip` sets, pooled by the ARRAY's identity (stable per grammar). */
|
|
@@ -14337,10 +14760,12 @@ var Encoder = class {
|
|
|
14337
14760
|
const final = classifyFinalChoice(
|
|
14338
14761
|
node.parsers,
|
|
14339
14762
|
this.refResolver(),
|
|
14340
|
-
node.cleared ?
|
|
14763
|
+
node.cleared ? null : this.gateTrivia(),
|
|
14764
|
+
false,
|
|
14765
|
+
node.disjoint
|
|
14341
14766
|
);
|
|
14342
14767
|
const classes = final.firstSets.map((first, i) => final.nullable[i] ? -1 : this.charClass(first));
|
|
14343
|
-
const exclusive = final.exclusive && classes.every((cls) => cls >= 0);
|
|
14768
|
+
const exclusive = final.exclusive && classes.every((cls) => cls >= 0) && this.wideArms(node.parsers, final.firstSets, node.disjoint, node.cleared ? null : this.gateTrivia(), node.cleared ? void 0 : this.activeTrivia).length === 0;
|
|
14344
14769
|
words.push(LEX_NODE_CHOICE, node.arms.length, exclusive ? 1 : 0, this.expected(node.expected));
|
|
14345
14770
|
for (let i = 0; i < node.arms.length; i++) {
|
|
14346
14771
|
words.push(classes[i], this.expected(node.armExpected[i]));
|
|
@@ -14495,16 +14920,117 @@ var Encoder = class {
|
|
|
14495
14920
|
kIndex = /* @__PURE__ */ new Map();
|
|
14496
14921
|
ccIndex = /* @__PURE__ */ new Map();
|
|
14497
14922
|
fxIndex = /* @__PURE__ */ new Map();
|
|
14498
|
-
/** Memoized by combinator identity: a shared sub-combinator is ONE row. */
|
|
14499
|
-
memo = /* @__PURE__ */ new Map();
|
|
14500
14923
|
/**
|
|
14501
|
-
*
|
|
14502
|
-
*
|
|
14503
|
-
*
|
|
14504
|
-
*
|
|
14924
|
+
* Memoized by combinator identity AND the trivia scope it is encoded under
|
|
14925
|
+
* (`scopeKey`): a shared sub-combinator is ONE row per scope it runs in.
|
|
14926
|
+
*
|
|
14927
|
+
* A construct's rows depend on that scope. A first set derived through a
|
|
14928
|
+
* nullable term takes in the trivia that may follow it, a gap gate holds only
|
|
14929
|
+
* where no trivia runs, a routed gate reads what may follow its token, and a
|
|
14930
|
+
* cross-rule reference installs its rule's trivia only from a cleared region
|
|
14931
|
+
* (`scopedRef`). One memo slot per combinator froze the FIRST scope it was
|
|
14932
|
+
* reached under onto every later one: a rule body encoded as an entry with no
|
|
14933
|
+
* trivia, then run under a caller's comment trivia, gated its repeats as if no
|
|
14934
|
+
* comment could come between their terms.
|
|
14505
14935
|
*/
|
|
14506
|
-
|
|
14936
|
+
memo = /* @__PURE__ */ new Map();
|
|
14507
14937
|
pending = /* @__PURE__ */ new Map();
|
|
14938
|
+
triviaSignatures = /* @__PURE__ */ new Map();
|
|
14939
|
+
/**
|
|
14940
|
+
* What of the live trivia an encoding can depend on: none, or its first set.
|
|
14941
|
+
* Every derivation reads trivia only through `firstSetOf(trivia)` or whether it
|
|
14942
|
+
* is live, so two scopes whose trivia opens on the same characters encode the
|
|
14943
|
+
* same rows and share them. A construct that reads no scope (`readsScope`)
|
|
14944
|
+
* has one encoding.
|
|
14945
|
+
*/
|
|
14946
|
+
scopeKey(p) {
|
|
14947
|
+
const t = this.activeTrivia;
|
|
14948
|
+
if (!this.readsScope(p)) return "";
|
|
14949
|
+
if (t === void 0) return this.triviaKnown ? "" : "?";
|
|
14950
|
+
let sig = this.triviaSignatures.get(t);
|
|
14951
|
+
if (sig === void 0) {
|
|
14952
|
+
sig = `t${JSON.stringify(firstSetOf(t, /* @__PURE__ */ new Set(), this.refResolver()))}`;
|
|
14953
|
+
this.triviaSignatures.set(t, sig);
|
|
14954
|
+
}
|
|
14955
|
+
return sig;
|
|
14956
|
+
}
|
|
14957
|
+
readsScopeMemo = /* @__PURE__ */ new Map();
|
|
14958
|
+
/**
|
|
14959
|
+
* Can `p`'s rows depend on the trivia scope it is encoded under? No for a
|
|
14960
|
+
* terminal, a scope of its own (`parser({ trivia })`, `noTrivia`, `token()`),
|
|
14961
|
+
* and a wrapper over a construct that reads none; yes wherever a first set, a gate or
|
|
14962
|
+
* a reference's install is derived with the scope: a sequence with a nullable
|
|
14963
|
+
* term before another (the trivia between them), a routed arm (the trivia after
|
|
14964
|
+
* its token), a reference that installs its rule's trivia from a cleared
|
|
14965
|
+
* region, and anything not modelled here — a cycle included.
|
|
14966
|
+
*/
|
|
14967
|
+
readsScope(p) {
|
|
14968
|
+
const hit = this.readsScopeMemo.get(p);
|
|
14969
|
+
if (hit !== void 0) return hit;
|
|
14970
|
+
this.readsScopeMemo.set(p, true);
|
|
14971
|
+
const d = p._def;
|
|
14972
|
+
const rr = this.refResolver();
|
|
14973
|
+
let out;
|
|
14974
|
+
switch (d.tag) {
|
|
14975
|
+
case "literal":
|
|
14976
|
+
case "regex":
|
|
14977
|
+
case "keywords":
|
|
14978
|
+
case "token":
|
|
14979
|
+
out = false;
|
|
14980
|
+
break;
|
|
14981
|
+
// `routed()` encodes its fallback under the scope that reaches it.
|
|
14982
|
+
case "routed":
|
|
14983
|
+
out = d.fallback !== void 0 && this.readsScope(d.fallback);
|
|
14984
|
+
break;
|
|
14985
|
+
case "grammar":
|
|
14986
|
+
out = d.clearTrivia !== true && d.triviaParser === void 0 && this.readsScope(d.parser);
|
|
14987
|
+
break;
|
|
14988
|
+
case "node":
|
|
14989
|
+
case "label":
|
|
14990
|
+
case "leaf":
|
|
14991
|
+
case "transform":
|
|
14992
|
+
case "attempt":
|
|
14993
|
+
case "expect":
|
|
14994
|
+
case "not":
|
|
14995
|
+
case "peek":
|
|
14996
|
+
case "optional":
|
|
14997
|
+
case "many":
|
|
14998
|
+
case "oneOrMore":
|
|
14999
|
+
case "field":
|
|
15000
|
+
out = this.readsScope(d.parser);
|
|
15001
|
+
break;
|
|
15002
|
+
case "sepBy":
|
|
15003
|
+
out = this.readsScope(d.parser) || this.readsScope(d.separator);
|
|
15004
|
+
break;
|
|
15005
|
+
case "choice":
|
|
15006
|
+
out = d.parsers.some((a) => this.readsScope(a));
|
|
15007
|
+
break;
|
|
15008
|
+
case "dispatch":
|
|
15009
|
+
out = this.readsScope(d.selector) || d.cases.some((c) => this.readsScope(c.parser)) || (d.matchers?.some((m) => this.readsScope(m.parser)) ?? false) || d.otherwise !== void 0 && this.readsScope(d.otherwise);
|
|
15010
|
+
break;
|
|
15011
|
+
case "sequence": {
|
|
15012
|
+
const ps = d.parsers;
|
|
15013
|
+
out = ps.some((t) => this.readsScope(t)) || ps[0] !== void 0 && (ps[0]._def.tag === "routed" || ps[0]._def.tag === "regex" && isGap(ps[0])) || ps.some((t, i) => i + 1 < ps.length && matchesEmpty(t, /* @__PURE__ */ new Set(), rr));
|
|
15014
|
+
break;
|
|
15015
|
+
}
|
|
15016
|
+
case "lazy": {
|
|
15017
|
+
let target = winnerForRef(p, rr);
|
|
15018
|
+
if (target === void 0) {
|
|
15019
|
+
try {
|
|
15020
|
+
target = d.thunk();
|
|
15021
|
+
} catch {
|
|
15022
|
+
target = void 0;
|
|
15023
|
+
}
|
|
15024
|
+
}
|
|
15025
|
+
out = target === void 0 || triviaThroughRef(p, target, null) !== null || this.readsScope(target);
|
|
15026
|
+
break;
|
|
15027
|
+
}
|
|
15028
|
+
default:
|
|
15029
|
+
out = true;
|
|
15030
|
+
}
|
|
15031
|
+
this.readsScopeMemo.set(p, out);
|
|
15032
|
+
return out;
|
|
15033
|
+
}
|
|
14508
15034
|
settings;
|
|
14509
15035
|
/** Resolved once, HERE, at table-build time — never consulted at run time. */
|
|
14510
15036
|
track;
|
|
@@ -14522,8 +15048,8 @@ var Encoder = class {
|
|
|
14522
15048
|
/**
|
|
14523
15049
|
* The class of the follow set of term `i` in a sequence — the sync sentinel a
|
|
14524
15050
|
* list nested in that term resyncs to, INFERRED from structure exactly as
|
|
14525
|
-
* `sequence()` (combinators/sequence.ts:58) and
|
|
14526
|
-
*
|
|
15051
|
+
* `sequence()` (combinators/sequence.ts:58) and the source
|
|
15052
|
+
* lowering's `emitSeqValues` infer it: the union of every LATER term's first
|
|
14527
15053
|
* set, not merely up to the first non-nullable one, so a mandatory middle term
|
|
14528
15054
|
* cannot hide a later close. −1 where there is no usable sentinel, which is the
|
|
14529
15055
|
* same set of cases `firstSetSentinel` answers `null` for.
|
|
@@ -14532,7 +15058,7 @@ var Encoder = class {
|
|
|
14532
15058
|
let fs = { kind: "empty" };
|
|
14533
15059
|
const rr = this.refResolver();
|
|
14534
15060
|
for (let j = i + 1; j < parsers.length; j++) {
|
|
14535
|
-
fs = union(fs, firstSetOf(parsers[j], /* @__PURE__ */ new Set(), rr,
|
|
15061
|
+
fs = union(fs, firstSetOf(parsers[j], /* @__PURE__ */ new Set(), rr, void 0, false));
|
|
14536
15062
|
}
|
|
14537
15063
|
return this.charClass(fs);
|
|
14538
15064
|
}
|
|
@@ -14700,7 +15226,7 @@ var Encoder = class {
|
|
|
14700
15226
|
if (op === OP_GATE || op === OP_LIT || op === OP_LIT_CI || op === OP_LIT_TRACK || op === OP_LIT_CI_TRACK || op === OP_RX || op === OP_RX_TRACK) return child;
|
|
14701
15227
|
const rr = this.refResolver();
|
|
14702
15228
|
if (matchesEmpty(p, /* @__PURE__ */ new Set(), rr)) return child;
|
|
14703
|
-
const cls = this.charClass(firstSetOf(p, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
15229
|
+
const cls = this.charClass(firstSetOf(p, /* @__PURE__ */ new Set(), rr, this.activeTrivia, false));
|
|
14704
15230
|
if (cls < 0) return child;
|
|
14705
15231
|
const e = deriveExpected(p);
|
|
14706
15232
|
return this.emit(OP_GATE, cls, child, this.expected(e.length > 0 ? e : [p._tag]));
|
|
@@ -14726,9 +15252,27 @@ var Encoder = class {
|
|
|
14726
15252
|
* `{`, `Call` at `}`). The resolved set is the one a choice arm's gate uses,
|
|
14727
15253
|
* over the final merged map.
|
|
14728
15254
|
*/
|
|
14729
|
-
|
|
15255
|
+
/**
|
|
15256
|
+
* The arms whose first set under `gateTrivia()` is wider than under the
|
|
15257
|
+
* active trivia alone — a reference's installed trivia read through from a
|
|
15258
|
+
* region with none. Empty for construction-set (disjoint) choices, whose
|
|
15259
|
+
* sets do not depend on trivia.
|
|
15260
|
+
*/
|
|
15261
|
+
wideArms(arms, wide, constructionSets, wideTrivia = this.gateTrivia(), base = this.activeTrivia) {
|
|
15262
|
+
if (constructionSets || wideTrivia === base) return [];
|
|
15263
|
+
const narrow = classifyFinalChoice(arms, this.refResolver(), base, false, false).firstSets;
|
|
15264
|
+
const out = [];
|
|
15265
|
+
for (let i = 0; i < arms.length; i++) {
|
|
15266
|
+
if (this.charClass(wide[i]) !== this.charClass(narrow[i])) out.push(i);
|
|
15267
|
+
}
|
|
15268
|
+
return out;
|
|
15269
|
+
}
|
|
15270
|
+
gateFirstSet(p, guarded, narrowed) {
|
|
14730
15271
|
const cached = p._meta.firstSet;
|
|
14731
|
-
|
|
15272
|
+
if (p._def.tag !== "lazy" && cached.kind !== "any") return cached;
|
|
15273
|
+
const rr = this.refResolver();
|
|
15274
|
+
if (guarded) return firstSetOf(p, /* @__PURE__ */ new Set(), rr, void 0, false);
|
|
15275
|
+
return firstSetOf(p, /* @__PURE__ */ new Set(), rr, this.gateTrivia(), narrowed && this.gateConsuming());
|
|
14732
15276
|
}
|
|
14733
15277
|
/**
|
|
14734
15278
|
* Wrap one choice arm in its `autoNot` checks (`OP_REJECT`).
|
|
@@ -14760,6 +15304,135 @@ var Encoder = class {
|
|
|
14760
15304
|
for (const w of words) this.code.push(w);
|
|
14761
15305
|
return ip;
|
|
14762
15306
|
}
|
|
15307
|
+
/**
|
|
15308
|
+
* An optional repeat item tests the item's class before it runs it (`OP_REP`
|
|
15309
|
+
* ip+7), wherever the item's own first-set gate would also run. So a sequence
|
|
15310
|
+
* item whose first term is a gate on that same class gets its own copy of the
|
|
15311
|
+
* sequence row with the gate's child as that term: the test runs once. The
|
|
15312
|
+
* shared row is left as it is for its other references.
|
|
15313
|
+
*/
|
|
15314
|
+
withoutLeadGate(seq, cls) {
|
|
15315
|
+
const op = this.code[seq];
|
|
15316
|
+
if (op !== OP_SEQ && op !== OP_SEQV) return seq;
|
|
15317
|
+
const first = this.code[seq + 2];
|
|
15318
|
+
if (this.code[first] !== OP_GATE || this.code[first + 1] !== cls) return seq;
|
|
15319
|
+
const n = this.code[seq + 1];
|
|
15320
|
+
const width = 1 + 2 * n;
|
|
15321
|
+
const head = this.emitHead(op, width);
|
|
15322
|
+
for (let i = 1; i <= width; i++) this.code[head + i] = this.code[seq + i];
|
|
15323
|
+
this.code[head + 2] = this.code[first + 2];
|
|
15324
|
+
return head;
|
|
15325
|
+
}
|
|
15326
|
+
/**
|
|
15327
|
+
* An optional repeat item that opens with a GAP — a regex that may match
|
|
15328
|
+
* empty, or one that starts only with whitespace or a comment's `/` — and
|
|
15329
|
+
* then a term with a finite first set gets an `OP_GAPGATE` row
|
|
15330
|
+
* (`gap-gate.ts`): the repeat reads the gap once, ends where the character
|
|
15331
|
+
* after it opens neither that term nor an arm without the gap, and hands the
|
|
15332
|
+
* gap's end to the regex row. Anything the walk cannot prove keeps the item as
|
|
15333
|
+
* written.
|
|
15334
|
+
*/
|
|
15335
|
+
gapGated(item, ip) {
|
|
15336
|
+
if (this.activeTrivia === void 0 && !this.triviaKnown) return ip;
|
|
15337
|
+
const lead2 = this.gapLead(item, this.activeTrivia, 0);
|
|
15338
|
+
if (lead2 === void 0) return ip;
|
|
15339
|
+
const cls = this.charClass(lead2.follow);
|
|
15340
|
+
if (cls < 0) return ip;
|
|
15341
|
+
const other = lead2.other.kind === "empty" ? -1 : this.charClass(lead2.other);
|
|
15342
|
+
if (lead2.other.kind !== "empty" && other < 0) return ip;
|
|
15343
|
+
const p = this.node(lead2.p).ip;
|
|
15344
|
+
if (this.code[p] !== OP_RX && this.code[p] !== OP_RX_TRACK) return ip;
|
|
15345
|
+
return this.emit(OP_GAPGATE, ip, p, cls, other);
|
|
15346
|
+
}
|
|
15347
|
+
/**
|
|
15348
|
+
* The gap an item opens with: the regex `p`, the first set `follow` of what
|
|
15349
|
+
* must come straight after it, and the first set `other` of choice arms that
|
|
15350
|
+
* do not open with `p`. Only through wrappers that consume nothing before
|
|
15351
|
+
* their body, a sequence's first term, and a choice's arms; the gap must sit
|
|
15352
|
+
* in a sequence with no trivia between its terms.
|
|
15353
|
+
*/
|
|
15354
|
+
gapLead(c, trivia2, depth) {
|
|
15355
|
+
if (depth > 24) return void 0;
|
|
15356
|
+
const rr = this.refResolver();
|
|
15357
|
+
const d = c._def;
|
|
15358
|
+
switch (d.tag) {
|
|
15359
|
+
case "lazy": {
|
|
15360
|
+
let target = winnerForRef(c, rr);
|
|
15361
|
+
if (target === void 0) {
|
|
15362
|
+
try {
|
|
15363
|
+
target = d.thunk();
|
|
15364
|
+
} catch {
|
|
15365
|
+
return void 0;
|
|
15366
|
+
}
|
|
15367
|
+
}
|
|
15368
|
+
return this.gapLead(target, triviaThroughRef(c, target, trivia2), depth + 1);
|
|
15369
|
+
}
|
|
15370
|
+
case "node":
|
|
15371
|
+
case "leaf":
|
|
15372
|
+
case "label":
|
|
15373
|
+
case "attempt":
|
|
15374
|
+
return this.gapLead(d.parser, trivia2, depth + 1);
|
|
15375
|
+
case "field":
|
|
15376
|
+
return d.leadingTrivia === true ? void 0 : this.gapLead(d.parser, trivia2, depth + 1);
|
|
15377
|
+
case "grammar":
|
|
15378
|
+
return this.gapLead(d.parser, d.clearTrivia === true ? null : d.triviaParser ?? trivia2, depth + 1);
|
|
15379
|
+
case "sequence": {
|
|
15380
|
+
const [first, ...rest] = d.parsers;
|
|
15381
|
+
if (first === void 0) return void 0;
|
|
15382
|
+
if (first._def.tag !== "regex" || !isGap(first)) {
|
|
15383
|
+
return this.gapLead(first, trivia2, depth + 1);
|
|
15384
|
+
}
|
|
15385
|
+
if (trivia2 !== void 0 && trivia2 !== null || rest.length === 0) return void 0;
|
|
15386
|
+
let follow = empty();
|
|
15387
|
+
let closed = false;
|
|
15388
|
+
for (const t of rest) {
|
|
15389
|
+
const fs = firstSetOf(t, /* @__PURE__ */ new Set(), rr, null);
|
|
15390
|
+
if (fs.kind === "any") return void 0;
|
|
15391
|
+
follow = union(follow, fs);
|
|
15392
|
+
if (!matchesEmpty(t, /* @__PURE__ */ new Set(), rr)) {
|
|
15393
|
+
closed = true;
|
|
15394
|
+
break;
|
|
15395
|
+
}
|
|
15396
|
+
}
|
|
15397
|
+
return closed ? { p: first, follow, other: empty() } : void 0;
|
|
15398
|
+
}
|
|
15399
|
+
case "choice": {
|
|
15400
|
+
let p;
|
|
15401
|
+
let follow = empty();
|
|
15402
|
+
let other = empty();
|
|
15403
|
+
for (const arm of d.parsers) {
|
|
15404
|
+
const lead2 = this.gapLead(arm, trivia2, depth + 1);
|
|
15405
|
+
if (lead2 !== void 0 && (p === void 0 || lead2.p === p)) {
|
|
15406
|
+
p = lead2.p;
|
|
15407
|
+
follow = union(follow, lead2.follow);
|
|
15408
|
+
other = union(other, lead2.other);
|
|
15409
|
+
continue;
|
|
15410
|
+
}
|
|
15411
|
+
if (matchesEmpty(arm, /* @__PURE__ */ new Set(), rr)) return void 0;
|
|
15412
|
+
const fs = firstSetOf(arm, /* @__PURE__ */ new Set(), rr, trivia2 ?? null);
|
|
15413
|
+
if (fs.kind === "any") return void 0;
|
|
15414
|
+
other = union(other, fs);
|
|
15415
|
+
}
|
|
15416
|
+
return p === void 0 ? void 0 : { p, follow, other };
|
|
15417
|
+
}
|
|
15418
|
+
default:
|
|
15419
|
+
return void 0;
|
|
15420
|
+
}
|
|
15421
|
+
}
|
|
15422
|
+
/**
|
|
15423
|
+
* The class a strict list may end on — a character its separator `p` (row
|
|
15424
|
+
* `ip`) cannot start — without entering the separator, or −1.
|
|
15425
|
+
*
|
|
15426
|
+
* The test runs before every separator, to save the one that fails at the
|
|
15427
|
+
* list's end, so it is laid down only where entering the separator costs more
|
|
15428
|
+
* than the test: not on a terminal row, which is itself one character test.
|
|
15429
|
+
*/
|
|
15430
|
+
sepGate(p, ip) {
|
|
15431
|
+
const op = this.code[ip];
|
|
15432
|
+
if (op === OP_LIT || op === OP_LIT_CI || op === OP_RX || op === OP_LIT_TRACK || op === OP_RX_TRACK || op === OP_LIT_CI_TRACK) return -1;
|
|
15433
|
+
if (matchesEmpty(p, /* @__PURE__ */ new Set(), this.refResolver())) return -1;
|
|
15434
|
+
return this.charClass(firstSetOf(p, /* @__PURE__ */ new Set(), this.refResolver(), this.gateTrivia(), this.gateConsuming()));
|
|
15435
|
+
}
|
|
14763
15436
|
/** Reserve `n` operand slots to patch once children are laid out. */
|
|
14764
15437
|
emitHead(op, n) {
|
|
14765
15438
|
const ip = this.code.length;
|
|
@@ -14803,8 +15476,10 @@ var Encoder = class {
|
|
|
14803
15476
|
}
|
|
14804
15477
|
encodeRule(name, p) {
|
|
14805
15478
|
this.activeTrivia = p._meta.grammarTrivia;
|
|
15479
|
+
this.triviaKnown = p._meta.grammarTrivia !== void 0;
|
|
14806
15480
|
const body = this.node(p).ip;
|
|
14807
15481
|
this.activeTrivia = void 0;
|
|
15482
|
+
this.triviaKnown = true;
|
|
14808
15483
|
const gss = p._meta.grammarScanSkip;
|
|
14809
15484
|
this.scanSkipOf.push(gss === void 0 ? -1 : this.scanSkipSlot(gss));
|
|
14810
15485
|
const amb = p._meta.grammarTrivia;
|
|
@@ -14850,11 +15525,15 @@ var Encoder = class {
|
|
|
14850
15525
|
* silently produced the ONE keyword `bc`.
|
|
14851
15526
|
*/
|
|
14852
15527
|
scopedRef(p, target) {
|
|
15528
|
+
const runsUnder = triviaThroughRef(p, target, this.activeTrivia);
|
|
15529
|
+
if (this.activeTrivia !== void 0 || runsUnder === void 0 || runsUnder === null) return this.node(target).ip;
|
|
15530
|
+
const savedKnown = this.triviaKnown;
|
|
15531
|
+
this.activeTrivia = runsUnder;
|
|
15532
|
+
this.triviaKnown = true;
|
|
14853
15533
|
const ip = this.node(target).ip;
|
|
14854
|
-
|
|
14855
|
-
|
|
14856
|
-
|
|
14857
|
-
return this.emit(OP_SCOPE_PLAIN, this.triviaSlot(amb), ip);
|
|
15534
|
+
this.activeTrivia = void 0;
|
|
15535
|
+
this.triviaKnown = savedKnown;
|
|
15536
|
+
return this.emit(OP_SCOPE_PLAIN, this.triviaSlot(runsUnder), ip);
|
|
14858
15537
|
}
|
|
14859
15538
|
/**
|
|
14860
15539
|
* The `OP_RGATE` operands of a choice arm that opens with `routed()`, or
|
|
@@ -14895,38 +15574,43 @@ var Encoder = class {
|
|
|
14895
15574
|
if (matchesEmpty(next, /* @__PURE__ */ new Set(), rr) || mayCommitFailure(next, rr, this.commitFailureMemo)) return void 0;
|
|
14896
15575
|
const nextDef = next._def;
|
|
14897
15576
|
if (nextDef.tag !== "literal" && nextDef.tag !== "regex" && nextDef.tag !== "keywords" && nextDef.tag !== "label") return void 0;
|
|
14898
|
-
|
|
15577
|
+
if (boundary === void 0 && !this.triviaKnown) return void 0;
|
|
15578
|
+
const first = firstSetOf(next, /* @__PURE__ */ new Set(), rr, boundary ?? null);
|
|
14899
15579
|
const cls = this.charClass(boundary === void 0 ? first : union(first, firstSetOf(boundary, /* @__PURE__ */ new Set(), rr)));
|
|
14900
15580
|
if (cls < 0) return void 0;
|
|
14901
|
-
const
|
|
14902
|
-
|
|
15581
|
+
const fx = this.expected(nextDef.tag === "label" ? deriveExpected(next) : directTerminalFailureExpected(nextDef));
|
|
15582
|
+
const two = firstTwo(next);
|
|
15583
|
+
if (two === void 0) return { cls, fx };
|
|
15584
|
+
if (boundary !== void 0 && intersects(two.first, firstSetOf(boundary, /* @__PURE__ */ new Set(), rr))) return { cls, fx };
|
|
15585
|
+
const a = this.charClass(two.first);
|
|
15586
|
+
const b = this.charClass(two.second);
|
|
15587
|
+
return a < 0 || b < 0 ? { cls, fx } : { cls, fx, two: [a, b] };
|
|
14903
15588
|
}
|
|
14904
15589
|
node(p) {
|
|
14905
|
-
const
|
|
14906
|
-
|
|
14907
|
-
const
|
|
14908
|
-
const hit = lazyRef ? refMemo.get(p)?.get(scopeKey) : this.memo.get(p);
|
|
15590
|
+
const key = this.scopeKey(p);
|
|
15591
|
+
let byScope = this.memo.get(p);
|
|
15592
|
+
const hit = byScope?.get(key);
|
|
14909
15593
|
if (hit !== void 0) return { ip: hit };
|
|
14910
|
-
|
|
15594
|
+
let inFlightByScope = this.pending.get(p);
|
|
15595
|
+
const inFlight = inFlightByScope?.get(key);
|
|
14911
15596
|
if (inFlight !== void 0) {
|
|
14912
15597
|
const ip2 = this.emitHead(OP_RULE, 1);
|
|
14913
15598
|
inFlight.push(ip2 + 1);
|
|
14914
15599
|
return { ip: ip2 };
|
|
14915
15600
|
}
|
|
14916
15601
|
const patches = [];
|
|
14917
|
-
|
|
15602
|
+
if (inFlightByScope === void 0) {
|
|
15603
|
+
inFlightByScope = /* @__PURE__ */ new Map();
|
|
15604
|
+
this.pending.set(p, inFlightByScope);
|
|
15605
|
+
}
|
|
15606
|
+
inFlightByScope.set(key, patches);
|
|
14918
15607
|
const ip = this.covWrap(this.encodeDef(p), this.plan?.rules.get(p), 0);
|
|
14919
|
-
|
|
14920
|
-
if (
|
|
14921
|
-
|
|
14922
|
-
|
|
14923
|
-
byScope = /* @__PURE__ */ new Map();
|
|
14924
|
-
refMemo.set(p, byScope);
|
|
14925
|
-
}
|
|
14926
|
-
byScope.set(scopeKey, ip);
|
|
14927
|
-
} else {
|
|
14928
|
-
this.memo.set(p, ip);
|
|
15608
|
+
inFlightByScope.delete(key);
|
|
15609
|
+
if (byScope === void 0) {
|
|
15610
|
+
byScope = /* @__PURE__ */ new Map();
|
|
15611
|
+
this.memo.set(p, byScope);
|
|
14929
15612
|
}
|
|
15613
|
+
byScope.set(key, ip);
|
|
14930
15614
|
for (const slot of patches) {
|
|
14931
15615
|
if (slot - 1 === ip) {
|
|
14932
15616
|
const rule = p._ruleName;
|
|
@@ -15024,8 +15708,19 @@ var Encoder = class {
|
|
|
15024
15708
|
}
|
|
15025
15709
|
case "choice": {
|
|
15026
15710
|
if (this.plan === void 0) {
|
|
15027
|
-
const
|
|
15028
|
-
if (
|
|
15711
|
+
const shared = factorSharedEnds(d);
|
|
15712
|
+
if (shared !== void 0) return this.node(shared).ip;
|
|
15713
|
+
if (this.unfactoredChoice !== p) {
|
|
15714
|
+
const prefix = factorPrefixArms(d);
|
|
15715
|
+
if (prefix !== void 0) {
|
|
15716
|
+
const strict = this.node(prefix).ip;
|
|
15717
|
+
const saved = this.unfactoredChoice;
|
|
15718
|
+
this.unfactoredChoice = p;
|
|
15719
|
+
const tolerant = this.encodeDef(p);
|
|
15720
|
+
this.unfactoredChoice = saved;
|
|
15721
|
+
return this.emit(OP_STRICT, strict, tolerant);
|
|
15722
|
+
}
|
|
15723
|
+
}
|
|
15029
15724
|
}
|
|
15030
15725
|
if (d.strategy.tag === "greedyClassify") {
|
|
15031
15726
|
const superIndex = d.strategy.superIndex;
|
|
@@ -15054,18 +15749,20 @@ var Encoder = class {
|
|
|
15054
15749
|
const plain = (checks === null || checks === void 0 || checks.length === 0) && (gate === null || gate === void 0);
|
|
15055
15750
|
const routedGate = plain ? this.routedArmGate(c) : void 0;
|
|
15056
15751
|
const body = this.node(c).ip;
|
|
15057
|
-
const inner = routedGate === void 0 ? body : this.emit(OP_RGATE, routedGate.cls, body, routedGate.fx);
|
|
15752
|
+
const inner = routedGate === void 0 ? body : routedGate.two === void 0 ? this.emit(OP_RGATE, routedGate.cls, body, routedGate.fx) : this.emit(OP_RGATE2, routedGate.cls, body, routedGate.fx, routedGate.two[0], routedGate.two[1]);
|
|
15058
15753
|
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
15059
15754
|
const gated = gate === null || gate === void 0 ? ip : this.emit(OP_ARMGATE, this.fn(gate, d.gateSrcs?.[src] ?? null), ip, this.expected(deriveExpected(c)));
|
|
15060
15755
|
return this.covWrap(gated, armCovIds?.[src], 1);
|
|
15061
15756
|
});
|
|
15062
15757
|
const rr = this.refResolver();
|
|
15063
|
-
const
|
|
15758
|
+
const constructionSets = d.disjoint && !factoredChoices.has(p);
|
|
15759
|
+
const finalChoice = classifyFinalChoice(arms, rr, this.gateTrivia(), false, constructionSets);
|
|
15760
|
+
const wideArms = this.wideArms(arms, finalChoice.firstSets, constructionSets);
|
|
15064
15761
|
const transactionalFirst = arms.map((arm, i) => {
|
|
15065
15762
|
if (!finalChoice.nullable[i]) return void 0;
|
|
15066
15763
|
const def = arm._def;
|
|
15067
15764
|
if (def.tag !== "attempt" || matchesEmpty(def.parser, /* @__PURE__ */ new Set(), rr)) return void 0;
|
|
15068
|
-
return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia);
|
|
15765
|
+
return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia, false);
|
|
15069
15766
|
});
|
|
15070
15767
|
const gateFirst = finalChoice.firstSets.map((first, i) => transactionalFirst[i] ?? first);
|
|
15071
15768
|
const classes = gateFirst.map((first, i) => finalChoice.nullable[i] && transactionalFirst[i] === void 0 ? -1 : this.charClass(first));
|
|
@@ -15083,6 +15780,9 @@ var Encoder = class {
|
|
|
15083
15780
|
if (transactionalFirst[i] !== void 0) classes[i] = -1;
|
|
15084
15781
|
}
|
|
15085
15782
|
}
|
|
15783
|
+
if (wideArms.length > 0 && dispatchIsExclusive(classes, this.cc)) {
|
|
15784
|
+
for (const i of wideArms) classes[i] = -1;
|
|
15785
|
+
}
|
|
15086
15786
|
if (d.gates.some((g) => g !== null && g !== void 0) && !dispatchIsExclusive(classes, this.cc)) {
|
|
15087
15787
|
for (let k = 0; k < classes.length; k++) {
|
|
15088
15788
|
const gate = d.gates[order[k]];
|
|
@@ -15116,27 +15816,34 @@ var Encoder = class {
|
|
|
15116
15816
|
}
|
|
15117
15817
|
case "many":
|
|
15118
15818
|
case "oneOrMore": {
|
|
15119
|
-
const child = this.node(d.parser).ip;
|
|
15120
15819
|
const rr = this.refResolver();
|
|
15121
|
-
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.charClass(
|
|
15820
|
+
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.charClass(this.gateFirstSet(d.parser, d.guarded === true, true));
|
|
15122
15821
|
const op = d.valueUnused ? OP_REPV : OP_REP;
|
|
15123
15822
|
const min = d.tag === "many" ? 0 : d.min;
|
|
15823
|
+
const item = min === 0 && itemClass >= 0 ? this.withoutLeadGate(this.node(d.parser).ip, itemClass) : this.node(d.parser).ip;
|
|
15824
|
+
const child = min === 0 && itemClass >= 0 ? this.gapGated(d.parser, item) : item;
|
|
15124
15825
|
return this.emit(op, child, min, d.max ?? -1, -1, 0, this.expected(deriveExpected(d.parser)), itemClass);
|
|
15125
15826
|
}
|
|
15126
15827
|
case "sepBy": {
|
|
15127
15828
|
const child = this.node(d.parser).ip;
|
|
15128
15829
|
const sep = this.node(d.separator).ip;
|
|
15129
|
-
const
|
|
15130
|
-
|
|
15131
|
-
|
|
15830
|
+
const gate = this.sepGate(d.separator, sep);
|
|
15831
|
+
const itemSet = deriveExpected(d.parser);
|
|
15832
|
+
const itemFx = this.expected(itemSet.length > 0 ? itemSet : [d.parser._tag]);
|
|
15833
|
+
const flags = (d.trailing === "allow" ? 1 : 0) | (d.keepSeparators === true ? 2 : 0) | (d.min >= 1 ? 4 : 0) | (gate >= 0 ? 8 : 0) | (itemSet.length === 0 ? 16 : 0);
|
|
15834
|
+
const ops = [
|
|
15132
15835
|
child,
|
|
15133
15836
|
d.min,
|
|
15134
15837
|
d.max ?? -1,
|
|
15135
15838
|
sep,
|
|
15136
15839
|
flags,
|
|
15137
|
-
|
|
15138
|
-
|
|
15139
|
-
|
|
15840
|
+
itemFx,
|
|
15841
|
+
// As 0.58.0: the interpreter resyncs on the separator itself
|
|
15842
|
+
// (`orSentinel`), which runs under the live trivia.
|
|
15843
|
+
this.charClass(firstSetOf(d.separator, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia, false))
|
|
15844
|
+
];
|
|
15845
|
+
if (gate >= 0) ops.push(gate);
|
|
15846
|
+
return this.emit(OP_REP, ...ops);
|
|
15140
15847
|
}
|
|
15141
15848
|
case "optional": {
|
|
15142
15849
|
const head = this.emit(OP_OPT, this.lookaheadGate(d.parser, this.node(d.parser).ip));
|
|
@@ -15145,7 +15852,7 @@ var Encoder = class {
|
|
|
15145
15852
|
}
|
|
15146
15853
|
case "transform": {
|
|
15147
15854
|
const inner = d.parser._def;
|
|
15148
|
-
if (inner.tag === "sequence" && !this.memo.has(d.parser) && !this.pending.has(d.parser)) {
|
|
15855
|
+
if (inner.tag === "sequence" && !this.memo.get(d.parser)?.has(this.scopeKey(d.parser)) && !this.pending.get(d.parser)?.has(this.scopeKey(d.parser))) {
|
|
15149
15856
|
const kids = inner.parsers.map((c) => this.node(c).ip);
|
|
15150
15857
|
const head = this.emitHead(OP_SEQX, 2 + 2 * kids.length);
|
|
15151
15858
|
const projection = directArrayProjection(d.fn, d.fnSrc, kids.length);
|
|
@@ -15186,7 +15893,7 @@ var Encoder = class {
|
|
|
15186
15893
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
15187
15894
|
);
|
|
15188
15895
|
if (matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return body;
|
|
15189
|
-
const fs = this.gateFirstSet(d.parser);
|
|
15896
|
+
const fs = this.gateFirstSet(d.parser, d.guarded === true, false);
|
|
15190
15897
|
if (fs.kind === "any") return body;
|
|
15191
15898
|
const cls = this.charClass(fs);
|
|
15192
15899
|
if (cls < 0) return body;
|
|
@@ -15194,7 +15901,14 @@ var Encoder = class {
|
|
|
15194
15901
|
return this.emit(OP_GATE, cls, body, this.expected(e.length > 0 ? e : [d.parser._tag]));
|
|
15195
15902
|
}
|
|
15196
15903
|
case "token": {
|
|
15197
|
-
|
|
15904
|
+
const saved = this.activeTrivia;
|
|
15905
|
+
const savedKnown = this.triviaKnown;
|
|
15906
|
+
this.activeTrivia = void 0;
|
|
15907
|
+
this.triviaKnown = true;
|
|
15908
|
+
const body = this.node(d.parser).ip;
|
|
15909
|
+
this.activeTrivia = saved;
|
|
15910
|
+
this.triviaKnown = savedKnown;
|
|
15911
|
+
return this.emit(OP_TOKEN, body);
|
|
15198
15912
|
}
|
|
15199
15913
|
case "routed":
|
|
15200
15914
|
return this.emit(OP_ROUTED, d.fallback === void 0 ? -1 : this.node(d.fallback).ip);
|
|
@@ -15250,7 +15964,7 @@ var Encoder = class {
|
|
|
15250
15964
|
this.code[head + 2] = dspIdx;
|
|
15251
15965
|
this.code[head + 3] = other;
|
|
15252
15966
|
const otherRouted = d.otherwise === void 0 ? false : branchUsesRouted({ parser: d.otherwise, usesRouted: d.otherwiseUsesRouted === true });
|
|
15253
|
-
this.code[head + 4] = otherRouted ? 1 : 0;
|
|
15967
|
+
this.code[head + 4] = (otherRouted ? 1 : 0) | (d.otherwiseCommit === false ? 2 : 0);
|
|
15254
15968
|
this.code[head + 5] = arms.length;
|
|
15255
15969
|
for (let i = 0; i < arms.length; i++) this.code[head + 6 + i] = arms[i];
|
|
15256
15970
|
return head;
|
|
@@ -15305,7 +16019,7 @@ var Encoder = class {
|
|
|
15305
16019
|
case "attempt": {
|
|
15306
16020
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
|
|
15307
16021
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
15308
|
-
const fs = this.gateFirstSet(d.parser);
|
|
16022
|
+
const fs = this.gateFirstSet(d.parser, d.guarded === true, false);
|
|
15309
16023
|
if (fs.kind === "any" || matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return inner;
|
|
15310
16024
|
const cls = this.charClass(fs);
|
|
15311
16025
|
if (cls < 0) return inner;
|
|
@@ -15314,7 +16028,7 @@ var Encoder = class {
|
|
|
15314
16028
|
}
|
|
15315
16029
|
// A LABEL IS A ROW — see `OP_LABEL`. It replaces the child's expected set,
|
|
15316
16030
|
// which is the entire combinator.
|
|
15317
|
-
// A LABEL IS CREDITED ON SUCCESS, as
|
|
16031
|
+
// A LABEL IS CREDITED ON SUCCESS, as the source lowering credited it: its hook
|
|
15318
16032
|
// is emitted AFTER the child's statements, where a failed child has already
|
|
15319
16033
|
// broken out of the labelled block.
|
|
15320
16034
|
case "label":
|
|
@@ -15331,10 +16045,17 @@ var Encoder = class {
|
|
|
15331
16045
|
const op = cap ? OP_SCOPE_CAP : OP_SCOPE;
|
|
15332
16046
|
const flags = (d.rootCapture === "opaque" ? 1 : 0) | (d.triviaParser !== void 0 && d.triviaParser._meta.rootTriviaClassified !== true && d.rootCapture !== "opaque" ? 2 : 0);
|
|
15333
16047
|
const savedTrivia = this.activeTrivia;
|
|
15334
|
-
|
|
15335
|
-
|
|
16048
|
+
const savedKnown = this.triviaKnown;
|
|
16049
|
+
if (d.clearTrivia === true) {
|
|
16050
|
+
this.activeTrivia = void 0;
|
|
16051
|
+
this.triviaKnown = true;
|
|
16052
|
+
} else if (d.triviaParser !== void 0) {
|
|
16053
|
+
this.activeTrivia = d.triviaParser;
|
|
16054
|
+
this.triviaKnown = true;
|
|
16055
|
+
}
|
|
15336
16056
|
const bodyIp = this.node(d.parser).ip;
|
|
15337
16057
|
this.activeTrivia = savedTrivia;
|
|
16058
|
+
this.triviaKnown = savedKnown;
|
|
15338
16059
|
if (d.clearTrivia === true) return this.emit(op, -1, bodyIp, flags);
|
|
15339
16060
|
if (d.triviaParser === void 0) {
|
|
15340
16061
|
return cap || flags !== 0 ? this.emit(op, -1, bodyIp, flags) : bodyIp;
|
|
@@ -15375,6 +16096,7 @@ var Encoder = class {
|
|
|
15375
16096
|
switch (this.code[ip]) {
|
|
15376
16097
|
case OP_GATE:
|
|
15377
16098
|
case OP_RGATE:
|
|
16099
|
+
case OP_RGATE2:
|
|
15378
16100
|
return [ip + 2];
|
|
15379
16101
|
case OP_RULE:
|
|
15380
16102
|
case OP_OPT:
|
|
@@ -15384,6 +16106,7 @@ var Encoder = class {
|
|
|
15384
16106
|
case OP_ATTEMPT:
|
|
15385
16107
|
case OP_LABEL:
|
|
15386
16108
|
case OP_COV:
|
|
16109
|
+
case OP_GAPGATE:
|
|
15387
16110
|
return [ip + 1];
|
|
15388
16111
|
case OP_SCOPE:
|
|
15389
16112
|
case OP_SCOPE_CAP:
|
|
@@ -15420,6 +16143,8 @@ var Encoder = class {
|
|
|
15420
16143
|
case OP_REP:
|
|
15421
16144
|
case OP_REPV:
|
|
15422
16145
|
return this.code[ip + 4] >= 0 ? [ip + 1, ip + 4] : [ip + 1];
|
|
16146
|
+
case OP_STRICT:
|
|
16147
|
+
return [ip + 1, ip + 2];
|
|
15423
16148
|
default:
|
|
15424
16149
|
return [];
|
|
15425
16150
|
}
|
|
@@ -15536,11 +16261,8 @@ function encodeTableProgram(ruleMap, settings = {}) {
|
|
|
15536
16261
|
return { prog, fnSrcs: enc.fnSrcs };
|
|
15537
16262
|
}
|
|
15538
16263
|
|
|
15539
|
-
// src/version.ts
|
|
15540
|
-
var PARSEMAN_VERSION = "0.59.2";
|
|
15541
|
-
|
|
15542
16264
|
// src/table/emit.ts
|
|
15543
|
-
var FACTORY_ARITY_GUARD = `if(arguments.length
|
|
16265
|
+
var FACTORY_ARITY_GUARD = `if(arguments.length!==${EMITTED_PARAMS.length})throw new Error(${JSON.stringify(`parseman: this parser was printed by parseman ${PARSEMAN_VERSION}; run it on parseman ${PARSEMAN_VERSION} or reprint it`)});`;
|
|
15544
16266
|
function jsString(s) {
|
|
15545
16267
|
return JSON.stringify(s);
|
|
15546
16268
|
}
|
|
@@ -15626,7 +16348,7 @@ function emitAssemblies(prog, cfgs) {
|
|
|
15626
16348
|
throw e;
|
|
15627
16349
|
}
|
|
15628
16350
|
const plan = em.plan;
|
|
15629
|
-
out.push(`{key:${key},factory:function(${EMITTED_PARAMS.join(",")}){${FACTORY_ARITY_GUARD}${em.source}
|
|
16351
|
+
out.push(`{key:${key},arity:${EMITTED_PARAMS.length},factory:function(${EMITTED_PARAMS.join(",")}){${FACTORY_ARITY_GUARD}${em.source}
|
|
15630
16352
|
},plan:{classes:[${plan.classes.map((r) => `[${r.join(",")}]`).join(",")}],armExpected:[${plan.armExpected.map((r) => `[${r.join(",")}]`).join(",")}],masks:[${plan.masks.join(",")}]},reached:[${[...em.reached].join(",")}]}`);
|
|
15631
16353
|
}
|
|
15632
16354
|
return [`a:[${out.join(",")}],`];
|
|
@@ -15928,7 +16650,7 @@ function payloadKey(p, d) {
|
|
|
15928
16650
|
case "sepBy":
|
|
15929
16651
|
return `sepBy\0${d.min}\0${d.max ?? ""}\0${d.trailing ?? ""}`;
|
|
15930
16652
|
case "dispatch":
|
|
15931
|
-
return `dispatch\0${d.cases.map((c) => JSON.stringify(c.keys)).join("")}\0${d.otherwise !== void 0}`;
|
|
16653
|
+
return `dispatch\0${d.cases.map((c) => JSON.stringify(c.keys)).join("")}\0${d.otherwise !== void 0}${d.otherwiseCommit === false ? "\0uncommitted" : ""}`;
|
|
15932
16654
|
case "expect":
|
|
15933
16655
|
return `expect\0${d.label ?? ""}\0${d.expected.join("")}`;
|
|
15934
16656
|
case "scanTo":
|
|
@@ -17340,7 +18062,10 @@ function staticWeights(code, entries) {
|
|
|
17340
18062
|
childSlots(code, ip, kids);
|
|
17341
18063
|
const op = code[ip];
|
|
17342
18064
|
const scale = op === OP_REP || op === OP_REPV ? LOOP : op === OP_CHOICE || op === OP_DISPATCH ? 1 / Math.max(1, kids.length) : 1;
|
|
17343
|
-
for (const
|
|
18065
|
+
for (const k of kids) {
|
|
18066
|
+
const kid = code[k] === OP_GAPGATE ? code[k + 1] : k;
|
|
18067
|
+
next.set(kid, Math.min(CAP, (next.get(kid) ?? 0) + w * scale));
|
|
18068
|
+
}
|
|
17344
18069
|
}
|
|
17345
18070
|
weight = next;
|
|
17346
18071
|
}
|
|
@@ -17457,7 +18182,7 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
17457
18182
|
const roots = assemblyExtraIps(artifact);
|
|
17458
18183
|
let siteBytes, fixed;
|
|
17459
18184
|
try {
|
|
17460
|
-
siteBytes = emitAssemblySource(table, artifact, cfg, roots, true, void 0, true).siteBytes;
|
|
18185
|
+
siteBytes = emitAssemblySource(table, artifact, cfg, roots, true, void 0, true, true).siteBytes;
|
|
17461
18186
|
fixed = emitAssemblySource(table, artifact, cfg, roots, true, /* @__PURE__ */ new Set(), true).source.length;
|
|
17462
18187
|
} catch (e) {
|
|
17463
18188
|
if (e instanceof Unemittable) return { ...none, refusal: e.construct };
|