parseman 0.55.1 → 0.55.3

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.
@@ -3585,14 +3585,8 @@ function choice(...args) {
3585
3585
  if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
3586
3586
  return { ok: false, expected, span: { start: pos, end: pos } };
3587
3587
  }
3588
- return {
3589
- ok: false,
3590
- expected: parsers.flatMap((p) => {
3591
- const r = p.parse(input, pos, ctx);
3592
- return r.ok ? [] : r.expected;
3593
- }),
3594
- span: { start: pos, end: pos }
3595
- };
3588
+ if (ctx._probe !== void 0 || ctx._tolerant) for (const p of parsers) p.parse(input, pos, ctx);
3589
+ return { ok: false, expected: [...scalarExpected], span: { start: pos, end: pos } };
3596
3590
  }
3597
3591
  if (strategy?.tag === "greedyClassify") {
3598
3592
  const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
@@ -5624,19 +5618,22 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
5624
5618
  return false;
5625
5619
  }
5626
5620
  }
5627
- function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve3) {
5628
- if (seen.has(p)) return false;
5629
- seen.add(p);
5621
+ function mayCommitFailure(p, resolve3, memo = /* @__PURE__ */ new Map()) {
5622
+ return reachesMarked(p, (node2) => commitFailureSuccessors(node2, resolve3), memo);
5623
+ }
5624
+ var NO_EDGES = [];
5625
+ function commitFailureSuccessors(p, resolve3) {
5630
5626
  const d = p._def;
5631
5627
  switch (d.tag) {
5632
5628
  case "dispatch":
5629
+ case "unknown":
5633
5630
  return true;
5634
5631
  case "choice":
5635
5632
  case "sequence":
5636
- return d.parsers.some((x) => mayCommitFailure(x, seen, resolve3));
5633
+ return d.parsers;
5637
5634
  // A contained transaction reports every failure uncommitted.
5638
5635
  case "attempt":
5639
- return d.contain !== true && mayCommitFailure(d.parser, seen, resolve3);
5636
+ return d.contain === true ? NO_EDGES : [d.parser];
5640
5637
  case "many":
5641
5638
  case "oneOrMore":
5642
5639
  case "optional":
@@ -5645,31 +5642,77 @@ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve3) {
5645
5642
  case "field":
5646
5643
  case "grammar":
5647
5644
  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
5645
  case "token":
5652
5646
  case "leaf":
5653
- return mayCommitFailure(d.parser, seen, resolve3);
5654
5647
  case "withCtx":
5655
- return mayCommitFailure(d.parser, seen, resolve3);
5648
+ return [d.parser];
5649
+ case "sepBy":
5650
+ return [d.parser, d.separator];
5656
5651
  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);
5652
+ return [
5653
+ d.sentinel,
5654
+ ...d.skip,
5655
+ ...d.recoverAt === void 0 ? NO_EDGES : [d.recoverAt],
5656
+ ...d.stopAt === void 0 ? NO_EDGES : [d.stopAt]
5657
+ ];
5658
5658
  case "lazy": {
5659
5659
  try {
5660
- return mayCommitFailure(d.thunk(), seen, resolve3);
5660
+ return [d.thunk()];
5661
5661
  } catch {
5662
5662
  const name = p._ruleName;
5663
5663
  const target = name === void 0 ? void 0 : resolve3?.(name);
5664
- return target === void 0 ? true : mayCommitFailure(target, seen, resolve3);
5664
+ return target === void 0 ? true : [target];
5665
5665
  }
5666
5666
  }
5667
- case "unknown":
5668
- return true;
5669
5667
  default:
5670
- return false;
5668
+ return NO_EDGES;
5671
5669
  }
5672
5670
  }
