parseman 0.49.0 → 0.50.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.
Files changed (77) hide show
  1. package/dist/analysis/commitment.d.ts +2 -1
  2. package/dist/analysis/commitment.d.ts.map +1 -1
  3. package/dist/analysis/diagnostics.js +1824 -737
  4. package/dist/analysis/diagnostics.js.map +3 -3
  5. package/dist/analysis/rebuild.d.ts.map +1 -1
  6. package/dist/cli/index.js +1252 -164
  7. package/dist/cli/index.js.map +3 -3
  8. package/dist/combinators/trivia-skip.d.ts +1 -1
  9. package/dist/combinators/trivia-skip.d.ts.map +1 -1
  10. package/dist/compiler/build-arity.d.ts +16 -0
  11. package/dist/compiler/build-arity.d.ts.map +1 -1
  12. package/dist/compiler/degradation.d.ts +0 -2
  13. package/dist/compiler/degradation.d.ts.map +1 -1
  14. package/dist/compiler/ir-serialize.d.ts.map +1 -1
  15. package/dist/compiler/token-alphabet.d.ts +11 -0
  16. package/dist/compiler/token-alphabet.d.ts.map +1 -1
  17. package/dist/compiler/token-capability.js +185 -20
  18. package/dist/compiler/token-capability.js.map +1 -1
  19. package/dist/cst/capture-buffer.d.ts +5 -1
  20. package/dist/cst/capture-buffer.d.ts.map +1 -1
  21. package/dist/index.js +1365 -279
  22. package/dist/index.js.map +3 -3
  23. package/dist/language-service/index.js +2 -1
  24. package/dist/language-service/index.js.map +1 -1
  25. package/dist/plugin/entry-supercompiler.d.ts +48 -0
  26. package/dist/plugin/entry-supercompiler.d.ts.map +1 -0
  27. package/dist/plugin/evaluator.d.ts.map +1 -1
  28. package/dist/plugin/index.d.ts.map +1 -1
  29. package/dist/plugin/index.js +1957 -385
  30. package/dist/plugin/index.js.map +3 -3
  31. package/dist/run/index.js +2 -1
  32. package/dist/run/index.js.map +1 -1
  33. package/dist/spec/index.js +28 -7
  34. package/dist/spec/index.js.map +1 -1
  35. package/dist/table/assemble.d.ts.map +1 -1
  36. package/dist/table/compile-rule-map.d.ts +6 -5
  37. package/dist/table/compile-rule-map.d.ts.map +1 -1
  38. package/dist/table/emit-assembly.d.ts +6 -1
  39. package/dist/table/emit-assembly.d.ts.map +1 -1
  40. package/dist/table/encode.d.ts.map +1 -1
  41. package/dist/table/index.js +1315 -231
  42. package/dist/table/index.js.map +3 -3
  43. package/dist/table/ops.d.ts +3 -2
  44. package/dist/table/ops.d.ts.map +1 -1
  45. package/dist/table/program.d.ts +15 -1
  46. package/dist/table/program.d.ts.map +1 -1
  47. package/dist/table/scalar-terminal.d.ts +30 -0
  48. package/dist/table/scalar-terminal.d.ts.map +1 -1
  49. package/dist/table/site-labels.d.ts +8 -0
  50. package/dist/table/site-labels.d.ts.map +1 -1
  51. package/dist/types.d.ts +2 -1
  52. package/dist/types.d.ts.map +1 -1
  53. package/dist/version.d.ts +1 -1
  54. package/package.json +1 -1
  55. package/src/analysis/commitment.ts +19 -8
  56. package/src/analysis/rebuild.ts +1 -0
  57. package/src/combinators/trivia-skip.ts +2 -2
  58. package/src/compiler/build-arity.ts +50 -0
  59. package/src/compiler/degradation.ts +0 -6
  60. package/src/compiler/ir-serialize.ts +6 -4
  61. package/src/compiler/token-alphabet.ts +322 -28
  62. package/src/cst/capture-buffer.ts +34 -11
  63. package/src/plugin/entry-supercompiler.ts +567 -0
  64. package/src/plugin/evaluator.ts +10 -0
  65. package/src/plugin/index.ts +7 -3
  66. package/src/table/assemble.ts +125 -42
  67. package/src/table/compile-rule-map.ts +8 -7
  68. package/src/table/compile.ts +7 -8
  69. package/src/table/emit-assembly.ts +646 -126
  70. package/src/table/emit.ts +1 -1
  71. package/src/table/encode.ts +152 -7
  72. package/src/table/ops.ts +3 -2
  73. package/src/table/program.ts +44 -3
  74. package/src/table/scalar-terminal.ts +213 -1
  75. package/src/table/site-labels.ts +22 -9
  76. package/src/types.ts +1 -1
  77. package/src/version.ts +1 -1
package/dist/cli/index.js CHANGED
@@ -927,7 +927,7 @@ function beginCstNodeCapture(ctx) {
927
927
  function finishCstBuf(buf) {
928
928
  if (!buf) return { children: EMPTY, rawChildren: EMPTY, triviaLog: EMPTY_TL };
929
929
  const children2 = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY);
930
- const rawChildren = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY);
930
+ const rawChildren = buf.noRaw === true ? EMPTY : buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY);
931
931
  const triviaLog = buf.tl ?? EMPTY_TL;
932
932
  return { children: children2, rawChildren, triviaLog };
933
933
  }
@@ -959,7 +959,8 @@ function pushCstChild(ctx, built, rawEntry2) {
959
959
  b.single = void 0;
960
960
  } else b.single = built;
961
961
  }
962
- if (b.raw) b.raw.push(rawEntry2);
962
+ if (b.noRaw === true) b.rawLen = (b.rawLen ?? 0) + 1;
963
+ else if (b.raw) b.raw.push(rawEntry2);
963
964
  else if (b.rawSingle !== void 0) {
964
965
  b.raw = [b.rawSingle, rawEntry2];
965
966
  b.rawSingle = void 0;
@@ -973,6 +974,7 @@ function pushCstChild(ctx, built, rawEntry2) {
973
974
  function cstRawLen(ctx) {
974
975
  const b = ctx._cstBuf;
975
976
  if (b) {
977
+ if (b.noRaw === true) return b.rawLen ?? 0;
976
978
  if (b.raw) return b.raw.length;
977
979
  return b.rawSingle !== void 0 ? 1 : 0;
978
980
  }
@@ -1032,19 +1034,37 @@ function rollbackCstCaptureAt(ctx, raw, tlog, leaves, fields, errors) {
1032
1034
  if (ctx._errors && errors !== void 0 && ctx._errors.length !== errors) ctx._errors.length = errors;
1033
1035
  const b = ctx._cstBuf;
1034
1036
  if (b) {
1035
- rollbackBufList(b, "raw", "rawSingle", raw);
1036
- rollbackBufList(b, "ch", "single", leaves);
1037
+ if (b.noRaw === true) {
1038
+ if (b.rawLen !== raw) b.rawLen = raw;
1039
+ } else {
1040
+ const rawList = b.raw;
1041
+ if (rawList) {
1042
+ if (raw === 0) b.raw = void 0;
1043
+ else if (raw === 1) {
1044
+ b.rawSingle = rawList[0];
1045
+ b.raw = void 0;
1046
+ } else if (rawList.length !== raw) rawList.length = raw;
1047
+ } else if (raw === 0) b.rawSingle = void 0;
1048
+ }
1049
+ const childList = b.ch;
1050
+ if (childList) {
1051
+ if (leaves === 0) b.ch = void 0;
1052
+ else if (leaves === 1) {
1053
+ b.single = childList[0];
1054
+ b.ch = void 0;
1055
+ } else if (childList.length !== leaves) childList.length = leaves;
1056
+ } else if (leaves === 0) b.single = void 0;
1037
1057
  if (b.tl) {
1038
1058
  if (tlog === 0) b.tl = void 0;
1039
1059
  else if (b.tl.length !== tlog) b.tl.length = tlog;
1040
1060
  }
1041
- if (ctx._fields && ctx._fields.length !== fields) ctx._fields.length = fields;
1061
+ if (ctx._fields && fields !== void 0 && ctx._fields.length !== fields) ctx._fields.length = fields;
1042
1062
  return;
1043
1063
  }
1044
1064
  if (ctx._cstRawChildren && ctx._cstRawChildren.length !== raw) ctx._cstRawChildren.length = raw;
1045
1065
  if (ctx._cstTriviaLog && ctx._cstTriviaLog.length !== tlog) ctx._cstTriviaLog.length = tlog;
1046
1066
  if (ctx._cstLeaves && ctx._cstLeaves.length !== leaves) ctx._cstLeaves.length = leaves;
1047
- if (ctx._fields && ctx._fields.length !== fields) ctx._fields.length = fields;
1067
+ if (ctx._fields && fields !== void 0 && ctx._fields.length !== fields) ctx._fields.length = fields;
1048
1068
  }
1049
1069
  function pushCstTriviaEntry(ctx, start, end, kindIndex) {
1050
1070
  const insertIdx = cstRawLen(ctx);
@@ -2476,6 +2496,13 @@ function canConsumeNewline(n) {
2476
2496
  return n.parts.some(canConsumeNewline);
2477
2497
  }
2478
2498
  }
2499
+ function regexCanMatchEmpty(source) {
2500
+ try {
2501
+ return nullable(parseRegex(source));
2502
+ } catch {
2503
+ return true;
2504
+ }
2505
+ }
2479
2506
  function firstSetFromRegex(source) {
2480
2507
  let ast;
2481
2508
  try {
@@ -4923,6 +4950,7 @@ function confirmedArityForDef(def) {
4923
4950
  }
4924
4951
  function buildReadsRaw(def) {
4925
4952
  if (!def.build) return true;
4953
+ if (def.buildRawUnused === true) return false;
4926
4954
  const arity = confirmedArityForDef(def);
4927
4955
  if (arity === null) return true;
4928
4956
  return arity >= 4;
@@ -5479,7 +5507,7 @@ function evalRuleMapIR(ir) {
5479
5507
  l._def.fnSrc = src;
5480
5508
  return l;
5481
5509
  };
5482
- const _nd = (type, child, src, opts, staticError, sigSrc, buildImports) => {
5510
+ const _nd = (type, child, src, opts, staticError, sigSrc, buildImports, rawUnused) => {
5483
5511
  if (staticError !== void 0 && staticError.length > 0) {
5484
5512
  throw new Error(`IR direct node builder for ${type} must be macro-static and self-contained; unsupported binding(s): ${staticError.join(", ")}`);
5485
5513
  }
@@ -5489,6 +5517,7 @@ function evalRuleMapIR(ir) {
5489
5517
  n._def.buildSrc = src;
5490
5518
  if (staticError !== void 0) n._def.buildStaticError = staticError;
5491
5519
  if (sigSrc !== void 0) n._def.buildSigSrc = sigSrc;
5520
+ if (rawUnused === true) n._def.buildRawUnused = true;
5492
5521
  if (buildImports !== void 0) n._def.buildImports = buildImports;
5493
5522
  return n;
5494
5523
  };
@@ -5621,6 +5650,301 @@ function evalRuleMapIR(ir) {
5621
5650
  return Object.entries(map);
5622
5651
  }
5623
5652
 
5653
+ // src/analysis/commitment.ts
5654
+ function mayFail(p, seen = /* @__PURE__ */ new Set()) {
5655
+ if (seen.has(p)) return true;
5656
+ seen.add(p);
5657
+ const d = p._def;
5658
+ switch (d.tag) {
5659
+ case "literal":
5660
+ return d.value.length > 0;
5661
+ case "trivia":
5662
+ return false;
5663
+ // `optional`/`many`/a min-0 `sepBy` swallow an ORDINARY failure — zero
5664
+ // repetitions is a match. They do NOT swallow a COMMITTED one: a dispatch
5665
+ // that has selected an arm and then failed inside it breaks out past every
5666
+ // enclosing repeat, straight to the fallible boundary. So these are total
5667
+ // exactly when their body cannot commit. (Measured: treating them as
5668
+ // unconditionally total left an extra zero-width leaf in
5669
+ // `BareInterpolatedSelector` on benchmark.less — a rollback the legacy
5670
+ // build fired and this one had deleted.)
5671
+ case "optional":
5672
+ case "many":
5673
+ return mayCommitFailure(d.parser);
5674
+ case "sepBy":
5675
+ return d.min >= 1 ? mayFail(d.parser, seen) : mayCommitFailure(d.parser) || mayCommitFailure(d.separator);
5676
+ case "oneOrMore":
5677
+ return mayFail(d.parser, seen);
5678
+ case "sequence":
5679
+ return d.parsers.some((x) => mayFail(x, seen));
5680
+ // Delegating wrappers: as fallible as what they wrap.
5681
+ case "node":
5682
+ case "transform":
5683
+ case "label":
5684
+ case "field":
5685
+ case "expect":
5686
+ case "withCtx":
5687
+ case "grammar":
5688
+ case "token":
5689
+ case "leaf":
5690
+ return mayFail(d.parser, seen);
5691
+ case "lazy": {
5692
+ try {
5693
+ return mayFail(d.thunk(), seen);
5694
+ } catch {
5695
+ return true;
5696
+ }
5697
+ }
5698
+ // An adjacency assertion is a TEST — failing is its whole job.
5699
+ case "adjacency":
5700
+ return true;
5701
+ default:
5702
+ return true;
5703
+ }
5704
+ }
5705
+ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActive = true) {
5706
+ if (seen.has(p)) return false;
5707
+ seen.add(p);
5708
+ const d = p._def;
5709
+ switch (d.tag) {
5710
+ // Atomic / non-capturing-then-failing: a failure happens before any push.
5711
+ case "literal":
5712
+ case "regex":
5713
+ case "keywords":
5714
+ case "guard":
5715
+ // Adjacency probes with `_cap = 0` / no `commit()`: it cannot push anything.
5716
+ case "adjacency":
5717
+ case "not":
5718
+ // peek(): emitted under a non-capturing probe ctx and zero-width on both
5719
+ // outcomes, so it can never leave a partial capture behind.
5720
+ case "peek":
5721
+ case "trivia":
5722
+ case "token":
5723
+ case "leaf":
5724
+ case "scanTo":
5725
+ case "unknown":
5726
+ return false;
5727
+ // node() captures into its own private buffers and rolls them back on
5728
+ // failure (emitNode restores _ctx.* and never pushes on the !ok path).
5729
+ case "node":
5730
+ return false;
5731
+ // choice/firstMatch already roll back each failed arm; on overall failure
5732
+ // nothing committed remains.
5733
+ case "choice":
5734
+ return false;
5735
+ case "dispatch":
5736
+ return capturesLeaf(d.selector, new Set(seen)) || d.cases.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) || (d.matchers ? d.matchers.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) : false) || (d.otherwise ? mayLeavePartialCapture(d.otherwise, new Set(seen), triviaActive) || capturesLeaf(d.otherwise, new Set(seen)) : false);
5737
+ case "attempt":
5738
+ return false;
5739
+ // optional never fails; many/oneOrMore only "fail" with zero captured items.
5740
+ case "optional":
5741
+ case "many":
5742
+ case "oneOrMore":
5743
+ return false;
5744
+ // sepBy emits its own per-iteration rollback in emitSepBy.
5745
+ case "sepBy":
5746
+ return false;
5747
+ // A sequence is the real case: an earlier capturing term followed by a term
5748
+ // that can fail leaves the earlier captures buffered.
5749
+ //
5750
+ // BOTH halves of that sentence are load-bearing, and the second half is what
5751
+ // this walk exists to exploit. "Some earlier term captures" alone was the old
5752
+ // test, and it is true of very nearly every sequence in a real grammar — a
5753
+ // sequence almost always opens with a literal or a node. The rollback is only
5754
+ // reachable if something AFTER the capture can still fail; once the remainder
5755
+ // is total (`optional`/`many`/trivia/a min-0 `sepBy`), the sequence has no
5756
+ // failure path left to roll back from, and the save+restore is dead code.
5757
+ //
5758
+ // `captured` tracks whether anything is in the buffers yet as the scan moves
5759
+ // left to right. Two things put it there:
5760
+ // - a term that captures (`capturesLeaf`/`hasNodeDef`), and
5761
+ // - the inter-term TRIVIA scan, which under `capturing` pushes into
5762
+ // `_cstRawChildren`/`_cstTriviaLog` BEFORE the term at each boundary
5763
+ // i >= 1. `emitSeqValues` only rewinds that push on the term's SUCCESS
5764
+ // path (the "matched empty, so leave the whitespace out of the span"
5765
+ // branch); a term that FAILS breaks straight out with the trivia still
5766
+ // buffered, so from boundary 1 onward the buffers are dirty regardless of
5767
+ // what the earlier terms did.
5768
+ // Each term is also asked about itself: a nested sequence can leave its own
5769
+ // partial capture behind, and its terms are emitted inline into this same
5770
+ // block with no boundary of their own to roll them back.
5771
+ case "sequence": {
5772
+ const parts = d.parsers;
5773
+ let captured = false;
5774
+ for (let i = 0; i < parts.length; i++) {
5775
+ const part = parts[i];
5776
+ if (i > 0 && triviaActive) captured = true;
5777
+ if (captured && mayFail(part)) return true;
5778
+ if (mayLeavePartialCapture(part, seen, triviaActive)) return true;
5779
+ if (capturesLeaf(part) || hasNodeDef(part)) captured = true;
5780
+ }
5781
+ return false;
5782
+ }
5783
+ // Delegating wrappers: defer to the wrapped parser.
5784
+ case "transform":
5785
+ case "label":
5786
+ case "field":
5787
+ case "expect":
5788
+ case "withCtx":
5789
+ case "grammar":
5790
+ return mayLeavePartialCapture(d.parser, seen, triviaActive);
5791
+ case "recover":
5792
+ return mayLeavePartialCapture(d.parser, seen, triviaActive);
5793
+ case "lazy": {
5794
+ try {
5795
+ return mayLeavePartialCapture(d.thunk(), seen, triviaActive);
5796
+ } catch {
5797
+ return true;
5798
+ }
5799
+ }
5800
+ // Unknown shapes: be safe and keep the rollback.
5801
+ default:
5802
+ return true;
5803
+ }
5804
+ }
5805
+ function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
5806
+ if (seen.has(p)) return false;
5807
+ seen.add(p);
5808
+ const d = p._def;
5809
+ switch (d.tag) {
5810
+ case "literal":
5811
+ case "regex":
5812
+ case "keywords":
5813
+ case "node":
5814
+ case "token":
5815
+ case "routed":
5816
+ case "leaf":
5817
+ return true;
5818
+ case "not":
5819
+ case "peek":
5820
+ case "guard":
5821
+ case "adjacency":
5822
+ case "trivia":
5823
+ case "unknown":
5824
+ return false;
5825
+ case "sequence":
5826
+ case "choice":
5827
+ return d.parsers.some((x) => capturesLeaf(x, seen));
5828
+ case "dispatch":
5829
+ return capturesLeaf(d.selector, seen) || d.cases.some((x) => capturesLeaf(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => capturesLeaf(entry.parser, seen)) : false) || (d.otherwise ? capturesLeaf(d.otherwise, seen) : false);
5830
+ case "sepBy":
5831
+ return capturesLeaf(d.parser, seen) || capturesLeaf(d.separator, seen);
5832
+ case "many":
5833
+ case "oneOrMore":
5834
+ case "optional":
5835
+ case "attempt":
5836
+ case "transform":
5837
+ case "label":
5838
+ case "field":
5839
+ case "expect":
5840
+ case "withCtx":
5841
+ case "grammar":
5842
+ case "recover":
5843
+ return capturesLeaf(d.parser, seen);
5844
+ case "scanTo":
5845
+ return true;
5846
+ case "lazy": {
5847
+ try {
5848
+ return capturesLeaf(d.thunk(), seen);
5849
+ } catch {
5850
+ return true;
5851
+ }
5852
+ }
5853
+ default:
5854
+ return true;
5855
+ }
5856
+ }
5857
+ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
5858
+ if (seen.has(p)) return false;
5859
+ seen.add(p);
5860
+ const d = p._def;
5861
+ switch (d.tag) {
5862
+ case "node":
5863
+ return true;
5864
+ case "lazy": {
5865
+ try {
5866
+ return hasNodeDef(d.thunk(), seen);
5867
+ } catch {
5868
+ return false;
5869
+ }
5870
+ }
5871
+ case "grammar":
5872
+ case "trivia":
5873
+ case "token":
5874
+ case "leaf":
5875
+ case "label":
5876
+ case "field":
5877
+ case "optional":
5878
+ case "many":
5879
+ case "oneOrMore":
5880
+ case "not":
5881
+ case "peek":
5882
+ case "transform":
5883
+ return hasNodeDef(d.parser, seen);
5884
+ case "sequence":
5885
+ case "choice":
5886
+ return d.parsers.some((x) => hasNodeDef(x, seen));
5887
+ case "dispatch":
5888
+ return hasNodeDef(d.selector, seen) || d.cases.some((x) => hasNodeDef(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => hasNodeDef(entry.parser, seen)) : false) || (d.otherwise ? hasNodeDef(d.otherwise, seen) : false);
5889
+ case "sepBy":
5890
+ return hasNodeDef(d.parser, seen) || hasNodeDef(d.separator, seen);
5891
+ case "scanTo":
5892
+ return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen));
5893
+ case "recover":
5894
+ return hasNodeDef(d.parser, seen) || hasNodeDef(d.sentinel, seen);
5895
+ case "expect":
5896
+ return hasNodeDef(d.parser, seen);
5897
+ case "withCtx":
5898
+ return hasNodeDef(d.parser, seen);
5899
+ default:
5900
+ return false;
5901
+ }
5902
+ }
5903
+ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve2) {
5904
+ if (seen.has(p)) return false;
5905
+ seen.add(p);
5906
+ const d = p._def;
5907
+ switch (d.tag) {
5908
+ case "dispatch":
5909
+ return true;
5910
+ case "choice":
5911
+ case "sequence":
5912
+ return d.parsers.some((x) => mayCommitFailure(x, seen, resolve2));
5913
+ case "many":
5914
+ case "oneOrMore":
5915
+ case "optional":
5916
+ case "attempt":
5917
+ case "transform":
5918
+ case "label":
5919
+ case "field":
5920
+ case "grammar":
5921
+ case "node":
5922
+ return mayCommitFailure(d.parser, seen, resolve2);
5923
+ case "sepBy":
5924
+ return mayCommitFailure(d.parser, seen, resolve2) || mayCommitFailure(d.separator, seen, resolve2);
5925
+ case "token":
5926
+ case "leaf":
5927
+ return mayCommitFailure(d.parser, seen, resolve2);
5928
+ case "withCtx":
5929
+ return mayCommitFailure(d.parser, seen, resolve2);
5930
+ case "scanTo":
5931
+ return mayCommitFailure(d.sentinel, seen, resolve2) || d.skip.some((x) => mayCommitFailure(x, seen, resolve2));
5932
+ case "lazy": {
5933
+ try {
5934
+ return mayCommitFailure(d.thunk(), seen, resolve2);
5935
+ } catch {
5936
+ const name = p._ruleName;
5937
+ const target = name === void 0 ? void 0 : resolve2?.(name);
5938
+ return target === void 0 ? true : mayCommitFailure(target, seen, resolve2);
5939
+ }
5940
+ }
5941
+ case "unknown":
5942
+ return true;
5943
+ default:
5944
+ return false;
5945
+ }
5946
+ }
5947
+
5624
5948
  // src/table/ops.ts
