parseman 0.55.3 → 0.56.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/choice-cost.d.ts.map +1 -1
- package/dist/analysis/commitment.d.ts.map +1 -1
- package/dist/analysis/diagnostics.js +3360 -3098
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/analysis/duplication.d.ts.map +1 -1
- package/dist/analysis/gating.d.ts.map +1 -1
- package/dist/cli/index.js +1820 -1558
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/attempt.d.ts.map +1 -1
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/combinators/lines.d.ts +79 -0
- package/dist/combinators/lines.d.ts.map +1 -0
- package/dist/combinators/trivia-skip.d.ts +1 -0
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/fields.d.ts.map +1 -1
- package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +25 -0
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/coverage.d.ts.map +1 -1
- package/dist/cst/reflection.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1912 -1628
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +2 -0
- package/dist/language-service/index.js.map +1 -1
- package/dist/parse-context.d.ts.map +1 -1
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.js +1325 -1048
- package/dist/plugin/index.js.map +3 -3
- package/dist/plugin/ir-eval.d.ts +0 -4
- package/dist/plugin/ir-eval.d.ts.map +1 -1
- package/dist/run/index.js +2 -0
- package/dist/run/index.js.map +1 -1
- package/dist/spec/index.js +15 -0
- package/dist/spec/index.js.map +1 -1
- package/dist/spec/model.d.ts.map +1 -1
- package/dist/table/assemble.d.ts +0 -65
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/index.js +3449 -3195
- package/dist/table/index.js.map +3 -3
- package/dist/table/line-scan.d.ts +9 -0
- package/dist/table/line-scan.d.ts.map +1 -0
- package/dist/table/program.d.ts +11 -2
- package/dist/table/program.d.ts.map +1 -1
- package/dist/types.d.ts +26 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/analysis/choice-cost.ts +1 -0
- package/src/analysis/commitment.ts +13 -0
- package/src/analysis/duplication.ts +3 -0
- package/src/analysis/gating.ts +5 -0
- package/src/analysis/rebuild.ts +2 -2
- package/src/combinators/attempt.ts +2 -0
- package/src/combinators/choice.ts +3 -0
- package/src/combinators/dispatch.ts +3 -0
- package/src/combinators/expect.ts +5 -0
- package/src/combinators/first-set.ts +9 -1
- package/src/combinators/lines.ts +244 -0
- package/src/combinators/trivia-skip.ts +4 -2
- package/src/compiler/fields.ts +3 -0
- package/src/compiler/grammar-coverage-ids.ts +1 -0
- package/src/compiler/ir-serialize.ts +10 -0
- package/src/compiler/token-alphabet.ts +3 -1
- package/src/coverage.ts +6 -0
- package/src/cst/reflection.ts +3 -0
- package/src/index.ts +2 -0
- package/src/parse-context.ts +2 -0
- package/src/plugin/evaluator.ts +4 -0
- package/src/plugin/ir-eval.ts +3 -0
- package/src/spec/model.ts +15 -0
- package/src/table/assemble.ts +10 -13
- package/src/table/compile.ts +5 -2
- package/src/table/emit.ts +7 -6
- package/src/table/encode.ts +18 -6
- package/src/table/exec.ts +7 -1
- package/src/table/line-scan.ts +19 -0
- package/src/table/program.ts +17 -2
- package/src/types.ts +19 -1
- package/src/version.ts +1 -1
package/dist/plugin/index.js
CHANGED
|
@@ -163,6 +163,11 @@ function matchesEmptyBody(p, seen, resolve3) {
|
|
|
163
163
|
return true;
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
+
// A run consumes at least its first line's prefix, and its body after that.
|
|
167
|
+
case "lines":
|
|
168
|
+
return me(d.first ?? d.prefix) && me(d.body);
|
|
169
|
+
case "columns":
|
|
170
|
+
return d.n === 0;
|
|
166
171
|
default:
|
|
167
172
|
return true;
|
|
168
173
|
}
|
|
@@ -277,6 +282,11 @@ function firstSetBody(p, seen, resolve3, activeTrivia) {
|
|
|
277
282
|
resolve3,
|
|
278
283
|
d.clearTrivia ? null : d.triviaParser ?? activeTrivia
|
|
279
284
|
);
|
|
285
|
+
// A run starts with its first line's prefix; a nullable prefix starts with anything.
|
|
286
|
+
case "lines": {
|
|
287
|
+
const opening = d.first ?? d.prefix;
|
|
288
|
+
return empties(opening) ? any() : fs3(opening);
|
|
289
|
+
}
|
|
280
290
|
default:
|
|
281
291
|
return p._meta.firstSet;
|
|
282
292
|
}
|
|
@@ -786,6 +796,8 @@ function createParseContext() {
|
|
|
786
796
|
_triviaCaptureMask: void 0,
|
|
787
797
|
trackLines: false,
|
|
788
798
|
state: void 0,
|
|
799
|
+
lineView: void 0,
|
|
800
|
+
_columnsSplit: void 0,
|
|
789
801
|
build: void 0,
|
|
790
802
|
_errors: void 0,
|
|
791
803
|
_tolerant: void 0,
|
|
@@ -1726,6 +1738,9 @@ function childrenOf(def) {
|
|
|
1726
1738
|
];
|
|
1727
1739
|
case "routed":
|
|
1728
1740
|
return def.fallback ? [def.fallback] : [];
|
|
1741
|
+
case "lines":
|
|
1742
|
+
return [def.prefix, def.body, ...def.first === void 0 ? [] : [def.first], ...def.lazy === void 0 ? [] : [def.lazy]];
|
|
1743
|
+
case "columns":
|
|
1729
1744
|
case "literal":
|
|
1730
1745
|
case "regex":
|
|
1731
1746
|
case "keywords":
|
|
@@ -2577,11 +2592,12 @@ function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
|
2577
2592
|
return result;
|
|
2578
2593
|
}
|
|
2579
2594
|
function saveLookaheadMark(ctx) {
|
|
2580
|
-
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
2595
|
+
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null, split: ctx._columnsSplit };
|
|
2581
2596
|
}
|
|
2582
2597
|
function rollbackLookahead(ctx, mark) {
|
|
2583
2598
|
rollbackTrivia(ctx, mark);
|
|
2584
2599
|
if (ctx._probe) ctx._probe.best = mark.probeBest;
|
|
2600
|
+
ctx._columnsSplit = mark.split;
|
|
2585
2601
|
}
|
|
2586
2602
|
function scanWithLabels(input, cur, ctx) {
|
|
2587
2603
|
const triviaP = ctx.trivia;
|
|
@@ -3427,6 +3443,12 @@ function derive(c, seen) {
|
|
|
3427
3443
|
return deriveExpected2(def.parser);
|
|
3428
3444
|
case "expect":
|
|
3429
3445
|
return def.expected;
|
|
3446
|
+
case "lines": {
|
|
3447
|
+
const opening = def.first ?? def.prefix;
|
|
3448
|
+
return matchesEmpty(opening) ? [...deriveExpected2(opening), ...deriveExpected2(def.body)] : deriveExpected2(opening);
|
|
3449
|
+
}
|
|
3450
|
+
case "columns":
|
|
3451
|
+
return [`columns(${def.n})`];
|
|
3430
3452
|
case "node":
|
|
3431
3453
|
case "grammar":
|
|
3432
3454
|
case "trivia":
|
|
@@ -3611,9 +3633,11 @@ function choice(...args) {
|
|
|
3611
3633
|
for (let i = 0; i < parsers.length; i++) {
|
|
3612
3634
|
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
3613
3635
|
const mark = saveTriviaMark(ctx);
|
|
3636
|
+
const split = ctx._columnsSplit;
|
|
3614
3637
|
const result = parsers[i].parse(input, pos, ctx);
|
|
3615
3638
|
if (!result.ok) {
|
|
3616
3639
|
rollbackTrivia(ctx, mark);
|
|
3640
|
+
ctx._columnsSplit = split;
|
|
3617
3641
|
const at = result.span.start;
|
|
3618
3642
|
if (at > expectedAt) {
|
|
3619
3643
|
expectedAt = at;
|
|
@@ -3834,6 +3858,9 @@ function parserUsesRouted(parser2, seen = /* @__PURE__ */ new Set()) {
|
|
|
3834
3858
|
return parserUsesRouted(def.sentinel, seen) || def.skip.some((entry) => parserUsesRouted(entry, seen)) || def.recoverAt !== void 0 && parserUsesRouted(def.recoverAt, seen) || def.stopAt !== void 0 && parserUsesRouted(def.stopAt, seen);
|
|
3835
3859
|
case "recover":
|
|
3836
3860
|
return parserUsesRouted(def.parser, seen) || parserUsesRouted(def.sentinel, seen);
|
|
3861
|
+
// The body parses its own input, so only the checks on this one can reuse a routed head.
|
|
3862
|
+
case "lines":
|
|
3863
|
+
return [def.prefix, def.first, def.lazy].some((entry) => entry !== void 0 && parserUsesRouted(entry, seen));
|
|
3837
3864
|
case "lazy":
|
|
3838
3865
|
try {
|
|
3839
3866
|
return parserUsesRouted(def.thunk(), seen);
|
|
@@ -4084,9 +4111,11 @@ function attempt(parser2, options) {
|
|
|
4084
4111
|
const mark = saveCstMark(ctx);
|
|
4085
4112
|
const log = ctx._triviaLog?.length;
|
|
4086
4113
|
const rootLog = ctx._rootTriviaLog?.length;
|
|
4114
|
+
const split = ctx._columnsSplit;
|
|
4087
4115
|
const result = parser2.parse(input, pos, ctx);
|
|
4088
4116
|
if (result.ok) return result;
|
|
4089
4117
|
rollbackCstCapture(ctx, mark);
|
|
4118
|
+
ctx._columnsSplit = split;
|
|
4090
4119
|
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
4091
4120
|
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
4092
4121
|
if (result.committed && !contain) return result;
|
|
@@ -4601,12 +4630,12 @@ function beginCompileDegradationDrain() {
|
|
|
4601
4630
|
return true;
|
|
4602
4631
|
});
|
|
4603
4632
|
if (fresh.length === 0) return;
|
|
4604
|
-
const
|
|
4633
|
+
const lines2 = formatDegradations(fresh);
|
|
4605
4634
|
if (resolveDegradationLevel() === "error") {
|
|
4606
4635
|
throw new Error(`parseman: ${fresh.length} degraded compilation path(s)
|
|
4607
|
-
${
|
|
4636
|
+
${lines2.join("\n")}`);
|
|
4608
4637
|
}
|
|
4609
|
-
for (const l of
|
|
4638
|
+
for (const l of lines2) console.warn(l);
|
|
4610
4639
|
};
|
|
4611
4640
|
}
|
|
4612
4641
|
|
|
@@ -4853,6 +4882,8 @@ function parserHasOwnFields(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4853
4882
|
return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen)) || d.recoverAt !== void 0 && parserHasOwnFields(d.recoverAt, seen) || d.stopAt !== void 0 && parserHasOwnFields(d.stopAt, seen);
|
|
4854
4883
|
case "recover":
|
|
4855
4884
|
return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.sentinel, seen);
|
|
4885
|
+
case "lines":
|
|
4886
|
+
return parserHasOwnFields(d.body, seen);
|
|
4856
4887
|
case "routed":
|
|
4857
4888
|
return d.fallback ? parserHasOwnFields(d.fallback, seen) : false;
|
|
4858
4889
|
case "many":
|
|
@@ -5266,801 +5297,230 @@ function sourceLeaf(root, fn) {
|
|
|
5266
5297
|
return makeLeaf(root, fn, true);
|
|
5267
5298
|
}
|
|
5268
5299
|
|
|
5269
|
-
// src/
|
|
5270
|
-
function
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
return d.parsers;
|
|
5275
|
-
case "dispatch":
|
|
5276
|
-
return [
|
|
5277
|
-
d.selector,
|
|
5278
|
-
...d.cases.map((c) => c.parser),
|
|
5279
|
-
...d.matchers ? d.matchers.map((c) => c.parser) : [],
|
|
5280
|
-
...d.otherwise === void 0 ? [] : [d.otherwise]
|
|
5281
|
-
];
|
|
5282
|
-
case "sepBy":
|
|
5283
|
-
return [d.parser, d.separator];
|
|
5284
|
-
case "recover":
|
|
5285
|
-
return [d.parser, d.sentinel];
|
|
5286
|
-
case "scanTo":
|
|
5287
|
-
return [
|
|
5288
|
-
d.sentinel,
|
|
5289
|
-
...d.skip,
|
|
5290
|
-
...d.recoverAt === void 0 ? [] : [d.recoverAt],
|
|
5291
|
-
...d.stopAt === void 0 ? [] : [d.stopAt]
|
|
5292
|
-
];
|
|
5293
|
-
case "grammar":
|
|
5294
|
-
return d.triviaParser ? [d.parser, d.triviaParser] : [d.parser];
|
|
5295
|
-
case "routed":
|
|
5296
|
-
return d.fallback ? [d.fallback] : [];
|
|
5297
|
-
// A `lazy` is a REFERENCE, not a subtree. Descending through it would make
|
|
5298
|
-
// every rule's walk cover the whole reachable grammar — site paths become
|
|
5299
|
-
// nonsense, and a structural hash includes half the grammar. Treated as a
|
|
5300
|
-
// leaf, keyed by the rule name it refers to, which is also the right
|
|
5301
|
-
// semantics: two productions referencing `g.Ident` really do fill that slot
|
|
5302
|
-
// the same way.
|
|
5303
|
-
case "lazy":
|
|
5304
|
-
case "literal":
|
|
5305
|
-
case "regex":
|
|
5306
|
-
case "keywords":
|
|
5307
|
-
case "guard":
|
|
5308
|
-
case "adjacency":
|
|
5309
|
-
case "unknown":
|
|
5310
|
-
return [];
|
|
5311
|
-
default: {
|
|
5312
|
-
const rec = d;
|
|
5313
|
-
return rec.parser ? [rec.parser] : [];
|
|
5314
|
-
}
|
|
5300
|
+
// src/table/lex-body.ts
|
|
5301
|
+
function buildLexBodyRecognizer(spec, constants) {
|
|
5302
|
+
const raw = constants[spec[0]];
|
|
5303
|
+
if (!(raw instanceof RegExp)) {
|
|
5304
|
+
throw new TypeError("table lexical body does not reference a RegExp constant");
|
|
5315
5305
|
}
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
return
|
|
5306
|
+
if (!Number.isInteger(spec[1]) || spec[1] < -1 || spec[1] > 65535) {
|
|
5307
|
+
throw new TypeError("table lexical body suffix is not absent or one UTF-16 code unit");
|
|
5308
|
+
}
|
|
5309
|
+
const re = raw.sticky ? new RegExp(raw.source, raw.flags) : new RegExp(raw.source, `${raw.flags.replace(/[gy]/g, "")}y`);
|
|
5310
|
+
const suffix = spec[1];
|
|
5311
|
+
return (input, pos) => {
|
|
5312
|
+
re.lastIndex = pos;
|
|
5313
|
+
if (!re.test(input)) return -1;
|
|
5314
|
+
const end = re.lastIndex;
|
|
5315
|
+
if (suffix < 0) return end * 2;
|
|
5316
|
+
return input.charCodeAt(end) === suffix ? (end + 1) * 2 + 1 : end * 2;
|
|
5317
|
+
};
|
|
5322
5318
|
}
|
|
5323
5319
|
|
|
5324
|
-
// src/
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
// `BareInterpolatedSelector` on benchmark.less — a rollback the legacy
|
|
5341
|
-
// build fired and this one had deleted.)
|
|
5342
|
-
case "optional":
|
|
5343
|
-
case "many":
|
|
5344
|
-
return mayCommitFailure(d.parser);
|
|
5345
|
-
case "sepBy":
|
|
5346
|
-
return d.min >= 1 ? mayFail(d.parser, seen) : mayCommitFailure(d.parser) || mayCommitFailure(d.separator);
|
|
5347
|
-
case "oneOrMore":
|
|
5348
|
-
return mayFail(d.parser, seen);
|
|
5349
|
-
case "sequence":
|
|
5350
|
-
return d.parsers.some((x) => mayFail(x, seen));
|
|
5351
|
-
// Delegating wrappers: as fallible as what they wrap.
|
|
5352
|
-
case "node":
|
|
5353
|
-
case "transform":
|
|
5354
|
-
case "label":
|
|
5355
|
-
case "field":
|
|
5356
|
-
case "expect":
|
|
5357
|
-
case "withCtx":
|
|
5358
|
-
case "grammar":
|
|
5359
|
-
case "token":
|
|
5360
|
-
case "leaf":
|
|
5361
|
-
return mayFail(d.parser, seen);
|
|
5362
|
-
case "lazy": {
|
|
5363
|
-
try {
|
|
5364
|
-
return mayFail(d.thunk(), seen);
|
|
5365
|
-
} catch {
|
|
5366
|
-
return true;
|
|
5367
|
-
}
|
|
5368
|
-
}
|
|
5369
|
-
// An adjacency assertion is a TEST — failing is its whole job.
|
|
5370
|
-
case "adjacency":
|
|
5371
|
-
return true;
|
|
5372
|
-
default:
|
|
5373
|
-
return true;
|
|
5320
|
+
// src/table/lex-program.ts
|
|
5321
|
+
var LEX_NODE_TERMINAL = 0;
|
|
5322
|
+
var LEX_NODE_SEQUENCE2 = 1;
|
|
5323
|
+
var LEX_NODE_SEQUENCE3 = 2;
|
|
5324
|
+
var LEX_NODE_SEQUENCE4 = 3;
|
|
5325
|
+
var LEX_NODE_SEQUENCE5 = 4;
|
|
5326
|
+
var LEX_NODE_CHOICE2 = 5;
|
|
5327
|
+
var LEX_NODE_CHOICE4 = 6;
|
|
5328
|
+
var LEX_NODE_CHOICE8 = 7;
|
|
5329
|
+
var LEX_NODE_NOT = 8;
|
|
5330
|
+
var LEX_NODE_OPTIONAL = 9;
|
|
5331
|
+
function lexProgramDigest(words) {
|
|
5332
|
+
let hash = 2166136261;
|
|
5333
|
+
for (const word2 of words) {
|
|
5334
|
+
hash ^= word2 | 0;
|
|
5335
|
+
hash = Math.imul(hash, 16777619);
|
|
5374
5336
|
}
|
|
5337
|
+
return hash | 0;
|
|
5375
5338
|
}
|
|
5376
|
-
function
|
|
5377
|
-
if (
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
// Atomic / non-capturing-then-failing: a failure happens before any push.
|
|
5382
|
-
case "literal":
|
|
5383
|
-
case "regex":
|
|
5384
|
-
case "keywords":
|
|
5385
|
-
case "guard":
|
|
5386
|
-
// Adjacency probes with `_cap = 0` / no `commit()`: it cannot push anything.
|
|
5387
|
-
case "adjacency":
|
|
5388
|
-
case "not":
|
|
5389
|
-
// peek(): emitted under a non-capturing probe ctx and zero-width on both
|
|
5390
|
-
// outcomes, so it can never leave a partial capture behind.
|
|
5391
|
-
case "peek":
|
|
5392
|
-
case "trivia":
|
|
5393
|
-
case "token":
|
|
5394
|
-
case "leaf":
|
|
5395
|
-
case "scanTo":
|
|
5396
|
-
case "unknown":
|
|
5397
|
-
return false;
|
|
5398
|
-
// node() captures into its own private buffers and rolls them back on
|
|
5399
|
-
// failure (emitNode restores _ctx.* and never pushes on the !ok path).
|
|
5400
|
-
case "node":
|
|
5401
|
-
return false;
|
|
5402
|
-
// choice/firstMatch already roll back each failed arm; on overall failure
|
|
5403
|
-
// nothing committed remains.
|
|
5404
|
-
case "choice":
|
|
5405
|
-
return false;
|
|
5406
|
-
case "dispatch":
|
|
5407
|
-
return capturesLeaf(d.selector, new Set(seen)) || d.cases.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) || (d.matchers ? d.matchers.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) : false) || (d.otherwise ? mayLeavePartialCapture(d.otherwise, new Set(seen), triviaActive) || capturesLeaf(d.otherwise, new Set(seen)) : false);
|
|
5408
|
-
case "attempt":
|
|
5409
|
-
return false;
|
|
5410
|
-
// optional never fails; many/oneOrMore only "fail" with zero captured items.
|
|
5411
|
-
case "optional":
|
|
5412
|
-
case "many":
|
|
5413
|
-
case "oneOrMore":
|
|
5414
|
-
return false;
|
|
5415
|
-
// sepBy emits its own per-iteration rollback in emitSepBy.
|
|
5416
|
-
case "sepBy":
|
|
5417
|
-
return false;
|
|
5418
|
-
// A sequence is the real case: an earlier capturing term followed by a term
|
|
5419
|
-
// that can fail leaves the earlier captures buffered.
|
|
5420
|
-
//
|
|
5421
|
-
// BOTH halves of that sentence are load-bearing, and the second half is what
|
|
5422
|
-
// this walk exists to exploit. "Some earlier term captures" alone was the old
|
|
5423
|
-
// test, and it is true of very nearly every sequence in a real grammar — a
|
|
5424
|
-
// sequence almost always opens with a literal or a node. The rollback is only
|
|
5425
|
-
// reachable if something AFTER the capture can still fail; once the remainder
|
|
5426
|
-
// is total (`optional`/`many`/trivia/a min-0 `sepBy`), the sequence has no
|
|
5427
|
-
// failure path left to roll back from, and the save+restore is dead code.
|
|
5428
|
-
//
|
|
5429
|
-
// `captured` tracks whether anything is in the buffers yet as the scan moves
|
|
5430
|
-
// left to right. Two things put it there:
|
|
5431
|
-
// - a term that captures (`capturesLeaf`/`hasNodeDef`), and
|
|
5432
|
-
// - the inter-term TRIVIA scan, which under `capturing` pushes into
|
|
5433
|
-
// `_cstRawChildren`/`_cstTriviaLog` BEFORE the term at each boundary
|
|
5434
|
-
// i >= 1. `emitSeqValues` only rewinds that push on the term's SUCCESS
|
|
5435
|
-
// path (the "matched empty, so leave the whitespace out of the span"
|
|
5436
|
-
// branch); a term that FAILS breaks straight out with the trivia still
|
|
5437
|
-
// buffered, so from boundary 1 onward the buffers are dirty regardless of
|
|
5438
|
-
// what the earlier terms did.
|
|
5439
|
-
// Each term is also asked about itself: a nested sequence can leave its own
|
|
5440
|
-
// partial capture behind, and its terms are emitted inline into this same
|
|
5441
|
-
// block with no boundary of their own to roll them back.
|
|
5442
|
-
case "sequence": {
|
|
5443
|
-
const parts = d.parsers;
|
|
5444
|
-
let captured = false;
|
|
5445
|
-
for (let i = 0; i < parts.length; i++) {
|
|
5446
|
-
const part = parts[i];
|
|
5447
|
-
if (i > 0 && triviaActive) captured = true;
|
|
5448
|
-
if (captured && mayFail(part)) return true;
|
|
5449
|
-
if (mayLeavePartialCapture(part, seen, triviaActive)) return true;
|
|
5450
|
-
if (capturesLeaf(part) || hasNodeDef(part)) captured = true;
|
|
5451
|
-
}
|
|
5452
|
-
return false;
|
|
5453
|
-
}
|
|
5454
|
-
// Delegating wrappers: defer to the wrapped parser.
|
|
5455
|
-
case "transform":
|
|
5456
|
-
case "label":
|
|
5457
|
-
case "field":
|
|
5458
|
-
case "expect":
|
|
5459
|
-
case "withCtx":
|
|
5460
|
-
case "grammar":
|
|
5461
|
-
return mayLeavePartialCapture(d.parser, seen, triviaActive);
|
|
5462
|
-
case "recover":
|
|
5463
|
-
return mayLeavePartialCapture(d.parser, seen, triviaActive);
|
|
5464
|
-
case "lazy": {
|
|
5465
|
-
try {
|
|
5466
|
-
return mayLeavePartialCapture(d.thunk(), seen, triviaActive);
|
|
5467
|
-
} catch {
|
|
5468
|
-
return true;
|
|
5469
|
-
}
|
|
5470
|
-
}
|
|
5471
|
-
// Unknown shapes: be safe and keep the rollback.
|
|
5472
|
-
default:
|
|
5473
|
-
return true;
|
|
5339
|
+
function classHas(cls, code) {
|
|
5340
|
+
if (code < 0) return false;
|
|
5341
|
+
if (code < 128) return cls.ascii[code] === 1;
|
|
5342
|
+
for (let i = 0; i < cls.hi.length; i += 2) {
|
|
5343
|
+
if (code >= cls.hi[i] && code <= cls.hi[i + 1]) return true;
|
|
5474
5344
|
}
|
|
5345
|
+
return false;
|
|
5475
5346
|
}
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
const
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
case "node":
|
|
5485
|
-
case "token":
|
|
5486
|
-
case "routed":
|
|
5487
|
-
case "leaf":
|
|
5488
|
-
return true;
|
|
5489
|
-
case "not":
|
|
5490
|
-
case "peek":
|
|
5491
|
-
case "guard":
|
|
5492
|
-
case "adjacency":
|
|
5493
|
-
case "trivia":
|
|
5494
|
-
case "unknown":
|
|
5495
|
-
return false;
|
|
5496
|
-
case "sequence":
|
|
5497
|
-
case "choice":
|
|
5498
|
-
return d.parsers.some((x) => capturesLeaf(x, seen));
|
|
5499
|
-
case "dispatch":
|
|
5500
|
-
return capturesLeaf(d.selector, seen) || d.cases.some((x) => capturesLeaf(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => capturesLeaf(entry.parser, seen)) : false) || (d.otherwise ? capturesLeaf(d.otherwise, seen) : false);
|
|
5501
|
-
case "sepBy":
|
|
5502
|
-
return capturesLeaf(d.parser, seen) || capturesLeaf(d.separator, seen);
|
|
5503
|
-
case "many":
|
|
5504
|
-
case "oneOrMore":
|
|
5505
|
-
case "optional":
|
|
5506
|
-
case "attempt":
|
|
5507
|
-
case "transform":
|
|
5508
|
-
case "label":
|
|
5509
|
-
case "field":
|
|
5510
|
-
case "expect":
|
|
5511
|
-
case "withCtx":
|
|
5512
|
-
case "grammar":
|
|
5513
|
-
case "recover":
|
|
5514
|
-
return capturesLeaf(d.parser, seen);
|
|
5515
|
-
case "scanTo":
|
|
5516
|
-
return true;
|
|
5517
|
-
case "lazy": {
|
|
5518
|
-
try {
|
|
5519
|
-
return capturesLeaf(d.thunk(), seen);
|
|
5520
|
-
} catch {
|
|
5521
|
-
return true;
|
|
5522
|
-
}
|
|
5523
|
-
}
|
|
5524
|
-
default:
|
|
5525
|
-
return true;
|
|
5347
|
+
var committed = (ctx) => ctx._fc === true;
|
|
5348
|
+
function trackLexLines(ctx, input, end) {
|
|
5349
|
+
let at = ctx._lineScannedTo ?? 0;
|
|
5350
|
+
const starts = ctx._lineStarts;
|
|
5351
|
+
if (starts === void 0 || end <= at) return;
|
|
5352
|
+
while (at < end) {
|
|
5353
|
+
if (input.charCodeAt(at) === 10) starts.push(at + 1);
|
|
5354
|
+
at++;
|
|
5526
5355
|
}
|
|
5356
|
+
ctx._lineScannedTo = end;
|
|
5527
5357
|
}
|
|
5528
|
-
function
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5358
|
+
function terminalNode(matcher, failure, tracksLines) {
|
|
5359
|
+
const match = (input, pos) => {
|
|
5360
|
+
const result = matcher(input, pos);
|
|
5361
|
+
return result < 0 ? -1 : result / 2;
|
|
5362
|
+
};
|
|
5363
|
+
return {
|
|
5364
|
+
match,
|
|
5365
|
+
run: (input, pos, ctx) => {
|
|
5366
|
+
const end = match(input, pos);
|
|
5367
|
+
if (end < 0) {
|
|
5368
|
+
ctx._fe = pos;
|
|
5369
|
+
ctx._fx = failure;
|
|
5370
|
+
if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
|
|
5371
|
+
return -1;
|
|
5540
5372
|
}
|
|
5373
|
+
if (tracksLines) trackLexLines(ctx, input, end);
|
|
5374
|
+
return end;
|
|
5541
5375
|
}
|
|
5542
|
-
|
|
5543
|
-
case "trivia":
|
|
5544
|
-
case "token":
|
|
5545
|
-
case "leaf":
|
|
5546
|
-
case "label":
|
|
5547
|
-
case "field":
|
|
5548
|
-
case "optional":
|
|
5549
|
-
case "many":
|
|
5550
|
-
case "oneOrMore":
|
|
5551
|
-
case "not":
|
|
5552
|
-
case "peek":
|
|
5553
|
-
case "transform":
|
|
5554
|
-
return hasNodeDef(d.parser, seen);
|
|
5555
|
-
case "sequence":
|
|
5556
|
-
case "choice":
|
|
5557
|
-
return d.parsers.some((x) => hasNodeDef(x, seen));
|
|
5558
|
-
case "dispatch":
|
|
5559
|
-
return hasNodeDef(d.selector, seen) || d.cases.some((x) => hasNodeDef(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => hasNodeDef(entry.parser, seen)) : false) || (d.otherwise ? hasNodeDef(d.otherwise, seen) : false);
|
|
5560
|
-
case "sepBy":
|
|
5561
|
-
return hasNodeDef(d.parser, seen) || hasNodeDef(d.separator, seen);
|
|
5562
|
-
case "scanTo":
|
|
5563
|
-
return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen)) || d.recoverAt !== void 0 && hasNodeDef(d.recoverAt, seen) || d.stopAt !== void 0 && hasNodeDef(d.stopAt, seen);
|
|
5564
|
-
case "recover":
|
|
5565
|
-
return hasNodeDef(d.parser, seen) || hasNodeDef(d.sentinel, seen);
|
|
5566
|
-
case "expect":
|
|
5567
|
-
return hasNodeDef(d.parser, seen);
|
|
5568
|
-
case "withCtx":
|
|
5569
|
-
return hasNodeDef(d.parser, seen);
|
|
5570
|
-
default:
|
|
5571
|
-
return false;
|
|
5572
|
-
}
|
|
5376
|
+
};
|
|
5573
5377
|
}
|
|
5574
|
-
function
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
return false;
|
|
5586
|
-
}
|
|
5378
|
+
function sequence2(a, b) {
|
|
5379
|
+
return {
|
|
5380
|
+
match: (input, pos) => {
|
|
5381
|
+
const e0 = a.match(input, pos);
|
|
5382
|
+
return e0 < 0 ? -1 : b.match(input, e0);
|
|
5383
|
+
},
|
|
5384
|
+
run: (input, pos, ctx) => {
|
|
5385
|
+
const e0 = a.run(input, pos, ctx);
|
|
5386
|
+
if (e0 < 0) return -1;
|
|
5387
|
+
ctx._fc = false;
|
|
5388
|
+
return b.run(input, e0, ctx);
|
|
5587
5389
|
}
|
|
5588
|
-
|
|
5589
|
-
case "trivia":
|
|
5590
|
-
case "token":
|
|
5591
|
-
case "leaf":
|
|
5592
|
-
case "label":
|
|
5593
|
-
case "field":
|
|
5594
|
-
case "optional":
|
|
5595
|
-
case "many":
|
|
5596
|
-
case "oneOrMore":
|
|
5597
|
-
case "attempt":
|
|
5598
|
-
case "not":
|
|
5599
|
-
case "peek":
|
|
5600
|
-
case "withCtx":
|
|
5601
|
-
case "expect":
|
|
5602
|
-
case "transform":
|
|
5603
|
-
return hasDirectBuildDef(d.parser, seen);
|
|
5604
|
-
case "sequence":
|
|
5605
|
-
case "choice":
|
|
5606
|
-
return d.parsers.some((x) => hasDirectBuildDef(x, seen));
|
|
5607
|
-
case "dispatch":
|
|
5608
|
-
return hasDirectBuildDef(d.selector, seen) || d.cases.some((x) => hasDirectBuildDef(x.parser, seen)) || (d.matchers ? d.matchers.some((x) => hasDirectBuildDef(x.parser, seen)) : false) || (d.otherwise ? hasDirectBuildDef(d.otherwise, seen) : false);
|
|
5609
|
-
case "sepBy":
|
|
5610
|
-
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.separator, seen);
|
|
5611
|
-
case "scanTo":
|
|
5612
|
-
return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen)) || d.recoverAt !== void 0 && hasDirectBuildDef(d.recoverAt, seen) || d.stopAt !== void 0 && hasDirectBuildDef(d.stopAt, seen);
|
|
5613
|
-
case "recover":
|
|
5614
|
-
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.sentinel, seen);
|
|
5615
|
-
case "routed":
|
|
5616
|
-
return d.fallback ? hasDirectBuildDef(d.fallback, seen) : false;
|
|
5617
|
-
default:
|
|
5618
|
-
return false;
|
|
5619
|
-
}
|
|
5390
|
+
};
|
|
5620
5391
|
}
|
|
5621
|
-
function
|
|
5622
|
-
return
|
|
5392
|
+
function sequence3(a, b, c) {
|
|
5393
|
+
return {
|
|
5394
|
+
match: (input, pos) => {
|
|
5395
|
+
const e0 = a.match(input, pos);
|
|
5396
|
+
if (e0 < 0) return -1;
|
|
5397
|
+
const e1 = b.match(input, e0);
|
|
5398
|
+
return e1 < 0 ? -1 : c.match(input, e1);
|
|
5399
|
+
},
|
|
5400
|
+
run: (input, pos, ctx) => {
|
|
5401
|
+
const e0 = a.run(input, pos, ctx);
|
|
5402
|
+
if (e0 < 0) return -1;
|
|
5403
|
+
ctx._fc = false;
|
|
5404
|
+
const e1 = b.run(input, e0, ctx);
|
|
5405
|
+
if (e1 < 0) return -1;
|
|
5406
|
+
ctx._fc = false;
|
|
5407
|
+
return c.run(input, e1, ctx);
|
|
5408
|
+
}
|
|
5409
|
+
};
|
|
5623
5410
|
}
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
return
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
return d.contain === true ? NO_EDGES : [d.parser];
|
|
5637
|
-
case "many":
|
|
5638
|
-
case "oneOrMore":
|
|
5639
|
-
case "optional":
|
|
5640
|
-
case "transform":
|
|
5641
|
-
case "label":
|
|
5642
|
-
case "field":
|
|
5643
|
-
case "grammar":
|
|
5644
|
-
case "node":
|
|
5645
|
-
case "token":
|
|
5646
|
-
case "leaf":
|
|
5647
|
-
case "withCtx":
|
|
5648
|
-
return [d.parser];
|
|
5649
|
-
case "sepBy":
|
|
5650
|
-
return [d.parser, d.separator];
|
|
5651
|
-
case "scanTo":
|
|
5652
|
-
return [
|
|
5653
|
-
d.sentinel,
|
|
5654
|
-
...d.skip,
|
|
5655
|
-
...d.recoverAt === void 0 ? NO_EDGES : [d.recoverAt],
|
|
5656
|
-
...d.stopAt === void 0 ? NO_EDGES : [d.stopAt]
|
|
5657
|
-
];
|
|
5658
|
-
case "lazy": {
|
|
5659
|
-
try {
|
|
5660
|
-
return [d.thunk()];
|
|
5661
|
-
} catch {
|
|
5662
|
-
const name = p._ruleName;
|
|
5663
|
-
const target = name === void 0 ? void 0 : resolve3?.(name);
|
|
5664
|
-
return target === void 0 ? true : [target];
|
|
5665
|
-
}
|
|
5411
|
+
function sequence4(a, b, c, d) {
|
|
5412
|
+
const abc = sequence3(a, b, c);
|
|
5413
|
+
return {
|
|
5414
|
+
match: (input, pos) => {
|
|
5415
|
+
const end = abc.match(input, pos);
|
|
5416
|
+
return end < 0 ? -1 : d.match(input, end);
|
|
5417
|
+
},
|
|
5418
|
+
run: (input, pos, ctx) => {
|
|
5419
|
+
const end = abc.run(input, pos, ctx);
|
|
5420
|
+
if (end < 0) return -1;
|
|
5421
|
+
ctx._fc = false;
|
|
5422
|
+
return d.run(input, end, ctx);
|
|
5666
5423
|
}
|
|
5667
|
-
|
|
5668
|
-
return NO_EDGES;
|
|
5669
|
-
}
|
|
5424
|
+
};
|
|
5670
5425
|
}
|
|
5671
|
-
function
|
|
5672
|
-
const
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
stack.push(node2);
|
|
5684
|
-
const next = successors(node2);
|
|
5685
|
-
if (next === true) found[at] = true;
|
|
5686
|
-
else {
|
|
5687
|
-
for (const child of next) {
|
|
5688
|
-
if (found[at]) break;
|
|
5689
|
-
const hit = memo.get(child);
|
|
5690
|
-
if (hit !== void 0) {
|
|
5691
|
-
if (hit) found[at] = true;
|
|
5692
|
-
continue;
|
|
5693
|
-
}
|
|
5694
|
-
const seen = order.get(child);
|
|
5695
|
-
if (seen !== void 0) {
|
|
5696
|
-
if (seen < low[at]) low[at] = seen;
|
|
5697
|
-
continue;
|
|
5698
|
-
}
|
|
5699
|
-
const k = visit(child);
|
|
5700
|
-
if (low[k] < low[at]) low[at] = low[k];
|
|
5701
|
-
if (found[k]) found[at] = true;
|
|
5702
|
-
}
|
|
5703
|
-
}
|
|
5704
|
-
if (low[at] === at) {
|
|
5705
|
-
const answer = found[at];
|
|
5706
|
-
let member;
|
|
5707
|
-
do {
|
|
5708
|
-
member = stack.pop();
|
|
5709
|
-
memo.set(member, answer);
|
|
5710
|
-
} while (member !== node2);
|
|
5426
|
+
function sequence5(a, b, c, d, e) {
|
|
5427
|
+
const abcd = sequence4(a, b, c, d);
|
|
5428
|
+
return {
|
|
5429
|
+
match: (input, pos) => {
|
|
5430
|
+
const end = abcd.match(input, pos);
|
|
5431
|
+
return end < 0 ? -1 : e.match(input, end);
|
|
5432
|
+
},
|
|
5433
|
+
run: (input, pos, ctx) => {
|
|
5434
|
+
const end = abcd.run(input, pos, ctx);
|
|
5435
|
+
if (end < 0) return -1;
|
|
5436
|
+
ctx._fc = false;
|
|
5437
|
+
return e.run(input, end, ctx);
|
|
5711
5438
|
}
|
|
5712
|
-
return at;
|
|
5713
5439
|
};
|
|
5714
|
-
return found[visit(root)];
|
|
5715
5440
|
}
|
|
5716
|
-
function
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
const def = parser2._def;
|
|
5722
|
-
if (def.tag === "transform" && !def.recognitionOnly) return true;
|
|
5723
|
-
if (def.tag === "choice" && def.gates.some(Boolean)) return true;
|
|
5724
|
-
if (def.tag === "guard" || def.tag === "withCtx") return true;
|
|
5725
|
-
if (def.tag === "node" && def.build !== void 0) return true;
|
|
5726
|
-
if (def.tag === "lazy") {
|
|
5727
|
-
if (externalRefs?.has(parser2)) return false;
|
|
5728
|
-
try {
|
|
5729
|
-
return visit(def.thunk());
|
|
5730
|
-
} catch {
|
|
5731
|
-
return true;
|
|
5732
|
-
}
|
|
5733
|
-
}
|
|
5734
|
-
return childrenOf2(def).some(visit);
|
|
5735
|
-
};
|
|
5736
|
-
return roots.some(visit);
|
|
5441
|
+
function appendExpected(acc, values) {
|
|
5442
|
+
if (values === void 0 || values.length === 0) return acc;
|
|
5443
|
+
if (acc === void 0) return values.slice();
|
|
5444
|
+
acc.push(...values);
|
|
5445
|
+
return acc;
|
|
5737
5446
|
}
|
|
5738
|
-
function
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5447
|
+
function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
5448
|
+
let matchTail = () => -1;
|
|
5449
|
+
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5450
|
+
const arm = arms[i], next = matchTail;
|
|
5451
|
+
matchTail = (input, pos) => {
|
|
5452
|
+
const end = arm.match(input, pos);
|
|
5453
|
+
return end < 0 ? next(input, pos) : end;
|
|
5454
|
+
};
|
|
5455
|
+
}
|
|
5456
|
+
let tail = (_input, pos, ctx, _lead, acc) => {
|
|
5457
|
+
ctx._fe = pos;
|
|
5458
|
+
ctx._fx = acc ?? choiceExpected;
|
|
5459
|
+
return -1;
|
|
5460
|
+
};
|
|
5461
|
+
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5462
|
+
const arm = arms[i], cls = classes[i], staticExpected = armExpected[i], next = tail;
|
|
5463
|
+
tail = (input, pos, ctx, lead2, acc, best) => {
|
|
5464
|
+
if (cls !== void 0 && !classHas(cls, lead2)) {
|
|
5465
|
+
return next(
|
|
5466
|
+
input,
|
|
5467
|
+
pos,
|
|
5468
|
+
ctx,
|
|
5469
|
+
lead2,
|
|
5470
|
+
best === pos ? appendExpected(acc, staticExpected) : acc,
|
|
5471
|
+
best
|
|
5472
|
+
);
|
|
5751
5473
|
}
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5474
|
+
ctx._fc = false;
|
|
5475
|
+
const end = arm.run(input, pos, ctx);
|
|
5476
|
+
if (end >= 0) return end;
|
|
5477
|
+
const at = ctx._fe ?? pos;
|
|
5478
|
+
if (at > best) {
|
|
5479
|
+
best = at;
|
|
5480
|
+
acc = void 0;
|
|
5755
5481
|
}
|
|
5756
|
-
|
|
5757
|
-
|
|
5482
|
+
const nextAcc = at === best ? appendExpected(acc, ctx._fx) : acc;
|
|
5483
|
+
if (committed(ctx)) {
|
|
5484
|
+
if (nextAcc !== void 0) ctx._fx = nextAcc;
|
|
5485
|
+
return -1;
|
|
5486
|
+
}
|
|
5487
|
+
return next(input, pos, ctx, lead2, nextAcc, best);
|
|
5488
|
+
};
|
|
5489
|
+
}
|
|
5490
|
+
return {
|
|
5491
|
+
match: matchTail,
|
|
5492
|
+
run: (input, pos, ctx) => tail(
|
|
5493
|
+
input,
|
|
5494
|
+
pos,
|
|
5495
|
+
ctx,
|
|
5496
|
+
pos < input.length ? input.codePointAt(pos) : -1,
|
|
5497
|
+
void 0,
|
|
5498
|
+
pos
|
|
5499
|
+
)
|
|
5500
|
+
};
|
|
5501
|
+
}
|
|
5502
|
+
function notNode(body, failure) {
|
|
5503
|
+
return {
|
|
5504
|
+
match: (input, pos) => body.match(input, pos) < 0 ? pos : -1,
|
|
5505
|
+
run: (input, pos, ctx) => {
|
|
5506
|
+
if (body.match(input, pos) < 0) return pos;
|
|
5507
|
+
ctx._fe = pos;
|
|
5508
|
+
ctx._fx = failure;
|
|
5509
|
+
return -1;
|
|
5758
5510
|
}
|
|
5759
|
-
for (const child of childrenOf2(def)) scanExternal(child);
|
|
5760
5511
|
};
|
|
5761
|
-
|
|
5512
|
+
}
|
|
5513
|
+
function optionalNode(body) {
|
|
5762
5514
|
return {
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
}
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
var OP_SEQV = 4;
|
|
5773
|
-
var OP_CHOICE = 5;
|
|
5774
|
-
var OP_REP = 6;
|
|
5775
|
-
var OP_REPV = 7;
|
|
5776
|
-
var OP_OPT = 8;
|
|
5777
|
-
var OP_XFORM = 9;
|
|
5778
|
-
var OP_NODE = 10;
|
|
5779
|
-
var OP_RULE = 11;
|
|
5780
|
-
var OP_GATE = 12;
|
|
5781
|
-
var OP_NOT = 13;
|
|
5782
|
-
var OP_PEEK = 14;
|
|
5783
|
-
var OP_LEAF = 15;
|
|
5784
|
-
var OP_EMPTY = 16;
|
|
5785
|
-
var OP_LIT_TRACK = 17;
|
|
5786
|
-
var OP_RX_TRACK = 18;
|
|
5787
|
-
var OP_NODE_TRACK = 19;
|
|
5788
|
-
var OP_SCOPE = 20;
|
|
5789
|
-
var OP_EXPECT = 21;
|
|
5790
|
-
var OP_SEQX = 22;
|
|
5791
|
-
var OP_SCAN = 23;
|
|
5792
|
-
var OP_FIELD = 24;
|
|
5793
|
-
var OP_LIT_CI = 27;
|
|
5794
|
-
var OP_LIT_CI_TRACK = 28;
|
|
5795
|
-
var OP_TOKEN = 29;
|
|
5796
|
-
var OP_SCOPE_CAP = 30;
|
|
5797
|
-
var OP_WITHCTX = 31;
|
|
5798
|
-
var OP_GUARD = 32;
|
|
5799
|
-
var OP_ADJ = 33;
|
|
5800
|
-
var OP_GREEDY = 34;
|
|
5801
|
-
var OP_REJECT = 35;
|
|
5802
|
-
var OP_ARMGATE = 36;
|
|
5803
|
-
var OP_LIVE = 37;
|
|
5804
|
-
var OP_ATTEMPT = 38;
|
|
5805
|
-
var OP_LABEL = 39;
|
|
5806
|
-
var OP_COV = 40;
|
|
5807
|
-
var OP_SCOPE_PLAIN = 41;
|
|
5808
|
-
var OP_LEX_BODY = 42;
|
|
5809
|
-
var OP_LEX_PROGRAM = 43;
|
|
5810
|
-
var OP_SOURCE_LEAF = 44;
|
|
5811
|
-
var OP_DISPATCH = 25;
|
|
5812
|
-
var OP_ROUTED = 26;
|
|
5813
|
-
var OP_NAMES = {
|
|
5814
|
-
[OP_LIT]: "LIT",
|
|
5815
|
-
[OP_RX]: "RX",
|
|
5816
|
-
[OP_SEQ]: "SEQ",
|
|
5817
|
-
[OP_SEQV]: "SEQV",
|
|
5818
|
-
[OP_CHOICE]: "CHOICE",
|
|
5819
|
-
[OP_REP]: "REP",
|
|
5820
|
-
[OP_REPV]: "REPV",
|
|
5821
|
-
[OP_OPT]: "OPT",
|
|
5822
|
-
[OP_XFORM]: "XFORM",
|
|
5823
|
-
[OP_NODE]: "NODE",
|
|
5824
|
-
[OP_RULE]: "RULE",
|
|
5825
|
-
[OP_GATE]: "GATE",
|
|
5826
|
-
[OP_NOT]: "NOT",
|
|
5827
|
-
[OP_PEEK]: "PEEK",
|
|
5828
|
-
[OP_LEAF]: "LEAF",
|
|
5829
|
-
[OP_SOURCE_LEAF]: "SOURCE_LEAF",
|
|
5830
|
-
[OP_EMPTY]: "EMPTY",
|
|
5831
|
-
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
5832
|
-
[OP_RX_TRACK]: "RX_TRACK",
|
|
5833
|
-
[OP_NODE_TRACK]: "NODE_TRACK",
|
|
5834
|
-
[OP_SCOPE]: "SCOPE",
|
|
5835
|
-
[OP_EXPECT]: "EXPECT",
|
|
5836
|
-
[OP_SEQX]: "SEQX",
|
|
5837
|
-
[OP_SCAN]: "SCAN",
|
|
5838
|
-
[OP_FIELD]: "FIELD",
|
|
5839
|
-
[OP_LIT_CI]: "LIT_CI",
|
|
5840
|
-
[OP_LIT_CI_TRACK]: "LIT_CI_TRACK",
|
|
5841
|
-
[OP_DISPATCH]: "DISPATCH",
|
|
5842
|
-
[OP_ROUTED]: "ROUTED",
|
|
5843
|
-
[OP_TOKEN]: "TOKEN",
|
|
5844
|
-
[OP_SCOPE_CAP]: "SCOPE_CAP",
|
|
5845
|
-
[OP_WITHCTX]: "WITHCTX",
|
|
5846
|
-
[OP_GUARD]: "GUARD",
|
|
5847
|
-
[OP_ADJ]: "ADJ",
|
|
5848
|
-
[OP_GREEDY]: "GREEDY",
|
|
5849
|
-
[OP_REJECT]: "REJECT",
|
|
5850
|
-
[OP_ARMGATE]: "ARMGATE",
|
|
5851
|
-
[OP_LIVE]: "LIVE",
|
|
5852
|
-
[OP_ATTEMPT]: "ATTEMPT",
|
|
5853
|
-
[OP_LABEL]: "LABEL",
|
|
5854
|
-
[OP_COV]: "COV",
|
|
5855
|
-
[OP_SCOPE_PLAIN]: "SCOPE_PLAIN",
|
|
5856
|
-
[OP_LEX_BODY]: "LEX_BODY",
|
|
5857
|
-
[OP_LEX_PROGRAM]: "LEX_PROGRAM"
|
|
5858
|
-
};
|
|
5859
|
-
|
|
5860
|
-
// src/table/lex-program.ts
|
|
5861
|
-
var LEX_NODE_TERMINAL = 0;
|
|
5862
|
-
var LEX_NODE_SEQUENCE2 = 1;
|
|
5863
|
-
var LEX_NODE_SEQUENCE3 = 2;
|
|
5864
|
-
var LEX_NODE_SEQUENCE4 = 3;
|
|
5865
|
-
var LEX_NODE_SEQUENCE5 = 4;
|
|
5866
|
-
var LEX_NODE_CHOICE2 = 5;
|
|
5867
|
-
var LEX_NODE_CHOICE4 = 6;
|
|
5868
|
-
var LEX_NODE_CHOICE8 = 7;
|
|
5869
|
-
var LEX_NODE_NOT = 8;
|
|
5870
|
-
var LEX_NODE_OPTIONAL = 9;
|
|
5871
|
-
function lexProgramDigest(words) {
|
|
5872
|
-
let hash = 2166136261;
|
|
5873
|
-
for (const word2 of words) {
|
|
5874
|
-
hash ^= word2 | 0;
|
|
5875
|
-
hash = Math.imul(hash, 16777619);
|
|
5876
|
-
}
|
|
5877
|
-
return hash | 0;
|
|
5878
|
-
}
|
|
5879
|
-
function classHas(cls, code) {
|
|
5880
|
-
if (code < 0) return false;
|
|
5881
|
-
if (code < 128) return cls.ascii[code] === 1;
|
|
5882
|
-
for (let i = 0; i < cls.hi.length; i += 2) {
|
|
5883
|
-
if (code >= cls.hi[i] && code <= cls.hi[i + 1]) return true;
|
|
5884
|
-
}
|
|
5885
|
-
return false;
|
|
5886
|
-
}
|
|
5887
|
-
var committed = (ctx) => ctx._fc === true;
|
|
5888
|
-
function trackLexLines(ctx, input, end) {
|
|
5889
|
-
let at = ctx._lineScannedTo ?? 0;
|
|
5890
|
-
const starts = ctx._lineStarts;
|
|
5891
|
-
if (starts === void 0 || end <= at) return;
|
|
5892
|
-
while (at < end) {
|
|
5893
|
-
if (input.charCodeAt(at) === 10) starts.push(at + 1);
|
|
5894
|
-
at++;
|
|
5895
|
-
}
|
|
5896
|
-
ctx._lineScannedTo = end;
|
|
5897
|
-
}
|
|
5898
|
-
function terminalNode(matcher, failure, tracksLines) {
|
|
5899
|
-
const match = (input, pos) => {
|
|
5900
|
-
const result = matcher(input, pos);
|
|
5901
|
-
return result < 0 ? -1 : result / 2;
|
|
5902
|
-
};
|
|
5903
|
-
return {
|
|
5904
|
-
match,
|
|
5905
|
-
run: (input, pos, ctx) => {
|
|
5906
|
-
const end = match(input, pos);
|
|
5907
|
-
if (end < 0) {
|
|
5908
|
-
ctx._fe = pos;
|
|
5909
|
-
ctx._fx = failure;
|
|
5910
|
-
if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
|
|
5911
|
-
return -1;
|
|
5912
|
-
}
|
|
5913
|
-
if (tracksLines) trackLexLines(ctx, input, end);
|
|
5914
|
-
return end;
|
|
5915
|
-
}
|
|
5916
|
-
};
|
|
5917
|
-
}
|
|
5918
|
-
function sequence2(a, b) {
|
|
5919
|
-
return {
|
|
5920
|
-
match: (input, pos) => {
|
|
5921
|
-
const e0 = a.match(input, pos);
|
|
5922
|
-
return e0 < 0 ? -1 : b.match(input, e0);
|
|
5923
|
-
},
|
|
5924
|
-
run: (input, pos, ctx) => {
|
|
5925
|
-
const e0 = a.run(input, pos, ctx);
|
|
5926
|
-
if (e0 < 0) return -1;
|
|
5927
|
-
ctx._fc = false;
|
|
5928
|
-
return b.run(input, e0, ctx);
|
|
5929
|
-
}
|
|
5930
|
-
};
|
|
5931
|
-
}
|
|
5932
|
-
function sequence3(a, b, c) {
|
|
5933
|
-
return {
|
|
5934
|
-
match: (input, pos) => {
|
|
5935
|
-
const e0 = a.match(input, pos);
|
|
5936
|
-
if (e0 < 0) return -1;
|
|
5937
|
-
const e1 = b.match(input, e0);
|
|
5938
|
-
return e1 < 0 ? -1 : c.match(input, e1);
|
|
5939
|
-
},
|
|
5940
|
-
run: (input, pos, ctx) => {
|
|
5941
|
-
const e0 = a.run(input, pos, ctx);
|
|
5942
|
-
if (e0 < 0) return -1;
|
|
5943
|
-
ctx._fc = false;
|
|
5944
|
-
const e1 = b.run(input, e0, ctx);
|
|
5945
|
-
if (e1 < 0) return -1;
|
|
5946
|
-
ctx._fc = false;
|
|
5947
|
-
return c.run(input, e1, ctx);
|
|
5948
|
-
}
|
|
5949
|
-
};
|
|
5950
|
-
}
|
|
5951
|
-
function sequence4(a, b, c, d) {
|
|
5952
|
-
const abc = sequence3(a, b, c);
|
|
5953
|
-
return {
|
|
5954
|
-
match: (input, pos) => {
|
|
5955
|
-
const end = abc.match(input, pos);
|
|
5956
|
-
return end < 0 ? -1 : d.match(input, end);
|
|
5957
|
-
},
|
|
5958
|
-
run: (input, pos, ctx) => {
|
|
5959
|
-
const end = abc.run(input, pos, ctx);
|
|
5960
|
-
if (end < 0) return -1;
|
|
5961
|
-
ctx._fc = false;
|
|
5962
|
-
return d.run(input, end, ctx);
|
|
5963
|
-
}
|
|
5964
|
-
};
|
|
5965
|
-
}
|
|
5966
|
-
function sequence5(a, b, c, d, e) {
|
|
5967
|
-
const abcd = sequence4(a, b, c, d);
|
|
5968
|
-
return {
|
|
5969
|
-
match: (input, pos) => {
|
|
5970
|
-
const end = abcd.match(input, pos);
|
|
5971
|
-
return end < 0 ? -1 : e.match(input, end);
|
|
5972
|
-
},
|
|
5973
|
-
run: (input, pos, ctx) => {
|
|
5974
|
-
const end = abcd.run(input, pos, ctx);
|
|
5975
|
-
if (end < 0) return -1;
|
|
5976
|
-
ctx._fc = false;
|
|
5977
|
-
return e.run(input, end, ctx);
|
|
5978
|
-
}
|
|
5979
|
-
};
|
|
5980
|
-
}
|
|
5981
|
-
function appendExpected(acc, values) {
|
|
5982
|
-
if (values === void 0 || values.length === 0) return acc;
|
|
5983
|
-
if (acc === void 0) return values.slice();
|
|
5984
|
-
acc.push(...values);
|
|
5985
|
-
return acc;
|
|
5986
|
-
}
|
|
5987
|
-
function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
5988
|
-
let matchTail = () => -1;
|
|
5989
|
-
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5990
|
-
const arm = arms[i], next = matchTail;
|
|
5991
|
-
matchTail = (input, pos) => {
|
|
5992
|
-
const end = arm.match(input, pos);
|
|
5993
|
-
return end < 0 ? next(input, pos) : end;
|
|
5994
|
-
};
|
|
5995
|
-
}
|
|
5996
|
-
let tail = (_input, pos, ctx, _lead, acc) => {
|
|
5997
|
-
ctx._fe = pos;
|
|
5998
|
-
ctx._fx = acc ?? choiceExpected;
|
|
5999
|
-
return -1;
|
|
6000
|
-
};
|
|
6001
|
-
for (let i = arms.length - 1; i >= 0; i--) {
|
|
6002
|
-
const arm = arms[i], cls = classes[i], staticExpected = armExpected[i], next = tail;
|
|
6003
|
-
tail = (input, pos, ctx, lead2, acc, best) => {
|
|
6004
|
-
if (cls !== void 0 && !classHas(cls, lead2)) {
|
|
6005
|
-
return next(
|
|
6006
|
-
input,
|
|
6007
|
-
pos,
|
|
6008
|
-
ctx,
|
|
6009
|
-
lead2,
|
|
6010
|
-
best === pos ? appendExpected(acc, staticExpected) : acc,
|
|
6011
|
-
best
|
|
6012
|
-
);
|
|
6013
|
-
}
|
|
6014
|
-
ctx._fc = false;
|
|
6015
|
-
const end = arm.run(input, pos, ctx);
|
|
6016
|
-
if (end >= 0) return end;
|
|
6017
|
-
const at = ctx._fe ?? pos;
|
|
6018
|
-
if (at > best) {
|
|
6019
|
-
best = at;
|
|
6020
|
-
acc = void 0;
|
|
6021
|
-
}
|
|
6022
|
-
const nextAcc = at === best ? appendExpected(acc, ctx._fx) : acc;
|
|
6023
|
-
if (committed(ctx)) {
|
|
6024
|
-
if (nextAcc !== void 0) ctx._fx = nextAcc;
|
|
6025
|
-
return -1;
|
|
6026
|
-
}
|
|
6027
|
-
return next(input, pos, ctx, lead2, nextAcc, best);
|
|
6028
|
-
};
|
|
6029
|
-
}
|
|
6030
|
-
return {
|
|
6031
|
-
match: matchTail,
|
|
6032
|
-
run: (input, pos, ctx) => tail(
|
|
6033
|
-
input,
|
|
6034
|
-
pos,
|
|
6035
|
-
ctx,
|
|
6036
|
-
pos < input.length ? input.codePointAt(pos) : -1,
|
|
6037
|
-
void 0,
|
|
6038
|
-
pos
|
|
6039
|
-
)
|
|
6040
|
-
};
|
|
6041
|
-
}
|
|
6042
|
-
function notNode(body, failure) {
|
|
6043
|
-
return {
|
|
6044
|
-
match: (input, pos) => body.match(input, pos) < 0 ? pos : -1,
|
|
6045
|
-
run: (input, pos, ctx) => {
|
|
6046
|
-
if (body.match(input, pos) < 0) return pos;
|
|
6047
|
-
ctx._fe = pos;
|
|
6048
|
-
ctx._fx = failure;
|
|
6049
|
-
return -1;
|
|
6050
|
-
}
|
|
6051
|
-
};
|
|
6052
|
-
}
|
|
6053
|
-
function optionalNode(body) {
|
|
6054
|
-
return {
|
|
6055
|
-
match: (input, pos) => {
|
|
6056
|
-
const end = body.match(input, pos);
|
|
6057
|
-
return end < 0 ? pos : end;
|
|
6058
|
-
},
|
|
6059
|
-
run: (input, pos, ctx) => {
|
|
6060
|
-
ctx._fc = false;
|
|
6061
|
-
const end = body.run(input, pos, ctx);
|
|
6062
|
-
return end < 0 && !committed(ctx) ? pos : end;
|
|
6063
|
-
}
|
|
5515
|
+
match: (input, pos) => {
|
|
5516
|
+
const end = body.match(input, pos);
|
|
5517
|
+
return end < 0 ? pos : end;
|
|
5518
|
+
},
|
|
5519
|
+
run: (input, pos, ctx) => {
|
|
5520
|
+
ctx._fc = false;
|
|
5521
|
+
const end = body.run(input, pos, ctx);
|
|
5522
|
+
return end < 0 && !committed(ctx) ? pos : end;
|
|
5523
|
+
}
|
|
6064
5524
|
};
|
|
6065
5525
|
}
|
|
6066
5526
|
function fixedTreeRunner(words, matchers, classes, expected) {
|
|
@@ -6235,26 +5695,6 @@ function buildLexProgramRunner(spec, matchers, classes, expected) {
|
|
|
6235
5695
|
};
|
|
6236
5696
|
}
|
|
6237
5697
|
|
|
6238
|
-
// src/table/lex-body.ts
|
|
6239
|
-
function buildLexBodyRecognizer(spec, constants) {
|
|
6240
|
-
const raw = constants[spec[0]];
|
|
6241
|
-
if (!(raw instanceof RegExp)) {
|
|
6242
|
-
throw new TypeError("table lexical body does not reference a RegExp constant");
|
|
6243
|
-
}
|
|
6244
|
-
if (!Number.isInteger(spec[1]) || spec[1] < -1 || spec[1] > 65535) {
|
|
6245
|
-
throw new TypeError("table lexical body suffix is not absent or one UTF-16 code unit");
|
|
6246
|
-
}
|
|
6247
|
-
const re = raw.sticky ? new RegExp(raw.source, raw.flags) : new RegExp(raw.source, `${raw.flags.replace(/[gy]/g, "")}y`);
|
|
6248
|
-
const suffix = spec[1];
|
|
6249
|
-
return (input, pos) => {
|
|
6250
|
-
re.lastIndex = pos;
|
|
6251
|
-
if (!re.test(input)) return -1;
|
|
6252
|
-
const end = re.lastIndex;
|
|
6253
|
-
if (suffix < 0) return end * 2;
|
|
6254
|
-
return input.charCodeAt(end) === suffix ? (end + 1) * 2 + 1 : end * 2;
|
|
6255
|
-
};
|
|
6256
|
-
}
|
|
6257
|
-
|
|
6258
5698
|
// src/table/program.ts
|
|
6259
5699
|
function closureArtifact(prog) {
|
|
6260
5700
|
return { ...prog, asm: [] };
|
|
@@ -6286,6 +5726,12 @@ function covKindName(code) {
|
|
|
6286
5726
|
function covDefinitions(prog) {
|
|
6287
5727
|
return (prog.cov ?? []).map(([id, kind]) => ({ id, kind: covKindName(kind) }));
|
|
6288
5728
|
}
|
|
5729
|
+
function scanRefs(s) {
|
|
5730
|
+
const refs = [];
|
|
5731
|
+
for (const r of [s.sentinel, s.recoverAt, s.stopAt, s.prefix, s.body, s.first, s.lazy]) if (r !== void 0) refs.push(r);
|
|
5732
|
+
refs.push(...s.skip);
|
|
5733
|
+
return refs;
|
|
5734
|
+
}
|
|
6289
5735
|
function expandCompact(p) {
|
|
6290
5736
|
if ("code" in p) return p;
|
|
6291
5737
|
return ownTableProgram({
|
|
@@ -6351,144 +5797,754 @@ function validateClassRange(lo, hi) {
|
|
|
6351
5797
|
throw new TypeError(`table char-class endpoint is outside Unicode: ${cp}`);
|
|
6352
5798
|
}
|
|
6353
5799
|
}
|
|
6354
|
-
if (lo > hi) {
|
|
6355
|
-
throw new TypeError(`table char-class range is descending: ${lo} > ${hi}`);
|
|
6356
|
-
}
|
|
6357
|
-
}
|
|
6358
|
-
function encodeClassSpec(ranges) {
|
|
6359
|
-
let wide = false;
|
|
6360
|
-
for (const range2 of ranges) {
|
|
6361
|
-
validateClassRange(range2.lo, range2.hi);
|
|
6362
|
-
if (range2.hi > 65535) wide = true;
|
|
6363
|
-
}
|
|
6364
|
-
if (!wide) {
|
|
6365
|
-
let spec2 = "";
|
|
6366
|
-
for (const range2 of ranges) spec2 += String.fromCharCode(range2.lo, range2.hi);
|
|
6367
|
-
return spec2;
|
|
6368
|
-
}
|
|
6369
|
-
let spec = String.fromCharCode(WIDE_CLASS_PREFIX_LO, WIDE_CLASS_PREFIX_HI);
|
|
6370
|
-
for (const range2 of ranges) {
|
|
6371
|
-
spec += String.fromCharCode(
|
|
6372
|
-
range2.lo >>> 16,
|
|
6373
|
-
range2.lo & 65535,
|
|
6374
|
-
range2.hi >>> 16,
|
|
6375
|
-
range2.hi & 65535
|
|
6376
|
-
);
|
|
6377
|
-
}
|
|
6378
|
-
return spec;
|
|
5800
|
+
if (lo > hi) {
|
|
5801
|
+
throw new TypeError(`table char-class range is descending: ${lo} > ${hi}`);
|
|
5802
|
+
}
|
|
5803
|
+
}
|
|
5804
|
+
function encodeClassSpec(ranges) {
|
|
5805
|
+
let wide = false;
|
|
5806
|
+
for (const range2 of ranges) {
|
|
5807
|
+
validateClassRange(range2.lo, range2.hi);
|
|
5808
|
+
if (range2.hi > 65535) wide = true;
|
|
5809
|
+
}
|
|
5810
|
+
if (!wide) {
|
|
5811
|
+
let spec2 = "";
|
|
5812
|
+
for (const range2 of ranges) spec2 += String.fromCharCode(range2.lo, range2.hi);
|
|
5813
|
+
return spec2;
|
|
5814
|
+
}
|
|
5815
|
+
let spec = String.fromCharCode(WIDE_CLASS_PREFIX_LO, WIDE_CLASS_PREFIX_HI);
|
|
5816
|
+
for (const range2 of ranges) {
|
|
5817
|
+
spec += String.fromCharCode(
|
|
5818
|
+
range2.lo >>> 16,
|
|
5819
|
+
range2.lo & 65535,
|
|
5820
|
+
range2.hi >>> 16,
|
|
5821
|
+
range2.hi & 65535
|
|
5822
|
+
);
|
|
5823
|
+
}
|
|
5824
|
+
return spec;
|
|
5825
|
+
}
|
|
5826
|
+
function decodeClassSpec(spec) {
|
|
5827
|
+
if (spec.charCodeAt(0) === WIDE_CLASS_PREFIX_LO && spec.charCodeAt(1) === WIDE_CLASS_PREFIX_HI) {
|
|
5828
|
+
if ((spec.length - 2) % 4 !== 0) throw new TypeError("table char-class spec has a truncated wide range");
|
|
5829
|
+
if (spec.length === 2) throw new TypeError("table char-class spec has a wide prefix but no ranges");
|
|
5830
|
+
const ranges2 = [];
|
|
5831
|
+
for (let i = 2; i < spec.length; i += 4) {
|
|
5832
|
+
const lo = spec.charCodeAt(i) * 65536 + spec.charCodeAt(i + 1);
|
|
5833
|
+
const hi = spec.charCodeAt(i + 2) * 65536 + spec.charCodeAt(i + 3);
|
|
5834
|
+
validateClassRange(lo, hi);
|
|
5835
|
+
ranges2.push({ lo, hi });
|
|
5836
|
+
}
|
|
5837
|
+
return ranges2;
|
|
5838
|
+
}
|
|
5839
|
+
if (spec.length % 2 !== 0) throw new TypeError("table char-class spec has an unmatched range endpoint");
|
|
5840
|
+
const ranges = [];
|
|
5841
|
+
for (let i = 0; i < spec.length; i += 2) {
|
|
5842
|
+
const lo = spec.charCodeAt(i);
|
|
5843
|
+
const hi = spec.charCodeAt(i + 1);
|
|
5844
|
+
validateClassRange(lo, hi);
|
|
5845
|
+
ranges.push({ lo, hi });
|
|
5846
|
+
}
|
|
5847
|
+
return ranges;
|
|
5848
|
+
}
|
|
5849
|
+
function resolveClass(spec) {
|
|
5850
|
+
const ascii = new Uint8Array(128);
|
|
5851
|
+
const hi = [];
|
|
5852
|
+
for (const { lo, hi: up } of decodeClassSpec(spec)) {
|
|
5853
|
+
if (lo < 128) for (let c = lo; c <= Math.min(up, 127); c++) ascii[c] = 1;
|
|
5854
|
+
if (up >= 128) hi.push(Math.max(lo, 128), up);
|
|
5855
|
+
}
|
|
5856
|
+
return { ascii, hi };
|
|
5857
|
+
}
|
|
5858
|
+
function classHas2(cls, code) {
|
|
5859
|
+
if (code < 0) return false;
|
|
5860
|
+
if (code < 128) return cls.ascii[code] === 1;
|
|
5861
|
+
const hi = cls.hi;
|
|
5862
|
+
for (let i = 0; i < hi.length; i += 2) if (code >= hi[i] && code <= hi[i + 1]) return true;
|
|
5863
|
+
return false;
|
|
5864
|
+
}
|
|
5865
|
+
function resolveDispatch(arms, cc) {
|
|
5866
|
+
const ascii = new Uint8Array(128);
|
|
5867
|
+
const hi = [];
|
|
5868
|
+
const open = [];
|
|
5869
|
+
const armCls = [];
|
|
5870
|
+
let exclusive = true;
|
|
5871
|
+
let hiOwners = 0;
|
|
5872
|
+
for (let a = 0; a < arms.length; a++) {
|
|
5873
|
+
const ci = arms[a];
|
|
5874
|
+
if (ci < 0) {
|
|
5875
|
+
open.push(a);
|
|
5876
|
+
armCls.push(null);
|
|
5877
|
+
exclusive = false;
|
|
5878
|
+
continue;
|
|
5879
|
+
}
|
|
5880
|
+
const cls = cc[ci];
|
|
5881
|
+
armCls.push(cls);
|
|
5882
|
+
for (let c = 0; c < 128; c++) {
|
|
5883
|
+
if (cls.ascii[c] !== 1) continue;
|
|
5884
|
+
if (ascii[c] === 0) ascii[c] = a + 1;
|
|
5885
|
+
else exclusive = false;
|
|
5886
|
+
}
|
|
5887
|
+
if (cls.hi.length > 0 && ++hiOwners > 1) exclusive = false;
|
|
5888
|
+
for (let i = 0; i < cls.hi.length; i += 2) hi.push(cls.hi[i], cls.hi[i + 1], a);
|
|
5889
|
+
}
|
|
5890
|
+
return { ascii, hi, open, armCls, exclusive };
|
|
5891
|
+
}
|
|
5892
|
+
function buildTrivia(spec) {
|
|
5893
|
+
if (spec.live !== void 0) return spec.live;
|
|
5894
|
+
if (spec.plain !== void 0) return trivia(regex(new RegExp(spec.plain[0], spec.plain[1])));
|
|
5895
|
+
if (spec.alts !== void 0) {
|
|
5896
|
+
const [head, ...rest] = spec.alts.map(([source, flags]) => regex(new RegExp(source, flags)));
|
|
5897
|
+
if (head === void 0) throw new TypeError("trivia spec has an EMPTY alternation, which matches nothing");
|
|
5898
|
+
const body = rest.length === 0 ? head : choice(head, ...rest);
|
|
5899
|
+
return trivia(many(body, { min: spec.min ?? 1 }));
|
|
5900
|
+
}
|
|
5901
|
+
const arms = {};
|
|
5902
|
+
for (const [name, source, flags] of spec.arms) arms[name] = regex(new RegExp(source, flags));
|
|
5903
|
+
return classifiedTrivia(arms);
|
|
5904
|
+
}
|
|
5905
|
+
function resolveTable(prog) {
|
|
5906
|
+
const owner = prog[TABLE_RUNTIME];
|
|
5907
|
+
const hit = owner?.resolved;
|
|
5908
|
+
if (hit !== void 0) return hit;
|
|
5909
|
+
const cc = prog.cc.map(resolveClass);
|
|
5910
|
+
const triviaBuilt = (prog.triviaSpecs ?? []).map(buildTrivia);
|
|
5911
|
+
const lex = (prog.lex ?? []).map((spec) => buildLexBodyRecognizer(spec, prog.k));
|
|
5912
|
+
const built = {
|
|
5913
|
+
prog,
|
|
5914
|
+
code: Int32Array.from(prog.code),
|
|
5915
|
+
k: prog.k,
|
|
5916
|
+
fns: prog.fns,
|
|
5917
|
+
cc,
|
|
5918
|
+
fx: prog.fx,
|
|
5919
|
+
disp: prog.disp.map((d) => resolveDispatch(d, cc)),
|
|
5920
|
+
trivia: triviaBuilt,
|
|
5921
|
+
triviaScan: triviaBuilt.map(fastTriviaScanner),
|
|
5922
|
+
triviaLabelled: triviaBuilt.map((t) => t._meta.triviaKindLabels !== void 0),
|
|
5923
|
+
dsp: prog.dsp.map((d) => ({
|
|
5924
|
+
byKey: new Map(d.key.map((x, i) => [x, d.keyArm[i]])),
|
|
5925
|
+
byFold: new Map(d.fold.map((x, i) => [x, d.foldArm[i]])),
|
|
5926
|
+
match: d.match,
|
|
5927
|
+
routed: d.routed,
|
|
5928
|
+
expected: d.expected
|
|
5929
|
+
})),
|
|
5930
|
+
lex,
|
|
5931
|
+
lexPrograms: (prog.lexPrograms ?? []).map((spec) => buildLexProgramRunner(spec, lex, cc, prog.fx)),
|
|
5932
|
+
rules: prog.rules
|
|
5933
|
+
};
|
|
5934
|
+
if (owner !== void 0) owner.resolved = built;
|
|
5935
|
+
return built;
|
|
5936
|
+
}
|
|
5937
|
+
|
|
5938
|
+
// src/analysis/gating.ts
|
|
5939
|
+
function childrenOf2(d) {
|
|
5940
|
+
switch (d.tag) {
|
|
5941
|
+
case "sequence":
|
|
5942
|
+
case "choice":
|
|
5943
|
+
return d.parsers;
|
|
5944
|
+
case "dispatch":
|
|
5945
|
+
return [
|
|
5946
|
+
d.selector,
|
|
5947
|
+
...d.cases.map((c) => c.parser),
|
|
5948
|
+
...d.matchers ? d.matchers.map((c) => c.parser) : [],
|
|
5949
|
+
...d.otherwise === void 0 ? [] : [d.otherwise]
|
|
5950
|
+
];
|
|
5951
|
+
case "sepBy":
|
|
5952
|
+
return [d.parser, d.separator];
|
|
5953
|
+
case "recover":
|
|
5954
|
+
return [d.parser, d.sentinel];
|
|
5955
|
+
case "scanTo":
|
|
5956
|
+
return [
|
|
5957
|
+
d.sentinel,
|
|
5958
|
+
...d.skip,
|
|
5959
|
+
...d.recoverAt === void 0 ? [] : [d.recoverAt],
|
|
5960
|
+
...d.stopAt === void 0 ? [] : [d.stopAt]
|
|
5961
|
+
];
|
|
5962
|
+
case "grammar":
|
|
5963
|
+
return d.triviaParser ? [d.parser, d.triviaParser] : [d.parser];
|
|
5964
|
+
case "routed":
|
|
5965
|
+
return d.fallback ? [d.fallback] : [];
|
|
5966
|
+
case "lines":
|
|
5967
|
+
return [d.prefix, d.body, ...d.first === void 0 ? [] : [d.first], ...d.lazy === void 0 ? [] : [d.lazy]];
|
|
5968
|
+
case "columns":
|
|
5969
|
+
return [];
|
|
5970
|
+
// A `lazy` is a REFERENCE, not a subtree. Descending through it would make
|
|
5971
|
+
// every rule's walk cover the whole reachable grammar — site paths become
|
|
5972
|
+
// nonsense, and a structural hash includes half the grammar. Treated as a
|
|
5973
|
+
// leaf, keyed by the rule name it refers to, which is also the right
|
|
5974
|
+
// semantics: two productions referencing `g.Ident` really do fill that slot
|
|
5975
|
+
// the same way.
|
|
5976
|
+
case "lazy":
|
|
5977
|
+
case "literal":
|
|
5978
|
+
case "regex":
|
|
5979
|
+
case "keywords":
|
|
5980
|
+
case "guard":
|
|
5981
|
+
case "adjacency":
|
|
5982
|
+
case "unknown":
|
|
5983
|
+
return [];
|
|
5984
|
+
default: {
|
|
5985
|
+
const rec = d;
|
|
5986
|
+
return rec.parser ? [rec.parser] : [];
|
|
5987
|
+
}
|
|
5988
|
+
}
|
|
5989
|
+
}
|
|
5990
|
+
var ch = (c) => c >= 32 && c < 127 ? `'${String.fromCharCode(c)}'` : `\\u${c}`;
|
|
5991
|
+
function firstSetToString(fs3) {
|
|
5992
|
+
if (fs3.kind === "any") return "ANY";
|
|
5993
|
+
if (fs3.kind === "empty") return "(empty)";
|
|
5994
|
+
return fs3.ranges.map((r) => r.lo === r.hi ? ch(r.lo) : `${ch(r.lo)}-${ch(r.hi)}`).join(",");
|
|
5995
|
+
}
|
|
5996
|
+
|
|
5997
|
+
// src/analysis/commitment.ts
|
|
5998
|
+
function mayFail(p, seen = /* @__PURE__ */ new Set()) {
|
|
5999
|
+
if (seen.has(p)) return true;
|
|
6000
|
+
seen.add(p);
|
|
6001
|
+
const d = p._def;
|
|
6002
|
+
switch (d.tag) {
|
|
6003
|
+
case "literal":
|
|
6004
|
+
return d.value.length > 0;
|
|
6005
|
+
case "trivia":
|
|
6006
|
+
return false;
|
|
6007
|
+
// `optional`/`many`/a min-0 `sepBy` swallow an ORDINARY failure — zero
|
|
6008
|
+
// repetitions is a match. They do NOT swallow a COMMITTED one: a dispatch
|
|
6009
|
+
// that has selected an arm and then failed inside it breaks out past every
|
|
6010
|
+
// enclosing repeat, straight to the fallible boundary. So these are total
|
|
6011
|
+
// exactly when their body cannot commit. (Measured: treating them as
|
|
6012
|
+
// unconditionally total left an extra zero-width leaf in
|
|
6013
|
+
// `BareInterpolatedSelector` on benchmark.less — a rollback the legacy
|
|
6014
|
+
// build fired and this one had deleted.)
|
|
6015
|
+
case "optional":
|
|
6016
|
+
case "many":
|
|
6017
|
+
return mayCommitFailure(d.parser);
|
|
6018
|
+
case "sepBy":
|
|
6019
|
+
return d.min >= 1 ? mayFail(d.parser, seen) : mayCommitFailure(d.parser) || mayCommitFailure(d.separator);
|
|
6020
|
+
case "oneOrMore":
|
|
6021
|
+
return mayFail(d.parser, seen);
|
|
6022
|
+
case "sequence":
|
|
6023
|
+
return d.parsers.some((x) => mayFail(x, seen));
|
|
6024
|
+
// Delegating wrappers: as fallible as what they wrap.
|
|
6025
|
+
case "node":
|
|
6026
|
+
case "transform":
|
|
6027
|
+
case "label":
|
|
6028
|
+
case "field":
|
|
6029
|
+
case "expect":
|
|
6030
|
+
case "withCtx":
|
|
6031
|
+
case "grammar":
|
|
6032
|
+
case "token":
|
|
6033
|
+
case "leaf":
|
|
6034
|
+
return mayFail(d.parser, seen);
|
|
6035
|
+
case "lazy": {
|
|
6036
|
+
try {
|
|
6037
|
+
return mayFail(d.thunk(), seen);
|
|
6038
|
+
} catch {
|
|
6039
|
+
return true;
|
|
6040
|
+
}
|
|
6041
|
+
}
|
|
6042
|
+
// An adjacency assertion is a TEST — failing is its whole job.
|
|
6043
|
+
case "adjacency":
|
|
6044
|
+
return true;
|
|
6045
|
+
default:
|
|
6046
|
+
return true;
|
|
6047
|
+
}
|
|
6048
|
+
}
|
|
6049
|
+
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActive = true) {
|
|
6050
|
+
if (seen.has(p)) return false;
|
|
6051
|
+
seen.add(p);
|
|
6052
|
+
const d = p._def;
|
|
6053
|
+
switch (d.tag) {
|
|
6054
|
+
// Atomic / non-capturing-then-failing: a failure happens before any push.
|
|
6055
|
+
case "literal":
|
|
6056
|
+
case "regex":
|
|
6057
|
+
case "keywords":
|
|
6058
|
+
case "guard":
|
|
6059
|
+
// Adjacency probes with `_cap = 0` / no `commit()`: it cannot push anything.
|
|
6060
|
+
case "adjacency":
|
|
6061
|
+
case "not":
|
|
6062
|
+
// peek(): emitted under a non-capturing probe ctx and zero-width on both
|
|
6063
|
+
// outcomes, so it can never leave a partial capture behind.
|
|
6064
|
+
case "peek":
|
|
6065
|
+
case "trivia":
|
|
6066
|
+
case "token":
|
|
6067
|
+
case "leaf":
|
|
6068
|
+
case "scanTo":
|
|
6069
|
+
case "unknown":
|
|
6070
|
+
case "columns":
|
|
6071
|
+
return false;
|
|
6072
|
+
// A run's prefixes are probed detached; only its body can capture.
|
|
6073
|
+
case "lines":
|
|
6074
|
+
return mayLeavePartialCapture(d.body, seen, triviaActive);
|
|
6075
|
+
// node() captures into its own private buffers and rolls them back on
|
|
6076
|
+
// failure (emitNode restores _ctx.* and never pushes on the !ok path).
|
|
6077
|
+
case "node":
|
|
6078
|
+
return false;
|
|
6079
|
+
// choice/firstMatch already roll back each failed arm; on overall failure
|
|
6080
|
+
// nothing committed remains.
|
|
6081
|
+
case "choice":
|
|
6082
|
+
return false;
|
|
6083
|
+
case "dispatch":
|
|
6084
|
+
return capturesLeaf(d.selector, new Set(seen)) || d.cases.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) || (d.matchers ? d.matchers.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) : false) || (d.otherwise ? mayLeavePartialCapture(d.otherwise, new Set(seen), triviaActive) || capturesLeaf(d.otherwise, new Set(seen)) : false);
|
|
6085
|
+
case "attempt":
|
|
6086
|
+
return false;
|
|
6087
|
+
// optional never fails; many/oneOrMore only "fail" with zero captured items.
|
|
6088
|
+
case "optional":
|
|
6089
|
+
case "many":
|
|
6090
|
+
case "oneOrMore":
|
|
6091
|
+
return false;
|
|
6092
|
+
// sepBy emits its own per-iteration rollback in emitSepBy.
|
|
6093
|
+
case "sepBy":
|
|
6094
|
+
return false;
|
|
6095
|
+
// A sequence is the real case: an earlier capturing term followed by a term
|
|
6096
|
+
// that can fail leaves the earlier captures buffered.
|
|
6097
|
+
//
|
|
6098
|
+
// BOTH halves of that sentence are load-bearing, and the second half is what
|
|
6099
|
+
// this walk exists to exploit. "Some earlier term captures" alone was the old
|
|
6100
|
+
// test, and it is true of very nearly every sequence in a real grammar — a
|
|
6101
|
+
// sequence almost always opens with a literal or a node. The rollback is only
|
|
6102
|
+
// reachable if something AFTER the capture can still fail; once the remainder
|
|
6103
|
+
// is total (`optional`/`many`/trivia/a min-0 `sepBy`), the sequence has no
|
|
6104
|
+
// failure path left to roll back from, and the save+restore is dead code.
|
|
6105
|
+
//
|
|
6106
|
+
// `captured` tracks whether anything is in the buffers yet as the scan moves
|
|
6107
|
+
// left to right. Two things put it there:
|
|
6108
|
+
// - a term that captures (`capturesLeaf`/`hasNodeDef`), and
|
|
6109
|
+
// - the inter-term TRIVIA scan, which under `capturing` pushes into
|
|
6110
|
+
// `_cstRawChildren`/`_cstTriviaLog` BEFORE the term at each boundary
|
|
6111
|
+
// i >= 1. `emitSeqValues` only rewinds that push on the term's SUCCESS
|
|
6112
|
+
// path (the "matched empty, so leave the whitespace out of the span"
|
|
6113
|
+
// branch); a term that FAILS breaks straight out with the trivia still
|
|
6114
|
+
// buffered, so from boundary 1 onward the buffers are dirty regardless of
|
|
6115
|
+
// what the earlier terms did.
|
|
6116
|
+
// Each term is also asked about itself: a nested sequence can leave its own
|
|
6117
|
+
// partial capture behind, and its terms are emitted inline into this same
|
|
6118
|
+
// block with no boundary of their own to roll them back.
|
|
6119
|
+
case "sequence": {
|
|
6120
|
+
const parts = d.parsers;
|
|
6121
|
+
let captured = false;
|
|
6122
|
+
for (let i = 0; i < parts.length; i++) {
|
|
6123
|
+
const part = parts[i];
|
|
6124
|
+
if (i > 0 && triviaActive) captured = true;
|
|
6125
|
+
if (captured && mayFail(part)) return true;
|
|
6126
|
+
if (mayLeavePartialCapture(part, seen, triviaActive)) return true;
|
|
6127
|
+
if (capturesLeaf(part) || hasNodeDef(part)) captured = true;
|
|
6128
|
+
}
|
|
6129
|
+
return false;
|
|
6130
|
+
}
|
|
6131
|
+
// Delegating wrappers: defer to the wrapped parser.
|
|
6132
|
+
case "transform":
|
|
6133
|
+
case "label":
|
|
6134
|
+
case "field":
|
|
6135
|
+
case "expect":
|
|
6136
|
+
case "withCtx":
|
|
6137
|
+
case "grammar":
|
|
6138
|
+
return mayLeavePartialCapture(d.parser, seen, triviaActive);
|
|
6139
|
+
case "recover":
|
|
6140
|
+
return mayLeavePartialCapture(d.parser, seen, triviaActive);
|
|
6141
|
+
case "lazy": {
|
|
6142
|
+
try {
|
|
6143
|
+
return mayLeavePartialCapture(d.thunk(), seen, triviaActive);
|
|
6144
|
+
} catch {
|
|
6145
|
+
return true;
|
|
6146
|
+
}
|
|
6147
|
+
}
|
|
6148
|
+
// Unknown shapes: be safe and keep the rollback.
|
|
6149
|
+
default:
|
|
6150
|
+
return true;
|
|
6151
|
+
}
|
|
6152
|
+
}
|
|
6153
|
+
function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
|
|
6154
|
+
if (seen.has(p)) return false;
|
|
6155
|
+
seen.add(p);
|
|
6156
|
+
const d = p._def;
|
|
6157
|
+
switch (d.tag) {
|
|
6158
|
+
case "literal":
|
|
6159
|
+
case "regex":
|
|
6160
|
+
case "keywords":
|
|
6161
|
+
case "node":
|
|
6162
|
+
case "token":
|
|
6163
|
+
case "routed":
|
|
6164
|
+
case "leaf":
|
|
6165
|
+
return true;
|
|
6166
|
+
case "not":
|
|
6167
|
+
case "peek":
|
|
6168
|
+
case "guard":
|
|
6169
|
+
case "adjacency":
|
|
6170
|
+
case "trivia":
|
|
6171
|
+
case "unknown":
|
|
6172
|
+
return false;
|
|
6173
|
+
case "sequence":
|
|
6174
|
+
case "choice":
|
|
6175
|
+
return d.parsers.some((x) => capturesLeaf(x, seen));
|
|
6176
|
+
case "dispatch":
|
|
6177
|
+
return capturesLeaf(d.selector, seen) || d.cases.some((x) => capturesLeaf(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => capturesLeaf(entry.parser, seen)) : false) || (d.otherwise ? capturesLeaf(d.otherwise, seen) : false);
|
|
6178
|
+
case "sepBy":
|
|
6179
|
+
return capturesLeaf(d.parser, seen) || capturesLeaf(d.separator, seen);
|
|
6180
|
+
case "many":
|
|
6181
|
+
case "oneOrMore":
|
|
6182
|
+
case "optional":
|
|
6183
|
+
case "attempt":
|
|
6184
|
+
case "transform":
|
|
6185
|
+
case "label":
|
|
6186
|
+
case "field":
|
|
6187
|
+
case "expect":
|
|
6188
|
+
case "withCtx":
|
|
6189
|
+
case "grammar":
|
|
6190
|
+
case "recover":
|
|
6191
|
+
return capturesLeaf(d.parser, seen);
|
|
6192
|
+
case "scanTo":
|
|
6193
|
+
return true;
|
|
6194
|
+
case "lines":
|
|
6195
|
+
return capturesLeaf(d.body, seen);
|
|
6196
|
+
case "columns":
|
|
6197
|
+
return true;
|
|
6198
|
+
case "lazy": {
|
|
6199
|
+
try {
|
|
6200
|
+
return capturesLeaf(d.thunk(), seen);
|
|
6201
|
+
} catch {
|
|
6202
|
+
return true;
|
|
6203
|
+
}
|
|
6204
|
+
}
|
|
6205
|
+
default:
|
|
6206
|
+
return true;
|
|
6207
|
+
}
|
|
6379
6208
|
}
|
|
6380
|
-
function
|
|
6381
|
-
if (
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6209
|
+
function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
6210
|
+
if (seen.has(p)) return false;
|
|
6211
|
+
seen.add(p);
|
|
6212
|
+
const d = p._def;
|
|
6213
|
+
switch (d.tag) {
|
|
6214
|
+
case "node":
|
|
6215
|
+
return true;
|
|
6216
|
+
case "lazy": {
|
|
6217
|
+
try {
|
|
6218
|
+
return hasNodeDef(d.thunk(), seen);
|
|
6219
|
+
} catch {
|
|
6220
|
+
return false;
|
|
6221
|
+
}
|
|
6390
6222
|
}
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6223
|
+
case "grammar":
|
|
6224
|
+
case "trivia":
|
|
6225
|
+
case "token":
|
|
6226
|
+
case "leaf":
|
|
6227
|
+
case "label":
|
|
6228
|
+
case "field":
|
|
6229
|
+
case "optional":
|
|
6230
|
+
case "many":
|
|
6231
|
+
case "oneOrMore":
|
|
6232
|
+
case "not":
|
|
6233
|
+
case "peek":
|
|
6234
|
+
case "transform":
|
|
6235
|
+
return hasNodeDef(d.parser, seen);
|
|
6236
|
+
case "sequence":
|
|
6237
|
+
case "choice":
|
|
6238
|
+
return d.parsers.some((x) => hasNodeDef(x, seen));
|
|
6239
|
+
case "dispatch":
|
|
6240
|
+
return hasNodeDef(d.selector, seen) || d.cases.some((x) => hasNodeDef(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => hasNodeDef(entry.parser, seen)) : false) || (d.otherwise ? hasNodeDef(d.otherwise, seen) : false);
|
|
6241
|
+
case "sepBy":
|
|
6242
|
+
return hasNodeDef(d.parser, seen) || hasNodeDef(d.separator, seen);
|
|
6243
|
+
case "scanTo":
|
|
6244
|
+
return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen)) || d.recoverAt !== void 0 && hasNodeDef(d.recoverAt, seen) || d.stopAt !== void 0 && hasNodeDef(d.stopAt, seen);
|
|
6245
|
+
case "lines":
|
|
6246
|
+
return hasNodeDef(d.body, seen);
|
|
6247
|
+
case "recover":
|
|
6248
|
+
return hasNodeDef(d.parser, seen) || hasNodeDef(d.sentinel, seen);
|
|
6249
|
+
case "expect":
|
|
6250
|
+
return hasNodeDef(d.parser, seen);
|
|
6251
|
+
case "withCtx":
|
|
6252
|
+
return hasNodeDef(d.parser, seen);
|
|
6253
|
+
default:
|
|
6254
|
+
return false;
|
|
6400
6255
|
}
|
|
6401
|
-
return ranges;
|
|
6402
6256
|
}
|
|
6403
|
-
function
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6257
|
+
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
6258
|
+
if (seen.has(p)) return false;
|
|
6259
|
+
seen.add(p);
|
|
6260
|
+
const d = p._def;
|
|
6261
|
+
switch (d.tag) {
|
|
6262
|
+
case "node":
|
|
6263
|
+
return d.build !== void 0 || hasDirectBuildDef(d.parser, seen);
|
|
6264
|
+
case "lazy": {
|
|
6265
|
+
try {
|
|
6266
|
+
return hasDirectBuildDef(d.thunk(), seen);
|
|
6267
|
+
} catch {
|
|
6268
|
+
return false;
|
|
6269
|
+
}
|
|
6270
|
+
}
|
|
6271
|
+
case "grammar":
|
|
6272
|
+
case "trivia":
|
|
6273
|
+
case "token":
|
|
6274
|
+
case "leaf":
|
|
6275
|
+
case "label":
|
|
6276
|
+
case "field":
|
|
6277
|
+
case "optional":
|
|
6278
|
+
case "many":
|
|
6279
|
+
case "oneOrMore":
|
|
6280
|
+
case "attempt":
|
|
6281
|
+
case "not":
|
|
6282
|
+
case "peek":
|
|
6283
|
+
case "withCtx":
|
|
6284
|
+
case "expect":
|
|
6285
|
+
case "transform":
|
|
6286
|
+
return hasDirectBuildDef(d.parser, seen);
|
|
6287
|
+
case "sequence":
|
|
6288
|
+
case "choice":
|
|
6289
|
+
return d.parsers.some((x) => hasDirectBuildDef(x, seen));
|
|
6290
|
+
case "dispatch":
|
|
6291
|
+
return hasDirectBuildDef(d.selector, seen) || d.cases.some((x) => hasDirectBuildDef(x.parser, seen)) || (d.matchers ? d.matchers.some((x) => hasDirectBuildDef(x.parser, seen)) : false) || (d.otherwise ? hasDirectBuildDef(d.otherwise, seen) : false);
|
|
6292
|
+
case "sepBy":
|
|
6293
|
+
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.separator, seen);
|
|
6294
|
+
case "scanTo":
|
|
6295
|
+
return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen)) || d.recoverAt !== void 0 && hasDirectBuildDef(d.recoverAt, seen) || d.stopAt !== void 0 && hasDirectBuildDef(d.stopAt, seen);
|
|
6296
|
+
case "lines":
|
|
6297
|
+
return hasDirectBuildDef(d.body, seen);
|
|
6298
|
+
case "recover":
|
|
6299
|
+
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.sentinel, seen);
|
|
6300
|
+
case "routed":
|
|
6301
|
+
return d.fallback ? hasDirectBuildDef(d.fallback, seen) : false;
|
|
6302
|
+
default:
|
|
6303
|
+
return false;
|
|
6409
6304
|
}
|
|
6410
|
-
return { ascii, hi };
|
|
6411
6305
|
}
|
|
6412
|
-
function
|
|
6413
|
-
|
|
6414
|
-
if (code < 128) return cls.ascii[code] === 1;
|
|
6415
|
-
const hi = cls.hi;
|
|
6416
|
-
for (let i = 0; i < hi.length; i += 2) if (code >= hi[i] && code <= hi[i + 1]) return true;
|
|
6417
|
-
return false;
|
|
6306
|
+
function mayCommitFailure(p, resolve3, memo = /* @__PURE__ */ new Map()) {
|
|
6307
|
+
return reachesMarked(p, (node2) => commitFailureSuccessors(node2, resolve3), memo);
|
|
6418
6308
|
}
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
const
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6309
|
+
var NO_EDGES = [];
|
|
6310
|
+
function commitFailureSuccessors(p, resolve3) {
|
|
6311
|
+
const d = p._def;
|
|
6312
|
+
switch (d.tag) {
|
|
6313
|
+
case "dispatch":
|
|
6314
|
+
case "unknown":
|
|
6315
|
+
return true;
|
|
6316
|
+
case "choice":
|
|
6317
|
+
case "sequence":
|
|
6318
|
+
return d.parsers;
|
|
6319
|
+
// A contained transaction reports every failure uncommitted.
|
|
6320
|
+
case "attempt":
|
|
6321
|
+
return d.contain === true ? NO_EDGES : [d.parser];
|
|
6322
|
+
case "many":
|
|
6323
|
+
case "oneOrMore":
|
|
6324
|
+
case "optional":
|
|
6325
|
+
case "transform":
|
|
6326
|
+
case "label":
|
|
6327
|
+
case "field":
|
|
6328
|
+
case "grammar":
|
|
6329
|
+
case "node":
|
|
6330
|
+
case "token":
|
|
6331
|
+
case "leaf":
|
|
6332
|
+
case "withCtx":
|
|
6333
|
+
return [d.parser];
|
|
6334
|
+
case "sepBy":
|
|
6335
|
+
return [d.parser, d.separator];
|
|
6336
|
+
case "scanTo":
|
|
6337
|
+
return [
|
|
6338
|
+
d.sentinel,
|
|
6339
|
+
...d.skip,
|
|
6340
|
+
...d.recoverAt === void 0 ? NO_EDGES : [d.recoverAt],
|
|
6341
|
+
...d.stopAt === void 0 ? NO_EDGES : [d.stopAt]
|
|
6342
|
+
];
|
|
6343
|
+
// A run's prefixes are probed detached; a committed failure reaches it only from its body.
|
|
6344
|
+
case "lines":
|
|
6345
|
+
return [d.body];
|
|
6346
|
+
case "lazy": {
|
|
6347
|
+
try {
|
|
6348
|
+
return [d.thunk()];
|
|
6349
|
+
} catch {
|
|
6350
|
+
const name = p._ruleName;
|
|
6351
|
+
const target = name === void 0 ? void 0 : resolve3?.(name);
|
|
6352
|
+
return target === void 0 ? true : [target];
|
|
6353
|
+
}
|
|
6433
6354
|
}
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6355
|
+
default:
|
|
6356
|
+
return NO_EDGES;
|
|
6357
|
+
}
|
|
6358
|
+
}
|
|
6359
|
+
function reachesMarked(root, successors, memo) {
|
|
6360
|
+
const known = memo.get(root);
|
|
6361
|
+
if (known !== void 0) return known;
|
|
6362
|
+
const order = /* @__PURE__ */ new Map();
|
|
6363
|
+
const low = [];
|
|
6364
|
+
const found = [];
|
|
6365
|
+
const stack = [];
|
|
6366
|
+
const visit = (node2) => {
|
|
6367
|
+
const at = low.length;
|
|
6368
|
+
order.set(node2, at);
|
|
6369
|
+
low.push(at);
|
|
6370
|
+
found.push(false);
|
|
6371
|
+
stack.push(node2);
|
|
6372
|
+
const next = successors(node2);
|
|
6373
|
+
if (next === true) found[at] = true;
|
|
6374
|
+
else {
|
|
6375
|
+
for (const child of next) {
|
|
6376
|
+
if (found[at]) break;
|
|
6377
|
+
const hit = memo.get(child);
|
|
6378
|
+
if (hit !== void 0) {
|
|
6379
|
+
if (hit) found[at] = true;
|
|
6380
|
+
continue;
|
|
6381
|
+
}
|
|
6382
|
+
const seen = order.get(child);
|
|
6383
|
+
if (seen !== void 0) {
|
|
6384
|
+
if (seen < low[at]) low[at] = seen;
|
|
6385
|
+
continue;
|
|
6386
|
+
}
|
|
6387
|
+
const k = visit(child);
|
|
6388
|
+
if (low[k] < low[at]) low[at] = low[k];
|
|
6389
|
+
if (found[k]) found[at] = true;
|
|
6390
|
+
}
|
|
6440
6391
|
}
|
|
6441
|
-
if (
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6392
|
+
if (low[at] === at) {
|
|
6393
|
+
const answer = found[at];
|
|
6394
|
+
let member;
|
|
6395
|
+
do {
|
|
6396
|
+
member = stack.pop();
|
|
6397
|
+
memo.set(member, answer);
|
|
6398
|
+
} while (member !== node2);
|
|
6399
|
+
}
|
|
6400
|
+
return at;
|
|
6401
|
+
};
|
|
6402
|
+
return found[visit(root)];
|
|
6445
6403
|
}
|
|
6446
|
-
function
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6404
|
+
function hasSemanticReduction(roots, externalRefs) {
|
|
6405
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6406
|
+
const visit = (parser2) => {
|
|
6407
|
+
if (seen.has(parser2)) return false;
|
|
6408
|
+
seen.add(parser2);
|
|
6409
|
+
const def = parser2._def;
|
|
6410
|
+
if (def.tag === "transform" && !def.recognitionOnly) return true;
|
|
6411
|
+
if (def.tag === "choice" && def.gates.some(Boolean)) return true;
|
|
6412
|
+
if (def.tag === "guard" || def.tag === "withCtx") return true;
|
|
6413
|
+
if (def.tag === "node" && def.build !== void 0) return true;
|
|
6414
|
+
if (def.tag === "lazy") {
|
|
6415
|
+
if (externalRefs?.has(parser2)) return false;
|
|
6416
|
+
try {
|
|
6417
|
+
return visit(def.thunk());
|
|
6418
|
+
} catch {
|
|
6419
|
+
return true;
|
|
6420
|
+
}
|
|
6421
|
+
}
|
|
6422
|
+
return childrenOf2(def).some(visit);
|
|
6423
|
+
};
|
|
6424
|
+
return roots.some(visit);
|
|
6458
6425
|
}
|
|
6459
|
-
function
|
|
6460
|
-
const
|
|
6461
|
-
const
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
rules: prog.rules
|
|
6426
|
+
function classifyRuleMap(ruleMap) {
|
|
6427
|
+
const externalRefs = /* @__PURE__ */ new Set();
|
|
6428
|
+
const scanned = /* @__PURE__ */ new Set();
|
|
6429
|
+
const scanExternal = (p) => {
|
|
6430
|
+
if (scanned.has(p)) return;
|
|
6431
|
+
scanned.add(p);
|
|
6432
|
+
const def = p._def;
|
|
6433
|
+
if (def.tag === "lazy") {
|
|
6434
|
+
let resolved;
|
|
6435
|
+
try {
|
|
6436
|
+
resolved = def.thunk();
|
|
6437
|
+
} catch {
|
|
6438
|
+
resolved = void 0;
|
|
6439
|
+
}
|
|
6440
|
+
if (resolved === void 0) {
|
|
6441
|
+
if (p._ruleName) externalRefs.add(p);
|
|
6442
|
+
return;
|
|
6443
|
+
}
|
|
6444
|
+
scanExternal(resolved);
|
|
6445
|
+
return;
|
|
6446
|
+
}
|
|
6447
|
+
for (const child of childrenOf2(def)) scanExternal(child);
|
|
6448
|
+
};
|
|
6449
|
+
for (const [, rule] of ruleMap) scanExternal(rule);
|
|
6450
|
+
return {
|
|
6451
|
+
hasDirectBuilders: ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
6452
|
+
isRecognitionOnly: !hasSemanticReduction(ruleMap.map(([, rule]) => rule), externalRefs)
|
|
6487
6453
|
};
|
|
6488
|
-
if (owner !== void 0) owner.resolved = built;
|
|
6489
|
-
return built;
|
|
6490
6454
|
}
|
|
6491
6455
|
|
|
6456
|
+
// src/table/ops.ts
|
|
6457
|
+
var OP_LIT = 1;
|
|
6458
|
+
var OP_RX = 2;
|
|
6459
|
+
var OP_SEQ = 3;
|
|
6460
|
+
var OP_SEQV = 4;
|
|
6461
|
+
var OP_CHOICE = 5;
|
|
6462
|
+
var OP_REP = 6;
|
|
6463
|
+
var OP_REPV = 7;
|
|
6464
|
+
var OP_OPT = 8;
|
|
6465
|
+
var OP_XFORM = 9;
|
|
6466
|
+
var OP_NODE = 10;
|
|
6467
|
+
var OP_RULE = 11;
|
|
6468
|
+
var OP_GATE = 12;
|
|
6469
|
+
var OP_NOT = 13;
|
|
6470
|
+
var OP_PEEK = 14;
|
|
6471
|
+
var OP_LEAF = 15;
|
|
6472
|
+
var OP_EMPTY = 16;
|
|
6473
|
+
var OP_LIT_TRACK = 17;
|
|
6474
|
+
var OP_RX_TRACK = 18;
|
|
6475
|
+
var OP_NODE_TRACK = 19;
|
|
6476
|
+
var OP_SCOPE = 20;
|
|
6477
|
+
var OP_EXPECT = 21;
|
|
6478
|
+
var OP_SEQX = 22;
|
|
6479
|
+
var OP_SCAN = 23;
|
|
6480
|
+
var OP_FIELD = 24;
|
|
6481
|
+
var OP_LIT_CI = 27;
|
|
6482
|
+
var OP_LIT_CI_TRACK = 28;
|
|
6483
|
+
var OP_TOKEN = 29;
|
|
6484
|
+
var OP_SCOPE_CAP = 30;
|
|
6485
|
+
var OP_WITHCTX = 31;
|
|
6486
|
+
var OP_GUARD = 32;
|
|
6487
|
+
var OP_ADJ = 33;
|
|
6488
|
+
var OP_GREEDY = 34;
|
|
6489
|
+
var OP_REJECT = 35;
|
|
6490
|
+
var OP_ARMGATE = 36;
|
|
6491
|
+
var OP_LIVE = 37;
|
|
6492
|
+
var OP_ATTEMPT = 38;
|
|
6493
|
+
var OP_LABEL = 39;
|
|
6494
|
+
var OP_COV = 40;
|
|
6495
|
+
var OP_SCOPE_PLAIN = 41;
|
|
6496
|
+
var OP_LEX_BODY = 42;
|
|
6497
|
+
var OP_LEX_PROGRAM = 43;
|
|
6498
|
+
var OP_SOURCE_LEAF = 44;
|
|
6499
|
+
var OP_DISPATCH = 25;
|
|
6500
|
+
var OP_ROUTED = 26;
|
|
6501
|
+
var OP_NAMES = {
|
|
6502
|
+
[OP_LIT]: "LIT",
|
|
6503
|
+
[OP_RX]: "RX",
|
|
6504
|
+
[OP_SEQ]: "SEQ",
|
|
6505
|
+
[OP_SEQV]: "SEQV",
|
|
6506
|
+
[OP_CHOICE]: "CHOICE",
|
|
6507
|
+
[OP_REP]: "REP",
|
|
6508
|
+
[OP_REPV]: "REPV",
|
|
6509
|
+
[OP_OPT]: "OPT",
|
|
6510
|
+
[OP_XFORM]: "XFORM",
|
|
6511
|
+
[OP_NODE]: "NODE",
|
|
6512
|
+
[OP_RULE]: "RULE",
|
|
6513
|
+
[OP_GATE]: "GATE",
|
|
6514
|
+
[OP_NOT]: "NOT",
|
|
6515
|
+
[OP_PEEK]: "PEEK",
|
|
6516
|
+
[OP_LEAF]: "LEAF",
|
|
6517
|
+
[OP_SOURCE_LEAF]: "SOURCE_LEAF",
|
|
6518
|
+
[OP_EMPTY]: "EMPTY",
|
|
6519
|
+
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
6520
|
+
[OP_RX_TRACK]: "RX_TRACK",
|
|
6521
|
+
[OP_NODE_TRACK]: "NODE_TRACK",
|
|
6522
|
+
[OP_SCOPE]: "SCOPE",
|
|
6523
|
+
[OP_EXPECT]: "EXPECT",
|
|
6524
|
+
[OP_SEQX]: "SEQX",
|
|
6525
|
+
[OP_SCAN]: "SCAN",
|
|
6526
|
+
[OP_FIELD]: "FIELD",
|
|
6527
|
+
[OP_LIT_CI]: "LIT_CI",
|
|
6528
|
+
[OP_LIT_CI_TRACK]: "LIT_CI_TRACK",
|
|
6529
|
+
[OP_DISPATCH]: "DISPATCH",
|
|
6530
|
+
[OP_ROUTED]: "ROUTED",
|
|
6531
|
+
[OP_TOKEN]: "TOKEN",
|
|
6532
|
+
[OP_SCOPE_CAP]: "SCOPE_CAP",
|
|
6533
|
+
[OP_WITHCTX]: "WITHCTX",
|
|
6534
|
+
[OP_GUARD]: "GUARD",
|
|
6535
|
+
[OP_ADJ]: "ADJ",
|
|
6536
|
+
[OP_GREEDY]: "GREEDY",
|
|
6537
|
+
[OP_REJECT]: "REJECT",
|
|
6538
|
+
[OP_ARMGATE]: "ARMGATE",
|
|
6539
|
+
[OP_LIVE]: "LIVE",
|
|
6540
|
+
[OP_ATTEMPT]: "ATTEMPT",
|
|
6541
|
+
[OP_LABEL]: "LABEL",
|
|
6542
|
+
[OP_COV]: "COV",
|
|
6543
|
+
[OP_SCOPE_PLAIN]: "SCOPE_PLAIN",
|
|
6544
|
+
[OP_LEX_BODY]: "LEX_BODY",
|
|
6545
|
+
[OP_LEX_PROGRAM]: "LEX_PROGRAM"
|
|
6546
|
+
};
|
|
6547
|
+
|
|
6492
6548
|
// src/compiler/direct-projection.ts
|
|
6493
6549
|
function directArrayProjection(fn, fnSrc, arity) {
|
|
6494
6550
|
let source = fnSrc;
|
|
@@ -7369,6 +7425,7 @@ var Encoder = class {
|
|
|
7369
7425
|
case "expect":
|
|
7370
7426
|
case "recover":
|
|
7371
7427
|
case "scanTo":
|
|
7428
|
+
case "lines":
|
|
7372
7429
|
case "unknown":
|
|
7373
7430
|
return true;
|
|
7374
7431
|
case "lazy": {
|
|
@@ -7589,6 +7646,18 @@ var Encoder = class {
|
|
|
7589
7646
|
open: bal.open,
|
|
7590
7647
|
close: bal.close
|
|
7591
7648
|
}));
|
|
7649
|
+
if (d.tag === "lines") {
|
|
7650
|
+
return this.emit(OP_SCAN, this.scanSlot({
|
|
7651
|
+
kind: 2,
|
|
7652
|
+
flags: 0,
|
|
7653
|
+
skip: [],
|
|
7654
|
+
prefix: this.subtree(d.prefix),
|
|
7655
|
+
body: this.subtree(d.body),
|
|
7656
|
+
...d.first === void 0 ? {} : { first: this.subtree(d.first) },
|
|
7657
|
+
...d.lazy === void 0 ? {} : { lazy: this.subtree(d.lazy) }
|
|
7658
|
+
}));
|
|
7659
|
+
}
|
|
7660
|
+
if (d.tag === "columns") return this.emit(OP_SCAN, this.scanSlot({ kind: 3, flags: 0, skip: [], n: d.n }));
|
|
7592
7661
|
if (d.tag === "scanTo") {
|
|
7593
7662
|
const sentDef = d.sentinel._def;
|
|
7594
7663
|
return this.emit(OP_SCAN, this.scanSlot({
|
|
@@ -8035,12 +8104,7 @@ var Encoder = class {
|
|
|
8035
8104
|
};
|
|
8036
8105
|
const seen = /* @__PURE__ */ new Set();
|
|
8037
8106
|
const refs = [];
|
|
8038
|
-
for (const s of this.scans)
|
|
8039
|
-
if (s.sentinel !== void 0) refs.push(s.sentinel);
|
|
8040
|
-
if (s.recoverAt !== void 0) refs.push(s.recoverAt);
|
|
8041
|
-
if (s.stopAt !== void 0) refs.push(s.stopAt);
|
|
8042
|
-
refs.push(...s.skip);
|
|
8043
|
-
}
|
|
8107
|
+
for (const s of this.scans) refs.push(...scanRefs(s));
|
|
8044
8108
|
for (const set of this.scanSkipSets) refs.push(...set);
|
|
8045
8109
|
const stack = [...Object.values(this.rules), ...refs.map((r) => r[0])];
|
|
8046
8110
|
while (stack.length > 0) {
|
|
@@ -8060,7 +8124,11 @@ var Encoder = class {
|
|
|
8060
8124
|
skip: s.skip.map(res),
|
|
8061
8125
|
...s.sentinel === void 0 ? {} : { sentinel: res(s.sentinel) },
|
|
8062
8126
|
...s.recoverAt === void 0 ? {} : { recoverAt: res(s.recoverAt) },
|
|
8063
|
-
...s.stopAt === void 0 ? {} : { stopAt: res(s.stopAt) }
|
|
8127
|
+
...s.stopAt === void 0 ? {} : { stopAt: res(s.stopAt) },
|
|
8128
|
+
...s.prefix === void 0 ? {} : { prefix: res(s.prefix) },
|
|
8129
|
+
...s.body === void 0 ? {} : { body: res(s.body) },
|
|
8130
|
+
...s.first === void 0 ? {} : { first: res(s.first) },
|
|
8131
|
+
...s.lazy === void 0 ? {} : { lazy: res(s.lazy) }
|
|
8064
8132
|
}));
|
|
8065
8133
|
this.scanSkipSets = this.scanSkipSets.map((set) => set.map(res));
|
|
8066
8134
|
}
|
|
@@ -8902,7 +8970,7 @@ function emitShapeMatch(shape, start, mint, ind, firstChar) {
|
|
|
8902
8970
|
if (shape.kind === "alt") {
|
|
8903
8971
|
const okV = mint("_ok");
|
|
8904
8972
|
const endV2 = mint("_end");
|
|
8905
|
-
const
|
|
8973
|
+
const lines2 = [`${ind}let ${okV} = false`, `${ind}let ${endV2} = ${start}`];
|
|
8906
8974
|
if (shape.arms.length >= 2 && shape.arms.every((a) => a.kind === "litFold" && a.open.length >= 1)) {
|
|
8907
8975
|
const groups = /* @__PURE__ */ new Map();
|
|
8908
8976
|
for (const a of shape.arms) {
|
|
@@ -8911,60 +8979,60 @@ function emitShapeMatch(shape, start, mint, ind, firstChar) {
|
|
|
8911
8979
|
const lower = f >= 65 && f <= 90 ? f + 32 : f;
|
|
8912
8980
|
(groups.get(lower) ?? groups.set(lower, []).get(lower)).push(open);
|
|
8913
8981
|
}
|
|
8914
|
-
|
|
8982
|
+
lines2.push(`${ind}if (${start} < input.length) switch (${codeAt(start, firstChar)}) {`);
|
|
8915
8983
|
for (const [lower, arms] of groups) {
|
|
8916
8984
|
const labels = lower >= 97 && lower <= 122 ? `case ${lower}: case ${lower - 32}:` : `case ${lower}:`;
|
|
8917
|
-
|
|
8985
|
+
lines2.push(`${ind} ${labels} {`);
|
|
8918
8986
|
for (const open of arms) {
|
|
8919
8987
|
const tail = open.slice(1).map((cp, i) => foldEq(`input.charCodeAt(${start} + ${i + 1})`, cp));
|
|
8920
8988
|
const cond = tail.length ? ` && ${tail.join(" && ")}` : "";
|
|
8921
|
-
|
|
8989
|
+
lines2.push(`${ind} if (${start} + ${open.length} <= input.length${cond}) { ${okV} = true; ${endV2} = ${start} + ${open.length}; break }`);
|
|
8922
8990
|
}
|
|
8923
|
-
|
|
8924
|
-
|
|
8991
|
+
lines2.push(`${ind} break`);
|
|
8992
|
+
lines2.push(`${ind} }`);
|
|
8925
8993
|
}
|
|
8926
|
-
|
|
8927
|
-
return { setup:
|
|
8994
|
+
lines2.push(`${ind}}`);
|
|
8995
|
+
return { setup: lines2, ok: okV, end: endV2 };
|
|
8928
8996
|
}
|
|
8929
8997
|
if (shape.disjoint) {
|
|
8930
8998
|
const plan = planAltSwitch(shape.firsts);
|
|
8931
8999
|
if (plan.kind === "switch") {
|
|
8932
|
-
|
|
9000
|
+
lines2.push(`${ind}if (${start} < input.length) switch (${codeAt(start, firstChar)}) {`);
|
|
8933
9001
|
shape.arms.forEach((arm, k) => {
|
|
8934
9002
|
const labels = plan.cases[k].map((cp) => `case ${cp}:`).join(" ");
|
|
8935
9003
|
const m = emitShapeMatch(arm, start, mint, `${ind} `, firstChar);
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
9004
|
+
lines2.push(`${ind} ${labels} {`);
|
|
9005
|
+
lines2.push(...m.setup);
|
|
9006
|
+
lines2.push(`${ind} ${okV} = ${m.ok}`);
|
|
9007
|
+
lines2.push(`${ind} ${endV2} = ${m.ok} ? ${m.end} : ${start}`);
|
|
9008
|
+
lines2.push(`${ind} break`);
|
|
9009
|
+
lines2.push(`${ind} }`);
|
|
8942
9010
|
});
|
|
8943
|
-
|
|
9011
|
+
lines2.push(`${ind}}`);
|
|
8944
9012
|
} else {
|
|
8945
9013
|
const c0 = codeAt(start, firstChar);
|
|
8946
9014
|
shape.arms.forEach((arm, k) => {
|
|
8947
9015
|
const fs3 = shape.firsts[k];
|
|
8948
9016
|
const cond = fs3.negated ? `!(${classCond(c0, fs3.ranges)})` : `(${classCond(c0, fs3.ranges)})`;
|
|
8949
9017
|
const m = emitShapeMatch(arm, start, mint, `${ind} `, firstChar);
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
9018
|
+
lines2.push(`${ind}${k === 0 ? "if" : "else if"} (${start} < input.length && ${cond}) {`);
|
|
9019
|
+
lines2.push(...m.setup);
|
|
9020
|
+
lines2.push(`${ind} ${okV} = ${m.ok}`);
|
|
9021
|
+
lines2.push(`${ind} ${endV2} = ${m.ok} ? ${m.end} : ${start}`);
|
|
9022
|
+
lines2.push(`${ind}}`);
|
|
8955
9023
|
});
|
|
8956
9024
|
}
|
|
8957
9025
|
} else {
|
|
8958
9026
|
const lbl = mint("_alt");
|
|
8959
|
-
|
|
9027
|
+
lines2.push(`${ind}${lbl}: {`);
|
|
8960
9028
|
for (const arm of shape.arms) {
|
|
8961
9029
|
const m = emitShapeMatch(arm, start, mint, `${ind} `, firstChar);
|
|
8962
|
-
|
|
8963
|
-
|
|
9030
|
+
lines2.push(...m.setup);
|
|
9031
|
+
lines2.push(`${ind} if (${m.ok}) { ${okV} = true; ${endV2} = ${m.end}; break ${lbl} }`);
|
|
8964
9032
|
}
|
|
8965
|
-
|
|
9033
|
+
lines2.push(`${ind}}`);
|
|
8966
9034
|
}
|
|
8967
|
-
return { setup:
|
|
9035
|
+
return { setup: lines2, ok: okV, end: endV2 };
|
|
8968
9036
|
}
|
|
8969
9037
|
if (shape.kind === "chars") {
|
|
8970
9038
|
const cur = mint("_e");
|
|
@@ -8999,64 +9067,64 @@ function emitShapeMatch(shape, start, mint, ind, firstChar) {
|
|
|
8999
9067
|
const c = classCond(`input.charCodeAt(${at})`, p.ranges);
|
|
9000
9068
|
return p.negated ? `!(${c})` : `(${c})`;
|
|
9001
9069
|
};
|
|
9002
|
-
const
|
|
9070
|
+
const lines2 = [`${ind}let ${endV2} = ${start}`, `${ind}let ${okV} = false`, `${ind}do {`];
|
|
9003
9071
|
let first = true;
|
|
9004
9072
|
for (const p of shape.parts) {
|
|
9005
9073
|
if (p.part === "lit") {
|
|
9006
9074
|
const L = p.cps.length;
|
|
9007
9075
|
const cond = litCond(endV2, p.cps, first ? firstChar : void 0);
|
|
9008
9076
|
if (p.optional) {
|
|
9009
|
-
|
|
9077
|
+
lines2.push(`${ind} if (${endV2} + ${L} <= input.length && (${cond})) ${endV2} += ${L}`);
|
|
9010
9078
|
} else {
|
|
9011
|
-
|
|
9012
|
-
|
|
9079
|
+
lines2.push(`${ind} if (!(${endV2} + ${L} <= input.length && (${cond}))) break`);
|
|
9080
|
+
lines2.push(`${ind} ${endV2} += ${L}`);
|
|
9013
9081
|
}
|
|
9014
9082
|
} else if (p.part === "run" && p.max === Infinity) {
|
|
9015
9083
|
const s = mint("_s");
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
if (p.min === 1)
|
|
9019
|
-
else if (p.min > 1)
|
|
9084
|
+
lines2.push(`${ind} const ${s} = ${endV2}`);
|
|
9085
|
+
lines2.push(`${ind} while (${endV2} < input.length && ${runCond(p, endV2)}) ${endV2}++`);
|
|
9086
|
+
if (p.min === 1) lines2.push(`${ind} if (${endV2} === ${s}) break`);
|
|
9087
|
+
else if (p.min > 1) lines2.push(`${ind} if (${endV2} - ${s} < ${p.min}) break`);
|
|
9020
9088
|
} else if (p.part === "run" && p.max === 1) {
|
|
9021
9089
|
if (p.min === 1) {
|
|
9022
|
-
|
|
9023
|
-
|
|
9090
|
+
lines2.push(`${ind} if (!(${endV2} < input.length && ${runCond(p, endV2)})) break`);
|
|
9091
|
+
lines2.push(`${ind} ${endV2}++`);
|
|
9024
9092
|
} else {
|
|
9025
|
-
|
|
9093
|
+
lines2.push(`${ind} if (${endV2} < input.length && ${runCond(p, endV2)}) ${endV2}++`);
|
|
9026
9094
|
}
|
|
9027
9095
|
} else if (p.part === "run") {
|
|
9028
9096
|
const s = mint("_s");
|
|
9029
|
-
|
|
9030
|
-
|
|
9031
|
-
if (p.min > 0)
|
|
9097
|
+
lines2.push(`${ind} const ${s} = ${endV2}`);
|
|
9098
|
+
lines2.push(`${ind} while (${endV2} - ${s} < ${p.max} && ${endV2} < input.length && ${runCond(p, endV2)}) ${endV2}++`);
|
|
9099
|
+
if (p.min > 0) lines2.push(`${ind} if (${endV2} - ${s} < ${p.min}) break`);
|
|
9032
9100
|
} else {
|
|
9033
9101
|
const inner = emitShapeMatch(p.inner, endV2, mint, `${ind} `, first ? firstChar : void 0);
|
|
9034
9102
|
if (!p.unbounded) {
|
|
9035
|
-
|
|
9103
|
+
lines2.push(...inner.setup);
|
|
9036
9104
|
if (p.min === 1) {
|
|
9037
|
-
|
|
9038
|
-
|
|
9105
|
+
lines2.push(`${ind} if (!(${inner.ok})) break`);
|
|
9106
|
+
lines2.push(`${ind} ${endV2} = ${inner.end}`);
|
|
9039
9107
|
} else {
|
|
9040
|
-
|
|
9108
|
+
lines2.push(`${ind} if (${inner.ok}) ${endV2} = ${inner.end}`);
|
|
9041
9109
|
}
|
|
9042
9110
|
} else {
|
|
9043
9111
|
const progV = mint("_prog");
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
if (p.min === 1)
|
|
9112
|
+
lines2.push(`${ind} let ${progV} = false`);
|
|
9113
|
+
lines2.push(`${ind} while (true) {`);
|
|
9114
|
+
lines2.push(...inner.setup);
|
|
9115
|
+
lines2.push(`${ind} if (!(${inner.ok})) break`);
|
|
9116
|
+
lines2.push(`${ind} ${endV2} = ${inner.end}`);
|
|
9117
|
+
lines2.push(`${ind} ${progV} = true`);
|
|
9118
|
+
lines2.push(`${ind} }`);
|
|
9119
|
+
if (p.min === 1) lines2.push(`${ind} if (!${progV}) break`);
|
|
9052
9120
|
}
|
|
9053
9121
|
}
|
|
9054
9122
|
first = false;
|
|
9055
9123
|
}
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
return { setup:
|
|
9124
|
+
lines2.push(`${ind} ${okV} = true`);
|
|
9125
|
+
lines2.push(`${ind}} while (false)`);
|
|
9126
|
+
lines2.push(`${ind}if (!${okV}) ${endV2} = ${start}`);
|
|
9127
|
+
return { setup: lines2, ok: okV, end: endV2 };
|
|
9060
9128
|
}
|
|
9061
9129
|
if (shape.kind === "litFold") {
|
|
9062
9130
|
const openLen2 = shape.open.length;
|
|
@@ -11333,6 +11401,188 @@ finish:_finish
|
|
|
11333
11401
|
};
|
|
11334
11402
|
}
|
|
11335
11403
|
|
|
11404
|
+
// src/combinators/lines.ts
|
|
11405
|
+
function lineIndexAt(view, offset) {
|
|
11406
|
+
const lines2 = view.lines;
|
|
11407
|
+
let lo = 0, hi = lines2.length - 1;
|
|
11408
|
+
while (lo < hi) {
|
|
11409
|
+
const mid = lo + hi + 1 >> 1;
|
|
11410
|
+
if (lines2[mid].offset <= offset) lo = mid;
|
|
11411
|
+
else hi = mid - 1;
|
|
11412
|
+
}
|
|
11413
|
+
return lo;
|
|
11414
|
+
}
|
|
11415
|
+
var lineAt = (view, offset) => view.lines[lineIndexAt(view, offset)];
|
|
11416
|
+
function sourceOffset(view, offset) {
|
|
11417
|
+
const line = lineAt(view, offset);
|
|
11418
|
+
return line === void 0 ? offset : line.source + (offset - line.offset);
|
|
11419
|
+
}
|
|
11420
|
+
function columnAt(input, pos, ctx) {
|
|
11421
|
+
const view = ctx.lineView;
|
|
11422
|
+
let start, column, split;
|
|
11423
|
+
const line = view === void 0 ? void 0 : lineAt(view, pos);
|
|
11424
|
+
if (line !== void 0 && pos >= line.offset) {
|
|
11425
|
+
start = line.offset;
|
|
11426
|
+
column = line.column;
|
|
11427
|
+
split = line.split;
|
|
11428
|
+
} else {
|
|
11429
|
+
start = input.lastIndexOf("\n", pos - 1) + 1;
|
|
11430
|
+
column = 0;
|
|
11431
|
+
split = 0;
|
|
11432
|
+
}
|
|
11433
|
+
for (let i = start; i < pos; i++) {
|
|
11434
|
+
if (input.charCodeAt(i) === 9) {
|
|
11435
|
+
const width = 4 - (column - (i === start ? split : 0)) % 4 - (i === start ? split : 0);
|
|
11436
|
+
column += width;
|
|
11437
|
+
} else column++;
|
|
11438
|
+
split = 0;
|
|
11439
|
+
}
|
|
11440
|
+
return { column, split: pos === start ? split : 0 };
|
|
11441
|
+
}
|
|
11442
|
+
function columns(n) {
|
|
11443
|
+
if (!Number.isInteger(n) || n < 0) throw new TypeError(`columns(n) needs a non-negative integer, got ${n}`);
|
|
11444
|
+
const expected = [`columns(${n})`];
|
|
11445
|
+
const meta = {
|
|
11446
|
+
firstSet: n === 0 ? any() : { kind: "ranges", ranges: [{ lo: 9, hi: 9 }, { lo: 32, hi: 32 }] },
|
|
11447
|
+
canMatchNewline: false,
|
|
11448
|
+
isTrivia: false
|
|
11449
|
+
};
|
|
11450
|
+
return {
|
|
11451
|
+
_tag: "columns",
|
|
11452
|
+
_meta: meta,
|
|
11453
|
+
_def: { tag: "columns", n },
|
|
11454
|
+
parse(input, pos, ctx) {
|
|
11455
|
+
const c = ctx;
|
|
11456
|
+
let { column, split } = columnAt(input, pos, c);
|
|
11457
|
+
const goal = column + n;
|
|
11458
|
+
let at = pos;
|
|
11459
|
+
while (column < goal) {
|
|
11460
|
+
const code = input.charCodeAt(at);
|
|
11461
|
+
if (code === 32) {
|
|
11462
|
+
column++;
|
|
11463
|
+
split = 0;
|
|
11464
|
+
at++;
|
|
11465
|
+
continue;
|
|
11466
|
+
}
|
|
11467
|
+
if (code !== 9) return { ok: false, expected, span: { start: at, end: at } };
|
|
11468
|
+
const width = 4 - (column - split) % 4 - split;
|
|
11469
|
+
if (column + width > goal) {
|
|
11470
|
+
c._columnsSplit = { at, split: split + (goal - column) };
|
|
11471
|
+
return { ok: true, value: input.slice(pos, at), span: { start: pos, end: at } };
|
|
11472
|
+
}
|
|
11473
|
+
column += width;
|
|
11474
|
+
split = 0;
|
|
11475
|
+
at++;
|
|
11476
|
+
}
|
|
11477
|
+
return { ok: true, value: input.slice(pos, at), span: { start: pos, end: at } };
|
|
11478
|
+
}
|
|
11479
|
+
};
|
|
11480
|
+
}
|
|
11481
|
+
function lines(prefix, body, options = {}) {
|
|
11482
|
+
const { first, lazy } = options;
|
|
11483
|
+
const opening = first ?? prefix;
|
|
11484
|
+
const meta = {
|
|
11485
|
+
// An opening that matches empty starts a run at any character.
|
|
11486
|
+
firstSet: matchesEmpty(opening) ? any() : opening._meta.firstSet,
|
|
11487
|
+
canMatchNewline: true,
|
|
11488
|
+
isTrivia: false
|
|
11489
|
+
};
|
|
11490
|
+
return {
|
|
11491
|
+
_tag: "lines",
|
|
11492
|
+
_meta: meta,
|
|
11493
|
+
_def: { tag: "lines", prefix, body, ...first === void 0 ? {} : { first }, ...lazy === void 0 ? {} : { lazy } },
|
|
11494
|
+
parse(input, pos, ctx) {
|
|
11495
|
+
const c = ctx;
|
|
11496
|
+
const probe = createDetachedParseContext(false, ctx.state);
|
|
11497
|
+
probe.lineView = c.lineView;
|
|
11498
|
+
const run = [];
|
|
11499
|
+
const parts = [];
|
|
11500
|
+
let offset = 0;
|
|
11501
|
+
for (let start = pos; start < input.length || start === pos; ) {
|
|
11502
|
+
let end2 = input.indexOf("\n", start);
|
|
11503
|
+
if (end2 < 0) end2 = input.length;
|
|
11504
|
+
probe._columnsSplit = void 0;
|
|
11505
|
+
const head = (run.length === 0 ? opening : prefix).parse(input, start, probe);
|
|
11506
|
+
let content;
|
|
11507
|
+
let joined;
|
|
11508
|
+
if (head.ok && head.span.end <= end2) {
|
|
11509
|
+
content = head.span.end;
|
|
11510
|
+
joined = "prefix";
|
|
11511
|
+
} else if (run.length === 0) {
|
|
11512
|
+
return { ok: false, expected: head.ok ? ["line prefix"] : head.expected, span: { start, end: start } };
|
|
11513
|
+
} else if (lazy !== void 0 && lazy.parse(input, start, probe).ok) {
|
|
11514
|
+
content = start;
|
|
11515
|
+
joined = "lazy";
|
|
11516
|
+
} else break;
|
|
11517
|
+
const mark = probe._columnsSplit;
|
|
11518
|
+
const here = columnAt(input, content, c);
|
|
11519
|
+
const split = joined === "prefix" && mark !== void 0 && mark.at === content ? mark.split : here.split;
|
|
11520
|
+
run.push({ offset, source: content, end: end2, column: here.column + (split - here.split), split, lazy: joined === "lazy" });
|
|
11521
|
+
const text = input.slice(content, end2);
|
|
11522
|
+
const newline = end2 < input.length;
|
|
11523
|
+
parts.push(newline ? `${text}
|
|
11524
|
+
` : text);
|
|
11525
|
+
offset += text.length + (newline ? 1 : 0);
|
|
11526
|
+
start = end2 + 1;
|
|
11527
|
+
if (!newline) break;
|
|
11528
|
+
}
|
|
11529
|
+
const view = { lines: run, parent: c.lineView };
|
|
11530
|
+
const saved = c.lineView, starts = c._lineStarts, lineIndex = c._lineIndex, scanned = c._lineScannedTo, probing = c._probe;
|
|
11531
|
+
const errors = c._errors?.length ?? 0;
|
|
11532
|
+
let cursor = -1;
|
|
11533
|
+
if (probing !== void 0) for (const line2 of run) {
|
|
11534
|
+
if (probing.offset >= line2.source && probing.offset <= line2.end) {
|
|
11535
|
+
cursor = line2.offset + probing.offset - line2.source;
|
|
11536
|
+
break;
|
|
11537
|
+
}
|
|
11538
|
+
}
|
|
11539
|
+
const inner = cursor < 0 ? void 0 : { offset: cursor, best: null };
|
|
11540
|
+
c.lineView = view;
|
|
11541
|
+
c._lineStarts = void 0;
|
|
11542
|
+
c._lineIndex = void 0;
|
|
11543
|
+
c._lineScannedTo = void 0;
|
|
11544
|
+
c._probe = inner;
|
|
11545
|
+
let result;
|
|
11546
|
+
try {
|
|
11547
|
+
result = body.parse(parts.join(""), 0, ctx);
|
|
11548
|
+
} finally {
|
|
11549
|
+
c.lineView = saved;
|
|
11550
|
+
c._lineStarts = starts;
|
|
11551
|
+
c._lineIndex = lineIndex;
|
|
11552
|
+
c._lineScannedTo = scanned;
|
|
11553
|
+
c._probe = probing;
|
|
11554
|
+
}
|
|
11555
|
+
if (inner?.best) failAt(c, inner.best.expected, sourceOffset(view, inner.best.span.start));
|
|
11556
|
+
if (c._errors !== void 0) for (let i = errors; i < c._errors.length; i++) {
|
|
11557
|
+
const error = c._errors[i];
|
|
11558
|
+
error.span = { start: sourceOffset(view, error.span.start), end: sourceOffset(view, error.span.end) };
|
|
11559
|
+
}
|
|
11560
|
+
if (!result.ok) {
|
|
11561
|
+
const at = sourceOffset(view, result.span.start);
|
|
11562
|
+
return { ...result, span: { start: at, end: at } };
|
|
11563
|
+
}
|
|
11564
|
+
const stop = result.span.end;
|
|
11565
|
+
const index = lineIndexAt(view, stop);
|
|
11566
|
+
const line = run[index];
|
|
11567
|
+
const end = stop === line.offset && index > 0 ? run[index - 1].end + 1 : stop - line.offset > line.end - line.source ? line.end + 1 : line.source + (stop - line.offset);
|
|
11568
|
+
recordLineRangeFromContext(c, input, pos, end);
|
|
11569
|
+
return { ok: true, value: result.value, span: { start: pos, end } };
|
|
11570
|
+
}
|
|
11571
|
+
};
|
|
11572
|
+
}
|
|
11573
|
+
|
|
11574
|
+
// src/table/line-scan.ts
|
|
11575
|
+
function rebuildLineScan(s, subtree) {
|
|
11576
|
+
if (s.kind === 2) {
|
|
11577
|
+
return lines(subtree(s.prefix), subtree(s.body), {
|
|
11578
|
+
...s.first === void 0 ? {} : { first: subtree(s.first) },
|
|
11579
|
+
...s.lazy === void 0 ? {} : { lazy: subtree(s.lazy) }
|
|
11580
|
+
});
|
|
11581
|
+
}
|
|
11582
|
+
if (s.kind === 3) return columns(s.n);
|
|
11583
|
+
return void 0;
|
|
11584
|
+
}
|
|
11585
|
+
|
|
11336
11586
|
// src/combinators/scanTo.ts
|
|
11337
11587
|
function resolveScanSkip(explicitSkip, raw, ctx) {
|
|
11338
11588
|
if (raw) return [];
|
|
@@ -11649,7 +11899,7 @@ function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(pr
|
|
|
11649
11899
|
...prog.labels === void 0 ? {} : { triviaKindLabels: prog.labels },
|
|
11650
11900
|
...prog.classified === 1 ? { rootTriviaClassified: true } : {}
|
|
11651
11901
|
};
|
|
11652
|
-
const
|
|
11902
|
+
const lines2 = prog.lines === 1;
|
|
11653
11903
|
const mode = prog.hostMode ?? "ast";
|
|
11654
11904
|
const elided = mode === "ast" && hasDirectBuilder(prog);
|
|
11655
11905
|
const coverageDefinitions = prog.cov === void 0 ? void 0 : Object.freeze(covDefinitions(prog).map(Object.freeze));
|
|
@@ -11677,7 +11927,7 @@ function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(pr
|
|
|
11677
11927
|
ctx._fe = -1;
|
|
11678
11928
|
ctx._fx = EMPTY_FX;
|
|
11679
11929
|
ctx._fc = false;
|
|
11680
|
-
if (
|
|
11930
|
+
if (lines2 && ctx._lineStarts === void 0) {
|
|
11681
11931
|
ctx._lineStarts = [0];
|
|
11682
11932
|
ctx._lineScannedTo = 0;
|
|
11683
11933
|
}
|
|
@@ -11685,10 +11935,10 @@ function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(pr
|
|
|
11685
11935
|
if (end < 0) {
|
|
11686
11936
|
const fe = ctx._fe;
|
|
11687
11937
|
const at = fe === void 0 || fe < 0 ? pos : fe;
|
|
11688
|
-
const fspan =
|
|
11938
|
+
const fspan = lines2 ? spanLines(ctx, at, at) : { start: at, end: at };
|
|
11689
11939
|
return committed2(ctx) ? { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan, committed: true } : { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan };
|
|
11690
11940
|
}
|
|
11691
|
-
return { ok: true, value: d.lastValue(), span:
|
|
11941
|
+
return { ok: true, value: d.lastValue(), span: lines2 ? spanLines(ctx, pos, end) : { start: pos, end } };
|
|
11692
11942
|
};
|
|
11693
11943
|
const ownTrivia = triviaOfRule(prog.rules[name]);
|
|
11694
11944
|
const meta = ownTrivia === void 0 ? baseMeta : { ...baseMeta, grammarTrivia: ownTrivia };
|
|
@@ -11783,12 +12033,7 @@ function assemble(t, prog, cfg) {
|
|
|
11783
12033
|
return recognize;
|
|
11784
12034
|
}
|
|
11785
12035
|
const labelExtraIps = [];
|
|
11786
|
-
for (const s of prog.scans ?? [])
|
|
11787
|
-
for (const r of s.skip) labelExtraIps.push(r[0]);
|
|
11788
|
-
if (s.sentinel !== void 0) labelExtraIps.push(s.sentinel[0]);
|
|
11789
|
-
if (s.recoverAt !== void 0) labelExtraIps.push(s.recoverAt[0]);
|
|
11790
|
-
if (s.stopAt !== void 0) labelExtraIps.push(s.stopAt[0]);
|
|
11791
|
-
}
|
|
12036
|
+
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) labelExtraIps.push(r[0]);
|
|
11792
12037
|
for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
|
|
11793
12038
|
const closureLabels = computeSiteLabels(
|
|
11794
12039
|
code,
|
|
@@ -14599,12 +14844,7 @@ function assemble(t, prog, cfg) {
|
|
|
14599
14844
|
let emitReached;
|
|
14600
14845
|
{
|
|
14601
14846
|
const extraIps = [];
|
|
14602
|
-
for (const s of prog.scans ?? [])
|
|
14603
|
-
for (const r of s.skip) extraIps.push(r[0]);
|
|
14604
|
-
if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
|
|
14605
|
-
if (s.recoverAt !== void 0) extraIps.push(s.recoverAt[0]);
|
|
14606
|
-
if (s.stopAt !== void 0) extraIps.push(s.stopAt[0]);
|
|
14607
|
-
}
|
|
14847
|
+
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) extraIps.push(r[0]);
|
|
14608
14848
|
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
14609
14849
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
14610
14850
|
for (const ip of reachableSites(code, roots)) {
|
|
@@ -14801,6 +15041,11 @@ function assemble(t, prog, cfg) {
|
|
|
14801
15041
|
return link(ip);
|
|
14802
15042
|
}
|
|
14803
15043
|
for (const s of prog.scans ?? []) {
|
|
15044
|
+
const rebuilt = rebuildLineScan(s, subtreeComb);
|
|
15045
|
+
if (rebuilt !== void 0) {
|
|
15046
|
+
scansArr.push(rebuilt);
|
|
15047
|
+
continue;
|
|
15048
|
+
}
|
|
14804
15049
|
const skip = s.skip.map((r) => subtreeComb(r));
|
|
14805
15050
|
const raw = (s.flags & 1) !== 0;
|
|
14806
15051
|
if (s.kind === 1) {
|
|
@@ -14986,7 +15231,8 @@ function tableRules(source, metadataOrEntry = {}) {
|
|
|
14986
15231
|
scanSkipFor: (ri, ctx) => {
|
|
14987
15232
|
const a = cache.forCtx(ctx);
|
|
14988
15233
|
selected = a;
|
|
14989
|
-
|
|
15234
|
+
const slot = skipOf?.[ri];
|
|
15235
|
+
return slot === void 0 || slot < 0 ? void 0 : a.scanSkip[slot];
|
|
14990
15236
|
}
|
|
14991
15237
|
}, artifactMetadata, resolved);
|
|
14992
15238
|
if (entry === void 0) return map;
|
|
@@ -15041,6 +15287,11 @@ function emitScanSpec(s) {
|
|
|
15041
15287
|
if (s.sent !== void 0) parts.push(`sent:${s.sent === null ? "null" : jsString(s.sent)}`);
|
|
15042
15288
|
if (s.open !== void 0) parts.push(`open:${jsString(s.open)}`);
|
|
15043
15289
|
if (s.close !== void 0) parts.push(`close:${jsString(s.close)}`);
|
|
15290
|
+
for (const key of ["prefix", "body", "first", "lazy"]) {
|
|
15291
|
+
const r = s[key];
|
|
15292
|
+
if (r !== void 0) parts.push(`${key}:${emitRef(r)}`);
|
|
15293
|
+
}
|
|
15294
|
+
if (s.n !== void 0) parts.push(`n:${s.n}`);
|
|
15044
15295
|
return `{${parts.join(",")}}`;
|
|
15045
15296
|
}
|
|
15046
15297
|
function emitDispatchSpec(d) {
|
|
@@ -15061,12 +15312,7 @@ function emitAssemblies(prog, cfgs) {
|
|
|
15061
15312
|
if (cfgs.length === 0) return ["a:[],"];
|
|
15062
15313
|
const t = resolveTable(prog);
|
|
15063
15314
|
const extraIps = [];
|
|
15064
|
-
for (const s of prog.scans ?? [])
|
|
15065
|
-
for (const r of s.skip) extraIps.push(r[0]);
|
|
15066
|
-
if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
|
|
15067
|
-
if (s.recoverAt !== void 0) extraIps.push(s.recoverAt[0]);
|
|
15068
|
-
if (s.stopAt !== void 0) extraIps.push(s.stopAt[0]);
|
|
15069
|
-
}
|
|
15315
|
+
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) extraIps.push(r[0]);
|
|
15070
15316
|
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
15071
15317
|
const out = [];
|
|
15072
15318
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -15218,6 +15464,8 @@ function children(def, winners) {
|
|
|
15218
15464
|
...def.recoverAt === void 0 ? [] : [def.recoverAt],
|
|
15219
15465
|
...def.stopAt === void 0 ? [] : [def.stopAt]
|
|
15220
15466
|
];
|
|
15467
|
+
case "lines":
|
|
15468
|
+
return [def.prefix, def.body, ...def.first === void 0 ? [] : [def.first], ...def.lazy === void 0 ? [] : [def.lazy]];
|
|
15221
15469
|
case "lazy": {
|
|
15222
15470
|
let resolved;
|
|
15223
15471
|
try {
|
|
@@ -15361,6 +15609,10 @@ function payloadKey(p, d) {
|
|
|
15361
15609
|
return `expect\0${d.label ?? ""}\0${d.expected.join("")}`;
|
|
15362
15610
|
case "scanTo":
|
|
15363
15611
|
return `scanTo\0${d.raw}\0${d.orEOF}\0${d.recoverAt !== void 0}\0${d.stopAt !== void 0}`;
|
|
15612
|
+
case "lines":
|
|
15613
|
+
return `lines\0${d.first !== void 0}\0${d.lazy !== void 0}`;
|
|
15614
|
+
case "columns":
|
|
15615
|
+
return `columns\0${d.n}`;
|
|
15364
15616
|
case "guard":
|
|
15365
15617
|
return `guard\0${fnKey(d.predSrc, d.predicate)}`;
|
|
15366
15618
|
case "adjacency":
|
|
@@ -15481,6 +15733,8 @@ function segment(d, index) {
|
|
|
15481
15733
|
if (d.recoverAt !== void 0 && index === d.skip.length + 1) return "scanTo.recoverAt";
|
|
15482
15734
|
return "scanTo.stopAt";
|
|
15483
15735
|
}
|
|
15736
|
+
case "lines":
|
|
15737
|
+
return ["lines.prefix", "lines.body", d.first === void 0 ? "lines.lazy" : "lines.first", "lines.lazy"][index] ?? "lines";
|
|
15484
15738
|
default:
|
|
15485
15739
|
return d.tag;
|
|
15486
15740
|
}
|
|
@@ -16523,60 +16777,60 @@ function findKeywordRegexes(visited) {
|
|
|
16523
16777
|
var sitesLine = (sites) => sites.slice(0, 6).map(siteToString).join("\n ") + (sites.length > 6 ? `
|
|
16524
16778
|
\u2026 and ${sites.length - 6} more` : "");
|
|
16525
16779
|
function formatDuplicationFindings(report) {
|
|
16526
|
-
const
|
|
16780
|
+
const lines2 = [];
|
|
16527
16781
|
for (const f of report.structureLoss) {
|
|
16528
|
-
|
|
16529
|
-
|
|
16530
|
-
|
|
16531
|
-
|
|
16532
|
-
|
|
16782
|
+
lines2.push(`parseman BUG [structure-loss] @ ${siteToString(f.site)}: arm[${f.earlier}] flattens \`${f.nodeType}\` where arm[${f.later}] structures it, on ${firstSetToString(f.on)}`);
|
|
16783
|
+
lines2.push(` flat: ${f.earlierShape}`);
|
|
16784
|
+
lines2.push(` rich: ${f.laterShape}`);
|
|
16785
|
+
lines2.push(` lost: ${f.lostNodeTypes.map((t) => `\`${t}\``).join(", ")}`);
|
|
16786
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16533
16787
|
}
|
|
16534
16788
|
for (const f of report.rewrites) {
|
|
16535
|
-
|
|
16536
|
-
|
|
16537
|
-
|
|
16538
|
-
|
|
16539
|
-
if (f.perf !== "")
|
|
16789
|
+
lines2.push(`parseman ${f.bug ? "BUG" : "rewrite"} [${f.rewrite}${f.sepByVerdict === void 0 ? "" : `/${f.sepByVerdict}`}] @ ${siteToString(f.site)}${f.astNeutral ? "" : " (candidate \u2014 verify AST identity)"}`);
|
|
16790
|
+
lines2.push(` from: ${f.from}`);
|
|
16791
|
+
lines2.push(` to: ${f.to}`);
|
|
16792
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16793
|
+
if (f.perf !== "") lines2.push(` perf: ${f.perf}`);
|
|
16540
16794
|
}
|
|
16541
16795
|
for (const f of report.divergentNodes) {
|
|
16542
|
-
|
|
16543
|
-
for (const p of f.productions)
|
|
16796
|
+
lines2.push(`parseman divergent-node: \`${f.nodeType}\` is built by ${f.count} different productions sharing ${f.sharedTerms.length} term(s): ${f.sharedTerms.map((t) => `\`${t}\``).join(", ")}`);
|
|
16797
|
+
for (const p of f.productions) lines2.push(` ${siteToString(p.site)}
|
|
16544
16798
|
${p.shape}
|
|
16545
16799
|
unique to it: ${p.distinctTerms.length === 0 ? "(none)" : p.distinctTerms.map((t) => `\`${t}\``).join(", ")}`);
|
|
16546
|
-
|
|
16800
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16547
16801
|
}
|
|
16548
16802
|
for (const f of report.keywordRegexes) {
|
|
16549
16803
|
const src = f.source.length > 90 ? `${f.source.slice(0, 88)}\u2026` : f.source;
|
|
16550
|
-
|
|
16551
|
-
|
|
16804
|
+
lines2.push(`parseman ${f.bug ? "BUG " : ""}keyword-regex @ ${siteToString(f.site)}: /${src}/${f.flags}${f.vocabulary ? ` [${f.words.length} literal words${f.longestFirst ? "" : ", NOT longest-first"}]` : ""}${f.hazards.length > 0 ? ` [${f.hazards.length} prefix hazard(s)${f.bug ? ", UNRESCUED" : ""}]` : ""}${f.caseFoldRisk ? " [CASE-FOLD RISK]" : ""}`);
|
|
16805
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16552
16806
|
}
|
|
16553
16807
|
for (const f of report.duplicates) {
|
|
16554
|
-
|
|
16555
|
-
|
|
16556
|
-
|
|
16808
|
+
lines2.push(`parseman duplication: ${f.count}\xD7 identical ${f.size}-node shape (saves ${f.savings} nodes) \u2014 ${f.shape}`);
|
|
16809
|
+
lines2.push(` at: ${sitesLine(f.sites)}`);
|
|
16810
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16557
16811
|
}
|
|
16558
16812
|
for (const f of report.nearDuplicates) {
|
|
16559
|
-
|
|
16560
|
-
|
|
16561
|
-
|
|
16562
|
-
|
|
16813
|
+
lines2.push(`parseman near-duplication: ${f.count} clones of a ${f.sharedSize}-node shape differing at ONE slot (saves ${f.savings} nodes) \u2014 ${f.shape}`);
|
|
16814
|
+
lines2.push(` slot: ${f.slotPath} \u2208 { ${f.variants.join(" | ")} }`);
|
|
16815
|
+
lines2.push(` at: ${sitesLine(f.sites)}`);
|
|
16816
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16563
16817
|
}
|
|
16564
16818
|
for (const f of report.regexFragments) {
|
|
16565
|
-
|
|
16566
|
-
|
|
16567
|
-
|
|
16819
|
+
lines2.push(`parseman regex-fragment: \`${f.fragment}\` (${f.branches} branches) re-spelled in ${f.count} regex() terminals`);
|
|
16820
|
+
lines2.push(` at: ${sitesLine(f.sites)}`);
|
|
16821
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16568
16822
|
}
|
|
16569
16823
|
for (const f of report.regexClasses) {
|
|
16570
|
-
|
|
16571
|
-
for (const v of f.variants)
|
|
16824
|
+
lines2.push(`parseman regex-class${f.drifted ? " DRIFT" : ""}: [${f.canonical}] across ${f.count} regex() terminals${f.bmpCeiling ? " [BMP ceiling]" : ""}`);
|
|
16825
|
+
for (const v of f.variants) lines2.push(` [${v.source}] \xD7${v.count} ${v.delta}
|
|
16572
16826
|
${sitesLine(v.sites)}`);
|
|
16573
|
-
|
|
16827
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16574
16828
|
}
|
|
16575
16829
|
for (const f of report.overlaps) {
|
|
16576
|
-
|
|
16577
|
-
|
|
16830
|
+
lines2.push(`parseman overlap @ ${siteToString(f.site)}: arm[${f.a}] \u2229 arm[${f.b}] on ${firstSetToString(f.on)}${f.sharedPrefix === null ? "" : ` \u2014 shared prefix: ${f.sharedPrefix}`}${f.handledByStrategy ? " [sharedPrefix strategy already handles this]" : ""}`);
|
|
16831
|
+
lines2.push(` fix: ${f.suggestion}`);
|
|
16578
16832
|
}
|
|
16579
|
-
return
|
|
16833
|
+
return lines2;
|
|
16580
16834
|
}
|
|
16581
16835
|
function duplicationFindingCount(report) {
|
|
16582
16836
|
return report.duplicates.length + report.nearDuplicates.length + report.regexFragments.length + report.regexClasses.length + report.overlaps.length + report.rewrites.length + report.divergentNodes.length + report.structureLoss.length + report.keywordRegexes.length;
|
|
@@ -16610,11 +16864,11 @@ function reportDuplication(opt, analyze) {
|
|
|
16610
16864
|
);
|
|
16611
16865
|
return void 0;
|
|
16612
16866
|
}
|
|
16613
|
-
const
|
|
16614
|
-
if (
|
|
16867
|
+
const lines2 = formatDuplicationFindings(report);
|
|
16868
|
+
if (lines2.length > 0) {
|
|
16615
16869
|
if (level === "error") throw new Error(`parseman: ${duplicationFindingCount(report)} duplication/overlap finding(s)
|
|
16616
|
-
${
|
|
16617
|
-
for (const l of
|
|
16870
|
+
${lines2.join("\n")}`);
|
|
16871
|
+
for (const l of lines2) console.warn(l);
|
|
16618
16872
|
}
|
|
16619
16873
|
return report;
|
|
16620
16874
|
}
|
|
@@ -16895,8 +17149,11 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
|
16895
17149
|
// falls back to regex-scanning generated hooks; a table has no hooks to scan,
|
|
16896
17150
|
// so this is the channel.
|
|
16897
17151
|
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
16898
|
-
parse
|
|
16899
|
-
|
|
17152
|
+
// The same three arguments as a combinator's own `parse`, so a compiled
|
|
17153
|
+
// parser runs where a combinator does. A caller probing many positions
|
|
17154
|
+
// passes one context and pays for none per call.
|
|
17155
|
+
parse(input, pos = 0, ctx) {
|
|
17156
|
+
return runOnce(input, pos, ctx ?? createParseContext());
|
|
16900
17157
|
},
|
|
16901
17158
|
parseWithContext(input, parseCtx, pos = 0) {
|
|
16902
17159
|
return runOnce(input, pos, parseCtx);
|
|
@@ -16958,6 +17215,9 @@ function childrenOf3(def) {
|
|
|
16958
17215
|
];
|
|
16959
17216
|
case "routed":
|
|
16960
17217
|
return def.fallback ? [def.fallback] : [];
|
|
17218
|
+
case "lines":
|
|
17219
|
+
return [def.prefix, def.body, ...def.first === void 0 ? [] : [def.first], ...def.lazy === void 0 ? [] : [def.lazy]];
|
|
17220
|
+
case "columns":
|
|
16961
17221
|
case "lazy":
|
|
16962
17222
|
case "literal":
|
|
16963
17223
|
case "regex":
|
|
@@ -17287,6 +17547,15 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
17287
17547
|
return `expect(${kid(def.parser)}${def.label !== void 0 ? `, ${JSON.stringify(def.label)}` : ""})`;
|
|
17288
17548
|
case "scanTo":
|
|
17289
17549
|
return `scanTo(${kid(def.sentinel)}, { skip: [${def.skip.map(kid).join(", ")}]${def.raw ? ", raw: true" : ""}, orEOF: ${def.orEOF}${def.recoverAt === void 0 ? "" : `, recoverAt: ${kid(def.recoverAt)}`}${def.stopAt === void 0 ? "" : `, stopAt: ${kid(def.stopAt)}`} })`;
|
|
17550
|
+
case "lines": {
|
|
17551
|
+
const options = [
|
|
17552
|
+
...def.first === void 0 ? [] : [`first: ${kid(def.first)}`],
|
|
17553
|
+
...def.lazy === void 0 ? [] : [`lazy: ${kid(def.lazy)}`]
|
|
17554
|
+
];
|
|
17555
|
+
return `lines(${kid(def.prefix)}, ${kid(def.body)}${options.length === 0 ? "" : `, { ${options.join(", ")} }`})`;
|
|
17556
|
+
}
|
|
17557
|
+
case "columns":
|
|
17558
|
+
return `columns(${def.n})`;
|
|
17290
17559
|
case "transform": {
|
|
17291
17560
|
if (def.fnSrc === void 0) throw new Unserializable("transform without fnSrc");
|
|
17292
17561
|
return `_tf(${kid(def.parser)}, ${JSON.stringify(def.fnSrc)}${def.recognitionOnly ? ", true" : ""})`;
|
|
@@ -17351,7 +17620,7 @@ function fieldOptionsSrc(def) {
|
|
|
17351
17620
|
}
|
|
17352
17621
|
|
|
17353
17622
|
// src/version.ts
|
|
17354
|
-
var PARSEMAN_VERSION = "0.
|
|
17623
|
+
var PARSEMAN_VERSION = "0.56.0";
|
|
17355
17624
|
|
|
17356
17625
|
// src/compiler/compile-linkable-table.ts
|
|
17357
17626
|
function isLocal(rule) {
|
|
@@ -17878,6 +18147,10 @@ var SUPPORTED = {
|
|
|
17878
18147
|
field: (...a) => field(a[0], a[1], a[2]),
|
|
17879
18148
|
noTrivia: (...a) => noTrivia(a[0]),
|
|
17880
18149
|
token: (...a) => token(a[0]),
|
|
18150
|
+
// `lines(prefix, body, { first, lazy })`: its options are combinators, which the
|
|
18151
|
+
// generic argument evaluation already resolves; a missing option stays absent.
|
|
18152
|
+
lines: (...a) => lines(a[0], a[1], a[2]),
|
|
18153
|
+
columns: (...a) => columns(a[0]),
|
|
17881
18154
|
// `routed(fallback)` — the fallback must be forwarded. A zero-arg entry here read
|
|
17882
18155
|
// as "routed takes no arguments" and SILENTLY built a bare `routed()`, so a
|
|
17883
18156
|
// production written to work both inside and outside a dispatch branch lost its
|
|
@@ -19960,6 +20233,8 @@ function evalIR(ir, rulesImpl) {
|
|
|
19960
20233
|
"_nd",
|
|
19961
20234
|
"_gch",
|
|
19962
20235
|
"_wc",
|
|
20236
|
+
"lines",
|
|
20237
|
+
"columns",
|
|
19963
20238
|
`return (${ir})`
|
|
19964
20239
|
);
|
|
19965
20240
|
return fn(
|
|
@@ -20003,7 +20278,9 @@ function evalIR(ir, rulesImpl) {
|
|
|
20003
20278
|
_lf,
|
|
20004
20279
|
_nd,
|
|
20005
20280
|
_gch,
|
|
20006
|
-
_wc
|
|
20281
|
+
_wc,
|
|
20282
|
+
lines,
|
|
20283
|
+
columns
|
|
20007
20284
|
);
|
|
20008
20285
|
}
|
|
20009
20286
|
|
|
@@ -21474,14 +21751,14 @@ ${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/v
|
|
|
21474
21751
|
}
|
|
21475
21752
|
if (!allOk) continue;
|
|
21476
21753
|
const holderVar = `__rules${ruleMapHolderCounter++}`;
|
|
21477
|
-
const
|
|
21754
|
+
const lines2 = [
|
|
21478
21755
|
`const ${holderVar} = ${compiledRules.replacement}`,
|
|
21479
21756
|
...bindings.map(({ ruleKey, localName }) => `${exportPrefix}${kind} ${localName} = ${holderVar}[${JSON.stringify(ruleKey)}]`)
|
|
21480
21757
|
];
|
|
21481
21758
|
replacements.push({
|
|
21482
21759
|
start: stmtStart,
|
|
21483
21760
|
end: stmtEnd,
|
|
21484
|
-
replacement:
|
|
21761
|
+
replacement: lines2.join("\n")
|
|
21485
21762
|
});
|
|
21486
21763
|
markUsedImportedFactories(compiledRules.importedFactory ? [compiledRules.importedFactory] : void 0);
|
|
21487
21764
|
}
|
|
@@ -21641,12 +21918,12 @@ ${free.map(where).join("\n")}${cause}`
|
|
|
21641
21918
|
setBuilderImportResolver(null);
|
|
21642
21919
|
const degradations = endDegradationCapture();
|
|
21643
21920
|
if (degradations.length > 0) {
|
|
21644
|
-
const
|
|
21921
|
+
const lines2 = formatDegradations(degradations);
|
|
21645
21922
|
if (resolveDegradationLevel() === "error") {
|
|
21646
21923
|
throw new Error(`parseman: ${degradations.length} degraded compilation path(s) in ${id}
|
|
21647
|
-
${
|
|
21924
|
+
${lines2.join("\n")}`);
|
|
21648
21925
|
}
|
|
21649
|
-
for (const l of
|
|
21926
|
+
for (const l of lines2) warnings.push(`${id}: ${l}`);
|
|
21650
21927
|
}
|
|
21651
21928
|
return {
|
|
21652
21929
|
code: ms.toString(),
|