parseman 0.50.3 → 0.50.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.
@@ -43,10 +43,20 @@ function classifyFinalChoice(arms, resolve3) {
43
43
  }
44
44
  return { exclusive, firstSets, nullable: nullable2 };
45
45
  }
46
- function resolveNamedRef(p, resolve3) {
46
+ function winnerForRef(p, resolve3) {
47
47
  if (resolve3 === void 0) return void 0;
48
48
  const name = p._ruleName;
49
- return name === void 0 ? void 0 : resolve3(name);
49
+ const w = name === void 0 ? void 0 : resolve3(name);
50
+ if (w === void 0 || w === p) return void 0;
51
+ let cur = w;
52
+ for (const seen = /* @__PURE__ */ new Set(); !seen.has(cur); ) {
53
+ if (cur === p) return void 0;
54
+ seen.add(cur);
55
+ const cd = cur._def;
56
+ if (cd.tag !== "grammar" && cd.tag !== "trivia") return w;
57
+ cur = cd.parser;
58
+ }
59
+ return w;
50
60
  }
51
61
  function union(a, b) {
52
62
  if (a.kind === "any" || b.kind === "any") return { kind: "any" };
@@ -144,13 +154,15 @@ function matchesEmptyBody(p, seen, resolve3) {
144
154
  case "grammar":
145
155
  case "recover":
146
156
  return me(d.parser);
147
- case "lazy":
157
+ case "lazy": {
158
+ const w = winnerForRef(p, resolve3);
159
+ if (w !== void 0) return me(w);
148
160
  try {
149
161
  return me(d.thunk());
150
162
  } catch {
151
- const t = resolveNamedRef(p, resolve3);
152
- return t ? me(t) : true;
163
+ return true;
153
164
  }
165
+ }
154
166
  default:
155
167
  return true;
156
168
  }
@@ -214,13 +226,15 @@ function firstSetBody(p, seen, resolve3) {
214
226
  // terminals: no refs, cached set is exact
215
227
  case "dispatch":
216
228
  return fs3(d.selector);
217
- case "lazy":
229
+ case "lazy": {
230
+ const w = winnerForRef(p, resolve3);
231
+ if (w !== void 0) return fs3(w);
218
232
  try {
219
233
  return fs3(d.thunk());
220
234
  } catch {
221
- const t = resolveNamedRef(p, resolve3);
222
- return t ? fs3(t) : any();
235
+ return any();
223
236
  }
237
+ }
224
238
  case "choice": {
225
239
  let out = empty();
226
240
  for (const arm of d.parsers) out = union(out, fs3(arm));
@@ -7665,7 +7679,7 @@ var Encoder = class {
7665
7679
  d.tags === void 0 ? -1 : this.constant(d.tags)
7666
7680
  );
7667
7681
  if (matchesEmpty(d.parser)) return body;
7668
- const fs3 = d.parser._meta.firstSet;
7682
+ const fs3 = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
7669
7683
  if (fs3.kind === "any") return body;
7670
7684
  const cls = this.charClass(fs3);
7671
7685
  if (cls < 0) return body;
@@ -7779,7 +7793,7 @@ var Encoder = class {
7779
7793
  case "attempt": {
7780
7794
  const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
7781
7795
  if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
7782
- const fs3 = d.parser._meta.firstSet;
7796
+ const fs3 = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
7783
7797
  if (fs3.kind === "any" || matchesEmpty(d.parser)) return inner;
7784
7798
  const cls = this.charClass(fs3);
7785
7799
  if (cls < 0) return inner;
@@ -16926,7 +16940,7 @@ function compileRuleMap(ruleMap, opts = {}) {
16926
16940
  }
16927
16941
 
16928
16942
  // src/version.ts
16929
- var PARSEMAN_VERSION = "0.50.3";
16943
+ var PARSEMAN_VERSION = "0.50.4";
16930
16944
 
16931
16945
  // src/compiler/compile-linkable-table.ts
16932
16946
  function isLocal(rule) {