parseman 0.22.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/compiler/codegen.d.ts +3 -1
- 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/index.cjs +273 -36
- 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 +273 -36
- package/dist/index.js.map +3 -3
- package/dist/plugin/index.cjs +128 -27
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +128 -27
- package/dist/plugin/index.js.map +3 -3
- 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
|
@@ -5433,9 +5433,10 @@ function publicRuleWrapperSource(rule, fnSource) {
|
|
|
5433
5433
|
if (labels === void 0) return fnSource;
|
|
5434
5434
|
return `Object.assign(${fnSource}, { _meta: { triviaKindLabels: ${JSON.stringify(labels)} } })`;
|
|
5435
5435
|
}
|
|
5436
|
-
function compileLinkable(ruleMapArg, ns) {
|
|
5436
|
+
function compileLinkable(ruleMapArg, ns, opts) {
|
|
5437
5437
|
if (!ns) throw new Error("compileLinkable: ns must be a non-empty namespace");
|
|
5438
5438
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
5439
|
+
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
5439
5440
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
5440
5441
|
const d = val._def;
|
|
5441
5442
|
if (d.tag !== "lazy") return true;
|
|
@@ -5466,7 +5467,8 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5466
5467
|
capturing: ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
5467
5468
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
5468
5469
|
ns,
|
|
5469
|
-
deferFirstSetRefs: true
|
|
5470
|
+
deferFirstSetRefs: true,
|
|
5471
|
+
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {}
|
|
5470
5472
|
};
|
|
5471
5473
|
const seen = /* @__PURE__ */ new Map();
|
|
5472
5474
|
const ruleNames = /* @__PURE__ */ new Map();
|
|
@@ -5529,7 +5531,10 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5529
5531
|
ctx.indent = 1;
|
|
5530
5532
|
ctx.failLabel = "_pfail";
|
|
5531
5533
|
ctx.recordFail = true;
|
|
5534
|
+
const savedTrivia = ctx.activeTrivia;
|
|
5535
|
+
if (rule._meta.isTrivia) ctx.activeTrivia = void 0;
|
|
5532
5536
|
const body = emit(resolved, ctx, "_pos");
|
|
5537
|
+
ctx.activeTrivia = savedTrivia;
|
|
5533
5538
|
ctx.indent = savedIndent;
|
|
5534
5539
|
ctx.failLabel = savedFail;
|
|
5535
5540
|
ctx.recordFail = savedRec;
|
|
@@ -5728,6 +5733,64 @@ function escapeClassChar(ch) {
|
|
|
5728
5733
|
}
|
|
5729
5734
|
|
|
5730
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
|
+
}
|
|
5731
5794
|
function evalRuleMapIR(ir) {
|
|
5732
5795
|
const _tf = (child, src) => {
|
|
5733
5796
|
let fn2;
|
|
@@ -5802,11 +5865,172 @@ function evalRuleMapIR(ir) {
|
|
|
5802
5865
|
);
|
|
5803
5866
|
return Object.entries(map);
|
|
5804
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
|
+
};
|
|
5805
6029
|
|
|
5806
6030
|
// src/compiler/linker.ts
|
|
5807
6031
|
var _nsCounter = 0;
|
|
5808
|
-
function linkable(rulesMap, ns) {
|
|
5809
|
-
const pieces = compileLinkable(
|
|
6032
|
+
function linkable(rulesMap, ns, trivia2) {
|
|
6033
|
+
const pieces = compileLinkable(Object.entries(rulesMap), ns ?? `_lk${_nsCounter++}_`, trivia2 ? { trivia: trivia2 } : void 0);
|
|
5810
6034
|
if (!pieces) throw new Error("linkable(): this grammar cannot be compiled to a linkable artifact (contains a runtime-only parser fallback)");
|
|
5811
6035
|
return pieces;
|
|
5812
6036
|
}
|
|
@@ -5830,28 +6054,6 @@ function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, trivi
|
|
|
5830
6054
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
5831
6055
|
return host;
|
|
5832
6056
|
}
|
|
5833
|
-
function pick(grammar, names) {
|
|
5834
|
-
const p = grammar.ruleFns instanceof Map ? grammar : linkable(grammar);
|
|
5835
|
-
const keep = /* @__PURE__ */ new Set();
|
|
5836
|
-
const has = new Set(p.keys);
|
|
5837
|
-
for (const n of names) {
|
|
5838
|
-
if (!has.has(n)) throw new Error(`pick: rule "${n}" is not in this grammar (available: ${p.keys.join(", ")})`);
|
|
5839
|
-
}
|
|
5840
|
-
const visit = (n) => {
|
|
5841
|
-
if (keep.has(n) || !has.has(n)) return;
|
|
5842
|
-
keep.add(n);
|
|
5843
|
-
for (const d of p.deps.get(n) ?? []) visit(d);
|
|
5844
|
-
};
|
|
5845
|
-
for (const n of names) visit(n);
|
|
5846
|
-
const filt = (m) => new Map([...m].filter(([k]) => keep.has(k)));
|
|
5847
|
-
return {
|
|
5848
|
-
...p,
|
|
5849
|
-
keys: [...keep],
|
|
5850
|
-
ruleFns: filt(p.ruleFns),
|
|
5851
|
-
wrappers: filt(p.wrappers),
|
|
5852
|
-
deps: filt(p.deps)
|
|
5853
|
-
};
|
|
5854
|
-
}
|
|
5855
6057
|
function fusedBody(pieces) {
|
|
5856
6058
|
const winner = /* @__PURE__ */ new Map();
|
|
5857
6059
|
for (const p of pieces) for (const k of p.keys) winner.set(k, p);
|
|
@@ -5871,7 +6073,7 @@ function fusedBody(pieces) {
|
|
|
5871
6073
|
...needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [],
|
|
5872
6074
|
...needsHostReads ? [HOST_READS_DECL] : [],
|
|
5873
6075
|
// Each contributing artifact's namespaced private prelude (regexes, _pf, …).
|
|
5874
|
-
...
|
|
6076
|
+
...new Set(contributingPieces.flatMap((p) => p.prelude)),
|
|
5875
6077
|
// The winning `_r_<Name>` function for each rule (one per name → no redeclare).
|
|
5876
6078
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
5877
6079
|
];
|
|
@@ -5905,12 +6107,13 @@ function fuseRules(pieces) {
|
|
|
5905
6107
|
return new Function("_env", body)(env);
|
|
5906
6108
|
}
|
|
5907
6109
|
var COMPOSED_PIECES = /* @__PURE__ */ Symbol.for("parseman.composedPieces");
|
|
6110
|
+
var COMPOSED_TRIVIA = /* @__PURE__ */ Symbol.for("parseman.composedTrivia");
|
|
5908
6111
|
function isIRPiece(p) {
|
|
5909
6112
|
return !!p && typeof p === "object" && typeof p.ir === "string" && typeof p.ns === "string" && !("ruleFns" in p);
|
|
5910
6113
|
}
|
|
5911
|
-
function materializePiece(p) {
|
|
6114
|
+
function materializePiece(p, trivia2) {
|
|
5912
6115
|
if (!isIRPiece(p)) return p;
|
|
5913
|
-
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns);
|
|
6116
|
+
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, trivia2 ? { trivia: trivia2 } : void 0);
|
|
5914
6117
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
5915
6118
|
return pieces;
|
|
5916
6119
|
}
|
|
@@ -5922,17 +6125,52 @@ function nextComposeNs(used) {
|
|
|
5922
6125
|
used.add(ns);
|
|
5923
6126
|
return ns;
|
|
5924
6127
|
}
|
|
5925
|
-
function
|
|
6128
|
+
function itemCarried(item, used, trivia2) {
|
|
5926
6129
|
const carried = item[COMPOSED_PIECES];
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
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;
|
|
5930
6165
|
}
|
|
5931
6166
|
function compose(items) {
|
|
5932
6167
|
const used = /* @__PURE__ */ new Set();
|
|
5933
|
-
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));
|
|
5934
6171
|
const map = fuseRules(pieces);
|
|
5935
|
-
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 });
|
|
5936
6174
|
return map;
|
|
5937
6175
|
}
|
|
5938
6176
|
|
|
@@ -6683,7 +6921,6 @@ export {
|
|
|
6683
6921
|
parse,
|
|
6684
6922
|
parseDoc,
|
|
6685
6923
|
parser,
|
|
6686
|
-
pick,
|
|
6687
6924
|
recover,
|
|
6688
6925
|
ref,
|
|
6689
6926
|
regex,
|