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
@@ -1706,7 +1706,12 @@ function childrenOf(def) {
1706
1706
  case "sepBy":
1707
1707
  return [def.parser, def.separator];
1708
1708
  case "scanTo":
1709
- return [def.sentinel, ...def.skip];
1709
+ return [
1710
+ def.sentinel,
1711
+ ...def.skip,
1712
+ ...def.recoverAt === void 0 ? [] : [def.recoverAt],
1713
+ ...def.stopAt === void 0 ? [] : [def.stopAt]
1714
+ ];
1710
1715
  case "routed":
1711
1716
  return def.fallback ? [def.fallback] : [];
1712
1717
  case "literal":
@@ -3751,7 +3756,7 @@ function parserUsesRouted(parser2, seen = /* @__PURE__ */ new Set()) {
3751
3756
  case "grammar":
3752
3757
  return parserUsesRouted(def.parser, seen) || (def.triviaParser ? parserUsesRouted(def.triviaParser, seen) : false);
3753
3758
  case "scanTo":
3754
- return parserUsesRouted(def.sentinel, seen) || def.skip.some((entry) => parserUsesRouted(entry, seen));
3759
+ 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);
3755
3760
  case "recover":
3756
3761
  return parserUsesRouted(def.parser, seen) || parserUsesRouted(def.sentinel, seen);
3757
3762
  case "lazy":
@@ -4658,7 +4663,7 @@ function parserHasOwnFields(p, seen = /* @__PURE__ */ new Set()) {
4658
4663
  case "grammar":
4659
4664
  return parserHasOwnFields(d.parser, seen) || (d.triviaParser ? parserHasOwnFields(d.triviaParser, seen) : false);
4660
4665
  case "scanTo":
4661
- return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen));
4666
+ 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);
4662
4667
  case "recover":
4663
4668
  return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.sentinel, seen);
4664
4669
  case "routed":
@@ -5035,7 +5040,7 @@ function resolveScanSkip(explicitSkip, raw, ctx) {
5035
5040
  out.push(...explicitSkip);
5036
5041
  return out;
5037
5042
  }
