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/cli/index.js CHANGED
@@ -265,6 +265,10 @@ function firstSetBody(p, seen, resolve2, 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 fs(d.parser);
269
273
  case "grammar":
270
274
  return firstSetOf(
@@ -1784,6 +1788,10 @@ function peelLabel(p) {
1784
1788
  return null;
1785
1789
  }
1786
1790
  function analyzeLabeledTrivia(trivia2) {
1791
+ if (trivia2._def.tag === "trivia") {
1792
+ const own = trivia2._meta.labeledTriviaSpec;
1793
+ if (own !== void 0) return own;
1794
+ }
1787
1795
  if (trivia2 === labeledTrivia0) return labeledSpec0;
1788
1796
  if (trivia2 === labeledTrivia1) return labeledSpec1;
1789
1797
  if (trivia2 === labeledTrivia2) return labeledSpec2;
@@ -4462,13 +4470,24 @@ function dispatch(selector, ...arms) {
4462
4470
  }
4463
4471
 
4464
4472
  // src/combinators/attempt.ts
4465
- function attempt(parser2) {
4473
+ function containOption(options) {
4474
+ if (options === void 0) return false;
4475
+ for (const key of Object.keys(options)) {
4476
+ if (key !== "contain") throw new TypeError(`attempt(): unknown option ${JSON.stringify(key)}`);
4477
+ }
4478
+ if (options.contain !== void 0 && typeof options.contain !== "boolean") {
4479
+ throw new TypeError("attempt(): `contain` must be a boolean");
4480
+ }
4481
+ return options.contain === true;
4482
+ }
4483
+ function attempt(parser2, options) {
4484
+ const contain = containOption(options);
4466
4485
  const guardable = parser2._meta.firstSet.kind !== "any" && !matchesEmpty(parser2);
4467
4486
  let failExpected;
4468
4487
  return {
4469
4488
  _tag: "attempt",
4470
4489
  _meta: parser2._meta,
4471
- _def: { tag: "attempt", parser: parser2 },
4490
+ _def: contain ? { tag: "attempt", parser: parser2, contain: true } : { tag: "attempt", parser: parser2 },
4472
4491
  parse(input, pos, ctx) {
4473
4492
  if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(parser2, input, pos)) {
4474
4493
  if (failExpected === void 0) {
@@ -4485,7 +4504,7 @@ function attempt(parser2) {
4485
4504
  rollbackCstCapture(ctx, mark);
4486
4505
  if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
4487
4506
  if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
4488
- if (result.committed) return result;
4507
+ if (result.committed && !contain) return result;
4489
4508
  return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
4490
4509
  }
4491
4510
  };
@@ -5304,7 +5323,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
5304
5323
  throw new Error("node() options cannot combine project with unwrap or collapse");
5305
5324
  }
5306
5325
  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;
5307
- const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
5326
+ const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
5308
5327
  const clonesState = build ? buildReadsState(def) : project === void 0;
5309
5328
  const hasOwnFields = parserHasOwnFields(combinator);
5310
5329
  const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
@@ -5418,13 +5437,17 @@ function transform(combinator, fn) {
5418
5437
  };
5419
5438
  }
5420
5439
  function trivia(combinator) {
5421
- const kindLabels = analyzeLabeledTrivia(combinator)?.labels;
5440
+ const labeled = analyzeLabeledTrivia(combinator);
5441
+ const kindLabels = labeled?.labels;
5422
5442
  return {
5423
5443
  _tag: combinator._tag,
5424
5444
  _meta: {
5425
5445
  ...combinator._meta,
5426
5446
  isTrivia: true,
5427
5447
  triviaScanner: fastTriviaScanner(combinator),
5448
+ // Every labeled scan of this trivia reads its spec; the module's four-slot
5449
+ // memo alone thrashes on a grammar with more than four trivia tables.
5450
+ labeledTriviaSpec: labeled,
5428
5451
  ...kindLabels ? { triviaKindLabels: kindLabels } : {}
5429
5452
  },
5430
5453
  _def: { tag: "trivia", parser: combinator },
@@ -6294,10 +6317,12 @@ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve2) {
6294
6317
  case "choice":
6295
6318
  case "sequence":
6296
6319
  return d.parsers.some((x) => mayCommitFailure(x, seen, resolve2));
6320
+ // A contained transaction reports every failure uncommitted.
6321
+ case "attempt":
6322
+ return d.contain !== true && mayCommitFailure(d.parser, seen, resolve2);
6297
6323
  case "many":
6298
6324
  case "oneOrMore":
6299
6325
  case "optional":
6300
- case "attempt":
6301
6326
  case "transform":
6302
6327
  case "label":
6303
6328
  case "field":
@@ -8355,7 +8380,7 @@ var Encoder = class {
8355
8380
  const derivedState = d.build !== void 0 ? buildReadsState(d) : noBuildCaptures;
8356
8381
  const derivedFields = d.build !== void 0 ? buildReadsFields(d) : noBuildCaptures;
8357
8382
  const wantsFields = parserHasOwnFields(d.parser) && (cstOut || derivedFields);
8358
- 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);
8383
+ 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);
8359
8384
  const body = this.emit(
8360
8385
  this.track ? OP_NODE_TRACK : OP_NODE,
8361
8386
  d.build === void 0 ? -1 : this.fn(d.build, d.buildSrc ?? null),
@@ -8481,7 +8506,7 @@ var Encoder = class {
8481
8506
  // A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
8482
8507
  // lowering was correct only for a choice arm.
8483
8508
  case "attempt": {
8484
- const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
8509
+ const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
8485
8510
  if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
8486
8511
  const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : d.parser._meta.firstSet;
8487
8512
  if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
@@ -9874,7 +9899,7 @@ function transfer(code, ip, at, hostCst) {
9874
9899
  }
9875
9900
  if (op === OP_NODE || op === OP_NODE_TRACK) {
9876
9901
  const flags = code[ip + 3];
9877
- const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
9902
+ const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && ((flags & ~128) === 2 || flags === 18 || flags === 34);
9878
9903
  if (directChildren) {
9879
9904
  return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
9880
9905
  }
@@ -11078,7 +11103,7 @@ ${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
11078
11103
  const v=${child}(input,pos,ctx)
11079
11104
  if(v!==FAIL)return v
11080
11105
  ${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
11081
- if(ctx._fc===true)return FAIL
11106
+ ${code[ip + 2] === 1 ? "ctx._fc=false" : "if(ctx._fc===true)return FAIL"}
11082
11107
  ctx._fe=pos
11083
11108
  return FAIL
11084
11109
  }`;
@@ -11667,7 +11692,8 @@ return nd
11667
11692
  const unwrap = (flags & 64) !== 0;
11668
11693
  const trailingTrivia = (flags & 128) !== 0;
11669
11694
  const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
11670
- if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
11695
+ const leanFlags = flags & ~128;
11696
+ if (!hostCst && !tracked && build !== void 0 && proj < 0 && (leanFlags === 2 || (flags === 18 || flags === 34))) {
11671
11697
  const fields = flags === 18;
11672
11698
  const collapseChildren = flags === 34;
11673
11699
  const publish = L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? `if(sBuf!==undefined){
@@ -11712,7 +11738,8 @@ ctx._cstTriviaLog=undefined
11712
11738
  ctx.captureTrivia=false
11713
11739
  ctx._fields=${fields ? "[]" : "undefined"}
11714
11740
  const v=${child}(input,pos,ctx)
11715
- const captured=_capturedFlatChildren(flat)
11741
+ ${trailingTrivia && L.tri !== TRI_NONE ? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? "&&ctx.trivia!==undefined" : ""})EC.e=consumeTrivia(input,EC.e,ctx)
11742
+ ` : ""}const captured=_capturedFlatChildren(flat)
11716
11743
  ${fields ? "const fieldMap=buildFieldMap(ctx._fields)\n" : ""}ctx._fields=sFields
11717
11744
  ctx._cstBuf=sBuf
11718
11745
  ctx._cstChildren=sCh
@@ -12084,7 +12111,7 @@ function assemble(t2, prog, cfg) {
12084
12111
  const lf = { _tag: "leaf", value, span: { start: s, end: e } };
12085
12112
  pushCstLeaf(ctx, lf);
12086
12113
  }
12087
- function plainBuildNode(child, build) {
12114
+ function plainBuildNode(child, build, trailing) {
12088
12115
  return (input, pos, ctx) => {
12089
12116
  const sCh = ctx._cstChildren;
12090
12117
  const sLv = ctx._cstLeaves;
@@ -12102,6 +12129,7 @@ function assemble(t2, prog, cfg) {
12102
12129
  ctx.captureTrivia = false;
12103
12130
  ctx._fields = void 0;
12104
12131
  const value = child(input, pos, ctx);
12132
+ if (trailing && value !== FAIL && ctx.trivia !== void 0) EC.e = consumeTrivia(input, EC.e, ctx);
12105
12133
  const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
12106
12134
  const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
12107
12135
  ctx._fields = savedFields;
@@ -12129,7 +12157,7 @@ function assemble(t2, prog, cfg) {
12129
12157
  while (first < children2.length && children2[first] === void 0) first++;
12130
12158
  return first === children2.length ? EMPTY_CH : children2.slice(first);
12131
12159
  }
12132
- function childrenOnlyBuildNode(child, build) {
12160
+ function childrenOnlyBuildNode(child, build, trailing) {
12133
12161
  return (input, pos, ctx) => {
12134
12162
  const sCh = ctx._cstChildren;
12135
12163
  const sLv = ctx._cstLeaves;
@@ -12147,6 +12175,7 @@ function assemble(t2, prog, cfg) {
12147
12175
  ctx.captureTrivia = false;
12148
12176
  ctx._fields = void 0;
12149
12177
  const value = child(input, pos, ctx);
12178
+ if (trailing && value !== FAIL && ctx.trivia !== void 0) EC.e = consumeTrivia(input, EC.e, ctx);
12150
12179
  const captured = capturedFlatChildren(kids);
12151
12180
  ctx._fields = savedFields;
12152
12181
  ctx._cstBuf = sBuf;
@@ -13171,6 +13200,7 @@ function assemble(t2, prog, cfg) {
13171
13200
  /* ── transaction ─────────────────────────────────────────────────────── */
13172
13201
  case OP_ATTEMPT: {
13173
13202
  const child = link(code[ip + 1]);
13203
+ const contain = code[ip + 2] === 1;
13174
13204
  return (input, pos, ctx) => {
13175
13205
  const need = markCst(ctx);
13176
13206
  const mRaw = MRAW;
@@ -13183,7 +13213,10 @@ function assemble(t2, prog, cfg) {
13183
13213
  const v = child(input, pos, ctx);
13184
13214
  if (v !== FAIL) return v;
13185
13215
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
13186
- if (committed3(ctx)) return FAIL;
13216
+ if (committed3(ctx)) {
13217
+ if (!contain) return FAIL;
13218
+ ctx._fc = false;
13219
+ }
13187
13220
  ctx._fe = pos;
13188
13221
  return FAIL;
13189
13222
  };
@@ -14634,11 +14667,11 @@ function assemble(t2, prog, cfg) {
14634
14667
  const trailingTrivia = (flags & 128) !== 0;
14635
14668
  const build = buildIdx >= 0 ? fns[buildIdx] : void 0;
14636
14669
  if (!hostCst && !tracked) {
14637
- if (build !== void 0 && proj < 0 && flags === 0) {
14638
- return plainBuildNode(child, build);
14670
+ if (build !== void 0 && proj < 0 && (flags & ~128) === 0) {
14671
+ return plainBuildNode(child, build, trailingTrivia);
14639
14672
  }
14640
- if (build !== void 0 && proj < 0 && flags === 2) {
14641
- return childrenOnlyBuildNode(child, build);
14673
+ if (build !== void 0 && proj < 0 && (flags & ~128) === 2) {
14674
+ return childrenOnlyBuildNode(child, build, trailingTrivia);
14642
14675
  }
14643
14676
  if (build !== void 0 && proj < 0 && flags === 18) {
14644
14677
  return childrenOnlyFieldsBuildNode(child, build);
@@ -18002,7 +18035,7 @@ function rebuildCombinator(root, replacements) {
18002
18035
  out = d.polarity === "adjacent" ? adjacent() : d.kinds === void 0 ? notAdjacent() : notAdjacent({ kinds: d.kinds });
18003
18036
  break;
18004
18037
  case "attempt":
18005
- out = attempt(one(d.parser));
18038
+ out = attempt(one(d.parser), d.contain === true ? { contain: true } : void 0);
18006
18039
  break;
18007
18040
  case "not":
18008
18041
  out = not(one(d.parser));