parseman 0.51.2 → 0.52.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 (54) hide show
  1. package/dist/analysis/commitment.d.ts.map +1 -1
  2. package/dist/analysis/diagnostics.js +53 -20
  3. package/dist/analysis/diagnostics.js.map +1 -1
  4. package/dist/cli/index.js +53 -20
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/combinators/attempt.d.ts +11 -1
  7. package/dist/combinators/attempt.d.ts.map +1 -1
  8. package/dist/combinators/map.d.ts.map +1 -1
  9. package/dist/combinators/node.d.ts +6 -2
  10. package/dist/combinators/node.d.ts.map +1 -1
  11. package/dist/compiler/token-capability.js +4 -0
  12. package/dist/compiler/token-capability.js.map +1 -1
  13. package/dist/cst/trivia-kinds.d.ts.map +1 -1
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +55 -22
  17. package/dist/index.js.map +1 -1
  18. package/dist/plugin/index.js +55 -22
  19. package/dist/plugin/index.js.map +1 -1
  20. package/dist/spec/index.js +28 -5
  21. package/dist/spec/index.js.map +1 -1
  22. package/dist/table/assemble.d.ts.map +1 -1
  23. package/dist/table/emit-assembly.d.ts.map +1 -1
  24. package/dist/table/encode-baseline.d.ts.map +1 -1
  25. package/dist/table/exec.d.ts.map +1 -1
  26. package/dist/table/index.js +37 -15
  27. package/dist/table/index.js.map +1 -1
  28. package/dist/table/ops.d.ts +7 -5
  29. package/dist/table/ops.d.ts.map +1 -1
  30. package/dist/table/site-labels.d.ts.map +1 -1
  31. package/dist/types.d.ts +8 -1
  32. package/dist/types.d.ts.map +1 -1
  33. package/dist/version.d.ts +1 -1
  34. package/package.json +1 -1
  35. package/src/analysis/commitment.ts +3 -1
  36. package/src/analysis/rebuild.ts +1 -1
  37. package/src/combinators/attempt.ts +26 -3
  38. package/src/combinators/first-set.ts +5 -1
  39. package/src/combinators/map.ts +5 -1
  40. package/src/combinators/node.ts +12 -3
  41. package/src/compiler/ir-serialize.ts +1 -1
  42. package/src/coverage.ts +1 -1
  43. package/src/cst/trivia-kinds.ts +6 -0
  44. package/src/index.ts +1 -0
  45. package/src/plugin/evaluator.ts +1 -1
  46. package/src/table/assemble.ts +22 -8
  47. package/src/table/emit-assembly.ts +8 -3
  48. package/src/table/encode-baseline.ts +5 -1
  49. package/src/table/encode.ts +13 -13
  50. package/src/table/exec.ts +6 -2
  51. package/src/table/ops.ts +7 -5
  52. package/src/table/site-labels.ts +3 -1
  53. package/src/types.ts +8 -1
  54. package/src/version.ts +1 -1