5625
5949
  var OP_LIT = 1;
5626
5950
  var OP_RX = 2;
@@ -6176,8 +6500,26 @@ function validateDispatchSpec(spec, arity, fallbackRouted) {
6176
6500
  }
6177
6501
  }
6178
6502
  var TABLE_RUNTIME = /* @__PURE__ */ Symbol("parseman.tableRuntime");
6179
- function ownTableProgram(prog, resolved) {
6180
- return { ...prog, [TABLE_RUNTIME]: { resolved } };
6503
+ function ownTableProgram(prog, resolved, caches = {}) {
6504
+ const runtime = prog[TABLE_RUNTIME];
6505
+ return {
6506
+ ...prog,
6507
+ [TABLE_RUNTIME]: {
6508
+ resolved,
6509
+ choiceRollbackMasks: caches.choiceRollbackMasks ?? runtime?.choiceRollbackMasks,
6510
+ nonCommittingChoiceSites: caches.nonCommittingChoiceSites ?? runtime?.nonCommittingChoiceSites,
6511
+ failureRollbackCleanSites: caches.failureRollbackCleanSites ?? runtime?.failureRollbackCleanSites
6512
+ }
6513
+ };
6514
+ }
6515
+ function choiceRollbackMask(prog, ip) {
6516
+ return prog[TABLE_RUNTIME]?.choiceRollbackMasks?.get(ip);
6517
+ }
6518
+ function choiceCannotCommit(prog, ip) {
6519
+ return prog[TABLE_RUNTIME]?.nonCommittingChoiceSites?.has(ip) === true;
6520
+ }
6521
+ function failureRollbackClean(prog, ip) {
6522
+ return prog[TABLE_RUNTIME]?.failureRollbackCleanSites?.has(ip) === true;
6181
6523
  }
6182
6524
  var WIDE_CLASS_PREFIX_LO = 65535;
6183
6525
  var WIDE_CLASS_PREFIX_HI = 0;
@@ -6352,7 +6694,6 @@ function directArrayProjection(fn, fnSrc, arity) {
6352
6694
 
6353
6695
  // src/table/encode.ts
6354
6696
  import {
6355
- assertLexicalCapabilityClosure,
6356
6697
  collectLexicalCapabilities,
6357
6698
  winnerWrapsReference as winnerWrapsReference2
6358
6699
  } from "../compiler/token-capability.js";
@@ -6734,6 +7075,25 @@ var Encoder = class {
6734
7075
  lexIndex = /* @__PURE__ */ new Map();
6735
7076
  lexPrograms = [];
6736
7077
  lexProgramIndex = /* @__PURE__ */ new Map();
7078
+ choiceRollbackMasks = /* @__PURE__ */ new Map();
7079
+ nonCommittingChoiceSites = /* @__PURE__ */ new Set();
7080
+ failureRollbackCleanSites = /* @__PURE__ */ new Set();
7081
+ /**
7082
+ * `hasSideWriter` memo for `failureNeedsRollback`, shared across every call
7083
+ * for the lifetime of this `Encoder`. A cached entry is written only when
7084
+ * `complete` is true, which means the answer is a path-independent fact
7085
+ * about that combinator node — it does not depend on which root's traversal
7086
+ * asked, only on the node's own reachable subgraph. Scoping the memo per call
7087
+ * (as a local inside `failureNeedsRollback`) was correct but discarded that
7088
+ * fact after every arm, so a grammar with many ordered-choice arms / optional
7089
+ * / attempt sites re-walked the SAME shared rule graph from scratch for each
7090
+ * site — O(sites × graph size) instead of O(graph size). Measured on the
7091
+ * scss-parser grammar (composed CSS-base superset, the deepest/largest of the
7092
+ * four grammars): 47-50s for one `compileRuleMap` with the per-call memo,
7093
+ * versus the whole macro transform completing in under a second once this
7094
+ * memo is hoisted here.
7095
+ */
7096
+ sideWriterMemo = /* @__PURE__ */ new Map();
6737
7097
  labels = void 0;
6738
7098
  /** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
6739
7099
  activeTrivia = void 0;
@@ -7144,6 +7504,72 @@ var Encoder = class {
7144
7504
  const w = this.winners;
7145
7505
  return w === void 0 ? void 0 : (name) => w[name];
7146
7506
  }
7507
+ /**
7508
+ * Whether a failed ordered-choice arm can leave state that the enclosing
7509
+ * choice must restore before trying its successor.
7510
+ *
7511
+ * `mayLeavePartialCapture` is the existing sound CST/trivia proof. The extra
7512
+ * writer census covers the side sinks that proof deliberately does not model:
7513
+ * fields, recovered errors, and interpreted scanners. Strict assemblies do
7514
+ * not run repeat recovery, but these rows can still publish through a caller's
7515
+ * context. Cycles are safe to stop: revisiting the same combinator cannot
7516
+ * discover a writer the first traversal did not already reach.
7517
+ */
7518
+ failureNeedsRollback(p, autoNot) {
7519
+ const refName = p._ruleName;
7520
+ const winner = refName === void 0 ? void 0 : this.winners?.[refName];
7521
+ const root = winner !== void 0 && !winnerWrapsReference2(winner, p) ? winner : p;
7522
+ const sideWriterMemo = this.sideWriterMemo;
7523
+ const seen = /* @__PURE__ */ new Set();
7524
+ const hasSideWriter = (current) => {
7525
+ const cached = sideWriterMemo.get(current);
7526
+ if (cached !== void 0) return { found: cached, complete: true };
7527
+ if (seen.has(current)) return { found: false, complete: false };
7528
+ seen.add(current);
7529
+ const def = current._def;
7530
+ let result;
7531
+ switch (def.tag) {
7532
+ case "field":
7533
+ case "expect":
7534
+ case "recover":
7535
+ case "scanTo":
7536
+ case "unknown":
7537
+ result = { found: true, complete: true };
7538
+ break;
7539
+ case "lazy": {
7540
+ const name = current._ruleName;
7541
+ const resolvedWinner = name === void 0 ? void 0 : this.winners?.[name];
7542
+ if (resolvedWinner !== void 0 && !winnerWrapsReference2(resolvedWinner, current)) {
7543
+ result = hasSideWriter(resolvedWinner);
7544
+ break;
7545
+ }
7546
+ try {
7547
+ result = hasSideWriter(def.thunk());
7548
+ } catch {
7549
+ result = { found: true, complete: true };
7550
+ }
7551
+ break;
7552
+ }
7553
+ default: {
7554
+ let complete = true;
7555
+ result = { found: false, complete: true };
7556
+ for (const child of childrenOf(def)) {
7557
+ const childResult = hasSideWriter(child);
7558
+ if (childResult.found) {
7559
+ result = { found: true, complete: true };
7560
+ break;
7561
+ }
7562
+ complete &&= childResult.complete;
7563
+ }
7564
+ if (!result.found) result = { found: false, complete };
7565
+ }
7566
+ }
7567
+ seen.delete(current);
7568
+ if (result.found || result.complete) sideWriterMemo.set(current, result.found);
7569
+ return result;
7570
+ };
7571
+ return mayLeavePartialCapture(root, /* @__PURE__ */ new Set(), true) || hasSideWriter(root).found || (autoNot?.length ?? 0) > 0 && capturesLeaf(root);
7572
+ }
7147
7573
  /** A first set becomes a char class string, or −1 for `any`. */
7148
7574
  charClass(fs) {
7149
7575
  if (fs.kind !== "ranges" || fs.ranges.length === 0) return -1;
@@ -7429,9 +7855,39 @@ var Encoder = class {
7429
7855
  });
7430
7856
  const rr = this.refResolver();
7431
7857
  const finalChoice = classifyFinalChoice(arms, rr);
7432
- const classes = arms.map((_, i) => finalChoice.nullable[i] ? -1 : this.charClass(finalChoice.firstSets[i]));
7858
+ const transactionalFirst = arms.map((arm, i) => {
7859
+ if (!finalChoice.nullable[i]) return void 0;
7860
+ const def = arm._def;
7861
+ if (def.tag !== "attempt" || matchesEmpty(def.parser, /* @__PURE__ */ new Set(), rr)) return void 0;
7862
+ return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr);
7863
+ });
7864
+ const gateFirst = finalChoice.firstSets.map((first, i) => transactionalFirst[i] ?? first);
7865
+ const classes = gateFirst.map((first, i) => finalChoice.nullable[i] && transactionalFirst[i] === void 0 ? -1 : this.charClass(first));
7866
+ if (transactionalFirst.some((first) => first !== void 0) && classes.every((cls) => cls >= 0)) {
7867
+ let overlap = false;
7868
+ for (let i = 0; i < gateFirst.length && !overlap; i++) {
7869
+ for (let j = i + 1; j < gateFirst.length; j++) {
7870
+ if (intersects(gateFirst[i], gateFirst[j])) {
7871
+ overlap = true;
7872
+ break;
7873
+ }
7874
+ }
7875
+ }
7876
+ if (!overlap) for (let i = 0; i < classes.length; i++) {
7877
+ if (transactionalFirst[i] !== void 0) classes[i] = -1;
7878
+ }
7879
+ }
7433
7880
  const dispIdx = this.disp.length;
7434
7881
  this.disp.push(classes);
7882
+ let rollbackMask = kids.length > 31 ? -1 : 0;
7883
+ if (rollbackMask === 0) {
7884
+ for (let i = 0; i < arms.length; i++) {
7885
+ const src = order[i];
7886
+ if (this.failureNeedsRollback(arms[i], d.autoNot[src])) {
7887
+ rollbackMask |= 1 << i;
7888
+ }
7889
+ }
7890
+ }
7435
7891
  const head = this.emitHead(OP_CHOICE, 3 + 2 * kids.length);
7436
7892
  this.code[head + 1] = dispIdx;
7437
7893
  this.code[head + 2] = kids.length;
@@ -7440,6 +7896,10 @@ var Encoder = class {
7440
7896
  this.code[head + 4 + i] = kids[i];
7441
7897
  this.code[head + 4 + kids.length + i] = this.expected(deriveExpected(arms[i]));
7442
7898
  }
7899
+ this.choiceRollbackMasks.set(head, rollbackMask);
7900
+ if (arms.every((arm) => !mayCommitFailure(arm, /* @__PURE__ */ new Set(), rr))) {
7901
+ this.nonCommittingChoiceSites.add(head);
7902
+ }
7443
7903
  return head;
7444
7904
  }
7445
7905
  case "many":
@@ -7469,8 +7929,11 @@ var Encoder = class {
7469
7929
  }
7470
7930
  return d.min >= 2 ? this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags, this.expected(deriveExpected(d.parser))) : this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags);
