parseman 0.26.3 → 0.27.1

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.
package/dist/index.d.ts CHANGED
@@ -33,7 +33,7 @@ export type { CSTNode, CSTLeaf, CSTError, CSTTrivia, CSTChild, CSTRawChild, Node
33
33
  export { parseDoc } from './functional/doc.ts';
34
34
  export type { ParseDoc, ParseDocOptions, Registry, RuleFn } from './functional/doc.ts';
35
35
  export { run } from './functional/run.ts';
36
- export type { RunResult, RunOptions, Runnable } from './functional/run.ts';
36
+ export type { RunResult, RunOptions, RunProfile, RunProfilePass, Runnable } from './functional/run.ts';
37
37
  export { buildTriviaIndex } from './cst/trivia-index.ts';
38
38
  export type { TriviaIndex, TriviaToken, TriviaIndexOptions } from './cst/trivia-index.ts';
39
39
  export { walk, createVisitor } from './cst/walk.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1437,6 +1437,12 @@ function scanTrivia(input, cur, ctx) {
1437
1437
  const tr = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
1438
1438
  return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
1439
1439
  }
1440
+ function consumeTrivia(input, cur, ctx) {
1441
+ if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
1442
+ const scan = scanTrivia(input, cur, ctx);
1443
+ scan.commit();
1444
+ return scan.end;
1445
+ }
1440
1446
  function fastTriviaScanner(trivia2) {
1441
1447
  const cached = fastTriviaCache.get(trivia2);
1442
1448
  if (cached !== void 0) return cached;
@@ -2217,6 +2223,98 @@ function parserHasOwnFields(p, seen = /* @__PURE__ */ new Set()) {
2217
2223
  return false;
2218
2224
  }
2219
2225
  }
2226
+ function parserHasTriviaSite(p, seen = /* @__PURE__ */ new Set()) {
2227
+ if (seen.has(p)) return true;
2228
+ seen.add(p);
2229
+ const d = p._def;
2230
+ switch (d.tag) {
2231
+ // Trivia is skipped between/around elements or iterations → a site.
2232
+ case "sequence":
2233
+ case "many":
2234
+ case "oneOrMore":
2235
+ case "sepBy":
2236
+ case "scanTo":
2237
+ case "recover":
2238
+ case "skip":
2239
+ return true;
2240
+ // Nested node manages its own trivia frame; none logs here.
2241
+ case "node":
2242
+ return false;
2243
+ // Pure terminals + trivia-suppressing token: no site.
2244
+ case "regex":
2245
+ case "literal":
2246
+ case "keywords":
2247
+ case "guard":
2248
+ case "token":
2249
+ return false;
2250
+ // Transparent single-child wrappers: recurse.
2251
+ case "optional":
2252
+ case "transform":
2253
+ case "trivia":
2254
+ case "label":
2255
+ case "expect":
2256
+ case "withCtx":
2257
+ case "not":
2258
+ case "field":
2259
+ return parserHasTriviaSite(d.parser, seen);
2260
+ case "choice":
2261
+ return d.parsers.some((x) => parserHasTriviaSite(x, seen));
2262
+ case "grammar":
2263
+ return parserHasTriviaSite(d.parser, seen);
2264
+ case "lazy": {
2265
+ try {
2266
+ return parserHasTriviaSite(d.thunk(), seen);
2267
+ } catch {
2268
+ return true;
2269
+ }
2270
+ }
2271
+ default:
2272
+ return true;
2273
+ }
2274
+ }
2275
+ function parserEnablesTriviaCapture(p, seen = /* @__PURE__ */ new Set()) {
2276
+ if (seen.has(p)) return false;
2277
+ seen.add(p);
2278
+ const d = p._def;
2279
+ switch (d.tag) {
2280
+ case "grammar":
2281
+ return d.captureTrivia === true || parserEnablesTriviaCapture(d.parser, seen);
2282
+ case "node":
2283
+ return false;
2284
+ case "sequence":
2285
+ case "choice":
2286
+ return d.parsers.some((x) => parserEnablesTriviaCapture(x, seen));
2287
+ case "sepBy":
2288
+ return parserEnablesTriviaCapture(d.parser, seen) || parserEnablesTriviaCapture(d.separator, seen);
2289
+ case "skip":
2290
+ return parserEnablesTriviaCapture(d.main, seen) || parserEnablesTriviaCapture(d.skipped, seen);
2291
+ case "scanTo":
2292
+ return parserEnablesTriviaCapture(d.sentinel, seen) || d.skip.some((x) => parserEnablesTriviaCapture(x, seen));
2293
+ case "recover":
2294
+ return parserEnablesTriviaCapture(d.parser, seen) || parserEnablesTriviaCapture(d.sentinel, seen);
2295
+ case "many":
2296
+ case "oneOrMore":
2297
+ case "optional":
2298
+ case "transform":
2299
+ case "trivia":
2300
+ case "token":
2301
+ case "label":
2302
+ case "field":
2303
+ case "expect":
2304
+ case "withCtx":
2305
+ case "not":
2306
+ return parserEnablesTriviaCapture(d.parser, seen);
2307
+ case "lazy": {
2308
+ try {
2309
+ return parserEnablesTriviaCapture(d.thunk(), seen);
2310
+ } catch {
2311
+ return false;
2312
+ }
2313
+ }
2314
+ default:
2315
+ return false;
2316
+ }
2317
+ }
2220
2318
  function buildFieldMap(captures) {
2221
2319
  if (!captures?.length) return void 0;
2222
2320
  const out = {};
@@ -2254,11 +2352,13 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
2254
2352
  };
