parseman 0.60.2 → 0.60.4

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.
Files changed (40) hide show
  1. package/dist/analysis/commitment.d.ts +1 -1
  2. package/dist/analysis/commitment.d.ts.map +1 -1
  3. package/dist/analysis/diagnostics.js +128 -43
  4. package/dist/analysis/diagnostics.js.map +2 -2
  5. package/dist/cli/index.js +128 -43
  6. package/dist/cli/index.js.map +2 -2
  7. package/dist/compiler/ir-serialize.d.ts +3 -1
  8. package/dist/compiler/ir-serialize.d.ts.map +1 -1
  9. package/dist/compiler/linker.d.ts +10 -0
  10. package/dist/compiler/linker.d.ts.map +1 -1
  11. package/dist/index.js +155 -57
  12. package/dist/index.js.map +2 -2
  13. package/dist/plugin/evaluator.d.ts +8 -0
  14. package/dist/plugin/evaluator.d.ts.map +1 -1
  15. package/dist/plugin/index.d.ts.map +1 -1
  16. package/dist/plugin/index.js +218 -59
  17. package/dist/plugin/index.js.map +2 -2
  18. package/dist/table/assemble.d.ts +11 -0
  19. package/dist/table/assemble.d.ts.map +1 -1
  20. package/dist/table/emit-assembly.d.ts +1 -0
  21. package/dist/table/emit-assembly.d.ts.map +1 -1
  22. package/dist/table/encode.d.ts.map +1 -1
  23. package/dist/table/exec.d.ts.map +1 -1
  24. package/dist/table/index.js +128 -43
  25. package/dist/table/index.js.map +2 -2
  26. package/dist/table/program.d.ts +9 -0
  27. package/dist/table/program.d.ts.map +1 -1
  28. package/dist/version.d.ts +1 -1
  29. package/package.json +1 -1
  30. package/src/analysis/commitment.ts +29 -15
  31. package/src/compiler/ir-serialize.ts +14 -3
  32. package/src/compiler/linker.ts +28 -12
  33. package/src/plugin/evaluator.ts +11 -0
  34. package/src/plugin/index.ts +29 -11
  35. package/src/table/assemble.ts +35 -10
  36. package/src/table/emit-assembly.ts +41 -11
  37. package/src/table/encode.ts +57 -9
  38. package/src/table/exec.ts +5 -2
  39. package/src/table/program.ts +19 -0
  40. package/src/version.ts +1 -1
@@ -19,7 +19,9 @@
19
19
  */
20
20
  import type { Combinator } from '../types.ts';
21
21
  type Comb = Combinator<unknown>;
22
- export declare function serializeRuleMap(ruleMap: ReadonlyArray<readonly [string, Comb]>, scanSkip?: readonly Comb[] | null): string | null;
22
+ export declare function serializeRuleMap(ruleMap: ReadonlyArray<readonly [string, Comb]>, scanSkip?: readonly Comb[] | null,
23
+ /** External names the factory read through `g`; any no rule body reaches is kept as `void g[name]`. */
24
+ accessed?: readonly string[]): string | null;
23
25
  /**
24
26
  * ONE plain combinator as IR — what a compiled module carries on an exported terminal
25
27
  * so another module can import it into a grammar (the macro evaluates grammars, and a
@@ -1 +1 @@
1
- {"version":3,"file":"ir-serialize.d.ts","sourceRoot":"","sources":["../../src/compiler/ir-serialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAkC,MAAM,aAAa,CAAA;AAuB7E,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;AAwG/B,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAC/C,QAAQ,CAAC,EAAE,SAAS,IAAI,EAAE,GAAG,IAAI,GAChC,MAAM,GAAG,IAAI,CAWf;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAE1D"}
1
+ {"version":3,"file":"ir-serialize.d.ts","sourceRoot":"","sources":["../../src/compiler/ir-serialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAkC,MAAM,aAAa,CAAA;AAuB7E,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;AAwG/B,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAC/C,QAAQ,CAAC,EAAE,SAAS,IAAI,EAAE,GAAG,IAAI;AACjC,uGAAuG;AACvG,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,GAC3B,MAAM,GAAG,IAAI,CAWf;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAE1D"}
@@ -101,6 +101,16 @@ export declare function composedCoverageRules(grammar: Record<string, unknown>):
101
101
  * Lets a coverage run over ONE composed rule name its choices exactly as
102
102
  * `composedGrammarCoverageDefinitions` does. INTERNAL: coverage tooling only. */
103
103
  export declare function linkedWinnersOf(rule: Combinator<unknown>): Record<string, Combinator<unknown>> | undefined;
