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
package/dist/index.js CHANGED
@@ -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(
@@ -1795,6 +1799,10 @@ function peelLabel(p) {
1795
1799
  return null;
1796
1800
  }
1797
1801
  function analyzeLabeledTrivia(trivia2) {
1802
+ if (trivia2._def.tag === "trivia") {
1803
+ const own = trivia2._meta.labeledTriviaSpec;
1804
+ if (own !== void 0) return own;
1805
+ }
1798
1806
  if (trivia2 === labeledTrivia0) return labeledSpec0;
1799
1807
  if (trivia2 === labeledTrivia1) return labeledSpec1;
1800
1808
  if (trivia2 === labeledTrivia2) return labeledSpec2;
@@ -3541,13 +3549,24 @@ function dispatch(selector, ...arms) {
3541
3549
  }
3542
3550
 
3543
3551
  // src/combinators/attempt.ts
3544
- function attempt(parser2) {
3552
+ function containOption(options) {
3553
+ if (options === void 0) return false;
3554
+ for (const key of Object.keys(options)) {
3555
+ if (key !== "contain") throw new TypeError(`attempt(): unknown option ${JSON.stringify(key)}`);
3556
+ }
3557
+ if (options.contain !== void 0 && typeof options.contain !== "boolean") {
3558
+ throw new TypeError("attempt(): `contain` must be a boolean");
3559
+ }
3560
+ return options.contain === true;
3561
+ }
3562
+ function attempt(parser2, options) {
3563
+ const contain = containOption(options);
3545
3564
  const guardable = parser2._meta.firstSet.kind !== "any" && !matchesEmpty(parser2);
3546
3565
  let failExpected;
3547
3566
  return {
3548
3567
  _tag: "attempt",
3549
3568
  _meta: parser2._meta,
3550
- _def: { tag: "attempt", parser: parser2 },
3569
+ _def: contain ? { tag: "attempt", parser: parser2, contain: true } : { tag: "attempt", parser: parser2 },
3551
3570
  parse(input, pos, ctx) {
3552
3571
  if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(parser2, input, pos)) {
3553
3572
  if (failExpected === void 0) {
@@ -3564,7 +3583,7 @@ function attempt(parser2) {
3564
3583
  rollbackCstCapture(ctx, mark);
3565
3584
  if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
3566
3585
  if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
3567
- if (result.committed) return result;
3586
+ if (result.committed && !contain) return result;
3568
3587
  return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
3569
3588
  }
3570
3589
  };
@@ -4964,7 +4983,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
4964
4983
  throw new Error("node() options cannot combine project with unwrap or collapse");
4965
4984
  }
4966
4985
  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;
4967
- const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
4986
+ const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
4968
4987
  const clonesState = build ? buildReadsState(def) : project === void 0;
4969
4988
  const hasOwnFields = parserHasOwnFields(combinator);
4970
4989
  const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
@@ -5078,13 +5097,17 @@ function transform(combinator, fn) {
5078
5097
  };
5079
5098
  }
5080
5099
  function trivia(combinator) {
5081
- const kindLabels = analyzeLabeledTrivia(combinator)?.labels;
5100
+ const labeled = analyzeLabeledTrivia(combinator);
5101
+ const kindLabels = labeled?.labels;
5082
5102
  return {
5083
5103
  _tag: combinator._tag,
5084
5104
  _meta: {
5085
5105
  ...combinator._meta,
5086
5106
  isTrivia: true,
5087
5107
  triviaScanner: fastTriviaScanner(combinator),
5108
+ // Every labeled scan of this trivia reads its spec; the module's four-slot
5109
+ // memo alone thrashes on a grammar with more than four trivia tables.
5110
+ labeledTriviaSpec: labeled,
5088
5111
  ...kindLabels ? { triviaKindLabels: kindLabels } : {}
5089
5112
  },
5090
5113
  _def: { tag: "trivia", parser: combinator },
@@ -5993,10 +6016,12 @@ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve) {
5993
6016
  case "choice":
5994
6017
  case "sequence":
5995
6018
  return d.parsers.some((x) => mayCommitFailure(x, seen, resolve));
6019
+ // A contained transaction reports every failure uncommitted.
6020
+ case "attempt":
6021
+ return d.contain !== true && mayCommitFailure(d.parser, seen, resolve);
5996
6022
  case "many":
5997
6023
  case "oneOrMore":
5998
6024
  case "optional":
5999
- case "attempt":
6000
6025
  case "transform":
6001
6026
  case "label":
6002
6027
  case "field":
@@ -8105,7 +8130,7 @@ var Encoder = class {
8105
8130
  const derivedState = d.build !== void 0 ? buildReadsState(d) : noBuildCaptures;
8106
8131
  const derivedFields = d.build !== void 0 ? buildReadsFields(d) : noBuildCaptures;
8107
8132
  const wantsFields = parserHasOwnFields(d.parser) && (cstOut || derivedFields);
8108
- 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);
8133
+ 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);
8109
8134
  const body = this.emit(
8110
8135
  this.track ? OP_NODE_TRACK : OP_NODE,
8111
8136
  d.build === void 0 ? -1 : this.fn(d.build, d.buildSrc ?? null),
@@ -8231,7 +8256,7 @@ var Encoder = class {
8231
8256
  // A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
8232
8257
  // lowering was correct only for a choice arm.
8233
8258
  case "attempt": {
8234
- const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
8259
+ const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
8235
8260
  if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
8236
8261
  const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : d.parser._meta.firstSet;
8237
8262
  if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
@@ -9627,7 +9652,7 @@ function transfer(code, ip, at, hostCst) {
9627
9652
  }
9628
9653
  if (op === OP_NODE || op === OP_NODE_TRACK) {
9629
9654
  const flags = code[ip + 3];
9630
- const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
9655
+ const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && ((flags & ~128) === 2 || flags === 18 || flags === 34);
9631
9656
  if (directChildren) {
9632
9657
  return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
9633
9658
  }
@@ -10831,7 +10856,7 @@ ${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
10831
10856
  const v=${child}(input,pos,ctx)
10832
10857
  if(v!==FAIL)return v
10833
10858
  ${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
10834
- if(ctx._fc===true)return FAIL
10859
+ ${code[ip + 2] === 1 ? "ctx._fc=false" : "if(ctx._fc===true)return FAIL"}
10835
10860
  ctx._fe=pos
10836
10861
  return FAIL
10837
10862
  }`;
@@ -11420,7 +11445,8 @@ return nd
11420
11445
  const unwrap = (flags & 64) !== 0;
11421
11446
  const trailingTrivia = (flags & 128) !== 0;
11422
11447
  const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
11423
- if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
11448
+ const leanFlags = flags & ~128;
11449
+ if (!hostCst && !tracked && build !== void 0 && proj < 0 && (leanFlags === 2 || (flags === 18 || flags === 34))) {
11424
11450
  const fields = flags === 18;
11425
11451
  const collapseChildren = flags === 34;
11426
11452
  const publish = L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? `if(sBuf!==undefined){
@@ -11465,7 +11491,8 @@ ctx._cstTriviaLog=undefined
11465
11491
  ctx.captureTrivia=false
11466
11492
  ctx._fields=${fields ? "[]" : "undefined"}
11467
11493
  const v=${child}(input,pos,ctx)
11468
- const captured=_capturedFlatChildren(flat)
11494
+ ${trailingTrivia && L.tri !== TRI_NONE ? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? "&&ctx.trivia!==undefined" : ""})EC.e=consumeTrivia(input,EC.e,ctx)
11495
+ ` : ""}const captured=_capturedFlatChildren(flat)
11469
11496
  ${fields ? "const fieldMap=buildFieldMap(ctx._fields)\n" : ""}ctx._fields=sFields
11470
11497
  ctx._cstBuf=sBuf
11471
11498
  ctx._cstChildren=sCh
@@ -12098,7 +12125,7 @@ function assemble(t, prog, cfg) {
12098
12125
  const lf = { _tag: "leaf", value, span: { start: s, end: e } };
12099
12126
  pushCstLeaf(ctx, lf);
12100
12127
  }
12101
- function plainBuildNode(child, build) {
12128
+ function plainBuildNode(child, build, trailing) {
12102
12129
  return (input, pos, ctx) => {
12103
12130
  const sCh = ctx._cstChildren;
12104
12131
  const sLv = ctx._cstLeaves;
@@ -12116,6 +12143,7 @@ function assemble(t, prog, cfg) {
12116
12143
  ctx.captureTrivia = false;
12117
12144
  ctx._fields = void 0;
12118
12145
  const value = child(input, pos, ctx);
12146
+ if (trailing && value !== FAIL && ctx.trivia !== void 0) EC.e = consumeTrivia(input, EC.e, ctx);
12119
12147
  const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
12120
12148
  const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
12121
12149
  ctx._fields = savedFields;
@@ -12143,7 +12171,7 @@ function assemble(t, prog, cfg) {
12143
12171
  while (first < children2.length && children2[first] === void 0) first++;
12144
12172
  return first === children2.length ? EMPTY_CH : children2.slice(first);
12145
12173
  }
12146
- function childrenOnlyBuildNode(child, build) {
12174
+ function childrenOnlyBuildNode(child, build, trailing) {
12147
12175
  return (input, pos, ctx) => {
12148
12176
  const sCh = ctx._cstChildren;
12149
12177
  const sLv = ctx._cstLeaves;
@@ -12161,6 +12189,7 @@ function assemble(t, prog, cfg) {
12161
12189
  ctx.captureTrivia = false;
12162
12190
  ctx._fields = void 0;
12163
12191
  const value = child(input, pos, ctx);
12192
+ if (trailing && value !== FAIL && ctx.trivia !== void 0) EC.e = consumeTrivia(input, EC.e, ctx);
12164
12193
  const captured = capturedFlatChildren(kids);
12165
12194
  ctx._fields = savedFields;
12166
12195
  ctx._cstBuf = sBuf;
@@ -13185,6 +13214,7 @@ function assemble(t, prog, cfg) {
13185
13214
  /* ── transaction ─────────────────────────────────────────────────────── */
13186
13215
  case OP_ATTEMPT: {
13187
13216
  const child = link(code[ip + 1]);
13217
+ const contain = code[ip + 2] === 1;
13188
13218
  return (input, pos, ctx) => {
13189
13219
  const need = markCst(ctx);
13190
13220
  const mRaw = MRAW;
@@ -13197,7 +13227,10 @@ function assemble(t, prog, cfg) {
13197
13227
  const v = child(input, pos, ctx);
13198
13228
  if (v !== FAIL) return v;
13199
13229
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
13200
- if (committed3(ctx)) return FAIL;
13230
+ if (committed3(ctx)) {
13231
+ if (!contain) return FAIL;
13232
+ ctx._fc = false;
13233
+ }
13201
13234
  ctx._fe = pos;
13202
13235
  return FAIL;
13203
13236
  };
@@ -14648,11 +14681,11 @@ function assemble(t, prog, cfg) {
14648
14681
  const trailingTrivia = (flags & 128) !== 0;
14649
14682
  const build = buildIdx >= 0 ? fns[buildIdx] : void 0;
14650
14683
  if (!hostCst && !tracked) {
14651
- if (build !== void 0 && proj < 0 && flags === 0) {
14652
- return plainBuildNode(child, build);
14684
+ if (build !== void 0 && proj < 0 && (flags & ~128) === 0) {
14685
+ return plainBuildNode(child, build, trailingTrivia);
14653
14686
  }
14654
- if (build !== void 0 && proj < 0 && flags === 2) {
14655
- return childrenOnlyBuildNode(child, build);
14687
+ if (build !== void 0 && proj < 0 && (flags & ~128) === 2) {
14688
+ return childrenOnlyBuildNode(child, build, trailingTrivia);
14656
14689
  }
14657
14690
  if (build !== void 0 && proj < 0 && flags === 18) {
14658
14691
  return childrenOnlyFieldsBuildNode(child, build);
@@ -17371,7 +17404,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
17371
17404
  case "optional":
17372
17405
  return `optional(${kid(def.parser)})`;
17373
17406
  case "attempt":
17374
- return `attempt(${kid(def.parser)})`;
17407
+ return `attempt(${kid(def.parser)}${def.contain === true ? ", { contain: true }" : ""})`;
17375
17408
  // `keepSeparators` is an opt-in expressed at the SEPARATOR, not in the options
17376
17409
  // bag, so it must round-trip as `keepSeparator(sep)` — serializing it as an
17377
17410
  // option would reconstruct a grammar whose call site no longer states its own
@@ -17579,7 +17612,7 @@ function compileRuleMap(ruleMap, opts = {}) {
17579
17612
  }
17580
17613
 
17581
17614
  // src/version.ts
17582
- var PARSEMAN_VERSION = "0.51.2";
17615
+ var PARSEMAN_VERSION = "0.52.0";
17583
17616
 
17584
17617
  // src/compiler/compile-linkable-table.ts
17585
17618
  function isLocal(rule) {
@@ -20272,7 +20305,7 @@ function coverageEntry(entry, collector, maps, trace) {
20272
20305
  case "optional":
20273
20306
  return optional(build(def.parser));
20274
20307
  case "attempt": {
20275
- const base2 = attempt(build(def.parser));
20308
+ const base2 = attempt(build(def.parser), def.contain === true ? { contain: true } : void 0);
20276
20309
  const id = maps.attempts.get(parser2);
20277
20310
  return id === void 0 ? base2 : {
20278
20311
  ...base2,