parseman 0.58.2 → 0.58.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 (56) hide show
  1. package/dist/analysis/diagnostics.js +203 -37
  2. package/dist/analysis/diagnostics.js.map +3 -3
  3. package/dist/cli/index.js +203 -37
  4. package/dist/cli/index.js.map +3 -3
  5. package/dist/combinators/first-set.d.ts.map +1 -1
  6. package/dist/combinators/regex.d.ts.map +1 -1
  7. package/dist/compiler/token-capability.js +28 -4
  8. package/dist/compiler/token-capability.js.map +2 -2
  9. package/dist/compiler/token-scanner.d.ts.map +1 -1
  10. package/dist/index.js +207 -41
  11. package/dist/index.js.map +3 -3
  12. package/dist/language-service/index.js +10 -3
  13. package/dist/language-service/index.js.map +2 -2
  14. package/dist/lead-ranges.d.ts +26 -0
  15. package/dist/lead-ranges.d.ts.map +1 -0
  16. package/dist/plugin/index.js +207 -41
  17. package/dist/plugin/index.js.map +3 -3
  18. package/dist/recovery/scan.d.ts.map +1 -1
  19. package/dist/regex/classes.d.ts +5 -3
  20. package/dist/regex/classes.d.ts.map +1 -1
  21. package/dist/regex/first-set.d.ts +7 -1
  22. package/dist/regex/first-set.d.ts.map +1 -1
  23. package/dist/run/index.js +10 -3
  24. package/dist/run/index.js.map +2 -2
  25. package/dist/table/assemble.d.ts.map +1 -1
  26. package/dist/table/compile-rule-map.d.ts.map +1 -1
  27. package/dist/table/emit-assembly.d.ts +8 -1
  28. package/dist/table/emit-assembly.d.ts.map +1 -1
  29. package/dist/table/encode-baseline.d.ts.map +1 -1
  30. package/dist/table/index.js +206 -40
  31. package/dist/table/index.js.map +3 -3
  32. package/dist/table/program.d.ts.map +1 -1
  33. package/dist/table/scan-shapes.d.ts +1 -1
  34. package/dist/table/scan-shapes.d.ts.map +1 -1
  35. package/dist/table/site-labels.d.ts.map +1 -1
  36. package/dist/table/trivia-gap.d.ts +11 -1
  37. package/dist/table/trivia-gap.d.ts.map +1 -1
  38. package/dist/version.d.ts +1 -1
  39. package/package.json +1 -1
  40. package/src/combinators/choice.ts +4 -0
  41. package/src/combinators/first-set.ts +13 -4
  42. package/src/combinators/regex.ts +28 -9
  43. package/src/compiler/token-scanner.ts +4 -1
  44. package/src/lead-ranges.ts +53 -0
  45. package/src/recovery/scan.ts +2 -3
  46. package/src/regex/classes.ts +22 -7
  47. package/src/regex/first-set.ts +67 -12
  48. package/src/table/assemble.ts +42 -3
  49. package/src/table/compile-rule-map.ts +5 -3
  50. package/src/table/emit-assembly.ts +42 -8
  51. package/src/table/encode-baseline.ts +2 -1
  52. package/src/table/program.ts +2 -1
  53. package/src/table/scan-shapes.ts +5 -2
  54. package/src/table/site-labels.ts +2 -1
  55. package/src/table/trivia-gap.ts +19 -0
  56. package/src/version.ts +1 -1
@@ -6,6 +6,35 @@ import { parseSync as parseSync5 } from "oxc-parser";
6
6
  import { ResolverFactory } from "oxc-resolver";
7
7
  import MagicString from "magic-string";
8
8
 
9
+ // src/lead-ranges.ts
10
+ function rangesHaveLead(ranges, code) {
11
+ for (const r of ranges) if (code >= r.lo && code <= r.hi) return true;
12
+ if (code <= 65535) return false;
13
+ const high = 55296 + (code - 65536 >> 10);
14
+ for (const r of ranges) if (high >= r.lo && high <= r.hi) return true;
15
+ return false;
16
+ }
17
+ function leadRanges(ranges) {
18
+ let out;
19
+ for (const r of ranges) {
20
+ const lo = Math.max(r.lo, 55296), hi = Math.min(r.hi, 56319);
21
+ if (lo <= hi) (out ??= [...ranges]).push({ lo: 65536 + (lo - 55296 << 10), hi: 65536 + (hi - 55296 << 10) + 1023 });
22
+ }
23
+ return out ?? ranges;
24
+ }
25
+ function implicitLeadsDropped(ranges) {
26
+ const implied = leadRanges(ranges.filter((r) => r.lo <= 65535)).filter((r) => r.lo > 65535);
27
+ const out = [];
28
+ for (const r of ranges) {
29
+ let pieces = [{ lo: r.lo, hi: r.hi }];
30
+ if (r.hi > 65535) for (const c of implied) {
31
+ pieces = pieces.flatMap((q2) => q2.hi < c.lo || q2.lo > c.hi ? [q2] : [...q2.lo < c.lo ? [{ lo: q2.lo, hi: c.lo - 1 }] : [], ...q2.hi > c.hi ? [{ lo: c.hi + 1, hi: q2.hi }] : []]);
32
+ }
33
+ out.push(...pieces);
34
+ }
35
+ return out;
36
+ }
37
+
9
38
  // src/combinators/first-set.ts