7471
7931
  }
7472
- case "optional":
7473
- return this.emit(OP_OPT, this.node(d.parser).ip);
7932
+ case "optional": {
7933
+ const head = this.emit(OP_OPT, this.node(d.parser).ip);
7934
+ if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(head);
7935
+ return head;
7936
+ }
7474
7937
  case "transform": {
7475
7938
  const inner = d.parser._def;
7476
7939
  if (inner.tag === "sequence" && !this.memo.has(d.parser) && !this.pending.has(d.parser)) {
@@ -7629,6 +8092,7 @@ var Encoder = class {
7629
8092
  // lowering was correct only for a choice arm.
7630
8093
  case "attempt": {
7631
8094
  const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
8095
+ if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
7632
8096
  const fs = d.parser._meta.firstSet;
7633
8097
  if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
7634
8098
  const cls = this.charClass(fs);
@@ -7797,6 +8261,10 @@ var Encoder = class {
7797
8261
  ...this.rec ? { rec: 1 } : {},
7798
8262
  ...this.cov === void 0 ? {} : { cov: this.cov },
7799
8263
  lines: this.track ? 1 : 0
8264
+ }, void 0, {
8265
+ choiceRollbackMasks: this.choiceRollbackMasks,
8266
+ failureRollbackCleanSites: this.failureRollbackCleanSites,
8267
+ nonCommittingChoiceSites: this.nonCommittingChoiceSites
7800
8268
  });
7801
8269
  }
7802
8270
  };
@@ -7841,7 +8309,6 @@ function encodeTableProgram(ruleMap, settings = {}) {
7841
8309
  const lexicalRoots = [...names].sort().map((name) => ruleMap[name]);
7842
8310
  const resolveLexical = (name) => ruleMap[name];
7843
8311
  const capabilities = collectLexicalCapabilities(lexicalRoots, resolveLexical);
7844
- assertLexicalCapabilityClosure(lexicalRoots, capabilities, resolveLexical);
7845
8312
  const enc = new Encoder(resolvedSettings, capabilities.capabilityComplete);
7846
8313
  enc.winners = ruleMap;
7847
8314
  for (const name of names) enc.encodeRule(name, ruleMap[name]);
@@ -8974,13 +9441,17 @@ var TRI_NONE = -1;
8974
9441
  var CAP_UNKNOWN = 0;
8975
9442
  var CAP_OFF = 1;
8976
9443
  var CAP_ON = 2;
8977
- var TOP = { tri: TRI_UNKNOWN, buf: false, cap: CAP_UNKNOWN };
9444
+ var RAW_UNKNOWN = 0;
9445
+ var RAW_CAPTURE = 1;
9446
+ var RAW_OMIT = 2;
9447
+ var TOP = { tri: TRI_UNKNOWN, buf: false, raw: RAW_UNKNOWN, cap: CAP_UNKNOWN };
8978
9448
  function meet(a, b) {
8979
9449
  const tri = a.tri === b.tri ? a.tri : TRI_UNKNOWN;
8980
9450
  const buf = a.buf && b.buf;
9451
+ const raw = a.raw === b.raw ? a.raw : RAW_UNKNOWN;
8981
9452
  const cap = a.cap === b.cap ? a.cap : CAP_UNKNOWN;
8982
- if (tri === a.tri && buf === a.buf && cap === a.cap) return a;
8983
- return { tri, buf, cap };
9453
+ if (tri === a.tri && buf === a.buf && raw === a.raw && cap === a.cap) return a;
9454
+ return { tri, buf, raw, cap };
8984
9455
  }
8985
9456
  function reachableSites(code, roots) {
8986
9457
  const seen = /* @__PURE__ */ new Set();
@@ -9003,25 +9474,26 @@ function transfer(code, ip, at, hostCst) {
9003
9474
  const tri = ki < 0 ? TRI_NONE : ki;
9004
9475
  const cap = op === OP_SCOPE_CAP ? CAP_ON : at.cap;
9005
9476
  if (tri === at.tri && cap === at.cap) return at;
9006
- return { tri, buf: at.buf, cap };
9477
+ return { tri, buf: at.buf, raw: at.raw, cap };
9007
9478
  }
9008
9479
  if (op === OP_NODE || op === OP_NODE_TRACK) {
9009
9480
  const flags = code[ip + 3];
9010
9481
  const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
9011
9482
  if (directChildren) {
9012
- return { tri: at.tri, buf: false, cap: CAP_OFF };
9483
+ return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
9013
9484
  }
9014
9485
  const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
9015
- if (at.buf && cap === at.cap) return at;
9016
- return { tri: at.tri, buf: true, cap };
9486
+ const raw = !hostCst && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags & 2) !== 0 ? RAW_OMIT : RAW_CAPTURE;
9487
+ if (at.buf && raw === at.raw && cap === at.cap) return at;
9488
+ return { tri: at.tri, buf: true, raw, cap };
9017
9489
  }
9018
9490
  if (op === OP_TOKEN) {
9019
9491
  if (at.tri === TRI_NONE && !at.buf) return at;
9020
- return { tri: TRI_NONE, buf: false, cap: at.cap };
9492
+ return { tri: TRI_NONE, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
9021
9493
  }
9022
9494
  if (op === OP_LEAF) {
9023
9495
  if (!at.buf) return at;
9024
- return { tri: at.tri, buf: false, cap: at.cap };
9496
+ return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
9025
9497
  }
9026
9498
  return at;
9027
9499
  }
@@ -9088,6 +9560,162 @@ function scalarTerminalNotChild(code, ip) {
9088
9560
  const op = code[child];
9089
9561
  return op === OP_RX || op === OP_LIT ? child : -1;
9090
9562
  }
9563
+ function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, throughPeek = false) {
9564
+ const seen = /* @__PURE__ */ new Set();
9565
+ let at = ip;
9566
+ let depth = 0;
9567
+ while (!seen.has(at)) {
9568
+ seen.add(at);
9569
+ const op = code[at];
9570
+ if (op === OP_LIT || op === OP_RX) return depth >= minDepth ? at : -1;
9571
+ if (op === OP_RULE || op === OP_LABEL || op === OP_TOKEN || throughAttempt && op === OP_ATTEMPT) {
9572
+ at = code[at + 1];
9573
+ depth++;
9574
+ continue;
9575
+ }
9576
+ if (throughPeek && op === OP_PEEK) {
9577
+ at = code[at + 1];
9578
+ depth++;
9579
+ continue;
9580
+ }
9581
+ 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) {
9582
+ at = code[at + 2];
9583
+ depth++;
9584
+ continue;
9585
+ }
9586
+ if (op === OP_SEQ || op === OP_SEQV) {
9587
+ if (code[at + 1] < 1) return -1;
9588
+ at = code[at + 2];
9589
+ depth++;
9590
+ continue;
9591
+ }
9592
+ if (op === OP_SEQX) {
9593
+ if (code[at + 2] < 1) return -1;
9594
+ at = code[at + 3];
9595
+ depth++;
9596
+ continue;
9597
+ }
9598
+ return -1;
9599
+ }
9600
+ return -1;
9601
+ }
9602
+ function leadingScalarSequence(code, ip) {
9603
+ const wholeScalar = (start) => {
9604
+ const seen2 = /* @__PURE__ */ new Set();
9605
+ let at2 = start;
9606
+ while (!seen2.has(at2)) {
9607
+ seen2.add(at2);
9608
+ const op = code[at2];
9609
+ if (op === OP_LIT || op === OP_RX) return at2;
9610
+ if (op === OP_RULE || op === OP_TOKEN || op === OP_ATTEMPT) {
9611
+ at2 = code[at2 + 1];
9612
+ continue;
9613
+ }
9614
+ if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
9615
+ at2 = code[at2 + 2];
9616
+ continue;
9617
+ }
9618
+ if (op === OP_SEQ || op === OP_SEQV) {
9619
+ if (code[at2 + 1] !== 1) return -1;
9620
+ at2 = code[at2 + 2];
9621
+ continue;
9622
+ }
9623
+ if (op === OP_SEQX) {
9624
+ if (code[at2 + 2] !== 1) return -1;
9625
+ at2 = code[at2 + 3];
9626
+ continue;
9627
+ }
9628
+ return -1;
9629
+ }
9630
+ return -1;
9631
+ };
9632
+ const seen = /* @__PURE__ */ new Set();
9633
+ let at = ip;
9634
+ let ambientTrivia;
9635
+ while (!seen.has(at)) {
9636
+ seen.add(at);
9637
+ const op = code[at];
9638
+ if (op === OP_RULE) {
9639
+ at = code[at + 1];
9640
+ continue;
9641
+ }
9642
+ if (op === OP_SCOPE_PLAIN) {
9643
+ ambientTrivia = code[at + 1];
9644
+ at = code[at + 2];
9645
+ continue;
9646
+ }
9647
+ if (op === OP_GATE || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
9648
+ at = code[at + 2];
9649
+ continue;
9650
+ }
9651
+ const n = op === OP_SEQ || op === OP_SEQV ? code[at + 1] : op === OP_SEQX ? code[at + 2] : 0;
9652
+ if (n < 3 || ambientTrivia === void 0) return void 0;
9653
+ const base = op === OP_SEQX ? at + 3 : at + 2;
9654
+ const terminals = [
9655
+ wholeScalar(code[base]),
9656
+ wholeScalar(code[base + 1]),
9657
+ wholeScalar(code[base + 2])
9658
+ ];
9659
+ return terminals.every((terminal) => terminal >= 0) ? { terminals, trivia: ambientTrivia } : void 0;
9660
+ }
9661
+ return void 0;
9662
+ }
9663
+ function leadingLiteralFamily(code, constants, ip, minDepth = 2, limit = 4) {
9664
+ const active = /* @__PURE__ */ new Set();
9665
+ const walk = (at, depth) => {
9666
+ if (active.has(at)) return void 0;
9667
+ active.add(at);
9668
+ try {
9669
+ const op = code[at];
9670
+ if (op === OP_LIT) {
9671
+ const value = constants[code[at + 1]];
9672
+ return depth >= minDepth && typeof value === "string" && value.length > 0 ? [at] : void 0;
9673
+ }
9674
+ if (op === OP_RULE || op === OP_LABEL || op === OP_TOKEN || op === OP_ATTEMPT || op === OP_PEEK) {
9675
+ return walk(code[at + 1], depth + 1);
9676
+ }
9677
+ 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) {
9678
+ return walk(code[at + 2], depth + 1);
9679
+ }
9680
+ if (op === OP_SEQ || op === OP_SEQV) {
9681
+ return code[at + 1] < 1 ? void 0 : walk(code[at + 2], depth + 1);
9682
+ }
9683
+ if (op === OP_SEQX) {
9684
+ return code[at + 2] < 1 ? void 0 : walk(code[at + 3], depth + 1);
9685
+ }
9686
+ if (op !== OP_CHOICE) return void 0;
9687
+ const n = code[at + 2];
9688
+ if (n < 1) return void 0;
9689
+ const out = [];
9690
+ for (let i = 0; i < n; i++) {
9691
+ const branch = walk(code[at + 4 + i], depth + 1);
9692
+ if (branch === void 0) return void 0;
9693
+ for (const terminal of branch) {
9694
+ const value = constants[code[terminal + 1]];
9695
+ let covered = false;
9696
+ for (let j = 0; j < out.length; j++) {
9697
+ const prior = constants[code[out[j] + 1]];
9698
+ if (value.startsWith(prior)) {
9699
+ covered = true;
9700
+ break;
9701
+ }
9702
+ }
9703
+ if (covered) continue;
9704
+ for (let j = out.length - 1; j >= 0; j--) {
9705
+ const prior = constants[code[out[j] + 1]];
9706
+ if (prior.startsWith(value)) out.splice(j, 1);
9707
+ }
9708
+ out.push(terminal);
9709
+ if (out.length > limit) return void 0;
9710
+ }
9711
+ }
9712
+ return out;
9713
+ } finally {
9714
+ active.delete(at);
9715
+ }
9716
+ };
9717
+ return walk(ip, 0);
9718
+ }
9091
9719
 