@@ -265,6 +265,10 @@ function firstSetBody(p, seen, resolve3, activeTrivia) {
265
265
  case "node":
266
266
  case "sepBy":
267
267
  case "expect":
268
+ // A transaction accepts exactly what its inner accepts. Its own `_meta` is
269
+ // the inner's construction-time set, which reads `any` when the inner opens
270
+ // with a rule reference — resolve through it like any other wrapper.
271
+ case "attempt":
268
272
  return fs3(d.parser);
269
273
  case "grammar":
270
274
  return firstSetOf(
@@ -1404,6 +1408,10 @@ function peelLabel(p) {
1404
1408
  return null;
1405
1409
  }
1406
1410
  function analyzeLabeledTrivia(trivia2) {
1411
+ if (trivia2._def.tag === "trivia") {
1412
+ const own = trivia2._meta.labeledTriviaSpec;
1413
+ if (own !== void 0) return own;
1414
+ }
1407
1415
  if (trivia2 === labeledTrivia0) return labeledSpec0;
1408
1416
  if (trivia2 === labeledTrivia1) return labeledSpec1;
1409
1417
  if (trivia2 === labeledTrivia2) return labeledSpec2;
@@ -4061,13 +4069,24 @@ function dispatch(selector, ...arms) {
4061
4069
  }
4062
4070
 
4063
4071
  // src/combinators/attempt.ts
4064
- function attempt(parser2) {
4072
+ function containOption(options) {
4073
+ if (options === void 0) return false;
4074
+ for (const key of Object.keys(options)) {
4075
+ if (key !== "contain") throw new TypeError(`attempt(): unknown option ${JSON.stringify(key)}`);
4076
+ }
4077
+ if (options.contain !== void 0 && typeof options.contain !== "boolean") {
4078
+ throw new TypeError("attempt(): `contain` must be a boolean");
4079
+ }
4080
+ return options.contain === true;
4081
+ }
4082
+ function attempt(parser2, options) {
4083
+ const contain = containOption(options);
4065
4084
  const guardable = parser2._meta.firstSet.kind !== "any" && !matchesEmpty(parser2);
4066
4085
  let failExpected;
4067
4086
  return {
4068
4087
  _tag: "attempt",
4069
4088
  _meta: parser2._meta,
4070
- _def: { tag: "attempt", parser: parser2 },
4089
+ _def: contain ? { tag: "attempt", parser: parser2, contain: true } : { tag: "attempt", parser: parser2 },
4071
4090
  parse(input, pos, ctx) {
4072
4091
  if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(parser2, input, pos)) {
4073
4092
  if (failExpected === void 0) {
@@ -4084,7 +4103,7 @@ function attempt(parser2) {
4084
4103
  rollbackCstCapture(ctx, mark);
4085
4104
  if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
4086
4105
  if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
4087
- if (result.committed) return result;
4106
+ if (result.committed && !contain) return result;
4088
4107
  return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
4089
4108
  }
4090
4109
  };
@@ -4939,7 +4958,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
4939
4958
  throw new Error("node() options cannot combine project with unwrap or collapse");
4940
4959
  }
4941
4960
  const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || buildArity !== void 0 || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...buildArity !== void 0 ? { buildArity } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
4942
- const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
4961
+ const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
4943
4962
  const clonesState = build ? buildReadsState(def) : project === void 0;
4944
4963
  const hasOwnFields = parserHasOwnFields(combinator);
4945
4964
  const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
@@ -5053,13 +5072,17 @@ function transform(combinator, fn) {
5053
5072
  };
5054
5073
  }
5055
5074
  function trivia(combinator) {
5056
- const kindLabels = analyzeLabeledTrivia(combinator)?.labels;
5075
+ const labeled = analyzeLabeledTrivia(combinator);
5076
+ const kindLabels = labeled?.labels;
5057
5077
  return {
5058
5078
  _tag: combinator._tag,
5059
5079
  _meta: {
5060
5080
  ...combinator._meta,
5061
5081
  isTrivia: true,
5062
5082
  triviaScanner: fastTriviaScanner(combinator),
5083
+ // Every labeled scan of this trivia reads its spec; the module's four-slot
5084
+ // memo alone thrashes on a grammar with more than four trivia tables.
5085
+ labeledTriviaSpec: labeled,
5063
5086
  ...kindLabels ? { triviaKindLabels: kindLabels } : {}
5064
5087
  },
5065
5088
  _def: { tag: "trivia", parser: combinator },
@@ -5592,10 +5615,12 @@ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve3) {
5592
5615
  case "choice":
5593
5616
  case "sequence":
5594
5617
  return d.parsers.some((x) => mayCommitFailure(x, seen, resolve3));
5618
+ // A contained transaction reports every failure uncommitted.
5619
+ case "attempt":
5620
+ return d.contain !== true && mayCommitFailure(d.parser, seen, resolve3);
5595
5621
  case "many":
5596
5622
  case "oneOrMore":
5597
5623
  case "optional":
5598
- case "attempt":
5599
5624
  case "transform":
5600
5625
  case "label":
5601
5626
  case "field":
@@ -7704,7 +7729,7 @@ var Encoder = class {
7704
7729
  const derivedState = d.build !== void 0 ? buildReadsState(d) : noBuildCaptures;
7705
7730
  const derivedFields = d.build !== void 0 ? buildReadsFields(d) : noBuildCaptures;
7706
7731
  const wantsFields = parserHasOwnFields(d.parser) && (cstOut || derivedFields);
7707
- const flags = (cstOut || d.captureTrivia === true || d.trailingTrivia === true || derivedTrivia ? 4 : 0) | (!cstOut && omitsRaw ? 2 : 0) | (cstOut || derivedState ? 8 : 0) | (wantsFields ? 16 : 0) | (d.collapse === true ? 32 : 0) | (d.unwrap === true ? 64 : 0) | (d.trailingTrivia === true ? 128 : 0) | (d.captureTrivia === true ? 1 : 0);
7732
+ const flags = (cstOut || d.captureTrivia === true || derivedTrivia ? 4 : 0) | (!cstOut && omitsRaw ? 2 : 0) | (cstOut || derivedState ? 8 : 0) | (wantsFields ? 16 : 0) | (d.collapse === true ? 32 : 0) | (d.unwrap === true ? 64 : 0) | (d.trailingTrivia === true ? 128 : 0) | (d.captureTrivia === true ? 1 : 0);
7708
7733
  const body = this.emit(
7709
7734
  this.track ? OP_NODE_TRACK : OP_NODE,
7710
7735
  d.build === void 0 ? -1 : this.fn(d.build, d.buildSrc ?? null),
@@ -7830,7 +7855,7 @@ var Encoder = class {
7830
7855
  // A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
7831
7856
  // lowering was correct only for a choice arm.
7832
7857
  case "attempt": {
7833
- const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
7858
+ const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
7834
7859
  if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
7835
7860
  const fs3 = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : d.parser._meta.firstSet;
7836
7861
  if (fs3.kind === "any" || matchesEmpty(d.parser)) return inner;
@@ -9223,7 +9248,7 @@ function transfer(code, ip, at, hostCst) {
9223
9248
  }
9224
9249
  if (op === OP_NODE || op === OP_NODE_TRACK) {
9225
9250
  const flags = code[ip + 3];
9226
- const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
9251
+ const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && ((flags & ~128) === 2 || flags === 18 || flags === 34);
9227
9252
  if (directChildren) {
9228
9253
  return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
9229
9254
  }
@@ -10427,7 +10452,7 @@ ${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
10427
10452
  const v=${child}(input,pos,ctx)
10428
10453
  if(v!==FAIL)return v
10429
10454
  ${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
10430
- if(ctx._fc===true)return FAIL
10455
+ ${code[ip + 2] === 1 ? "ctx._fc=false" : "if(ctx._fc===true)return FAIL"}
10431
10456
  ctx._fe=pos
10432
10457
  return FAIL
10433
10458
  }`;
@@ -11016,7 +11041,8 @@ return nd
11016
11041
  const unwrap = (flags & 64) !== 0;
11017
11042
  const trailingTrivia = (flags & 128) !== 0;
11018
11043
  const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
11019
- if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
11044
+ const leanFlags = flags & ~128;
11045
+ if (!hostCst && !tracked && build !== void 0 && proj < 0 && (leanFlags === 2 || (flags === 18 || flags === 34))) {
11020
11046
  const fields = flags === 18;
11021
11047
  const collapseChildren = flags === 34;
11022
11048
  const publish = L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? `if(sBuf!==undefined){
@@ -11061,7 +11087,8 @@ ctx._cstTriviaLog=undefined
11061
11087
  ctx.captureTrivia=false
11062
11088
  ctx._fields=${fields ? "[]" : "undefined"}
11063
11089
  const v=${child}(input,pos,ctx)
11064
- const captured=_capturedFlatChildren(flat)
11090
+ ${trailingTrivia && L.tri !== TRI_NONE ? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? "&&ctx.trivia!==undefined" : ""})EC.e=consumeTrivia(input,EC.e,ctx)
11091
+ ` : ""}const captured=_capturedFlatChildren(flat)
11065
11092
  ${fields ? "const fieldMap=buildFieldMap(ctx._fields)\n" : ""}ctx._fields=sFields
11066
11093
  ctx._cstBuf=sBuf
11067
11094
  ctx._cstChildren=sCh
@@ -11681,7 +11708,7 @@ function assemble(t, prog, cfg) {
11681
11708
  const lf = { _tag: "leaf", value, span: { start: s, end: e } };
11682
11709
  pushCstLeaf(ctx, lf);
11683
11710
  }
11684
- function plainBuildNode(child, build) {
11711
+ function plainBuildNode(child, build, trailing) {
11685
11712
  return (input, pos, ctx) => {
11686
11713
  const sCh = ctx._cstChildren;
11687
11714
  const sLv = ctx._cstLeaves;
@@ -11699,6 +11726,7 @@ function assemble(t, prog, cfg) {
11699
11726
  ctx.captureTrivia = false;
11700
11727
  ctx._fields = void 0;
11701
11728
  const value = child(input, pos, ctx);
11729
+ if (trailing && value !== FAIL && ctx.trivia !== void 0) EC.e = consumeTrivia(input, EC.e, ctx);
11702
11730
  const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
11703
11731
  const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
11704
11732
  ctx._fields = savedFields;
@@ -11726,7 +11754,7 @@ function assemble(t, prog, cfg) {
11726
11754
  while (first < children3.length && children3[first] === void 0) first++;
11727
11755
  return first === children3.length ? EMPTY_CH : children3.slice(first);
11728
11756
  }
11729
- function childrenOnlyBuildNode(child, build) {
11757
+ function childrenOnlyBuildNode(child, build, trailing) {
11730
11758
  return (input, pos, ctx) => {
11731
11759
  const sCh = ctx._cstChildren;
11732
11760
  const sLv = ctx._cstLeaves;
@@ -11744,6 +11772,7 @@ function assemble(t, prog, cfg) {
11744
11772
  ctx.captureTrivia = false;
11745
11773
  ctx._fields = void 0;
11746
11774
  const value = child(input, pos, ctx);
11775
+ if (trailing && value !== FAIL && ctx.trivia !== void 0) EC.e = consumeTrivia(input, EC.e, ctx);
11747
11776
  const captured = capturedFlatChildren(kids);
11748
11777
  ctx._fields = savedFields;
11749
11778
  ctx._cstBuf = sBuf;
@@ -12768,6 +12797,7 @@ function assemble(t, prog, cfg) {
12768
12797
  /* ── transaction ─────────────────────────────────────────────────────── */
12769
12798
  case OP_ATTEMPT: {
12770
12799
  const child = link(code[ip + 1]);
12800
+ const contain = code[ip + 2] === 1;
12771
12801
  return (input, pos, ctx) => {
12772
12802
  const need = markCst(ctx);
12773
12803
  const mRaw = MRAW;
@@ -12780,7 +12810,10 @@ function assemble(t, prog, cfg) {
12780
12810
  const v = child(input, pos, ctx);
12781
12811
  if (v !== FAIL) return v;
12782
12812
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12783
- if (committed3(ctx)) return FAIL;
12813
+ if (committed3(ctx)) {
12814
+ if (!contain) return FAIL;
12815
+ ctx._fc = false;
12816
+ }
12784
12817
  ctx._fe = pos;
12785
12818
  return FAIL;
12786
12819
  };
@@ -14231,11 +14264,11 @@ function assemble(t, prog, cfg) {
14231
14264
  const trailingTrivia = (flags & 128) !== 0;
14232
14265
  const build = buildIdx >= 0 ? fns[buildIdx] : void 0;
14233
14266
  if (!hostCst && !tracked) {
14234
- if (build !== void 0 && proj < 0 && flags === 0) {
14235
- return plainBuildNode(child, build);
14267
+ if (build !== void 0 && proj < 0 && (flags & ~128) === 0) {
14268
+ return plainBuildNode(child, build, trailingTrivia);
14236
14269
  }
14237
- if (build !== void 0 && proj < 0 && flags === 2) {
14238
- return childrenOnlyBuildNode(child, build);
14270
+ if (build !== void 0 && proj < 0 && (flags & ~128) === 2) {
14271
+ return childrenOnlyBuildNode(child, build, trailingTrivia);
14239
14272
  }
14240
14273
  if (build !== void 0 && proj < 0 && flags === 18) {
14241
14274
  return childrenOnlyFieldsBuildNode(child, build);
@@ -16954,7 +16987,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
16954
16987
  case "optional":
16955
16988
  return `optional(${kid(def.parser)})`;
16956
16989
  case "attempt":
16957
- return `attempt(${kid(def.parser)})`;
16990
+ return `attempt(${kid(def.parser)}${def.contain === true ? ", { contain: true }" : ""})`;
16958
16991
  // `keepSeparators` is an opt-in expressed at the SEPARATOR, not in the options
16959
16992
  // bag, so it must round-trip as `keepSeparator(sep)` — serializing it as an
16960
16993
  // option would reconstruct a grammar whose call site no longer states its own
@@ -17162,7 +17195,7 @@ function compileRuleMap(ruleMap, opts = {}) {
17162
17195
  }
17163
17196
 
17164
17197
  // src/version.ts
17165
- var PARSEMAN_VERSION = "0.51.2";
17198
+ var PARSEMAN_VERSION = "0.52.0";
17166
17199
 
17167
17200
  // src/compiler/compile-linkable-table.ts
17168
17201
  function isLocal(rule) {
@@ -17611,7 +17644,7 @@ var SUPPORTED = {
17611
17644
  word: (...a) => word(a[0], a[1], a[2]),
17612
17645
  sequence: (...a) => sequence(...a),
17613
17646
  choice: (...a) => choice(...a),
17614
- attempt: (...a) => attempt(a[0]),
17647
+ attempt: (...a) => attempt(a[0], a[1]),
17615
17648
  optional: (...a) => optional(a[0]),
17616
17649
  trivia: (...a) => trivia(a[0]),
17617
17650
  classifiedTrivia: (...a) => classifiedTrivia(