parseman 0.50.7 → 0.51.0

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.
Files changed (56) hide show
  1. package/dist/analysis/choice-cost.d.ts.map +1 -1
  2. package/dist/analysis/commitment.d.ts.map +1 -1
  3. package/dist/analysis/diagnostics.js +165 -21
  4. package/dist/analysis/diagnostics.js.map +2 -2
  5. package/dist/analysis/duplication.d.ts.map +1 -1
  6. package/dist/analysis/gating.d.ts.map +1 -1
  7. package/dist/cli/index.js +171 -22
  8. package/dist/cli/index.js.map +2 -2
  9. package/dist/combinators/dispatch.d.ts.map +1 -1
  10. package/dist/combinators/scanTo.d.ts +23 -1
  11. package/dist/combinators/scanTo.d.ts.map +1 -1
  12. package/dist/compiler/fields.d.ts.map +1 -1
  13. package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
  14. package/dist/compiler/ir-serialize.d.ts.map +1 -1
  15. package/dist/compiler/token-capability.js +2 -2
  16. package/dist/compiler/token-capability.js.map +1 -1
  17. package/dist/coverage.d.ts.map +1 -1
  18. package/dist/cst/reflection.d.ts.map +1 -1
  19. package/dist/index.js +192 -28
  20. package/dist/index.js.map +2 -2
  21. package/dist/plugin/index.js +179 -25
  22. package/dist/plugin/index.js.map +2 -2
  23. package/dist/spec/index.js +127 -12
  24. package/dist/spec/index.js.map +2 -2
  25. package/dist/table/assemble.d.ts.map +1 -1
  26. package/dist/table/emit.d.ts.map +1 -1
  27. package/dist/table/encode.d.ts.map +1 -1
  28. package/dist/table/exec.d.ts.map +1 -1
  29. package/dist/table/index.js +171 -22
  30. package/dist/table/index.js.map +2 -2
  31. package/dist/table/program.d.ts +2 -0
  32. package/dist/table/program.d.ts.map +1 -1
  33. package/dist/types.d.ts +2 -0
  34. package/dist/types.d.ts.map +1 -1
  35. package/dist/version.d.ts +1 -1
  36. package/package.json +1 -1
  37. package/src/analysis/choice-cost.ts +6 -1
  38. package/src/analysis/commitment.ts +10 -2
  39. package/src/analysis/duplication.ts +7 -2
  40. package/src/analysis/gating.ts +6 -1
  41. package/src/analysis/rebuild.ts +1 -1
  42. package/src/combinators/dispatch.ts +4 -1
  43. package/src/combinators/scanTo.ts +163 -9
  44. package/src/compiler/fields.ts +8 -2
  45. package/src/compiler/grammar-coverage-ids.ts +6 -1
  46. package/src/compiler/ir-serialize.ts +7 -2
  47. package/src/compiler/token-alphabet.ts +1 -1
  48. package/src/coverage.ts +7 -1
  49. package/src/cst/reflection.ts +6 -1
  50. package/src/table/assemble.ts +11 -1
  51. package/src/table/emit.ts +4 -0
  52. package/src/table/encode.ts +6 -0
  53. package/src/table/exec.ts +7 -1
  54. package/src/table/program.ts +2 -0
  55. package/src/types.ts +1 -1
  56. package/src/version.ts +1 -1