9092
9720
  // src/table/emit-assembly.ts
9093
9721
  var Unemittable = class extends Error {
@@ -9169,6 +9797,16 @@ let _pfScan=null
9169
9797
  let _pfHost
9170
9798
  let _pfDepth=0
9171
9799
  const _pfFrames=[]
9800
+ let _pfTokInput
9801
+ let _pfTokPos=-1
9802
+ let _pfTokBody=-1
9803
+ let _pfTokPacked=-1
9804
+ let _pfTokValue
9805
+ let _pfTokDispatch=-1
9806
+ let _pfTokArm=-1
9807
+ let _pfTokEnd=-1
9808
+ let _pfSeqEnd=-1
9809
+ function _asciiFoldCode(c){return c>=65&&c<=90?c+32:c}
9172
9810
  function _skipTrivia(input,cur,ctx){
9173
9811
  const s=_pfScan
9174
9812
  if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
@@ -9234,6 +9872,40 @@ if(ctx._triviaLog!==undefined&&ctx._triviaLog.length!==lg)ctx._triviaLog.length=
9234
9872
  if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTriviaLog.length=rt
9235
9873
  }
9236
9874
  `;
9875
+ var NO_RAW_RUNTIME_PRELUDE = `
9876
+ function _pushLeafNoRawBuf(ctx,value,s,e){
9877
+ const l={_tag:'leaf',value,span:{start:s,end:e}}
9878
+ const b=ctx._cstBuf
9879
+ if(b.ch!==undefined)b.ch.push(l)
9880
+ else if(b.single!==undefined){b.ch=[b.single,l];b.single=undefined}
9881
+ else b.single=l
9882
+ b.rawLen++
9883
+ }
9884
+ function _pushNodeNoRawBuf(ctx,value){
9885
+ const b=ctx._cstBuf
9886
+ if(b.ch!==undefined)b.ch.push(value)
9887
+ else if(b.single!==undefined){b.ch=[b.single,value];b.single=undefined}
9888
+ else b.single=value
9889
+ b.rawLen++
9890
+ }
9891
+ function _rbNoRawBuf(ctx,raw,tl,lv,lg,rt){
9892
+ const b=ctx._cstBuf
9893
+ if(b.rawLen!==raw)b.rawLen=raw
9894
+ const ch=b.ch
9895
+ if(ch!==undefined){
9896
+ if(lv===0)b.ch=undefined
9897
+ else if(lv===1){b.single=ch[0];b.ch=undefined}
9898
+ else if(ch.length!==lv)ch.length=lv
9899
+ }else if(lv===0)b.single=undefined
9900
+ const bt=b.tl
9901
+ if(bt!==undefined){
9902
+ if(tl===0)b.tl=undefined
9903
+ else if(bt.length!==tl)bt.length=tl
9904
+ }
9905
+ if(ctx._triviaLog!==undefined&&ctx._triviaLog.length!==lg)ctx._triviaLog.length=lg
9906
+ if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTriviaLog.length=rt
9907
+ }
9908
+ `;
9237
9909
  function q(s) {
9238
9910
  return JSON.stringify(s);
9239
9911
  }
@@ -9246,11 +9918,12 @@ function sinkReads(t2, s) {
9246
9918
  ${t2}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${s.er ? `
9247
9919
  ${t2}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
9248
9920
  }
9249
- function emitMark(t2, buf, s = NO_SINKS, decl = true) {
9921
+ function emitMark(t2, buf, rawMode, s = NO_SINKS, decl = true) {
9250
9922
  if (buf) {
9923
+ const raw = rawMode === RAW_OMIT ? `${t2}raw=b.rawLen` : rawMode === RAW_CAPTURE ? `const r=b.raw;${t2}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0` : `const r=b.raw;${t2}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)`;
9251
9924
  return `${decl ? `let ${t2}raw=0,${t2}tl=0,${t2}lv=0,${t2}lg=0,${t2}rt=0${sinkSlots(t2, s)}
9252
9925
  ` : ""}{const b=ctx._cstBuf
9253
- const r=b.raw;${t2}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
9926
+ ${raw}
9254
9927
  const h=b.ch;${t2}lv=h!==undefined?h.length:b.single!==undefined?1:0
9255
9928
  const l=b.tl;${t2}tl=l!==undefined?l.length:0
9256
9929
  ${t2}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
@@ -9260,7 +9933,7 @@ ${t2}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${sinkReads(t2
9260
9933
  ` : `${t2}n=false
9261
9934
  `}{const b=ctx._cstBuf
9262
9935
  if(b!==undefined){
9263
- const r=b.raw;${t2}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
9936
+ const r=b.raw;${t2}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)
9264
9937
  const h=b.ch;${t2}lv=h!==undefined?h.length:b.single!==undefined?1:0
9265
9938
  const l=b.tl;${t2}tl=l!==undefined?l.length:0
9266
9939
  ${t2}n=true
@@ -9275,14 +9948,16 @@ ${t2}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
9275
9948
  ${t2}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${sinkReads(t2, s)}
9276
9949
  }}`;
9277
9950
  }
9278
- function emitRollback(t2, buf, s = NO_SINKS) {
9951
+ function emitRollback(t2, buf, rawMode, s = NO_SINKS) {
9279
9952
  const fd = s.fd ? `
9280
9953
  if(ctx._fields!==undefined&&ctx._fields.length!==${t2}fd)ctx._fields.length=${t2}fd` : "";
9281
9954
  const er = s.er ? `
9282
9955
  if(ctx._errors!==undefined&&ctx._errors.length!==${t2}er)ctx._errors.length=${t2}er` : "";
9283
- if (buf) return `_rbBuf(ctx,${t2}raw,${t2}tl,${t2}lv,${t2}lg,${t2}rt)${fd}${er}`;
9284
- if (!s.fd && !s.er) return `if(${t2}n)rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,0,undefined,${t2}lg,${t2}rt)`;
9285
- return `if(${t2}n){rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,${s.fd ? `${t2}fd` : "0"},${s.er ? `${t2}er` : "undefined"},${t2}lg,${t2}rt)}`;
9956
+ if (buf && rawMode === RAW_OMIT) return `_rbNoRawBuf(ctx,${t2}raw,${t2}tl,${t2}lv,${t2}lg,${t2}rt)${fd}${er}`;
9957
+ if (buf && rawMode === RAW_CAPTURE) return `_rbBuf(ctx,${t2}raw,${t2}tl,${t2}lv,${t2}lg,${t2}rt)${fd}${er}`;
9958
+ if (buf) return `rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,${s.fd ? `${t2}fd` : "undefined"},${s.er ? `${t2}er` : "undefined"},${t2}lg,${t2}rt)`;
9959
+ if (!s.fd && !s.er) return `if(${t2}n)rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,undefined,undefined,${t2}lg,${t2}rt)`;
9960
+ return `if(${t2}n){rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,${s.fd ? `${t2}fd` : "undefined"},${s.er ? `${t2}er` : "undefined"},${t2}lg,${t2}rt)}`;
9286
9961
  }
9287
9962
  function emitTerm(callee, dst, t2, l, skip) {
9288
9963
  const fast = `const ${t2}v=${callee}(input,cur,ctx)
@@ -9340,37 +10015,111 @@ function rebuildPools(cc, fx, disp, plan) {
9340
10015
  })
9341
10016
  };
9342
10017
  }
9343
- function emitAssemblySource(t2, prog, cfg, extraIps = []) {
9344
- const { code, k, disp, dsp, triviaLabelled } = t2;
10018
+ function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false) {
10019
+ const { code, k, fx, disp, dsp, triviaLabelled } = t2;
9345
10020
  const swapLegal = !cfg.trackLines;
9346
10021
  const hostCst = cfg.hostCst;
9347
10022
  const REC = prog.rec === 1 && cfg.tolerant;
9348
10023
  if (cfg.coverage) throw new Unemittable("a coverage assembly");
9349
10024
  const roots = [...Object.values(prog.rules), ...extraIps];
10025
+ const reachable = [...reachableSites(code, roots)];
9350
10026
  const labels = computeSiteLabels(code, roots, hostCst);
9351
10027
  const scalarSpecs = /* @__PURE__ */ new Set();
10028
+ const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
10029
+ const largeChoiceLiteralFamilies = /* @__PURE__ */ new Map();
10030
+ const largeChoiceScalarSequences = /* @__PURE__ */ new Map();
10031
+ const tokenChoiceCandidates = /* @__PURE__ */ new Map();
10032
+ const tokenChoiceDispatches = /* @__PURE__ */ new Set();
10033
+ const tokenChoiceBodies = /* @__PURE__ */ new Set();
9352
10034
  if (!hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
9353
- for (const ip of reachableSites(code, roots)) {
9354
- if (code[ip] !== OP_NODE) continue;
9355
- const child = scalarTerminalNodeChild(code, ip);
9356
- if (child >= 0) scalarSpecs.add(code[child + 1]);
10035
+ for (const ip of reachable) {
10036
+ if (code[ip] === OP_NODE) {
10037
+ const child = scalarTerminalNodeChild(code, ip);
10038
+ if (child >= 0) scalarSpecs.add(code[child + 1]);
10039
+ continue;
10040
+ }
10041
+ if (code[ip] !== OP_CHOICE || disp[code[ip + 1]].exclusive) continue;
10042
+ const n = code[ip + 2];
10043
+ for (let i = 0; i < n; i++) {
10044
+ const armIp = code[ip + 4 + i];
10045
+ const child = leadingScalarTerminal(code, armIp, 2, true, true);
10046
+ if (n === 2 || n === 3) {
10047
+ if (child >= 0) scalarSpecs.add(code[child + 1]);
10048
+ continue;
10049
+ }
10050
+ if (child >= 0) {
10051
+ const spec = k[code[child + 1]];
10052
+ if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) {
10053
+ largeChoiceScalarSpecs.add(code[child + 1]);
10054
+ continue;
10055
+ }
10056
+ }
10057
+ const family = leadingLiteralFamily(code, k, armIp);
10058
+ if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
10059
+ const value = k[code[terminal + 1]];
10060
+ return typeof value === "string" && value.length >= 2;
10061
+ })) {
10062
+ largeChoiceLiteralFamilies.set(armIp, family);
10063
+ }
10064
+ const sequence6 = leadingScalarSequence(code, armIp);
10065
+ if (sequence6 !== void 0 && (sequence6.trivia < 0 || swapLegal && t2.triviaScan[sequence6.trivia] != null)) {
10066
+ largeChoiceScalarSequences.set(armIp, sequence6);
10067
+ }
10068
+ }
10069
+ let candidate;
10070
+ let ambiguous = false;
10071
+ for (let i = 0; i < n; i++) {
10072
+ const armIp = code[ip + 4 + i];
10073
+ if (code[armIp] !== OP_XFORM) continue;
10074
+ const dispatchIp = code[armIp + 2];
10075
+ if (code[dispatchIp] !== OP_DISPATCH) continue;
10076
+ const selectorIp = code[dispatchIp + 1];
10077
+ if (code[selectorIp] !== OP_LEX_BODY) continue;
10078
+ if (candidate !== void 0) {
10079
+ ambiguous = true;
10080
+ break;
10081
+ }
10082
+ candidate = { arm: i, dispatchIp };
10083
+ }
10084
+ if (!ambiguous && candidate !== void 0) {
10085
+ tokenChoiceCandidates.set(ip, candidate);
10086
+ tokenChoiceDispatches.add(candidate.dispatchIp);
10087
+ tokenChoiceBodies.add(code[code[candidate.dispatchIp + 1] + 1]);
10088
+ }
9357
10089
  }
9358
10090
  }