104
+ /**
105
+ * The reason a linked map is incomplete, or `undefined` when every `g.X` some piece
106
+ * reads is defined by some piece. A linked namespace holds every name a factory
107
+ * merely ACCESSED, so a name nobody defines is a slot that stays undefined. Runtime
108
+ * `compose()` and the macro's build-time fuse both refuse it with these words, naming
109
+ * the rule that reaches the hole when one does.
110
+ */
111
+ export declare function danglingReference(map: Record<string, Combinator<unknown>>,
112
+ /** Names read through `g` that `map` itself does not hold (a merge-by-name fuse drops them). */
113
+ accessed?: Iterable<string>): string | undefined;
104
114
  /**
105
115
  * Compose grammars into ONE parser map — the only public composition entry point.
106
116
  * `compose([base, ext, …])`: a later entry's rule WINS by name, and because every
@@ -1 +1 @@
1
- {"version":3,"file":"linker.d.ts","sourceRoot":"","sources":["../../src/compiler/linker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"linker.d.ts","sourceRoot":"","sources":["../../src/compiler/linker.ts"],"names":[],"mappings":"AAeA,OAAO,EAAsC,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACvF,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAGtF,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAiBpD,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,EAC7C,EAAE,CAAC,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAK5B,QAAQ,CAAC,EAAE,QAAQ,GAClB,aAAa,CAYf;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,GAAG,oBAAoB,CAAA;IAC7D;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,CAAA;AA4BD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAA;AACtE,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,EAChC,MAAM,EAAE,OAAO,EACf,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACpC,WAAW,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,EACpC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,EAC7B,KAAK,CAAC,EAAE,OAAO,EACf,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACnC,OAAO,CAAA;AAoCV;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACxC,WAAW,CAAC,OAAO,CAAC,GAAG;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAGxD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAExE,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAG1D;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;2EAE2E;AAC3E,eAAO,MAAM,eAAe,eAAwC,CAAA;AA0BpE;+DAC+D;AAC/D,MAAM,MAAM,OAAO,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,IAAI,CAAA;CAAE,CAAA;AAiBnE;;8CAE8C;AAC9C,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,CAO5C;AAgBD;;;;;;;iFAOiF;AACjF,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,CAAC,aAAa,GAAG,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAE5H;AAED;qFACqF;AACrF,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,aAAa,CAAC,aAAa,GAAG,OAAO,CAAC,GAC9C;IAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE,CAS3G;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B;IAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,SAAS,CAa7G;AAED;qEACqE;AACrE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAGvH;AAKD;;iFAEiF;AACjF,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAE1G;AAkDD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;AACxC,gGAAgG;AAChG,QAAQ,GAAE,QAAQ,CAAC,MAAM,CAAM,GAC9B,MAAM,GAAG,SAAS,CAapB;AAuBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CACrB,KAAK,EAAE,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrD;;;;GAIG;AACH,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAE,GAC7B,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAK1B;AA6BD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACpD,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAE1B;AAED;gEACgE;AAChE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACrD,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAE,GAC7B,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAGrC"}
package/dist/index.js CHANGED
@@ -6241,7 +6241,9 @@ function ownTableProgram(prog, resolved, caches = {}) {
6241
6241
  resolved,
6242
6242
  choiceRollbackMasks: caches.choiceRollbackMasks ?? runtime?.choiceRollbackMasks,
6243
6243
  nonCommittingChoiceSites: caches.nonCommittingChoiceSites ?? runtime?.nonCommittingChoiceSites,
6244
- failureRollbackCleanSites: caches.failureRollbackCleanSites ?? runtime?.failureRollbackCleanSites
6244
+ failureRollbackCleanSites: caches.failureRollbackCleanSites ?? runtime?.failureRollbackCleanSites,
6245
+ choiceLogRollbackMasks: caches.choiceLogRollbackMasks ?? runtime?.choiceLogRollbackMasks,
6246
+ failureLogRollbackSites: caches.failureLogRollbackSites ?? runtime?.failureLogRollbackSites
6245
6247
  }
6246
6248
  };
6247
6249
  }
@@ -6254,6 +6256,12 @@ function choiceCannotCommit(prog, ip) {
6254
6256
  function failureRollbackClean(prog, ip) {
6255
6257
  return prog[TABLE_RUNTIME]?.failureRollbackCleanSites?.has(ip) === true;
6256
6258
  }
6259
+ function choiceLogRollbackMask(prog, ip) {
6260
+ return prog[TABLE_RUNTIME]?.choiceLogRollbackMasks?.get(ip) ?? 0;
6261
+ }
6262
+ function failureLogRollback(prog, ip) {
6263
+ return prog[TABLE_RUNTIME]?.failureLogRollbackSites?.has(ip) === true;
6264
+ }
6257
6265
  var WIDE_CLASS_PREFIX_LO = 65535;
6258
6266
  var WIDE_CLASS_PREFIX_HI = 0;
6259
6267
  function validateClassRange(lo, hi) {
@@ -6895,7 +6903,7 @@ function mayFail(p, seen = /* @__PURE__ */ new Set()) {
6895
6903
  return true;
6896
6904
  }
6897
6905
  }
