parseman 0.50.1 → 0.50.3

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 (53) hide show
  1. package/README.md +14 -10
  2. package/dist/analysis/diagnostics.js +431 -219
  3. package/dist/analysis/diagnostics.js.map +3 -3
  4. package/dist/cli/index.js +421 -184
  5. package/dist/cli/index.js.map +3 -3
  6. package/dist/combinators/choice.d.ts.map +1 -1
  7. package/dist/combinators/grammar.d.ts.map +1 -1
  8. package/dist/combinators/keywords.d.ts.map +1 -1
  9. package/dist/combinators/literal.d.ts.map +1 -1
  10. package/dist/combinators/map.d.ts.map +1 -1
  11. package/dist/combinators/ref.d.ts.map +1 -1
  12. package/dist/combinators/regex.d.ts.map +1 -1
  13. package/dist/combinators/repeat.d.ts.map +1 -1
  14. package/dist/combinators/scalar.d.ts +6 -0
  15. package/dist/combinators/scalar.d.ts.map +1 -0
  16. package/dist/combinators/sequence.d.ts.map +1 -1
  17. package/dist/combinators/trivia-skip.d.ts +2 -0
  18. package/dist/combinators/trivia-skip.d.ts.map +1 -1
  19. package/dist/compiler/token-capability.js +0 -3
  20. package/dist/compiler/token-capability.js.map +2 -2
  21. package/dist/index.js +422 -185
  22. package/dist/index.js.map +3 -3
  23. package/dist/language-service/index.js +68 -172
  24. package/dist/language-service/index.js.map +3 -3
  25. package/dist/parse-context.d.ts.map +1 -1
  26. package/dist/plugin/index.js +467 -299
  27. package/dist/plugin/index.js.map +3 -3
  28. package/dist/run/index.js +1 -0
  29. package/dist/run/index.js.map +1 -1
  30. package/dist/spec/index.js +399 -277
  31. package/dist/spec/index.js.map +3 -3
  32. package/dist/table/emit-assembly.d.ts.map +1 -1
  33. package/dist/table/index.js +307 -181
  34. package/dist/table/index.js.map +3 -3
  35. package/dist/types.d.ts +8 -0
  36. package/dist/types.d.ts.map +1 -1
  37. package/dist/version.d.ts +1 -1
  38. package/package.json +4 -2
  39. package/src/combinators/choice.ts +34 -1
  40. package/src/combinators/grammar.ts +39 -0
  41. package/src/combinators/keywords.ts +14 -3
  42. package/src/combinators/literal.ts +26 -0
  43. package/src/combinators/map.ts +60 -0
  44. package/src/combinators/ref.ts +26 -7
  45. package/src/combinators/regex.ts +23 -0
  46. package/src/combinators/repeat.ts +109 -16
  47. package/src/combinators/scalar.ts +30 -0
  48. package/src/combinators/sequence.ts +76 -161
  49. package/src/combinators/trivia-skip.ts +14 -1
  50. package/src/parse-context.ts +1 -0
  51. package/src/table/emit-assembly.ts +39 -16
  52. package/src/types.ts +8 -0
  53. package/src/version.ts +1 -1
@@ -615,16 +615,26 @@ function keywords(words, opts = {}) {
615
615
  caseInsensitive: opts.caseInsensitive ?? false,
616
616
  boundary: opts.boundary
617
617
  };