2255
2353
  const unwrap = opts?.unwrap === true;
2256
2354
  const collapse = opts?.collapse === true;
2355
+ const captureTrivia = opts?.captureTrivia === true;
2356
+ const trailingTrivia = opts?.trailingTrivia === true;
2257
2357
  if (unwrap && collapse) {
2258
2358
  throw new Error("node() options cannot set both unwrap and collapse");
2259
2359
  }
2260
- const def = unwrap || collapse ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {} } : baseDef;
2261
- const capturesTrivia = build ? buildReadsTrivia(def) : true;
2360
+ const def = unwrap || collapse || captureTrivia || trailingTrivia ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {} } : baseDef;
2361
+ const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : true);
2262
2362
  const clonesState = build ? buildReadsState(def) : true;
2263
2363
  const capturesFields = parserHasOwnFields(combinator) && (build ? buildReadsFields(def) : true);
2264
2364
  return {
@@ -2274,7 +2374,11 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
2274
2374
  ctx._triviaCaptureMask = ctx.build._parsemanTriviaKinds(def.type);
2275
2375
  }
2276
2376
  if (!capturesTrivia) ctx.captureTrivia = false;
2277
- const r = combinator.parse(input, pos, ctx);
2377
+ let r = combinator.parse(input, pos, ctx);
2378
+ if (r.ok && trailingTrivia && ctx.trivia) {
2379
+ const end = consumeTrivia(input, r.span.end, ctx);
2380
+ r = { ...r, span: { start: r.span.start, end } };
2381
+ }
2278
2382
  const fields = capturesFields ? buildFieldMap(ctx._fields) : void 0;
2279
2383
  ctx._fields = savedFields;
2280
2384
  ctx._triviaCaptureMask = savedMask;
@@ -2282,8 +2386,9 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
2282
2386
  if (!r.ok) return r;
2283
2387
  const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
2284
2388
  const nodeType = def.type ?? missingInferredType();
2285
- const built = unwrap && children.length === 1 ? unwrapChild(children[0]) : collapse && children.length === 1 ? children[0] : !build && ctx.build?._parsemanCstCollapse && children.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children[0], children, rawChildren) ? children[0] : build ? build(children, fields, r.span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children, fields, r.span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: { start: r.span.start, end: r.span.end }, state: st ?? null, children };
2286
- const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : "", span: r.span };
2389
+ const cstOutput = ctx.build?._parsemanCstOutput === true;
2390
+ const built = unwrap && children.length === 1 ? unwrapChild(children[0]) : collapse && children.length === 1 ? children[0] : !build && ctx.build?._parsemanCstCollapse && children.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children[0], children, rawChildren) ? children[0] : build ? cstOutput && ctx.build ? ctx.build(nodeType, children, fields, r.span, rawChildren, triviaLog, st) : build(children, fields, r.span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children, fields, r.span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: { start: r.span.start, end: r.span.end }, state: st ?? null, children };
2391
+ const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span: r.span };
2287
2392
  if (saved.buf !== void 0 || saved.ch !== void 0) {
2288
2393
  pushCstChild(ctx, built, rawEntry);
2289
2394
  }