9359
- const sinks = (() => {
9360
- let fd = false;
9361
- let er = REC;
9362
- for (const ip of reachableSites(code, roots)) {
9363
- const op = code[ip];
9364
- if (op === OP_SCAN) {
9365
- fd = true;
9366
- er = true;
9367
- break;
10091
+ const needsNoRawPrelude = !hostCst && reachable.some((ip) => {
10092
+ const op = code[ip];
10093
+ return (op === OP_NODE || op === OP_NODE_TRACK) && code[ip + 1] >= 0 && code[ip + 4] < 0 && (code[ip + 3] & 2) !== 0;
10094
+ });
10095
+ const sinkSites = reachable;
10096
+ const sinkBits = /* @__PURE__ */ new Map();
10097
+ for (const ip of sinkSites) {
10098
+ const op = code[ip];
10099
+ sinkBits.set(
10100
+ ip,
10101
+ op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC && (op === OP_REP || op === OP_REPV) ? 2 : 0)
10102
+ );
10103
+ }
10104
+ const sinkKids = [];
10105
+ let sinkChanged = true;
10106
+ while (sinkChanged) {
10107
+ sinkChanged = false;
10108
+ for (const ip of sinkSites) {
10109
+ let bits = sinkBits.get(ip) ?? 0;
10110
+ sinkKids.length = 0;
10111
+ childSlots(code, ip, sinkKids);
10112
+ for (let i = 0; i < sinkKids.length; i++) bits |= sinkBits.get(sinkKids[i]) ?? 0;
10113
+ if (bits !== sinkBits.get(ip)) {
10114
+ sinkBits.set(ip, bits);
10115
+ sinkChanged = true;
9368
10116
  }
9369
- if (op === OP_FIELD) fd = true;
9370
- else if (op === OP_EXPECT) er = true;
9371
10117
  }
9372
- return { fd, er };
9373
- })();
10118
+ }
10119
+ const sinksAt = (ip) => {
10120
+ const bits = sinkBits.get(ip) ?? 0;
10121
+ return bits === 0 ? NO_SINKS : { fd: (bits & 1) !== 0, er: (bits & 2) !== 0 };
10122
+ };
9374
10123
  const bodies = [];
9375
10124
  const byIp = /* @__PURE__ */ new Map();
9376
10125
  const reached = /* @__PURE__ */ new Set();
@@ -9397,9 +10146,117 @@ function emitAssemblySource(t2, prog, cfg, extraIps = []) {
9397
10146
  const fxRef = (i) => hoist("fx", `FX[${i}]`);
9398
10147
  const fnRef = (i) => hoist("fn", `FNS[${i}]`);
9399
10148
  const recognizerRef = (i) => hoist("rec", `RECOG[${i}]`);
10149
+ const scalarSequenceRefs = /* @__PURE__ */ new Map();
10150
+ const scalarSequenceRef = (sequence6) => {
10151
+ const key = `${sequence6.trivia}:${sequence6.terminals.map((terminal) => code[terminal + 1]).join(",")}`;
10152
+ const prior = scalarSequenceRefs.get(key);
10153
+ if (prior !== void 0) return prior;
10154
+ const recognizers = sequence6.terminals.map((terminal) => recognizerRef(code[terminal + 1]));
10155
+ const expected = sequence6.terminals.map((terminal) => fxRef(code[terminal + 2]));
10156
+ const scan = sequence6.trivia < 0 ? void 0 : hoist("ts", `TRIVIASCAN[${sequence6.trivia}]`);
10157
+ const name = `_sd${scalarSequenceRefs.size}_`;
10158
+ const steps = recognizers.map((recognize, i) => `${i === 0 ? "let " : ""}at=${i === 0 ? "pos" : scan === void 0 ? "cur" : `${scan}(input,cur)`}
10159
+ ${i === 0 ? "let " : ""}cur=${recognize}(input,at)
10160
+ if(cur<0){_pfSeqEnd=at;return ${~i}}`).join("\n");
10161
+ choiceDefs.push(`function ${name}(input,pos){
10162
+ ${steps}
10163
+ return cur
10164
+ }`);
10165
+ const made = { name, expected };
10166
+ scalarSequenceRefs.set(key, made);
10167
+ return made;
10168
+ };
9400
10169
  const sentRef = (cls) => cls < 0 ? "undefined" : hoist("sent", `SENTS[${cls}]`);
9401
10170
  let uid = 0;
9402
10171
  const tmp = () => `_t${uid++}_`;
10172
+ const dispatchClaim = (m) => {
10173
+ switch (m[0]) {
10174
+ case 0:
10175
+ return `key.startsWith(${q(m[1])})`;
10176
+ case 1:
10177
+ return `key.endsWith(${q(m[1])})`;
10178
+ case 3:
10179
+ return `asciiFoldKey(key).startsWith(${q(m[1])})`;
10180
+ case 4:
10181
+ return `asciiFoldKey(key).endsWith(${q(m[1])})`;
10182
+ default: {
10183
+ if (!m[2].includes("g") && !m[2].includes("y")) {
10184
+ try {
10185
+ new RegExp(m[1], m[2]);
10186
+ return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
10187
+ } catch {
10188
+ }
10189
+ }
10190
+ return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
10191
+ }
10192
+ }
10193
+ };
10194
+ const tokenDecisionRefs = /* @__PURE__ */ new Map();
10195
+ function tokenDecisionFor(dispatchIp) {
10196
+ const prior = tokenDecisionRefs.get(dispatchIp);
10197
+ if (prior !== void 0) return prior;
10198
+ const selectorIp = code[dispatchIp + 1];
10199
+ const body = code[selectorIp + 1];
10200
+ const lineFlags = code[selectorIp + 4];
10201
+ const hasSuffix = (lineFlags & 4) !== 0;
10202
+ const di = code[dispatchIp + 2];
10203
+ const spec = dsp[di];
10204
+ const n = code[dispatchIp + 5];
10205
+ validateDispatchSpec(spec, n, code[dispatchIp + 4]);
10206
+ const recognize = hoist("lex", `LEX[${body}]`);
10207
+ const bk = hoist("bk", `DSP[${di}].byKey`);
10208
+ const expected = hoist("dx", `DSP[${di}].expected`);
10209
+ const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
10210
+ ` : "";
10211
+ const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
10212
+ ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${dispatchClaim(m)})arm=${m[3]}`).join("\n")}
10213
+ }
10214
+ `;
10215
+ const foldedEntries = [...spec.byFold.entries()];
10216
+ const fixedFunctionChoice = spec.byKey.size === 0 && foldedEntries.length === 1 && spec.match.length === 1 && spec.match[0][0] === 2 && spec.match[0][1] === "^(?!(?:url|calc)\\($).+\\($" && spec.match[0][2] === "i" && code[dispatchIp + 3] < 0;
10217
+ const foldedRangeEquals = (value) => {
10218
+ const folded = value.replace(/[A-Z]/g, (c) => c.toLowerCase());
10219
+ return `e-pos===${folded.length}&&${[...folded].map((c, i) => {
10220
+ const cc = c.charCodeAt(0);
10221
+ return `_asciiFoldCode(input.charCodeAt(pos+${i}))===${cc}`;
10222
+ }).join("&&")}`;
10223
+ };
10224
+ const classify = fixedFunctionChoice ? (() => {
10225
+ const [exact, exactArm] = foldedEntries[0];
10226
+ const genericArm = spec.match[0][3];
10227
+ return `let arm
10228
+ if(${foldedRangeEquals(exact)})arm=${exactArm}
10229
+ else if(sm&&e>pos+1){
10230
+ let clean=true
10231
+ for(let i=pos;i<e;i++){const c=input.charCodeAt(i);if(c===10||c===13||c===0x2028||c===0x2029){clean=false;break}}
10232
+ if(clean&&!(${foldedRangeEquals("url(")})&&!(${foldedRangeEquals("calc(")}))arm=${genericArm}
10233
+ }`;
10234
+ })() : `const key=input.slice(pos,e)
10235
+ let arm=${bk}.get(key)
10236
+ ${fold}${chain}`;
10237
+ const name = `_td${tokenDecisionRefs.size}_`;
10238
+ choiceDefs.push(`function ${name}(input,pos){
10239
+ const r=${recognize}(input,pos)
10240
+ if(r<0)return -1
10241
+ const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
10242
+ ${classify}
10243
+ if(arm===undefined){
10244
+ ${code[dispatchIp + 3] < 0 ? "_pfTokEnd=e;return 0" : `arm=${n}`}
10245
+ }
10246
+ ${fixedFunctionChoice ? "const key=input.slice(pos,e)" : ""}
10247
+ _pfTokInput=input
10248
+ _pfTokPos=pos
10249
+ _pfTokBody=${body}
10250
+ _pfTokPacked=r
10251
+ _pfTokValue=key
10252
+ _pfTokDispatch=${dispatchIp}
10253
+ _pfTokArm=arm
10254
+ return 1
10255
+ }`);
10256
+ const made = { name, expected };
10257
+ tokenDecisionRefs.set(dispatchIp, made);
10258
+ return made;
10259
+ }
9403
10260
  function skipFor(l) {
9404
10261
  if (l.tri < 0) return "_skipTrivia";
9405
10262
  const ki = l.tri;
@@ -9487,7 +10344,8 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
9487
10344
  const op = code[ip];
9488
10345
  const head = `function ${fname}(input,pos,ctx){`;
9489
10346
  const L = labels.at(ip);
9490
- const pushLeaf = L.buf && !cfg.trackLines ? "_pushLeafBuf" : "_pushLeaf";
10347
+ const sinks = sinksAt(ip);
10348
+ const pushLeaf = L.buf && !cfg.trackLines ? L.raw === RAW_OMIT ? "_pushLeafNoRawBuf" : L.raw === RAW_CAPTURE ? "_pushLeafBuf" : "_pushLeaf" : "_pushLeaf";
9491
10349
  const captureLeaf = (value) => {
9492
10350
  const call = `${pushLeaf}(ctx,${value},pos,e)`;
9493
10351
  return L.buf ? call : `if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)${call}`;
@@ -9738,20 +10596,24 @@ return out
9738
10596
  }`;
9739
10597
  }