618
+ const expected = directTerminalFailureExpected(def);
619
+ const parseScalar = (input, pos, ctx) => {
620
+ re.lastIndex = pos;
621
+ const m = re.exec(input);
622
+ if (m === null) {
623
+ ctx._fx = expected;
624
+ return ~pos;
625
+ }
626
+ ctx._sv = m[0];
627
+ return pos + m[0].length;
628
+ };
618
629
  return {
619
630
  _tag: "keywords",
620
631
  _meta: meta,
621
632
  _def: def,
633
+ _parseScalar: parseScalar,
622
634
  parse(input, pos, ctx) {
623
635
  re.lastIndex = pos;
624
636
  const m = re.exec(input);
625
- if (m === null || m.index !== pos) {
626
- return failAt(ctx, directTerminalFailureExpected(def), pos);
627
- }
637
+ if (m === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
628
638
  const value = m[0];
629
639
  const span = { start: pos, end: pos + value.length };
630
640
  if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
@@ -768,6 +778,7 @@ function createParseContext() {
768
778
  _fe: void 0,
769
779
  _fx: void 0,
770
780
  _fc: void 0,
781
+ _sv: void 0,
771
782
  _probe: void 0,
772
783
  _cstChildren: void 0,
773
784
  _cstLeaves: void 0,
@@ -1468,6 +1479,9 @@ var fastScanner3;
1468
1479
  function needsDeferredTriviaCommit(ctx) {
1469
1480
  return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
1470
1481
  }
1482
+ function needsTriviaRollback(ctx) {
1483
+ return ctx._cstBuf !== void 0 || ctx._cstLeaves !== void 0 || ctx._cstRawChildren !== void 0 || ctx._cstTriviaLog !== void 0 || ctx._fields !== void 0 || ctx._errors !== void 0 || ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0;
1484
+ }
1471
1485
  function saveTriviaMark(ctx) {
1472
1486
  const m = saveCstMark(ctx);
1473
1487
  return {
@@ -1584,7 +1598,8 @@ function advanceTrivia(input, cur, ctx) {
1584
1598
  const triviaP = ctx.trivia;
1585
1599
  if (!triviaP) return cur;
1586
1600
  if (!ctx.trackLines) {
1587
- const fast2 = fastTriviaScanner(triviaP);
1601
+ const classified = triviaP._meta.triviaScanner;
1602
+ const fast2 = classified === void 0 ? fastTriviaScanner(triviaP) : classified;
1588
1603
  if (fast2) return fast2(input, cur);
1589
1604
  if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
1590
1605
  const tr2 = triviaP.parse(input, cur, createDetachedParseContext(ctx.trackLines, ctx.state));
@@ -2151,6 +2166,28 @@ function refuseUnclassifiedRootScope(strict) {
2151
2166
  if (strict === true) throw new TypeError(ROOT_TRIVIA_SCOPE_REFUSAL);
2152
2167
  }
2153
2168
 
2169
+ // src/combinators/scalar.ts
2170
+ var SCALAR_TAG = /^(?:literal|regex|keywords|sequence|choice|many|oneOrMore|optional|transform|trivia|grammar|sepBy|lazy)$/;
2171
+ function scalarOf(combinator) {
2172
+ return combinator._parseScalar;
2173
+ }
2174
+ function scalarTree(parser2, seen) {
2175
+ if (seen.has(parser2)) return true;
2176
+ if (parser2._parseScalar === void 0) return false;
2177
+ seen.add(parser2);
2178
+ const def = parser2._def;
2179
+ if (!SCALAR_TAG.test(def.tag)) return false;
2180
+ if ("parsers" in def && !def.parsers.every((child) => scalarTree(child, seen))) return false;
2181
+ if ("parser" in def && !scalarTree(def.parser, seen)) return false;
2182
+ if ("separator" in def && !scalarTree(def.separator, seen)) return false;
2183
+ return def.tag !== "lazy" || scalarTree(def.thunk(), seen);
2184
+ }
2185
+ function scalarRootOf(combinator) {
2186
+ const scalar = combinator._parseScalar;
2187
+ const def = combinator._def;
2188
+ return scalar !== void 0 && def.tag === "grammar" && scalarTree(def.parser, /* @__PURE__ */ new Set()) ? scalar : void 0;
2189
+ }
2190
+
2154
2191
  // src/combinators/grammar.ts
2155
2192
  function annotateResultLines(result, index) {
2156
2193
  const annotated = { ...result, span: annotateSpan(result.span, index) };
@@ -2187,6 +2224,24 @@ function parser(opts, root) {
2187
2224
  const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
2188
2225
  const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
2189
2226
  const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
2227
+ const rootScalar = scalarOf(root);
2228
+ const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
2229
+ const parseScalar = scalarEligible ? (input, pos, ctx) => {
2230
+ const savedTrivia = ctx.trivia;
2231
+ const savedLabels = ctx.triviaKindLabels;
2232
+ if (clearTrivia) {
2233
+ ctx.trivia = void 0;
2234
+ ctx.triviaKindLabels = void 0;
2235
+ } else if (scopeTrivia !== void 0) {
2236
+ ctx.trivia = scopeTrivia;
2237
+ ctx.triviaKindLabels = scopeLabels;
2238
+ }
2239
+ const end = rootScalar(input, pos, ctx);
2240
+ ctx.trivia = savedTrivia;
2241
+ ctx.triviaKindLabels = savedLabels;
2242
+ return end;
2243
+ } : void 0;
2244
+ let publicScalar;
2190
2245
  const grammar = {
2191
2246
  _tag: "grammar",
2192
2247
  _meta: {
@@ -2210,7 +2265,20 @@ function parser(opts, root) {
2210
2265
  constructionTrackLines: trackLinesPolicy,
2211
2266
  ...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
2212
2267
  },
2268
+ _parseScalar: parseScalar,
2213
2269
  parse(input, pos, _ctx) {
2270
+ if (pos === void 0 && _ctx === void 0) {
2271
+ publicScalar ??= scalarRootOf(grammar) ?? null;
2272
+ if (publicScalar) {
2273
+ const ctx2 = createParseContext();
2274
+ const end = publicScalar(input, 0, ctx2);
2275
+ if (end < 0) {
2276
+ const at = ~end;
2277
+ return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
2278
+ }
2279
+ return { ok: true, value: ctx2._sv, span: { start: 0, end } };
2280
+ }
2281
+ }
2214
2282
  if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
2215
2283
  const trackLines = trackLinesOf(_ctx);
2216
2284
  const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
@@ -2245,6 +2313,9 @@ function parse(combinator, input, opts = {}) {
2245
2313
  _analyzed.add(combinator);
2246
2314
  markUnusedValues(combinator);
2247
2315
  }
2316
+ if (!opts.trackLines && !opts.recover && combinator._def.tag === "grammar" && combinator._meta.grammarScanSkip === void 0) {
2317
+ return combinator.parse(input);
2318
+ }
2248
2319
  const trackLines = opts.trackLines ?? combinator._meta.grammarTrackLines ?? false;
2249
2320
  const lineContext = trackLines ? createParseLineContext(input, 0) : void 0;
2250
2321
  const lineIndex = lineContext?.lineIndex;
@@ -3410,7 +3481,8 @@ function choice(...args) {
3410
3481
  disjoint
3411
3482
  };
3412
3483
  const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
3413
- const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
3484
+ const ordered = strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix";
3485
+ const autoNot = !disjoint && !hasGates && ordered ? computeAutoNot(parsers) : parsers.map(() => null);
3414
3486
  let greedyLitMap = null;
3415
3487
  let sortedParsers = null;
3416
3488
  const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
@@ -3424,6 +3496,37 @@ function choice(...args) {
3424
3496
  } else if (strategy?.tag === "literalsLongestFirst") {
3425
3497
  sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
3426
3498
  }
3499
+ const scalarParsers = parsers.map(scalarOf);
3500
+ const scalarEligible = !hasGates && parsers.every((p) => p._parseScalar !== void 0) && (disjoint || ordered);
3501
+ const scalarExpected = parsers.flatMap(deriveExpected);
3502
+ const parseScalar = (input, pos, ctx) => {
3503
+ if (disjoint) {
3504
+ const code = pos < input.length ? input.codePointAt(pos) : -1;
3505
+ let idx = code >= 0 && code < 128 ? asciiDispatch[code] : -1;
3506
+ if (idx < 0 && code >= 0) {
3507
+ for (let i = 0; i < parsers.length; i++) {
3508
+ if (inFirstSet(code, parsers[i]._meta.firstSet)) {
3509
+ idx = i;
3510
+ break;
3511
+ }
3512
+ }
3513
+ }
3514
+ if (idx >= 0) {
3515
+ const gate = gates[idx];
3516
+ if (!gate || gate(ctx.state)) return scalarParsers[idx](input, pos, ctx);
3517
+ ctx._fx = deriveExpected(parsers[idx]);
3518
+ return ~pos;
3519
+ }
3520
+ } else {
3521
+ for (let i = 0; i < scalarParsers.length; i++) {
3522
+ if (gates[i] && !gates[i](ctx.state)) continue;
3523
+ const end = scalarParsers[i](input, pos, ctx);
3524
+ if (end >= 0 && (!autoNot[i] || !autoNotFires(input, end, autoNot[i]))) return end;
3525
+ }
3526
+ }
3527
+ ctx._fx = scalarExpected;
3528
+ return ~pos;
3529
+ };
3427
3530
  return {
3428
3531
  _tag: "choice",
3429
3532
  _meta: meta,
@@ -3435,6 +3538,7 @@ function choice(...args) {
3435
3538
  strategy: strategy ?? { tag: "firstMatch" },
3436
3539
  autoNot
3437
3540
  },
3541
+ _parseScalar: scalarEligible ? parseScalar : void 0,
3438
3542
  parse(input, pos, ctx) {
3439
3543
  const expected = [];
3440
3544
  let expectedAt = pos;
@@ -4774,8 +4878,8 @@ function buildLexProgramRunner(spec, matchers, classes, expected) {
4774
4878
  }
4775
4879
 
4776
4880
  // src/combinators/repeat.ts
4777
- function repItem(combinator, input, cur, ctx, guardable, mandatory) {
4778
- const mark = saveTriviaMark(ctx);
4881
+ function repItem(combinator, input, cur, ctx, guardable, mandatory, rollbackNeeded) {
4882
+ const mark = rollbackNeeded ? saveTriviaMark(ctx) : void 0;
4779
4883
  let pos = cur;
4780
4884
  if (ctx.trivia) {
4781
4885
  if (needsDeferredTriviaCommit(ctx)) {
@@ -4785,24 +4889,24 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
4785
4889
  }
4786
4890
  }
4787
4891
  if (pos >= input.length && !mandatory) {
4788
- rollbackTrivia(ctx, mark);
4892
+ if (mark !== void 0) rollbackTrivia(ctx, mark);
4789
4893
  return "stop";
4790
4894
  }
4791
4895
  if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
4792
- rollbackTrivia(ctx, mark);
4896
+ if (mark !== void 0) rollbackTrivia(ctx, mark);
4793
4897
  return "stop";
4794
4898
  }
4795
4899
  const result = combinator.parse(input, pos, ctx);
4796
4900
  if (!result.ok) {
4797
- rollbackTrivia(ctx, mark);
4901
+ if (mark !== void 0) rollbackTrivia(ctx, mark);
4798
4902
  if (result.committed) return { fail: result, failPos: pos };
4799
4903
  return { fail: result, failPos: pos };
4800
4904
  }
4801
4905
  if (result.span.end === pos && !mandatory) {
4802
- rollbackTrivia(ctx, mark);
4906
+ if (mark !== void 0) rollbackTrivia(ctx, mark);
4803
4907
  return "stop";
4804
4908
  }
4805
- return { value: result.value, end: result.span.end };
4909
+ return result;
4806
4910
  }
4807
4911
  function resolveBounds(what, opts) {
4808
4912
  const min = opts.min ?? 0;
@@ -4815,6 +4919,21 @@ function resolveBounds(what, opts) {
4815
4919
  if (max < min) bad(`max (${max}) is less than min (${min}) \u2014 the combinator could never succeed`);
4816
4920
  return { min, max };
4817
4921
  }
4922
+ function repeatScalarTail(combinator, child, input, cur, ctx, guardable, values, remaining) {
4923
+ while (cur < input.length && remaining > 0) {
4924
+ let itemPos = cur;
4925
+ if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
4926
+ if (itemPos >= input.length) break;
4927
+ if (guardable && !startsFirstSet(combinator, input, itemPos)) break;
4928
+ const end = child(input, itemPos, ctx);
4929
+ if (end <= itemPos) break;
4930
+ if (values !== void 0) values.push(ctx._sv);
4931
+ cur = end;
4932
+ remaining--;
4933
+ }
4934
+ ctx._sv = values;
4935
+ return cur;
4936
+ }
4818
4937
  function many(combinator, opts = {}) {
4819
4938
  const { min, max } = resolveBounds("many()", opts);
4820
4939
  if (min >= 1) return atLeast(combinator, min, max);
@@ -4826,17 +4945,21 @@ function many(combinator, opts = {}) {
4826
4945
  const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max } };
4827
4946
  let expected;
4828
4947
  const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
4948
+ const scalarChild = scalarOf(combinator);
4949
+ const parseScalar = (input, pos, ctx) => repeatScalarTail(combinator, scalarChild, input, pos, ctx, guardable, def.valueUnused ? void 0 : [], max);
4829
4950
  return {
4830
4951
  _tag: "many",
4831
4952
  _meta: meta,
4832
4953
  _def: def,
4954
+ _parseScalar: parseScalar,
4833
4955
  parse(input, pos, ctx) {
4834
4956
  const values = def.valueUnused ? void 0 : [];
4957
+ const rollbackNeeded = needsTriviaRollback(ctx);
4835
4958
  let cur = pos;
4836
4959
  let count = 0;
4837
4960
  while (cur < input.length) {
4838
4961
  if (count >= max) break;
4839
- const item = repItem(combinator, input, cur, ctx, guardable, false);
4962
+ const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
4840
4963
  if (item === "stop") break;
4841
4964
  if ("fail" in item) {
4842
4965
  if (!item.fail.ok && item.fail.committed) return item.fail;
@@ -4853,7 +4976,7 @@ function many(combinator, opts = {}) {
4853
4976
  }
4854
4977
  if (values !== void 0) values.push(item.value);
4855
4978
  count++;
4856
- cur = item.end;
4979
+ cur = item.span.end;
4857
4980
  }
4858
4981
  return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
4859
4982
  }
@@ -4871,30 +4994,47 @@ function atLeast(combinator, min, max) {
4871
4994
  const def = { tag: "oneOrMore", parser: combinator, min, ...max === Infinity ? {} : { max } };
4872
4995
  let expected;
4873
4996
  const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
4997
+ const scalarChild = scalarOf(combinator);
4998
+ const parseScalar = (input, pos, ctx) => {
4999
+ let cur = scalarChild(input, pos, ctx);
5000
+ if (cur < 0) return cur;
5001
+ const values = def.valueUnused ? void 0 : [ctx._sv];
5002
+ for (let count = 1; count < min; count++) {
5003
+ let itemPos = cur;
5004
+ if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
5005
+ const end = scalarChild(input, itemPos, ctx);
5006
+ if (end < 0) return ~cur;
5007
+ cur = end;
5008
+ if (values !== void 0) values.push(ctx._sv);
5009
+ }
5010
+ return repeatScalarTail(combinator, scalarChild, input, cur, ctx, guardable, values, max - min);
5011
+ };
4874
5012
  return {
4875
5013
  _tag: "oneOrMore",
4876
5014
  _meta: meta,
4877
5015
  _def: def,
5016
+ _parseScalar: parseScalar,
4878
5017
  parse(input, pos, ctx) {
4879
5018
  const first = combinator.parse(input, pos, ctx);
4880
5019
  if (!first.ok) return first;
4881
5020
  const values = def.valueUnused ? void 0 : [first.value];
5021
+ const rollbackNeeded = needsTriviaRollback(ctx);
4882
5022
  let cur = first.span.end;
4883
5023
  let count = 1;
4884
5024
  while (count < min) {
4885
- const item = repItem(combinator, input, cur, ctx, guardable, true);
5025
+ const item = repItem(combinator, input, cur, ctx, guardable, true, rollbackNeeded);
4886
5026
  if (item === "stop" || "fail" in item) {
4887
5027
  if (item !== "stop" && !item.fail.ok && item.fail.committed) return item.fail;
4888
5028
  expected ??= deriveExpected(combinator);
4889
5029
  return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: cur, end: cur } };
4890
5030
  }
4891
5031
  if (values !== void 0) values.push(item.value);
4892
- cur = item.end;
5032
+ cur = item.span.end;
4893
5033
  count++;
4894
5034
  }
4895
5035
  while (cur < input.length) {
4896
5036
  if (count >= max) break;
4897
- const item = repItem(combinator, input, cur, ctx, guardable, false);
5037
+ const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
4898
5038
  if (item === "stop") break;
4899
5039
  if ("fail" in item) {
4900
5040
  if (!item.fail.ok && item.fail.committed) return item.fail;
@@ -4911,7 +5051,7 @@ function atLeast(combinator, min, max) {
4911
5051
  }
4912
5052
  if (values !== void 0) values.push(item.value);
4913
5053
  count++;
4914
- cur = item.end;
5054
+ cur = item.span.end;
4915
5055
  }
4916
5056
  return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
4917
5057
  }
@@ -4924,10 +5064,22 @@ function optional(combinator) {
4924
5064
  isTrivia: false
4925
5065
  };
4926
5066
  const firstSetSkippable = !matchesEmpty(combinator);
5067
+ const scalarChild = scalarOf(combinator);
5068
+ const parseScalar = (input, pos, ctx) => {
5069
+ if (firstSetSkippable && !startsFirstSet(combinator, input, pos)) {
5070
+ ctx._sv = null;
5071
+ return pos;
5072
+ }
5073
+ const end = scalarChild(input, pos, ctx);
5074
+ if (end >= 0) return end;
5075
+ ctx._sv = null;
5076
+ return pos;
5077
+ };
4927
5078
  return {
4928
5079
  _tag: "optional",
4929
5080
  _meta: meta,
4930
5081
  _def: { tag: "optional", parser: combinator },
5082
+ _parseScalar: parseScalar,
4931
5083
  parse(input, pos, ctx) {
4932
5084
  if (firstSetSkippable && ctx._probe === void 0 && !startsFirstSet(combinator, input, pos)) {
4933
5085
  return { ok: true, value: null, span: { start: pos, end: pos } };
@@ -4958,6 +5110,43 @@ function sepBy(combinator, separatorArg, opts = {}) {
4958
5110
  expected ??= deriveExpected(combinator);
4959
5111
  return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: at, end: at } };
4960
5112
  };
5113
+ const scalarExpected = deriveExpected(combinator);
5114
+ const scalarChild = scalarOf(combinator);
5115
+ const scalarSeparator = scalarOf(separator);
5116
+ const parseScalar = (input, pos, ctx) => {
5117
+ let cur = scalarChild(input, pos, ctx);
5118
+ if (cur < 0) {
5119
+ if (min >= 1) {
5120
+ ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
5121
+ return ~pos;
5122
+ }
5123
+ ctx._sv = [];
5124
+ return pos;
5125
+ }
5126
+ const values = [ctx._sv];
5127
+ while (values.length < max && (cur < input.length || values.length < min)) {
5128
+ const beforeSeparator = cur;
5129
+ let separatorPos = cur;
5130
+ if (ctx.trivia) separatorPos = advanceTrivia(input, cur, ctx);
5131
+ const separatorEnd = scalarSeparator(input, separatorPos, ctx);
5132
+ if (separatorEnd < 0) break;
5133
+ let itemPos = separatorEnd;
5134
+ if (ctx.trivia) itemPos = advanceTrivia(input, itemPos, ctx);
5135
+ const itemEnd = scalarChild(input, itemPos, ctx);
5136
+ if (itemEnd < 0) {
5137
+ cur = trailing === "allow" ? separatorEnd : beforeSeparator;
5138
+ break;
5139
+ }
5140
+ values.push(ctx._sv);
5141
+ cur = itemEnd;
5142
+ }
5143
+ if (values.length < min) {
5144
+ ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
5145
+ return ~cur;
5146
+ }
5147
+ ctx._sv = values;
5148
+ return cur;
5149
+ };
4961
5150
  return {
4962
5151
  _tag: "sepBy",
4963
5152
  _meta: meta,
@@ -4973,6 +5162,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
4973
5162
  // this option surface already; parity is held by test/parity, not by hope.
4974
5163
  ...keepSeparators ? { keepSeparators: true } : {}
4975
5164
  },
5165
+ _parseScalar: keepSeparators ? void 0 : parseScalar,
4976
5166
  parse(input, pos, ctx) {
4977
5167
  const first = combinator.parse(input, pos, ctx);
4978
5168
  const values = [];
@@ -5050,11 +5240,54 @@ function sepBy(combinator, separatorArg, opts = {}) {
5050
5240
  }
5051
5241
 
5052
5242
  // src/combinators/map.ts
5243
+ var JSON_STRING_BODY = String.raw`(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*`;
5053
5244
  function transform(combinator, fn) {
5245
+ const observesSpan = fn.length > 1;
5246
+ const sequenceDef = combinator._def.tag === "sequence" ? combinator._def : void 0;
5247
+ const terms = sequenceDef?.parsers;
5248
+ const inner = terms?.[1];
5249
+ const fused = terms?.length === 3 && terms[0]._def.tag === "literal" && terms[0]._def.value === '"' && !terms[0]._def.caseInsensitive && inner._def.tag === "regex" && inner._def.source === JSON_STRING_BODY && inner._def.flags === "" && terms[2]._def.tag === "literal" && terms[2]._def.value === '"' && !terms[2]._def.caseInsensitive && inner._stickyRegex !== void 0;
5250
+ const child = scalarOf(combinator);
5251
+ const parseScalar = fused ? (() => {
5252
+ const body = inner._stickyRegex;
5253
+ const tuple = ['"', "", '"'];
5254
+ const expected = [JSON.stringify('"')];
5255
+ return (input, pos, ctx) => {
5256
+ if (ctx.trivia !== void 0) {
5257
+ const end2 = child(input, pos, ctx);
5258
+ if (end2 < 0) return end2;
5259
+ ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end: end2 }) : fn(ctx._sv);
5260
+ return end2;
5261
+ }
5262
+ if (input.charCodeAt(pos) !== 34) {
5263
+ ctx._fx = expected;
5264
+ return ~pos;
5265
+ }
5266
+ body.lastIndex = pos + 1;
5267
+ const match = body.exec(input);
5268
+ const close = pos + 1 + match[0].length;
5269
+ if (input.charCodeAt(close) !== 34) {
5270
+ ctx._fx = expected;
5271
+ return ~close;
5272
+ }
5273
+ tuple[1] = match[0];
5274
+ const end = close + 1;
5275
+ ctx._sv = observesSpan ? fn(tuple, { start: pos, end }) : fn(tuple);
5276
+ return end;
5277
+ };
5278
+ })() : /* @__PURE__ */ (() => {
5279
+ return (input, pos, ctx) => {
5280
+ const end = child(input, pos, ctx);
5281
+ if (end < 0) return end;
5282
+ ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end }) : fn(ctx._sv);
5283
+ return end;
5284
+ };
5285
+ })();
5054
5286
  return {
5055
5287
  _tag: "transform",
5056
5288
  _meta: combinator._meta,
5057
5289
  _def: { tag: "transform", parser: combinator, fn },
5290
+ _parseScalar: parseScalar,
5058
5291
  parse(input, pos, ctx) {
5059
5292
  const result = combinator.parse(input, pos, ctx);
5060
5293
  if (!result.ok) return result;
@@ -5069,9 +5302,11 @@ function trivia(combinator) {
5069
5302
  _meta: {
5070
5303
  ...combinator._meta,
5071
5304
  isTrivia: true,
5305
+ triviaScanner: fastTriviaScanner(combinator),
5072
5306
  ...kindLabels ? { triviaKindLabels: kindLabels } : {}
5073
5307
  },
5074
5308
  _def: { tag: "trivia", parser: combinator },
5309
+ _parseScalar: scalarOf(combinator),
5075
5310
  parse: combinator.parse.bind(combinator)
5076
5311
  };
5077
5312
  }
@@ -5192,10 +5427,32 @@ function regex(pattern, flags = "") {
5192
5427
  const canMatchNewline = raw.canMatchNewline;
5193
5428
  const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
5194
5429
  const def = { tag: "regex", source, flags: resolvedFlags };
5430
+ const expected = directTerminalFailureExpected(def);
5431
+ const parseScalar = (input, pos, ctx) => {
5432
+ const scanEnd = scan?.(input, pos);
5433
+ if (scanEnd !== void 0) {
5434
+ if (scanEnd === null) {
5435
+ ctx._fx = expected;
5436
+ return ~pos;
5437
+ }
5438
+ ctx._sv = input.slice(pos, scanEnd);
5439
+ return scanEnd;
5440
+ }
5441
+ anchored.lastIndex = pos;
5442
+ const match = anchored.exec(input);
5443
+ if (match === null) {
5444
+ ctx._fx = expected;
5445
+ return ~pos;
5446
+ }
5447
+ ctx._sv = match[0];
5448
+ return pos + match[0].length;
5449
+ };
5195
5450
  return {
5196
5451
  _tag: "regex",
5197
5452
  _meta: meta,
5198
5453
  _def: def,
5454
+ _stickyRegex: anchored,
5455
+ _parseScalar: parseScalar,
5199
5456
  parse(input, pos, ctx) {
5200
5457
  const scanEnd = scan?.(input, pos);
5201
5458
  if (scanEnd !== void 0) {
@@ -6805,7 +7062,7 @@ var Encoder = class {
6805
7062
  const dispCovIds = this.plan?.dispatches.get(p);
6806
7063
  let dispCov = 0;
6807
7064
  const arms = [];
6808
- const routed2 = [];
7065
+ const routed = [];
6809
7066
  const key = [], keyArm = [];
6810
7067
  const fold = [], foldArm = [];
6811
7068
  const match = [];
@@ -6813,7 +7070,7 @@ var Encoder = class {
6813
7070
  for (const c of d.cases) {
6814
7071
  const arm = arms.length;
6815
7072
  arms.push(this.covWrap(this.node(c.parser).ip, dispCovIds?.[dispCov++], 1));
6816
- routed2.push(branchUsesRouted(c) ? 1 : 0);
7073
+ routed.push(branchUsesRouted(c) ? 1 : 0);
6817
7074
  for (const kk of c.keys) {
6818
7075
  expected.push(JSON.stringify(kk));
6819
7076
  if (c.caseInsensitive) {
@@ -6829,7 +7086,7 @@ var Encoder = class {
6829
7086
  for (const m of d.matchers ?? []) {
6830
7087
  const arm = arms.length;
6831
7088
  arms.push(this.covWrap(this.node(m.parser).ip, dispCovIds?.[dispCov++], 1));
6832
- routed2.push(branchUsesRouted(m) ? 1 : 0);
7089
+ routed.push(branchUsesRouted(m) ? 1 : 0);
6833
7090
  if (!m.caseInsensitive) {
6834
7091
  match.push([KIND[m.kind], m.value, m.flags ?? "", arm]);
6835
7092
  continue;
@@ -6843,7 +7100,7 @@ var Encoder = class {
6843
7100
  }
6844
7101
  const other = d.otherwise === void 0 ? -1 : this.covWrap(this.node(d.otherwise).ip, dispCovIds?.[dispCov++], 1);
6845
7102
  const dspIdx = this.dsp.length;
6846
- this.dsp.push({ key, keyArm, fold, foldArm, match, routed: routed2, expected });
7103
+ this.dsp.push({ key, keyArm, fold, foldArm, match, routed, expected });
6847
7104
  const head = this.emitHead(OP_DISPATCH, 5 + arms.length);
6848
7105
  this.code[head + 1] = sel;
6849
7106
  this.code[head + 2] = dspIdx;
@@ -8715,6 +8972,9 @@ if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTrivi
8715
8972
  function q(s) {
8716
8973
  return JSON.stringify(s);
8717
8974
  }
8975
+ function isAsciiOnlyClass(cls) {
8976
+ return cls !== null && cls !== void 0 && cls.hi.length === 0;
8977
+ }
8718
8978
  var NO_SINKS = { fd: false, er: false };
8719
8979
  function sinkSlots(t2, s) {
8720
8980
  return `${s.fd ? `,${t2}fd=0` : ""}${s.er ? `,${t2}er=0` : ""}`;
@@ -9261,12 +9521,13 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
9261
9521
  return `${head}EC.e=pos;return ''}`;
9262
9522
  case OP_GATE: {
9263
9523
  const child = link(code[ip + 2]);
9264
- const ci = classes.push([t2.cc[code[ip + 1]]]) - 1;
9524
+ const resolved = t2.cc[code[ip + 1]];
9525
+ const ci = classes.push([resolved]) - 1;
9265
9526
  classPlan.push([code[ip + 1]]);
9266
9527
  const cls = hoist("cl", `CLS[${ci}][0]`);
9267
9528
  const xf = fxRef(code[ip + 3]);
9268
9529
  return `${head}
9269
- if(!classHas(${cls},lead(input,pos))){ctx._fe=pos;ctx._fx=${xf};return FAIL}
9530
+ if(${staticBuild && isAsciiOnlyClass(resolved) ? `${cls}.ascii[input.charCodeAt(pos)]!==1` : `!classHas(${cls},lead(input,pos))`}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
9270
9531
  return ${child}(input,pos,ctx)
9271
9532
  }`;
9272
9533
  }
@@ -9609,10 +9870,11 @@ return v
9609
9870
  const asc = hoist("as", `DISP[${di}].ascii`);
9610
9871
  const hiArr = table.hi;
9611
9872
  const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
9873
+ const directAscii = staticBuild && table.hi.length === 0;
9612
9874
  return `${head}
9613
- const c=lead(input,pos)
9875
+ const c=${directAscii ? "input.charCodeAt(pos)" : "lead(input,pos)"}
9614
9876
  let arm=-1
9615
- if(c>=0&&c<128){const a=${asc}[c];if(a!==0)arm=a-1}
9877
+ if(${directAscii ? "c<128" : "c>=0&&c<128"}){const a=${asc}[c];if(a!==0)arm=a-1}
9616
9878
  ${hiArr.length === 0 ? "" : `else if(c>=128){const h=${hoist("hi", `DISP[${di}].hi`)}
9617
9879
  for(let i=0;i<h.length;i+=3){if(c>=h[i]&&c<=h[i+1]){arm=h[i+2];break}}}`}
9618
9880
  if(arm>=0){
@@ -9634,7 +9896,9 @@ return FAIL
9634
9896
  const di = code[ip + 1];
9635
9897
  const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
9636
9898
  const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
9637
- const gateRefs = Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
9899
+ const maskable = n <= 32;
9900
+ const directAsciiMask = staticBuild && maskable && gates.every(isAsciiOnlyClass);
9901
+ const gateRefs = directAsciiMask ? [] : Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
9638
9902
  const tokenCandidate = tokenChoiceCandidates.get(ip);
9639
9903
  const pretests = Array.from({ length: n }, (_, i) => {
9640
9904
  if (tokenCandidate?.arm === i) {
@@ -9654,7 +9918,6 @@ return FAIL
9654
9918
  const sequence6 = largeChoiceScalarSequences.get(code[base + i]);
9655
9919
  return sequence6 === void 0 ? void 0 : { sequence: scalarSequenceRef(sequence6) };
9656
9920
  });
9657
- const maskable = n <= 32;
9658
9921
  const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
9659
9922
  if (maskable) maskPlan.push(~di);
9660
9923
  const p = tmp();
@@ -9716,16 +9979,16 @@ ${merge}
9716
9979
  ctx._fe=pos;ctx._fx=acc??${choiceFx}
9717
9980
  return FAIL`;
9718
9981
  return `${head}
9719
- const c=lead(input,pos)
9982
+ const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
9720
9983
  ${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
9721
9984
  ${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
9722
9985
  ${maskable ? `if(c<128){
9723
- const bits=${maskName}[c<0?128:c]
9986
+ const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
9724
9987
  if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
9725
9988
  ${lazyArms(true)}
9726
- }else{
9989
+ }${directAsciiMask ? "" : `else{
9727
9990
  ${lazyArms(false)}
9728
- }
9991
+ }`}
9729
9992
  ` : lazyArms(false)}
9730
9993
  ${finish}
9731
9994
  }`;
@@ -9776,7 +10039,7 @@ if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0
9776
10039
  ${rollbackFor(i)}
9777
10040
  }${routeMiss}${sequenceMiss}`;
9778
10041
  }).join("\n") : "";
9779
- const generalArms = arms.map((arm, i) => {
10042
+ const generalArms = directAsciiMask ? "" : arms.map((arm, i) => {
9780
10043
  const pretest = pretests[i];
9781
10044
  const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
9782
10045
  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("||")})`;
@@ -9806,12 +10069,12 @@ ${rollbackFor(i)}
9806
10069
  }${miss}`;
9807
10070
  }).join("\n");
9808
10071
  return `${head}
9809
- const c=lead(input,pos)
10072
+ const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
9810
10073
  ${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
9811
10074
  let acc
9812
10075
  let best=pos
9813
10076
  ${maskable ? `if(c<128){
9814
- const bits=${maskName}[c<0?128:c]
10077
+ const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
9815
10078
  if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
9816
10079
  ${startFailureExact ? "" : "let prev=0"}
9817
10080
  ${maskArms}
@@ -9906,14 +10169,18 @@ return [key,v]
9906
10169
  const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
9907
10170
  const collect = op === OP_REP;
9908
10171
  let itemCls;
10172
+ let itemAscii = false;
9909
10173
  if (!REC) {
9910
10174
  const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
9911
10175
  if (itemClassIndex >= 0) {
9912
- const ci = classes.push([t2.cc[itemClassIndex]]) - 1;
10176
+ const resolved = t2.cc[itemClassIndex];
10177
+ const ci = classes.push([resolved]) - 1;
9913
10178
  classPlan.push([itemClassIndex]);
9914
10179
  itemCls = hoist("ri", `CLS[${ci}][0]`);
10180
+ itemAscii = staticBuild && isAsciiOnlyClass(resolved);
9915
10181
  }
9916
10182
  }
10183
+ const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
9917
10184
  const skipBeforeFirst = sepIp < 0 && min === 0;
9918
10185
  const p = tmp();
9919
10186
  const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
@@ -9973,7 +10240,7 @@ let count=0
9973
10240
  for(;;){
9974
10241
  ${max >= 0 ? `if(count>=${max})break
9975
10242
  ` : ""}${sep !== void 0 ? `if(count>0&&count>=${min}&&cur>=input.length)break
9976
- ` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}&&!classHas(${itemCls},lead(input,cur)))break
10243
+ ` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}&&${itemMiss("cur")})break
9977
10244
  ` : ""}let ${p}raw=0,${p}tl=0,${p}lv=0,${p}lg=0,${p}rt=0${sinks.fd ? `,${p}fd=0` : ""}${sinks.er ? `,${p}er=0` : ""}
9978
10245
  ${markBody}
9979
10246
  let itemStart=cur
@@ -9998,7 +10265,7 @@ itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(inp
9998
10265
  ${rb}
9999
10266
  ${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
10000
10267
  }
10001
- ${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&!classHas(${itemCls},lead(input,itemStart))){
10268
+ ${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&${itemMiss("itemStart")}){
10002
10269
  ${rb}
10003
10270
  ${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
10004
10271
  }
@@ -10282,6 +10549,28 @@ function literal(value, opts = {}) {
10282
10549
  isTrivia: false
10283
10550
  };
10284
10551
  const canMatchNewline = meta.canMatchNewline;
10552
+ const parseScalar = !caseInsensitive && value.length === 1 ? (() => {
10553
+ const code = value.charCodeAt(0);
10554
+ return (input, pos, ctx) => {
10555
+ if (input.charCodeAt(pos) === code) {
10556
+ ctx._sv = value;
10557
+ return pos + 1;
10558
+ }
10559
+ ctx._fx = expected;
10560
+ return ~pos;
10561
+ };
10562
+ })() : (input, pos, ctx) => {
10563
+ const end = pos + value.length;
10564
+ if (end <= input.length) {
10565
+ const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
10566
+ if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
10567
+ ctx._sv = matchedValue;
10568
+ return end;
10569
+ }
10570
+ }
10571
+ ctx._fx = expected;
10572
+ return ~pos;
10573
+ };
10285
10574
  if (caseInsensitive) {
10286
10575
  const upper = value.toUpperCase();
10287
10576
  const lower = value.toLowerCase();
@@ -10322,6 +10611,7 @@ function literal(value, opts = {}) {
10322
10611
  _tag: "literal",
10323
10612
  _meta: meta,
10324
10613
  _def: { tag: "literal", value, caseInsensitive },
10614
+ _parseScalar: parseScalar,
10325
10615
  parse: parse2
10326
10616
  };
10327
10617
  }
@@ -10341,6 +10631,7 @@ function sequence(...parsers) {
10341
10631
  (adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
10342
10632
  }
10343
10633
  const hasAdjacency = adjacency !== null;
10634
+ const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
10344
10635
  const meta = {
10345
10636
  // Union through the nullable prefix — a leading optional()/many() lets a later
10346
10637
  // term's first char start the sequence. Just `parsers[0]` under-approximates.
@@ -10349,165 +10640,96 @@ function sequence(...parsers) {
10349
10640
  isTrivia: false
10350
10641
  };
10351
10642
  const def = { tag: "sequence", parsers };
10352
- let followSentinels;
10353
- function parseTolerant(input, pos, ctx) {
10354
- followSentinels ??= parsers.map((_, i) => {
10355
- const fs = parsers.slice(i + 1).reduce(
10356
- (acc, p) => union(acc, firstSetOf(p)),
10357
- { kind: "empty" }
10358
- );
10359
- return firstSetSentinel(fs);
10360
- });
10361
- const values = def.valueUnused ? void 0 : [];
10643
+ const scalarParsers = parsers.map(scalarOf);
10644
+ const parseScalar = (input, pos, ctx) => {
10362
10645
  let cur = pos;
10363
- const inheritedSync = ctx._sync;
10364
- try {
10365
- for (let i = 0; i < parsers.length; i++) {
10366
- ctx._sync = followSentinels[i] ?? inheritedSync;
10367
- const adj = adjacency === null ? null : adjacency[i];
10368
- if (adj) {
10369
- if (!holdsAdjacency(input, cur, ctx, adj)) return adjacencyFail(cur, adj);
10370
- if (values !== void 0) values.push(null);
10371
- continue;
10372
- }
10373
- if (ctx.trivia && i > 0) {
10374
- const mTlog = cstTlLen(ctx);
10375
- const mLog = ctx._triviaLog?.length ?? 0;
10376
- const mRootLog = ctx._rootTriviaLog?.length ?? 0;
10377
- let scanEnd;
10378
- if (needsDeferredTriviaCommit(ctx)) {
10379
- scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
10380
- } else {
10381
- scanEnd = advanceTrivia(input, cur, ctx);
10382
- }
10383
- const scanTlog = cstTlLen(ctx);
10384
- const scanLog = ctx._triviaLog?.length ?? 0;
10385
- const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
10386
- const result2 = parsers[i].parse(input, scanEnd, ctx);
10387
- if (!result2.ok) return result2;
10388
- if (result2.span.end > scanEnd) cur = result2.span.end;
10389
- else rollbackScannedTriviaAt(
10390
- ctx,
10391
- mTlog,
10392
- scanTlog,
10393
- mLog,
10394
- scanLog,
10395
- mRootLog,
10396
- scanRootLog
10397
- );
10398
- if (values !== void 0) values.push(result2.value);
10399
- continue;
10400
- }
10401
- const result = parsers[i].parse(input, cur, ctx);
10402
- if (!result.ok) return result;
10403
- if (values !== void 0) values.push(result.value);
10404
- cur = result.span.end;
10646
+ if (strictArity !== 0) {
10647
+ cur = scalarParsers[0](input, cur, ctx);
10648
+ if (cur < 0) return cur;
10649
+ const first = ctx._sv;
10650
+ if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
10651
+ cur = scalarParsers[1](input, cur, ctx);
10652
+ if (cur < 0) return cur;
10653
+ const second = ctx._sv;
10654
+ if (strictArity === 2) {
10655
+ ctx._sv = def.valueUnused ? void 0 : [first, second];
10656
+ return cur;
10405
10657
  }
10406
- } finally {
10407
- ctx._sync = inheritedSync;
10658
+ if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
10659
+ cur = scalarParsers[2](input, cur, ctx);
10660
+ if (cur < 0) return cur;
10661
+ ctx._sv = def.valueUnused ? void 0 : [first, second, ctx._sv];
10662
+ return cur;
10408
10663
  }
10409
- return {
10410
- ok: true,
10411
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
10412
- value: values ?? void 0,
10413
- span: { start: pos, end: cur }
10414
- };
10415
- }
10416
- function parseAdjacent(input, pos, ctx) {
10417
10664
  const values = def.valueUnused ? void 0 : [];
10418
- let cur = pos;
10419
- for (let i = 0; i < parsers.length; i++) {
10420
- const adj = adjacency[i];
10421
- if (adj) {
10422
- if (!holdsAdjacency(input, cur, ctx, adj)) return adjacencyFail(cur, adj);
10423
- if (values !== void 0) values.push(null);
10424
- continue;
10425
- }
10426
- if (ctx.trivia && i > 0) {
10427
- let scanEnd;
10428
- const mTlog = cstTlLen(ctx);
10429
- const mLog = ctx._triviaLog?.length ?? 0;
10430
- const mRootLog = ctx._rootTriviaLog?.length ?? 0;
10431
- if (needsDeferredTriviaCommit(ctx)) {
10432
- scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
10433
- } else {
10434
- scanEnd = advanceTrivia(input, cur, ctx);
10435
- }
10436
- const scanTlog = cstTlLen(ctx);
10437
- const scanLog = ctx._triviaLog?.length ?? 0;
10438
- const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
10439
- const result2 = parsers[i].parse(input, scanEnd, ctx);
10440
- if (!result2.ok) return result2;
10441
- if (result2.span.end > scanEnd) cur = result2.span.end;
10442
- else rollbackScannedTriviaAt(
10443
- ctx,
10444
- mTlog,
10445
- scanTlog,
10446
- mLog,
10447
- scanLog,
10448
- mRootLog,
10449
- scanRootLog
10450
- );
10451
- if (values !== void 0) values.push(result2.value);
10452
- continue;
10453
- }
10454
- const result = parsers[i].parse(input, cur, ctx);
10455
- if (!result.ok) return result;
10456
- if (values !== void 0) values.push(result.value);
10457
- cur = result.span.end;
10458
- }
10459
- return {
10460
- ok: true,
10461
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
10462
- value: values ?? void 0,
10463
- span: { start: pos, end: cur }
10464
- };
10465
- }
10665
+ for (let i = 0; i < scalarParsers.length; i++) {
10666
+ let termPos = cur;
10667
+ if (i > 0 && ctx.trivia) termPos = advanceTrivia(input, cur, ctx);
10668
+ const end = scalarParsers[i](input, termPos, ctx);
10669
+ if (end < 0) return end;
10670
+ if (values !== void 0) values.push(ctx._sv);
10671
+ if (end > termPos || termPos === cur) cur = end;
10672
+ }
10673
+ ctx._sv = values;
10674
+ return cur;
10675
+ };
10676
+ let followSentinels;
10466
10677
  return {
10467
10678
  _tag: "sequence",
10468
10679
  _meta: meta,
10469
10680
  _def: def,
10681
+ _parseScalar: hasAdjacency ? void 0 : parseScalar,
10470
10682
  parse(input, pos, ctx) {
10471
- if (ctx._tolerant) return parseTolerant(input, pos, ctx);
10472
- if (hasAdjacency) return parseAdjacent(input, pos, ctx);
10683
+ const tolerant = ctx._tolerant === true;
10684
+ if (tolerant) {
10685
+ followSentinels ??= parsers.map((_, i) => firstSetSentinel(
10686
+ parsers.slice(i + 1).reduce(
10687
+ (set, parser2) => union(set, firstSetOf(parser2)),
10688
+ { kind: "empty" }
10689
+ )
10690
+ ));
10691
+ }
10692
+ const inheritedSync = ctx._sync;
10693
+ const deferredTrivia = needsDeferredTriviaCommit(ctx);
10473
10694
  const values = def.valueUnused ? void 0 : [];
10474
10695
  let cur = pos;
10475
- for (let i = 0; i < parsers.length; i++) {
10476
- if (ctx.trivia && i > 0) {
10477
- let scanEnd;
10478
- const mTlog = cstTlLen(ctx);
10479
- const mLog = ctx._triviaLog?.length ?? 0;
10480
- const mRootLog = ctx._rootTriviaLog?.length ?? 0;
10481
- if (needsDeferredTriviaCommit(ctx)) {
10482
- scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
10483
- } else {
10484
- scanEnd = advanceTrivia(input, cur, ctx);
10696
+ try {
10697
+ for (let i = 0; i < parsers.length; i++) {
10698
+ if (tolerant) ctx._sync = followSentinels[i] ?? inheritedSync;
10699
+ const assertion = adjacency?.[i];
10700
+ if (assertion) {
10701
+ if (!holdsAdjacency(input, cur, ctx, assertion)) return adjacencyFail(cur, assertion);
10702
+ if (values !== void 0) values.push(null);
10703
+ continue;
10485
10704
  }
10486
- const scanTlog = cstTlLen(ctx);
10487
- const scanLog = ctx._triviaLog?.length ?? 0;
10488
- const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
10489
- const result2 = parsers[i].parse(input, scanEnd, ctx);
10490
- if (!result2.ok) return result2;
10491
- if (result2.span.end > scanEnd) {
10492
- cur = result2.span.end;
10493
- } else {
10705
+ let termPos = cur;
10706
+ const markTlog = deferredTrivia ? cstTlLen(ctx) : 0;
10707
+ const markLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
10708
+ const markRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
10709
+ if (ctx.trivia && i > 0) {
10710
+ termPos = deferredTrivia ? commitTriviaScan(scanTriviaCompact(input, cur, ctx)) : advanceTrivia(input, cur, ctx);
10711
+ }
10712
+ const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
10713
+ const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
10714
+ const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
10715
+ const result = parsers[i].parse(input, termPos, ctx);
10716
+ if (!result.ok) return result;
10717
+ if (values !== void 0) values.push(result.value);
10718
+ if (result.span.end > termPos || termPos === cur) cur = result.span.end;
10719
+ else if (deferredTrivia) {
10494
10720
  rollbackScannedTriviaAt(
10495
10721
  ctx,
10496
- mTlog,
10722
+ markTlog,
10497
10723
  scanTlog,
10498
- mLog,
10724
+ markLog,
10499
10725
  scanLog,
10500
- mRootLog,
10726
+ markRootLog,
10501
10727
  scanRootLog
10502
10728
  );
10503
10729
  }
10504
- if (values !== void 0) values.push(result2.value);
10505
- continue;
10506
10730
  }
10507
- const result = parsers[i].parse(input, cur, ctx);
10508
- if (!result.ok) return result;
10509
- if (values !== void 0) values.push(result.value);
10510
- cur = result.span.end;
10731
+ } finally {
10732
+ if (tolerant) ctx._sync = inheritedSync;
10511
10733
  }
10512
10734
  return {
10513
10735
  ok: true,
@@ -10520,8 +10742,20 @@ function sequence(...parsers) {
10520
10742
  }
10521
10743
 
10522
10744
  // src/combinators/ref.ts
10745
+ function withRuleTrivia(trivia2, ctx, run) {
10746
+ const savedLabels = ctx.triviaKindLabels;
10747
+ ctx.trivia = trivia2;
10748
+ ctx.triviaKindLabels = trivia2._meta.triviaKindLabels;
10749
+ try {
10750
+ return run();
10751
+ } finally {
10752
+ ctx.trivia = void 0;
10753
+ ctx.triviaKindLabels = savedLabels;
10754
+ }
10755
+ }
10523
10756
  function ref() {
10524
10757
  let resolved = null;
10758
+ let resolvedScalar = null;
10525
10759
  let ownBoundary = false;
10526
10760
  const meta = {
10527
10761
  firstSet: any(),
@@ -10538,25 +10772,28 @@ function ref() {
10538
10772
  return resolved;
10539
10773
  }
10540
10774
  },
10775
+ _parseScalar(input, pos, ctx) {
10776
+ const scalar = resolvedScalar;
10777
+ if (!scalar) throw new Error("ref<T>() used before .define() was called");
10778
+ const gt = meta.grammarTrivia;
10779
+ if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
10780
+ return withRuleTrivia(gt, ctx, () => scalar(input, pos, ctx));
10781
+ }
10782
+ return scalar(input, pos, ctx);
10783
+ },
10541
10784
  parse(input, pos, ctx) {
10542
- if (!resolved) throw new Error("ref<T>() used before .define() was called");
10785
+ const parser2 = resolved;
10786
+ if (!parser2) throw new Error("ref<T>() used before .define() was called");
10543
10787
  const gt = meta.grammarTrivia;
10544
10788
  if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
10545
- const savedLabels = ctx.triviaKindLabels;
10546
- ctx.trivia = gt;
10547
- ctx.triviaKindLabels = gt._meta.triviaKindLabels;
10548
- try {
10549
- return resolved.parse(input, pos, ctx);
10550
- } finally {
10551
- ctx.trivia = void 0;
10552
- ctx.triviaKindLabels = savedLabels;
10553
- }
10789
+ return withRuleTrivia(gt, ctx, () => parser2.parse(input, pos, ctx));
10554
10790
  }
10555
- return resolved.parse(input, pos, ctx);
10791
+ return parser2.parse(input, pos, ctx);
10556
10792
  },
10557
10793
  define(p) {
10558
10794
  if (resolved) throw new Error("ref<T>() already defined");
10559
10795
  resolved = p;
10796
+ resolvedScalar = scalarOf(p);
10560
10797
  ownBoundary = hasOwnTriviaBoundary(p);
10561
10798
  meta.firstSet = p._meta.firstSet;
10562
10799
  meta.canMatchNewline = p._meta.canMatchNewline;
@@ -13461,10 +13698,10 @@ function assemble(t2, prog, cfg) {
13461
13698
  const hasFold = spec.byFold.size > 0;
13462
13699
  const match = spec.match;
13463
13700
  const matchN = match.length;
13464
- const routed2 = spec.routed;
13701
+ const routed = spec.routed;
13465
13702
  const expected = spec.expected;
13466
13703
  const validArm = (arm) => Number.isInteger(arm) && arm >= 0 && arm < n;
13467
- if (routed2.length !== n) throw new TypeError("table assembler: malformed dispatch routed arity");
13704
+ if (routed.length !== n) throw new TypeError("table assembler: malformed dispatch routed arity");
13468
13705
  for (const arm of byKey.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch exact arm");
13469
13706
  for (const arm of byFold.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch folded arm");
13470
13707
  for (const m of match) if (!validArm(m[3])) throw new TypeError("table assembler: malformed dispatch matcher arm");
@@ -13489,7 +13726,7 @@ function assemble(t2, prog, cfg) {
13489
13726
  const classify = hasFold ? matchBlock === void 0 ? (key) => byKey.get(key) ?? byFold.get(asciiFoldKey(key)) : (key) => byKey.get(key) ?? byFold.get(asciiFoldKey(key)) ?? matchBlock(key) : matchBlock === void 0 ? (key) => byKey.get(key) : (key) => byKey.get(key) ?? matchBlock(key);
13490
13727
  const neverBranch = () => FAIL;
13491
13728
  const bindArms = (start) => {
13492
- const branch = (i) => i < n ? dispatchBranch(link(code[armBase + i]), routed2[i] === 1) : neverBranch;
13729
+ const branch = (i) => i < n ? dispatchBranch(link(code[armBase + i]), routed[i] === 1) : neverBranch;
13493
13730
  const next = start + 4 < n ? bindArms(start + 4) : void 0;
13494
13731
  return dispatchArmBlock(
13495
13732
  start,
@@ -14308,7 +14545,7 @@ function buildGrammarPlan(entry, winners) {
14308
14545
  const dispatches = /* @__PURE__ */ new Map();
14309
14546
  const attempts = /* @__PURE__ */ new Map();
14310
14547
  const labels = /* @__PURE__ */ new Map();
14311
- const rules2 = /* @__PURE__ */ new Map();
14548
+ const rules = /* @__PURE__ */ new Map();
14312
14549
  const winnerNames = /* @__PURE__ */ new Map();
14313
14550
  if (winners) {
14314
14551
  for (const [name, winner] of Object.entries(winners)) {
@@ -14329,7 +14566,7 @@ function buildGrammarPlan(entry, winners) {
14329
14566
  if (rule2 && (winnerNames.has(parser2) || parser2._def.tag !== "lazy")) {
14330
14567
  const id = `rule:${rule2}`;
14331
14568
  definitions.set(id, { id, kind: "rule" });
14332
- rules2.set(parser2, id);
14569
+ rules.set(parser2, id);
14333
14570
  }
14334
14571
  if (parser2._def.tag === "choice") {
14335
14572
  const ids = parser2._def.parsers.map((_, index) => `choice:${path}/arm:${index}`);
@@ -14353,7 +14590,7 @@ function buildGrammarPlan(entry, winners) {
14353
14590
  for (const root of roots) {
14354
14591
  visit(root, winnerNames.get(root) ?? root._ruleName ?? "entry");
14355
14592
  }
14356
- return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
14593
+ return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules };
14357
14594
  }
14358
14595
 
14359
14596
  // src/analysis/duplication.ts
@@ -17021,31 +17258,6 @@ function locatedLines(l, opts) {
17021
17258
  return out;
17022
17259
  }
17023
17260
 
17024
- // src/compiler/linker.ts
17025
- function normalizeCstCollapse(collapse) {
17026
- if (collapse === true) return () => true;
17027
- if (Array.isArray(collapse)) {
17028
- const types = new Set(collapse);
17029
- return (type) => types.has(type);
17030
- }
17031
- return typeof collapse === "function" ? collapse : void 0;
17032
- }
17033
- function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
17034
- return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children2] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
17035
- }
17036
- function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
17037
- if (typeof typeOrOptions === "string") {
17038
- return buildCstNode(typeOrOptions, children2 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
17039
- }
17040
- const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
17041
- const materializeTags = typeOrOptions?.tags === true;
17042
- const host = (type, children3, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children3 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
17043
- host._parsemanCstOutput = true;
17044
- if (collapse) host._parsemanCstCollapse = collapse;
17045
- return host;
17046
- }
17047
- cstBuildHost._parsemanCstOutput = true;
17048
-
17049
17261
  // src/analysis/diagnose.ts
17050
17262
  function examinedNothing(d) {
17051
17263
  return d.summary.totalChoices === 0 && d.summary.unanalysable > 0;