@@ -2400,6 +2505,7 @@ function parser(opts, root) {
2400
2505
  parser: root,
2401
2506
  triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
2402
2507
  clearTrivia,
2508
+ ...opts.captureTrivia ? { captureTrivia: true } : {},
2403
2509
  trackLines: opts.trackLines ?? false
2404
2510
  },
2405
2511
  parse(input, pos, _ctx) {
@@ -3561,7 +3667,7 @@ function scanBranchLabeled(shape, kindIndex, mint) {
3561
3667
  ` if (${m.end} > _e) {`,
3562
3668
  ` if (_cap) {`,
3563
3669
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, ${m.end}, ${kindIndex})`,
3564
- ` if (_ctx._cstTriviaLog !== undefined && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << kindIndex}))) _ctx._cstTriviaLog.push(_e, ${m.end}, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${kindIndex})`,
3670
+ ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << kindIndex}))) _ctx._cstTriviaLog.push(_e, ${m.end}, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${kindIndex})`,
3565
3671
  ` }`,
3566
3672
  ` _e = ${m.end}`,
3567
3673
  ` continue`,
@@ -3617,7 +3723,7 @@ function analyzeTriviaFastPath(trivia2) {
3617
3723
  var CAP_RECORD = [
3618
3724
  ` if (_cap && _e > _pos) {`,
3619
3725
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_pos, _e)`,
3620
- ` if (_ctx._cstTriviaLog !== undefined) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
3726
+ ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
3621
3727
  ` }`
3622
3728
  ].join("\n");
