parseman 0.55.1 → 0.55.2

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.
@@ -5624,19 +5624,22 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
5624
5624
  return false;
5625
5625
  }
5626
5626
  }
5627
- function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve3) {
5628
- if (seen.has(p)) return false;
5629
- seen.add(p);
5627
+ function mayCommitFailure(p, resolve3, memo = /* @__PURE__ */ new Map()) {
5628
+ return reachesMarked(p, (node2) => commitFailureSuccessors(node2, resolve3), memo);
5629
+ }
5630
+ var NO_EDGES = [];
5631
+ function commitFailureSuccessors(p, resolve3) {
5630
5632
  const d = p._def;
5631
5633
  switch (d.tag) {
5632
5634
  case "dispatch":
5635
+ case "unknown":
5633
5636
  return true;
5634
5637
  case "choice":
5635
5638
  case "sequence":
5636
- return d.parsers.some((x) => mayCommitFailure(x, seen, resolve3));
5639
+ return d.parsers;
5637
5640
  // A contained transaction reports every failure uncommitted.
5638
5641
  case "attempt":
5639
- return d.contain !== true && mayCommitFailure(d.parser, seen, resolve3);
5642
+ return d.contain === true ? NO_EDGES : [d.parser];
5640
5643
  case "many":
5641
5644
  case "oneOrMore":
5642
5645
  case "optional":
@@ -5645,31 +5648,77 @@ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve3) {
5645
5648
  case "field":
5646
5649
  case "grammar":
5647
5650
  case "node":
5648
- return mayCommitFailure(d.parser, seen, resolve3);
5649
- case "sepBy":
5650
- return mayCommitFailure(d.parser, seen, resolve3) || mayCommitFailure(d.separator, seen, resolve3);
5651
5651
  case "token":
5652
5652
  case "leaf":
5653
- return mayCommitFailure(d.parser, seen, resolve3);
5654
5653
  case "withCtx":
5655
- return mayCommitFailure(d.parser, seen, resolve3);
5654
+ return [d.parser];
5655
+ case "sepBy":
5656
+ return [d.parser, d.separator];
5656
5657
  case "scanTo":
5657
- return mayCommitFailure(d.sentinel, seen, resolve3) || d.skip.some((x) => mayCommitFailure(x, seen, resolve3)) || d.recoverAt !== void 0 && mayCommitFailure(d.recoverAt, seen, resolve3) || d.stopAt !== void 0 && mayCommitFailure(d.stopAt, seen, resolve3);
5658
+ return [
5659
+ d.sentinel,
5660
+ ...d.skip,
5661
+ ...d.recoverAt === void 0 ? NO_EDGES : [d.recoverAt],
5662
+ ...d.stopAt === void 0 ? NO_EDGES : [d.stopAt]
5663
+ ];
5658
5664
  case "lazy": {
5659
5665
  try {
5660
- return mayCommitFailure(d.thunk(), seen, resolve3);
5666
+ return [d.thunk()];
5661
5667
  } catch {
5662
5668
  const name = p._ruleName;
5663
5669
  const target = name === void 0 ? void 0 : resolve3?.(name);
5664
- return target === void 0 ? true : mayCommitFailure(target, seen, resolve3);
5670
+ return target === void 0 ? true : [target];
5665
5671
  }
5666
5672
  }
5667
- case "unknown":
5668
- return true;
5669
5673
  default:
5670
- return false;
5674
+ return NO_EDGES;
5671
5675
  }
5672
5676
  }
5677
+ function reachesMarked(root, successors, memo) {
5678
+ const known = memo.get(root);
5679
+ if (known !== void 0) return known;
5680
+ const order = /* @__PURE__ */ new Map();
5681
+ const low = [];
5682
+ const found = [];
5683
+ const stack = [];
5684
+ const visit = (node2) => {
5685
+ const at = low.length;
5686
+ order.set(node2, at);
5687
+ low.push(at);
5688
+ found.push(false);
5689
+ stack.push(node2);
5690
+ const next = successors(node2);
5691
+ if (next === true) found[at] = true;
5692
+ else {
5693
+ for (const child of next) {
5694
+ if (found[at]) break;
5695
+ const hit = memo.get(child);
5696
+ if (hit !== void 0) {
5697
+ if (hit) found[at] = true;
5698
+ continue;
5699
+ }
5700
+ const seen = order.get(child);
5701
+ if (seen !== void 0) {
5702
+ if (seen < low[at]) low[at] = seen;
5703
+ continue;
5704
+ }
5705
+ const k = visit(child);
5706
+ if (low[k] < low[at]) low[at] = low[k];
5707
+ if (found[k]) found[at] = true;
5708
+ }
5709
+ }
5710
+ if (low[at] === at) {
5711
+ const answer = found[at];
5712
+ let member;
5713
+ do {
5714
+ member = stack.pop();
5715
+ memo.set(member, answer);
5716
+ } while (member !== node2);
5717
+ }
5718
+ return at;
5719
+ };
5720
+ return found[visit(root)];
5721
+ }
5673
5722
  function hasSemanticReduction(roots, externalRefs) {
5674
5723
  const seen = /* @__PURE__ */ new Set();
5675
5724
  const visit = (parser2) => {
@@ -6865,6 +6914,13 @@ var Encoder = class {
6865
6914
  * attempt sites reach it.
6866
6915
  */
6867
6916
  sideWriterMemo = /* @__PURE__ */ new Map();
6917
+ /**
6918
+ * `mayCommitFailure`'s answers, shared by every choice site for the lifetime
6919
+ * of this `Encoder` — exact for the graph and the `winners` resolver it is
6920
+ * encoding, so the rule graph is walked once per encode rather than once per
6921
+ * choice site.
6922
+ */
6923
+ commitFailureMemo = /* @__PURE__ */ new Map();
6868
6924
  labels = void 0;
6869
6925
  /** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
6870
6926
  activeTrivia = void 0;
@@ -7305,62 +7361,11 @@ var Encoder = class {
7305
7361
  }
7306
7362
  /**
7307
7363
  * Whether a field, recovered error, interpreted scanner or unresolvable shape
7308
- * is reachable from `root` — the writer census of `failureNeedsRollback`.
7309
- *
7310
- * Reachability over a cyclic graph, decided with Tarjan's strongly connected
7311
- * components so that every node the walk enters leaves with its exact answer
7312
- * memoized: the members of one component reach each other, so they share one
7313
- * answer, settled when the walk returns to the component's first node. A DFS
7314
- * that instead cuts a cycle at its own ancestor path learns nothing it can
7315
- * keep about a node whose walk hit the cut, and re-walks that node along
7316
- * every path that reaches it — exponential over recursive value rules (linking
7317
- * jess's SCSS grammar cost ~290G instructions). This walk enters each node
7318
- * once per `Encoder`.
7364
+ * is reachable from `root` — the writer census of `failureNeedsRollback`,
7365
+ * entering each combinator once per `Encoder` (see `reachesMarked`).
7319
7366
  */
7320
7367
  reachesSideWriter(root) {
7321
- const memo = this.sideWriterMemo;
7322
- const known = memo.get(root);
7323
- if (known !== void 0) return known;
7324
- const order = /* @__PURE__ */ new Map();
7325
- const low = [];
7326
- const found = [];
7327
- const stack = [];
7328
- const visit = (node2) => {
7329
- const at = low.length;
7330
- order.set(node2, at);
7331
- low.push(at);
7332
- found.push(false);
7333
- stack.push(node2);
7334
- const next = this.sideWriterSuccessors(node2);
7335
- if (next === true) found[at] = true;
7336
- else {
7337
- for (const child of next) {
7338
- const hit = memo.get(child);
7339
- if (hit !== void 0) {
7340
- if (hit) found[at] = true;
7341
- continue;
7342
- }
7343
- const seen = order.get(child);
7344
- if (seen !== void 0) {
7345
- if (seen < low[at]) low[at] = seen;
7346
- continue;
7347
- }
7348
- const k = visit(child);
7349
- if (low[k] < low[at]) low[at] = low[k];
7350
- if (found[k]) found[at] = true;
7351
- }
7352
- }
7353
- if (low[at] === at) {
7354
- const answer = found[at];
7355
- let member;
7356
- do {
7357
- member = stack.pop();
7358
- memo.set(member, answer);
7359
- } while (member !== node2);
7360
- }
7361
- return at;
7362
- };
7363
- return found[visit(root)];
7368
+ return reachesMarked(root, (node2) => this.sideWriterSuccessors(node2), this.sideWriterMemo);
7364
7369
  }
7365
7370
  /** The census's edges out of `node`, or `true` when `node` is itself a writer. */
7366
7371
  sideWriterSuccessors(node2) {
@@ -7715,7 +7720,7 @@ var Encoder = class {
7715
7720
  this.code[head + 4 + kids.length + i] = this.expected(deriveExpected(arms[i]));
7716
7721
  }
7717
7722
  this.choiceRollbackMasks.set(head, rollbackMask);
7718
- if (arms.every((arm) => !mayCommitFailure(arm, /* @__PURE__ */ new Set(), rr))) {
7723
+ if (arms.every((arm) => !mayCommitFailure(arm, rr, this.commitFailureMemo))) {
7719
7724
  this.nonCommittingChoiceSites.add(head);
7720
7725
  }
7721
7726
  return head;
@@ -17352,7 +17357,7 @@ function fieldOptionsSrc(def) {
17352
17357
  }
17353
17358
 
17354
17359
  // src/version.ts
17355
- var PARSEMAN_VERSION = "0.55.1";
17360
+ var PARSEMAN_VERSION = "0.55.2";
17356
17361
 
17357
17362
  // src/compiler/compile-linkable-table.ts
17358
17363
  function isLocal(rule) {