9740
10598
  case OP_LEX_BODY: {
9741
- const recognize = hoist("lex", `LEX[${code[ip + 1]}]`);
10599
+ const body = code[ip + 1];
10600
+ const recognize = hoist("lex", `LEX[${body}]`);
9742
10601
  const expected = fxRef(code[ip + 2]);
9743
10602
  const suffixExpected = fxRef(code[ip + 3]);
9744
10603
  const lineFlags = code[ip + 4];
9745
10604
  const hasSuffix = (lineFlags & 4) !== 0;
10605
+ const pending = tokenChoiceBodies.has(body);
9746
10606
  return `${head}
9747
- const r=${recognize}(input,pos)
10607
+ ${pending ? `const tp=_pfTokBody===${body}&&_pfTokInput===input&&_pfTokPos===pos
10608
+ const r=tp?_pfTokPacked:${recognize}(input,pos)` : `const r=${recognize}(input,pos)`}
9748
10609
  if(r<0){ctx._fe=pos;ctx._fx=${expected};if(ctx._probe!==undefined)failAt(ctx,${expected},pos);return FAIL}
9749
10610
  const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
9750
10611
  ${(lineFlags & 1) !== 0 ? "_trackLines(ctx,input,sm?e-1:e)" : ""}
9751
10612
  ${hasSuffix ? "ctx._fc=false" : ""}
9752
10613
  ${hasSuffix && (lineFlags & 2) !== 0 ? "if(sm)_trackLines(ctx,input,e)" : ""}
9753
10614
  ${hasSuffix ? `if(!sm){ctx._fe=e;ctx._fx=${suffixExpected};if(ctx._probe!==undefined)failAt(ctx,${suffixExpected},e)}` : ""}
9754
- const v=input.slice(pos,e)
10615
+ const v=${pending ? "tp?_pfTokValue:" : ""}input.slice(pos,e)
10616
+ ${pending ? "if(tp){_pfTokBody=-1;_pfTokValue=undefined}" : ""}
9755
10617
  if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
9756
10618
  EC.e=e
9757
10619
  return v
@@ -9807,12 +10669,13 @@ return v
9807
10669
  /* ── transaction ─────────────────────────────────────────────────────── */
9808
10670
  case OP_ATTEMPT: {
9809
10671
  const child = link(code[ip + 1]);
10672
+ const clean = !REC && failureRollbackClean(prog, ip);
9810
10673
  const p = tmp();
9811
10674
  return `${head}
9812
- ${emitMark(p, L.buf, sinks)}
10675
+ ${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
9813
10676
  const v=${child}(input,pos,ctx)
9814
10677
  if(v!==FAIL)return v
9815
- ${emitRollback(p, L.buf, sinks)}
10678
+ ${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
9816
10679
  if(ctx._fc===true)return FAIL
9817
10680
  ctx._fe=pos
9818
10681
  return FAIL
@@ -9835,9 +10698,9 @@ return FAIL
9835
10698
  const xf = fxRef(code[ip + 2]);
9836
10699
  const p = tmp();
9837
10700
  return `${head}
9838
- ${emitMark(p, L.buf, sinks)}
10701
+ ${emitMark(p, L.buf, L.raw, sinks)}
9839
10702
  const v=${child}(input,pos,ctx)
9840
- ${emitRollback(p, L.buf, sinks)}
10703
+ ${emitRollback(p, L.buf, L.raw, sinks)}
9841
10704
  if(v===FAIL){EC.e=pos;return null}
9842
10705
  ctx._fe=pos
9843
10706
  ctx._fx=${xf}
@@ -9849,9 +10712,9 @@ return FAIL
9849
10712
  const xf = fxRef(code[ip + 2]);
9850
10713
  const p = tmp();
9851
10714
  return `${head}
9852
- ${emitMark(p, L.buf, sinks)}
10715
+ ${emitMark(p, L.buf, L.raw, sinks)}
9853
10716
  const v=${child}(input,pos,ctx)
9854
- ${emitRollback(p, L.buf, sinks)}
10717
+ ${emitRollback(p, L.buf, L.raw, sinks)}
9855
10718
  if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
9856
10719
  EC.e=pos
9857
10720
  return null
@@ -9859,14 +10722,15 @@ return null
9859
10722
  }
9860
10723
  case OP_OPT: {
9861
10724
  const child = link(code[ip + 1]);
10725
+ const clean = !REC && failureRollbackClean(prog, ip);
9862
10726
  const p = tmp();
9863
10727
  return `${head}
9864
- ${emitMark(p, L.buf, sinks)}
10728
+ ${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
9865
10729
  ctx._fc=false
9866
10730
  const v=${child}(input,pos,ctx)
9867
10731
  if(v===FAIL){
9868
10732
  if(ctx._fc===true)return FAIL
9869
- ${emitRollback(p, L.buf, sinks)}
10733
+ ${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
9870
10734
  EC.e=pos
9871
10735
  return null
9872
10736
  }
@@ -9965,57 +10829,193 @@ return FAIL
9965
10829
  const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
9966
10830
  const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
9967
10831
  const gateRefs = Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
10832
+ const tokenCandidate = tokenChoiceCandidates.get(ip);
10833
+ const pretests = Array.from({ length: n }, (_, i) => {
10834
+ if (tokenCandidate?.arm === i) {
10835
+ return { token: tokenDecisionFor(tokenCandidate.dispatchIp) };
10836
+ }
10837
+ const terminal = leadingScalarTerminal(code, code[base + i], 2, true, true);
10838
+ if (terminal >= 0) {
10839
+ const spec = code[terminal + 1];
10840
+ if ((n === 2 || n === 3 ? scalarSpecs : largeChoiceScalarSpecs).has(spec)) {
10841
+ return { scalar: [recognizerRef(spec)] };
10842
+ }
10843
+ }
10844
+ const family = largeChoiceLiteralFamilies.get(code[base + i]);
10845
+ if (family !== void 0) {
10846
+ return { scalar: family.map((member) => recognizerRef(code[member + 1])) };
10847
+ }
10848
+ const sequence6 = largeChoiceScalarSequences.get(code[base + i]);
10849
+ return sequence6 === void 0 ? void 0 : { sequence: scalarSequenceRef(sequence6) };
10850
+ });
9968
10851
  const maskable = n <= 32;
9969
10852
  const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
9970
10853
  if (maskable) maskPlan.push(~di);
9971
10854
  const p = tmp();
9972
- const catchName = maskable ? `_cx${uid++}_` : "";
9973
- if (maskable) {
10855
+ const encodedRollbackMask = choiceRollbackMask(prog, ip) ?? -1;
10856
+ const rollbackMask = REC ? -1 : encodedRollbackMask;
10857
+ const hasRollback = rollbackMask !== 0;
10858
+ const startFailureExact = arms.every((_arm, i) => {
10859
+ const terminal = leadingScalarTerminal(code, code[base + i], 0, false);
10860
+ if (terminal < 0) return false;
10861
+ const op2 = code[terminal];
10862
+ const spec = k[code[terminal + 1]];
10863
+ const terminalFx = fx[code[terminal + 2]];
10864
+ const armFx = fx[code[base + n + i]];
10865
+ if (terminalFx.length !== armFx.length || terminalFx.some((expected2, at) => expected2 !== armFx[at])) return false;
10866
+ if (op2 === OP_LIT) return typeof spec === "string" && spec.length > 0;
10867
+ return op2 === OP_RX && spec instanceof RegExp && !regexCanMatchEmpty(spec.source);
10868
+ });
10869
+ const rollbackFor = (i) => rollbackMask === -1 || (rollbackMask & 1 << i) !== 0 ? emitRollback(p, L.buf, L.raw, sinks) : "";
10870
+ if (choiceCannotCommit(prog, ip) && !startFailureExact) {
10871
+ const deepAt = Array.from({ length: n }, () => tmp());
10872
+ const deepFx = Array.from({ length: n }, () => tmp());
10873
+ const remember = (i, at, expectedSet) => `${deepAt[i]}=${at};${deepFx[i]}=${expectedSet}`;
10874
+ const lazyArms = (ascii) => arms.map((arm, i) => {
10875
+ const pretest = pretests[i];
10876
+ const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
10877
+ const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
10878
+ const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
10879
+ const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
10880
+ const gate = ascii ? `(bits&${1 << i})!==0${condition}` : `(${gateRefs[i]}===null||classHas(${gateRefs[i]},c))${condition}`;
10881
+ const routeMiss = pretest?.token === void 0 ? "" : `
10882
+ if(${decision}===0){
10883
+ ctx._fc=false
10884
+ {const at=_pfTokEnd
10885
+ ${remember(i, "at", pretest.token.expected)}}
10886
+ }`;
10887
+ const sequenceMiss = pretest?.sequence === void 0 ? "" : `
10888
+ else if(${ascii ? `(bits&${1 << i})!==0&&` : ""}${decision}<0){
10889
+ ctx._fc=false
10890
+ {const at=_pfSeqEnd
10891
+ ${remember(i, "at", pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("") + pretest.sequence.expected.at(-1))}}
10892
+ }`;
10893
+ return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
10894
+ `}if(${gate}){
10895
+ ctx._fc=false
10896
+ {const v=${arm}(input,pos,ctx)
10897
+ if(v!==FAIL)return v}
10898
+ {const at=ctx._fe??pos
10899
+ ${remember(i, "at", "ctx._fx")}}
10900
+ ${rollbackFor(i)}
10901
+ }${routeMiss}${sequenceMiss}`;
10902
+ }).join("\n");
10903
+ const merge = deepAt.map((at, i) => `{const at=${at}??pos
10904
+ const ex=${at}===undefined?${expected[i]}:${deepFx[i]}
10905
+ if(at>best){best=at;acc=_accSet(ex,undefined)}
10906
+ else if(at===best)acc=_accSet(ex,acc)
10907
+ }`).join("\n");
10908
+ const finish = `let best=pos,acc
10909
+ ${merge}
10910
+ ctx._fe=pos;ctx._fx=acc??${choiceFx}
10911
+ return FAIL`;
10912
+ return `${head}
10913
+ const c=lead(input,pos)
10914
+ ${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
10915
+ ${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
10916
+ ${maskable ? `if(c<128){
10917
+ const bits=${maskName}[c<0?128:c]
10918
+ if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
10919
+ ${lazyArms(true)}
10920
+ }else{
10921
+ ${lazyArms(false)}
10922
+ }
10923
+ ` : lazyArms(false)}
10924
+ ${finish}
10925
+ }`;
10926
+ }
10927
+ const needsCatch = maskable || startFailureExact;
10928
+ const catchName = needsCatch ? `_cx${uid++}_` : "";
10929
+ if (needsCatch) {
9974
10930
  const catchCases = expected.map((e, i) => `case ${i}:if(target<=${i})return acc;acc=_accSet(${e},acc)`).join("\n");
9975
10931
  choiceDefs.push(`function ${catchName}(target,prev,acc){switch(prev){
9976
10932
  ${catchCases}
9977
10933
  }return acc}`);
9978
10934
  }
9979
10935
  const maskArms = maskable ? arms.map((arm, i) => {
9980
- return `if((bits&${1 << i})!==0){
10936
+ const pretest = pretests[i];
10937
+ const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
10938
+ const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
10939
+ const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
10940
+ const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
10941
+ const routeMiss = pretest?.token === void 0 ? "" : `
10942
+ if(${decision}===0){
10943
+ ctx._fc=false
10944
+ ${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
10945
+ prev=${i + 1}`}
10946
+ {const at=_pfTokEnd
10947
+ if(at>best){best=at;acc=undefined}
10948
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.token.expected},acc)}
10949
+ }`;
10950
+ const sequenceMiss = pretest?.sequence === void 0 ? "" : `
10951
+ else if((bits&${1 << i})!==0&&${decision}<0){
10952
+ ctx._fc=false
10953
+ ${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
10954
+ prev=${i + 1}`}
10955
+ {const at=_pfSeqEnd
10956
+ if(at>best){best=at;acc=undefined}
10957
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("")}${pretest.sequence.expected.at(-1)},acc)}
10958
+ }`;
10959
+ return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
10960
+ `}if((bits&${1 << i})!==0${condition}){
9981
10961
  ctx._fc=false
9982
10962
  {const v=${arm}(input,pos,ctx)
9983
10963
  if(v!==FAIL)return v}
9984
- if(best===pos)acc=${catchName}(${i},prev,acc)
9985
- prev=${i + 1}
10964
+ ${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
10965
+ prev=${i + 1}`}
9986
10966
  {const at=ctx._fe??pos
9987
10967
  if(at>best){best=at;acc=undefined}
9988
- if(at===best)acc=_accSet(ctx._fx,acc)}
9989
- if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
9990
- ${emitRollback(p, L.buf, sinks)}
9991
- }`;
10968
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(ctx._fx,acc)}
10969
+ if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0,undefined);acc=_accSet(ctx._fx,acc)}` : ""}if(acc!==undefined)ctx._fx=acc;return FAIL}
10970
+ ${rollbackFor(i)}
10971
+ }${routeMiss}${sequenceMiss}`;
9992
10972
  }).join("\n") : "";
9993
- const generalArms = arms.map((arm, i) => `if(${gateRefs[i]}===null||classHas(${gateRefs[i]},c)){
10973
+ const generalArms = arms.map((arm, i) => {
10974
+ const pretest = pretests[i];
10975
+ const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
10976
+ const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
10977
+ const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
10978
+ const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
10979
+ const miss = pretest?.sequence !== void 0 ? `else if(${decision}<0){
10980
+ ctx._fc=false
10981
+ const at=_pfSeqEnd
10982
+ if(at>best){best=at;acc=undefined}
10983
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("")}${pretest.sequence.expected.at(-1)},acc)
10984
+ }${startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)`}` : pretest?.token === void 0 ? startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)` : `else if(${decision}===0){
10985
+ ctx._fc=false
10986
+ const at=_pfTokEnd
10987
+ if(at>best){best=at;acc=undefined}
10988
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.token.expected},acc)
10989
+ }${startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)`}`;
10990
+ return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
10991
+ `}if((${gateRefs[i]}===null||classHas(${gateRefs[i]},c))${condition}){
9994
10992
  ctx._fc=false
9995
10993
  {const v=${arm}(input,pos,ctx)
9996
10994
  if(v!==FAIL)return v}
9997
10995
  {const at=ctx._fe??pos
9998
10996
  if(at>best){best=at;acc=undefined}
9999
- if(at===best)acc=_accSet(ctx._fx,acc)}
10000
- if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
10001
- ${emitRollback(p, L.buf, sinks)}
10002
- }else if(best===pos)acc=_accSet(${expected[i]},acc)`).join("\n");
10997
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(ctx._fx,acc)}
10998
+ if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0,undefined);acc=_accSet(ctx._fx,acc)}` : ""}if(acc!==undefined)ctx._fx=acc;return FAIL}
10999
+ ${rollbackFor(i)}
11000
+ }${miss}`;
11001
+ }).join("\n");
10003
11002
  return `${head}
10004
11003
  const c=lead(input,pos)
10005
- ${emitMark(p, L.buf, sinks)}
11004
+ ${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
10006
11005
  let acc
10007
11006
  let best=pos
10008
11007
  ${maskable ? `if(c<128){
10009
11008
  const bits=${maskName}[c<0?128:c]
10010
- let prev=0
11009
+ if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
11010
+ ${startFailureExact ? "" : "let prev=0"}
10011
11011
  ${maskArms}
10012
- if(best===pos)acc=${catchName}(${n},prev,acc)
10013
- ctx._fe=pos;ctx._fx=acc??${choiceFx}
11012
+ ${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${n},prev,acc)`}
11013
+ ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
10014
11014
  return FAIL
10015
11015
  }
10016
11016
  ` : ""}
10017
11017
  ${generalArms}
10018
- ctx._fe=pos;ctx._fx=acc??${choiceFx}
11018
+ ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
10019
11019
  return FAIL
10020
11020
  }`;
10021
11021
  }
@@ -10034,30 +11034,8 @@ return FAIL
10034
11034
  for (let i = 0; i < n; i++) arms.push(link(code[armBase + i]));
10035
11035
  const bk = hoist("bk", `DSP[${di}].byKey`);
10036
11036
  const dx = hoist("dx", `DSP[${di}].expected`);
10037
- const claims = (m) => {
10038
- switch (m[0]) {
10039
- case 0:
10040
- return `key.startsWith(${q(m[1])})`;
10041
- case 1:
10042
- return `key.endsWith(${q(m[1])})`;
10043
- case 3:
10044
- return `asciiFoldKey(key).startsWith(${q(m[1])})`;
10045
- case 4:
10046
- return `asciiFoldKey(key).endsWith(${q(m[1])})`;
10047
- default: {
10048
- if (!m[2].includes("g") && !m[2].includes("y")) {
10049
- try {
10050
- new RegExp(m[1], m[2]);
10051
- return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
10052
- } catch {
10053
- }
10054
- }
10055
- return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
10056
- }
10057
- }
10058
- };
10059
11037
  const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
10060
- ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${claims(m)})arm=${m[3]}`).join("\n")}
11038
+ ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${dispatchClaim(m)})arm=${m[3]}`).join("\n")}
10061
11039
  }
10062
11040
  `;
10063
11041
  const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
@@ -10065,33 +11043,43 @@ ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${claims(m)})arm=${m[3]}
10065
11043
  const m1 = tmp();
10066
11044
  const m2 = tmp();
10067
11045
  const routedCall = (target) => `{const savedRouted=ctx._routed
10068
- ${emitRollback(m1, L.buf, sinks)}
10069
- ${emitMark(m2, L.buf, sinks, false)}
11046
+ ${emitRollback(m1, L.buf, L.raw, sinks)}
11047
+ ${emitMark(m2, L.buf, L.raw, sinks, false)}
10070
11048
  ctx._routed={value:key,span:{start:pos,end:selEnd}}
10071
11049
  try{v=${target}(input,pos,ctx)}finally{ctx._routed=savedRouted}
10072
11050
  break}`;
10073
11051
  const plainCall = (target) => `v=${target}(input,selEnd,ctx);break`;
10074
11052
  const armCases = arms.map((target, i) => `case ${i}:${spec.routed[i] === 1 ? routedCall(target) : plainCall(target)}`).join("\n");
10075
11053
  const fallbackCase = other === void 0 ? "" : `default:${otherRouted ? routedCall(other) : plainCall(other)}`;
11054
+ const armSelection = tokenChoiceDispatches.has(ip) ? `const tp=_pfTokDispatch===${ip}&&_pfTokInput===input&&_pfTokPos===pos
11055
+ let arm
11056
+ if(tp){
11057
+ arm=_pfTokArm
11058
+ _pfTokDispatch=-1
11059
+ _pfTokInput=undefined
11060
+ if(arm===${n})arm=undefined
11061
+ }else{
11062
+ arm=${bk}.get(key)
11063
+ ${fold}${chain}}` : `let arm=${bk}.get(key)
11064
+ ${fold}${chain}`;
10076
11065
  return `${head}
10077
- ${emitMark(m1, L.buf, sinks)}
11066
+ ${emitMark(m1, L.buf, L.raw, sinks)}
10078
11067
  const sv=${selector}(input,pos,ctx)
10079
11068
  if(sv===FAIL)return FAIL
10080
11069
  const selEnd=EC.e
10081
11070
  const key=sv
10082
- let arm=${bk}.get(key)
10083
- ${fold}${chain}
11071
+ ${armSelection}
10084
11072
  if(arm===undefined){
10085
11073
  ${other === void 0 ? `ctx._fe=selEnd;ctx._fx=${dx};return FAIL` : ""}
10086
11074
  }
10087
- ${emitMark(m2, L.buf, sinks)}
11075
+ ${emitMark(m2, L.buf, L.raw, sinks)}
10088
11076
  let v
10089
11077
  switch(arm){
10090
11078
  ${armCases}
10091
11079
  ${fallbackCase}
10092
11080
  }
10093
11081
  if(v===FAIL){
10094
- ${emitRollback(m2, L.buf, sinks)}
11082
+ ${emitRollback(m2, L.buf, L.raw, sinks)}
10095
11083
  ctx._fc=true
10096
11084
  return FAIL
10097
11085
  }
@@ -10127,23 +11115,25 @@ return [key,v]
10127
11115
  const skip = skipFor(L);
10128
11116
  const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
10129
11117
  const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
10130
- const pfd = sinks.fd ? `${p}fd` : "0";
11118
+ const pfd = sinks.fd ? `${p}fd` : "undefined";
10131
11119
  const per = sinks.er ? `${p}er` : "undefined";