3623
3729
  function composeFastLoop(shapes) {
@@ -3677,7 +3783,7 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
3677
3783
  ` const _ce = _e + _m${i}[0].length`,
3678
3784
  ` if (_cap) {`,
3679
3785
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
3680
- ` if (_ctx._cstTriviaLog !== undefined && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
3786
+ ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
3681
3787
  ` }`,
3682
3788
  ` _e = _ce`,
3683
3789
  ` _matched = true`,
@@ -3715,7 +3821,7 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
3715
3821
  ` const _ce = _r${i}.span.end`,
3716
3822
  ` if (_cap) {`,
3717
3823
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
3718
- ` if (_ctx._cstTriviaLog !== undefined && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
3824
+ ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
3719
3825
  ` }`,
3720
3826
  ` _e = _ce`,
3721
3827
  ` _matched = true`,
@@ -4058,7 +4164,7 @@ function ensureTriviaFn(ctx) {
4058
4164
  ` }`,
4059
4165
  ` if (_cap && _e > _pos) {`,
4060
4166
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_pos, _e)`,
4061
- ` if (_ctx._cstTriviaLog !== undefined) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
4167
+ ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
4062
4168
  ` }`,
4063
4169
  ` return _e`,
4064
4170
  `}`
@@ -5193,47 +5299,71 @@ function emitNode(def, ctx, pos) {
5193
5299
  ctx.buildSrcs.push(def.buildSrc ?? null);
5194
5300
  }
5195
5301
  const i = ind(ctx);
5196
- const capturesTrivia = mkType !== null || !structural && buildReadsTrivia(def);
5302
+ const capturesTrivia = mkType !== null || def.captureTrivia === true || def.trailingTrivia === true || !structural && buildReadsTrivia(def);
5197
5303
  const clonesState = !structural && buildReadsState(def);
5198
5304
  const hasFields = parserHasOwnFields(def.parser);
5199
5305
  const capturesFields = hasFields && !structural && buildReadsFields(def);
5306
+ const innerEnablesTriviaCapture = parserEnablesTriviaCapture(def.parser);
5200
5307
  const chV = v(ctx, "_ch");
5201
5308
  const rawV = v(ctx, "_raw");
5202
- const capTLv = structural ? v(ctx, "_ctl") : null;
5309
+ const capTLv = structural || capturesTrivia ? v(ctx, "_ctl") : null;
5203
5310
  const capSTv = structural ? v(ctx, "_cst") : null;
5204
5311
  const capFv = structural && hasFields ? v(ctx, "_cf") : null;
5205
5312
  const tlV = capturesTrivia || structural ? v(ctx, "_tl") : "_EMPTY_TL";
5206
- if (!capturesTrivia) ctx.needsEmptyTl = true;
5313
+ if (!capturesTrivia || structural) ctx.needsEmptyTl = true;
5207
5314
  const sc = v(ctx, "_sc"), sl = v(ctx, "_sl"), sr = v(ctx, "_sr"), st = v(ctx, "_st"), stl = v(ctx, "_stl");
5208
5315
  const smk = structural ? v(ctx, "_smk") : null;
5209
5316
  if (structural) ctx.needsHostReads = true;
5210
5317
  const hostTriviaGate = `_ctx.build !== undefined && (_ctx.build._parsemanCaptureTrivia !== undefined ? _ctx.build._parsemanCaptureTrivia(${JSON.stringify(def.type)}) : (_ctx._pmCapTL ??= _hostReads(_ctx.build, 5)))`;
5211
- const allocStmt = structural ? `${i}const ${capTLv} = ${hostTriviaGate}, ${capSTv} = _ctx._pmCapST ??= (_ctx.build === undefined || _hostReads(_ctx.build, 6))${capFv ? `, ${capFv} = _ctx.build !== undefined && _hostReads(_ctx.build, 2)` : ""}
5212
- ${i}const ${chV} = [], ${rawV} = [], ${tlV} = ${capTLv} ? [] : _EMPTY_TL` : capturesTrivia ? `${i}const ${chV} = [], ${rawV} = [], ${tlV} = []` : `${i}const ${chV} = [], ${rawV} = []`;
5213
- const innerTl = structural ? `${capTLv} ? ${tlV} : undefined` : capturesTrivia ? tlV : "undefined";
5214
- const fieldsOn = structural ? capFv ?? "false" : capturesFields ? "true" : "false";
5318
+ const pmV = v(ctx, "_pm"), recV = v(ctx, "_rec"), capV = v(ctx, "_cap");
5319
+ const profHoist = `${i}const ${pmV} = _ctx._pmProfile, ${recV} = ${pmV}?.phase === 'recognizer', ${capV} = ${pmV}?.phase === 'capture'`;
5320
+ const profileRecognizer = recV;
5321
+ const profileCapture = capV;
5322
+ const structuralCapturesTrivia = structural && (def.captureTrivia === true || def.trailingTrivia === true);
5323
+ const allocStmt = structural ? `${i}const ${capTLv} = !(${profileRecognizer}) && (${profileCapture} || ${structuralCapturesTrivia ? "true" : hostTriviaGate}), ${capSTv} = !(${profileRecognizer} || ${profileCapture}) && (_ctx._pmCapST ??= (_ctx.build === undefined || _hostReads(_ctx.build, 6)))${capFv ? `, ${capFv} = !(${profileRecognizer}) && (${profileCapture} || (_ctx.build !== undefined && _hostReads(_ctx.build, 2)))` : ""}
5324
+ ${i}const ${chV} = ${profileRecognizer} ? undefined : [], ${rawV} = ${profileRecognizer} ? undefined : [], ${tlV} = ${profileRecognizer} ? undefined : ${innerEnablesTriviaCapture ? "[]" : `${capTLv} ? [] : _EMPTY_TL`}` : capturesTrivia ? `${i}const ${capTLv} = !(${profileRecognizer}), ${chV} = ${profileRecognizer} ? undefined : [], ${rawV} = ${profileRecognizer} ? undefined : [], ${tlV} = ${profileRecognizer} ? undefined : []` : `${i}const ${chV} = ${profileRecognizer} ? undefined : [], ${rawV} = ${profileRecognizer} ? undefined : []`;
5325
+ const innerTl = structural || capturesTrivia ? structural && !innerEnablesTriviaCapture ? `${capTLv} ? ${tlV} : undefined` : tlV : "undefined";
5326
+ const fieldsOn = structural ? capFv ?? "false" : `${profileRecognizer} ? false : ${capturesFields ? "true" : "false"}`;
5215
5327
  const sf = hasFields ? v(ctx, "_sf") : null;
5216
5328
  const fArr = hasFields ? v(ctx, "_fa") : null;
5217
5329
  const fObj = hasFields ? v(ctx, "_fields") : "undefined";
5330
+ const needsTriviaFrame = def.trailingTrivia === true || parserHasTriviaSite(def.parser);
5331
+ const saveTrivia = needsTriviaFrame ? `, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog${smk ? `, ${smk} = _ctx._triviaCaptureMask` : ""}` : "";
5332
+ const installTrivia = needsTriviaFrame ? `; _ctx.captureTrivia = ${capTLv ?? "false"}; _ctx._cstTriviaLog = ${innerTl}${smk ? `; _ctx._triviaCaptureMask = ${capTLv} && _ctx.build !== undefined && _ctx.build._parsemanTriviaKinds !== undefined ? _ctx.build._parsemanTriviaKinds(${JSON.stringify(def.type)}) : ${smk}` : ""}` : "";
5333
+ const restoreTrivia = needsTriviaFrame ? `; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}${smk ? `; _ctx._triviaCaptureMask = ${smk}` : ""}` : "";
5218
5334
  const stmts = [
5335
+ profHoist,
5219
5336
  allocStmt,
5220
- `${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog${smk ? `, ${smk} = _ctx._triviaCaptureMask` : ""}${sf ? `, ${sf} = _ctx._fields` : ""}`,
5221
- `${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}${smk ? `; _ctx._triviaCaptureMask = ${capTLv} && _ctx.build._parsemanTriviaKinds !== undefined ? _ctx.build._parsemanTriviaKinds(${JSON.stringify(def.type)}) : ${smk}` : ""}${sf ? `; _ctx._fields = ${fieldsOn} ? [] : undefined` : ""}`
5337
+ `${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren${saveTrivia}${sf ? `, ${sf} = _ctx._fields` : ""}`,
5338
+ `${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}${installTrivia}${sf ? `; _ctx._fields = ${fieldsOn} ? [] : undefined` : ""}`
5222
5339
  ];
5223
- const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
5340
+ const { stmts: innerStmts, okVar, endVar: innerEndVar } = emitFallible(def.parser, ctx, pos);
5341
+ const endVar = def.trailingTrivia === true && ctx.activeTrivia ? v(ctx, "_trailend") : innerEndVar;
5224
5342
  stmts.push(...innerStmts);
5343
+ if (def.trailingTrivia === true && ctx.activeTrivia) {
5344
+ const triviaFn = ensureTriviaFn(ctx);
5345
+ stmts.push(`${i}const ${endVar} = ${okVar} ? ${triviaFn}(input, ${innerEndVar}, _ctx, 1) : ${innerEndVar}`);
5346
+ }
5225
5347
  if (sf && fArr) {
5226
5348
  stmts.push(`${i}const ${fArr} = _ctx._fields`);
5227
5349
  }
5228
- stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}${smk ? `; _ctx._triviaCaptureMask = ${smk}` : ""}${sf ? `; _ctx._fields = ${sf}` : ""}`);
5350
+ stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}${restoreTrivia}${sf ? `; _ctx._fields = ${sf}` : ""}`);
5229
5351
  stmts.push(...emitIfFail(ctx, `!${okVar}`, propagateFailBody(ctx)));