10
39
  function classifyFinalChoice(arms, resolve3, activeTrivia) {
11
40
  const firstSets = [];
@@ -67,8 +96,9 @@ function union(a, b) {
67
96
  function intersects(a, b) {
68
97
  if (a.kind === "any" || b.kind === "any") return true;
69
98
  if (a.kind === "empty" || b.kind === "empty") return false;
70
- for (const ra of a.ranges) {
71
- for (const rb of b.ranges) {
99
+ const bs = leadRanges(b.ranges);
100
+ for (const ra of leadRanges(a.ranges)) {
101
+ for (const rb of bs) {
72
102
  if (ra.lo <= rb.hi && rb.lo <= ra.hi) return true;
73
103
  }
74
104
  }
@@ -84,6 +114,9 @@ function startsFirstSet(combinator, input, pos) {
84
114
  const code = input.codePointAt(pos);
85
115
  if (code === void 0) return false;
86
116
  for (const r of fs3.ranges) if (code >= r.lo && code <= r.hi) return true;
117
+ if (code <= 65535) return false;
118
+ const high = 55296 + (code - 65536 >> 10);
119
+ for (const r of fs3.ranges) if (high >= r.lo && high <= r.hi) return true;
87
120
  return false;
88
121
  }
89
122
  function fromRange(lo, hi) {
@@ -184,12 +217,13 @@ function narrowBy(acc, constraint) {
184
217
  if (acc.kind === "any") return constraint;
185
218
  if (acc.kind === "empty" || constraint.kind === "empty") return { kind: "empty" };
186
219
  const ranges = [];
187
- for (const a of acc.ranges) for (const b of constraint.ranges) {
220
+ const bs = leadRanges(constraint.ranges);
221
+ for (const a of leadRanges(acc.ranges)) for (const b of bs) {
188
222
  const lo = Math.max(a.lo, b.lo);
189
223
  const hi = Math.min(a.hi, b.hi);
190
224
  if (lo <= hi) ranges.push({ lo, hi });
191
225
  }
192
- return ranges.length === 0 ? { kind: "empty" } : { kind: "ranges", ranges };
226
+ return ranges.length === 0 ? { kind: "empty" } : { kind: "ranges", ranges: implicitLeadsDropped(ranges) };
193
227
  }
194
228
  function applyAssertion(fs3, assertion) {
195
229
  return assertion === null ? fs3 : fs3.kind === "empty" ? assertion : narrowBy(fs3, assertion);
@@ -880,11 +914,17 @@ function shorthandRanges(ch2) {
880
914
  if (ch2 === "s") return SPACE_RANGES;
881
915
  return [[48, 57], [65, 90], [97, 122], [95, 95]];
882
916
  }
883
- function readUnicodeEscape(body, i) {
917
+ function readUnicodeEscape(body, i, unicode = false) {
884
918
  if (body[i] !== "\\" || body[i + 1] !== "u") return null;
885
919
  const hex = body.slice(i + 2, i + 6);
886
920
  if (!/^[0-9a-fA-F]{4}$/.test(hex)) return null;
887
- return { cp: Number.parseInt(hex, 16), next: i + 6 };
921
+ const cp = Number.parseInt(hex, 16);
922
+ if (unicode && cp >= 55296 && cp <= 56319 && body[i + 6] === "\\" && body[i + 7] === "u") {
923
+ const lowHex = body.slice(i + 8, i + 12);
924
+ const low = /^[0-9a-fA-F]{4}$/.test(lowHex) ? Number.parseInt(lowHex, 16) : -1;
925
+ if (low >= 56320 && low <= 57343) return { cp: 65536 + (cp - 55296 << 10) + (low - 56320), next: i + 12 };
926
+ }
927
+ return { cp, next: i + 6 };
888
928
  }
889
929
  var META = new Set("()[]{}*+?|^$.".split(""));
890
930
  function literalCodePoints(frag) {
@@ -896,6 +936,7 @@ function literalCodePoints(frag) {
896
936
  const e = frag[i + 1];
897
937
  if (e === void 0) return null;
898
938
  if (!(e in CLASS_ESCAPES) && /\w/.test(e)) return null;
939
+ if (e === "0" && frag[i + 2] !== void 0 && frag[i + 2] >= "0" && frag[i + 2] <= "9") return null;
899
940
  out.push(e in CLASS_ESCAPES ? CLASS_ESCAPES[e] : e.codePointAt(0));
900
941
  i += 2;
901
942
  continue;
@@ -936,14 +977,14 @@ function parseClassOperand(body) {
936
977
  if (cps && cps.length === 1) return { ranges: [[cps[0], cps[0]]], negated: false };
937
978
  return null;
938
979
  }
939
- function parseClassRanges(body) {
980
+ function parseClassRanges(body, unicode = false) {
940
981
  const ranges = [];
941
982
  let i = 0;
942
983
  const readAtom = () => {
943
984
  const ch2 = body[i];
944
985
  if (ch2 === void 0) return null;
945
986
  if (ch2 === "\\") {
946
- const uni = readUnicodeEscape(body, i);
987
+ const uni = readUnicodeEscape(body, i, unicode);
947
988
  if (uni) {
948
989
  i = uni.next;
949
990
  return { cp: uni.cp };
@@ -951,13 +992,15 @@ function parseClassRanges(body) {
951
992
  const e = body[i + 1];
952
993
  if (e === void 0) return null;
953
994
  i += 2;
995
+ if (e === "0" && body[i] !== void 0 && body[i] >= "0" && body[i] <= "9" || e >= "1" && e <= "9") return null;
954
996
  if (e in CLASS_ESCAPES) return { cp: CLASS_ESCAPES[e] };
955
997
  if (e === "d" || e === "w" || e === "s") return { set: shorthandRanges(e) };
956
998
  if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
957
999
  return { cp: e.codePointAt(0) };
958
1000
  }
959
- i += ch2.length;
960
- return { cp: ch2.codePointAt(0) };
1001
+ const cp = unicode ? body.codePointAt(i) : body.charCodeAt(i);
1002
+ i += cp > 65535 ? 2 : 1;
1003
+ return { cp };
961
1004
  };
962
1005
  while (i < body.length) {
963
1006
  const lo = readAtom();
@@ -2083,7 +2126,7 @@ function rangesHaveNewline(ranges) {
2083
2126
  return ranges.some(([lo, hi]) => lo <= 10 && 10 <= hi);
2084
2127
  }
2085
2128
  var BAIL = /* @__PURE__ */ Symbol("regex-bail");
2086
- function parseRegex(src) {
2129
+ function parseRegex(src, unicode = false, sets = false) {
2087
2130
  let i = 0;
2088
2131
  const parseAlt = () => {
2089
2132
  const arms = [parseSeq()];
@@ -2153,9 +2196,11 @@ function parseRegex(src) {
2153
2196
  i++;
2154
2197
  return charNode(fromRange(123, 123), false);
2155
2198
  // a `{` with nothing to quantify is a literal brace
2156
- default:
2157
- i += ch2.length;
2158
- return charNode(fromRange(ch2.codePointAt(0), ch2.codePointAt(0)), ch2 === "\n");
2199
+ default: {
2200
+ const cp = unicode ? src.codePointAt(i) : src.charCodeAt(i);
2201
+ i += cp > 65535 ? 2 : 1;
2202
+ return charNode(fromRange(cp, cp), ch2 === "\n");
2203
+ }
2159
2204
  }
2160
2205
  };
2161
2206
  const parseGroup = () => {
@@ -2188,6 +2233,32 @@ function parseRegex(src) {
2188
2233
  let k = i + 1;
2189
2234
  const negated = src[k] === "^";
2190
2235
  if (negated) k++;
2236
+ if (sets) {
2237
+ let depth = 1;
2238
+ let nested = false;
2239
+ while (k < src.length && depth > 0) {
2240
+ const c = src[k];
2241
+ if (c === "\\") {
2242
+ if (src[k + 1] === "q") nested = true;
2243
+ k += 2;
2244
+ continue;
2245
+ }
2246
+ if (c === "[") {
2247
+ depth++;
2248
+ nested = true;
2249
+ } else if (c === "]") {
2250
+ depth--;
2251
+ if (depth === 0) break;
2252
+ } else if ((c === "-" || c === "&") && src[k + 1] === c) nested = true;
2253
+ k++;
2254
+ }
2255
+ if (src[k] !== "]") throw BAIL;
2256
+ if (nested) {
2257
+ i = k + 1;
2258
+ return charNode(any(), true);
2259
+ }
2260
+ k = i + 1 + (negated ? 1 : 0);
2261
+ }
2191
2262
  let body = "";
2192
2263
  while (k < src.length && src[k] !== "]") {
2193
2264
  if (src[k] === "\\") {
@@ -2200,7 +2271,7 @@ function parseRegex(src) {
2200
2271
  }
2201
2272
  if (src[k] !== "]") throw BAIL;
2202
2273
  i = k + 1;
2203
- const ranges = parseClassRanges(body);
2274
+ const ranges = parseClassRanges(body, unicode);
2204
2275
  if (negated) return charNode(any(), !ranges || !rangesHaveNewline(ranges));
2205
2276
  if (!ranges) return charNode(any(), true);
2206
2277
  return charNode(rangesToSet(ranges), rangesHaveNewline(ranges));
@@ -2208,9 +2279,20 @@ function parseRegex(src) {
2208
2279
  const parseEscape = () => {
2209
2280
  const e = src[i + 1];
2210
2281
  if (e === void 0) throw BAIL;
2211
- if (e === "u" && /^[0-9a-fA-F]{4}$/.test(src.slice(i + 2, i + 6))) {
2212
- const cp = Number.parseInt(src.slice(i + 2, i + 6), 16);
2213
- i += 6;
2282
+ const uni = readUnicodeEscape(src, i, unicode);
2283
+ if (uni !== null) {
2284
+ i = uni.next;
2285
+ return charNode(fromRange(uni.cp, uni.cp), uni.cp === 10);
2286
+ }
2287
+ if (e === "u" && src[i + 2] === "{") {
2288
+ const close = src.indexOf("}", i + 3);
2289
+ const hex = close < 0 ? "" : src.slice(i + 3, close);
2290
+ if (!unicode || !/^[0-9a-fA-F]{1,6}$/.test(hex)) {
2291
+ i += 2;
2292
+ return ANY;
2293
+ }
2294
+ const cp = Number.parseInt(hex, 16);
2295
+ i = close + 1;
2214
2296
  return charNode(fromRange(cp, cp), cp === 10);
2215
2297
  }
2216
2298
  if (e === "x" && /^[0-9a-fA-F]{2}$/.test(src.slice(i + 2, i + 4))) {
@@ -2218,6 +2300,16 @@ function parseRegex(src) {
2218
2300
  i += 4;
2219
2301
  return charNode(fromRange(cp, cp), cp === 10);
2220
2302
  }
2303
+ if (e === "c") {
2304
+ const x = src[i + 2];
2305
+ if (x !== void 0 && /^[A-Za-z]$/.test(x)) {
2306
+ const cp = x.charCodeAt(0) % 32;
2307
+ i += 3;
2308
+ return charNode(fromRange(cp, cp), cp === 10);
2309
+ }
2310
+ i += 2;
2311
+ return ANY;
2312
+ }
2221
2313
  i += 2;
2222
2314
  switch (e) {
2223
2315
  case "d":
@@ -2245,8 +2337,16 @@ function parseRegex(src) {
2245
2337
  return charNode(fromRange(12, 12), false);
2246
2338
  case "v":
2247
2339
  return charNode(fromRange(11, 11), false);
2340
+ // `\0` then a digit is a legacy octal escape (`\012` is a newline), not NUL.
2248
2341
  case "0":
2249
- return charNode(fromRange(0, 0), false);
2342
+ return src[i] !== void 0 && src[i] >= "0" && src[i] <= "9" ? ANY : charNode(fromRange(0, 0), false);
2343
+ // A property escape (`\p{…}`/`\P{…}`) matches one character of a class this
2344
+ // analyzer does not enumerate; `\k<name>` is a backreference, which may match empty.
2345
+ case "p":
2346
+ case "P":
2347
+ return charNode(any(), true);
2348
+ case "k":
2349
+ return ANY;
2250
2350
  default:
2251
2351
  if (e >= "1" && e <= "9") return ANY;
2252
2352
  return charNode(fromRange(e.codePointAt(0), e.codePointAt(0)), e === "\n");
@@ -2320,10 +2420,10 @@ function regexCanMatchEmpty(source) {
2320
2420
  return true;
2321
2421
  }
2322
2422
  }
2323
- function firstSetFromRegex(source) {
2423
+ function firstSetFromRegex(source, flags = "") {
2324
2424
  let ast2;
2325
2425
  try {
2326
- ast2 = parseRegex(source);
2426
+ ast2 = parseRegex(source, flags.includes("u") || flags.includes("v"), flags.includes("v"));
2327
2427
  } catch {
2328
2428
  return { firstSet: any(), canMatchNewline: true };
2329
2429
  }
@@ -2372,8 +2472,18 @@ function shortScanner(source, flags) {
2372
2472
  return minOne && end === pos ? null : end;
2373
2473
  };
2374
2474
  }
2475
+ function coversNonAscii(ranges) {
2476
+ let next = 128;
2477
+ for (const r of [...ranges].sort((a, b) => a.lo - b.lo)) {
2478
+ if (r.lo > next) return false;
2479
+ if (r.hi >= next) next = r.hi + 1;
2480
+ if (next > 65535) return true;
2481
+ }
2482
+ return false;
2483
+ }
2375
2484
  function asciiCaseFold(fs3) {
2376
2485
  if (fs3.kind !== "ranges") return fs3;
2486
+ if (fs3.ranges.some((r) => r.hi >= 128) && !coversNonAscii(fs3.ranges)) return any();
2377
2487
  const ranges = fs3.ranges.map((r) => ({ lo: r.lo, hi: r.hi }));
2378
2488
  const add = (lo, hi) => {
2379
2489
  if (lo <= hi) ranges.push({ lo, hi });
@@ -2398,7 +2508,7 @@ function regex(pattern, flags = "") {
2398
2508
  const resolvedFlags = typeof pattern === "string" ? flags : pattern.flags;
2399
2509
  const anchored = new RegExp(source, "y" + resolvedFlags.replace(/[gy]/g, ""));
2400
2510
  const scan = shortScanner(source, resolvedFlags);
2401
- const raw = firstSetFromRegex(source);
2511
+ const raw = firstSetFromRegex(source, resolvedFlags);
2402
2512
  const firstSet2 = !resolvedFlags.includes("i") ? raw.firstSet : resolvedFlags.includes("u") || resolvedFlags.includes("v") ? any() : asciiCaseFold(raw.firstSet);
2403
2513
  const canMatchNewline = raw.canMatchNewline;
2404
2514
  const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
@@ -3234,9 +3344,7 @@ function firstSetSentinel(fs3) {
3234
3344
  parse(input, pos) {
3235
3345
  const code = pos < input.length ? input.codePointAt(pos) : void 0;
3236
3346
  if (code !== void 0) {
3237
- for (const r of ranges) {
3238
- if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
3239
- }
3347
+ if (rangesHaveLead(ranges, code)) return { ok: true, value: null, span: { start: pos, end: pos } };
3240
3348
  }
3241
3349
  return { ok: false, expected: [], span: { start: pos, end: pos } };
3242
3350
  }
@@ -3887,6 +3995,9 @@ function inFirstSet(code, fs3) {
3887
3995
  if (fs3.kind === "any") return true;
3888
3996
  if (fs3.kind === "empty") return false;
3889
3997
  for (const r of fs3.ranges) if (code >= r.lo && code <= r.hi) return true;
3998
+ if (code <= 65535) return false;
3999
+ const high = 55296 + (code - 65536 >> 10);
4000
+ for (const r of fs3.ranges) if (high >= r.lo && high <= r.hi) return true;
3890
4001
  return false;
3891
4002
  }
3892
4003
  function areDisjoint(sets) {
@@ -6103,7 +6214,7 @@ function decodeClassSpec(spec) {
6103
6214
  function resolveClass(spec) {
6104
6215
  const ascii = new Uint8Array(128);
6105
6216
  const hi = [];
6106
- for (const { lo, hi: up } of decodeClassSpec(spec)) {
6217
+ for (const { lo, hi: up } of leadRanges(decodeClassSpec(spec))) {
6107
6218
  if (lo < 128) for (let c = lo; c <= Math.min(up, 127); c++) ascii[c] = 1;
6108
6219
  if (up >= 128) hi.push(Math.max(lo, 128), up);
6109
6220
  }
@@ -8821,6 +8932,7 @@ function parseSeqParts(source) {
8821
8932
  cp2 = uni.cp;
8822
8933
  i = uni.next;
8823
8934
  } else if (e === void 0) return null;
8935
+ else if (e >= "0" && e <= "9" && (e !== "0" || source[i + 2] !== void 0 && source[i + 2] >= "0" && source[i + 2] <= "9")) return null;
8824
8936
  else if (e in CLASS_ESCAPES) {
8825
8937
  cp2 = CLASS_ESCAPES[e];
8826
8938
  i += 2;
@@ -9370,7 +9482,7 @@ function parseScanShapeCore(source) {
9370
9482
  return null;
9371
9483
  }
9372
9484
  function scanShapeFromRegex(source, flags) {
9373
- if (/[msu]/.test(flags)) return null;
9485
+ if (/[msuv]/.test(flags)) return null;
9374
9486
  if (/i/.test(flags)) return caseFoldShape(source);
9375
9487
  return parseScanShape(source);
9376
9488
  }
@@ -9975,7 +10087,7 @@ function triviaLeadRanges(tri, trivia2) {
9975
10087
  const fs3 = trivia2[tri]?._meta.firstSet;
9976
10088
  if (fs3 === void 0) return void 0;
9977
10089
  if (fs3.kind === "empty") return [];
9978
- return fs3.kind === "ranges" && fs3.ranges !== void 0 ? fs3.ranges : void 0;
10090
+ return fs3.kind === "ranges" && fs3.ranges !== void 0 ? leadRanges(fs3.ranges) : void 0;
9979
10091
  }
9980
10092
 
9981
10093
  // src/table/scalar-terminal.ts
@@ -10505,7 +10617,7 @@ if(ctx._errors!==undefined&&ctx._errors.length!==${t}er)ctx._errors.length=${t}e
10505
10617
  if (!s.fd && !s.er) return `if(${t}n)rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,undefined,undefined,${t}lg,${t}rt)`;
10506
10618
  return `if(${t}n){rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,${s.fd ? `${t}fd` : "undefined"},${s.er ? `${t}er` : "undefined"},${t}lg,${t}rt)}`;
10507
10619
  }
10508
- function emitTerm(callee, dst, t, l, skip) {
10620
+ function emitTerm(callee, dst, t, l, skip, miss) {
10509
10621
  const fast = `const ${t}v=${callee}(input,cur,ctx)
10510
10622
  if(${t}v===FAIL)return FAIL
10511
10623
  ${dst}=${t}v
@@ -10523,7 +10635,12 @@ if(${t}v===FAIL)return FAIL
10523
10635
  ${dst}=${t}v
10524
10636
  if(EC.e>${t}s)cur=EC.e
10525
10637
  else{rollbackScannedTriviaAt(ctx,${t}tl,${t}stl,${t}lg,${t}slg,${t}rt,${t}srt)}`;
10526
- if (l.tri !== TRI_UNKNOWN) return scanned;
10638
+ if (l.tri !== TRI_UNKNOWN) return miss === void 0 ? scanned : `const ${t}c=input.charCodeAt(cur)
10639
+ if(${miss(`${t}c`)}){
10640
+ ${fast}
10641
+ }else{
10642
+ ${scanned}
10643
+ }`;
10527
10644
  return `if(ctx.trivia===undefined){
10528
10645
  ${fast}
10529
10646
  }else{
@@ -10579,7 +10696,7 @@ function rebuildPools(cc, fx, disp, plan) {
10579
10696
  })
10580
10697
  };
10581
10698
  }
10582
- function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, select) {
10699
+ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, select, scanSinkNeutral = false) {
10583
10700
  const { code, k, fx, disp, dsp, triviaLabelled } = t;
10584
10701
  const swapLegal = !cfg.trackLines;
10585
10702
  const hostCst = cfg.hostCst;
@@ -10655,7 +10772,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, se
10655
10772
  const op = code[ip];
10656
10773
  sinkBits.set(
10657
10774
  ip,
10658
- op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC2 && (op === OP_REP || op === OP_REPV) ? 2 : 0)
10775
+ op === OP_SCAN || !scanSinkNeutral && op === OP_LEX_PROGRAM && t.lexPrograms[code[ip + 1]].scan !== void 0 ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC2 && (op === OP_REP || op === OP_REPV) ? 2 : 0)
10659
10776
  );
10660
10777
  }
10661
10778
  const sinkKids = [];
@@ -10828,6 +10945,12 @@ return 1
10828
10945
  return `if(${gateMissTest(child)}){${miss}}
10829
10946
  `;
10830
10947
  }
10948
+ function triviaMiss(ki) {
10949
+ const leads = triviaLeadRanges(ki, t.trivia);
10950
+ if (leads === void 0 || leads.length > 16) return void 0;
10951
+ if (leads.length === 0) return (c) => `${c}<55296`;
10952
+ return (c) => `${c}<55296&&!(${leads.map((r) => r.lo === r.hi ? `${c}===${r.lo}` : `(${c}>=${r.lo}&&${c}<=${r.hi})`).join("||")})`;
10953
+ }
10831
10954
  function skipFor(l) {
10832
10955
  if (l.tri < 0) return "_skipTrivia";
10833
10956
  const ki = l.tri;
@@ -10838,8 +10961,13 @@ return 1
10838
10961
  const nm = `_sk${skipPool.size}`;
10839
10962
  skipPool.set(key, nm);
10840
10963
  if (!hasScan) {
10841
- skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return skipDeferredTrivia(input,cur,ctx)}` : `function ${nm}(input,cur,ctx){
10842
- if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
10964
+ const miss = triviaMiss(ki);
10965
+ const pre = miss === void 0 ? "" : `const c=input.charCodeAt(cur)
10966
+ if(${miss("c")})return cur
10967
+ `;
10968
+ skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){${pre === "" ? "" : `
10969
+ ${pre}`}return skipDeferredTrivia(input,cur,ctx)}` : `function ${nm}(input,cur,ctx){
10970
+ ${pre}if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
10843
10971
  return advanceTrivia(input,cur,ctx)}`);
10844
10972
  return nm;
10845
10973
  }
@@ -11423,7 +11551,7 @@ return v
11423
11551
  );
11424
11552
  } else {
11425
11553
  const callee = leadingTriviaFieldAt(code, k, childIp) ? `(LEAD.at=cur,${kids[i]})` : kids[i];
11426
- parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L)));
11554
+ parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L), L.tri >= 0 ? triviaMiss(L.tri) : void 0));
11427
11555
  }
11428
11556
  names.push(vn);
11429
11557
  }
@@ -12602,6 +12730,15 @@ function skipDeferredTrivia(input, cur, ctx) {
12602
12730
  if (plain) remember(cur, scan, ctx, input, triviaP);
12603
12731
  return scan;
12604
12732
  }
12733
+ function triviaLeadTable(triviaP) {
12734
+ const fs3 = triviaP._meta.firstSet;
12735
+ if (fs3.kind === "any") return null;
12736
+ const table = new Uint8Array(128);
12737
+ if (fs3.kind === "ranges") {
12738
+ for (const r of fs3.ranges) for (let c = Math.max(0, r.lo); c <= Math.min(127, r.hi); c++) table[c] = 1;
12739
+ }
12740
+ return table;
12741
+ }
12605
12742
  function clearRunEnd(input, cur, ctx, triviaP, plain) {
12606
12743
  const rootKinds = ctx._rootTriviaKindIndex;
12607
12744
  const spec = triviaP?._meta.labeledTriviaSpec;
@@ -13275,7 +13412,23 @@ function assemble(t, prog, cfg) {
13275
13412
  }
13276
13413
  return out;
13277
13414
  }
13415
+ const LEAD_TABLES = trivia2.map((tp) => tp === void 0 ? null : triviaLeadTable(tp));
13416
+ let LEAD_OF;
13417
+ let LEAD_TABLE = null;
13418
+ function cannotStartTrivia(input, cur, triviaP) {
13419
+ if (triviaP !== LEAD_OF) {
13420
+ LEAD_OF = triviaP;
13421
+ const slot = trivia2.indexOf(triviaP);
13422
+ LEAD_TABLE = slot >= 0 ? LEAD_TABLES[slot] : triviaLeadTable(triviaP);
13423
+ }
13424
+ const table = LEAD_TABLE;
13425
+ if (table === null) return false;
13426
+ const c = input.charCodeAt(cur);
13427
+ return c < 128 && table[c] === 0;
13428
+ }
13278
13429
  function skipTrivia(input, cur, ctx) {
13430
+ const t2 = ctx.trivia;
13431
+ if (t2 !== void 0 && cannotStartTrivia(input, cur, t2)) return cur;
13279
13432
  const s = SCAN;
13280
13433
  if (s !== null && ctx._triviaLog === void 0 && !(ctx.captureTrivia === true && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0))) {
13281
13434
  return s(input, cur);
@@ -13290,7 +13443,8 @@ function assemble(t, prog, cfg) {
13290
13443
  const frames = [];
13291
13444
  let depth = 0;
13292
13445
  function nextTerm(child, input, cur, ctx) {
13293
- if (ctx.trivia === void 0) {
13446
+ const t2 = ctx.trivia;
13447
+ if (t2 === void 0 || cannotStartTrivia(input, cur, t2)) {
13294
13448
  const v2 = child(input, cur, ctx);
13295
13449
  if (v2 === FAIL) return -1;
13296
13450
  TERMV = v2;
@@ -13319,7 +13473,8 @@ function assemble(t, prog, cfg) {
13319
13473
  return cur;
13320
13474
  }
13321
13475
  function nextTermBuffered(child, input, cur, ctx) {
13322
- if (ctx.trivia === void 0) {
13476
+ const t2 = ctx.trivia;
13477
+ if (t2 === void 0 || cannotStartTrivia(input, cur, t2)) {
13323
13478
  const v2 = child(input, cur, ctx);
13324
13479
  if (v2 === FAIL) return -1;
13325
13480
  TERMV = v2;
@@ -14121,6 +14276,7 @@ function assemble(t, prog, cfg) {
14121
14276
  const scopeTrivia = ki < 0 ? void 0 : trivia2[ki];
14122
14277
  const scopeLabels = scopeTrivia?._meta.triviaKindLabels;
14123
14278
  const scanFor = swapLegal && ki >= 0 && !triviaLabelled[ki] ? triviaScan[ki] : null;
14279
+ const scopeLead = ki < 0 ? null : LEAD_TABLES[ki];
14124
14280
  const child = link(code[ip + 2]);
14125
14281
  const scopePiece = code[ip] === OP_SCOPE_CAP ? (input, pos, ctx) => {
14126
14282
  const saved = ctx.trivia;
@@ -14128,6 +14284,9 @@ function assemble(t, prog, cfg) {
14128
14284
  const savedScan = SCAN;
14129
14285
  const savedCap = ctx.captureTrivia;
14130
14286
  SCAN = scanFor;
14287
+ const savedLeadOf = LEAD_OF, savedLead = LEAD_TABLE;
14288
+ LEAD_OF = scopeTrivia;
14289
+ LEAD_TABLE = scopeLead;
14131
14290
  ctx.trivia = scopeTrivia;
14132
14291
  ctx.triviaKindLabels = scopeLabels;
14133
14292
  ctx.captureTrivia = true;
@@ -14136,18 +14295,25 @@ function assemble(t, prog, cfg) {
14136
14295
  ctx.trivia = saved;
14137
14296
  ctx.triviaKindLabels = savedLabels;
14138
14297
  SCAN = savedScan;
14298
+ LEAD_OF = savedLeadOf;
14299
+ LEAD_TABLE = savedLead;
14139
14300
  return v;
14140
14301
  } : (input, pos, ctx) => {
14141
14302
  const saved = ctx.trivia;
14142
14303
  const savedLabels = ctx.triviaKindLabels;
14143
14304
  const savedScan = SCAN;
14144
14305
  SCAN = scanFor;
14306
+ const savedLeadOf = LEAD_OF, savedLead = LEAD_TABLE;
14307
+ LEAD_OF = scopeTrivia;
14308
+ LEAD_TABLE = scopeLead;
14145
14309
  ctx.trivia = scopeTrivia;
14146
14310
  ctx.triviaKindLabels = scopeLabels;
14147
14311
  const v = child(input, pos, ctx);
14148
14312
  ctx.trivia = saved;
14149
14313
  ctx.triviaKindLabels = savedLabels;
14150
14314
  SCAN = savedScan;
14315
+ LEAD_OF = savedLeadOf;
14316
+ LEAD_TABLE = savedLead;
14151
14317
  return v;
14152
14318
  };
14153
14319
  return scopeRootPolicy(scopePiece, code[ip] === OP_SCOPE_PLAIN ? 0 : code[ip + 3]);
@@ -18194,8 +18360,8 @@ function compileRuleMap(ruleMap, opts = {}) {
18194
18360
  const roots = assemblyExtraIps(artifact);
18195
18361
  let siteBytes, fixed;
18196
18362
  try {
18197
- siteBytes = emitAssemblySource(table, artifact, cfg, roots, true).siteBytes;
18198
- fixed = emitAssemblySource(table, artifact, cfg, roots, true, /* @__PURE__ */ new Set()).source.length;
18363
+ siteBytes = emitAssemblySource(table, artifact, cfg, roots, true, void 0, true).siteBytes;
18364
+ fixed = emitAssemblySource(table, artifact, cfg, roots, true, /* @__PURE__ */ new Set(), true).source.length;
18199
18365
  } catch (e) {
18200
18366
  if (e instanceof Unemittable) return { ...none, refusal: e.construct };
18201
18367
  throw e;
@@ -18211,7 +18377,7 @@ function compileRuleMap(ruleMap, opts = {}) {
18211
18377
  refusal: `a site within its ${Math.floor(ceiling)} B selection ceiling (the prelude alone is ${fixed} B)`
18212
18378
  };
18213
18379
  }
18214
- const bytes = emitAssemblySource(table, artifact, cfg, roots, true, sites).source.length;
18380
+ const bytes = emitAssemblySource(table, artifact, cfg, roots, true, sites, true).source.length;
18215
18381
  if (bytes <= ceiling) return { sites, bytes: Math.ceil(bytes * SUPERCOMPILE_GROWTH) };
18216
18382
  target *= Math.min(ceiling / bytes, 0.99);
18217
18383
  }
@@ -18856,7 +19022,7 @@ function fieldOptionsSrc(def) {
18856
19022
  }
18857
19023
 
18858
19024
  // src/version.ts
18859
- var PARSEMAN_VERSION = "0.58.2";
19025
+ var PARSEMAN_VERSION = "0.58.3";
18860
19026
 
18861
19027
  // src/compiler/compile-linkable-table.ts
18862
19028
  function isLocal(rule) {