parseman 0.51.1 → 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 (64) hide show
  1. package/dist/analysis/commitment.d.ts.map +1 -1
  2. package/dist/analysis/diagnostics.js +101 -35
  3. package/dist/analysis/diagnostics.js.map +1 -1
  4. package/dist/cli/index.js +103 -37
  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/combinators/token.d.ts +8 -8
  12. package/dist/combinators/token.d.ts.map +1 -1
  13. package/dist/compiler/token-capability.js +4 -0
  14. package/dist/compiler/token-capability.js.map +1 -1
  15. package/dist/coverage.d.ts.map +1 -1
  16. package/dist/cst/trivia-kinds.d.ts.map +1 -1
  17. package/dist/index.d.ts +2 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +107 -40
  20. package/dist/index.js.map +1 -1
  21. package/dist/plugin/evaluator.d.ts.map +1 -1
  22. package/dist/plugin/index.js +107 -41
  23. package/dist/plugin/index.js.map +1 -1
  24. package/dist/spec/index.js +55 -10
  25. package/dist/spec/index.js.map +1 -1
  26. package/dist/table/assemble.d.ts.map +1 -1
  27. package/dist/table/emit-assembly.d.ts.map +1 -1
  28. package/dist/table/encode-baseline.d.ts.map +1 -1
  29. package/dist/table/exec-baseline.d.ts.map +1 -1
  30. package/dist/table/exec.d.ts.map +1 -1
  31. package/dist/table/index.js +404 -371
  32. package/dist/table/index.js.map +2 -2
  33. package/dist/table/ops.d.ts +9 -5
  34. package/dist/table/ops.d.ts.map +1 -1
  35. package/dist/table/site-labels.d.ts.map +1 -1
  36. package/dist/types.d.ts +9 -1
  37. package/dist/types.d.ts.map +1 -1
  38. package/dist/version.d.ts +1 -1
  39. package/package.json +1 -1
  40. package/src/analysis/commitment.ts +3 -1
  41. package/src/analysis/duplication.ts +1 -1
  42. package/src/analysis/rebuild.ts +3 -3
  43. package/src/combinators/attempt.ts +26 -3
  44. package/src/combinators/first-set.ts +5 -1
  45. package/src/combinators/map.ts +5 -1
  46. package/src/combinators/node.ts +12 -3
  47. package/src/combinators/token.ts +46 -3
  48. package/src/compiler/ir-serialize.ts +5 -5
  49. package/src/coverage.ts +3 -4
  50. package/src/cst/trivia-kinds.ts +6 -0
  51. package/src/index.ts +2 -1
  52. package/src/plugin/evaluator.ts +8 -5
  53. package/src/table/assemble.ts +30 -11
  54. package/src/table/child-slots.ts +2 -2
  55. package/src/table/emit-assembly.ts +13 -6
  56. package/src/table/encode-baseline.ts +8 -3
  57. package/src/table/encode.ts +16 -16
  58. package/src/table/exec-baseline.ts +30 -4
  59. package/src/table/exec.ts +14 -5
  60. package/src/table/ops.ts +10 -6
  61. package/src/table/scalar-terminal.ts +5 -5
  62. package/src/table/site-labels.ts +5 -3
  63. package/src/types.ts +9 -2
  64. package/src/version.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"commitment.d.ts","sourceRoot":"","sources":["../../src/analysis/commitment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAI9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAqCnG;AAkCD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAiC1G;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,EAAE,YAAY,UAAO,GAAG,OAAO,CAwGvI;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAkDxG;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAgCtG;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAqC7G;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAC9B,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EACtB,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,EAC1C,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CA6CT;AAwCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAC7D;IAAE,iBAAiB,EAAE,OAAO,CAAC;IAAC,iBAAiB,EAAE,OAAO,CAAA;CAAE,CAwB5D"}
