parseman 0.21.0 → 0.23.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/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +12 -0
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +6 -2
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +7 -2
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/functional/run.d.ts.map +1 -1
- package/dist/index.cjs +289 -38
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +289 -38
- package/dist/index.js.map +3 -3
- package/dist/plugin/index.cjs +161 -34
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +161 -34
- package/dist/plugin/index.js.map +3 -3
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type { ParseOptions, ParserOptions, ParsemanParser } from './combinators/
|
|
|
18
18
|
export { token } from './combinators/token.ts';
|
|
19
19
|
export { compile } from './compiler/codegen.ts';
|
|
20
20
|
export type { CompiledParser, LinkablePieces } from './compiler/codegen.ts';
|
|
21
|
-
export { compose,
|
|
21
|
+
export { compose, cstBuildHost } from './compiler/linker.ts';
|
|
22
22
|
export type { CstBuildHostOptions, FusedRule } from './compiler/linker.ts';
|
|
23
23
|
export { buildLineIndex, offsetToLineCol, annotateSpan } from './compiler/line-index.ts';
|
|
24
24
|
export type { LineIndex } from './compiler/line-index.ts';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,oBAAoB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1P,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAU9C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpE,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAC5C,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAEnE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5E,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAClE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC3F,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAE9C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1690,7 +1690,9 @@ function tagRule(r, key) {
|
|
|
1690
1690
|
r._ruleName = key;
|
|
1691
1691
|
if (r._def.tag === "node" && r._def.type === void 0) r._def.type = key;
|
|
1692
1692
|
}
|
|
1693
|
-
function rules(
|
|
1693
|
+
function rules(a, b) {
|
|
1694
|
+
const factory = typeof a === "function" ? a : b;
|
|
1695
|
+
const options = typeof a === "function" ? b : a;
|
|
1694
1696
|
const cache = {};
|
|
1695
1697
|
const proxy = new Proxy(cache, {
|
|
1696
1698
|
get(target, key) {
|
|
@@ -1718,6 +1720,12 @@ function rules(factory) {
|
|
|
1718
1720
|
cache[key] = parser2;
|
|
1719
1721
|
}
|
|
1720
1722
|
}
|
|
1723
|
+
if (options?.trivia !== void 0) {
|
|
1724
|
+
for (const key of Object.keys(definitions)) {
|
|
1725
|
+
const rule = cache[key];
|
|
1726
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrivia = options.trivia;
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1721
1729
|
for (const key of Object.keys(definitions)) {
|
|
1722
1730
|
markUnusedValues(cache[key]);
|
|
1723
1731
|
}
|
|
@@ -2060,8 +2068,10 @@ function parse(combinator, input, opts = {}) {
|
|
|
2060
2068
|
const trackLines = opts.trackLines ?? false;
|
|
2061
2069
|
const _errors = opts.recover ? [] : void 0;
|
|
2062
2070
|
const _probe = opts.recover ? { offset: input.length, best: null } : void 0;
|
|
2071
|
+
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
2063
2072
|
const ctx = {
|
|
2064
2073
|
trackLines,
|
|
2074
|
+
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
|
|
2065
2075
|
..._errors !== void 0 ? { _errors } : {},
|
|
2066
2076
|
..._probe !== void 0 ? { _probe } : {}
|
|
2067
2077
|
};
|
|
@@ -5327,6 +5337,7 @@ function ruleDependencies(ruleMap) {
|
|
|
5327
5337
|
}
|
|
5328
5338
|
function compile(combinator, mapFnSources) {
|
|
5329
5339
|
markUnusedValues(combinator);
|
|
5340
|
+
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
5330
5341
|
const ctx = {
|
|
5331
5342
|
vars: 0,
|
|
5332
5343
|
indent: 1,
|
|
@@ -5345,7 +5356,8 @@ function compile(combinator, mapFnSources) {
|
|
|
5345
5356
|
triviaFnNames: /* @__PURE__ */ new Map(),
|
|
5346
5357
|
namedFnDecls: [],
|
|
5347
5358
|
capturing: hasNodeDef(combinator),
|
|
5348
|
-
lazyUsage: analyzeLazyUsage(combinator)
|
|
5359
|
+
lazyUsage: analyzeLazyUsage(combinator),
|
|
5360
|
+
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {}
|
|
5349
5361
|
};
|
|
5350
5362
|
const r = emit(combinator, ctx, "_pos");
|
|
5351
5363
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? [...namedFnPrelude(), ""] : [];
|
|
@@ -5421,9 +5433,10 @@ function publicRuleWrapperSource(rule, fnSource) {
|
|
|
5421
5433
|
if (labels === void 0) return fnSource;
|
|
5422
5434
|
return `Object.assign(${fnSource}, { _meta: { triviaKindLabels: ${JSON.stringify(labels)} } })`;
|
|
5423
5435
|
}
|
|
5424
|
-
function compileLinkable(ruleMapArg, ns) {
|
|
5436
|
+
function compileLinkable(ruleMapArg, ns, opts) {
|
|
5425
5437
|
if (!ns) throw new Error("compileLinkable: ns must be a non-empty namespace");
|
|
5426
5438
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
5439
|
+
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
5427
5440
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
5428
5441
|
const d = val._def;
|
|
5429
5442
|
if (d.tag !== "lazy") return true;
|
|
@@ -5454,7 +5467,8 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5454
5467
|
capturing: ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
5455
5468
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
5456
5469
|
ns,
|
|
5457
|
-
deferFirstSetRefs: true
|
|
5470
|
+
deferFirstSetRefs: true,
|
|
5471
|
+
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {}
|
|
5458
5472
|
};
|
|
5459
5473
|
const seen = /* @__PURE__ */ new Map();
|
|
5460
5474
|
const ruleNames = /* @__PURE__ */ new Map();
|
|
@@ -5517,7 +5531,10 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5517
5531
|
ctx.indent = 1;
|
|
5518
5532
|
ctx.failLabel = "_pfail";
|
|
5519
5533
|
ctx.recordFail = true;
|
|
5534
|
+
const savedTrivia = ctx.activeTrivia;
|
|
5535
|
+
if (rule._meta.isTrivia) ctx.activeTrivia = void 0;
|
|
5520
5536
|
const body = emit(resolved, ctx, "_pos");
|
|
5537
|
+
ctx.activeTrivia = savedTrivia;
|
|
5521
5538
|
ctx.indent = savedIndent;
|
|
5522
5539
|
ctx.failLabel = savedFail;
|
|
5523
5540
|
ctx.recordFail = savedRec;
|
|
@@ -5716,6 +5733,64 @@ function escapeClassChar(ch) {
|
|
|
5716
5733
|
}
|
|
5717
5734
|
|
|
5718
5735
|
// src/compiler/ir-serialize.ts
|
|
5736
|
+
function childrenOf2(def) {
|
|
5737
|
+
switch (def.tag) {
|
|
5738
|
+
case "sequence":
|
|
5739
|
+
case "choice":
|
|
5740
|
+
return def.parsers;
|
|
5741
|
+
case "many":
|
|
5742
|
+
case "oneOrMore":
|
|
5743
|
+
case "optional":
|
|
5744
|
+
case "transform":
|
|
5745
|
+
case "trivia":
|
|
5746
|
+
case "token":
|
|
5747
|
+
case "label":
|
|
5748
|
+
case "field":
|
|
5749
|
+
case "not":
|
|
5750
|
+
case "node":
|
|
5751
|
+
case "expect":
|
|
5752
|
+
return [def.parser];
|
|
5753
|
+
case "grammar":
|
|
5754
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
5755
|
+
case "sepBy":
|
|
5756
|
+
return [def.parser, def.separator];
|
|
5757
|
+
case "skip":
|
|
5758
|
+
return [def.main, def.skipped];
|
|
5759
|
+
case "scanTo":
|
|
5760
|
+
return [def.sentinel, ...def.skip];
|
|
5761
|
+
case "lazy":
|
|
5762
|
+
case "literal":
|
|
5763
|
+
case "regex":
|
|
5764
|
+
case "keywords":
|
|
5765
|
+
case "guard":
|
|
5766
|
+
case "withCtx":
|
|
5767
|
+
case "recover":
|
|
5768
|
+
case "unknown":
|
|
5769
|
+
return [];
|
|
5770
|
+
}
|
|
5771
|
+
}
|
|
5772
|
+
var ruleNameOf = (c) => c._ruleName;
|
|
5773
|
+
function lazyTarget(c) {
|
|
5774
|
+
if (c._def.tag !== "lazy") return null;
|
|
5775
|
+
try {
|
|
5776
|
+
return c._def.thunk();
|
|
5777
|
+
} catch {
|
|
5778
|
+
return null;
|
|
5779
|
+
}
|
|
5780
|
+
}
|
|
5781
|
+
var Unserializable = class extends Error {
|
|
5782
|
+
};
|
|
5783
|
+
function serializeRuleMap(ruleMap) {
|
|
5784
|
+
try {
|
|
5785
|
+
return new Serializer(ruleMap).run();
|
|
5786
|
+
} catch (e) {
|
|
5787
|
+
if (e instanceof Unserializable) {
|
|
5788
|
+
if (process.env.PARSEMAN_IR_DEBUG) console.error(`[ir] fallback: ${e.message}`);
|
|
5789
|
+
return null;
|
|
5790
|
+
}
|
|
5791
|
+
throw e;
|
|
5792
|
+
}
|
|
5793
|
+
}
|
|
5719
5794
|
function evalRuleMapIR(ir) {
|
|
5720
5795
|
const _tf = (child, src) => {
|
|
5721
5796
|
let fn2;
|
|
@@ -5790,11 +5865,172 @@ function evalRuleMapIR(ir) {
|
|
|
5790
5865
|
);
|
|
5791
5866
|
return Object.entries(map);
|
|
5792
5867
|
}
|
|
5868
|
+
var Serializer = class {
|
|
5869
|
+
counts = /* @__PURE__ */ new Map();
|
|
5870
|
+
selfRef = /* @__PURE__ */ new Set();
|
|
5871
|
+
// combinators reached by an unnamed lazy pointing back into their own subtree
|
|
5872
|
+
constName = /* @__PURE__ */ new Map();
|
|
5873
|
+
emitted = /* @__PURE__ */ new Set();
|
|
5874
|
+
decls = [];
|
|
5875
|
+
ruleValues = /* @__PURE__ */ new Set();
|
|
5876
|
+
ruleMap;
|
|
5877
|
+
constructor(ruleMap) {
|
|
5878
|
+
this.ruleMap = ruleMap;
|
|
5879
|
+
for (const [, c] of ruleMap) this.ruleValues.add(this.body(c));
|
|
5880
|
+
}
|
|
5881
|
+
/** A `rules()` map wraps each rule value in a named `lazy` proxy; the real body is
|
|
5882
|
+
* its target (compileLinkable unwraps the same way). A ref INSIDE a body stays a
|
|
5883
|
+
* `g[name]` ref — only the top-level entry is unwrapped. */
|
|
5884
|
+
body(c) {
|
|
5885
|
+
return c._def.tag === "lazy" && ruleNameOf(c) !== void 0 ? lazyTarget(c) ?? c : c;
|
|
5886
|
+
}
|
|
5887
|
+
run() {
|
|
5888
|
+
for (const [, c] of this.ruleMap) this.analyze(this.body(c), /* @__PURE__ */ new Set());
|
|
5889
|
+
let n = 0;
|
|
5890
|
+
for (const [c, count] of this.counts) {
|
|
5891
|
+
if (this.ruleValues.has(c)) continue;
|
|
5892
|
+
if (count >= 2 || this.selfRef.has(c)) this.constName.set(c, `_s${n++}`);
|
|
5893
|
+
}
|
|
5894
|
+
const body = this.ruleMap.map(([name, c]) => ` ${JSON.stringify(name)}: ${this.wrap(this.body(c))}`).join(",\n");
|
|
5895
|
+
if (this.decls.length === 0) return `rules((g) => ({
|
|
5896
|
+
${body}
|
|
5897
|
+
}))`;
|
|
5898
|
+
return `rules((g) => {
|
|
5899
|
+
${this.decls.map((d) => " " + d).join("\n")}
|
|
5900
|
+
return ({
|
|
5901
|
+
${body}
|
|
5902
|
+
})
|
|
5903
|
+
})`;
|
|
5904
|
+
}
|
|
5905
|
+
/** Count identity references and flag self-referential subtrees. `active` is the
|
|
5906
|
+
* set of combinators on the current DFS path (to detect a lazy pointing back). */
|
|
5907
|
+
analyze(c, active) {
|
|
5908
|
+
const def = c._def;
|
|
5909
|
+
if (def.tag === "lazy") {
|
|
5910
|
+
if (ruleNameOf(c) !== void 0) return;
|
|
5911
|
+
const target = lazyTarget(c);
|
|
5912
|
+
if (!target) throw new Unserializable("unresolved unnamed ref");
|
|
5913
|
+
if (active.has(target)) {
|
|
5914
|
+
this.selfRef.add(target);
|
|
5915
|
+
return;
|
|
5916
|
+
}
|
|
5917
|
+
this.analyze(target, active);
|
|
5918
|
+
return;
|
|
5919
|
+
}
|
|
5920
|
+
if (def.tag === "guard" || def.tag === "withCtx" || def.tag === "recover" || def.tag === "unknown") {
|
|
5921
|
+
throw new Unserializable(`unsupported tag ${def.tag}`);
|
|
5922
|
+
}
|
|
5923
|
+
this.counts.set(c, (this.counts.get(c) ?? 0) + 1);
|
|
5924
|
+
if ((this.counts.get(c) ?? 0) > 1) return;
|
|
5925
|
+
active.add(c);
|
|
5926
|
+
for (const child of childrenOf2(def)) this.analyze(child, active);
|
|
5927
|
+
active.delete(c);
|
|
5928
|
+
}
|
|
5929
|
+
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
5930
|
+
* `selfOf` is the const currently being wrapped in a ref()/define closure — an
|
|
5931
|
+
* unnamed lazy back into it emits the local ref var instead of recursing. */
|
|
5932
|
+
ref(c, selfOf) {
|
|
5933
|
+
const cn = this.constName.get(c);
|
|
5934
|
+
if (cn) {
|
|
5935
|
+
this.emitDecl(c);
|
|
5936
|
+
return cn;
|
|
5937
|
+
}
|
|
5938
|
+
return this.expr(c, selfOf);
|
|
5939
|
+
}
|
|
5940
|
+
emitDecl(c) {
|
|
5941
|
+
const name = this.constName.get(c);
|
|
5942
|
+
if (this.emitted.has(name)) return;
|
|
5943
|
+
this.emitted.add(name);
|
|
5944
|
+
this.decls.push(`const ${name} = ${this.wrap(c)}`);
|
|
5945
|
+
}
|
|
5946
|
+
selfN = 0;
|
|
5947
|
+
/** Emit `c`'s own constructor call, wrapping it in a `ref()`+`.define()` closure
|
|
5948
|
+
* if it is self-referential (an unnamed lazy in its subtree points back to it) —
|
|
5949
|
+
* the shape `balanced()` and other recursive library combinators build. */
|
|
5950
|
+
wrap(c) {
|
|
5951
|
+
if (!this.selfRef.has(c)) return this.expr(c, null);
|
|
5952
|
+
const rv = `_rr${this.selfN++}`;
|
|
5953
|
+
const bodyExpr = this.expr(c, { comb: c, var: rv });
|
|
5954
|
+
return `(() => { const ${rv} = ref(); const _b = ${bodyExpr}; ${rv}.define(_b); return _b })()`;
|
|
5955
|
+
}
|
|
5956
|
+
/** Emit the constructor-call source for `c` (never a const shortcut for `c` itself). */
|
|
5957
|
+
expr(c, selfOf) {
|
|
5958
|
+
const def = c._def;
|
|
5959
|
+
const kid = (x) => this.ref(x, selfOf);
|
|
5960
|
+
switch (def.tag) {
|
|
5961
|
+
case "lazy": {
|
|
5962
|
+
if (ruleNameOf(c) !== void 0) return `g[${JSON.stringify(ruleNameOf(c))}]`;
|
|
5963
|
+
const target = lazyTarget(c);
|
|
5964
|
+
if (selfOf && target === selfOf.comb) return selfOf.var;
|
|
5965
|
+
return this.ref(target, selfOf);
|
|
5966
|
+
}
|
|
5967
|
+
case "literal":
|
|
5968
|
+
return `literal(${JSON.stringify(def.value)}${def.caseInsensitive ? ", { caseInsensitive: true }" : ""})`;
|
|
5969
|
+
case "regex":
|
|
5970
|
+
return `regex(${JSON.stringify(def.source)}, ${JSON.stringify(def.flags)})`;
|
|
5971
|
+
case "keywords":
|
|
5972
|
+
return `keywords(${JSON.stringify(def.words)}, { caseInsensitive: ${def.caseInsensitive}${def.boundary !== void 0 ? `, boundary: ${JSON.stringify(def.boundary)}` : ""} })`;
|
|
5973
|
+
case "sequence":
|
|
5974
|
+
return `sequence(${def.parsers.map(kid).join(", ")})`;
|
|
5975
|
+
case "choice": {
|
|
5976
|
+
if (def.gates.some((g) => g !== null)) throw new Unserializable("choice with a gate() has no source");
|
|
5977
|
+
return `choice(${def.parsers.map(kid).join(", ")})`;
|
|
5978
|
+
}
|
|
5979
|
+
case "many":
|
|
5980
|
+
return `many(${kid(def.parser)})`;
|
|
5981
|
+
case "oneOrMore":
|
|
5982
|
+
return `oneOrMore(${kid(def.parser)})`;
|
|
5983
|
+
case "optional":
|
|
5984
|
+
return `optional(${kid(def.parser)})`;
|
|
5985
|
+
case "sepBy":
|
|
5986
|
+
return `sepBy(${kid(def.parser)}, ${kid(def.separator)})`;
|
|
5987
|
+
case "not":
|
|
5988
|
+
return `not(${kid(def.parser)})`;
|
|
5989
|
+
case "trivia":
|
|
5990
|
+
return `trivia(${kid(def.parser)})`;
|
|
5991
|
+
case "token":
|
|
5992
|
+
return `token(${kid(def.parser)})`;
|
|
5993
|
+
case "label":
|
|
5994
|
+
return `label(${JSON.stringify(def.label)}, ${kid(def.parser)})`;
|
|
5995
|
+
case "field":
|
|
5996
|
+
return `field(${JSON.stringify(def.name)}, ${kid(def.parser)})`;
|
|
5997
|
+
case "expect":
|
|
5998
|
+
return `expect(${kid(def.parser)}${def.label !== void 0 ? `, ${JSON.stringify(def.label)}` : ""})`;
|
|
5999
|
+
case "skip":
|
|
6000
|
+
return `skip(${kid(def.main)}, ${kid(def.skipped)})`;
|
|
6001
|
+
case "scanTo":
|
|
6002
|
+
return `scanTo(${kid(def.sentinel)}, { skip: [${def.skip.map(kid).join(", ")}], orEOF: ${def.orEOF} })`;
|
|
6003
|
+
case "transform": {
|
|
6004
|
+
if (def.fnSrc === void 0) throw new Unserializable("transform without fnSrc");
|
|
6005
|
+
return `_tf(${kid(def.parser)}, ${JSON.stringify(def.fnSrc)})`;
|
|
6006
|
+
}
|
|
6007
|
+
case "node": {
|
|
6008
|
+
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
6009
|
+
const opts = def.unwrap || def.collapse ? `, { ${def.unwrap ? "unwrap: true" : "collapse: true"} }` : "";
|
|
6010
|
+
if (def.type === void 0) {
|
|
6011
|
+
if (def.buildSrc !== void 0) throw new Unserializable("inferred node build without inferred type");
|
|
6012
|
+
return opts ? `node(${kid(def.parser)}, undefined${opts})` : `node(${kid(def.parser)})`;
|
|
6013
|
+
}
|
|
6014
|
+
if (def.buildSrc !== void 0) return `_nd(${JSON.stringify(def.type)}, ${kid(def.parser)}, ${JSON.stringify(def.buildSrc)}${opts})`;
|
|
6015
|
+
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
6016
|
+
}
|
|
6017
|
+
case "grammar": {
|
|
6018
|
+
const trivia2 = def.clearTrivia ? "null" : def.triviaParser ? kid(def.triviaParser) : "undefined";
|
|
6019
|
+
return `parser({ trivia: ${trivia2}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(def.parser)})`;
|
|
6020
|
+
}
|
|
6021
|
+
case "guard":
|
|
6022
|
+
case "withCtx":
|
|
6023
|
+
case "recover":
|
|
6024
|
+
case "unknown":
|
|
6025
|
+
throw new Unserializable(`unsupported tag ${def.tag}`);
|
|
6026
|
+
}
|
|
6027
|
+
}
|
|
6028
|
+
};
|
|
5793
6029
|
|
|
5794
6030
|
// src/compiler/linker.ts
|
|
5795
6031
|
var _nsCounter = 0;
|
|
5796
|
-
function linkable(rulesMap, ns) {
|
|
5797
|
-
const pieces = compileLinkable(
|
|
6032
|
+
function linkable(rulesMap, ns, trivia2) {
|
|
6033
|
+
const pieces = compileLinkable(Object.entries(rulesMap), ns ?? `_lk${_nsCounter++}_`, trivia2 ? { trivia: trivia2 } : void 0);
|
|
5798
6034
|
if (!pieces) throw new Error("linkable(): this grammar cannot be compiled to a linkable artifact (contains a runtime-only parser fallback)");
|
|
5799
6035
|
return pieces;
|
|
5800
6036
|
}
|
|
@@ -5818,28 +6054,6 @@ function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, trivi
|
|
|
5818
6054
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
5819
6055
|
return host;
|
|
5820
6056
|
}
|
|
5821
|
-
function pick(grammar, names) {
|
|
5822
|
-
const p = grammar.ruleFns instanceof Map ? grammar : linkable(grammar);
|
|
5823
|
-
const keep = /* @__PURE__ */ new Set();
|
|
5824
|
-
const has = new Set(p.keys);
|
|
5825
|
-
for (const n of names) {
|
|
5826
|
-
if (!has.has(n)) throw new Error(`pick: rule "${n}" is not in this grammar (available: ${p.keys.join(", ")})`);
|
|
5827
|
-
}
|
|
5828
|
-
const visit = (n) => {
|
|
5829
|
-
if (keep.has(n) || !has.has(n)) return;
|
|
5830
|
-
keep.add(n);
|
|
5831
|
-
for (const d of p.deps.get(n) ?? []) visit(d);
|
|
5832
|
-
};
|
|
5833
|
-
for (const n of names) visit(n);
|
|
5834
|
-
const filt = (m) => new Map([...m].filter(([k]) => keep.has(k)));
|
|
5835
|
-
return {
|
|
5836
|
-
...p,
|
|
5837
|
-
keys: [...keep],
|
|
5838
|
-
ruleFns: filt(p.ruleFns),
|
|
5839
|
-
wrappers: filt(p.wrappers),
|
|
5840
|
-
deps: filt(p.deps)
|
|
5841
|
-
};
|
|
5842
|
-
}
|
|
5843
6057
|
function fusedBody(pieces) {
|
|
5844
6058
|
const winner = /* @__PURE__ */ new Map();
|
|
5845
6059
|
for (const p of pieces) for (const k of p.keys) winner.set(k, p);
|
|
@@ -5859,7 +6073,7 @@ function fusedBody(pieces) {
|
|
|
5859
6073
|
...needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [],
|
|
5860
6074
|
...needsHostReads ? [HOST_READS_DECL] : [],
|
|
5861
6075
|
// Each contributing artifact's namespaced private prelude (regexes, _pf, …).
|
|
5862
|
-
...
|
|
6076
|
+
...new Set(contributingPieces.flatMap((p) => p.prelude)),
|
|
5863
6077
|
// The winning `_r_<Name>` function for each rule (one per name → no redeclare).
|
|
5864
6078
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
5865
6079
|
];
|
|
@@ -5893,12 +6107,13 @@ function fuseRules(pieces) {
|
|
|
5893
6107
|
return new Function("_env", body)(env);
|
|
5894
6108
|
}
|
|
5895
6109
|
var COMPOSED_PIECES = /* @__PURE__ */ Symbol.for("parseman.composedPieces");
|
|
6110
|
+
var COMPOSED_TRIVIA = /* @__PURE__ */ Symbol.for("parseman.composedTrivia");
|
|
5896
6111
|
function isIRPiece(p) {
|
|
5897
6112
|
return !!p && typeof p === "object" && typeof p.ir === "string" && typeof p.ns === "string" && !("ruleFns" in p);
|
|
5898
6113
|
}
|
|
5899
|
-
function materializePiece(p) {
|
|
6114
|
+
function materializePiece(p, trivia2) {
|
|
5900
6115
|
if (!isIRPiece(p)) return p;
|
|
5901
|
-
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns);
|
|
6116
|
+
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, trivia2 ? { trivia: trivia2 } : void 0);
|
|
5902
6117
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
5903
6118
|
return pieces;
|
|
5904
6119
|
}
|
|
@@ -5910,17 +6125,52 @@ function nextComposeNs(used) {
|
|
|
5910
6125
|
used.add(ns);
|
|
5911
6126
|
return ns;
|
|
5912
6127
|
}
|
|
5913
|
-
function
|
|
6128
|
+
function itemCarried(item, used, trivia2) {
|
|
5914
6129
|
const carried = item[COMPOSED_PIECES];
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
6130
|
+
if (Array.isArray(carried)) {
|
|
6131
|
+
const items = carried;
|
|
6132
|
+
for (const p of items) used.add(p.ns);
|
|
6133
|
+
return items;
|
|
6134
|
+
}
|
|
6135
|
+
if (item.ruleFns instanceof Map) {
|
|
6136
|
+
const p = item;
|
|
6137
|
+
used.add(p.ns);
|
|
6138
|
+
return [p];
|
|
6139
|
+
}
|
|
6140
|
+
const map = item;
|
|
6141
|
+
const ns = nextComposeNs(used);
|
|
6142
|
+
const entries = Object.entries(map).filter(([, val]) => {
|
|
6143
|
+
const d = val._def;
|
|
6144
|
+
if (d.tag !== "lazy") return true;
|
|
6145
|
+
try {
|
|
6146
|
+
d.thunk();
|
|
6147
|
+
return true;
|
|
6148
|
+
} catch {
|
|
6149
|
+
return false;
|
|
6150
|
+
}
|
|
6151
|
+
});
|
|
6152
|
+
const ir = serializeRuleMap(entries);
|
|
6153
|
+
return ir ? [{ ns, ir }] : [linkable(map, ns, trivia2)];
|
|
6154
|
+
}
|
|
6155
|
+
function composingTriviaOf(items) {
|
|
6156
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
6157
|
+
const item = items[i];
|
|
6158
|
+
if (!item || item.ruleFns instanceof Map || item[COMPOSED_PIECES]) continue;
|
|
6159
|
+
for (const v2 of Object.values(item)) {
|
|
6160
|
+
const t = v2?._meta?.grammarTrivia;
|
|
6161
|
+
if (t) return t;
|
|
6162
|
+
}
|
|
6163
|
+
}
|
|
6164
|
+
return void 0;
|
|
5918
6165
|
}
|
|
5919
6166
|
function compose(items) {
|
|
5920
6167
|
const used = /* @__PURE__ */ new Set();
|
|
5921
|
-
const
|
|
6168
|
+
const trivia2 = composingTriviaOf(items);
|
|
6169
|
+
const carried = items.flatMap((item) => itemCarried(item, used, trivia2));
|
|
6170
|
+
const pieces = carried.map((p) => materializePiece(p, trivia2));
|
|
5922
6171
|
const map = fuseRules(pieces);
|
|
5923
|
-
Object.defineProperty(map, COMPOSED_PIECES, { value:
|
|
6172
|
+
Object.defineProperty(map, COMPOSED_PIECES, { value: carried, enumerable: false });
|
|
6173
|
+
if (trivia2) Object.defineProperty(map, COMPOSED_TRIVIA, { value: trivia2, enumerable: false });
|
|
5924
6174
|
return map;
|
|
5925
6175
|
}
|
|
5926
6176
|
|
|
@@ -6203,12 +6453,14 @@ function run(entry, input, options = {}) {
|
|
|
6203
6453
|
}
|
|
6204
6454
|
const triviaLog = [];
|
|
6205
6455
|
const errors = [];
|
|
6456
|
+
const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
|
|
6206
6457
|
const ctx = {
|
|
6207
6458
|
trackLines: false,
|
|
6208
6459
|
_triviaLog: triviaLog,
|
|
6209
6460
|
_errors: errors,
|
|
6210
6461
|
build: options.build,
|
|
6211
6462
|
state: options.state,
|
|
6463
|
+
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
|
|
6212
6464
|
...options.triviaCaptureMask !== void 0 ? { _triviaCaptureMask: options.triviaCaptureMask } : {}
|
|
6213
6465
|
};
|
|
6214
6466
|
const r = invoke(entry, input, 0, ctx);
|
|
@@ -6669,7 +6921,6 @@ export {
|
|
|
6669
6921
|
parse,
|
|
6670
6922
|
parseDoc,
|
|
6671
6923
|
parser,
|
|
6672
|
-
pick,
|
|
6673
6924
|
recover,
|
|
6674
6925
|
ref,
|
|
6675
6926
|
regex,
|