5038
- function scanTo(sentinel, { skip, raw = false, orEOF = false } = {}) {
5043
+ function scanTo(sentinel, { skip, raw = false, orEOF = false, recoverAt, stopAt } = {}) {
5039
5044
  const meta = {
5040
5045
  firstSet: any(),
5041
5046
  canMatchNewline: true,
@@ -5045,7 +5050,15 @@ function scanTo(sentinel, { skip, raw = false, orEOF = false } = {}) {
5045
5050
  return {
5046
5051
  _tag: "scanTo",
5047
5052
  _meta: meta,
5048
- _def: { tag: "scanTo", sentinel, skip: explicitSkip, raw, orEOF },
5053
+ _def: {
5054
+ tag: "scanTo",
5055
+ sentinel,
5056
+ skip: explicitSkip,
5057
+ raw,
5058
+ orEOF,
5059
+ ...recoverAt === void 0 ? {} : { recoverAt },
5060
+ ...stopAt === void 0 ? {} : { stopAt }
5061
+ },
5049
5062
  parse(input, pos, ctx) {
5050
5063
  let cur = pos;
5051
5064
  const skip2 = resolveScanSkip(explicitSkip, raw, ctx);
@@ -5057,28 +5070,130 @@ function scanTo(sentinel, { skip, raw = false, orEOF = false } = {}) {
5057
5070
  pushCstLeaf(ctx, leaf2);
5058
5071
  }
5059
5072
  };
5060
- while (cur < input.length) {
5061
- const s = sentinel.parse(input, cur, probeCtx);
5062
- if (s.ok) {
5073
+ if (recoverAt === void 0 && stopAt === void 0) {
5074
+ while (cur < input.length) {
5075
+ const s = sentinel.parse(input, cur, probeCtx);
5076
+ if (s.ok) {
5077
+ if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
5078
+ emit(cur);
5079
+ return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
5080
+ }
5081
+ let advanced = false;
5082
+ for (const skipper of skip2) {
5083
+ const r = skipper.parse(input, cur, probeCtx);
5084
+ if (r.ok && r.span.end > cur) {
5085
+ cur = r.span.end;
5086
+ advanced = true;
5087
+ break;
5088
+ }
5089
+ }
5090
+ if (!advanced) cur++;
5091
+ }
5092
+ if (orEOF) {
5063
5093
  if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
5064
5094
  emit(cur);
5065
5095
  return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
5066
5096
  }
5097
+ const sentDef2 = sentinel._def;
5098
+ const expected2 = sentDef2.tag === "literal" ? [JSON.stringify(sentDef2.value)] : ["sentinel"];
5099
+ return { ok: false, expected: expected2, span: { start: pos, end: cur } };
5100
+ }
5101
+ let recovery = -1;
5102
+ let firstSentinel = -1;
5103
+ let sentinelCount = 0;
5104
+ let recoveryErrorCount = -1;
5105
+ let sentinelErrorCount = -1;
5106
+ const succeed = (end) => {
5107
+ if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
5108
+ emit(end);
5109
+ return { ok: true, value: input.slice(pos, end), span: { start: pos, end } };
5110
+ };
5111
+ const recoveredEnd = () => {
5112
+ const acceptSentinel = firstSentinel >= 0 && (sentinelCount & 1) === 1;
5113
+ const errors = ctx._errors;
5114
+ if (errors !== void 0) {
5115
+ const keep = acceptSentinel ? sentinelErrorCount : recoveryErrorCount;
5116
+ if (keep >= 0 && errors.length > keep) errors.length = keep;
5117
+ }
5118
+ return acceptSentinel ? firstSentinel : recovery;
5119
+ };
5120
+ while (cur < input.length) {
5121
+ const sentinelProbeErrorCount = ctx._errors?.length ?? -1;
5122
+ const s = sentinel.parse(input, cur, probeCtx);
5123
+ const sentinelProbeErrors = ctx._errors;
5124
+ if (sentinelProbeErrors !== void 0 && sentinelProbeErrorCount >= 0 && sentinelProbeErrors.length > sentinelProbeErrorCount) {
5125
+ sentinelProbeErrors.length = sentinelProbeErrorCount;
5126
+ }
5127
+ if (s.ok) {
5128
+ if (recovery < 0) return succeed(cur);
5129
+ if (s.span.end <= cur) {
5130
+ throw new TypeError("scanTo recovery requires a sentinel that consumes input");
5131
+ }
5132
+ if (firstSentinel < 0) {
5133
+ firstSentinel = cur;
5134
+ sentinelErrorCount = sentinelProbeErrorCount;
5135
+ }
5136
+ sentinelCount++;
5137
+ cur = s.span.end;
5138
+ continue;
5139
+ }
5140
+ if (stopAt !== void 0) {
5141
+ const errorCount = ctx._errors?.length ?? -1;
5142
+ const stop = stopAt.parse(input, cur, probeCtx);
5143
+ const errors = ctx._errors;
5144
+ if (errors !== void 0 && errorCount >= 0 && errors.length > errorCount) {
5145
+ errors.length = errorCount;
5146
+ }
5147
+ if (stop.ok) {
5148
+ if (recovery < 0) {
5149
+ recovery = cur;
5150
+ recoveryErrorCount = errorCount;
5151
+ }
5152
+ return succeed(recoveredEnd());
5153
+ }
5154
+ }
5067
5155
  let advanced = false;
5068
5156
  for (const skipper of skip2) {
5157
+ const errorCount = ctx._errors?.length ?? -1;
5069
5158
  const r = skipper.parse(input, cur, probeCtx);
5070
5159
  if (r.ok && r.span.end > cur) {
5071
5160
  cur = r.span.end;
5072
5161
  advanced = true;
5073
5162
  break;
5074
5163
  }
5164
+ const errors = ctx._errors;
5165
+ if (errors !== void 0 && errorCount >= 0 && errors.length > errorCount) {
5166
+ errors.length = errorCount;
5167
+ }
5168
+ }
5169
+ if (advanced) continue;
5170
+ if (recoverAt !== void 0) {
5171
+ const errorCount = ctx._errors?.length ?? -1;
5172
+ const recover = recoverAt.parse(input, cur, probeCtx);
5173
+ const errors = ctx._errors;
5174
+ if (errors !== void 0 && errorCount >= 0 && errors.length > errorCount) {
5175
+ errors.length = errorCount;
5176
+ }
5177
+ if (recover.ok) {
5178
+ if (recover.span.end <= cur) {
5179
+ throw new TypeError("scanTo recoverAt must consume input");
5180
+ }
5181
+ if (recovery < 0) {
5182
+ recovery = cur;
5183
+ recoveryErrorCount = errorCount;
5184
+ }
5185
+ if (firstSentinel >= 0 && (sentinelCount & 1) === 1) {
5186
+ return succeed(recoveredEnd());
5187
+ }
5188
+ cur = recover.span.end;
5189
+ continue;
5190
+ }
5075
5191
  }
5076
- if (!advanced) cur++;
5192
+ cur++;
5077
5193
  }
5194
+ if (recovery >= 0) return succeed(recoveredEnd());
5078
5195
  if (orEOF) {
5079
- if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
5080
- emit(cur);
5081
- return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
5196
+ return succeed(cur);
5082
5197
  }
5083
5198
  const sentDef = sentinel._def;
5084
5199
  const expected = sentDef.tag === "literal" ? [JSON.stringify(sentDef.value)] : ["sentinel"];