6898
- function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActive = true) {
6906
+ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActive = true, throughNodes = false) {
6899
6907
  if (seen.has(p)) return false;
6900
6908
  seen.add(p);
6901
6909
  const d = p._def;
@@ -6920,17 +6928,26 @@ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActiv
6920
6928
  return false;
6921
6929
  // A run's prefixes are probed detached; only its body can capture.
6922
6930
  case "lines":
6923
- return mayLeavePartialCapture(d.body, seen, triviaActive);
6924
- // node() captures into its own private buffers and rolls them back on
6925
- // failure (emitNode restores _ctx.* and never pushes on the !ok path).
6931
+ return mayLeavePartialCapture(d.body, seen, triviaActive, throughNodes);
6932
+ // node() captures its children into a frame of its own and drops it on
6933
+ // failure. The trivia logs (`_triviaLog`, `_rootTriviaLog`) are not part of
6934
+ // that frame: trivia its body scanned before failing stays recorded. With
6935
+ // `throughNodes` (a program that installs trivia somewhere) a node leaves
6936
+ // what its body leaves; without, it leaves nothing.
6926
6937
  case "node":
6927
- return false;
6928
- // choice/firstMatch already roll back each failed arm; on overall failure
6929
- // nothing committed remains.
6938
+ return throughNodes && mayLeavePartialCapture(d.parser, seen, triviaActive, throughNodes);
6939
+ // choice/firstMatch already roll back each failed arm's captures; on overall
6940
+ // failure nothing committed remains. The trivia logs are the exception: a
6941
+ // choice the table lowers as an exclusive dispatch runs its one selected arm
6942
+ // with no mark of its own (`emit-assembly.ts`, `table.exclusive`), so the
6943
+ // rows that arm's trivia scans recorded stay when it fails. With
6944
+ // `throughNodes` a choice leaves what one of its arms leaves, unless
6945
+ // `throughNodes` is the encoder's answer that this choice marks and restores
6946
+ // each arm it enters.
6930
6947
  case "choice":
6931
- return false;
6948
+ return throughNodes !== false && !(typeof throughNodes === "function" && throughNodes(p)) && d.parsers.some((arm) => mayLeavePartialCapture(arm, new Set(seen), triviaActive, throughNodes));
6932
6949
  case "dispatch":
6933
- return capturesLeaf(d.selector, new Set(seen)) || d.cases.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) || (d.matchers ? d.matchers.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) : false) || (d.otherwise ? mayLeavePartialCapture(d.otherwise, new Set(seen), triviaActive) || capturesLeaf(d.otherwise, new Set(seen)) : false);
6950
+ return capturesLeaf(d.selector, new Set(seen)) || d.cases.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive, throughNodes) || capturesLeaf(x.parser, new Set(seen))) || (d.matchers ? d.matchers.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive, throughNodes) || capturesLeaf(x.parser, new Set(seen))) : false) || (d.otherwise ? mayLeavePartialCapture(d.otherwise, new Set(seen), triviaActive, throughNodes) || capturesLeaf(d.otherwise, new Set(seen)) : false);
6934
6951
  case "attempt":
6935
6952
  return false;
6936
6953
  // optional never fails; many/oneOrMore only "fail" with zero captured items.
@@ -6972,7 +6989,7 @@ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActiv
6972
6989
  const part = parts[i];
6973
6990
  if (i > 0 && triviaActive) captured = true;
6974
6991
  if (captured && mayFail(part)) return true;
6975
- if (mayLeavePartialCapture(part, seen, triviaActive)) return true;
6992
+ if (mayLeavePartialCapture(part, seen, triviaActive, throughNodes)) return true;
6976
6993
  if (capturesLeaf(part) || hasNodeDef(part)) captured = true;
6977
6994
  }
6978
6995
  return false;
@@ -6984,12 +7001,12 @@ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActiv
6984
7001
  case "expect":
6985
7002
  case "withCtx":
6986
7003
  case "grammar":
6987
- return mayLeavePartialCapture(d.parser, seen, triviaActive);
7004
+ return mayLeavePartialCapture(d.parser, seen, triviaActive, throughNodes);
6988
7005
  case "recover":