5671
+ function reachesMarked(root, successors, memo) {
5672
+ const known = memo.get(root);
5673
+ if (known !== void 0) return known;
5674
+ const order = /* @__PURE__ */ new Map();
5675
+ const low = [];
5676
+ const found = [];
5677
+ const stack = [];
5678
+ const visit = (node2) => {
5679
+ const at = low.length;
5680
+ order.set(node2, at);
5681
+ low.push(at);
5682
+ found.push(false);
5683
+ stack.push(node2);
5684
+ const next = successors(node2);
5685
+ if (next === true) found[at] = true;
5686
+ else {
5687
+ for (const child of next) {
5688
+ if (found[at]) break;
5689
+ const hit = memo.get(child);
5690
+ if (hit !== void 0) {
5691
+ if (hit) found[at] = true;
5692
+ continue;
5693
+ }
5694
+ const seen = order.get(child);
5695
+ if (seen !== void 0) {
5696
+ if (seen < low[at]) low[at] = seen;
5697
+ continue;
5698
+ }
5699
+ const k = visit(child);
5700
+ if (low[k] < low[at]) low[at] = low[k];
5701
+ if (found[k]) found[at] = true;
5702
+ }
5703
+ }
5704
+ if (low[at] === at) {
5705
+ const answer = found[at];
5706
+ let member;
5707
+ do {
5708
+ member = stack.pop();
5709
+ memo.set(member, answer);
5710
+ } while (member !== node2);
5711
+ }
5712
+ return at;
5713
+ };
5714
+ return found[visit(root)];
5715
+ }
5673
5716
  function hasSemanticReduction(roots, externalRefs) {
5674
5717
  const seen = /* @__PURE__ */ new Set();
5675
5718
  const visit = (parser2) => {
@@ -6865,6 +6908,13 @@ var Encoder = class {
6865
6908
  * attempt sites reach it.
6866
6909
  */
6867
6910
  sideWriterMemo = /* @__PURE__ */ new Map();
6911
+ /**
6912
+ * `mayCommitFailure`'s answers, shared by every choice site for the lifetime
6913
+ * of this `Encoder` — exact for the graph and the `winners` resolver it is
6914
+ * encoding, so the rule graph is walked once per encode rather than once per
6915
+ * choice site.
6916
+ */
6917
+ commitFailureMemo = /* @__PURE__ */ new Map();
6868
6918
  labels = void 0;
6869
6919
  /** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
6870
6920
  activeTrivia = void 0;
@@ -7305,62 +7355,11 @@ var Encoder = class {
7305
7355
  }
7306
7356
  /**
7307
7357
  * 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`.
7358
+ * is reachable from `root` — the writer census of `failureNeedsRollback`,
7359
+ * entering each combinator once per `Encoder` (see `reachesMarked`).
7319
7360
  */
7320
7361
  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)];
7362
+ return reachesMarked(root, (node2) => this.sideWriterSuccessors(node2), this.sideWriterMemo);
7364
7363
  }
7365
7364
  /** The census's edges out of `node`, or `true` when `node` is itself a writer. */
7366
7365
  sideWriterSuccessors(node2) {
@@ -7715,7 +7714,7 @@ var Encoder = class {
7715
7714
  this.code[head + 4 + kids.length + i] = this.expected(deriveExpected(arms[i]));
7716
7715
  }
7717
7716
  this.choiceRollbackMasks.set(head, rollbackMask);
7718
- if (arms.every((arm) => !mayCommitFailure(arm, /* @__PURE__ */ new Set(), rr))) {
7717
+ if (arms.every((arm) => !mayCommitFailure(arm, rr, this.commitFailureMemo))) {
7719
7718
  this.nonCommittingChoiceSites.add(head);
7720
7719
  }
7721
7720
  return head;
@@ -17352,7 +17351,7 @@ function fieldOptionsSrc(def) {
17352
17351
  }
17353
17352
 
17354
17353
  // src/version.ts
17355
- var PARSEMAN_VERSION = "0.55.1";
17354
+ var PARSEMAN_VERSION = "0.55.3";
17356
17355
 
17357
17356
  // src/compiler/compile-linkable-table.ts
17358
17357
  function isLocal(rule) {