10132
- const rb = L.buf ? `_rbBuf(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
11120
+ const rbHelper = L.raw === RAW_OMIT ? "_rbNoRawBuf" : "_rbBuf";
11121
+ const rb = L.buf && L.raw !== 0 ? `${rbHelper}(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
10133
11122
  if(ctx._fields!==undefined&&ctx._fields.length!==${p}fd)ctx._fields.length=${p}fd` : ""}${sinks.er ? `
10134
- if(ctx._errors!==undefined&&ctx._errors.length!==${p}er)ctx._errors.length=${p}er` : ""}` : `if(needMark)rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)`;
11123
+ if(ctx._errors!==undefined&&ctx._errors.length!==${p}er)ctx._errors.length=${p}er` : ""}` : L.buf ? `rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)` : `if(needMark)rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)`;
10135
11124
  const markSinks = `${sinks.fd ? `
10136
11125
  ${p}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${sinks.er ? `
10137
11126
  ${p}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
11127
+ const markRaw = L.raw === RAW_OMIT ? `${p}raw=b.rawLen` : L.raw === RAW_CAPTURE ? `const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0` : `const r=b.raw;${p}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)`;
10138
11128
  const markBody = L.buf ? `const b=ctx._cstBuf
10139
- const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
11129
+ ${markRaw}
10140
11130
  const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
10141
11131
  const l=b.tl;${p}tl=l!==undefined?l.length:0
10142
11132
  ${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
10143
11133
  ${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}` : `if(needMark){
10144
11134
  const b=ctx._cstBuf
10145
11135
  if(b!==undefined){
10146
- const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
11136
+ const r=b.raw;${p}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)
10147
11137
  const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
10148
11138
  const l=b.tl;${p}tl=l!==undefined?l.length:0
10149
11139
  }else{
@@ -10250,7 +11240,7 @@ const leaf={_tag:'leaf',value,span:{start:pos,end}}
10250
11240
  const kids=[leaf],rawKids=[leaf],span={start:pos,end}
10251
11241
  EC.e=end
10252
11242
  const nd=${build2}(kids,undefined,span,rawKids,EMPTY_TL,undefined)
10253
- ${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
11243
+ ${L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : staticBuild ? "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,ctx._cstBuf!==undefined&&ctx._cstBuf.noRaw===true?undefined:ctx._cstBuf!==undefined||ctx._cstRawChildren!==undefined?rawEntry(nd,input,pos,end):undefined)" : "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
10254
11244
  EC.e=end
10255
11245
  return nd
10256
11246
  }`;
@@ -10272,7 +11262,22 @@ return nd
10272
11262
  if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
10273
11263
  const fields = flags === 18;
10274
11264
  const collapseChildren = flags === 34;
10275
- const publish = `if(sBuf!==undefined){
11265
+ const publish = L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? `if(sBuf!==undefined){
11266
+ if(sBuf.rawOnly!==true){
11267
+ if(sBuf.ch!==undefined)sBuf.ch.push(nd)
11268
+ else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
11269
+ else sBuf.single=nd
11270
+ }
11271
+ const rawNd=rawEntry(nd,input,pos,end)
11272
+ if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
11273
+ else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
11274
+ else sBuf.rawSingle=rawNd
11275
+ }else if(sCh!==undefined){
11276
+ sCh.push(nd)
11277
+ if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
11278
+ }` : `if(sBuf!==undefined){
11279
+ if(sBuf.noRaw===true)_pushNodeNoRawBuf(ctx,nd)
11280
+ else{
10276
11281
  if(sBuf.rawOnly!==true){
10277
11282
  if(sBuf.ch!==undefined)sBuf.ch.push(nd)
10278
11283
  else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
@@ -10282,6 +11287,7 @@ const rawNd=rawEntry(nd,input,pos,end)
10282
11287
  if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
10283
11288
  else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
10284
11289
  else sBuf.rawSingle=rawNd
11290
+ }
10285
11291
  }else if(sCh!==undefined){
10286
11292
  sCh.push(nd)
10287
11293
  if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
@@ -10320,6 +11326,7 @@ return nd
10320
11326
  const wantFields = hasFields || hostCst;
10321
11327
  const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
10322
11328
  const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
11329
+ const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
10323
11330
  const ty = q(type);
10324
11331
  const stArg = readsState ? "st" : "(ctx.state!==undefined?Object.assign({},ctx.state):undefined)";
10325
11332
  const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
@@ -10333,7 +11340,12 @@ return nd
10333
11340
  value = `nd=_pfHost!==undefined?_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,st,${tags}):{_tag:'node',type:${ty},span,state:st??null,children:kids}`;
10334
11341
  }
10335
11342
  const collapsible = keepChildren && (hostCst || build === void 0 && proj < 0);
10336
- const openCapture = keepChildren ? `const buf={}
11343
+ const openCapture = omitsRaw ? `const buf={noRaw:true,rawLen:0}
11344
+ ctx._cstBuf=buf
11345
+ ctx._cstChildren=undefined
11346
+ ctx._cstLeaves=undefined
11347
+ ctx._cstRawChildren=undefined
11348
+ ctx._cstTriviaLog=undefined` : keepChildren ? `const buf={}
10337
11349
  ctx._cstBuf=buf
10338
11350
  ctx._cstChildren=undefined
10339
11351
  ctx._cstLeaves=undefined
@@ -10344,7 +11356,10 @@ ctx._cstChildren=undefined
10344
11356
  ctx._cstLeaves=undefined
10345
11357
  ctx._cstRawChildren=undefined
10346
11358
  ctx._cstTriviaLog=undefined`;
10347
- const finishCapture = keepChildren ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
11359
+ const finishCapture = omitsRaw ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
11360
+ const hostKids=kids
11361
+ const rawKids=EMPTY_CH
11362
+ const tlog=buf.tl??EMPTY_TLOG` : keepChildren ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
10348
11363
  const hostKids=kids
10349
11364
  const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
10350
11365
  const tlog=buf.tl??EMPTY_TLOG` : `const kids=EMPTY_CH
@@ -10378,7 +11393,7 @@ const st=${readsState ? "(ctx.state!==undefined?Object.assign({},ctx.state):unde
10378
11393
  let nd
10379
11394
  ${unwrap ? "if(kids.length===1)nd=unwrapChild(kids[0])\nelse " : ""}${collapse ? "if(kids.length===1)nd=kids[0]\nelse " : ""}${collapsible ? `if(_pfHost!==undefined&&_pfHost._parsemanCstCollapse!==undefined&&kids.length===1&&rawKids.length===1&&_pfHost._parsemanCstCollapse(${ty},kids[0],kids,rawKids))nd=kids[0]
10380
11395
  else ` : ""}{${value}}
10381
- ${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
11396
+ ${L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : staticBuild ? "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,sBuf!==undefined?(sBuf.noRaw===true?undefined:rawEntry(nd,input,pos,end)):sRaw!==undefined?rawEntry(nd,input,pos,end):undefined)" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
10382
11397
  EC.e=end
10383
11398
  return nd
10384
11399
  }`;
@@ -10396,7 +11411,7 @@ return nd
10396
11411
  }
10397
11412
  const extra = [];
10398
11413
  for (const ip of extraIps) extra.push(`${ip}:${link(ip)}`);
10399
- const source = `${RUNTIME_PRELUDE}
11414
+ const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
10400
11415
  ${prelude.join("\n")}
10401
11416
  ${skipDefs.join("\n")}
10402
11417
  ${choiceDefs.join("\n")}
@@ -10411,7 +11426,13 @@ _pfHost=host
10411
11426
  function _finish(){
10412
11427
  if(_pfDepth<=0)throw new Error('parseman emitted table assembly frame underflow')
10413
11428
  _pfDepth--
10414
- if(_pfDepth===0)return
11429
+ if(_pfDepth===0){
11430
+ _pfTokInput=undefined
11431
+ _pfTokBody=-1
11432
+ _pfTokValue=undefined
11433
+ _pfTokDispatch=-1
11434
+ return
11435
+ }
10415
11436
  const prior=_pfFrames.pop()
10416
11437
  _pfScan=prior[0]
10417
11438
  _pfHost=prior[1]
@@ -10635,6 +11656,17 @@ function assemble(t2, prog, cfg) {
10635
11656
  }
10636
11657
  return recognize;
10637
11658
  }
11659
+ const labelExtraIps = [];
11660
+ for (const s of prog.scans ?? []) {
11661
+ for (const r of s.skip) labelExtraIps.push(r[0]);
11662
+ if (s.sentinel !== void 0) labelExtraIps.push(s.sentinel[0]);
11663
+ }
11664
+ for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
11665
+ const closureLabels = computeSiteLabels(
11666
+ code,
11667
+ [...Object.values(prog.rules), ...labelExtraIps],
11668
+ hostCst
11669
+ );
10638
11670
  let SCAN = null;
10639
11671
  const memo = /* @__PURE__ */ new Map();
10640
11672
  const reached = /* @__PURE__ */ new Set();
@@ -10880,7 +11912,7 @@ function assemble(t2, prog, cfg) {
10880
11912
  const b = ctx._cstBuf;
10881
11913
  if (b !== void 0) {
10882
11914
  const raw = b.raw;
10883
- MRAW = raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
11915
+ MRAW = b.noRaw === true ? b.rawLen ?? 0 : raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
10884
11916
  const ch2 = b.ch;
10885
11917
  MLV = ch2 !== void 0 ? ch2.length : b.single !== void 0 ? 1 : 0;
10886
11918
  const tl = b.tl;
@@ -10964,6 +11996,31 @@ function assemble(t2, prog, cfg) {
10964
11996
  if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
10965
11997
  return cur;
10966
11998
  }
11999
+ function nextTermBuffered(child, input, cur, ctx) {
12000
+ if (ctx.trivia === void 0) {
12001
+ const v2 = child(input, cur, ctx);
12002
+ if (v2 === FAIL) return -1;
12003
+ TERMV = v2;
12004
+ return EC.e;
12005
+ }
12006
+ const before = ctx._cstBuf;
12007
+ const beforeTl = before.tl;
12008
+ const mTl = beforeTl === void 0 ? 0 : beforeTl.length;
12009
+ const mLog = ctx._triviaLog?.length ?? 0;
12010
+ const mRoot = ctx._rootTriviaLog?.length ?? 0;
12011
+ const scanEnd = skipTrivia(input, cur, ctx);
12012
+ const scanned = ctx._cstBuf;
12013
+ const scannedTl = scanned.tl;
12014
+ const scanTl = scannedTl === void 0 ? 0 : scannedTl.length;
12015
+ const scanLog = ctx._triviaLog?.length ?? 0;
12016
+ const scanRoot = ctx._rootTriviaLog?.length ?? 0;
12017
+ const v = child(input, scanEnd, ctx);
12018
+ if (v === FAIL) return -1;
12019
+ TERMV = v;
12020
+ if (EC.e > scanEnd) return EC.e;
12021
+ rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
12022
+ return cur;
12023
+ }
10967
12024
  function committed3(c) {
10968
12025
  return c._fc === true;
10969
12026
  }
@@ -11234,7 +12291,8 @@ function assemble(t2, prog, cfg) {
11234
12291
  target = p;
11235
12292
  } };
11236
12293
  inFlight.set(ip, holder);
11237
- const piece = lower(ip);
12294
+ const op = code[ip];
12295
+ const piece = (op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[ip + 3] === 0) && code[ip + 1] >= 0 && closureLabels.at(ip).tri === code[ip + 1] ? link(code[ip + 2]) : lower(ip);
11238
12296
  inFlight.delete(ip);
11239
12297
  holder.set(piece);
11240
12298
  memo.set(ip, piece);
@@ -11977,6 +13035,7 @@ function assemble(t2, prog, cfg) {
11977
13035
  const reducer = fused ? code[ip + 1] : -1;
11978
13036
  const projection = reducer < 0 ? ~reducer : -1;
11979
13037
  const fn = fused && projection < 0 ? fns[reducer] : void 0;
13038
+ const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm;
11980
13039
  const runnerBlock = (count, r0, r1, r2, r3, next) => {
11981
13040
  if (count === 1) return (input, cur, ctx, values, inherited) => {
11982
13041
  cur = r0(input, cur, ctx, inherited);
@@ -12031,7 +13090,7 @@ function assemble(t2, prog, cfg) {
12031
13090
  const kid = link(kidIp);
12032
13091
  return (input, cur, ctx, inherited) => {
12033
13092
  ctx._sync = sync ?? inherited;
12034
- return nextTerm(kid, input, cur, ctx);
13093
+ return step(kid, input, cur, ctx);
12035
13094
  };
12036
13095
  }
12037
13096
  const negated = code[kidIp + 1] === 1;
@@ -12116,7 +13175,7 @@ function assemble(t2, prog, cfg) {
12116
13175
  const kidIp = code[base + i];
12117
13176
  if (code[kidIp] !== OP_ADJ) {
12118
13177
  const kid = link(kidIp);
12119
- return (input, cur, ctx) => nextTerm(kid, input, cur, ctx);
13178
+ return (input, cur, ctx) => step(kid, input, cur, ctx);
12120
13179
  }
12121
13180
  const negated = code[kidIp + 1] === 1;
12122
13181
  const ki = code[kidIp + 2];
@@ -12205,7 +13264,7 @@ function assemble(t2, prog, cfg) {
12205
13264
  return (input, pos, ctx) => {
12206
13265
  const v0 = k0(input, pos, ctx);
12207
13266
  if (v0 === FAIL) return FAIL;
12208
- const cur = nextTerm(k1, input, EC.e, ctx);
13267
+ const cur = step(k1, input, EC.e, ctx);
12209
13268
  if (cur < 0) return FAIL;
12210
13269
  EC.e = cur;
12211
13270
  return projection === 0 ? v0 : projection === 1 ? TERMV : fn([v0, TERMV], { start: pos, end: cur });
@@ -12215,7 +13274,7 @@ function assemble(t2, prog, cfg) {
12215
13274
  return (input, pos, ctx) => {
12216
13275
  const v0 = k0(input, pos, ctx);
12217
13276
  if (v0 === FAIL) return FAIL;
12218
- const cur = nextTerm(k1, input, EC.e, ctx);
13277
+ const cur = step(k1, input, EC.e, ctx);
12219
13278
  if (cur < 0) return FAIL;
12220
13279
  EC.e = cur;
12221
13280
  return [v0, TERMV];
@@ -12224,7 +13283,7 @@ function assemble(t2, prog, cfg) {
12224
13283
  return (input, pos, ctx) => {
12225
13284
  const v0 = k0(input, pos, ctx);
12226
13285
  if (v0 === FAIL) return FAIL;
12227
- const cur = nextTerm(k1, input, EC.e, ctx);
13286
+ const cur = step(k1, input, EC.e, ctx);
12228
13287
  if (cur < 0) return FAIL;
12229
13288
  EC.e = cur;
12230
13289
  return void 0;
@@ -12236,10 +13295,10 @@ function assemble(t2, prog, cfg) {
12236
13295
  return (input, pos, ctx) => {
12237
13296
  const v0 = k0(input, pos, ctx);
12238
13297
  if (v0 === FAIL) return FAIL;
12239
- let cur = nextTerm(k1, input, EC.e, ctx);
13298
+ let cur = step(k1, input, EC.e, ctx);
12240
13299
  if (cur < 0) return FAIL;
12241
13300
  const v1 = TERMV;
12242
- cur = nextTerm(k2, input, cur, ctx);
13301
+ cur = step(k2, input, cur, ctx);
12243
13302
  if (cur < 0) return FAIL;
12244
13303
  EC.e = cur;
12245
13304
  return projection === 0 ? v0 : projection === 1 ? v1 : projection === 2 ? TERMV : fn([v0, v1, TERMV], { start: pos, end: cur });
@@ -12249,10 +13308,10 @@ function assemble(t2, prog, cfg) {
12249
13308
  return (input, pos, ctx) => {
12250
13309
  const v0 = k0(input, pos, ctx);
12251
13310
  if (v0 === FAIL) return FAIL;
12252
- let cur = nextTerm(k1, input, EC.e, ctx);
13311
+ let cur = step(k1, input, EC.e, ctx);
12253
13312
  if (cur < 0) return FAIL;
12254
13313
  const v1 = TERMV;
12255
- cur = nextTerm(k2, input, cur, ctx);
13314
+ cur = step(k2, input, cur, ctx);
12256
13315
  if (cur < 0) return FAIL;
12257
13316
  EC.e = cur;
12258
13317
  return [v0, v1, TERMV];
@@ -12261,9 +13320,9 @@ function assemble(t2, prog, cfg) {
12261
13320
  return (input, pos, ctx) => {
12262
13321
  const v0 = k0(input, pos, ctx);
12263
13322
  if (v0 === FAIL) return FAIL;
12264
- let cur = nextTerm(k1, input, EC.e, ctx);
13323
+ let cur = step(k1, input, EC.e, ctx);
12265
13324
  if (cur < 0) return FAIL;
12266
- cur = nextTerm(k2, input, cur, ctx);
13325
+ cur = step(k2, input, cur, ctx);
12267
13326
  if (cur < 0) return FAIL;
12268
13327
  EC.e = cur;
12269
13328
  return void 0;
@@ -12271,43 +13330,43 @@ function assemble(t2, prog, cfg) {
12271
13330
  }
12272
13331
  const block = (count, k0, k1, k2, k3, next) => {
12273
13332
  if (count === 1) return (input, cur, ctx, values) => {
12274
- cur = nextTerm(k0, input, cur, ctx);
13333
+ cur = step(k0, input, cur, ctx);
12275
13334
  if (cur < 0) return -1;
12276
13335
  if (values !== void 0) values.push(TERMV);
12277
13336
  return next === void 0 ? cur : next(input, cur, ctx, values);
12278
13337
  };
12279
13338
  if (count === 2) return (input, cur, ctx, values) => {
12280
- cur = nextTerm(k0, input, cur, ctx);
13339
+ cur = step(k0, input, cur, ctx);
12281
13340
  if (cur < 0) return -1;
12282
13341
  if (values !== void 0) values.push(TERMV);
12283
- cur = nextTerm(k1, input, cur, ctx);
13342
+ cur = step(k1, input, cur, ctx);
12284
13343
  if (cur < 0) return -1;
12285
13344
  if (values !== void 0) values.push(TERMV);
12286
13345
  return next === void 0 ? cur : next(input, cur, ctx, values);
12287
13346
  };
12288
13347
  if (count === 3) return (input, cur, ctx, values) => {
12289
- cur = nextTerm(k0, input, cur, ctx);
13348
+ cur = step(k0, input, cur, ctx);
12290
13349
  if (cur < 0) return -1;
12291
13350
  if (values !== void 0) values.push(TERMV);
12292
- cur = nextTerm(k1, input, cur, ctx);
13351
+ cur = step(k1, input, cur, ctx);
12293
13352
  if (cur < 0) return -1;
12294
13353
  if (values !== void 0) values.push(TERMV);
12295
- cur = nextTerm(k2, input, cur, ctx);
13354
+ cur = step(k2, input, cur, ctx);
12296
13355
  if (cur < 0) return -1;
12297
13356
  if (values !== void 0) values.push(TERMV);
12298
13357
  return next === void 0 ? cur : next(input, cur, ctx, values);
12299
13358
  };
12300
13359
  return (input, cur, ctx, values) => {
12301
- cur = nextTerm(k0, input, cur, ctx);
13360
+ cur = step(k0, input, cur, ctx);
12302
13361
  if (cur < 0) return -1;
12303
13362
  if (values !== void 0) values.push(TERMV);
12304
- cur = nextTerm(k1, input, cur, ctx);
13363
+ cur = step(k1, input, cur, ctx);
12305
13364
  if (cur < 0) return -1;
12306
13365
  if (values !== void 0) values.push(TERMV);
12307
- cur = nextTerm(k2, input, cur, ctx);
13366
+ cur = step(k2, input, cur, ctx);
12308
13367
  if (cur < 0) return -1;
12309
13368
  if (values !== void 0) values.push(TERMV);
12310
- cur = nextTerm(k3, input, cur, ctx);
13369
+ cur = step(k3, input, cur, ctx);
12311
13370
  if (cur < 0) return -1;
12312
13371
  if (values !== void 0) values.push(TERMV);
12313
13372
  return next === void 0 ? cur : next(input, cur, ctx, values);
@@ -12478,6 +13537,13 @@ function assemble(t2, prog, cfg) {
12478
13537
  if (n === 2 || n === 3) {
12479
13538
  const a0 = link(code[base]), a1 = link(code[base + 1]);
12480
13539
  const a2 = n === 3 ? link(code[base + 2]) : void 0;
13540
+ const predecide = !hostCst && !REC && !cfg.probe && !cfg.coverage && !cfg.trackLines;
13541
+ const p0ip = predecide ? leadingScalarTerminal(code, code[base], 2, true, true) : -1;
13542
+ const p1ip = predecide ? leadingScalarTerminal(code, code[base + 1], 2, true, true) : -1;
13543
+ const p2ip = predecide && n === 3 ? leadingScalarTerminal(code, code[base + 2], 2, true, true) : -1;
13544
+ const p0 = p0ip < 0 ? void 0 : scalarFor(p0ip);
13545
+ const p1 = p1ip < 0 ? void 0 : scalarFor(p1ip);
13546
+ const p2 = p2ip < 0 ? void 0 : scalarFor(p2ip);
12481
13547
  const e0 = fx[code[base + n]];
12482
13548
  const e1 = fx[code[base + n + 1]];
12483
13549
  const e2 = n === 3 ? fx[code[base + n + 2]] : void 0;
@@ -12507,7 +13573,10 @@ function assemble(t2, prog, cfg) {
12507
13573
  let acc;
12508
13574
  let best = pos;
12509
13575
  if (c < 128) {
12510
- const bits = mask[c < 0 ? 128 : c];
13576
+ let bits = mask[c < 0 ? 128 : c];
13577
+ if ((bits & 1) !== 0 && p0 !== void 0 && p0(input, pos) < 0) bits &= ~1;
13578
+ if ((bits & 2) !== 0 && p1 !== void 0 && p1(input, pos) < 0) bits &= ~2;
13579
+ if ((bits & 4) !== 0 && p2 !== void 0 && p2(input, pos) < 0) bits &= ~4;
12511
13580
  let prev = 0;
12512
13581
  if ((bits & 1) !== 0) {
12513
13582
  ctx._fc = false;
@@ -12570,7 +13639,7 @@ function assemble(t2, prog, cfg) {
12570
13639
  ctx._fx = acc ?? choiceFx;
12571
13640
  return FAIL;
12572
13641
  }
12573
- if (g0 === null || classHas2(g0, c)) {
13642
+ if ((g0 === null || classHas2(g0, c)) && (p0 === void 0 || p0(input, pos) >= 0)) {
12574
13643
  ctx._fc = false;
12575
13644
  const v = a0(input, pos, ctx);
12576
13645
  if (v !== FAIL) return v;
@@ -12586,7 +13655,7 @@ function assemble(t2, prog, cfg) {
12586
13655
  }
12587
13656
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12588
13657
  } else if (best === pos) acc = accSet(e0, acc);
12589
- if (g1 === null || classHas2(g1, c)) {
13658
+ if ((g1 === null || classHas2(g1, c)) && (p1 === void 0 || p1(input, pos) >= 0)) {
12590
13659
  ctx._fc = false;
12591
13660
  const v = a1(input, pos, ctx);
12592
13661
  if (v !== FAIL) return v;
@@ -12603,7 +13672,7 @@ function assemble(t2, prog, cfg) {
12603
13672
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12604
13673
  } else if (best === pos) acc = accSet(e1, acc);
12605
13674
  if (n === 3) {
12606
- if (g2 === null || classHas2(g2, c)) {
13675
+ if ((g2 === null || classHas2(g2, c)) && (p2 === void 0 || p2(input, pos) >= 0)) {
12607
13676
  ctx._fc = false;
12608
13677
  const v = a2(input, pos, ctx);
12609
13678
  if (v !== FAIL) return v;
@@ -13176,20 +14245,14 @@ function assemble(t2, prog, cfg) {
13176
14245
  const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
13177
14246
  const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
13178
14247
  const rawOnly = !keepChildren;
14248
+ const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
13179
14249
  return (input, pos, ctx) => {
13180
14250
  const host = HOST;
13181
14251
  const sCh = ctx._cstChildren;
13182
- const sLv = ctx._cstLeaves;
13183
- const sRaw = ctx._cstRawChildren;
13184
- const sTl = ctx._cstTriviaLog;
13185
14252
  const sCap = ctx.captureTrivia;
13186
14253
  const sBuf = ctx._cstBuf;
13187
- const buf = rawOnly ? { rawOnly: true } : {};
14254
+ const buf = rawOnly ? { rawOnly: true } : omitsRaw ? { noRaw: true, rawLen: 0 } : {};
13188
14255
  ctx._cstBuf = buf;
13189
- ctx._cstChildren = void 0;
13190
- ctx._cstLeaves = void 0;
13191
- ctx._cstRawChildren = void 0;
13192
- ctx._cstTriviaLog = void 0;
13193
14256
  ctx.captureTrivia = captureWide;
13194
14257
  const savedFields = ctx._fields;
13195
14258
  ctx._fields = wantFields ? [] : void 0;
@@ -13204,13 +14267,9 @@ function assemble(t2, prog, cfg) {
13204
14267
  if (structural) ctx._triviaCaptureMask = savedMask;
13205
14268
  const kids = rawOnly ? EMPTY_CH : buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
13206
14269
  const hostKids = kids;
13207
- const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
14270
+ const rawKids = omitsRaw ? EMPTY_CH : buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
13208
14271
  const tlog = buf.tl ?? EMPTY_TLOG;
13209
14272
  ctx._cstBuf = sBuf;
13210
- ctx._cstChildren = sCh;
13211
- ctx._cstLeaves = sLv;
13212
- ctx._cstRawChildren = sRaw;
13213
- ctx._cstTriviaLog = sTl;
13214
14273
  ctx.captureTrivia = sCap;
13215
14274
  if (v === FAIL) return FAIL;
13216
14275
  const end = EC.e;
@@ -13301,6 +14360,34 @@ function assemble(t2, prog, cfg) {
13301
14360
  rawScalarSpecs.add(code[child + 1]);
13302
14361
  scalarFor(child);
13303
14362
  }
14363
+ } else if (code[ip] === OP_CHOICE && !disp[code[ip + 1]].exclusive) {
14364
+ const n = code[ip + 2];
14365
+ for (let i = 0; i < n; i++) {
14366
+ const armIp = code[ip + 4 + i];
14367
+ const child = leadingScalarTerminal(code, armIp, 2, true, true);
14368
+ if (n === 2 || n === 3) {
14369
+ if (child >= 0) scalarFor(child);
14370
+ continue;
14371
+ }
14372
+ if (child >= 0) {
14373
+ const spec = k[code[child + 1]];
14374
+ if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) {
14375
+ scalarFor(child);
14376
+ continue;
14377
+ }
14378
+ }
14379
+ const family = leadingLiteralFamily(code, k, armIp);
14380
+ if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
14381
+ const value = k[code[terminal + 1]];
14382
+ return typeof value === "string" && value.length >= 2;
14383
+ })) {
14384
+ for (const terminal of family) scalarFor(terminal);
14385
+ }
14386
+ const sequence6 = leadingScalarSequence(code, armIp);
14387
+ if (sequence6 !== void 0 && (sequence6.trivia < 0 || triviaScan[sequence6.trivia] != null)) {
14388
+ for (const terminal of sequence6.terminals) scalarFor(terminal);
14389
+ }
14390
+ }
13304
14391
  }
13305
14392
  }
13306
14393
  const notChild = scalarTerminalNotChild(code, ip);
@@ -13711,7 +14798,7 @@ function emitAssemblies(prog, cfgs) {
13711
14798
  seen.add(key);
13712
14799
  let em;
13713
14800
  try {
13714
- em = emitAssemblySource(t2, prog, cfg, extraIps);
14801
+ em = emitAssemblySource(t2, prog, cfg, extraIps, true);
13715
14802
  } catch (e) {
13716
14803
  if (e instanceof Unemittable) continue;
13717
14804
  throw e;
@@ -16086,7 +17173,7 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
16086
17173
  };
16087
17174
  const { prog, fnSrcs } = encodeTableProgram({ [ENTRY]: combinator }, settings);
16088
17175
  const artifact = closureArtifact(prog);
16089
- const entry = tableRules(artifact)[ENTRY];
17176
+ const entry = tableRules(prog)[ENTRY];
16090
17177
  const offered = opts.fnSources ?? mapFnSources;
16091
17178
  const supplied = offered !== void 0 && offered.length === fnSrcs.length ? offered : void 0;
16092
17179
  const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? ownSource(prog.fns[i]));
@@ -16550,6 +17637,7 @@ function rebuildCombinator(root, replacements) {
16550
17637
  return p;
16551
17638
  }
16552
17639
  out = d.type === void 0 ? d.build === void 0 ? node(one(d.parser), opts) : node(one(d.parser), d.build) : node(d.type, one(d.parser), d.build, opts);
17640
+ if (d.buildRawUnused === true && out._def.tag === "node") out._def.buildRawUnused = true;
16553
17641
  break;
16554
17642
  }
16555
17643
  case "grammar": {