6989
- return mayLeavePartialCapture(d.parser, seen, triviaActive);
7006
+ return mayLeavePartialCapture(d.parser, seen, triviaActive, throughNodes);
6990
7007
  case "lazy": {
6991
7008
  try {
6992
- return mayLeavePartialCapture(d.thunk(), seen, triviaActive);
7009
+ return mayLeavePartialCapture(d.thunk(), seen, triviaActive, throughNodes);
6993
7010
  } catch {
6994
7011
  return true;
6995
7012
  }
@@ -7992,6 +8009,32 @@ var Encoder = class {
7992
8009
  choiceRollbackMasks = /* @__PURE__ */ new Map();
7993
8010
  nonCommittingChoiceSites = /* @__PURE__ */ new Set();
7994
8011
  failureRollbackCleanSites = /* @__PURE__ */ new Set();
8012
+ /**
8013
+ * THE TRIVIA LOGS A FAILED NODE LEAVES. A node drops its own capture frame when
8014
+ * it fails, but the trivia its body recorded into `_triviaLog`/`_rootTriviaLog`
8015
+ * is not part of that frame. So a child the census above counts as clean can
8016
+ * still leave trivia rows when it reaches a node whose body can fail after a
8017
+ * trivia scan (`mayLeavePartialCapture`'s `throughNodes`). These are the arms
8018
+ * and sites that need only the two logs restored. A program with no trivia of
8019
+ * its own records rows only under trivia its caller supplies, so its emitted
8020
+ * assembly takes these marks only for such a parse (`RunCfg.inheritedTrivia`).
8021
+ */
8022
+ choiceLogRollbackMasks = /* @__PURE__ */ new Map();
8023
+ failureLogRollbackSites = /* @__PURE__ */ new Set();
8024
+ /**
8025
+ * HOW EACH CHOICE WAS LOWERED, for the census above. A choice on the ordered
8026
+ * path whose arms cannot commit a failure restores the logs after every arm
8027
+ * it enters (its full mark, or its own two-log mark), so it leaves no rows.
8028
+ * An exclusive dispatch runs its one arm with no mark, and an ordered choice
8029
+ * returns a committed arm's failure before restoring, so either leaves what an
8030
+ * arm leaves. A choice in neither set, or in both, is taken to leave rows. Both
8031
+ * sets are complete only once every rule is encoded, so the trivia-log census
8032
+ * runs then (`logCensus`).
8033
+ */
8034
+ restoringChoices = /* @__PURE__ */ new Set();
8035
+ leakingChoices = /* @__PURE__ */ new Set();
8036
+ logCensus = [];
8037
+ restoresArms = (choice2) => this.restoringChoices.has(choice2) && !this.leakingChoices.has(choice2);
7995
8038
  /**
7996
8039
  * `reachesSideWriter`'s answers, shared by every `failureNeedsRollback` call
7997
8040
  * for the lifetime of this `Encoder`. Every entry is exact — it depends only on
@@ -8566,11 +8609,19 @@ var Encoder = class {
8566
8609
  * not run repeat recovery, but these rows can still publish through a caller's
8567
8610
  * context.
8568
8611
  */
8569
- failureNeedsRollback(p, autoNot) {
8612
+ failureNeedsRollback(p, autoNot, throughNodes) {
8570
8613
  const refName = p._ruleName;
8571
8614
  const winner = refName === void 0 ? void 0 : this.winners?.[refName];
8572
8615
  const root = winner !== void 0 && !winnerWrapsReference2(winner, p) ? winner : p;
8573
- return mayLeavePartialCapture(root, /* @__PURE__ */ new Set(), true) || this.reachesSideWriter(root) || (autoNot?.length ?? 0) > 0 && capturesLeaf(root);
8616
+ return mayLeavePartialCapture(root, /* @__PURE__ */ new Set(), true, throughNodes) || this.reachesSideWriter(root) || (autoNot?.length ?? 0) > 0 && capturesLeaf(root);
8617
+ }
8618
+ /** The rollback census of an `optional()` or `attempt()` row at `ip` over `child`. */
8619
+ censusTransaction(child, ip) {
8620
+ if (this.failureNeedsRollback(child, void 0, false)) return;
8621
+ this.failureRollbackCleanSites.add(ip);
8622
+ this.logCensus.push(() => {
8623
+ if (this.failureNeedsRollback(child, void 0, this.restoresArms)) this.failureLogRollbackSites.add(ip);
8624
+ });
8574
8625
  }
8575
8626
  /**
8576
8627
  * Whether a field, recovered error, interpreted scanner or unresolvable shape
@@ -9192,13 +9243,11 @@ var Encoder = class {
9192
9243
  }
9193
9244
  const dispIdx = this.disp.length;
9194
9245
  this.disp.push(classes);
9246
+ const exclusive = dispatchIsExclusive(classes, this.cc);
9195
9247
  let rollbackMask = kids.length > 31 ? -1 : 0;
9196
9248
  if (rollbackMask === 0) {
9197
9249
  for (let i = 0; i < arms.length; i++) {
9198
- const src = order[i];
9199
- if (this.failureNeedsRollback(arms[i], d.autoNot[src])) {
9200
- rollbackMask |= 1 << i;
9201
- }
9250
+ if (this.failureNeedsRollback(arms[i], d.autoNot[order[i]], false)) rollbackMask |= 1 << i;
9202
9251
  }
9203
9252
  }
9204
9253
  const head = this.emitHead(OP_CHOICE, 3 + 2 * kids.length);
@@ -9210,9 +9259,19 @@ var Encoder = class {
9210
9259
  this.code[head + 4 + kids.length + i] = this.expected(deriveExpected(arms[i]));
9211
9260
  }
9212
9261
  this.choiceRollbackMasks.set(head, rollbackMask);
9213
- if (arms.every((arm) => !mayCommitFailure(arm, rr, this.commitFailureMemo))) {
9214
- this.nonCommittingChoiceSites.add(head);
9262
+ if (rollbackMask !== -1) {
9263
+ const full = rollbackMask;
9264
+ this.logCensus.push(() => {
9265
+ let logMask = 0;
9266
+ for (let i = 0; i < arms.length; i++) {
9267
+ if ((full & 1 << i) === 0 && this.failureNeedsRollback(arms[i], d.autoNot[order[i]], this.restoresArms)) logMask |= 1 << i;
9268
+ }
9269
+ if (logMask !== 0) this.choiceLogRollbackMasks.set(head, logMask);
9270
+ });
9215
9271
  }
9272
+ const nonCommitting = arms.every((arm) => !mayCommitFailure(arm, rr, this.commitFailureMemo));
9273
+ if (nonCommitting) this.nonCommittingChoiceSites.add(head);
9274
+ (!exclusive && nonCommitting ? this.restoringChoices : this.leakingChoices).add(p);
9216
9275
  return head;
9217
9276
  }
9218
9277
  case "many":
@@ -9248,7 +9307,7 @@ var Encoder = class {
9248
9307
  }
9249
9308
  case "optional": {
9250
9309
  const head = this.emit(OP_OPT, this.lookaheadGate(d.parser, this.node(d.parser).ip));
9251
- if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(head);
9310
+ this.censusTransaction(d.parser, head);
9252
9311
  return head;
9253
9312
  }
9254
9313
  case "transform": {
@@ -9419,7 +9478,7 @@ var Encoder = class {
9419
9478
  // lowering was correct only for a choice arm.
9420
9479
  case "attempt": {
9421
9480
  const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
9422
- if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
9481
+ this.censusTransaction(d.parser, inner);
9423
9482
  const fs = this.gateFirstSet(d.parser, d.guarded === true, false);
9424
9483
  if (fs.kind === "any" || matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return inner;
9425
9484
  const cls = this.charClass(fs);
@@ -9583,6 +9642,7 @@ var Encoder = class {
9583
9642
  finish() {
9584
9643
  if (this.code.length === 0) this.emit(OP_EMPTY);
9585
9644
  this.collapseIndirection();
9645
+ for (const census of this.logCensus) census();
9586
9646
  return ownTableProgram({
9587
9647
  code: this.code,
9588
9648
  k: this.k,
@@ -9607,6 +9667,8 @@ var Encoder = class {
9607
9667
  }, void 0, {
9608
9668
  choiceRollbackMasks: this.choiceRollbackMasks,
9609
9669
  failureRollbackCleanSites: this.failureRollbackCleanSites,
9670
+ choiceLogRollbackMasks: this.choiceLogRollbackMasks,
9671
+ failureLogRollbackSites: this.failureLogRollbackSites,
9610
9672
  nonCommittingChoiceSites: this.nonCommittingChoiceSites
9611
9673
  });
9612
9674
  }
@@ -11496,6 +11558,13 @@ if(ctx._errors!==undefined&&ctx._errors.length!==${t}er)ctx._errors.length=${t}e
11496
11558
  if (!s.fd && !s.er) return `if(${t}n)rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,undefined,undefined,${t}lg,${t}rt)`;
11497
11559
  return `if(${t}n){rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,${s.fd ? `${t}fd` : "undefined"},${s.er ? `${t}er` : "undefined"},${t}lg,${t}rt)}`;
11498
11560
  }
11561
+ function emitLogMark(t) {
11562
+ return `const ${t}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0,${t}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0`;
11563
+ }
11564
+ function emitLogRollback(t) {
11565
+ return `{const g=ctx._triviaLog;if(g!==undefined)while(g.length>${t}lg)g.pop()}
11566
+ {const r=ctx._rootTriviaLog;if(r!==undefined)while(r.length>${t}rt)r.pop()}`;
11567
+ }
11499
11568
  function emitTerm(callee, dst, t, l, skip, miss) {
11500
11569
  const fast = `const ${t}v=${callee}(input,cur,ctx)
11501
11570
  if(${t}v===FAIL)return FAIL
@@ -11579,6 +11648,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, se
11579
11648
  const { code, k, fx, disp, dsp, triviaLabelled } = t;
11580
11649
  const swapLegal = !cfg.trackLines;
11581
11650
  const hostCst = cfg.hostCst;
11651
+ const LOGS = (prog.triviaSpecs?.length ?? 0) > 0 || cfg.inheritedTrivia === true;
11582
11652
  const REC2 = prog.rec === 1 && cfg.tolerant;
11583
11653
  if (cfg.coverage) throw new Unemittable("a coverage assembly");
11584
11654
  const roots = [...Object.values(prog.rules), ...extraIps];
@@ -12347,12 +12417,13 @@ return v
12347
12417
  case OP_ATTEMPT: {
12348
12418
  const child = link(code[ip + 1]);
12349
12419
  const clean = !REC2 && failureRollbackClean(prog, ip);
12420
+ const logs = clean && LOGS && failureLogRollback(prog, ip);
12350
12421
  const p = tmp();
12351
12422
  return `${head}
12352
- ${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
12423
+ ${clean ? logs ? emitLogMark(p) : "" : emitMark(p, L.buf, L.raw, sinks)}
12353
12424
  const v=${child}(input,pos,ctx)
12354
12425
  if(v!==FAIL)return v
12355
- ${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
12426
+ ${clean ? logs ? emitLogRollback(p) : "" : emitRollback(p, L.buf, L.raw, sinks)}
12356
12427
  ${code[ip + 2] === 1 ? "ctx._fc=false" : "if(ctx._fc===true)return FAIL"}
12357
12428
  ctx._fe=pos
12358
12429
  return FAIL
@@ -12378,6 +12449,7 @@ return FAIL
12378
12449
  ${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${emitMark(p, L.buf, L.raw, sinks)}
12379
12450
  ${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
12380
12451
  ${emitRollback(p, L.buf, L.raw, sinks)}
12452
+ ctx._fc=false
12381
12453
  ${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){EC.e=pos;return null}
12382
12454
  ctx._fe=pos
12383
12455
  ctx._fx=${xf}
@@ -12402,6 +12474,7 @@ return null
12402
12474
  ${lookaheadMiss(code[ip + 1], `ctx._fe=pos;ctx._fx=${xf};return FAIL`)}${emitMark(p, L.buf, L.raw, sinks)}
12403
12475
  ${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
12404
12476
  ${emitRollback(p, L.buf, L.raw, sinks)}
12477
+ ctx._fc=false
12405
12478
  ${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
12406
12479
  EC.e=pos
12407
12480
  return null
@@ -12410,14 +12483,15 @@ return null
12410
12483
  case OP_OPT: {
12411
12484
  const child = link(code[ip + 1]);
12412
12485
  const clean = !REC2 && failureRollbackClean(prog, ip);
12486
+ const logs = clean && LOGS && failureLogRollback(prog, ip);
12413
12487
  const p = tmp();
12414
12488
  return `${head}
12415
- ${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
12489
+ ${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${clean ? logs ? emitLogMark(p) : "" : emitMark(p, L.buf, L.raw, sinks)}
12416
12490
  ctx._fc=false
12417
12491
  const v=${child}(input,pos,ctx)
12418
12492
  if(v===FAIL){
12419
12493
  if(ctx._fc===true)return FAIL
12420
- ${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
12494
+ ${clean ? logs ? emitLogRollback(p) : "" : emitRollback(p, L.buf, L.raw, sinks)}
12421
12495
  EC.e=pos
12422
12496
  return null
12423
12497
  }
@@ -12567,6 +12641,10 @@ return FAIL
12567
12641
  const encodedRollbackMask = choiceRollbackMask(prog, ip) ?? -1;
12568
12642
  const rollbackMask = REC2 ? -1 : encodedRollbackMask;
12569
12643
  const hasRollback = rollbackMask !== 0;
12644
+ const logMask = rollbackMask === -1 || !LOGS ? 0 : choiceLogRollbackMask(prog, ip);
12645
+ const choiceMark = hasRollback ? emitMark(p, L.buf, L.raw, sinks) : "";
12646
+ const armMark = (i) => !hasRollback && (logMask & 1 << i) !== 0 ? `${emitLogMark(p)}
12647
+ ` : "";
12570
12648
  const startFailureExact = arms.every((_arm, i) => {
12571
12649
  const terminal = leadingScalarTerminal(code, code[base + i], 0, false);
12572
12650
  if (terminal < 0) return false;
@@ -12578,7 +12656,7 @@ return FAIL
12578
12656
  if (op2 === OP_LIT) return typeof spec === "string" && spec.length > 0;
12579
12657
  return op2 === OP_RX && spec instanceof RegExp && !regexCanMatchEmpty(spec.source);
12580
12658
  });
12581
- const rollbackFor = (i) => rollbackMask === -1 || (rollbackMask & 1 << i) !== 0 ? emitRollback(p, L.buf, L.raw, sinks) : "";
12659
+ const rollbackFor = (i) => rollbackMask === -1 || (rollbackMask & 1 << i) !== 0 ? emitRollback(p, L.buf, L.raw, sinks) : (logMask & 1 << i) === 0 ? "" : hasRollback ? emitRollback(p, L.buf, L.raw, sinks) : emitLogRollback(p);
12582
12660
  if (choiceCannotCommit(prog, ip) && !startFailureExact) {
12583
12661
  const deepAt = Array.from({ length: n }, () => tmp());
12584
12662
  const deepFx = Array.from({ length: n }, () => tmp());
@@ -12604,7 +12682,7 @@ ${remember2(i, "at", pretest.sequence.expected.map((value, at) => `${decision}==
12604
12682
  }`;
12605
12683
  return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
12606
12684
  `}if(${gate2}){
12607
- ctx._fc=false
12685
+ ${armMark(i)}ctx._fc=false
12608
12686
  {const v=${arm}(input,pos,ctx)
12609
12687
  if(v!==FAIL)return v}
12610
12688
  {const at=ctx._fe??pos
@@ -12623,7 +12701,7 @@ ctx._fe=pos;ctx._fx=acc??${choiceFx}
12623
12701
  return FAIL`;
12624
12702
  return `${head}
12625
12703
  const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
12626
- ${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
12704
+ ${choiceMark}
12627
12705
  ${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
12628
12706
  ${maskable ? `if(c<128){
12629
12707
  const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
@@ -12670,7 +12748,7 @@ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.sequenc
12670
12748
  }`;
12671
12749
  return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
12672
12750
  `}if((bits&${1 << i})!==0${condition}){
12673
- ctx._fc=false
12751
+ ${armMark(i)}ctx._fc=false
12674
12752
  {const v=${arm}(input,pos,ctx)
12675
12753
  if(v!==FAIL)return v}
12676
12754
  ${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
@@ -12701,7 +12779,7 @@ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.token.e
12701
12779
  }${startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)`}`;
12702
12780
  return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
12703
12781
  `}if((${gateRefs[i]}===null||classHas(${gateRefs[i]},c))${condition}){
12704
- ctx._fc=false
12782
+ ${armMark(i)}ctx._fc=false
12705
12783
  {const v=${arm}(input,pos,ctx)
12706
12784
  if(v!==FAIL)return v}
12707
12785
  {const at=ctx._fe??pos
@@ -12713,7 +12791,7 @@ ${rollbackFor(i)}
12713
12791
  }).join("\n");
12714
12792
  return `${head}
12715
12793
  const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
12716
- ${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
12794
+ ${choiceMark}
12717
12795
  let acc
12718
12796
  let best=pos
12719
12797
  ${maskable ? `if(c<128){
@@ -13793,7 +13871,7 @@ function clearOf(ranges, input, from, to) {
13793
13871
  }
13794
13872
 
13795
13873
  // src/version.ts
13796
- var PARSEMAN_VERSION = "0.60.2";
13874
+ var PARSEMAN_VERSION = "0.60.4";
13797
13875
 
13798
13876
  // src/table/assemble.ts
13799
13877
  import { PlainBuf as PlainBuf2, PlainField, PlainLeaf as PlainLeaf9, PlainNode as PlainNode2, PlainSpan as PlainSpan10 } from "./cst/plain.js";
@@ -14065,11 +14143,11 @@ function linkMatcher(m) {
14065
14143
  }
14066
14144
  var NO_COVERAGE = (_id) => {
14067
14145
  };
14068
- function cfgKeyOf(hostCst, trackLines, tolerant, coverage, probe, hostReadsChildren = true) {
14069
- return (hostCst ? 1 : 0) | (trackLines ? 2 : 0) | (tolerant ? 4 : 0) | (coverage ? 8 : 0) | (probe ? 16 : 0) | (hostReadsChildren ? 0 : 32);
14146
+ function cfgKeyOf(hostCst, trackLines, tolerant, coverage, probe, hostReadsChildren = true, inheritedTrivia = false) {
14147
+ return (hostCst ? 1 : 0) | (trackLines ? 2 : 0) | (tolerant ? 4 : 0) | (coverage ? 8 : 0) | (probe ? 16 : 0) | (hostReadsChildren ? 0 : 32) | (inheritedTrivia ? 64 : 0);
14070
14148
  }
14071
14149
  function cfgKey(c) {
14072
- return cfgKeyOf(c.hostCst, c.trackLines, c.tolerant, c.coverage, c.probe, c.hostReadsChildren);
14150
+ return cfgKeyOf(c.hostCst, c.trackLines, c.tolerant, c.coverage, c.probe, c.hostReadsChildren, c.inheritedTrivia);
14073
14151
  }
14074
14152
  function assertFactoryArity(pre) {
14075
14153
  if (pre.arity === EMITTED_PARAMS.length) return;
@@ -15444,6 +15522,7 @@ function assemble(t, prog, cfg) {
15444
15522
  const probeBest = PROBE ? ctx._probe?.best : void 0;
15445
15523
  const v = child(input, pos, ctx);
15446
15524
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
15525
+ ctx._fc = false;
15447
15526
  if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
15448
15527
  if (v === FAIL) {
15449
15528
  EC.e = pos;
@@ -15489,6 +15568,7 @@ function assemble(t, prog, cfg) {
15489
15568
  const probeBest = PROBE ? ctx._probe?.best : void 0;
15490
15569
  const v = child(input, pos, ctx);
15491
15570
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
15571
+ ctx._fc = false;
15492
15572
  if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
15493
15573
  if (v === FAIL) {
15494
15574
  ctx._fe = pos;
@@ -17347,7 +17427,7 @@ function assemble(t, prog, cfg) {
17347
17427
  if (emitted !== void 0) throw new ServedByBuild();
17348
17428
  if (prog.asm !== void 0) {
17349
17429
  throw new Unemittable(
17350
- `option set ${cfgKey(cfg)} (hostCst=${cfg.hostCst} trackLines=${cfg.trackLines} tolerant=${cfg.tolerant} coverage=${cfg.coverage} probe=${cfg.probe}), which this build did not pre-compile. The Function constructor is NOT used for an artifact that carries assemblies \u2014 see \`EmitOptions.assemblies\` to add this option set to the build`
17430
+ `option set ${cfgKey(cfg)} (hostCst=${cfg.hostCst} trackLines=${cfg.trackLines} tolerant=${cfg.tolerant} coverage=${cfg.coverage} probe=${cfg.probe} inheritedTrivia=${cfg.inheritedTrivia === true}), which this build did not pre-compile. The Function constructor is NOT used for an artifact that carries assemblies \u2014 see \`EmitOptions.assemblies\` to add this option set to the build`
17351
17431
  );
17352
17432
  }
17353
17433
  if (!EMIT_ENABLED) throw new Unemittable("PM_TABLE_EMIT=0 (measurement toggle)");
@@ -17546,7 +17626,9 @@ function countedPiece(piece, ip) {
17546
17626
  var AssemblyCache = class {
17547
17627
  t;
17548
17628
  prog;
17549
- byCfg = Array.from({ length: 64 });
17629
+ byCfg = Array.from({ length: 128 });
17630
+ /** Whether this program installs no trivia of its own (`RunCfg.inheritedTrivia`). */
17631
+ noOwnTrivia;
17550
17632
  /**
17551
17633
  * Monomorphic predicate inline cache. An assembly depends on the predicate
17552
17634
  * FUNCTION and the scalar cfg key, not on the host object that carries it, so
@@ -17559,6 +17641,7 @@ var AssemblyCache = class {
17559
17641
  constructor(prog, resolved = resolveTable(prog)) {
17560
17642
  this.prog = prog;
17561
17643
  this.t = resolved;
17644
+ this.noOwnTrivia = prog.triviaSpecs === void 0 || prog.triviaSpecs.length === 0;
17562
17645
  }
17563
17646
  for(cfg) {
17564
17647
  const key = cfgKey(cfg);
@@ -17622,13 +17705,14 @@ var AssemblyCache = class {
17622
17705
  const tolerant = ctx._tolerant === true;
17623
17706
  const coverage = ctx._grammarCoverage !== void 0;
17624
17707
  const probe = ctx._probe !== void 0;
17625
- const key = cfgKeyOf(hostCst, trackLines, tolerant, coverage, probe, hostReadsChildren);
17708
+ const inheritedTrivia = this.noOwnTrivia && ctx.trivia !== void 0;
17709
+ const key = cfgKeyOf(hostCst, trackLines, tolerant, coverage, probe, hostReadsChildren, inheritedTrivia);
17626
17710
  let cache = this.byCfg;
17627
17711
  if (hostCaptureTrivia !== void 0) {
17628
17712
  if (this.hostPredicate === hostCaptureTrivia) {
17629
17713
  cache = this.hostAssemblies;
17630
17714
  } else {
17631
- cache = Array.from({ length: 64 });
17715
+ cache = Array.from({ length: 128 });
17632
17716
  this.hostPredicate = hostCaptureTrivia;
17633
17717
  this.hostAssemblies = cache;
17634
17718
  }
@@ -17642,7 +17726,8 @@ var AssemblyCache = class {
17642
17726
  trackLines,
17643
17727
  tolerant,
17644
17728
  coverage,
17645
- probe
17729
+ probe,
17730
+ inheritedTrivia
17646
17731
  });
17647
17732
  cache[key] = made;
17648
17733
  return made;
@@ -19782,9 +19867,9 @@ function matcherExpr(entry) {
19782
19867
  return `matches(${new RegExp(entry.value, entry.flags ?? "").toString()})`;
19783
19868
  }
19784
19869
  }
19785
- function serializeRuleMap(ruleMap, scanSkip) {
19870
+ function serializeRuleMap(ruleMap, scanSkip, accessed) {
19786
19871
  try {
19787
- return new Serializer(ruleMap, scanSkip ?? []).run();
19872
+ return new Serializer(ruleMap, scanSkip ?? [], accessed ?? []).run();
19788
19873
  } catch (e) {
19789
19874
  if (e instanceof Unserializable) {
19790
19875
  if (typeof process !== "undefined" && process.env?.PARSEMAN_IR_DEBUG) console.error(`[ir] fallback: ${e.message}`);
@@ -19806,9 +19891,12 @@ var Serializer = class {
19806
19891
  localRuleNames = /* @__PURE__ */ new Map();
19807
19892
  ruleMap;
19808
19893
  scanSkip;
19809
- constructor(ruleMap, scanSkip = []) {
19894
+ accessed;
19895
+ referenced = /* @__PURE__ */ new Set();
19896
+ constructor(ruleMap, scanSkip = [], accessed = []) {
19810
19897
  this.ruleMap = ruleMap;
19811
19898
  this.scanSkip = scanSkip;
19899
+ this.accessed = accessed;
19812
19900
  for (const [name, c] of ruleMap) {
19813
19901
  this.localRuleNames.set(c, name);
19814
19902
  this.ruleValues.add(this.body(c));
@@ -19884,6 +19972,9 @@ var Serializer = class {
19884
19972
  }
19885
19973
  this.decls = innerDecls;
19886
19974
  const body = this.ruleMap.map(([name, c]) => ` ${JSON.stringify(name)}: ${this.wrap(this.body(c), [])}`).join(",\n");
19975
+ for (const name of this.accessed) {
19976
+ if (!this.referenced.has(name)) innerDecls.push(`void g[${JSON.stringify(name)}]`);
19977
+ }
19887
19978
  const factory = innerDecls.length === 0 ? `(g) => ({
19888
19979
  ${body}
19889
19980
  })` : `(g) => {
@@ -19982,7 +20073,10 @@ ${outerDecls.map((d) => " " + d).join("\n")}
19982
20073
  switch (def.tag) {
19983
20074
  case "lazy": {
19984
20075
  const name = this.localRuleNames.get(c) ?? ruleNameOf4(c);
19985
- if (name !== void 0) return `g[${JSON.stringify(name)}]`;
20076
+ if (name !== void 0) {
20077
+ this.referenced.add(name);
20078
+ return `g[${JSON.stringify(name)}]`;
20079
+ }
19986
20080
  const target = lazyTarget(c);
19987
20081
  for (let i = frames.length - 1; i >= 0; i--) {
19988
20082
  const f = frames[i];
@@ -20316,24 +20410,28 @@ function declaredNamesOf(items) {
20316
20410
  }
20317
20411
  return [...names];
20318
20412
  }
20319
- function linkComposition(recipes, link) {
20320
- const map = linkRules(recipes, link);
20321
- const missing = [];
20413
+ function danglingReference(map, accessed = []) {
20414
+ const holes = /* @__PURE__ */ new Set();
20322
20415
  for (const [name, rule] of Object.entries(map)) {
20323
20416
  if (rule._def.tag !== "lazy") continue;
20324
20417
  try {
20325
20418
  rule._def.thunk();
20326
20419
  } catch {
20327
- missing.push(name);
20420
+ holes.add(name);
20328
20421
  }
20329
20422
  }
20330
- if (missing.length > 0) {
20331
- const holes = new Set(missing);
20332
- for (const [name, deps] of ruleDependencies(Object.entries(map).filter(([n]) => !holes.has(n)))) {
20333
- for (const dep of deps) if (holes.has(dep)) throw new Error(`compose: rule "${name}" references missing rule "${dep}"`);
20334
- }
20335
- throw new Error(`compose: rule(s) ${missing.map((n) => `"${n}"`).join(", ")} are referenced but defined by no composed grammar`);
20423
+ for (const name of accessed) if (!Object.hasOwn(map, name)) holes.add(name);
20424
+ if (holes.size === 0) return void 0;
20425
+ const missing = [...holes];
20426
+ for (const [name, deps] of ruleDependencies(Object.entries(map).filter(([n]) => !holes.has(n)))) {
20427
+ for (const dep of deps) if (holes.has(dep)) return `rule "${name}" references missing rule "${dep}"`;
20336
20428
  }
20429
+ return `rule(s) ${missing.map((n) => `"${n}"`).join(", ")} are referenced but defined by no composed grammar`;
20430
+ }
20431
+ function linkComposition(recipes, link) {
20432
+ const map = linkRules(recipes, link);
20433
+ const dangling = danglingReference(map);
20434
+ if (dangling !== void 0) throw new Error(`compose: ${dangling}`);
20337
20435
  const borrowed = borrowedRuleReference(map);
20338
20436
  if (borrowed !== void 0) throw new Error(borrowedRuleMessage("compose", borrowed));
20339
20437
  for (const rule of Object.values(map)) LINKED_WINNERS.set(rule, map);