5352
+ stmts.push(
5353
+ `${i}if (_ctx._pmProfile) {`,
5354
+ `${i} _ctx._pmProfile.nodes++`,
5355
+ `${i} if (${profileCapture}) {`,
5356
+ `${i} _ctx._pmProfile.childSlots += ${chV}.length; _ctx._pmProfile.rawSlots += ${rawV}.length; _ctx._pmProfile.triviaSlots += ${tlV}.length${fArr ? `; _ctx._pmProfile.fieldSlots += ${fArr} ? ${fArr}.length : 0` : ""}`,
5357
+ `${i} }`,
5358
+ `${i}}`
5359
+ );
5230
5360
  let stV = "undefined";
5231
5361
  if (structural) {
5232
5362
  stV = v(ctx, "_nst");
5233
5363
  stmts.push(`${i}const ${stV} = ${capSTv} && _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
5234
5364
  } else if (clonesState) {
5235
5365
  stV = v(ctx, "_nst");
5236
- stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
5366
+ stmts.push(`${i}const ${stV} = !(${profileRecognizer} || ${profileCapture}) && _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
5237
5367
  }
5238
5368
  if (sf && fArr) {
5239
5369
  const fe = v(ctx, "_fe");
@@ -5253,15 +5383,18 @@ ${i}const ${chV} = [], ${rawV} = [], ${tlV} = ${capTLv} ? [] : _EMPTY_TL` : capt
5253
5383
  }
5254
5384
  const ndV = v(ctx, "_nd");
5255
5385
  const buildExpr = structural ? `{ _tag: 'node', type: ${JSON.stringify(def.type)}, span: { start: ${pos}, end: ${endVar} }, state: ${stV} ?? null, children: ${chV} }` : mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, pos, endVar, tlV) : `${buildRef(ctx)}[${buildIdx}](${chV}, ${fObj}, { start: ${pos}, end: ${endVar} }, ${rawV}, ${tlV}, ${stV})`;
5256
- const ndExpr = ctx.ns || structural ? `_ctx.build !== undefined ? _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${fObj}, { start: ${pos}, end: ${endVar} }, ${rawV}, ${tlV}, ${stV}) : (${buildExpr})` : buildExpr;
5257
- const hostCollapseExpr = ctx.ns || structural ? `_ctx.build !== undefined && _ctx.build._parsemanCstCollapse !== undefined && ${chV}.length === 1 && ${rawV}.length === 1 && _ctx.build._parsemanCstCollapse(${JSON.stringify(def.type)}, ${chV}[0], ${chV}, ${rawV}) ? ${chV}[0] : (${ndExpr})` : ndExpr;
5386
+ const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${fObj}, { start: ${pos}, end: ${endVar} }, ${rawV}, ${tlV}, ${stV})`;
5387
+ const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : `_ctx.build?._parsemanCstOutput === true ? (${hostBuildExpr}) : (${buildExpr})`;
5388
+ const hostCollapseExpr = structural ? `_ctx.build !== undefined && _ctx.build._parsemanCstCollapse !== undefined && ${chV}.length === 1 && ${rawV}.length === 1 && _ctx.build._parsemanCstCollapse(${JSON.stringify(def.type)}, ${chV}[0], ${chV}, ${rawV}) ? ${chV}[0] : (${ndExpr})` : ndExpr;
5258
5389
  const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
5259
5390
  const collapseExpr = `${chV}.length === 1 ? ${chV}[0] : (${ndExpr})`;
5260
5391
  const finalExpr = def.unwrap ? unwrapExpr : def.collapse ? collapseExpr : hostCollapseExpr;
5261
5392
  stmts.push(
5262
- `${i}const ${ndV} = ${finalExpr}`,
5263
- `${i}if (${sc}) ${sc}.push(${ndV})`,
5264
- `${i}if (${sr}) ${sr}.push((typeof ${ndV} === 'object' && ${ndV} !== null && (${ndV}._tag === 'node' || ${ndV}._tag === 'leaf' || ${ndV}._tag === 'parseError')) ? ${ndV} : { _tag: 'leaf', value: typeof ${ndV} === 'string' ? ${ndV} : '', span: { start: ${pos}, end: ${endVar} } })`
5393
+ `${i}const ${ndV} = (${profileRecognizer} || ${profileCapture}) ? undefined : (${finalExpr})`,
5394
+ `${i}if (!(${profileRecognizer})) {`,
5395
+ `${i} if (${sc}) ${sc}.push(${ndV})`,
5396
+ `${i} if (${sr}) ${sr}.push((typeof ${ndV} === 'object' && ${ndV} !== null && (${ndV}._tag === 'node' || ${ndV}._tag === 'leaf' || ${ndV}._tag === 'parseError')) ? ${ndV} : { _tag: 'leaf', value: typeof ${ndV} === 'string' ? ${ndV} : (typeof ${ndV} === 'object' && ${ndV} !== null ? input.slice(${pos}, ${endVar}) : ''), span: { start: ${pos}, end: ${endVar} } })`,
5397
+ `${i}}`
5265
5398
  );
5266
5399
  return { stmts, valueVar: ndV, endVar };
5267
5400
  }
