parseman 0.18.2 → 0.19.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.
@@ -217,6 +217,13 @@ function ref() {
217
217
  define(p) {
218
218
  if (resolved) throw new Error("ref<T>() already defined");
219
219
  resolved = p;
220
+ meta.firstSet = p._meta.firstSet;
221
+ meta.canMatchNewline = p._meta.canMatchNewline;
222
+ meta.isTrivia = p._meta.isTrivia;
223
+ if (p._meta.triviaKindLabels !== void 0) meta.triviaKindLabels = p._meta.triviaKindLabels;
224
+ else delete meta.triviaKindLabels;
225
+ if (p._meta.disjoint !== void 0) meta.disjoint = p._meta.disjoint;
226
+ else delete meta.disjoint;
220
227
  }
221
228
  };
222
229
  return slot;
@@ -324,7 +331,8 @@ function saveCstMark(ctx) {
324
331
  return {
325
332
  raw: cstRawLen(ctx),
326
333
  tlog: cstTlLen(ctx),
327
- leaves: cstLeavesLen(ctx)
334
+ leaves: cstLeavesLen(ctx),
335
+ fields: ctx._fields?.length ?? 0
328
336
  };
329
337
  }
330
338
  function rollbackBufList(b, keyMulti, keySingle, len) {
@@ -348,11 +356,13 @@ function rollbackCstCapture(ctx, mark) {
348
356
  if (mark.tlog === 0) b.tl = void 0;
349
357
  else b.tl.length = mark.tlog;
350
358
  }
359
+ if (ctx._fields) ctx._fields.length = mark.fields;
351
360
  return;
352
361
  }
353
362
  if (ctx._cstRawChildren) ctx._cstRawChildren.length = mark.raw;
354
363
  if (ctx._cstTriviaLog) ctx._cstTriviaLog.length = mark.tlog;
355
364
  if (ctx._cstLeaves) ctx._cstLeaves.length = mark.leaves;
365
+ if (ctx._fields) ctx._fields.length = mark.fields;
356
366
  }
357
367
  function pushCstTriviaEntry(ctx, start, end, kindIndex) {
358
368
  const insertIdx = cstRawLen(ctx);
@@ -1089,10 +1099,10 @@ function needsDeferredTriviaCommit(ctx) {
1089
1099
  }
1090
1100
  function saveTriviaMark(ctx) {
1091
1101
  const m = saveCstMark(ctx);
1092
- return { raw: m.raw, tlog: m.tlog, leaves: m.leaves, log: ctx._triviaLog ? ctx._triviaLog.length : 0 };
1102
+ return { raw: m.raw, tlog: m.tlog, leaves: m.leaves, fields: m.fields, log: ctx._triviaLog ? ctx._triviaLog.length : 0 };
1093
1103
  }
1094
1104
  function rollbackTrivia(ctx, mark) {
1095
- rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves });
1105
+ rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields });
1096
1106
  if (ctx._triviaLog) ctx._triviaLog.length = mark.log;
1097
1107
  }
