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.
package/dist/index.js CHANGED
@@ -6025,19 +6025,22 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
6025
6025
  return false;
6026
6026
  }
6027
6027
  }
6028
- function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve) {
6029
- if (seen.has(p)) return false;
6030
- seen.add(p);
6028
+ function mayCommitFailure(p, resolve, memo = /* @__PURE__ */ new Map()) {
6029
+ return reachesMarked(p, (node2) => commitFailureSuccessors(node2, resolve), memo);
6030
+ }
6031
+ var NO_EDGES = [];
6032
+ function commitFailureSuccessors(p, resolve) {
6031
6033
  const d = p._def;
6032
6034
  switch (d.tag) {
6033
6035
  case "dispatch":
6036
+ case "unknown":
6034
6037
  return true;
6035
6038
  case "choice":
6036
6039
  case "sequence":
6037
- return d.parsers.some((x) => mayCommitFailure(x, seen, resolve));
6040
+ return d.parsers;
6038
6041
  // A contained transaction reports every failure uncommitted.
6039
6042
  case "attempt":
6040
- return d.contain !== true && mayCommitFailure(d.parser, seen, resolve);
6043
+ return d.contain === true ? NO_EDGES : [d.parser];
6041
6044
  case "many":
6042
6045
  case "oneOrMore":
6043
6046
  case "optional":
@@ -6046,31 +6049,77 @@ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve) {
6046
6049
  case "field":
6047
6050
  case "grammar":
6048
6051
  case "node":
6049
- return mayCommitFailure(d.parser, seen, resolve);
6050
- case "sepBy":
6051
- return mayCommitFailure(d.parser, seen, resolve) || mayCommitFailure(d.separator, seen, resolve);
6052
6052
  case "token":
6053
6053
  case "leaf":
6054
- return mayCommitFailure(d.parser, seen, resolve);
6055
6054
  case "withCtx":
6056
- return mayCommitFailure(d.parser, seen, resolve);
6055
+ return [d.parser];
6056
+ case "sepBy":
6057
+ return [d.parser, d.separator];
6057
6058
  case "scanTo":
6058
- return mayCommitFailure(d.sentinel, seen, resolve) || d.skip.some((x) => mayCommitFailure(x, seen, resolve)) || d.recoverAt !== void 0 && mayCommitFailure(d.recoverAt, seen, resolve) || d.stopAt !== void 0 && mayCommitFailure(d.stopAt, seen, resolve);
6059
+ return [
6060
+ d.sentinel,
6061
+ ...d.skip,
6062
+ ...d.recoverAt === void 0 ? NO_EDGES : [d.recoverAt],
6063
+ ...d.stopAt === void 0 ? NO_EDGES : [d.stopAt]
6064
+ ];
6059
6065
  case "lazy": {
6060
6066
  try {
6061
- return mayCommitFailure(d.thunk(), seen, resolve);
6067
+ return [d.thunk()];
6062
6068
  } catch {
6063
6069
  const name = p._ruleName;
6064
6070
  const target = name === void 0 ? void 0 : resolve?.(name);
6065
- return target === void 0 ? true : mayCommitFailure(target, seen, resolve);
6071
+ return target === void 0 ? true : [target];
6066
6072
  }
6067
6073
  }
6068
- case "unknown":
6069
- return true;
6070
6074
  default:
6071
- return false;
6075
+ return NO_EDGES;
6072
6076
  }
6073
6077
  }
6078
+ function reachesMarked(root, successors, memo) {
6079
+ const known = memo.get(root);
6080
+ if (known !== void 0) return known;
6081
+ const order = /* @__PURE__ */ new Map();
6082
+ const low = [];
6083
+ const found = [];
6084
+ const stack = [];
6085
+ const visit = (node2) => {
6086
+ const at = low.length;
6087
+ order.set(node2, at);
6088
+ low.push(at);
6089
+ found.push(false);
6090
+ stack.push(node2);
6091
+ const next = successors(node2);
6092
+ if (next === true) found[at] = true;
6093
+ else {
6094
+ for (const child of next) {
6095
+ if (found[at]) break;
6096
+ const hit = memo.get(child);
6097
+ if (hit !== void 0) {
6098
+ if (hit) found[at] = true;
6099
+ continue;
6100
+ }
6101
+ const seen = order.get(child);
6102
+ if (seen !== void 0) {
6103
+ if (seen < low[at]) low[at] = seen;
6104
+ continue;
6105
+ }
6106
+ const k = visit(child);
6107
+ if (low[k] < low[at]) low[at] = low[k];
6108
+ if (found[k]) found[at] = true;
6109
+ }
6110
+ }
6111
+ if (low[at] === at) {
6112
+ const answer = found[at];
6113
+ let member;
6114
+ do {
6115
+ member = stack.pop();
6116
+ memo.set(member, answer);
6117
+ } while (member !== node2);
6118
+ }
6119
+ return at;
6120
+ };
6121
+ return found[visit(root)];
6122
+ }
6074
6123
  function hasSemanticReduction(roots, externalRefs) {
6075
6124
  const seen = /* @__PURE__ */ new Set();
6076
6125
  const visit = (parser2) => {
@@ -7266,6 +7315,13 @@ var Encoder = class {
7266
7315
  * attempt sites reach it.
7267
7316
  */
7268
7317
  sideWriterMemo = /* @__PURE__ */ new Map();
7318
+ /**
7319
+ * `mayCommitFailure`'s answers, shared by every choice site for the lifetime
7320
+ * of this `Encoder` — exact for the graph and the `winners` resolver it is
7321
+ * encoding, so the rule graph is walked once per encode rather than once per
7322
+ * choice site.
7323
+ */
7324
+ commitFailureMemo = /* @__PURE__ */ new Map();
7269
7325
  labels = void 0;
7270
7326
  /** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
7271
7327
  activeTrivia = void 0;
@@ -7706,62 +7762,11 @@ var Encoder = class {
7706
7762
  }
7707
7763
  /**
7708
7764
  * Whether a field, recovered error, interpreted scanner or unresolvable shape
7709
- * is reachable from `root` — the writer census of `failureNeedsRollback`.
7710
- *
7711
- * Reachability over a cyclic graph, decided with Tarjan's strongly connected
7712
- * components so that every node the walk enters leaves with its exact answer
7713
- * memoized: the members of one component reach each other, so they share one
7714
- * answer, settled when the walk returns to the component's first node. A DFS
7715
- * that instead cuts a cycle at its own ancestor path learns nothing it can
7716
- * keep about a node whose walk hit the cut, and re-walks that node along
7717
- * every path that reaches it — exponential over recursive value rules (linking
7718
- * jess's SCSS grammar cost ~290G instructions). This walk enters each node
7719
- * once per `Encoder`.
7765
+ * is reachable from `root` — the writer census of `failureNeedsRollback`,
7766
+ * entering each combinator once per `Encoder` (see `reachesMarked`).
7720
7767
  */
7721
7768
  reachesSideWriter(root) {
7722
- const memo = this.sideWriterMemo;
7723
- const known = memo.get(root);
7724
- if (known !== void 0) return known;
7725
- const order = /* @__PURE__ */ new Map();
7726
- const low = [];
7727
- const found = [];
7728
- const stack = [];
7729
- const visit = (node2) => {
7730
- const at = low.length;
7731
- order.set(node2, at);
7732
- low.push(at);
7733
- found.push(false);
7734
- stack.push(node2);
7735
- const next = this.sideWriterSuccessors(node2);
7736
- if (next === true) found[at] = true;
7737
- else {
7738
- for (const child of next) {
7739
- const hit = memo.get(child);
7740
- if (hit !== void 0) {
7741
- if (hit) found[at] = true;
7742
- continue;
7743
- }
7744
- const seen = order.get(child);
7745
- if (seen !== void 0) {
7746
- if (seen < low[at]) low[at] = seen;
7747
- continue;
7748
- }
7749
- const k = visit(child);
7750
- if (low[k] < low[at]) low[at] = low[k];
7751
- if (found[k]) found[at] = true;
7752
- }
7753
- }
7754
- if (low[at] === at) {
7755
- const answer = found[at];
7756
- let member;
7757
- do {
7758
- member = stack.pop();
7759
- memo.set(member, answer);
7760
- } while (member !== node2);
7761
- }
7762
- return at;
7763
- };
7764
- return found[visit(root)];
7769
+ return reachesMarked(root, (node2) => this.sideWriterSuccessors(node2), this.sideWriterMemo);
7765
7770
  }
7766
7771
  /** The census's edges out of `node`, or `true` when `node` is itself a writer. */
7767
7772
  sideWriterSuccessors(node2) {
@@ -8116,7 +8121,7 @@ var Encoder = class {
8116
8121
  this.code[head + 4 + kids.length + i] = this.expected(deriveExpected(arms[i]));
8117
8122
  }
8118
8123
  this.choiceRollbackMasks.set(head, rollbackMask);
8119
- if (arms.every((arm) => !mayCommitFailure(arm, /* @__PURE__ */ new Set(), rr))) {
8124
+ if (arms.every((arm) => !mayCommitFailure(arm, rr, this.commitFailureMemo))) {
8120
8125
  this.nonCommittingChoiceSites.add(head);
8121
8126
  }
8122
8127
  return head;
@@ -17766,7 +17771,7 @@ function fieldOptionsSrc(def) {
17766
17771
  }
17767
17772
 
17768
17773
  // src/version.ts
17769
- var PARSEMAN_VERSION = "0.55.1";
17774
+ var PARSEMAN_VERSION = "0.55.2";
17770
17775
 
17771
17776
  // src/compiler/compile-linkable-table.ts
17772
17777
  function isLocal(rule) {