@@ -5503,10 +5636,19 @@ function emitDispatch(p, ctx, pos) {
5503
5636
  ctx.triviaKindLabels = def.triviaParser._meta.triviaKindLabels;
5504
5637
  }
5505
5638
  }
5639
+ const savedCapture = def.captureTrivia ? v(ctx, "_gcap") : null;
5506
5640
  const r = emit(def.parser, ctx, pos);
5507
5641
  ctx.activeTrivia = savedTrivia;
5508
5642
  ctx.triviaKindLabels = savedKindLabels;
5509
- return r;
5643
+ if (!savedCapture) return r;
5644
+ return {
5645
+ ...r,
5646
+ stmts: [
5647
+ `${ind(ctx)}const ${savedCapture} = _ctx.captureTrivia; _ctx.captureTrivia = true`,
5648
+ ...r.stmts,
5649
+ `${ind(ctx)}_ctx.captureTrivia = ${savedCapture}`
5650
+ ]
5651
+ };
5510
5652
  }
5511
5653
  case "not":
5512
5654
  return emitNot(def, ctx, pos);
@@ -6269,9 +6411,15 @@ function evalRuleMapIR(ir) {
6269
6411
  t._def.fnSrc = src;
6270
6412
  return t;
6271
6413
  };
6272
- const _nd = (type, child, src, opts) => {
6273
- const n = node(type, child, void 0, opts);
6414
+ const _nd = (type, child, src, opts, staticError) => {
6415
+ if (staticError !== void 0 && staticError.length > 0) {
6416
+ throw new Error(`IR direct node builder for ${type} must be macro-static and self-contained; unsupported binding(s): ${staticError.join(", ")}`);
6417
+ }
6418
+ const n = node(type, child, (() => {
6419
+ throw new Error("IR node build requires static re-lowering");
6420
+ }), opts);
6274
6421
  n._def.buildSrc = src;
6422
+ if (staticError !== void 0) n._def.buildStaticError = staticError;
6275
6423
  return n;
6276
6424
  };
6277
6425
  const _gch = (items) => {
@@ -6521,17 +6669,26 @@ ${body}
6521
6669
  }
6522
6670
  case "node": {
6523
6671
  if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
6524
- const opts = def.unwrap || def.collapse ? `, { ${def.unwrap ? "unwrap: true" : "collapse: true"} }` : "";
6672
+ const optEntries = [
6673
+ ...def.unwrap ? ["unwrap: true"] : [],
6674
+ ...def.collapse ? ["collapse: true"] : [],
6675
+ ...def.captureTrivia ? ["captureTrivia: true"] : [],
6676
+ ...def.trailingTrivia ? ["trailingTrivia: true"] : []
6677
+ ];
6678
+ const opts = optEntries.length > 0 ? `, { ${optEntries.join(", ")} }` : "";
6525
6679
  if (def.type === void 0) {
6526
6680
  if (def.buildSrc !== void 0) throw new Unserializable("inferred node build without inferred type");
6527
6681
  return opts ? `node(${kid(def.parser)}, undefined${opts})` : `node(${kid(def.parser)})`;
6528
6682
  }
6529
- if (def.buildSrc !== void 0) return `_nd(${JSON.stringify(def.type)}, ${kid(def.parser)}, ${JSON.stringify(def.buildSrc)}${opts})`;
6683
+ if (def.buildSrc !== void 0) {
6684
+ const staticError = def.buildStaticError === void 0 ? "" : `${opts ? "" : ", undefined"}, ${JSON.stringify(def.buildStaticError)}`;
6685
+ return `_nd(${JSON.stringify(def.type)}, ${kid(def.parser)}, ${JSON.stringify(def.buildSrc)}${opts}${staticError})`;
6686
+ }
6530
6687
  return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
6531
6688
  }
6532
6689
  case "grammar": {
6533
6690
  const trivia2 = def.clearTrivia ? "null" : def.triviaParser ? kid(def.triviaParser) : "undefined";
6534
- return `parser({ trivia: ${trivia2}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(def.parser)})`;
6691
+ return `parser({ trivia: ${trivia2}${def.captureTrivia ? ", captureTrivia: true" : ""}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(def.parser)})`;
6535
6692
  }
6536
6693
  case "withCtx": {
6537
6694
  if (def.extraSrc === void 0) throw new Unserializable("withCtx without extraSrc");
@@ -6569,9 +6726,11 @@ function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, trivi
6569
6726
  }
6570
6727
  const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
6571
6728
  const host = (type, children2, fields, span2, rawChildren2, triviaLog2, state2) => buildCstNode(type, children2, fields, span2, rawChildren2, triviaLog2, state2);
6729
+ host._parsemanCstOutput = true;
6572
6730
  if (collapse) host._parsemanCstCollapse = collapse;
6573
6731
  return host;
6574
6732
  }