@@ -1753,7 +1753,12 @@ function childrenOf(def) {
1753
1753
  case "sepBy":
1754
1754
  return [def.parser, def.separator];
1755
1755
  case "scanTo":
1756
- return [def.sentinel, ...def.skip];
1756
+ return [
1757
+ def.sentinel,
1758
+ ...def.skip,
1759
+ ...def.recoverAt === void 0 ? [] : [def.recoverAt],
1760
+ ...def.stopAt === void 0 ? [] : [def.stopAt]
1761
+ ];
1757
1762
  case "routed":
1758
1763
  return def.fallback ? [def.fallback] : [];
1759
1764
  case "literal":
@@ -3832,7 +3837,7 @@ function parserUsesRouted(parser2, seen = /* @__PURE__ */ new Set()) {
3832
3837
  case "grammar":
3833
3838
  return parserUsesRouted(def.parser, seen) || (def.triviaParser ? parserUsesRouted(def.triviaParser, seen) : false);
3834
3839
  case "scanTo":
3835
- return parserUsesRouted(def.sentinel, seen) || def.skip.some((entry) => parserUsesRouted(entry, seen));
3840
+ return parserUsesRouted(def.sentinel, seen) || def.skip.some((entry) => parserUsesRouted(entry, seen)) || def.recoverAt !== void 0 && parserUsesRouted(def.recoverAt, seen) || def.stopAt !== void 0 && parserUsesRouted(def.stopAt, seen);
3836
3841
  case "recover":
3837
3842
  return parserUsesRouted(def.parser, seen) || parserUsesRouted(def.sentinel, seen);
3838
3843
  case "lazy":
@@ -4838,7 +4843,7 @@ function parserHasOwnFields(p, seen = /* @__PURE__ */ new Set()) {
4838
4843
  case "grammar":
4839
4844
  return parserHasOwnFields(d.parser, seen) || (d.triviaParser ? parserHasOwnFields(d.triviaParser, seen) : false);
4840
4845
  case "scanTo":
4841
- return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen));
4846
+ return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen)) || d.recoverAt !== void 0 && parserHasOwnFields(d.recoverAt, seen) || d.stopAt !== void 0 && parserHasOwnFields(d.stopAt, seen);
4842
4847
  case "recover":
4843
4848
  return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.sentinel, seen);
4844
4849
  case "routed":
@@ -5221,7 +5226,12 @@ function childrenOf2(d) {
5221
5226
  case "recover":
5222
5227
  return [d.parser, d.sentinel];
5223
5228
  case "scanTo":
5224
- return [d.sentinel, ...d.skip];
5229
+ return [
5230
+ d.sentinel,
5231
+ ...d.skip,
5232
+ ...d.recoverAt === void 0 ? [] : [d.recoverAt],
5233
+ ...d.stopAt === void 0 ? [] : [d.stopAt]
5234
+ ];
5225
5235
  case "grammar":
5226
5236
  return d.triviaParser ? [d.parser, d.triviaParser] : [d.parser];
5227
5237
  case "routed":
@@ -5492,7 +5502,7 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
5492
5502
  case "sepBy":
5493
5503
  return hasNodeDef(d.parser, seen) || hasNodeDef(d.separator, seen);
5494
5504
  case "scanTo":
5495
- return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen));
5505
+ return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen)) || d.recoverAt !== void 0 && hasNodeDef(d.recoverAt, seen) || d.stopAt !== void 0 && hasNodeDef(d.stopAt, seen);
5496
5506
  case "recover":
5497
5507
  return hasNodeDef(d.parser, seen) || hasNodeDef(d.sentinel, seen);
5498
5508
  case "expect":
@@ -5541,7 +5551,7 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
5541
5551
  case "sepBy":
5542
5552
  return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.separator, seen);
5543
5553
  case "scanTo":
5544
- return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen));
5554
+ return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen)) || d.recoverAt !== void 0 && hasDirectBuildDef(d.recoverAt, seen) || d.stopAt !== void 0 && hasDirectBuildDef(d.stopAt, seen);
5545
5555
  case "recover":
5546
5556
  return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.sentinel, seen);
5547
5557
  case "routed":
@@ -5578,7 +5588,7 @@ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve3) {
5578
5588
  case "withCtx":
5579
5589
  return mayCommitFailure(d.parser, seen, resolve3);
5580
5590
  case "scanTo":
5581
- return mayCommitFailure(d.sentinel, seen, resolve3) || d.skip.some((x) => mayCommitFailure(x, seen, resolve3));
5591
+ 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);
5582
5592
  case "lazy": {
5583
5593
  try {
5584
5594
  return mayCommitFailure(d.thunk(), seen, resolve3);
@@ -7484,6 +7494,8 @@ var Encoder = class {
7484
7494
  flags: (d.raw ? 1 : 0) | (d.orEOF ? 2 : 0),
7485
7495
  skip: d.skip.map((c) => this.subtree(c)),
7486
7496
  sentinel: this.subtree(d.sentinel),
7497
+ ...d.recoverAt === void 0 ? {} : { recoverAt: this.subtree(d.recoverAt) },
7498
+ ...d.stopAt === void 0 ? {} : { stopAt: this.subtree(d.stopAt) },
7487
7499
  sent: sentDef.tag === "literal" ? sentDef.value : null
7488
7500
  }));
