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/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, pick, cstBuildHost } from './compiler/linker.ts';
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';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
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(factory) {
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([...Object.entries(rulesMap)], ns ?? `_lk${_nsCounter++}_`);
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
- ...[...new Set(contributingPieces.flatMap((p) => p.prelude))],
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 itemPieces(item, used) {
6128
+ function itemCarried(item, used, trivia2) {
5914
6129
  const carried = item[COMPOSED_PIECES];
5915
- const pieces = Array.isArray(carried) ? carried.map(materializePiece) : item.ruleFns instanceof Map ? [item] : [linkable(item, nextComposeNs(used))];
5916
- for (const p of pieces) used.add(p.ns);
5917
- return pieces;
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 pieces = items.flatMap((item) => itemPieces(item, used));
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: pieces, enumerable: false });
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,