6733
+ cstBuildHost._parsemanCstOutput = true;
6575
6734
  function fusedBody(pieces) {
6576
6735
  const winner = /* @__PURE__ */ new Map();
6577
6736
  for (const p of pieces) for (const k of p.keys) winner.set(k, p);
@@ -7229,7 +7388,7 @@ function parseDoc(registry, rootRule, input, opts = {}) {
7229
7388
 
7230
7389
  // src/functional/run.ts
7231
7390
  var invoke = (r, input, pos, ctx) => typeof r === "function" ? r(input, pos, ctx) : r.parse(input, pos, ctx);
7232
- function run(entry, input, options = {}) {
7391
+ function runOnce(entry, input, options, phase, profileState) {
7233
7392
  if (typeof entry !== "function" && typeof entry?.parse !== "function") {
7234
7393
  throw new TypeError(
7235
7394
  `run(): start production is ${entry === null ? "null" : typeof entry}, not a rule \u2014 the requested grammar rule does not exist (check the rule name).`
@@ -7237,11 +7396,12 @@ function run(entry, input, options = {}) {
7237
7396
  }
7238
7397
  const triviaLog = [];
7239
7398
  const errors = [];
7399
+ const profile = profileState ?? (phase === void 0 ? void 0 : { phase, nodes: 0, childSlots: 0, rawSlots: 0, triviaSlots: 0, fieldSlots: 0, hostCalls: 0 });
7400
+ const skipGlobalSinks = phase === "recognizer" || phase === "capture";
7240
7401
  const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
7241
7402
  const ctx = {
7242
7403
  trackLines: false,
7243
- _triviaLog: triviaLog,
7244
- _errors: errors,
7404
+ ...skipGlobalSinks ? { _pmProfile: profile } : { _triviaLog: triviaLog, _errors: errors, ...profile === void 0 ? {} : { _pmProfile: profile } },
7245
7405
  build: options.build,
7246
7406
  state: options.state,
7247
7407
  ...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
@@ -7268,6 +7428,38 @@ function run(entry, input, options = {}) {
7268
7428
  unconsumedFrom
7269
7429
  };
7270
7430
  }
7431
+ function clonePassState(state) {
7432
+ if (state === null || typeof state !== "object") return state;
7433
+ return Array.isArray(state) ? [...state] : { ...state };
7434
+ }
7435
+ function profilePass(entry, input, options, phase) {
7436
+ const state = { phase, nodes: 0, childSlots: 0, rawSlots: 0, triviaSlots: 0, fieldSlots: 0, hostCalls: 0 };
7437
+ const passOptions = options.state === void 0 ? options : { ...options, state: clonePassState(options.state) };
7438
+ const start = performance.now();
7439
+ const result = runOnce(entry, input, passOptions, phase, state);
7440
+ const { phase: _phase, ...counts } = state;
7441
+ return { result, profile: { ms: performance.now() - start, ...counts } };
7442
+ }
7443
+ function run(entry, input, options = {}) {
7444
+ if (!options.profile) return runOnce(entry, input, options);
7445
+ if (typeof entry !== "function") {
7446
+ throw new TypeError("run({ profile: true }) requires a compiled parser entry");
7447
+ }
7448
+ const recognizer = profilePass(entry, input, options, "recognizer");
7449
+ const capture = profilePass(entry, input, options, "capture");
7450
+ const host = profilePass(entry, input, options, "host");
7451
+ if (recognizer.result.ok !== host.result.ok || capture.result.ok !== host.result.ok || recognizer.result.unconsumedFrom !== host.result.unconsumedFrom || capture.result.unconsumedFrom !== host.result.unconsumedFrom) {
7452
+ throw new Error("run({ profile: true }) changed recognition; the grammar is not profile-safe");
7453
+ }
7454
+ return {
7455
+ ...host.result,
7456
+ profile: {
7457
+ recognizer: recognizer.profile,
7458
+ structuralCapture: capture.profile,
7459
+ hostConstruction: host.profile
7460
+ }
7461
+ };
7462
+ }
7271
7463
 
7272
7464
  // src/cst/trivia-index.ts
7273
7465
  function merge(map, key, run2) {
@@ -7388,6 +7580,9 @@ function triviaEntries(log, labels, opts) {
7388
7580
  end(i) {
7389
7581
  return log[entryOffset(i, stride) + 1];
7390
7582
  },
7583
+ insertIndex(i) {
7584
+ return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
7585
+ },
7391
7586
  kindIndex(i) {
7392
7587
  if (!labels) return void 0;
7393
7588
  return log[entryOffset(i, stride) + baseStride];