1098
1108
  function scanWithLabels(input, cur, ctx) {
@@ -1476,6 +1486,9 @@ function markUnusedValues(root) {
1476
1486
  case "transform":
1477
1487
  visit(def.parser, true);
1478
1488
  return;
1489
+ case "field":
1490
+ visit(def.parser, true);
1491
+ return;
1479
1492
  case "skip":
1480
1493
  visit(def.main, consumed);
1481
1494
  visit(def.skipped, false);
@@ -1527,6 +1540,11 @@ function markUnusedValues(root) {
1527
1540
  }
1528
1541
 
1529
1542
  // src/combinators/parser.ts
1543
+ function tagRule(r, key) {
1544
+ ;
1545
+ r._ruleName = key;
1546
+ if (r._def.tag === "node" && r._def.type === void 0) r._def.type = key;
1547
+ }
1530
1548
  function rules(factory) {
1531
1549
  const cache = {};
1532
1550
  const proxy = new Proxy(cache, {
@@ -1535,7 +1553,7 @@ function rules(factory) {
1535
1553
  const record = target;
1536
1554
  if (!(key in record)) {
1537
1555
  const r = ref();
1538
- r._ruleName = key;
1556
+ tagRule(r, key);
1539
1557
  record[key] = r;
1540
1558
  }
1541
1559
  return record[key];
@@ -1546,12 +1564,12 @@ function rules(factory) {
1546
1564
  const placeholder = cache[key];
1547
1565
  const parser2 = definitions[key];
1548
1566
  if (placeholder !== void 0 && typeof placeholder.define === "function") {
1549
- ;
1567
+ tagRule(parser2, key);
1550
1568
  placeholder.define(parser2);
1551
1569
  placeholder._meta.firstSet = parser2._meta.firstSet;
1552
1570
  placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
1553
1571
  } else {
1554
- ;
1572
+ tagRule(parser2, key);
1555
1573
  cache[key] = parser2;
1556
1574
  }
1557
1575
  }
@@ -1608,44 +1626,130 @@ function buildReadsTrivia(def) {
1608
1626
  const src = def.buildSrc ?? def.build.toString();
1609
1627
  const arity = confirmedBuildArity(src);
1610
1628
  if (arity === null) return true;
1611
- return arity >= 4;
1629
+ return arity >= 5;
1612
1630
  }
1613
1631
  function buildReadsState(def) {
1614
1632
  if (!def.build) return true;
1615
1633
  const src = def.buildSrc ?? def.build.toString();
1616
1634
  const arity = confirmedBuildArity(src);
1617
1635
  if (arity === null) return true;
1618
- return arity >= 5;
1636
+ return arity >= 6;
1637
+ }
1638
+
1639
+ // src/compiler/fields.ts
1640
+ function buildReadsFields(def) {
1641
+ if (!def.build) return true;
1642
+ const src = def.buildSrc ?? def.build.toString();
1643
+ const arity = confirmedBuildArity(src);
1644
+ if (arity === null) return true;
1645
+ return arity >= 2;
1646
+ }
1647
+ function parserHasOwnFields(p, seen = /* @__PURE__ */ new Set()) {
1648
+ if (seen.has(p)) return false;
1649
+ seen.add(p);
1650
+ const d = p._def;
1651
+ switch (d.tag) {
1652
+ case "field":
1653
+ return true;
1654
+ case "node":
1655
+ return false;
1656
+ case "lazy": {
1657
+ try {
1658
+ return parserHasOwnFields(d.thunk(), seen);
1659
+ } catch {
1660
+ return false;
1661
+ }
1662
+ }
1663
+ case "sequence":
1664
+ case "choice":
1665
+ return d.parsers.some((x) => parserHasOwnFields(x, seen));
1666
+ case "sepBy":
1667
+ return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.separator, seen);
1668
+ case "skip":
1669
+ return parserHasOwnFields(d.main, seen) || parserHasOwnFields(d.skipped, seen);
1670
+ case "grammar":
1671
+ return parserHasOwnFields(d.parser, seen) || (d.triviaParser ? parserHasOwnFields(d.triviaParser, seen) : false);
1672
+ case "scanTo":
1673
+ return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen));
1674
+ case "recover":
1675
+ return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.sentinel, seen);
1676
+ case "many":
1677
+ case "oneOrMore":
1678
+ case "optional":
1679
+ case "transform":
1680
+ case "trivia":
1681
+ case "token":
1682
+ case "label":
1683
+ case "expect":
1684
+ case "withCtx":
1685
+ case "not":
1686
+ return parserHasOwnFields(d.parser, seen);
1687
+ default:
1688
+ return false;
1689
+ }
1690
+ }
1691
+ function buildFieldMap(captures) {
1692
+ if (!captures?.length) return void 0;
1693
+ const out = {};
1694
+ for (const cap of captures) {
1695
+ const entry = { value: cap.value, span: cap.span };
1696
+ const current = out[cap.name];
1697
+ if (current === void 0) out[cap.name] = entry;
1698
+ else if (Array.isArray(current)) current.push(entry);
1699
+ else out[cap.name] = [current, entry];
1700
+ }
1701
+ return out;
1619
1702
  }
1620
1703
 
1621
1704
  // src/combinators/node.ts
1622
- function collapseChild(child) {
1705
+ function unwrapChild(child) {
1623
1706
  return child !== null && typeof child === "object" && child._tag === "leaf" ? child.value : child;
1624
1707
  }
1625
- function node(type, combinator, build, opts) {
1708
+ function isCstChild(value) {
1709
+ return typeof value === "object" && value !== null && (value._tag === "node" || value._tag === "leaf" || value._tag === "error");
1710
+ }
1711
+ function missingInferredType() {
1712
+ throw new Error('node(): inferred node type requires a rules() key; pass node("Type", parser) outside rules()');
1713
+ }
1714
+ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
1715
+ const hasExplicitType = typeof typeOrCombinator === "string";
1716
+ const type = hasExplicitType ? typeOrCombinator : void 0;
1717
+ const combinator = hasExplicitType ? combinatorOrBuild : typeOrCombinator;
1718
+ const build = hasExplicitType ? buildOrOpts : combinatorOrBuild;
1719
+ const opts = hasExplicitType ? maybeOpts : buildOrOpts;
1720
+ const baseDef = { tag: "node", parser: combinator, ...type === void 0 ? {} : { type }, ...build === void 0 ? {} : { build } };
1626
1721
  const meta = {
1627
1722
  firstSet: combinator._meta.firstSet,
1628
1723
  canMatchNewline: combinator._meta.canMatchNewline,
1629
1724
  isTrivia: false
1630
1725
  };
1726
+ const unwrap = opts?.unwrap === true;
1631
1727
  const collapse = opts?.collapse === true;
1632
- const def = collapse ? { tag: "node", type, parser: combinator, build, collapse: true } : { tag: "node", type, parser: combinator, build };
1728
+ if (unwrap && collapse) {
1729
+ throw new Error("node() options cannot set both unwrap and collapse");
1730
+ }
1731
+ const def = unwrap || collapse ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {} } : baseDef;
1633
1732
  const capturesTrivia = build ? buildReadsTrivia(def) : true;
1634
1733
  const clonesState = build ? buildReadsState(def) : true;
1734
+ const capturesFields = parserHasOwnFields(combinator) && (build ? buildReadsFields(def) : true);
1635
1735
  return {
1636
1736
  _tag: "node",
1637
1737
  _meta: meta,
1638
1738
  _def: def,
1639
1739
  parse(input, pos, ctx) {
1640
1740
  const saved = beginCstNodeCapture(ctx);
1741
+ const savedFields = ctx._fields;
1742
+ ctx._fields = capturesFields ? [] : void 0;
1641
1743
  if (!capturesTrivia) ctx.captureTrivia = false;
1642
1744
  const r = combinator.parse(input, pos, ctx);
1745
+ const fields = capturesFields ? buildFieldMap(ctx._fields) : void 0;
1746
+ ctx._fields = savedFields;
1643
1747
  const { children, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
1644
1748
  if (!r.ok) return r;
1645
1749
  const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
1646
- const built = collapse && children.length === 1 ? collapseChild(children[0]) : build ? build(children, rawChildren, r.span, triviaLog, st) : ctx.build ? ctx.build(type, children, rawChildren, r.span, triviaLog, st) : { _tag: "node", type, span: { start: r.span.start, end: r.span.end }, state: st ?? null, children };
1647
- const isNodeLike = typeof built === "object" && built !== null && built._tag === "node";
1648
- const rawEntry = isNodeLike ? built : { _tag: "leaf", value: typeof built === "string" ? built : "", span: r.span };
1750
+ const nodeType = def.type ?? missingInferredType();
1751
+ const built = unwrap && children.length === 1 ? unwrapChild(children[0]) : collapse && children.length === 1 ? children[0] : !build && ctx.build?._parsemanCstCollapse && children.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children[0], children, rawChildren) ? children[0] : build ? build(children, fields, r.span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children, fields, r.span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: { start: r.span.start, end: r.span.end }, state: st ?? null, children };
1752
+ const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : "", span: r.span };
1649
1753
  if (saved.buf !== void 0 || saved.ch !== void 0) {
1650
1754
  pushCstChild(ctx, built, rawEntry);
1651
1755
  }
@@ -1706,6 +1810,19 @@ function label(name, combinator) {
1706
1810
  }
1707
1811
  };
1708
1812
  }
1813
+ function field(name, combinator) {
1814
+ return {
1815
+ _tag: combinator._tag,
1816
+ _meta: combinator._meta,
1817
+ _def: { tag: "field", name, parser: combinator },
1818
+ parse(input, pos, ctx) {
1819
+ const result = combinator.parse(input, pos, ctx);
1820
+ if (!result.ok) return result;
1821
+ ctx._fields?.push({ name, value: result.value, span: result.span });
1822
+ return result;
1823
+ }
1824
+ };
1825
+ }
1709
1826
 
1710
1827
  // src/compiler/line-index.ts
1711
1828
  function buildLineIndex(input) {
@@ -3165,21 +3282,22 @@ function emitScannableTerminal(shape, c) {
3165
3282
  }
3166
3283
 
3167
3284
  // src/compiler/inline-build.ts
3168
- var MK_BUILD_RE = /^\(\s*(?:\w+\s*,\s*){3}\w+\s*\)\s*=>\s*mk\s*\(\s*(['"])([^'"]+)\1\s*,\s*\w+\s*,\s*\w+\s*,\s*\w+\s*,\s*\w+\s*\)\s*$/;
3285
+ var MK_BUILD_RE = /^\(\s*(\w+)\s*,\s*\w+\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\)\s*=>\s*mk\s*\(\s*(['"])([^'"]+)\5\s*,\s*\1\s*,\s*\3\s*,\s*\2\s*,\s*\4\s*\)\s*$/;
3169
3286
  function escapeRegExp(s) {
3170
3287
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3171
3288
  }
3172
3289
  function looseMkBuildRe(type) {
3173
3290
  return new RegExp(
3174
- String.raw`^\(\s*(?:\w+\s*,\s*){3}\w+\s*\)\s*=>\s*.+\(\s*(['"])${escapeRegExp(type)}\1\s*,\s*\w+\s*,\s*\w+\s*,\s*\w+\s*,\s*\w+\s*\)\s*$`
3291
+ String.raw`^\(\s*(\w+)\s*,\s*\w+\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\)\s*=>\s*.+\(\s*(['"])${escapeRegExp(type)}\5\s*,\s*\1\s*,\s*\3\s*,\s*\2\s*,\s*\4\s*\)\s*$`
3175
3292
  );
3176
3293
  }
3177
3294
  function analyzeMkInlineBuild(def) {
3178
3295
  if (!def.build) return null;
3296
+ if (def.type === void 0) return null;
3179
3297
  const src = (def.buildSrc ?? def.build.toString()).trim();
3180
3298
  const strict = src.match(MK_BUILD_RE);
3181
3299
  if (strict) {
3182
- const mkType = strict[2];
3300
+ const mkType = strict[6];
3183
3301
  return mkType === def.type ? def.type : null;
3184
3302
  }
3185
3303
  if (looseMkBuildRe(def.type).test(src)) return def.type;
@@ -3514,8 +3632,9 @@ function planDisjointDispatch(parsers) {
3514
3632
  }
3515
3633
  return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
3516
3634
  }
3517
- function captureRestoreBody(mL, mR, mTl, mLg) {
3518
- const base = `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${mL}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${mR}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${mTl}`;
3635
+ function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
3636
+ const fieldRestore = mF ? `; if (_ctx._fields) _ctx._fields.length = ${mF}` : "";
3637
+ const base = `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${mL}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${mR}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${mTl}${fieldRestore}`;
3519
3638
  return mLg ? `${base}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${mLg}` : base;
3520
3639
  }
3521
3640
  function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
@@ -3563,6 +3682,7 @@ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
3563
3682
  // Delegating wrappers: defer to the wrapped parser.
3564
3683
  case "transform":
3565
3684
  case "label":
3685
+ case "field":
3566
3686
  case "expect":
3567
3687
  case "withCtx":
3568
3688
  case "grammar":
@@ -3609,6 +3729,7 @@ function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
3609
3729
  case "optional":
3610
3730
  case "transform":
3611
3731
  case "label":
3732
+ case "field":
3612
3733
  case "expect":
3613
3734
  case "withCtx":
3614
3735
  case "grammar":
@@ -3646,22 +3767,25 @@ function emitFallible(inner, ctx, pos, swallow = false) {
3646
3767
  ctx.recordFail = savedRecord;
3647
3768
  const ind0 = ind(ctx);
3648
3769
  const needsRollback = ctx.capturing && mayLeavePartialCapture(inner);
3770
+ const needsFieldRollback = needsRollback && parserHasOwnFields(inner);
3649
3771
  const mL = needsRollback ? v(ctx, "_fcl") : null;
3650
3772
  const mR = needsRollback ? v(ctx, "_fcr") : null;
3651
3773
  const mTl = needsRollback ? v(ctx, "_fctl") : null;
3774
+ const mF = needsFieldRollback ? v(ctx, "_fcf") : null;
3652
3775
  const stmts = [
3653
3776
  `${ind0}let ${okV} = false, ${valV}, ${endV} = ${pos}`,
3654
3777
  ...mL ? [
3655
3778
  `${ind0}const ${mL} = _ctx._cstLeaves?.length ?? 0`,
3656
3779
  `${ind0}const ${mR} = _ctx._cstRawChildren?.length ?? 0`,
3657
- `${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0`
3780
+ `${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0`,
3781
+ ...mF ? [`${ind0}const ${mF} = _ctx._fields?.length ?? 0`] : []
3658
3782
  ] : [],
3659
3783
  `${ind0}${lbl}: {`,
3660
3784
  ...r.stmts,
3661
3785
  `${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
3662
3786
  `${ind0}}`,
3663
3787
  ...mL ? [
3664
- `${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null)} }`
3788
+ `${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
3665
3789
  ] : []
3666
3790
  ];
3667
3791
  return { stmts, okVar: okV, valVar: valV, endVar: endV };
@@ -3888,6 +4012,7 @@ function failsAtStart(p) {
3888
4012
  return true;
3889
4013
  case "transform":
3890
4014
  case "label":
4015
+ case "field":
3891
4016
  return failsAtStart(d.parser);
3892
4017
  default:
3893
4018
  return false;
@@ -3907,6 +4032,7 @@ function canMatchEmptyAtStart(p) {
3907
4032
  return true;
3908
4033
  case "transform":
3909
4034
  case "label":
4035
+ case "field":
3910
4036
  return canMatchEmptyAtStart(d.parser);
3911
4037
  case "literal":
3912
4038
  return d.value.length === 0;
@@ -4089,11 +4215,13 @@ function emitFirstMatch(def, ctx, pos) {
4089
4215
  const skipCond = gateCond ? `!${resOkV} && ${gateCond}` : `!${resOkV}`;
4090
4216
  const armHasAutoNot = !!(autoNot && autoNot.length > 0);
4091
4217
  const armNeedsRollback = ctx.capturing && (mayLeavePartialCapture(p) || armHasAutoNot && capturesLeaf(p));
4218
+ const armNeedsFieldRollback = armNeedsRollback && parserHasOwnFields(p);
4092
4219
  const markLeaves = armNeedsRollback ? v(ctx, "_cml") : null;
4093
4220
  const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
4094
4221
  const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
4095
4222
  const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
4096
- const rollback = markLeaves ? captureRestoreBody(markLeaves, markRaw, markTl, markLog) : "";
4223
+ const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
4224
+ const rollback = markLeaves ? captureRestoreBody(markLeaves, markRaw, markTl, markLog, markFields) : "";
4097
4225
  const failSlot = atStart ? staticFx : "_ctx._fx";
4098
4226
  stmts.push(`${ind0}if (${skipCond}) {`);
4099
4227
  if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
@@ -4103,7 +4231,8 @@ function emitFirstMatch(def, ctx, pos) {
4103
4231
  `${ind(ctx)}const ${markLeaves} = _ctx._cstLeaves?.length ?? 0`,
4104
4232
  `${ind(ctx)}const ${markRaw} = _ctx._cstRawChildren?.length ?? 0`,
4105
4233
  `${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog?.length ?? 0`,
4106
- `${ind(ctx)}const ${markLog} = _ctx._triviaLog?.length ?? 0`
4234
+ `${ind(ctx)}const ${markLog} = _ctx._triviaLog?.length ?? 0`,
4235
+ ...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
4107
4236
  );
4108
4237
  }
4109
4238
  const { stmts: armStmts, okVar, valVar, endVar } = emitFallible(p, ctx, pos, atStart);
@@ -4496,6 +4625,9 @@ function emitToken(def, ctx, pos) {
4496
4625
  };
4497
4626
  }
4498
4627
  function emitNode(def, ctx, pos) {
4628
+ if (def.type === void 0) {
4629
+ throw new Error('node(): inferred node type requires a rules() key; pass node("Type", parser) outside rules()');
4630
+ }
4499
4631
  const structural = def.build === void 0;
4500
4632
  const mkType = structural ? null : analyzeMkInlineBuild(def);
4501
4633
  let buildIdx = null;
@@ -4507,25 +4639,36 @@ function emitNode(def, ctx, pos) {
4507
4639
  const i = ind(ctx);
4508
4640
  const capturesTrivia = mkType !== null || !structural && buildReadsTrivia(def);
4509
4641
  const clonesState = !structural && buildReadsState(def);
4642
+ const hasFields = parserHasOwnFields(def.parser);
4643
+ const capturesFields = hasFields && !structural && buildReadsFields(def);
4510
4644
  const chV = v(ctx, "_ch");
4511
4645
  const rawV = v(ctx, "_raw");
4512
4646
  const capTLv = structural ? v(ctx, "_ctl") : null;
4513
4647
  const capSTv = structural ? v(ctx, "_cst") : null;
4648
+ const capFv = structural && hasFields ? v(ctx, "_cf") : null;
4514
4649
  const tlV = capturesTrivia || structural ? v(ctx, "_tl") : "_EMPTY_TL";
4515
4650
  if (!capturesTrivia) ctx.needsEmptyTl = true;
4516
4651
  const sc = v(ctx, "_sc"), sl = v(ctx, "_sl"), sr = v(ctx, "_sr"), st = v(ctx, "_st"), stl = v(ctx, "_stl");
4517
4652
  if (structural) ctx.needsHostReads = true;
4518
- const allocStmt = structural ? `${i}const ${capTLv} = _ctx._pmCapTL ??= _hostReads(_ctx.build, 4), ${capSTv} = _ctx._pmCapST ??= (_ctx.build === undefined || _hostReads(_ctx.build, 5))
4653
+ const hostTriviaGate = `_ctx.build !== undefined && (_ctx.build._parsemanCaptureTrivia !== undefined ? _ctx.build._parsemanCaptureTrivia(${JSON.stringify(def.type)}) : (_ctx._pmCapTL ??= _hostReads(_ctx.build, 5)))`;
4654
+ const allocStmt = structural ? `${i}const ${capTLv} = ${hostTriviaGate}, ${capSTv} = _ctx._pmCapST ??= (_ctx.build === undefined || _hostReads(_ctx.build, 6))${capFv ? `, ${capFv} = _ctx.build !== undefined && _hostReads(_ctx.build, 2)` : ""}
4519
4655
  ${i}const ${chV} = [], ${rawV} = [], ${tlV} = ${capTLv} ? [] : _EMPTY_TL` : capturesTrivia ? `${i}const ${chV} = [], ${rawV} = [], ${tlV} = []` : `${i}const ${chV} = [], ${rawV} = []`;
4520
4656
  const innerTl = structural ? `${capTLv} ? ${tlV} : undefined` : capturesTrivia ? tlV : "undefined";
4657
+ const fieldsOn = structural ? capFv ?? "false" : capturesFields ? "true" : "false";
4658
+ const sf = hasFields ? v(ctx, "_sf") : null;
4659
+ const fArr = hasFields ? v(ctx, "_fa") : null;
4660
+ const fObj = hasFields ? v(ctx, "_fields") : "undefined";
4521
4661
  const stmts = [
4522
4662
  allocStmt,
4523
- `${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog`,
4524
- `${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}`
4663
+ `${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog${sf ? `, ${sf} = _ctx._fields` : ""}`,
4664
+ `${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}${sf ? `; _ctx._fields = ${fieldsOn} ? [] : undefined` : ""}`
4525
4665
  ];
4526
4666
  const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
4527
4667
  stmts.push(...innerStmts);
4528
- stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}`);
4668
+ if (sf && fArr) {
4669
+ stmts.push(`${i}const ${fArr} = _ctx._fields`);
4670
+ }
4671
+ stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}${sf ? `; _ctx._fields = ${sf}` : ""}`);
4529
4672
  stmts.push(...emitIfFail(ctx, `!${okVar}`, propagateFailBody(ctx)));
4530
4673
  let stV = "undefined";
4531
4674
  if (structural) {
@@ -4535,14 +4678,33 @@ ${i}const ${chV} = [], ${rawV} = [], ${tlV} = ${capTLv} ? [] : _EMPTY_TL` : capt
4535
4678
  stV = v(ctx, "_nst");
4536
4679
  stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
4537
4680
  }
4681
+ if (sf && fArr) {
4682
+ const fe = v(ctx, "_fe");
4683
+ const cur = v(ctx, "_fc");
4684
+ stmts.push(
4685
+ `${i}let ${fObj} = undefined`,
4686
+ `${i}if (${fArr} && ${fArr}.length) {`,
4687
+ `${i} ${fObj} = {}`,
4688
+ `${i} for (const ${fe} of ${fArr}) {`,
4689
+ `${i} const ${cur} = ${fObj}[${fe}.name], _entry = { value: ${fe}.value, span: ${fe}.span }`,
4690
+ `${i} if (${cur} === undefined) ${fObj}[${fe}.name] = _entry`,
4691
+ `${i} else if (Array.isArray(${cur})) ${cur}.push(_entry)`,
4692
+ `${i} else ${fObj}[${fe}.name] = [${cur}, _entry]`,
4693
+ `${i} }`,
4694
+ `${i}}`
4695
+ );
4696
+ }
4538
4697
  const ndV = v(ctx, "_nd");
4539
- const buildExpr = structural ? `{ _tag: 'node', type: ${JSON.stringify(def.type)}, span: { start: ${pos}, end: ${endVar} }, state: ${stV} ?? null, children: ${chV} }` : mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, pos, endVar, tlV) : `${buildRef(ctx)}[${buildIdx}](${chV}, ${rawV}, { start: ${pos}, end: ${endVar} }, ${tlV}, ${stV})`;
4540
- const ndExpr = ctx.ns || structural ? `_ctx.build !== undefined ? _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${rawV}, { start: ${pos}, end: ${endVar} }, ${tlV}, ${stV}) : (${buildExpr})` : buildExpr;
4541
- const finalExpr = def.collapse ? `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})` : ndExpr;
4698
+ const buildExpr = structural ? `{ _tag: 'node', type: ${JSON.stringify(def.type)}, span: { start: ${pos}, end: ${endVar} }, state: ${stV} ?? null, children: ${chV} }` : mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, pos, endVar, tlV) : `${buildRef(ctx)}[${buildIdx}](${chV}, ${fObj}, { start: ${pos}, end: ${endVar} }, ${rawV}, ${tlV}, ${stV})`;
4699
+ const ndExpr = ctx.ns || structural ? `_ctx.build !== undefined ? _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${fObj}, { start: ${pos}, end: ${endVar} }, ${rawV}, ${tlV}, ${stV}) : (${buildExpr})` : buildExpr;
4700
+ const hostCollapseExpr = ctx.ns || structural ? `_ctx.build !== undefined && _ctx.build._parsemanCstCollapse !== undefined && ${chV}.length === 1 && ${rawV}.length === 1 && _ctx.build._parsemanCstCollapse(${JSON.stringify(def.type)}, ${chV}[0], ${chV}, ${rawV}) ? ${chV}[0] : (${ndExpr})` : ndExpr;
4701
+ const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
4702
+ const collapseExpr = `${chV}.length === 1 ? ${chV}[0] : (${ndExpr})`;
4703
+ const finalExpr = def.unwrap ? unwrapExpr : def.collapse ? collapseExpr : hostCollapseExpr;
4542
4704
  stmts.push(
4543
4705
  `${i}const ${ndV} = ${finalExpr}`,
4544
4706
  `${i}if (${sc}) ${sc}.push(${ndV})`,
4545
- `${i}if (${sr}) ${sr}.push((typeof ${ndV} === 'object' && ${ndV} !== null && ${ndV}._tag === 'node') ? ${ndV} : { _tag: 'leaf', value: typeof ${ndV} === 'string' ? ${ndV} : '', span: { start: ${pos}, end: ${endVar} } })`
4707
+ `${i}if (${sr}) ${sr}.push((typeof ${ndV} === 'object' && ${ndV} !== null && (${ndV}._tag === 'node' || ${ndV}._tag === 'leaf' || ${ndV}._tag === 'error')) ? ${ndV} : { _tag: 'leaf', value: typeof ${ndV} === 'string' ? ${ndV} : '', span: { start: ${pos}, end: ${endVar} } })`
4546
4708
  );
4547
4709
  return { stmts, valueVar: ndV, endVar };
4548
4710
  }
@@ -4757,6 +4919,17 @@ function emitDispatch(p, ctx, pos) {
4757
4919
  endVar: inner.endVar
4758
4920
  };
4759
4921
  }
4922
+ case "field": {
4923
+ const inner = emit(def.parser, ctx, pos);
4924
+ return {
4925
+ stmts: [
4926
+ ...inner.stmts,
4927
+ `${ind(ctx)}if (_ctx._fields) _ctx._fields.push({ name: ${JSON.stringify(def.name)}, value: ${inner.valueVar}, span: { start: ${pos}, end: ${inner.endVar} } })`
4928
+ ],
4929
+ valueVar: inner.valueVar,
4930
+ endVar: inner.endVar
4931
+ };
4932
+ }
4760
4933
  case "grammar": {
4761
4934
  const savedTrivia = ctx.activeTrivia;
4762
4935
  const savedKindLabels = ctx.triviaKindLabels;
@@ -4858,6 +5031,7 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
4858
5031
  case "trivia":
4859
5032
  case "token":
4860
5033
  case "label":
5034
+ case "field":
4861
5035
  case "optional":
4862
5036
  case "many":
4863
5037
  case "oneOrMore":
@@ -4894,6 +5068,7 @@ function childrenOf(def) {
4894
5068
  case "trivia":
4895
5069
  case "token":
4896
5070
  case "label":
5071
+ case "field":
4897
5072
  case "grammar":
4898
5073
  case "not":
4899
5074
  case "node":
@@ -5135,6 +5310,11 @@ function assertRuleName(name) {
5135
5310
  );
5136
5311
  }
5137
5312
  }
5313
+ function publicRuleWrapperSource(rule, fnSource) {
5314
+ const labels = rule._meta.triviaKindLabels;
5315
+ if (labels === void 0) return fnSource;
5316
+ return `Object.assign(${fnSource}, { _meta: { triviaKindLabels: ${JSON.stringify(labels)} } })`;
5317
+ }
5138
5318
  function compileRuleMap(ruleMap) {
5139
5319
  for (const [, rule] of ruleMap) markUnusedValues(rule);
5140
5320
  const ctx = {
@@ -5167,7 +5347,7 @@ function compileRuleMap(ruleMap) {
5167
5347
  ruleNames.set(rule, n === 0 ? base : `${base}$${n}`);
5168
5348
  }
5169
5349
  ctx.ruleNames = ruleNames;
5170
- const perEntry = ruleMap.map(([key, rule]) => ({ key, r: emit(rule, ctx, "_pos") }));
5350
+ const perEntry = ruleMap.map(([key, rule]) => ({ key, rule, r: emit(rule, ctx, "_pos") }));
5171
5351
  const derivedSrcs = ctx.mapFnSrcs.length === ctx.mapFns.length && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : void 0;
5172
5352
  const buildCovered = ctx.buildFns.length === 0 || ctx.buildSrcs.every((s) => s !== null);
5173
5353
  const buildSources = ctx.buildFns.length === 0 ? void 0 : ctx.buildSrcs;
@@ -5197,7 +5377,10 @@ function compileRuleMap(ruleMap) {
5197
5377
  ` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
5198
5378
  `}`
5199
5379
  ].join("\n");
5200
- const objBody = perEntry.map(({ key, r }) => ` ${JSON.stringify(key)}: ${entryFnText(r).split("\n").join("\n ")}`).join(",\n");
5380
+ const objBody = perEntry.map(({ key, rule, r }) => {
5381
+ const src = publicRuleWrapperSource(rule, entryFnText(r));
5382
+ return ` ${JSON.stringify(key)}: ${src.split("\n").join("\n ")}`;
5383
+ }).join(",\n");
5201
5384
  const replacement = [
5202
5385
  `/* @__PURE__ */ (() => {`,
5203
5386
  ...hoistedDecls,
@@ -5310,7 +5493,7 @@ function compileLinkable(ruleMapArg, ns) {
5310
5493
  ctx.recordFail = savedRec;
5311
5494
  pushNamedFnDecl(ctx, fn, body.stmts, body.valueVar, body.endVar);
5312
5495
  }
5313
- perEntry.push({ key, r: emitNamedFnCall(ctx, fn, "_pos") });
5496
+ perEntry.push({ key, rule, r: emitNamedFnCall(ctx, fn, "_pos") });
5314
5497
  }
5315
5498
  if (ctx.runtimeParsers.length !== 0) return null;
5316
5499
  const mfSrcs = ctx.mapFns.length > 0 && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : null;
@@ -5333,14 +5516,14 @@ function compileLinkable(ruleMapArg, ns) {
5333
5516
  ...privateFns
5334
5517
  ].filter(Boolean);
5335
5518
  const wrappers = /* @__PURE__ */ new Map();
5336
- for (const { key, r } of perEntry) {
5337
- wrappers.set(key, [
5519
+ for (const { key, rule, r } of perEntry) {
5520
+ wrappers.set(key, publicRuleWrapperSource(rule, [
5338
5521
  `function(input, _pos, _ctx) {`,
5339
5522
  ` let pos = _pos`,
5340
5523
  ...r.stmts,
5341
5524
  ` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
5342
5525
  `}`
5343
- ].join("\n"));
5526
+ ].join("\n")));
5344
5527
  }
5345
5528
  const firstSets = /* @__PURE__ */ new Map();
5346
5529
  for (const [key, rule] of ruleMap) {
@@ -5515,6 +5698,7 @@ function childrenOf2(def) {
5515
5698
  case "trivia":
5516
5699
  case "token":
5517
5700
  case "label":
5701
+ case "field":
5518
5702
  case "not":
5519
5703
  case "node":
5520
5704
  case "expect":
@@ -5600,6 +5784,7 @@ function evalRuleMapIR(ir) {
5600
5784
  "skip",
5601
5785
  "trivia",
5602
5786
  "label",
5787
+ "field",
5603
5788
  "expect",
5604
5789
  "_tf",
5605
5790
  "_nd",
@@ -5626,6 +5811,7 @@ function evalRuleMapIR(ir) {
5626
5811
  skip,
5627
5812
  trivia,
5628
5813
  label,
5814
+ field,
5629
5815
  expect,
5630
5816
  _tf,
5631
5817
  _nd
@@ -5759,6 +5945,8 @@ ${body}
5759
5945
  return `token(${kid(def.parser)})`;
5760
5946
  case "label":
5761
5947
  return `label(${JSON.stringify(def.label)}, ${kid(def.parser)})`;
5948
+ case "field":
5949
+ return `field(${JSON.stringify(def.name)}, ${kid(def.parser)})`;
5762
5950
  case "expect":
5763
5951
  return `expect(${kid(def.parser)}${def.label !== void 0 ? `, ${JSON.stringify(def.label)}` : ""})`;
5764
5952
  case "skip":
@@ -5771,7 +5959,11 @@ ${body}
5771
5959
  }
5772
5960
  case "node": {
5773
5961
  if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
5774
- const opts = def.collapse ? `, { collapse: true }` : "";
5962
+ const opts = def.unwrap || def.collapse ? `, { ${def.unwrap ? "unwrap: true" : "collapse: true"} }` : "";
5963
+ if (def.type === void 0) {
5964
+ if (def.buildSrc !== void 0) throw new Unserializable("inferred node build without inferred type");
5965
+ return opts ? `node(${kid(def.parser)}, undefined${opts})` : `node(${kid(def.parser)})`;
5966
+ }
5775
5967
  if (def.buildSrc !== void 0) return `_nd(${JSON.stringify(def.type)}, ${kid(def.parser)}, ${JSON.stringify(def.buildSrc)}${opts})`;
5776
5968
  return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
5777
5969
  }
@@ -5798,8 +5990,9 @@ function fusedBody(pieces) {
5798
5990
  }
5799
5991
  }
5800
5992
  const contributing = new Set(winner.values());
5801
- const needsEmptyTl = [...contributing].some((p) => p.needsEmptyTl);
5802
- const needsHostReads = [...contributing].some((p) => p.needsHostReads);
5993
+ const contributingPieces = [...contributing];
5994
+ const needsEmptyTl = contributingPieces.some((p) => p.needsEmptyTl);
5995
+ const needsHostReads = contributingPieces.some((p) => p.needsHostReads);
5803
5996
  const lines = [
5804
5997
  // Shared sentinel protocol (must match NAMED_FN_FAIL / NAMED_FN_END in codegen).
5805
5998
  "const _pfFail = {}",
@@ -5807,7 +6000,7 @@ function fusedBody(pieces) {
5807
6000
  ...needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [],
5808
6001
  ...needsHostReads ? [HOST_READS_DECL] : [],
5809
6002
  // Each contributing artifact's namespaced private prelude (regexes, _pf, …).
5810
- ...[...contributing].flatMap((p) => p.prelude),
6003
+ ...[...new Set(contributingPieces.flatMap((p) => p.prelude))],
5811
6004
  // The winning `_r_<Name>` function for each rule (one per name → no redeclare).
5812
6005
  ...[...winner].map(([k, p]) => p.ruleFns.get(k))
5813
6006
  ];
@@ -5830,7 +6023,7 @@ function fusedBody(pieces) {
5830
6023
  }
5831
6024
  );
5832
6025
  const env = {};
5833
- for (const p of contributing) {
6026
+ for (const p of contributingPieces) {
5834
6027
  if (p.mfFns.length) env[`${p.ns}mf`] = p.mfFns;
5835
6028
  if (p.buildFns.length) env[`${p.ns}build`] = p.buildFns;
5836
6029
  }
@@ -5878,6 +6071,7 @@ var SUPPORTED = {
5878
6071
  sepBy: (...a) => sepBy(a[0], a[1]),
5879
6072
  trivia: (...a) => trivia(a[0]),
5880
6073
  label: (...a) => label(a[0], a[1]),
6074
+ field: (...a) => field(a[0], a[1]),
5881
6075
  noTrivia: (...a) => noTrivia(a[0]),
5882
6076
  token: (...a) => token(a[0]),
5883
6077
  expect: (...a) => expect(a[0], a[1])
@@ -5898,19 +6092,20 @@ function scopeGet(scope, name, mfs) {
5898
6092
  if (isCombinator(entry)) return entry;
5899
6093
  return null;
5900
6094
  }
5901
- function staticCollapseOption(expr) {
5902
- if (expr.type !== "ObjectExpression") return false;
6095
+ function staticNodeOptions(expr) {
6096
+ if (expr.type !== "ObjectExpression") return void 0;
6097
+ const opts = {};
5903
6098
  for (const prop of expr.properties) {
5904
6099
  const p = prop;
5905
6100
  if (p.computed) continue;
5906
6101
  const key = p.key;
5907
6102
  const name = key.type === "Identifier" ? key.name : key.type === "Literal" ? String(key.value) : void 0;
5908
- if (name === "collapse") {
6103
+ if (name === "unwrap" || name === "collapse") {
5909
6104
  const val = p.value;
5910
- return (val.type === "Literal" || val.type === "BooleanLiteral") && val.value === true;
6105
+ if ((val.type === "Literal" || val.type === "BooleanLiteral") && val.value === true) opts[name] = true;
5911
6106
  }
5912
6107
  }
5913
- return false;
6108
+ return opts.unwrap || opts.collapse ? opts : void 0;
5914
6109
  }
5915
6110
  function exprToCombi(node2, scope, code, mfs) {
5916
6111
  if (node2.type === "Identifier") return scopeGet(scope, node2.name, mfs);
@@ -5960,18 +6155,22 @@ function exprToCombi(node2, scope, code, mfs) {
5960
6155
  }
5961
6156
  }
5962
6157
  if (callee.name === "node" && code !== void 0) {
5963
- const [typeArg, parserArg, buildArg, optsArg] = node2.arguments;
5964
- if (!typeArg || !parserArg || typeArg.type === "SpreadElement" || parserArg.type === "SpreadElement") return null;
5965
- const typeVal = anyValue(typeArg, scope, code);
5966
- if (typeof typeVal !== "string") return null;
6158
+ const [firstArg, secondArg, thirdArg, fourthArg] = node2.arguments;
6159
+ if (!firstArg || firstArg.type === "SpreadElement") return null;
6160
+ const firstVal = anyValue(firstArg, scope, code, mfs);
6161
+ const explicitType = typeof firstVal === "string" ? firstVal : void 0;
6162
+ const parserArg = explicitType !== void 0 ? secondArg : firstArg;
6163
+ const buildArg = explicitType !== void 0 ? thirdArg : secondArg;
6164
+ const optsArg = explicitType !== void 0 ? fourthArg : thirdArg;
6165
+ if (!parserArg || parserArg.type === "SpreadElement") return null;
5967
6166
  const inner = anyValue(parserArg, scope, code, mfs);
5968
6167
  if (!isCombinator(inner)) return null;
5969
6168
  const be = buildArg;
5970
6169
  const hasBuild = be !== void 0 && be.type !== "SpreadElement" && !(be.type === "Identifier" && be.name === "undefined");
5971
6170
  const buildSrc = hasBuild ? code.slice(be.start, be.end) : void 0;
5972
- const collapse = optsArg !== void 0 && optsArg.type !== "SpreadElement" ? staticCollapseOption(optsArg) : false;
6171
+ const opts = optsArg !== void 0 && optsArg.type !== "SpreadElement" ? staticNodeOptions(optsArg) : void 0;
5973
6172
  try {
5974
- const combi = node(typeVal, inner, hasBuild ? () => null : void 0, collapse ? { collapse: true } : void 0);
6173
+ const combi = explicitType !== void 0 ? node(explicitType, inner, hasBuild ? () => null : void 0, opts) : node(inner, hasBuild ? () => null : void 0, opts);
5975
6174
  if (combi._def.tag === "node" && buildSrc !== void 0) combi._def.buildSrc = buildSrc;
5976
6175
  return combi;
5977
6176
  } catch {
@@ -6237,7 +6436,9 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources) {
6237
6436
  if (!keys) return null;
6238
6437
  const ruleRefs = /* @__PURE__ */ new Map();
6239
6438
  const tagRef = (r, name) => {
6439
+ ;
6240
6440
  r._ruleName = name;
6441
+ if (r._def.tag === "node" && r._def.type === void 0) r._def.type = name;
6241
6442
  };
6242
6443
  for (const key of keys) {
6243
6444
  if (!ruleRefs.has(key)) {
@@ -6269,6 +6470,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources) {
6269
6470
  for (const [key, e] of finalByKey) {
6270
6471
  const val = anyValue(e.value, e.scope, e.code, mapFnSources);
6271
6472
  if (!isCombinator(val)) return null;
6473
+ tagRef(val, key);
6272
6474
  ruleRefs.get(key).define(val);
6273
6475
  }
6274
6476
  return ruleRefs;