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.
package/dist/cli/index.js CHANGED
@@ -43,10 +43,20 @@ function classifyFinalChoice(arms, resolve2) {
43
43
  }
44
44
  return { exclusive, firstSets, nullable: nullable2 };
45
45
  }
46
- function resolveNamedRef(p, resolve2) {
46
+ function winnerForRef(p, resolve2) {
47
47
  if (resolve2 === void 0) return void 0;
48
48
  const name = p._ruleName;
49
- return name === void 0 ? void 0 : resolve2(name);
49
+ const w = name === void 0 ? void 0 : resolve2(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, resolve2) {
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, resolve2);
159
+ if (w !== void 0) return me(w);
148
160
  try {
149
161
  return me(d.thunk());
150
162
  } catch {
151
- const t2 = resolveNamedRef(p, resolve2);
152
- return t2 ? me(t2) : true;
163
+ return true;
153
164
  }
165
+ }
154
166
  default:
155
167
  return true;
156
168
  }
@@ -214,13 +226,15 @@ function firstSetBody(p, seen, resolve2) {
214
226
  // terminals: no refs, cached set is exact
215
227
  case "dispatch":
216
228
  return fs(d.selector);
217
- case "lazy":
229
+ case "lazy": {
230
+ const w = winnerForRef(p, resolve2);
231
+ if (w !== void 0) return fs(w);
218
232
  try {
219
233
  return fs(d.thunk());
220
234
  } catch {
221
- const t2 = resolveNamedRef(p, resolve2);
222
- return t2 ? fs(t2) : 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, fs(arm));
@@ -8206,7 +8220,7 @@ var Encoder = class {
8206
8220
  d.tags === void 0 ? -1 : this.constant(d.tags)
8207
8221
  );
8208
8222
  if (matchesEmpty(d.parser)) return body;
8209
- const fs = d.parser._meta.firstSet;
8223
+ const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
8210
8224
  if (fs.kind === "any") return body;
8211
8225
  const cls = this.charClass(fs);
8212
8226
  if (cls < 0) return body;
@@ -8320,7 +8334,7 @@ var Encoder = class {
8320
8334
  case "attempt": {
8321
8335
  const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
8322
8336
  if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
8323
- const fs = d.parser._meta.firstSet;
8337
+ const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
8324
8338
  if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
8325
8339
  const cls = this.charClass(fs);
8326
8340
  if (cls < 0) return inner;