parseman 0.60.6 → 0.61.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/diagnostics.js +47 -36
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +47 -36
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/link-scope.d.ts +7 -0
- package/dist/combinators/link-scope.d.ts.map +1 -0
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +1 -0
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/compiler/value-usage.d.ts.map +1 -1
- package/dist/functional/run.d.ts.map +1 -1
- package/dist/index.js +91 -66
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +1 -1
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/index.js +254 -229
- package/dist/plugin/index.js.map +3 -3
- package/dist/run/index.js +1 -1
- package/dist/run/index.js.map +1 -1
- package/dist/spec/index.js.map +1 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/index.js +11 -6
- package/dist/table/index.js.map +3 -3
- package/dist/table/program.d.ts +3 -1
- package/dist/table/program.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/combinators/choice.ts +3 -1
- package/src/combinators/expect.ts +1 -0
- package/src/combinators/link-scope.ts +19 -0
- package/src/combinators/node.ts +11 -2
- package/src/combinators/parser.ts +37 -31
- package/src/compiler/value-usage.ts +16 -29
- package/src/functional/run.ts +3 -1
- package/src/table/emit.ts +5 -1
- package/src/table/program.ts +8 -2
- package/src/version.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -3203,6 +3203,7 @@ function derive(c, seen) {
|
|
|
3203
3203
|
case "optional":
|
|
3204
3204
|
case "many":
|
|
3205
3205
|
case "oneOrMore":
|
|
3206
|
+
case "sepBy":
|
|
3206
3207
|
case "transform":
|
|
3207
3208
|
case "not":
|
|
3208
3209
|
case "peek":
|
|
@@ -3353,7 +3354,7 @@ function choice(...args) {
|
|
|
3353
3354
|
const result = parsers[idx].parse(input, pos, ctx);
|
|
3354
3355
|
if (result.ok) return result;
|
|
3355
3356
|
expected.push(...result.expected);
|
|
3356
|
-
if (result.committed) return { ok: false, expected, span:
|
|
3357
|
+
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
3357
3358
|
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
3358
3359
|
}
|
|
3359
3360
|
if (ctx._probe !== void 0 || ctx._tolerant) for (const p of parsers) p.parse(input, pos, ctx);
|
|
@@ -4348,15 +4349,20 @@ function markUnusedValues(root) {
|
|
|
4348
4349
|
case "many":
|
|
4349
4350
|
case "oneOrMore":
|
|
4350
4351
|
mark(def, consumed);
|
|
4351
|
-
visit(def.parser, consumed);
|
|
4352
|
-
return;
|
|
4353
4352
|
case "optional":
|
|
4353
|
+
// `optional` returns `inner | null` — no aggregate array/tuple to elide, so
|
|
4354
|
+
// it carries no valueUnused flag. Still descend so an inner many/sequence
|
|
4355
|
+
// under a node() is analyzed (it benefits even when its optional wrapper
|
|
4356
|
+
// doesn't).
|
|
4357
|
+
case "label":
|
|
4358
|
+
case "trivia":
|
|
4359
|
+
case "attempt":
|
|
4360
|
+
case "withCtx":
|
|
4361
|
+
case "expect":
|
|
4354
4362
|
visit(def.parser, consumed);
|
|
4355
4363
|
return;
|
|
4356
4364
|
case "sequence":
|
|
4357
4365
|
mark(def, consumed);
|
|
4358
|
-
for (const p of def.parsers) visit(p, consumed);
|
|
4359
|
-
return;
|
|
4360
4366
|
case "choice":
|
|
4361
4367
|
for (const p of def.parsers) visit(p, consumed);
|
|
4362
4368
|
return;
|
|
@@ -4367,22 +4373,24 @@ function markUnusedValues(root) {
|
|
|
4367
4373
|
if (def.otherwise) visit(def.otherwise, consumed);
|
|
4368
4374
|
return;
|
|
4369
4375
|
case "node":
|
|
4376
|
+
// builds from captured children, NOT the inner parser value.
|
|
4377
|
+
case "not":
|
|
4378
|
+
case "peek":
|
|
4379
|
+
// lookahead — value never observed
|
|
4380
|
+
case "token":
|
|
4370
4381
|
visit(def.parser, false);
|
|
4371
4382
|
return;
|
|
4372
4383
|
case "transform":
|
|
4373
|
-
|
|
4374
|
-
return;
|
|
4384
|
+
// the map fn reads the value → always consumed.
|
|
4375
4385
|
case "field":
|
|
4386
|
+
// the field capture records the parsed value → always consumed.
|
|
4387
|
+
case "leaf":
|
|
4376
4388
|
visit(def.parser, true);
|
|
4377
4389
|
return;
|
|
4378
4390
|
case "sepBy":
|
|
4379
4391
|
visit(def.parser, true);
|
|
4380
4392
|
visit(def.separator, false);
|
|
4381
4393
|
return;
|
|
4382
|
-
case "not":
|
|
4383
|
-
case "peek":
|
|
4384
|
-
visit(def.parser, false);
|
|
4385
|
-
return;
|
|
4386
4394
|
case "grammar":
|
|
4387
4395
|
visit(def.parser, consumed);
|
|
4388
4396
|
if (def.triviaParser) visit(def.triviaParser, false);
|
|
@@ -4391,19 +4399,6 @@ function markUnusedValues(root) {
|
|
|
4391
4399
|
visit(def.parser, consumed);
|
|
4392
4400
|
visit(def.sentinel, false);
|
|
4393
4401
|
return;
|
|
4394
|
-
case "token":
|
|
4395
|
-
visit(def.parser, false);
|
|
4396
|
-
return;
|
|
4397
|
-
case "label":
|
|
4398
|
-
case "trivia":
|
|
4399
|
-
case "attempt":
|
|
4400
|
-
case "withCtx":
|
|
4401
|
-
case "expect":
|
|
4402
|
-
visit(def.parser, consumed);
|
|
4403
|
-
return;
|
|
4404
|
-
case "leaf":
|
|
4405
|
-
visit(def.parser, true);
|
|
4406
|
-
return;
|
|
4407
4402
|
case "lazy":
|
|
4408
4403
|
return;
|
|
4409
4404
|
default:
|
|
@@ -4433,6 +4428,21 @@ function markUnusedValues(root) {
|
|
|
4433
4428
|
visit(resolveRoot2(root), true);
|
|
4434
4429
|
}
|
|
4435
4430
|
|
|
4431
|
+
// src/combinators/link-scope.ts
|
|
4432
|
+
var scope;
|
|
4433
|
+
function afterLink(settle) {
|
|
4434
|
+
scope?.push(settle);
|
|
4435
|
+
}
|
|
4436
|
+
function collectAfterLink(pending, build) {
|
|
4437
|
+
const outer = scope;
|
|
4438
|
+
scope = outer ?? pending;
|
|
4439
|
+
try {
|
|
4440
|
+
return build();
|
|
4441
|
+
} finally {
|
|
4442
|
+
scope = outer;
|
|
4443
|
+
}
|
|
4444
|
+
}
|
|
4445
|
+
|
|
4436
4446
|
// src/cst/root-trivia-scope.ts
|
|
4437
4447
|
var ROOT_TRIVIA_SCOPE_REFUSAL = "parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'.";
|
|
4438
4448
|
function refuseUnclassifiedRootScope(strict) {
|
|
@@ -4779,6 +4789,7 @@ function linkRules(recipes, link) {
|
|
|
4779
4789
|
}
|
|
4780
4790
|
});
|
|
4781
4791
|
const winners = /* @__PURE__ */ new Map();
|
|
4792
|
+
const afterLink2 = [];
|
|
4782
4793
|
const priorHoles = /* @__PURE__ */ new Map();
|
|
4783
4794
|
const prior = new Proxy({}, {
|
|
4784
4795
|
get(_target, key) {
|
|
@@ -4791,38 +4802,42 @@ function linkRules(recipes, link) {
|
|
|
4791
4802
|
return hole;
|
|
4792
4803
|
}
|
|
4793
4804
|
});
|
|
4794
|
-
for (const recipe of recipes) {
|
|
4795
|
-
const definitions = recipe.factory(proxy, prior);
|
|
4796
|
-
for (const key of Object.keys(definitions)) {
|
|
4797
|
-
winners.set(key, { parser: definitions[key], options: recipe.options });
|
|
4798
|
-
}
|
|
4799
|
-
}
|
|
4800
|
-
const keys = [...winners.keys()];
|
|
4801
4805
|
const copies = /* @__PURE__ */ new Map();
|
|
4802
|
-
|
|
4803
|
-
const
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
placeholder
|
|
4811
|
-
|
|
4812
|
-
placeholder
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4806
|
+
try {
|
|
4807
|
+
for (const recipe of recipes) {
|
|
4808
|
+
const definitions = collectAfterLink(afterLink2, () => recipe.factory(proxy, prior));
|
|
4809
|
+
for (const key of Object.keys(definitions)) {
|
|
4810
|
+
winners.set(key, { parser: definitions[key], options: recipe.options });
|
|
4811
|
+
}
|
|
4812
|
+
}
|
|
4813
|
+
for (const [key, { parser: defined }] of winners) {
|
|
4814
|
+
const placeholder = cache[key];
|
|
4815
|
+
const parser2 = ownRule(defined, copies);
|
|
4816
|
+
if (placeholder === parser2) {
|
|
4817
|
+
throw new Error(`rules(): rule "${key}" cannot be a direct alias to itself`);
|
|
4818
|
+
}
|
|
4819
|
+
if (isDefinableRef(placeholder)) {
|
|
4820
|
+
if (!isNamedRuleRefForAnotherRule(parser2, key)) tagRule(parser2, key);
|
|
4821
|
+
placeholder.define(parser2);
|
|
4822
|
+
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
4823
|
+
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
4824
|
+
} else if (isNamedRuleRefForAnotherRule(parser2, key) || link !== void 0) {
|
|
4825
|
+
if (!isNamedRuleRefForAnotherRule(parser2, key)) tagRule(parser2, key);
|
|
4826
|
+
const alias = ref();
|
|
4827
|
+
tagRule(alias, key);
|
|
4828
|
+
alias.define(parser2);
|
|
4829
|
+
alias._meta.firstSet = parser2._meta.firstSet;
|
|
4830
|
+
alias._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
4831
|
+
cache[key] = alias;
|
|
4832
|
+
} else {
|
|
4833
|
+
tagRule(parser2, key);
|
|
4834
|
+
cache[key] = parser2;
|
|
4835
|
+
}
|
|
4824
4836
|
}
|
|
4837
|
+
} finally {
|
|
4838
|
+
for (const settle of afterLink2) settle();
|
|
4825
4839
|
}
|
|
4840
|
+
const keys = [...winners.keys()];
|
|
4826
4841
|
for (const key of keys) {
|
|
4827
4842
|
const options = winners.get(key).options;
|
|
4828
4843
|
let rule = cache[key];
|
|
@@ -5307,8 +5322,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
5307
5322
|
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || buildArity !== void 0 || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...buildArity !== void 0 ? { buildArity } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
|
|
5308
5323
|
const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
5309
5324
|
const readsState = build ? buildReadsState(def) : project === void 0;
|
|
5310
|
-
|
|
5311
|
-
|
|
5325
|
+
let hasOwnFields = parserHasOwnFields(combinator);
|
|
5326
|
+
let capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
|
|
5327
|
+
if (!hasOwnFields) {
|
|
5328
|
+
afterLink(() => {
|
|
5329
|
+
hasOwnFields = parserHasOwnFields(combinator);
|
|
5330
|
+
capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
|
|
5331
|
+
});
|
|
5332
|
+
}
|
|
5312
5333
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
5313
5334
|
let failExpected;
|
|
5314
5335
|
return {
|
|
@@ -5621,6 +5642,9 @@ function sourceLeaf(root, fn) {
|
|
|
5621
5642
|
return makeLeaf(root, fn, true);
|
|
5622
5643
|
}
|
|
5623
5644
|
|
|
5645
|
+
// src/version.ts
|
|
5646
|
+
var PARSEMAN_VERSION = "0.61.0";
|
|
5647
|
+
|
|
5624
5648
|
// src/table/lex-body.ts
|
|
5625
5649
|
function buildLexBodyRecognizer(spec, constants) {
|
|
5626
5650
|
const raw = constants[spec[0]];
|
|
@@ -6236,11 +6260,12 @@ function assemblyExtraIps(prog) {
|
|
|
6236
6260
|
}
|
|
6237
6261
|
function expandCompact(p) {
|
|
6238
6262
|
if ("code" in p) return p;
|
|
6263
|
+
if (p.es === void 0) throw new Error(`parseman: this parser was printed by an earlier parseman; reprint it with parseman ${PARSEMAN_VERSION}`);
|
|
6239
6264
|
return ownTableProgram({
|
|
6240
6265
|
code: p.c,
|
|
6241
6266
|
k: p.k,
|
|
6242
6267
|
cc: p.x,
|
|
6243
|
-
fx: p.e,
|
|
6268
|
+
fx: p.e.map((set) => set.map((i) => p.es[i])),
|
|
6244
6269
|
disp: p.d,
|
|
6245
6270
|
rules: p.r,
|
|
6246
6271
|
fns: p.f,
|
|
@@ -7649,7 +7674,7 @@ function selectOptionalSuffixLexBody(ir) {
|
|
|
7649
7674
|
function reinstallsRuleTrivia(reference, target) {
|
|
7650
7675
|
return (reference._meta.grammarTrivia ?? target._meta.grammarTrivia) !== void 0 && hasOwnTriviaBoundary(target);
|
|
7651
7676
|
}
|
|
7652
|
-
function directTokenBodyParser(parser2, resolve,
|
|
7677
|
+
function directTokenBodyParser(parser2, resolve, scope2) {
|
|
7653
7678
|
const outer = parser2._def;
|
|
7654
7679
|
if (outer.tag !== "token") return void 0;
|
|
7655
7680
|
let body = outer.parser;
|
|
@@ -7659,7 +7684,7 @@ function directTokenBodyParser(parser2, resolve, scope) {
|
|
|
7659
7684
|
const wrapper = body._def;
|
|
7660
7685
|
if (wrapper.tag === "grammar") {
|
|
7661
7686
|
if (wrapper.clearTrivia !== true || wrapper.triviaParser !== void 0 || wrapper.captureTrivia === true || wrapper.rootCapture === "opaque" || wrapper.constructionTrackLines !== "inherit" || wrapper.constructionCaptureTriviaKinds !== void 0) return void 0;
|
|
7662
|
-
if (
|
|
7687
|
+
if (scope2 !== void 0) scope2.cleared = true;
|
|
7663
7688
|
body = wrapper.parser;
|
|
7664
7689
|
continue;
|
|
7665
7690
|
}
|
|
@@ -7916,10 +7941,10 @@ function directFixedLexNode(parser2, resolve, active, pureOnly = false, cleared
|
|
|
7916
7941
|
}
|
|
7917
7942
|
}
|
|
7918
7943
|
function directFixedTokenBody(parser2, resolve) {
|
|
7919
|
-
const
|
|
7920
|
-
const body = directTokenBodyParser(parser2, resolve,
|
|
7944
|
+
const scope2 = { cleared: false };
|
|
7945
|
+
const body = directTokenBodyParser(parser2, resolve, scope2);
|
|
7921
7946
|
if (body === void 0) return void 0;
|
|
7922
|
-
const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set(), false,
|
|
7947
|
+
const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set(), false, scope2.cleared);
|
|
7923
7948
|
return root === void 0 ? void 0 : { kind: "fixed-tree", root };
|
|
7924
7949
|
}
|
|
7925
7950
|
function directBalancedTokenBody(parser2, resolve) {
|
|
@@ -13918,9 +13943,6 @@ function clearOf(ranges, input, from, to) {
|
|
|
13918
13943
|
return true;
|
|
13919
13944
|
}
|
|
13920
13945
|
|
|
13921
|
-
// src/version.ts
|
|
13922
|
-
var PARSEMAN_VERSION = "0.60.6";
|
|
13923
|
-
|
|
13924
13946
|
// src/table/assemble.ts
|
|
13925
13947
|
import { PlainBuf as PlainBuf2, PlainField, PlainLeaf as PlainLeaf9, PlainNode as PlainNode2, PlainSpan as PlainSpan10 } from "./cst/plain.js";
|
|
13926
13948
|
|
|
@@ -17928,12 +17950,15 @@ function assertPrintable(prog, who) {
|
|
|
17928
17950
|
}
|
|
17929
17951
|
}
|
|
17930
17952
|
function programFields(prog, fns, opts = {}) {
|
|
17953
|
+
const tokens = [...new Set(prog.fx.flat())];
|
|
17954
|
+
const tokenAt = new Map(tokens.map((token2, i) => [token2, i]));
|
|
17931
17955
|
return [
|
|
17932
17956
|
...emitAssemblies(prog, opts.assemblies ?? []),
|
|
17933
17957
|
`c:[${prog.code.join(",")}],`,
|
|
17934
17958
|
`k:[${prog.k.map(emitConst).join(",")}],`,
|
|
17935
17959
|
`x:${emitClassPool(prog.cc)},`,
|
|
17936
|
-
`e:[${prog.fx.map((f) => `[${f.map(
|
|
17960
|
+
`e:[${prog.fx.map((f) => `[${f.map((token2) => tokenAt.get(token2)).join(",")}]`).join(",")}],`,
|
|
17961
|
+
`es:[${tokens.map(jsString).join(",")}],`,
|
|
17937
17962
|
`d:[${prog.disp.map((a) => `[${a.join(",")}]`).join(",")}],`,
|
|
17938
17963
|
`r:${JSON.stringify(prog.rules)},`,
|
|
17939
17964
|
...prog.lines === 1 ? ["l:1,"] : [],
|
|
@@ -21056,7 +21081,7 @@ function runOnce(entry, input, options) {
|
|
|
21056
21081
|
const r = invoke(entry, input, 0, ctx);
|
|
21057
21082
|
const value = r.ok ? r.value : void 0;
|
|
21058
21083
|
let span = r.span ?? { start: 0, end: 0 };
|
|
21059
|
-
const expected = r.ok ? [] : r.expected ?? [];
|
|
21084
|
+
const expected = r.ok ? [] : [...new Set(r.expected ?? [])];
|
|
21060
21085
|
let unconsumedFrom = null;
|
|
21061
21086
|
if (r.ok) {
|
|
21062
21087
|
let pos = span.end;
|