7489
7501
  }
@@ -7917,6 +7929,8 @@ var Encoder = class {
7917
7929
  const refs = [];
7918
7930
  for (const s of this.scans) {
7919
7931
  if (s.sentinel !== void 0) refs.push(s.sentinel);
7932
+ if (s.recoverAt !== void 0) refs.push(s.recoverAt);
7933
+ if (s.stopAt !== void 0) refs.push(s.stopAt);
7920
7934
  refs.push(...s.skip);
7921
7935
  }
7922
7936
  for (const set of this.scanSkipSets) refs.push(...set);
@@ -7936,7 +7950,9 @@ var Encoder = class {
7936
7950
  this.scans = this.scans.map((s) => ({
7937
7951
  ...s,
7938
7952
  skip: s.skip.map(res),
7939
- ...s.sentinel === void 0 ? {} : { sentinel: res(s.sentinel) }
7953
+ ...s.sentinel === void 0 ? {} : { sentinel: res(s.sentinel) },
7954
+ ...s.recoverAt === void 0 ? {} : { recoverAt: res(s.recoverAt) },
7955
+ ...s.stopAt === void 0 ? {} : { stopAt: res(s.stopAt) }
7940
7956
  }));
7941
7957
  this.scanSkipSets = this.scanSkipSets.map((set) => set.map(res));
7942
7958
  }
@@ -11180,7 +11196,7 @@ function resolveScanSkip(explicitSkip, raw, ctx) {
11180
11196
  out.push(...explicitSkip);
11181
11197
  return out;
11182
11198
  }
11183
- function scanTo(sentinel, { skip, raw = false, orEOF = false } = {}) {
11199
+ function scanTo(sentinel, { skip, raw = false, orEOF = false, recoverAt, stopAt } = {}) {
11184
11200
  const meta = {
11185
11201
  firstSet: any(),
11186
11202
  canMatchNewline: true,
@@ -11190,7 +11206,15 @@ function scanTo(sentinel, { skip, raw = false, orEOF = false } = {}) {
11190
11206
  return {
11191
11207
  _tag: "scanTo",
11192
11208
  _meta: meta,
11193
- _def: { tag: "scanTo", sentinel, skip: explicitSkip, raw, orEOF },
11209
+ _def: {
11210
+ tag: "scanTo",
11211
+ sentinel,
11212
+ skip: explicitSkip,
11213
+ raw,
11214
+ orEOF,
11215
+ ...recoverAt === void 0 ? {} : { recoverAt },
11216
+ ...stopAt === void 0 ? {} : { stopAt }
11217
+ },
11194
11218
  parse(input, pos, ctx) {
11195
11219
  let cur = pos;
11196
11220
  const skip2 = resolveScanSkip(explicitSkip, raw, ctx);
@@ -11202,28 +11226,130 @@ function scanTo(sentinel, { skip, raw = false, orEOF = false } = {}) {
11202
11226
  pushCstLeaf(ctx, leaf2);
11203
11227
  }
11204
11228
  };
11205
- while (cur < input.length) {
11206
- const s = sentinel.parse(input, cur, probeCtx);
11207
- if (s.ok) {
11229
+ if (recoverAt === void 0 && stopAt === void 0) {
11230
+ while (cur < input.length) {
11231
+ const s = sentinel.parse(input, cur, probeCtx);
11232
+ if (s.ok) {
11233
+ if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
11234
+ emit(cur);
11235
+ return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
11236
+ }
11237
+ let advanced = false;
11238
+ for (const skipper of skip2) {
11239
+ const r = skipper.parse(input, cur, probeCtx);
11240
+ if (r.ok && r.span.end > cur) {
11241
+ cur = r.span.end;
11242
+ advanced = true;
11243
+ break;
11244
+ }
11245
+ }
11246
+ if (!advanced) cur++;
11247
+ }
11248
+ if (orEOF) {
11208
11249
  if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
11209
11250
  emit(cur);
11210
11251
  return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
11211
11252
  }
11253
+ const sentDef2 = sentinel._def;
11254
+ const expected2 = sentDef2.tag === "literal" ? [JSON.stringify(sentDef2.value)] : ["sentinel"];
11255
+ return { ok: false, expected: expected2, span: { start: pos, end: cur } };
11256
+ }
11257
+ let recovery = -1;
11258
+ let firstSentinel = -1;
11259
+ let sentinelCount = 0;
11260
+ let recoveryErrorCount = -1;
11261
+ let sentinelErrorCount = -1;
11262
+ const succeed = (end) => {
11263
+ if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
11264
+ emit(end);
11265
+ return { ok: true, value: input.slice(pos, end), span: { start: pos, end } };
11266
+ };
11267
+ const recoveredEnd = () => {
11268
+ const acceptSentinel = firstSentinel >= 0 && (sentinelCount & 1) === 1;
11269
+ const errors = ctx._errors;
11270
+ if (errors !== void 0) {
11271
+ const keep = acceptSentinel ? sentinelErrorCount : recoveryErrorCount;
11272
+ if (keep >= 0 && errors.length > keep) errors.length = keep;
11273
+ }
11274
+ return acceptSentinel ? firstSentinel : recovery;
11275
+ };
11276
+ while (cur < input.length) {
11277
+ const sentinelProbeErrorCount = ctx._errors?.length ?? -1;
11278
+ const s = sentinel.parse(input, cur, probeCtx);
11279
+ const sentinelProbeErrors = ctx._errors;
11280
+ if (sentinelProbeErrors !== void 0 && sentinelProbeErrorCount >= 0 && sentinelProbeErrors.length > sentinelProbeErrorCount) {
11281
+ sentinelProbeErrors.length = sentinelProbeErrorCount;
11282
+ }
11283
+ if (s.ok) {
11284
+ if (recovery < 0) return succeed(cur);
11285
+ if (s.span.end <= cur) {
11286
+ throw new TypeError("scanTo recovery requires a sentinel that consumes input");
11287
+ }
11288
+ if (firstSentinel < 0) {
11289
+ firstSentinel = cur;
11290
+ sentinelErrorCount = sentinelProbeErrorCount;
11291
+ }
11292
+ sentinelCount++;
11293
+ cur = s.span.end;
11294
+ continue;
11295
+ }
11296
+ if (stopAt !== void 0) {
11297
+ const errorCount = ctx._errors?.length ?? -1;
11298
+ const stop = stopAt.parse(input, cur, probeCtx);
11299
+ const errors = ctx._errors;
11300
+ if (errors !== void 0 && errorCount >= 0 && errors.length > errorCount) {
11301
+ errors.length = errorCount;
11302
+ }
11303
+ if (stop.ok) {
11304
+ if (recovery < 0) {
11305
+ recovery = cur;
11306
+ recoveryErrorCount = errorCount;
11307
+ }
11308
+ return succeed(recoveredEnd());
11309
+ }
11310
+ }
11212
11311
  let advanced = false;
11213
11312
  for (const skipper of skip2) {
11313
+ const errorCount = ctx._errors?.length ?? -1;
11214
11314
  const r = skipper.parse(input, cur, probeCtx);
11215
11315
  if (r.ok && r.span.end > cur) {
11216
11316
  cur = r.span.end;
11217
11317
  advanced = true;
11218
11318
  break;
11219
11319
  }
11320
+ const errors = ctx._errors;
11321
+ if (errors !== void 0 && errorCount >= 0 && errors.length > errorCount) {
11322
+ errors.length = errorCount;
11323
+ }
11324
+ }
11325
+ if (advanced) continue;
11326
+ if (recoverAt !== void 0) {
11327
+ const errorCount = ctx._errors?.length ?? -1;
11328
+ const recover = recoverAt.parse(input, cur, probeCtx);
11329
+ const errors = ctx._errors;
11330
+ if (errors !== void 0 && errorCount >= 0 && errors.length > errorCount) {
11331
+ errors.length = errorCount;
11332
+ }
11333
+ if (recover.ok) {
11334
+ if (recover.span.end <= cur) {
11335
+ throw new TypeError("scanTo recoverAt must consume input");
11336
+ }
11337
+ if (recovery < 0) {
11338
+ recovery = cur;
11339
+ recoveryErrorCount = errorCount;
11340
+ }
11341
+ if (firstSentinel >= 0 && (sentinelCount & 1) === 1) {
11342
+ return succeed(recoveredEnd());
11343
+ }
11344
+ cur = recover.span.end;
11345
+ continue;
11346
+ }
11220
11347
  }
11221
- if (!advanced) cur++;
11348
+ cur++;
11222
11349
  }
11350
+ if (recovery >= 0) return succeed(recoveredEnd());
11223
11351
  if (orEOF) {
11224
- if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
11225
- emit(cur);
11226
- return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
11352
+ return succeed(cur);
11227
11353
  }
11228
11354
  const sentDef = sentinel._def;
11229
11355
  const expected = sentDef.tag === "literal" ? [JSON.stringify(sentDef.value)] : ["sentinel"];
@@ -11511,6 +11637,8 @@ function assemble(t, prog, cfg) {
11511
11637
  for (const s of prog.scans ?? []) {
11512
11638
  for (const r of s.skip) labelExtraIps.push(r[0]);
11513
11639
  if (s.sentinel !== void 0) labelExtraIps.push(s.sentinel[0]);
11640
+ if (s.recoverAt !== void 0) labelExtraIps.push(s.recoverAt[0]);
11641
+ if (s.stopAt !== void 0) labelExtraIps.push(s.stopAt[0]);
11514
11642
  }
11515
11643
  for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
11516
11644
  const closureLabels = computeSiteLabels(
@@ -14196,6 +14324,8 @@ function assemble(t, prog, cfg) {
14196
14324
  for (const s of prog.scans ?? []) {
14197
14325
  for (const r of s.skip) extraIps.push(r[0]);
14198
14326
  if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
14327
+ if (s.recoverAt !== void 0) extraIps.push(s.recoverAt[0]);
14328
+ if (s.stopAt !== void 0) extraIps.push(s.stopAt[0]);
14199
14329
  }
14200
14330
  for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
14201
14331
  const roots = [...Object.values(prog.rules), ...extraIps];
@@ -14407,7 +14537,13 @@ function assemble(t, prog, cfg) {
14407
14537
  continue;
14408
14538
  }
14409
14539
  const sentDef = typeof s.sent === "string" ? { tag: "literal", value: s.sent, caseInsensitive: false } : void 0;
14410
- scansArr.push(scanTo(subtreeComb(s.sentinel, sentDef), { skip, raw, orEOF: (s.flags & 2) !== 0 }));
14540
+ scansArr.push(scanTo(subtreeComb(s.sentinel, sentDef), {
14541
+ skip,
14542
+ raw,
14543
+ orEOF: (s.flags & 2) !== 0,
14544
+ ...s.recoverAt === void 0 ? {} : { recoverAt: subtreeComb(s.recoverAt) },
14545
+ ...s.stopAt === void 0 ? {} : { stopAt: subtreeComb(s.stopAt) }
14546
+ }));
14411
14547
  }
14412
14548
  const scans = scansArr;
14413
14549
  const scanSkip = (prog.scanSkip ?? []).map((set) => set.map((r) => subtreeComb(r)));
@@ -14624,6 +14760,8 @@ function emitRef(r) {
14624
14760
  function emitScanSpec(s) {
14625
14761
  const parts = [`kind:${s.kind}`, `flags:${s.flags}`, `skip:[${s.skip.map(emitRef).join(",")}]`];
14626
14762
  if (s.sentinel !== void 0) parts.push(`sentinel:${emitRef(s.sentinel)}`);
14763
+ if (s.recoverAt !== void 0) parts.push(`recoverAt:${emitRef(s.recoverAt)}`);
14764
+ if (s.stopAt !== void 0) parts.push(`stopAt:${emitRef(s.stopAt)}`);
14627
14765
  if (s.sent !== void 0) parts.push(`sent:${s.sent === null ? "null" : jsString(s.sent)}`);
14628
14766
  if (s.open !== void 0) parts.push(`open:${jsString(s.open)}`);
14629
14767
  if (s.close !== void 0) parts.push(`close:${jsString(s.close)}`);
@@ -14650,6 +14788,8 @@ function emitAssemblies(prog, cfgs) {
14650
14788
  for (const s of prog.scans ?? []) {
14651
14789
  for (const r of s.skip) extraIps.push(r[0]);
14652
14790
  if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
14791
+ if (s.recoverAt !== void 0) extraIps.push(s.recoverAt[0]);
14792
+ if (s.stopAt !== void 0) extraIps.push(s.stopAt[0]);
14653
14793
  }
14654
14794
  for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
14655
14795
  const out = [];
@@ -14792,7 +14932,12 @@ function children(def, winners) {
14792
14932
  case "sepBy":
14793
14933
  return [def.parser, def.separator];
14794
14934
  case "scanTo":
14795
- return [def.sentinel, ...def.skip];
14935
+ return [
14936
+ def.sentinel,
14937
+ ...def.skip,
14938
+ ...def.recoverAt === void 0 ? [] : [def.recoverAt],
14939
+ ...def.stopAt === void 0 ? [] : [def.stopAt]
14940
+ ];
14796
14941
  case "lazy": {
14797
14942
  let resolved;
14798
14943
  try {
@@ -14905,7 +15050,7 @@ function payloadKey(p, d) {
14905
15050
  case "expect":
14906
15051
  return `expect\0${d.label ?? ""}\0${d.expected.join("")}`;
14907
15052
  case "scanTo":
14908
- return `scanTo\0${d.raw}\0${d.orEOF}`;
15053
+ return `scanTo\0${d.raw}\0${d.orEOF}\0${d.recoverAt !== void 0}\0${d.stopAt !== void 0}`;
14909
15054
  case "guard":
14910
15055
  return `guard\0${fnKey(d.predSrc, d.predicate)}`;
14911
15056
  case "adjacency":
@@ -15020,8 +15165,12 @@ function segment(d, index) {
15020
15165
  return index === 0 ? "sepBy.item" : "sepBy.sep";
15021
15166
  case "recover":
15022
15167
  return index === 0 ? "recover.body" : "recover.sentinel";
15023
- case "scanTo":
15024
- return index === 0 ? "scanTo.sentinel" : `scanTo.skip[${index - 1}]`;
15168
+ case "scanTo": {
15169
+ if (index === 0) return "scanTo.sentinel";
15170
+ if (index <= d.skip.length) return `scanTo.skip[${index - 1}]`;
15171
+ if (d.recoverAt !== void 0 && index === d.skip.length + 1) return "scanTo.recoverAt";
15172
+ return "scanTo.stopAt";
15173
+ }
15025
15174
  default:
15026
15175
  return d.tag;
15027
15176
  }
@@ -16297,7 +16446,12 @@ function childrenOf3(def) {
16297
16446
  case "sepBy":
16298
16447
  return [def.parser, def.separator];
16299
16448
  case "scanTo":
16300
- return [def.sentinel, ...def.skip];
16449
+ return [
16450
+ def.sentinel,
16451
+ ...def.skip,
16452
+ ...def.recoverAt === void 0 ? [] : [def.recoverAt],
16453
+ ...def.stopAt === void 0 ? [] : [def.stopAt]
16454
+ ];
16301
16455
  case "routed":
16302
16456
  return def.fallback ? [def.fallback] : [];
16303
16457
  case "lazy":
@@ -16791,7 +16945,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
16791
16945
  case "expect":
16792
16946
  return `expect(${kid(def.parser)}${def.label !== void 0 ? `, ${JSON.stringify(def.label)}` : ""})`;
16793
16947
  case "scanTo":
16794
- return `scanTo(${kid(def.sentinel)}, { skip: [${def.skip.map(kid).join(", ")}]${def.raw ? ", raw: true" : ""}, orEOF: ${def.orEOF} })`;
16948
+ return `scanTo(${kid(def.sentinel)}, { skip: [${def.skip.map(kid).join(", ")}]${def.raw ? ", raw: true" : ""}, orEOF: ${def.orEOF}${def.recoverAt === void 0 ? "" : `, recoverAt: ${kid(def.recoverAt)}`}${def.stopAt === void 0 ? "" : `, stopAt: ${kid(def.stopAt)}`} })`;
16795
16949
  case "transform": {
16796
16950
  if (def.fnSrc === void 0) throw new Unserializable("transform without fnSrc");
16797
16951
  return `_tf(${kid(def.parser)}, ${JSON.stringify(def.fnSrc)}${def.recognitionOnly ? ", true" : ""})`;
@@ -16971,7 +17125,7 @@ function compileRuleMap(ruleMap, opts = {}) {
16971
17125
  }
16972
17126
 
16973
17127
  // src/version.ts
16974
- var PARSEMAN_VERSION = "0.50.7";
17128
+ var PARSEMAN_VERSION = "0.51.0";
16975
17129
 
16976
17130
  // src/compiler/compile-linkable-table.ts
16977
17131
  function isLocal(rule) {