1
+ {"version":3,"file":"commitment.d.ts","sourceRoot":"","sources":["../../src/analysis/commitment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAI9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAqCnG;AAkCD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAiC1G;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,EAAE,YAAY,UAAO,GAAG,OAAO,CAwGvI;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAkDxG;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAgCtG;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAqC7G;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAC9B,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EACtB,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,EAC1C,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CA+CT;AAwCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAC7D;IAAE,iBAAiB,EAAE,OAAO,CAAC;IAAC,iBAAiB,EAAE,OAAO,CAAA;CAAE,CAwB5D"}
@@ -257,6 +257,10 @@ function firstSetBody(p, seen, resolve, activeTrivia) {
257
257
  case "node":
258
258
  case "sepBy":
259
259
  case "expect":
260
+ // A transaction accepts exactly what its inner accepts. Its own `_meta` is
261
+ // the inner's construction-time set, which reads `any` when the inner opens
262
+ // with a rule reference — resolve through it like any other wrapper.
263
+ case "attempt":
260
264
  return fs(d.parser);
261
265
  case "grammar":
262
266
  return firstSetOf(
@@ -1291,6 +1295,10 @@ function peelLabel(p) {
1291
1295
  return null;
1292
1296
  }
1293
1297
  function analyzeLabeledTrivia(trivia2) {
1298
+ if (trivia2._def.tag === "trivia") {
1299
+ const own = trivia2._meta.labeledTriviaSpec;
1300
+ if (own !== void 0) return own;
1301
+ }
1294
1302
  if (trivia2 === labeledTrivia0) return labeledSpec0;
1295
1303
  if (trivia2 === labeledTrivia1) return labeledSpec1;
1296
1304
  if (trivia2 === labeledTrivia2) return labeledSpec2;
@@ -3254,10 +3262,12 @@ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve) {
3254
3262
  case "choice":
3255
3263
  case "sequence":
3256
3264
  return d.parsers.some((x) => mayCommitFailure(x, seen, resolve));
3265
+ // A contained transaction reports every failure uncommitted.
3266
+ case "attempt":
3267
+ return d.contain !== true && mayCommitFailure(d.parser, seen, resolve);
3257
3268
  case "many":
3258
3269
  case "oneOrMore":
3259
3270
  case "optional":
3260
- case "attempt":
3261
3271
  case "transform":
3262
3272
  case "label":
3263
3273
  case "field":
@@ -4253,6 +4263,7 @@ var OP_COV = 40;
4253
4263
  var OP_SCOPE_PLAIN = 41;
4254
4264
  var OP_LEX_BODY = 42;
4255
4265
  var OP_LEX_PROGRAM = 43;
4266
+ var OP_SOURCE_LEAF = 44;
4256
4267
  var OP_DISPATCH = 25;
4257
4268
  var OP_ROUTED = 26;
4258
4269
  var OP_NAMES = {
@@ -4271,6 +4282,7 @@ var OP_NAMES = {
4271
4282
  [OP_NOT]: "NOT",
4272
4283
  [OP_PEEK]: "PEEK",
4273
4284
  [OP_LEAF]: "LEAF",
4285
+ [OP_SOURCE_LEAF]: "SOURCE_LEAF",
4274
4286
  [OP_EMPTY]: "EMPTY",
4275
4287
  [OP_LIT_TRACK]: "LIT_TRACK",
4276
4288
  [OP_RX_TRACK]: "RX_TRACK",
@@ -4426,7 +4438,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
4426
4438
  throw new Error("node() options cannot combine project with unwrap or collapse");
4427
4439
  }
4428
4440
  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;
4429
- const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
4441
+ const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
4430
4442
  const clonesState = build ? buildReadsState(def) : project === void 0;
4431
4443
  const hasOwnFields = parserHasOwnFields(combinator);
4432
4444
  const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
@@ -5316,13 +5328,17 @@ function transform(combinator, fn) {
5316
5328
  };
5317
5329
  }
5318
5330
  function trivia(combinator) {
5319
- const kindLabels = analyzeLabeledTrivia(combinator)?.labels;
5331
+ const labeled = analyzeLabeledTrivia(combinator);
5332
+ const kindLabels = labeled?.labels;
5320
5333
  return {
5321
5334
  _tag: combinator._tag,
5322
5335
  _meta: {
5323
5336
  ...combinator._meta,
5324
5337
  isTrivia: true,
5325
5338
  triviaScanner: fastTriviaScanner(combinator),
5339
+ // Every labeled scan of this trivia reads its spec; the module's four-slot
5340
+ // memo alone thrashes on a grammar with more than four trivia tables.
5341
+ labeledTriviaSpec: labeled,
5326
5342
  ...kindLabels ? { triviaKindLabels: kindLabels } : {}
5327
5343
  },
5328
5344
  _def: { tag: "trivia", parser: combinator },
@@ -7040,7 +7056,7 @@ var Encoder = class {
7040
7056
  }
7041
7057
  case "leaf": {
7042
7058
  const child = this.node(d.parser).ip;
7043
- return this.emit(OP_LEAF, this.fn(d.fn, d.fnSrc ?? null), child);
7059
+ return this.emit(d.cstValue === "source" ? OP_SOURCE_LEAF : OP_LEAF, this.fn(d.fn, d.fnSrc ?? null), child);
7044
7060
  }
7045
7061
  case "node": {
7046
7062
  if (d.type === void 0) missingInferredType();
@@ -7052,7 +7068,7 @@ var Encoder = class {
7052
7068
  const derivedState = d.build !== void 0 ? buildReadsState(d) : noBuildCaptures;
7053
7069
  const derivedFields = d.build !== void 0 ? buildReadsFields(d) : noBuildCaptures;
7054
7070
  const wantsFields = parserHasOwnFields(d.parser) && (cstOut || derivedFields);
7055
- 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);
7071
+ 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);
7056
7072
  const body = this.emit(
7057
7073
  this.track ? OP_NODE_TRACK : OP_NODE,
7058
7074
  d.build === void 0 ? -1 : this.fn(d.build, d.buildSrc ?? null),
@@ -7178,7 +7194,7 @@ var Encoder = class {
7178
7194
  // A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
7179
7195
  // lowering was correct only for a choice arm.
7180
7196
  case "attempt": {
7181
- const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
7197
+ const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
7182
7198
  if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
7183
7199
  const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : d.parser._meta.firstSet;
7184
7200
  if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
@@ -7265,6 +7281,7 @@ var Encoder = class {
7265
7281
  case OP_WITHCTX:
7266
7282
  case OP_XFORM:
7267
7283
  case OP_LEAF:
7284
+ case OP_SOURCE_LEAF:
7268
7285
  case OP_NODE:
7269
7286
  case OP_NODE_TRACK:
7270
7287
  return [ip + 2];
@@ -8474,6 +8491,7 @@ function childSlots(code, ip, out) {
8474
8491
  case OP_NODE_TRACK:
8475
8492
  case OP_FIELD:
8476
8493
  case OP_LEAF:
8494
+ case OP_SOURCE_LEAF:
8477
8495
  case OP_ARMGATE:
8478
8496
  out.push(code[ip + 2]);
8479
8497
  return true;
@@ -8569,7 +8587,7 @@ function transfer(code, ip, at, hostCst) {
8569
8587
  }
8570
8588
  if (op === OP_NODE || op === OP_NODE_TRACK) {
8571
8589
  const flags = code[ip + 3];
8572
- const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
8590
+ const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && ((flags & ~128) === 2 || flags === 18 || flags === 34);
8573
8591
  if (directChildren) {
8574
8592
  return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
8575
8593
  }
@@ -8582,7 +8600,7 @@ function transfer(code, ip, at, hostCst) {
8582
8600
  if (at.tri === TRI_NONE && !at.buf) return at;
8583
8601
  return { tri: TRI_NONE, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
8584
8602
  }
8585
- if (op === OP_LEAF) {
8603
+ if (op === OP_LEAF || op === OP_SOURCE_LEAF) {
8586
8604
  if (!at.buf) return at;
8587
8605
  return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
8588
8606
  }
@@ -8669,7 +8687,7 @@ function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, th
8669
8687
  depth++;
8670
8688
  continue;
8671
8689
  }
8672
- if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
8690
+ if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || (op === OP_LEAF || op === OP_SOURCE_LEAF)) {
8673
8691
  at = code[at + 2];
8674
8692
  depth++;
8675
8693
  continue;
@@ -8702,7 +8720,7 @@ function leadingScalarSequence(code, ip) {
8702
8720
  at2 = code[at2 + 1];
8703
8721
  continue;
8704
8722
  }
8705
- if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
8723
+ if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || (op === OP_LEAF || op === OP_SOURCE_LEAF)) {
8706
8724
  at2 = code[at2 + 2];
8707
8725
  continue;
8708
8726
  }
@@ -8735,7 +8753,7 @@ function leadingScalarSequence(code, ip) {
8735
8753
  at = code[at + 2];
8736
8754
  continue;
8737
8755
  }
8738
- if (op === OP_GATE || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
8756
+ if (op === OP_GATE || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || (op === OP_LEAF || op === OP_SOURCE_LEAF)) {
8739
8757
  at = code[at + 2];
8740
8758
  continue;
8741
8759
  }
@@ -8765,7 +8783,7 @@ function leadingLiteralFamily(code, constants, ip, minDepth = 2, limit = 4) {
8765
8783
  if (op === OP_RULE || op === OP_LABEL || op === OP_TOKEN || op === OP_ATTEMPT || op === OP_PEEK) {
8766
8784
  return walk(code[at + 1], depth + 1);
8767
8785
  }
8768
- if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
8786
+ if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || (op === OP_LEAF || op === OP_SOURCE_LEAF)) {
8769
8787
  return walk(code[at + 2], depth + 1);
8770
8788
  }
8771
8789
  if (op === OP_SEQ || op === OP_SEQV) {
@@ -9651,8 +9669,10 @@ ${rootCap ? "ctx._rootTriviaCapture=sR\n" : ""}return v
9651
9669
  }
9652
9670
  /* ── boundaries ──────────────────────────────────────────────────────── */
9653
9671
  case OP_TOKEN:
9654
- case OP_LEAF: {
9672
+ case OP_LEAF:
9673
+ case OP_SOURCE_LEAF: {
9655
9674
  const isToken = op === OP_TOKEN;
9675
+ const capturesSource = isToken || op === OP_SOURCE_LEAF && hostCst;
9656
9676
  const fn = isToken ? void 0 : fnRef(code[ip + 1]);
9657
9677
  const child = link(isToken ? code[ip + 1] : code[ip + 2]);
9658
9678
  const wasCap = L.buf ? "true" : "(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)";
@@ -9685,7 +9705,7 @@ ctx._triviaLog=sOtl
9685
9705
  if(v===FAIL)return FAIL
9686
9706
  const e=EC.e
9687
9707
  const out=${isToken ? "input.slice(pos,e)" : `${fn}(v,{start:pos,end:e})`}
9688
- if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:out,span:{start:pos,end:e}})
9708
+ if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:${capturesSource ? "input.slice(pos,e)" : "out"},span:{start:pos,end:e}})
9689
9709
  EC.e=e
9690
9710
  return out
9691
9711
  }`;
@@ -9771,7 +9791,7 @@ ${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
9771
9791
  const v=${child}(input,pos,ctx)
9772
9792
  if(v!==FAIL)return v
9773
9793
  ${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
9774
- if(ctx._fc===true)return FAIL
9794
+ ${code[ip + 2] === 1 ? "ctx._fc=false" : "if(ctx._fc===true)return FAIL"}
9775
9795
  ctx._fe=pos
9776
9796
  return FAIL
9777
9797
  }`;
@@ -10360,7 +10380,8 @@ return nd
10360
10380
  const unwrap = (flags & 64) !== 0;
10361
10381
  const trailingTrivia = (flags & 128) !== 0;
10362
10382
  const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
10363
- if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
10383
+ const leanFlags = flags & ~128;
10384
+ if (!hostCst && !tracked && build !== void 0 && proj < 0 && (leanFlags === 2 || (flags === 18 || flags === 34))) {
10364
10385
  const fields = flags === 18;
10365
10386
  const collapseChildren = flags === 34;
10366
10387
  const publish = L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? `if(sBuf!==undefined){
@@ -10405,7 +10426,8 @@ ctx._cstTriviaLog=undefined
10405
10426
  ctx.captureTrivia=false
10406
10427
  ctx._fields=${fields ? "[]" : "undefined"}
10407
10428
  const v=${child}(input,pos,ctx)
10408
- const captured=_capturedFlatChildren(flat)
10429
+ ${trailingTrivia && L.tri !== TRI_NONE ? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? "&&ctx.trivia!==undefined" : ""})EC.e=consumeTrivia(input,EC.e,ctx)
10430
+ ` : ""}const captured=_capturedFlatChildren(flat)
10409
10431
  ${fields ? "const fieldMap=buildFieldMap(ctx._fields)\n" : ""}ctx._fields=sFields
10410
10432
  ctx._cstBuf=sBuf
10411
10433
  ctx._cstChildren=sCh
@@ -10836,6 +10858,12 @@ function ref() {
10836
10858
  }
10837
10859
 
10838
10860
  // src/combinators/token.ts
10861
+ function semanticLeafValue(_ctx, _input, _start, _end, value) {
10862
+ return value;
10863
+ }
10864
+ function sourceLeafValue(ctx, input, start, end, value) {
10865
+ return cstOutputHost(ctx.build) ? input.slice(start, end) : value;
10866
+ }
10839
10867
  function token(root) {
10840
10868
  const meta = {
10841
10869
  firstSet: root._meta.firstSet,
@@ -10888,7 +10916,8 @@ function token(root) {
10888
10916
  }
10889
10917
  };
10890
10918
  }
10891
- function leaf(root, fn) {
10919
+ function makeLeaf(root, fn, sourceCstValue) {
10920
+ const cstValue = sourceCstValue ? sourceLeafValue : semanticLeafValue;
10892
10921
  const meta = {
10893
10922
  firstSet: root._meta.firstSet,
10894
10923
  canMatchNewline: root._meta.canMatchNewline,
@@ -10897,7 +10926,12 @@ function leaf(root, fn) {
10897
10926
  return {
10898
10927
  _tag: "leaf",
10899
10928
  _meta: meta,
10900
- _def: { tag: "leaf", parser: root, fn },
10929
+ _def: {
10930
+ tag: "leaf",
10931
+ parser: root,
10932
+ fn,
10933
+ ...sourceCstValue ? { cstValue: "source" } : {}
10934
+ },
10901
10935
  parse(input, pos, ctx) {
10902
10936
  const savedBuf = ctx._cstBuf;
10903
10937
  const savedChildren = ctx._cstChildren;
@@ -10925,11 +10959,21 @@ function leaf(root, fn) {
10925
10959
  }
10926
10960
  if (!result.ok) return result;
10927
10961
  const value = fn(result.value, result.span);
10928
- if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span: result.span });
10962
+ if (wasCapturing) pushCstLeaf(ctx, {
10963
+ _tag: "leaf",
10964
+ value: cstValue(ctx, input, pos, result.span.end, value),
10965
+ span: result.span
10966
+ });
10929
10967
  return { ok: true, value, span: result.span };
10930
10968
  }
10931
10969
  };
10932
10970
  }
10971
+ function leaf(root, fn) {
10972
+ return makeLeaf(root, fn, false);
10973
+ }
10974
+ function sourceLeaf(root, fn) {
10975
+ return makeLeaf(root, fn, true);
10976
+ }
10933
10977
 
10934
10978
  // src/combinators/scanTo.ts
10935
10979
  function resolveScanSkip(explicitSkip, raw, ctx) {
@@ -11400,7 +11444,7 @@ function assemble(t2, prog, cfg) {
11400
11444
  const lf = { _tag: "leaf", value, span: { start: s, end: e } };
11401
11445
  pushCstLeaf(ctx, lf);
11402
11446
  }
11403
- function plainBuildNode(child, build) {
11447
+ function plainBuildNode(child, build, trailing) {
11404
11448
  return (input, pos, ctx) => {
11405
11449
  const sCh = ctx._cstChildren;
11406
11450
  const sLv = ctx._cstLeaves;
@@ -11418,6 +11462,7 @@ function assemble(t2, prog, cfg) {
11418
11462
  ctx.captureTrivia = false;
11419
11463
  ctx._fields = void 0;
11420
11464
  const value = child(input, pos, ctx);
11465
+ if (trailing && value !== FAIL && ctx.trivia !== void 0) EC.e = consumeTrivia(input, EC.e, ctx);
11421
11466
  const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
11422
11467
  const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
11423
11468
  ctx._fields = savedFields;
@@ -11445,7 +11490,7 @@ function assemble(t2, prog, cfg) {
11445
11490
  while (first < children2.length && children2[first] === void 0) first++;
11446
11491
  return first === children2.length ? EMPTY_CH : children2.slice(first);
11447
11492
  }
11448
- function childrenOnlyBuildNode(child, build) {
11493
+ function childrenOnlyBuildNode(child, build, trailing) {
11449
11494
  return (input, pos, ctx) => {
11450
11495
  const sCh = ctx._cstChildren;
11451
11496
  const sLv = ctx._cstLeaves;
@@ -11463,6 +11508,7 @@ function assemble(t2, prog, cfg) {
11463
11508
  ctx.captureTrivia = false;
11464
11509
  ctx._fields = void 0;
11465
11510
  const value = child(input, pos, ctx);
11511
+ if (trailing && value !== FAIL && ctx.trivia !== void 0) EC.e = consumeTrivia(input, EC.e, ctx);
11466
11512
  const captured = capturedFlatChildren(kids);
11467
11513
  ctx._fields = savedFields;
11468
11514
  ctx._cstBuf = sBuf;
@@ -12487,6 +12533,7 @@ function assemble(t2, prog, cfg) {
12487
12533
  /* ── transaction ─────────────────────────────────────────────────────── */
12488
12534
  case OP_ATTEMPT: {
12489
12535
  const child = link(code[ip + 1]);
12536
+ const contain = code[ip + 2] === 1;
12490
12537
  return (input, pos, ctx) => {
12491
12538
  const need = markCst(ctx);
12492
12539
  const mRaw = MRAW;
@@ -12499,7 +12546,10 @@ function assemble(t2, prog, cfg) {
12499
12546
  const v = child(input, pos, ctx);
12500
12547
  if (v !== FAIL) return v;
12501
12548
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12502
- if (committed3(ctx)) return FAIL;
12549
+ if (committed3(ctx)) {
12550
+ if (!contain) return FAIL;
12551
+ ctx._fc = false;
12552
+ }
12503
12553
  ctx._fe = pos;
12504
12554
  return FAIL;
12505
12555
  };
@@ -12717,7 +12767,8 @@ function assemble(t2, prog, cfg) {
12717
12767
  return value;
12718
12768
  };
12719
12769
  }
12720
- case OP_LEAF: {
12770
+ case OP_LEAF:
12771
+ case OP_SOURCE_LEAF: {
12721
12772
  const fn = fns[code[ip + 1]];
12722
12773
  const child = link(code[ip + 2]);
12723
12774
  return (input, pos, ctx) => {
@@ -12745,7 +12796,11 @@ function assemble(t2, prog, cfg) {
12745
12796
  if (v === FAIL) return FAIL;
12746
12797
  const end = EC.e;
12747
12798
  const out = fn(v, { start: pos, end });
12748
- if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value: out, span: { start: pos, end } });
12799
+ if (wasCapturing) pushCstLeaf(ctx, {
12800
+ _tag: "leaf",
12801
+ value: op === OP_SOURCE_LEAF && hostCst ? input.slice(pos, end) : out,
12802
+ span: { start: pos, end }
12803
+ });
12749
12804
  EC.e = end;
12750
12805
  return out;
12751
12806
  };
@@ -13945,11 +14000,11 @@ function assemble(t2, prog, cfg) {
13945
14000
  const trailingTrivia = (flags & 128) !== 0;
13946
14001
  const build = buildIdx >= 0 ? fns[buildIdx] : void 0;
13947
14002
  if (!hostCst && !tracked) {
13948
- if (build !== void 0 && proj < 0 && flags === 0) {
13949
- return plainBuildNode(child, build);
14003
+ if (build !== void 0 && proj < 0 && (flags & ~128) === 0) {
14004
+ return plainBuildNode(child, build, trailingTrivia);
13950
14005
  }
13951
- if (build !== void 0 && proj < 0 && flags === 2) {
13952
- return childrenOnlyBuildNode(child, build);
14006
+ if (build !== void 0 && proj < 0 && (flags & ~128) === 2) {
14007
+ return childrenOnlyBuildNode(child, build, trailingTrivia);
13953
14008
  }
13954
14009
  if (build !== void 0 && proj < 0 && flags === 18) {
13955
14010
  return childrenOnlyFieldsBuildNode(child, build);
@@ -14775,7 +14830,7 @@ function payloadKey(p, d) {
14775
14830
  case "transform":
14776
14831
  return `transform\0${fnKey(d.fnSrc, d.fn)}\0${d.recognitionOnly === true}`;
14777
14832
  case "leaf":
14778
- return `leaf\0${fnKey(d.fnSrc, d.fn)}`;
14833
+ return `leaf\0${d.cstValue ?? "value"}\0${fnKey(d.fnSrc, d.fn)}`;
14779
14834
  case "many":
14780
14835
  case "oneOrMore":
14781
14836
  return `${d.tag}\0${d.min}\0${d.max ?? ""}`;
@@ -16339,13 +16394,24 @@ function digestValue(value, prefix = "", options) {
16339
16394
  }
16340
16395
 
16341
16396
  // src/combinators/attempt.ts
16342
- function attempt(parser2) {
16397
+ function containOption(options) {
16398
+ if (options === void 0) return false;
16399
+ for (const key of Object.keys(options)) {
16400
+ if (key !== "contain") throw new TypeError(`attempt(): unknown option ${JSON.stringify(key)}`);
16401
+ }
16402
+ if (options.contain !== void 0 && typeof options.contain !== "boolean") {
16403
+ throw new TypeError("attempt(): `contain` must be a boolean");
16404
+ }
16405
+ return options.contain === true;
16406
+ }
16407
+ function attempt(parser2, options) {
16408
+ const contain = containOption(options);
16343
16409
  const guardable = parser2._meta.firstSet.kind !== "any" && !matchesEmpty(parser2);
16344
16410
  let failExpected;
16345
16411
  return {
16346
16412
  _tag: "attempt",
16347
16413
  _meta: parser2._meta,
16348
- _def: { tag: "attempt", parser: parser2 },
16414
+ _def: contain ? { tag: "attempt", parser: parser2, contain: true } : { tag: "attempt", parser: parser2 },
16349
16415
  parse(input, pos, ctx) {
16350
16416
  if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(parser2, input, pos)) {
16351
16417
  if (failExpected === void 0) {
@@ -16362,7 +16428,7 @@ function attempt(parser2) {
16362
16428
  rollbackCstCapture(ctx, mark);
16363
16429
  if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
16364
16430
  if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
16365
- if (result.committed) return result;
16431
+ if (result.committed && !contain) return result;
16366
16432
  return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
16367
16433
  }
16368
16434
  };
@@ -16529,7 +16595,7 @@ function rebuildCombinator(root, replacements) {
16529
16595
  out = d.polarity === "adjacent" ? adjacent() : d.kinds === void 0 ? notAdjacent() : notAdjacent({ kinds: d.kinds });
16530
16596
  break;
16531
16597
  case "attempt":
16532
- out = attempt(one(d.parser));
16598
+ out = attempt(one(d.parser), d.contain === true ? { contain: true } : void 0);
16533
16599
  break;
16534
16600
  case "not":
16535
16601
  out = not(one(d.parser));
@@ -16566,7 +16632,7 @@ function rebuildCombinator(root, replacements) {
16566
16632
  out = token(one(d.parser));
16567
16633
  break;
16568
16634
  case "leaf":
16569
- out = leaf(one(d.parser), d.fn);
16635
+ out = d.cstValue === "source" ? sourceLeaf(one(d.parser), d.fn) : leaf(one(d.parser), d.fn);
16570
16636
  break;
16571
16637
  // A LABELLED expect reproduces `d.expected` exactly (`expect` sets it to `[label]`).
16572
16638
  // An unlabelled one RE-DERIVES it from the rebuilt inner parser, so it can differ