parseman 0.47.1 → 0.48.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 (126) hide show
  1. package/README.md +27 -21
  2. package/dist/analysis/diagnostics.js +2964 -347
  3. package/dist/analysis/diagnostics.js.map +3 -3
  4. package/dist/cli/index.js +2960 -343
  5. package/dist/cli/index.js.map +3 -3
  6. package/dist/combinators/choice.d.ts.map +1 -1
  7. package/dist/combinators/expect.d.ts +1 -0
  8. package/dist/combinators/expect.d.ts.map +1 -1
  9. package/dist/combinators/expected.d.ts +8 -0
  10. package/dist/combinators/expected.d.ts.map +1 -0
  11. package/dist/combinators/first-set.d.ts +8 -0
  12. package/dist/combinators/first-set.d.ts.map +1 -1
  13. package/dist/combinators/grammar.d.ts.map +1 -1
  14. package/dist/combinators/keywords.d.ts +4 -0
  15. package/dist/combinators/keywords.d.ts.map +1 -1
  16. package/dist/combinators/literal.d.ts.map +1 -1
  17. package/dist/combinators/not.d.ts.map +1 -1
  18. package/dist/combinators/peek.d.ts.map +1 -1
  19. package/dist/combinators/regex.d.ts.map +1 -1
  20. package/dist/combinators/repeat.d.ts.map +1 -1
  21. package/dist/combinators/sequence.d.ts.map +1 -1
  22. package/dist/combinators/trivia-skip.d.ts +16 -3
  23. package/dist/combinators/trivia-skip.d.ts.map +1 -1
  24. package/dist/compiler/direct-projection.d.ts +12 -0
  25. package/dist/compiler/direct-projection.d.ts.map +1 -0
  26. package/dist/compiler/token-alphabet.d.ts +845 -5
  27. package/dist/compiler/token-alphabet.d.ts.map +1 -1
  28. package/dist/compiler/token-capability.d.ts +3 -0
  29. package/dist/compiler/token-capability.d.ts.map +1 -0
  30. package/dist/compiler/token-capability.js +3192 -0
  31. package/dist/compiler/token-capability.js.map +6 -0
  32. package/dist/cst/trivia-charscan.d.ts +3 -0
  33. package/dist/cst/trivia-charscan.d.ts.map +1 -1
  34. package/dist/cst/trivia-css-scanner.d.ts +5 -0
  35. package/dist/cst/trivia-css-scanner.d.ts.map +1 -0
  36. package/dist/cst/trivia-kinds.d.ts.map +1 -1
  37. package/dist/index.js +2973 -343
  38. package/dist/index.js.map +3 -3
  39. package/dist/language-service/index.js +5 -1
  40. package/dist/language-service/index.js.map +1 -1
  41. package/dist/plugin/index.js +2982 -352
  42. package/dist/plugin/index.js.map +3 -3
  43. package/dist/spec/index.js +325 -47
  44. package/dist/spec/index.js.map +3 -3
  45. package/dist/table/assemble.d.ts.map +1 -1
  46. package/dist/table/child-slots.d.ts.map +1 -1
  47. package/dist/table/compile-rule-map.d.ts +3 -1
  48. package/dist/table/compile-rule-map.d.ts.map +1 -1
  49. package/dist/table/emit-assembly.d.ts +12 -13
  50. package/dist/table/emit-assembly.d.ts.map +1 -1
  51. package/dist/table/emit.d.ts.map +1 -1
  52. package/dist/table/encode.d.ts.map +1 -1
  53. package/dist/table/exec-baseline.d.ts.map +1 -1
  54. package/dist/table/exec.d.ts.map +1 -1
  55. package/dist/table/index.js +2937 -311
  56. package/dist/table/index.js.map +3 -3
  57. package/dist/table/lex-body.d.ts +9 -0
  58. package/dist/table/lex-body.d.ts.map +1 -0
  59. package/dist/table/lex-program.d.ts +25 -0
  60. package/dist/table/lex-program.d.ts.map +1 -0
  61. package/dist/table/ops.d.ts +47 -11
  62. package/dist/table/ops.d.ts.map +1 -1
  63. package/dist/table/program.d.ts +50 -2
  64. package/dist/table/program.d.ts.map +1 -1
  65. package/dist/table/scalar-terminal.d.ts +13 -0
  66. package/dist/table/scalar-terminal.d.ts.map +1 -0
  67. package/dist/table/site-labels.d.ts.map +1 -1
  68. package/dist/types.d.ts +2 -0
  69. package/dist/types.d.ts.map +1 -1
  70. package/dist/version.d.ts +1 -1
  71. package/package.json +11 -11
  72. package/src/combinators/choice.ts +10 -1
  73. package/src/combinators/expect.ts +1 -0
  74. package/src/combinators/expected.ts +17 -0
  75. package/src/combinators/first-set.ts +58 -5
  76. package/src/combinators/grammar.ts +8 -3
  77. package/src/combinators/keywords.ts +22 -6
  78. package/src/combinators/literal.ts +2 -1
  79. package/src/combinators/not.ts +5 -1
  80. package/src/combinators/peek.ts +5 -1
  81. package/src/combinators/regex.ts +5 -3
  82. package/src/combinators/repeat.ts +4 -10
  83. package/src/combinators/sequence.ts +17 -14
  84. package/src/combinators/trivia-skip.ts +46 -13
  85. package/src/compiler/direct-projection.ts +43 -0
  86. package/src/compiler/token-alphabet.ts +4316 -12
  87. package/src/compiler/token-capability.ts +6 -0
  88. package/src/cst/trivia-charscan.ts +34 -0
  89. package/src/cst/trivia-css-scanner.ts +142 -0
  90. package/src/cst/trivia-kinds.ts +3 -1
  91. package/src/plugin/index.ts +4 -4
  92. package/src/table/assemble.ts +1253 -240
  93. package/src/table/child-slots.ts +2 -1
  94. package/src/table/compile-rule-map.ts +21 -3
  95. package/src/table/emit-assembly.ts +335 -87
  96. package/src/table/emit.ts +16 -2
  97. package/src/table/encode.ts +248 -60
  98. package/src/table/exec-baseline.ts +3 -7
  99. package/src/table/exec.ts +134 -25
  100. package/src/table/lex-body.ts +30 -0
  101. package/src/table/lex-program.ts +431 -0
  102. package/src/table/ops.ts +49 -11
  103. package/src/table/program.ts +46 -2
  104. package/src/table/scalar-terminal.ts +51 -0
  105. package/src/table/site-labels.ts +11 -1
  106. package/src/table/stamp.ts +1 -1
  107. package/src/types.ts +1 -1
  108. package/src/version.ts +1 -1
  109. package/dist/analysis/diagnostics.cjs +0 -13824
  110. package/dist/analysis/diagnostics.cjs.map +0 -6
  111. package/dist/cli/index.cjs +0 -14925
  112. package/dist/cli/index.cjs.map +0 -6
  113. package/dist/index.cjs +0 -16391
  114. package/dist/index.cjs.map +0 -6
  115. package/dist/language-service/index.cjs +0 -1304
  116. package/dist/language-service/index.cjs.map +0 -6
  117. package/dist/oracle/index.cjs +0 -254
  118. package/dist/oracle/index.cjs.map +0 -6
  119. package/dist/plugin/index.cjs +0 -16097
  120. package/dist/plugin/index.cjs.map +0 -6
  121. package/dist/run/index.cjs +0 -577
  122. package/dist/run/index.cjs.map +0 -6
  123. package/dist/spec/index.cjs +0 -6236
  124. package/dist/spec/index.cjs.map +0 -6
  125. package/dist/table/index.cjs +0 -11463
  126. package/dist/table/index.cjs.map +0 -6
package/dist/index.js CHANGED
@@ -1,4 +1,40 @@
1
1
  // src/combinators/first-set.ts
2
+ function classifyFinalChoice(arms, resolve) {
3
+ const firstSets = [];
4
+ const nullable2 = [];
5
+ let exclusive = true;
6
+ for (const arm of arms) {
7
+ const empty2 = matchesEmpty(arm, /* @__PURE__ */ new Set(), resolve);
8
+ nullable2.push(empty2);
9
+ firstSets.push(empty2 ? { kind: "any" } : firstSetOf(arm, /* @__PURE__ */ new Set(), resolve));
10
+ if (empty2) exclusive = false;
11
+ }
12
+ if (exclusive) {
13
+ const ascii = new Uint8Array(128);
14
+ let highOwners = 0;
15
+ for (let arm = 0; arm < firstSets.length && exclusive; arm++) {
16
+ const first = firstSets[arm];
17
+ if (first.kind !== "ranges" || first.ranges.length === 0) {
18
+ exclusive = false;
19
+ break;
20
+ }
21
+ let ownsHigh = false;
22
+ for (const range of first.ranges) {
23
+ if (range.hi >= 128) ownsHigh = true;
24
+ for (let code = Math.max(0, range.lo); code <= Math.min(127, range.hi); code++) {
25
+ if (ascii[code] !== 0) {
26
+ exclusive = false;
27
+ break;
28
+ }
29
+ ascii[code] = 1;
30
+ }
31
+ if (!exclusive) break;
32
+ }
33
+ if (ownsHigh && ++highOwners > 1) exclusive = false;
34
+ }
35
+ }
36
+ return { exclusive, firstSets, nullable: nullable2 };
37
+ }
2
38
  function resolveNamedRef(p, resolve) {
3
39
  if (resolve === void 0) return void 0;
4
40
  const name = p._ruleName;
@@ -503,6 +539,21 @@ function pushTriviaLogEntry(ctx, start, end, kindIndex) {
503
539
  }
504
540
  }
505
541
 
542
+ // src/combinators/expected.ts
543
+ function directTerminalFailureExpected(def) {
544
+ switch (def.tag) {
545
+ case "literal":
546
+ return [JSON.stringify(def.value)];
547
+ case "regex":
548
+ return [`/${def.source}/`];
549
+ case "keywords":
550
+ return ["keyword"];
551
+ }
552
+ }
553
+ function assertionFailureExpected(positive, childTag) {
554
+ return [`${positive ? "peek" : "not"}(${childTag})`];
555
+ }
556
+
506
557
  // src/combinators/literal.ts
507
558
  function asciiFoldEq(a, b) {
508
559
  if (a.length !== b.length) return false;
@@ -534,7 +585,7 @@ function literal(value, opts = {}) {
534
585
  { lo: firstUpper, hi: firstUpper }
535
586
  ] } : firstSet2;
536
587
  }
537
- const expected = [JSON.stringify(value)];
588
+ const expected = directTerminalFailureExpected({ tag: "literal", value, caseInsensitive });
538
589
  const parse2 = !caseInsensitive && value.length === 1 ? (() => {
539
590
  const code = value.charCodeAt(0);
540
591
  return function parse3(input, pos, ctx) {
@@ -1012,14 +1063,15 @@ function regex(pattern, flags = "") {
1012
1063
  const firstSet2 = !resolvedFlags.includes("i") ? raw.firstSet : resolvedFlags.includes("u") || resolvedFlags.includes("v") ? any() : asciiCaseFold(raw.firstSet);
1013
1064
  const canMatchNewline = raw.canMatchNewline;
1014
1065
  const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
1066
+ const def = { tag: "regex", source, flags: resolvedFlags };
1015
1067
  return {
1016
1068
  _tag: "regex",
1017
1069
  _meta: meta,
1018
- _def: { tag: "regex", source, flags: resolvedFlags },
1070
+ _def: def,
1019
1071
  parse(input, pos, ctx) {
1020
1072
  const scanEnd = scan?.(input, pos);
1021
1073
  if (scanEnd !== void 0) {
1022
- if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
1074
+ if (scanEnd === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
1023
1075
  const value = input.slice(pos, scanEnd);
1024
1076
  const span2 = { start: pos, end: scanEnd };
1025
1077
  if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, scanEnd);
@@ -1029,7 +1081,7 @@ function regex(pattern, flags = "") {
1029
1081
  anchored.lastIndex = pos;
1030
1082
  const m = anchored.exec(input);
1031
1083
  if (m === null) {
1032
- return failAt(ctx, [`/${source}/`], pos);
1084
+ return failAt(ctx, directTerminalFailureExpected(def), pos);
1033
1085
  }
1034
1086
  const span = { start: pos, end: pos + m[0].length };
1035
1087
  if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
@@ -1088,12 +1140,14 @@ function makeWord(boundaryOrOpts = "_0-9A-Za-z", opts) {
1088
1140
  function escapeRe(s) {
1089
1141
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1090
1142
  }
1143
+ function keywordsRegExp(words, boundary, caseInsensitive) {
1144
+ const alt = words.map(escapeRe).join("|");
1145
+ const boundarySource = boundary ? `(?![${boundary}])` : "";
1146
+ return new RegExp(`(?:${alt})${boundarySource}`, caseInsensitive ? "iy" : "uy");
1147
+ }
1091
1148
  function keywords(words, opts = {}) {
1092
1149
  const sorted = [...new Set(words)].sort((a, b) => b.length - a.length);
1093
- const alt = sorted.map(escapeRe).join("|");
1094
- const boundary = opts.boundary ? `(?![${opts.boundary}])` : "";
1095
- const flags = opts.caseInsensitive ? "iy" : "uy";
1096
- const re = new RegExp(`(?:${alt})${boundary}`, flags);
1150
+ const re = keywordsRegExp(sorted, opts.boundary, opts.caseInsensitive ?? false);
1097
1151
  let firstSet2 = empty();
1098
1152
  for (const w of sorted) {
1099
1153
  if (w.length === 0) continue;
@@ -1104,15 +1158,21 @@ function keywords(words, opts = {}) {
1104
1158
  }
1105
1159
  }
1106
1160
  const meta = { firstSet: firstSet2, canMatchNewline: false, isTrivia: false };
1161
+ const def = {
1162
+ tag: "keywords",
1163
+ words: sorted,
1164
+ caseInsensitive: opts.caseInsensitive ?? false,
1165
+ boundary: opts.boundary
1166
+ };
1107
1167
  return {
1108
1168
  _tag: "keywords",
1109
1169
  _meta: meta,
1110
- _def: { tag: "keywords", words: sorted, caseInsensitive: opts.caseInsensitive ?? false, boundary: opts.boundary },
1170
+ _def: def,
1111
1171
  parse(input, pos, ctx) {
1112
1172
  re.lastIndex = pos;
1113
1173
  const m = re.exec(input);
1114
1174
  if (m === null || m.index !== pos) {
1115
- return failAt(ctx, ["keyword"], pos);
1175
+ return failAt(ctx, directTerminalFailureExpected(def), pos);
1116
1176
  }
1117
1177
  const value = m[0];
1118
1178
  const span = { start: pos, end: pos + value.length };
@@ -1167,6 +1227,179 @@ function createDetachedParseContext(trackLines, state) {
1167
1227
  return ctx;
1168
1228
  }
1169
1229
 
1230
+ // src/cst/trivia-css-scanner.ts
1231
+ var CSS_WS_SOURCE = "[ \\t\\n\\r\\f]+";
1232
+ var CSS_LINE_COMMENT_SOURCE = "\\/\\/[^\\n\\r]*";
1233
+ var CSS_BLOCK_COMMENT_SOURCE = "\\/\\*(?:[^*]|\\*(?!\\/))*\\*\\/";
1234
+ function scanWhitespace(input, cur) {
1235
+ let pos = cur;
1236
+ while (pos < input.length) {
1237
+ const c = input.charCodeAt(pos);
1238
+ if (c !== 32 && c !== 9 && c !== 10 && c !== 13 && c !== 12) break;
1239
+ pos++;
1240
+ }
1241
+ return pos;
1242
+ }
1243
+ function scanLineComment(input, cur) {
1244
+ if (input.charCodeAt(cur) !== 47 || input.charCodeAt(cur + 1) !== 47) return cur;
1245
+ let pos = cur + 2;
1246
+ while (pos < input.length) {
1247
+ const c = input.charCodeAt(pos);
1248
+ if (c === 10 || c === 13) break;
1249
+ pos++;
1250
+ }
1251
+ return pos;
1252
+ }
1253
+ function scanBlockComment(input, cur) {
1254
+ if (input.charCodeAt(cur) !== 47 || input.charCodeAt(cur + 1) !== 42) return cur;
1255
+ const close = input.indexOf("*/", cur + 2);
1256
+ return close < 0 ? cur : close + 2;
1257
+ }
1258
+ function scanWsLineBlockTrivia(input, cur) {
1259
+ let pos = cur;
1260
+ for (; ; ) {
1261
+ const ws = scanWhitespace(input, pos);
1262
+ if (ws !== pos) {
1263
+ pos = ws;
1264
+ continue;
1265
+ }
1266
+ const line = scanLineComment(input, pos);
1267
+ if (line !== pos) {
1268
+ pos = line;
1269
+ continue;
1270
+ }
1271
+ const block = scanBlockComment(input, pos);
1272
+ if (block !== pos) {
1273
+ pos = block;
1274
+ continue;
1275
+ }
1276
+ return pos;
1277
+ }
1278
+ }
1279
+ function scanWsBlockTrivia(input, cur) {
1280
+ let pos = cur;
1281
+ for (; ; ) {
1282
+ const ws = scanWhitespace(input, pos);
1283
+ if (ws !== pos) {
1284
+ pos = ws;
1285
+ continue;
1286
+ }
1287
+ const block = scanBlockComment(input, pos);
1288
+ if (block !== pos) {
1289
+ pos = block;
1290
+ continue;
1291
+ }
1292
+ return pos;
1293
+ }
1294
+ }
1295
+ function scanLineBlockTrivia(input, cur) {
1296
+ let pos = cur;
1297
+ for (; ; ) {
1298
+ const line = scanLineComment(input, pos);
1299
+ if (line !== pos) {
1300
+ pos = line;
1301
+ continue;
1302
+ }
1303
+ const block = scanBlockComment(input, pos);
1304
+ if (block !== pos) {
1305
+ pos = block;
1306
+ continue;
1307
+ }
1308
+ return pos;
1309
+ }
1310
+ }
1311
+ function scanBlockTrivia(input, cur) {
1312
+ let pos = cur;
1313
+ for (; ; ) {
1314
+ const block = scanBlockComment(input, pos);
1315
+ if (block === pos) return pos;
1316
+ pos = block;
1317
+ }
1318
+ }
1319
+ function visitWsLineBlock(input, cur, visit) {
1320
+ let pos = cur;
1321
+ for (; ; ) {
1322
+ let end = scanWhitespace(input, pos);
1323
+ if (end !== pos) {
1324
+ visit(pos, end, 0);
1325
+ pos = end;
1326
+ continue;
1327
+ }
1328
+ end = scanLineComment(input, pos);
1329
+ if (end !== pos) {
1330
+ visit(pos, end, 1);
1331
+ pos = end;
1332
+ continue;
1333
+ }
1334
+ end = scanBlockComment(input, pos);
1335
+ if (end !== pos) {
1336
+ visit(pos, end, 2);
1337
+ pos = end;
1338
+ continue;
1339
+ }
1340
+ return pos;
1341
+ }
1342
+ }
1343
+ function visitWsBlock(input, cur, visit) {
1344
+ let pos = cur;
1345
+ for (; ; ) {
1346
+ let end = scanWhitespace(input, pos);
1347
+ if (end !== pos) {
1348
+ visit(pos, end, 0);
1349
+ pos = end;
1350
+ continue;
1351
+ }
1352
+ end = scanBlockComment(input, pos);
1353
+ if (end !== pos) {
1354
+ visit(pos, end, 1);
1355
+ pos = end;
1356
+ continue;
1357
+ }
1358
+ return pos;
1359
+ }
1360
+ }
1361
+ function visitLineBlock(input, cur, visit) {
1362
+ let pos = cur;
1363
+ for (; ; ) {
1364
+ let end = scanLineComment(input, pos);
1365
+ if (end !== pos) {
1366
+ visit(pos, end, 0);
1367
+ pos = end;
1368
+ continue;
1369
+ }
1370
+ end = scanBlockComment(input, pos);
1371
+ if (end !== pos) {
1372
+ visit(pos, end, 1);
1373
+ pos = end;
1374
+ continue;
1375
+ }
1376
+ return pos;
1377
+ }
1378
+ }
1379
+ function visitBlock(input, cur, visit) {
1380
+ let pos = cur;
1381
+ for (; ; ) {
1382
+ const end = scanBlockComment(input, pos);
1383
+ if (end === pos) return pos;
1384
+ visit(pos, end, 0);
1385
+ pos = end;
1386
+ }
1387
+ }
1388
+ function commonCssTriviaScanner(sources) {
1389
+ if (sources.length === 3 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_LINE_COMMENT_SOURCE && sources[2] === CSS_BLOCK_COMMENT_SOURCE) return scanWsLineBlockTrivia;
1390
+ if (sources.length === 2 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return scanWsBlockTrivia;
1391
+ if (sources.length === 2 && sources[0] === CSS_LINE_COMMENT_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return scanLineBlockTrivia;
1392
+ if (sources.length === 1 && sources[0] === CSS_BLOCK_COMMENT_SOURCE) return scanBlockTrivia;
1393
+ return null;
1394
+ }
1395
+ function commonCssTriviaVisitor(sources) {
1396
+ if (sources.length === 3 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_LINE_COMMENT_SOURCE && sources[2] === CSS_BLOCK_COMMENT_SOURCE) return visitWsLineBlock;
1397
+ if (sources.length === 2 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return visitWsBlock;
1398
+ if (sources.length === 2 && sources[0] === CSS_LINE_COMMENT_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return visitLineBlock;
1399
+ if (sources.length === 1 && sources[0] === CSS_BLOCK_COMMENT_SOURCE) return visitBlock;
1400
+ return null;
1401
+ }
1402
+
1170
1403
  // src/cst/trivia-charscan.ts
1171
1404
  function inRanges2(cp, ranges) {
1172
1405
  for (let i = 0; i < ranges.length; i++) {
@@ -1320,6 +1553,35 @@ function classifyParser(p) {
1320
1553
  if (d.tag !== "regex" || d.flags) return null;
1321
1554
  return classifyArm(d.source);
1322
1555
  }
1556
+ function plainRegexSource(p) {
1557
+ const d = p._def;
1558
+ return d.tag === "regex" && d.flags === "" ? d.source : null;
1559
+ }
1560
+ var visitSpec0;
1561
+ var visitSpec1;
1562
+ var visitSpec2;
1563
+ var visitSpec3;
1564
+ var visitValue0;
1565
+ var visitValue1;
1566
+ var visitValue2;
1567
+ var visitValue3;
1568
+ function commonLabeledTriviaVisitor(spec) {
1569
+ if (spec === visitSpec0) return visitValue0;
1570
+ if (spec === visitSpec1) return visitValue1;
1571
+ if (spec === visitSpec2) return visitValue2;
1572
+ if (spec === visitSpec3) return visitValue3;
1573
+ const sources = spec.minRepeats <= 1 ? spec.arms.map((arm) => plainRegexSource(arm.parser)) : [];
1574
+ const visitor = commonCssTriviaVisitor(sources);
1575
+ visitSpec3 = visitSpec2;
1576
+ visitValue3 = visitValue2;
1577
+ visitSpec2 = visitSpec1;
1578
+ visitValue2 = visitValue1;
1579
+ visitSpec1 = visitSpec0;
1580
+ visitValue1 = visitValue0;
1581
+ visitSpec0 = spec;
1582
+ visitValue0 = visitor;
1583
+ return visitor;
1584
+ }
1323
1585
  var armSpec0;
1324
1586
  var armSpec1;
1325
1587
  var armSpec2;
@@ -1518,6 +1780,8 @@ function scanLabeledTriviaEnd(input, cur, spec, state) {
1518
1780
  }
1519
1781
  function visitLabeledTrivia(input, cur, spec, state, visit) {
1520
1782
  if (spec.minRepeats > 1) return void 0;
1783
+ const common = commonLabeledTriviaVisitor(spec);
1784
+ if (common !== null) return common(input, cur, visit);
1521
1785
  const chars = charArmsFor(spec);
1522
1786
  if (chars !== null) return charTriviaVisit(input, cur, chars, visit);
1523
1787
  let pos = cur;
@@ -1617,6 +1881,14 @@ function triviaKindMask(labels, keep) {
1617
1881
  // src/combinators/trivia-skip.ts
1618
1882
  var NOOP_COMMIT = () => {
1619
1883
  };
1884
+ function triviaScanEnd(scan) {
1885
+ return typeof scan === "number" ? scan : scan.end;
1886
+ }
1887
+ function commitTriviaScan(scan) {
1888
+ if (typeof scan === "number") return scan;
1889
+ scan.commit();
1890
+ return scan.end;
1891
+ }
1620
1892
  var fastTrivia0;
1621
1893
  var fastTrivia1;
1622
1894
  var fastTrivia2;
@@ -1686,7 +1958,7 @@ function rollbackLookahead(ctx, mark) {
1686
1958
  function scanWithLabels(input, cur, ctx) {
1687
1959
  const triviaP = ctx.trivia;
1688
1960
  const spec = analyzeLabeledTrivia(triviaP);
1689
- if (!spec) return { end: cur, commit: NOOP_COMMIT };
1961
+ if (!spec) return cur;
1690
1962
  const log = ctx._triviaLog;
1691
1963
  const rootLog = ctx._rootTriviaLog;
1692
1964
  const rootKinds = ctx._rootTriviaKindIndex;
@@ -1704,7 +1976,8 @@ function scanWithLabels(input, cur, ctx) {
1704
1976
  }
1705
1977
  });
1706
1978
  if (visitedEnd !== void 0) {
1707
- if (visitedEnd === cur) return { end: cur, commit: NOOP_COMMIT };
1979
+ if (visitedEnd === cur) return cur;
1980
+ if (fullRows === void 0 && rootRows === void 0 && cstRows === void 0) return visitedEnd;
1708
1981
  return {
1709
1982
  end: visitedEnd,
1710
1983
  commit: () => {
@@ -1723,7 +1996,7 @@ function scanWithLabels(input, cur, ctx) {
1723
1996
  };
1724
1997
  }
1725
1998
  const { end, chunks } = scanLabeledTriviaChunks(input, cur, spec, ctx.state);
1726
- if (end === cur) return { end: cur, commit: NOOP_COMMIT };
1999
+ if (end === cur) return cur;
1727
2000
  return {
1728
2001
  end,
1729
2002
  commit: () => recordTriviaChunks(ctx, chunks)
@@ -1764,7 +2037,7 @@ function advanceTrivia(input, cur, ctx) {
1764
2037
  const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
1765
2038
  return tr.ok && tr.span.end > cur ? tr.span.end : cur;
1766
2039
  }
1767
- function scanTrivia(input, cur, ctx) {
2040
+ function scanTriviaCompact(input, cur, ctx) {
1768
2041
  const triviaP = ctx.trivia;
1769
2042
  if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
1770
2043
  const log = ctx._triviaLog;
@@ -1805,7 +2078,7 @@ function scanTrivia(input, cur, ctx) {
1805
2078
  }
1806
2079
  if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
1807
2080
  const scan = scanWithLabels(input, cur, ctx);
1808
- if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
2081
+ if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, triviaScanEnd(scan));
1809
2082
  return scan;
1810
2083
  }
1811
2084
  if (ctx.triviaKindLabels) {
@@ -1835,6 +2108,10 @@ function scanTrivia(input, cur, ctx) {
1835
2108
  const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
1836
2109
  return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
1837
2110
  }
2111
+ function scanTrivia(input, cur, ctx) {
2112
+ const scan = scanTriviaCompact(input, cur, ctx);
2113
+ return typeof scan === "number" ? { end: scan, commit: NOOP_COMMIT } : scan;
2114
+ }
1838
2115
  function skipTriviaScanned(s, input, cur, ctx) {
1839
2116
  const end = s(input, cur);
1840
2117
  if (end !== cur) {
@@ -1847,14 +2124,12 @@ function skipTriviaScanned(s, input, cur, ctx) {
1847
2124
  }
1848
2125
  function consumeTrivia(input, cur, ctx) {
1849
2126
  if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
1850
- const scan = scanTrivia(input, cur, ctx);
1851
- scan.commit();
1852
- return scan.end;
2127
+ return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
1853
2128
  }
1854
2129
  function probeTriviaEnd(input, cur, ctx) {
1855
2130
  if (!ctx.trivia) return cur;
1856
2131
  const probeCtx = { ...ctx, trackLines: false };
1857
- if (needsDeferredTriviaCommit(probeCtx)) return scanTrivia(input, cur, probeCtx).end;
2132
+ if (needsDeferredTriviaCommit(probeCtx)) return triviaScanEnd(scanTriviaCompact(input, cur, probeCtx));
1858
2133
  return advanceTrivia(input, cur, probeCtx);
1859
2134
  }
1860
2135
  function fastTriviaScanner(trivia2) {
@@ -1882,10 +2157,16 @@ function buildFastTriviaScanner(trivia2) {
1882
2157
  const one = regexTriviaScanner(repeat);
1883
2158
  if (one) return loopScanner([one]);
1884
2159
  if (repeat._def.tag !== "choice") return null;
2160
+ const fused = commonCssTriviaScanner(repeat._def.parsers.map(triviaRegexSource));
2161
+ if (fused !== null) return fused;
1885
2162
  const arms = repeat._def.parsers.map(regexTriviaScanner);
1886
2163
  if (arms.some((s) => s === null)) return null;
1887
2164
  return loopScanner(arms);
1888
2165
  }
2166
+ function triviaRegexSource(parser2) {
2167
+ const d = parser2._def.tag === "label" ? parser2._def.parser._def : parser2._def;
2168
+ return d.tag === "regex" && d.flags === "" ? d.source : null;
2169
+ }
1889
2170
  function loopScanner(arms) {
1890
2171
  return (input, cur) => {
1891
2172
  let pos = cur;
@@ -2376,9 +2657,7 @@ function sequence(...parsers) {
2376
2657
  const mRootLog = ctx._rootTriviaLog?.length ?? 0;
2377
2658
  let scanEnd;
2378
2659
  if (needsDeferredTriviaCommit(ctx)) {
2379
- const scan = scanTrivia(input, cur, ctx);
2380
- scan.commit();
2381
- scanEnd = scan.end;
2660
+ scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
2382
2661
  } else {
2383
2662
  scanEnd = advanceTrivia(input, cur, ctx);
2384
2663
  }
@@ -2388,7 +2667,15 @@ function sequence(...parsers) {
2388
2667
  const result2 = parsers[i].parse(input, scanEnd, ctx);
2389
2668
  if (!result2.ok) return result2;
2390
2669
  if (result2.span.end > scanEnd) cur = result2.span.end;
2391
- else rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
2670
+ else rollbackScannedTriviaAt(
2671
+ ctx,
2672
+ mTlog,
2673
+ scanTlog,
2674
+ mLog,
2675
+ scanLog,
2676
+ mRootLog,
2677
+ scanRootLog
2678
+ );
2392
2679
  if (values !== void 0) values.push(result2.value);
2393
2680
  continue;
2394
2681
  }
@@ -2423,9 +2710,7 @@ function sequence(...parsers) {
2423
2710
  const mLog = ctx._triviaLog?.length ?? 0;
2424
2711
  const mRootLog = ctx._rootTriviaLog?.length ?? 0;
2425
2712
  if (needsDeferredTriviaCommit(ctx)) {
2426
- const scan = scanTrivia(input, cur, ctx);
2427
- scan.commit();
2428
- scanEnd = scan.end;
2713
+ scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
2429
2714
  } else {
2430
2715
  scanEnd = advanceTrivia(input, cur, ctx);
2431
2716
  }
@@ -2435,7 +2720,15 @@ function sequence(...parsers) {
2435
2720
  const result2 = parsers[i].parse(input, scanEnd, ctx);
2436
2721
  if (!result2.ok) return result2;
2437
2722
  if (result2.span.end > scanEnd) cur = result2.span.end;
2438
- else rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
2723
+ else rollbackScannedTriviaAt(
2724
+ ctx,
2725
+ mTlog,
2726
+ scanTlog,
2727
+ mLog,
2728
+ scanLog,
2729
+ mRootLog,
2730
+ scanRootLog
2731
+ );
2439
2732
  if (values !== void 0) values.push(result2.value);
2440
2733
  continue;
2441
2734
  }
@@ -2467,9 +2760,7 @@ function sequence(...parsers) {
2467
2760
  const mLog = ctx._triviaLog?.length ?? 0;
2468
2761
  const mRootLog = ctx._rootTriviaLog?.length ?? 0;
2469
2762
  if (needsDeferredTriviaCommit(ctx)) {
2470
- const scan = scanTrivia(input, cur, ctx);
2471
- scan.commit();
2472
- scanEnd = scan.end;
2763
+ scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
2473
2764
  } else {
2474
2765
  scanEnd = advanceTrivia(input, cur, ctx);
2475
2766
  }
@@ -2481,7 +2772,15 @@ function sequence(...parsers) {
2481
2772
  if (result2.span.end > scanEnd) {
2482
2773
  cur = result2.span.end;
2483
2774
  } else {
2484
- rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
2775
+ rollbackScannedTriviaAt(
2776
+ ctx,
2777
+ mTlog,
2778
+ scanTlog,
2779
+ mLog,
2780
+ scanLog,
2781
+ mRootLog,
2782
+ scanRootLog
2783
+ );
2485
2784
  }
2486
2785
  if (values !== void 0) values.push(result2.value);
2487
2786
  continue;
@@ -2651,6 +2950,7 @@ function choice(...args) {
2651
2950
  },
2652
2951
  parse(input, pos, ctx) {
2653
2952
  const expected = [];
2953
+ let expectedAt = pos;
2654
2954
  if (disjoint) {
2655
2955
  const code = pos < input.length ? input.codePointAt(pos) : -1;
2656
2956
  let idx = code >= 0 && code < 128 ? asciiDispatch[code] : -1;
@@ -2708,7 +3008,12 @@ function choice(...args) {
2708
3008
  const result = parsers[i].parse(input, pos, ctx);
2709
3009
  if (!result.ok) {
2710
3010
  rollbackTrivia(ctx, mark);
2711
- expected.push(...result.expected);
3011
+ const at = result.span.start;
3012
+ if (at > expectedAt) {
3013
+ expectedAt = at;
3014
+ expected.length = 0;
3015
+ }
3016
+ if (at === expectedAt) expected.push(...result.expected);
2712
3017
  if (result.committed) return { ok: false, expected, span: result.span, committed: true };
2713
3018
  continue;
2714
3019
  }
@@ -2719,6 +3024,9 @@ function choice(...args) {
2719
3024
  }
2720
3025
  return result;
2721
3026
  }
3027
+ if (expected.length === 0) {
3028
+ for (const parser2 of parsers) expected.push(...deriveExpected(parser2));
3029
+ }
2722
3030
  return { ok: false, expected, span: { start: pos, end: pos } };
2723
3031
  }
2724
3032
  };
@@ -3179,9 +3487,7 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
3179
3487
  let pos = cur;
3180
3488
  if (ctx.trivia) {
3181
3489
  if (needsDeferredTriviaCommit(ctx)) {
3182
- const scan = scanTrivia(input, cur, ctx);
3183
- scan.commit();
3184
- pos = scan.end;
3490
+ pos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
3185
3491
  } else {
3186
3492
  pos = advanceTrivia(input, cur, ctx);
3187
3493
  }
@@ -3407,9 +3713,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
3407
3713
  let sepPos = cur;
3408
3714
  if (ctx.trivia) {
3409
3715
  if (needsDeferredTriviaCommit(ctx)) {
3410
- const scan = scanTrivia(input, cur, ctx);
3411
- scan.commit();
3412
- sepPos = scan.end;
3716
+ sepPos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
3413
3717
  } else {
3414
3718
  sepPos = advanceTrivia(input, cur, ctx);
3415
3719
  }
@@ -3425,9 +3729,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
3425
3729
  let nextPos = sep.span.end;
3426
3730
  if (ctx.trivia) {
3427
3731
  if (needsDeferredTriviaCommit(ctx)) {
3428
- const scan = scanTrivia(input, sep.span.end, ctx);
3429
- scan.commit();
3430
- nextPos = scan.end;
3732
+ nextPos = commitTriviaScan(scanTriviaCompact(input, sep.span.end, ctx));
3431
3733
  } else {
3432
3734
  nextPos = advanceTrivia(input, sep.span.end, ctx);
3433
3735
  }
@@ -3687,11 +3989,12 @@ function parser(opts, root) {
3687
3989
  const scopeLabels = scopeTrivia?._meta?.triviaKindLabels;
3688
3990
  const refuseUnclassified = scopeTrivia !== void 0 && !scopeTrivia._meta?.rootTriviaClassified && !opaqueRootCapture;
3689
3991
  const forceCaptureTrivia = opts.captureTrivia === true;
3690
- const trackLinesOf = opts.trackLines === true ? TRACK_LINES_ON : opts.trackLines === false ? TRACK_LINES_OFF : TRACK_LINES_INHERIT;
3992
+ const trackLinesPolicy = opts.trackLines === true ? "on" : opts.trackLines === false ? "off" : "inherit";
3993
+ const trackLinesOf = trackLinesPolicy === "on" ? TRACK_LINES_ON : trackLinesPolicy === "off" ? TRACK_LINES_OFF : TRACK_LINES_INHERIT;
3691
3994
  const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
3692
3995
  const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
3693
3996
  const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
3694
- return {
3997
+ const grammar = {
3695
3998
  _tag: "grammar",
3696
3999
  _meta: {
3697
4000
  ...root._meta,
@@ -3710,7 +4013,9 @@ function parser(opts, root) {
3710
4013
  clearTrivia,
3711
4014
  ...opaqueRootCapture ? { rootCapture: "opaque" } : {},
3712
4015
  ...opts.captureTrivia ? { captureTrivia: true } : {},
3713
- trackLines: opts.trackLines ?? false
4016
+ trackLines: opts.trackLines ?? false,
4017
+ constructionTrackLines: trackLinesPolicy,
4018
+ ...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
3714
4019
  },
3715
4020
  parse(input, pos, _ctx) {
3716
4021
  if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
@@ -3739,6 +4044,7 @@ function parser(opts, root) {
3739
4044
  return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
3740
4045
  }
3741
4046
  };
4047
+ return grammar;
3742
4048
  }
3743
4049
  function noTrivia(root) {
3744
4050
  return parser({ trivia: null }, root);
@@ -3998,7 +4304,11 @@ function not(combinator) {
3998
4304
  const result = combinator.parse(input, pos, ctx);
3999
4305
  rollbackLookahead(ctx, mark);
4000
4306
  if (result.ok) {
4001
- return { ok: false, expected: [`not(${combinator._tag})`], span: { start: pos, end: pos } };
4307
+ return {
4308
+ ok: false,
4309
+ expected: assertionFailureExpected(false, combinator._tag),
4310
+ span: { start: pos, end: pos }
4311
+ };
4002
4312
  }
4003
4313
  return { ok: true, value: null, span: { start: pos, end: pos } };
4004
4314
  }
@@ -4022,7 +4332,11 @@ function peek(combinator) {
4022
4332
  const result = combinator.parse(input, pos, ctx);
4023
4333
  rollbackLookahead(ctx, mark);
4024
4334
  if (result.ok) return { ok: true, value: null, span: { start: pos, end: pos } };
4025
- return { ok: false, expected: [`peek(${combinator._tag})`], span: { start: pos, end: pos } };
4335
+ return {
4336
+ ok: false,
4337
+ expected: assertionFailureExpected(true, combinator._tag),
4338
+ span: { start: pos, end: pos }
4339
+ };
4026
4340
  }
4027
4341
  };
4028
4342
  }
@@ -4272,6 +4586,12 @@ function confirmedArityForDef(def) {
4272
4586
  });
4273
4587
  return null;
4274
4588
  }
4589
+ function buildReadsRaw(def) {
4590
+ if (!def.build) return true;
4591
+ const arity = confirmedArityForDef(def);
4592
+ if (arity === null) return true;
4593
+ return arity >= 4;
4594
+ }
4275
4595
  function buildReadsTrivia(def) {
4276
4596
  if (!def.build) return true;
4277
4597
  const arity = confirmedArityForDef(def);
@@ -5104,6 +5424,8 @@ var OP_ATTEMPT = 38;
5104
5424
  var OP_LABEL = 39;
5105
5425
  var OP_COV = 40;
5106
5426
  var OP_SCOPE_PLAIN = 41;
5427
+ var OP_LEX_BODY = 42;
5428
+ var OP_LEX_PROGRAM = 43;
5107
5429
  var OP_DISPATCH = 25;
5108
5430
  var OP_ROUTED = 26;
5109
5431
  var OP_NAMES = {
@@ -5147,9 +5469,409 @@ var OP_NAMES = {
5147
5469
  [OP_ATTEMPT]: "ATTEMPT",
5148
5470
  [OP_LABEL]: "LABEL",
5149
5471
  [OP_COV]: "COV",
5150
- [OP_SCOPE_PLAIN]: "SCOPE_PLAIN"
5472
+ [OP_SCOPE_PLAIN]: "SCOPE_PLAIN",
5473
+ [OP_LEX_BODY]: "LEX_BODY",
5474
+ [OP_LEX_PROGRAM]: "LEX_PROGRAM"
5151
5475
  };
5152
5476
 
5477
+ // src/table/lex-program.ts
5478
+ var LEX_NODE_TERMINAL = 0;
5479
+ var LEX_NODE_SEQUENCE2 = 1;
5480
+ var LEX_NODE_SEQUENCE3 = 2;
5481
+ var LEX_NODE_SEQUENCE4 = 3;
5482
+ var LEX_NODE_SEQUENCE5 = 4;
5483
+ var LEX_NODE_CHOICE2 = 5;
5484
+ var LEX_NODE_CHOICE4 = 6;
5485
+ var LEX_NODE_CHOICE8 = 7;
5486
+ var LEX_NODE_NOT = 8;
5487
+ var LEX_NODE_OPTIONAL = 9;
5488
+ function lexProgramDigest(words) {
5489
+ let hash = 2166136261;
5490
+ for (const word2 of words) {
5491
+ hash ^= word2 | 0;
5492
+ hash = Math.imul(hash, 16777619);
5493
+ }
5494
+ return hash | 0;
5495
+ }
5496
+ function classHas(cls, code) {
5497
+ if (code < 0) return false;
5498
+ if (code < 128) return cls.ascii[code] === 1;
5499
+ for (let i = 0; i < cls.hi.length; i += 2) {
5500
+ if (code >= cls.hi[i] && code <= cls.hi[i + 1]) return true;
5501
+ }
5502
+ return false;
5503
+ }
5504
+ var committed = (ctx) => ctx._fc === true;
5505
+ function trackLexLines(ctx, input, end) {
5506
+ let at = ctx._lineScannedTo ?? 0;
5507
+ const starts = ctx._lineStarts;
5508
+ if (starts === void 0 || end <= at) return;
5509
+ while (at < end) {
5510
+ if (input.charCodeAt(at) === 10) starts.push(at + 1);
5511
+ at++;
5512
+ }
5513
+ ctx._lineScannedTo = end;
5514
+ }
5515
+ function terminalNode(matcher, failure, tracksLines) {
5516
+ const match = (input, pos) => {
5517
+ const result = matcher(input, pos);
5518
+ return result < 0 ? -1 : result / 2;
5519
+ };
5520
+ return {
5521
+ match,
5522
+ run: (input, pos, ctx) => {
5523
+ const end = match(input, pos);
5524
+ if (end < 0) {
5525
+ ctx._fe = pos;
5526
+ ctx._fx = failure;
5527
+ if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
5528
+ return -1;
5529
+ }
5530
+ if (tracksLines) trackLexLines(ctx, input, end);
5531
+ return end;
5532
+ }
5533
+ };
5534
+ }
5535
+ function sequence2(a, b) {
5536
+ return {
5537
+ match: (input, pos) => {
5538
+ const e0 = a.match(input, pos);
5539
+ return e0 < 0 ? -1 : b.match(input, e0);
5540
+ },
5541
+ run: (input, pos, ctx) => {
5542
+ const e0 = a.run(input, pos, ctx);
5543
+ if (e0 < 0) return -1;
5544
+ ctx._fc = false;
5545
+ return b.run(input, e0, ctx);
5546
+ }
5547
+ };
5548
+ }
5549
+ function sequence3(a, b, c) {
5550
+ return {
5551
+ match: (input, pos) => {
5552
+ const e0 = a.match(input, pos);
5553
+ if (e0 < 0) return -1;
5554
+ const e1 = b.match(input, e0);
5555
+ return e1 < 0 ? -1 : c.match(input, e1);
5556
+ },
5557
+ run: (input, pos, ctx) => {
5558
+ const e0 = a.run(input, pos, ctx);
5559
+ if (e0 < 0) return -1;
5560
+ ctx._fc = false;
5561
+ const e1 = b.run(input, e0, ctx);
5562
+ if (e1 < 0) return -1;
5563
+ ctx._fc = false;
5564
+ return c.run(input, e1, ctx);
5565
+ }
5566
+ };
5567
+ }
5568
+ function sequence4(a, b, c, d) {
5569
+ const abc = sequence3(a, b, c);
5570
+ return {
5571
+ match: (input, pos) => {
5572
+ const end = abc.match(input, pos);
5573
+ return end < 0 ? -1 : d.match(input, end);
5574
+ },
5575
+ run: (input, pos, ctx) => {
5576
+ const end = abc.run(input, pos, ctx);
5577
+ if (end < 0) return -1;
5578
+ ctx._fc = false;
5579
+ return d.run(input, end, ctx);
5580
+ }
5581
+ };
5582
+ }
5583
+ function sequence5(a, b, c, d, e) {
5584
+ const abcd = sequence4(a, b, c, d);
5585
+ return {
5586
+ match: (input, pos) => {
5587
+ const end = abcd.match(input, pos);
5588
+ return end < 0 ? -1 : e.match(input, end);
5589
+ },
5590
+ run: (input, pos, ctx) => {
5591
+ const end = abcd.run(input, pos, ctx);
5592
+ if (end < 0) return -1;
5593
+ ctx._fc = false;
5594
+ return e.run(input, end, ctx);
5595
+ }
5596
+ };
5597
+ }
5598
+ function appendExpected(acc, values) {
5599
+ if (values === void 0 || values.length === 0) return acc;
5600
+ if (acc === void 0) return values.slice();
5601
+ acc.push(...values);
5602
+ return acc;
5603
+ }
5604
+ function choiceNode(arms, classes, armExpected, choiceExpected) {
5605
+ let matchTail = () => -1;
5606
+ for (let i = arms.length - 1; i >= 0; i--) {
5607
+ const arm = arms[i], next = matchTail;
5608
+ matchTail = (input, pos) => {
5609
+ const end = arm.match(input, pos);
5610
+ return end < 0 ? next(input, pos) : end;
5611
+ };
5612
+ }
5613
+ let tail = (_input, pos, ctx, _lead, acc) => {
5614
+ ctx._fe = pos;
5615
+ ctx._fx = acc ?? choiceExpected;
5616
+ return -1;
5617
+ };
5618
+ for (let i = arms.length - 1; i >= 0; i--) {
5619
+ const arm = arms[i], cls = classes[i], staticExpected = armExpected[i], next = tail;
5620
+ tail = (input, pos, ctx, lead2, acc, best) => {
5621
+ if (cls !== void 0 && !classHas(cls, lead2)) {
5622
+ return next(
5623
+ input,
5624
+ pos,
5625
+ ctx,
5626
+ lead2,
5627
+ best === pos ? appendExpected(acc, staticExpected) : acc,
5628
+ best
5629
+ );
5630
+ }
5631
+ ctx._fc = false;
5632
+ const end = arm.run(input, pos, ctx);
5633
+ if (end >= 0) return end;
5634
+ const at = ctx._fe ?? pos;
5635
+ if (at > best) {
5636
+ best = at;
5637
+ acc = void 0;
5638
+ }
5639
+ const nextAcc = at === best ? appendExpected(acc, ctx._fx) : acc;
5640
+ if (committed(ctx)) {
5641
+ if (nextAcc !== void 0) ctx._fx = nextAcc;
5642
+ return -1;
5643
+ }
5644
+ return next(input, pos, ctx, lead2, nextAcc, best);
5645
+ };
5646
+ }
5647
+ return {
5648
+ match: matchTail,
5649
+ run: (input, pos, ctx) => tail(
5650
+ input,
5651
+ pos,
5652
+ ctx,
5653
+ pos < input.length ? input.codePointAt(pos) : -1,
5654
+ void 0,
5655
+ pos
5656
+ )
5657
+ };
5658
+ }
5659
+ function notNode(body, failure) {
5660
+ return {
5661
+ match: (input, pos) => body.match(input, pos) < 0 ? pos : -1,
5662
+ run: (input, pos, ctx) => {
5663
+ if (body.match(input, pos) < 0) return pos;
5664
+ ctx._fe = pos;
5665
+ ctx._fx = failure;
5666
+ return -1;
5667
+ }
5668
+ };
5669
+ }
5670
+ function optionalNode(body) {
5671
+ return {
5672
+ match: (input, pos) => {
5673
+ const end = body.match(input, pos);
5674
+ return end < 0 ? pos : end;
5675
+ },
5676
+ run: (input, pos, ctx) => {
5677
+ ctx._fc = false;
5678
+ const end = body.run(input, pos, ctx);
5679
+ return end < 0 && !committed(ctx) ? pos : end;
5680
+ }
5681
+ };
5682
+ }
5683
+ function fixedTreeRunner(words, matchers, classes, expected) {
5684
+ const stack = [];
5685
+ const pop = () => {
5686
+ const value = stack.pop();
5687
+ if (value === void 0) throw new TypeError("table lexical tree has an incomplete fixed body");
5688
+ return value;
5689
+ };
5690
+ for (let at = 0; at < words.length; ) {
5691
+ const op = words[at++];
5692
+ if (op === LEX_NODE_TERMINAL) {
5693
+ const matcher = matchers[words[at++]], failure = expected[words[at++]];
5694
+ const tracks = words[at++];
5695
+ if (matcher === void 0 || failure === void 0 || tracks !== 0 && tracks !== 1) {
5696
+ throw new TypeError("table lexical tree terminal references an invalid pool entry");
5697
+ }
5698
+ stack.push(terminalNode(matcher, failure, tracks === 1));
5699
+ continue;
5700
+ }
5701
+ if (op >= LEX_NODE_SEQUENCE2 && op <= LEX_NODE_SEQUENCE5) {
5702
+ const count = op - LEX_NODE_SEQUENCE2 + 2;
5703
+ const nodes = Array.from({ length: count }, pop).reverse();
5704
+ if (count === 2) stack.push(sequence2(nodes[0], nodes[1]));
5705
+ else if (count === 3) stack.push(sequence3(nodes[0], nodes[1], nodes[2]));
5706
+ else if (count === 4) stack.push(sequence4(nodes[0], nodes[1], nodes[2], nodes[3]));
5707
+ else stack.push(sequence5(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4]));
5708
+ continue;
5709
+ }
5710
+ if (op >= LEX_NODE_CHOICE2 && op <= LEX_NODE_CHOICE8) {
5711
+ const count = op === LEX_NODE_CHOICE2 ? 2 : op === LEX_NODE_CHOICE4 ? 4 : 8;
5712
+ const choiceFx = expected[words[at++]];
5713
+ if (choiceFx === void 0) throw new TypeError("table lexical tree choice has an invalid expected set");
5714
+ const armClasses = [];
5715
+ const armFx = [];
5716
+ for (let i = 0; i < count; i++) {
5717
+ const cls = words[at++], fx = expected[words[at++]];
5718
+ if (cls < -1 || cls >= 0 && classes[cls] === void 0 || fx === void 0) {
5719
+ throw new TypeError("table lexical tree choice references an invalid pool entry");
5720
+ }
5721
+ armClasses.push(cls < 0 ? void 0 : classes[cls]);
5722
+ armFx.push(fx);
5723
+ }
5724
+ const arms = Array.from({ length: count }, pop).reverse();
5725
+ stack.push(choiceNode(arms, armClasses, armFx, choiceFx));
5726
+ continue;
5727
+ }
5728
+ if (op === LEX_NODE_NOT) {
5729
+ const failure = expected[words[at++]];
5730
+ if (failure === void 0) throw new TypeError("table lexical tree assertion has an invalid expected set");
5731
+ stack.push(notNode(pop(), failure));
5732
+ continue;
5733
+ }
5734
+ if (op === LEX_NODE_OPTIONAL) {
5735
+ stack.push(optionalNode(pop()));
5736
+ continue;
5737
+ }
5738
+ throw new TypeError("table lexical tree has an unknown fixed body");
5739
+ }
5740
+ if (stack.length !== 1) throw new TypeError("table lexical tree does not resolve to one root body");
5741
+ return stack[0].run;
5742
+ }
5743
+ function buildLexProgramRunner(spec, matchers, classes, expected) {
5744
+ if (spec[0] !== 0 && spec[0] !== 1 && spec[0] !== 2 && spec[0] !== 3 || spec[0] === 0 && spec.length !== 13 || spec[0] === 1 && spec.length !== 12 || spec[0] === 2 && spec.length < 6 || spec[0] === 3 && spec.length !== 3) {
5745
+ throw new TypeError("table lexical program has an invalid fixed body width");
5746
+ }
5747
+ if (spec[1] !== lexProgramDigest(spec.slice(2))) {
5748
+ throw new TypeError("table lexical program semantic digest is inconsistent");
5749
+ }
5750
+ if (spec[0] === 3) {
5751
+ if (!Number.isInteger(spec[2]) || spec[2] < 0) {
5752
+ throw new TypeError("table balanced lexical program has an invalid scan reference");
5753
+ }
5754
+ const run3 = (_input, _pos, ctx, scan) => {
5755
+ if (scan === void 0) throw new TypeError("table balanced lexical program lost its scan body");
5756
+ const result = scan.parse(_input, _pos, ctx);
5757
+ if (!result.ok) {
5758
+ ctx._fe = result.span.start;
5759
+ ctx._fx = result.expected ?? [];
5760
+ return -1;
5761
+ }
5762
+ return result.span.end;
5763
+ };
5764
+ return Object.assign(run3, { scan: spec[2] });
5765
+ }
5766
+ if (spec[0] === 2) return fixedTreeRunner(spec.slice(2), matchers, classes, expected);
5767
+ if (spec[0] === 1) {
5768
+ const g00 = matchers[spec[2]], g01 = matchers[spec[3]];
5769
+ const g02 = matchers[spec[4]], g03 = matchers[spec[5]];
5770
+ const guard0Fx = expected[spec[6]];
5771
+ const g1 = matchers[spec[7]], guard1Fx = expected[spec[8]];
5772
+ const terminal = matchers[spec[9]], terminalFx = expected[spec[10]];
5773
+ const tracks2 = spec[11];
5774
+ if (g00 === void 0 || g01 === void 0 || g02 === void 0 || g03 === void 0 || guard0Fx === void 0 || g1 === void 0 || guard1Fx === void 0 || terminal === void 0 || terminalFx === void 0 || tracks2 !== 0 && tracks2 !== 1) {
5775
+ throw new TypeError("table lexical program references an invalid pool entry");
5776
+ }
5777
+ return (input, pos, ctx) => {
5778
+ ctx._fc = false;
5779
+ if (g00(input, pos) >= 0 || g01(input, pos) >= 0 || g02(input, pos) >= 0 || g03(input, pos) >= 0) {
5780
+ ctx._fe = pos;
5781
+ ctx._fx = guard0Fx;
5782
+ return -1;
5783
+ }
5784
+ ctx._fc = false;
5785
+ if (g1(input, pos) >= 0) {
5786
+ ctx._fe = pos;
5787
+ ctx._fx = guard1Fx;
5788
+ return -1;
5789
+ }
5790
+ ctx._fc = false;
5791
+ const result = terminal(input, pos);
5792
+ if (result < 0) {
5793
+ ctx._fe = pos;
5794
+ ctx._fx = terminalFx;
5795
+ if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
5796
+ return -1;
5797
+ }
5798
+ const end = result / 2;
5799
+ if (tracks2 === 1) trackLexLines(ctx, input, end);
5800
+ return end;
5801
+ };
5802
+ }
5803
+ const cls = classes[spec[2]];
5804
+ const choiceFx = expected[spec[3]];
5805
+ const m0 = matchers[spec[4]], x0 = expected[spec[5]];
5806
+ const m1 = matchers[spec[6]], x1 = expected[spec[7]];
5807
+ const m2 = matchers[spec[8]], x2 = expected[spec[9]];
5808
+ const m3 = matchers[spec[10]], x3 = expected[spec[11]];
5809
+ const tracks = spec[12];
5810
+ if (cls === void 0 || choiceFx === void 0 || m0 === void 0 || x0 === void 0 || m1 === void 0 || x1 === void 0 || m2 === void 0 || x2 === void 0 || m3 === void 0 || x3 === void 0 || tracks !== 0 && tracks !== 1) {
5811
+ throw new TypeError("table lexical program references an invalid pool entry");
5812
+ }
5813
+ return (input, pos, ctx) => {
5814
+ const lead2 = pos < input.length ? input.codePointAt(pos) : -1;
5815
+ if (!classHas(cls, lead2)) {
5816
+ ctx._fe = pos;
5817
+ ctx._fx = choiceFx.slice();
5818
+ return -1;
5819
+ }
5820
+ let acc;
5821
+ const failed = (fx) => {
5822
+ ctx._fe = pos;
5823
+ ctx._fx = fx;
5824
+ if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
5825
+ if (acc === void 0) acc = fx.slice();
5826
+ else acc.push(...fx);
5827
+ };
5828
+ ctx._fc = false;
5829
+ const success = (result2) => {
5830
+ const end = result2 / 2;
5831
+ if (tracks === 1) trackLexLines(ctx, input, end);
5832
+ return end;
5833
+ };
5834
+ let result = m0(input, pos);
5835
+ if (result >= 0) return success(result);
5836
+ failed(x0);
5837
+ ctx._fc = false;
5838
+ result = m1(input, pos);
5839
+ if (result >= 0) return success(result);
5840
+ failed(x1);
5841
+ ctx._fc = false;
5842
+ result = m2(input, pos);
5843
+ if (result >= 0) return success(result);
5844
+ failed(x2);
5845
+ ctx._fc = false;
5846
+ result = m3(input, pos);
5847
+ if (result >= 0) return success(result);
5848
+ failed(x3);
5849
+ ctx._fe = pos;
5850
+ ctx._fx = acc ?? choiceFx;
5851
+ return -1;
5852
+ };
5853
+ }
5854
+
5855
+ // src/table/lex-body.ts
5856
+ function buildLexBodyRecognizer(spec, constants) {
5857
+ const raw = constants[spec[0]];
5858
+ if (!(raw instanceof RegExp)) {
5859
+ throw new TypeError("table lexical body does not reference a RegExp constant");
5860
+ }
5861
+ if (!Number.isInteger(spec[1]) || spec[1] < -1 || spec[1] > 65535) {
5862
+ throw new TypeError("table lexical body suffix is not absent or one UTF-16 code unit");
5863
+ }
5864
+ const re = raw.sticky ? new RegExp(raw.source, raw.flags) : new RegExp(raw.source, `${raw.flags.replace(/[gy]/g, "")}y`);
5865
+ const suffix = spec[1];
5866
+ return (input, pos) => {
5867
+ re.lastIndex = pos;
5868
+ if (!re.test(input)) return -1;
5869
+ const end = re.lastIndex;
5870
+ if (suffix < 0) return end * 2;
5871
+ return input.charCodeAt(end) === suffix ? (end + 1) * 2 + 1 : end * 2;
5872
+ };
5873
+ }
5874
+
5153
5875
  // src/table/program.ts
5154
5876
  function closureArtifact(prog) {
5155
5877
  return { ...prog, asm: [] };
@@ -5193,6 +5915,8 @@ function expandCompact(p) {
5193
5915
  fns: p.f,
5194
5916
  lines: p.l ?? 0,
5195
5917
  dsp: p.p ?? [],
5918
+ ...p.lx === void 0 ? {} : { lex: p.lx },
5919
+ ...p.lp === void 0 ? {} : { lexPrograms: p.lp },
5196
5920
  ...p.lb === void 0 ? {} : { labels: p.lb },
5197
5921
  ...p.rc === void 0 ? {} : { classified: p.rc },
5198
5922
  ...p.h === void 0 ? {} : { hostMode: p.h },
@@ -5284,7 +6008,7 @@ function resolveClass(spec) {
5284
6008
  }
5285
6009
  return { ascii, hi };
5286
6010
  }
5287
- function classHas(cls, code) {
6011
+ function classHas2(cls, code) {
5288
6012
  if (code < 0) return false;
5289
6013
  if (code < 128) return cls.ascii[code] === 1;
5290
6014
  const hi = cls.hi;
@@ -5337,6 +6061,7 @@ function resolveTable(prog) {
5337
6061
  if (hit !== void 0) return hit;
5338
6062
  const cc = prog.cc.map(resolveClass);
5339
6063
  const triviaBuilt = (prog.triviaSpecs ?? []).map(buildTrivia);
6064
+ const lex = (prog.lex ?? []).map((spec) => buildLexBodyRecognizer(spec, prog.k));
5340
6065
  const built = {
5341
6066
  prog,
5342
6067
  code: Int32Array.from(prog.code),
@@ -5355,31 +6080,385 @@ function resolveTable(prog) {
5355
6080
  routed: d.routed,
5356
6081
  expected: d.expected
5357
6082
  })),
6083
+ lex,
6084
+ lexPrograms: (prog.lexPrograms ?? []).map((spec) => buildLexProgramRunner(spec, lex, cc, prog.fx)),
5358
6085
  rules: prog.rules
5359
6086
  };
5360
6087
  if (owner !== void 0) owner.resolved = built;
5361
6088
  return built;
5362
6089
  }
5363
6090
 
6091
+ // src/compiler/direct-projection.ts
6092
+ function directArrayProjection(fn, fnSrc, arity) {
6093
+ let source = fnSrc;
6094
+ if (source === void 0) {
6095
+ source = Function.prototype.toString.call(fn);
6096
+ if (source.includes("[native code]")) return null;
6097
+ }
6098
+ const match = /^\s*\(\s*\[([^\]]*)\]\s*\)\s*=>\s*([A-Za-z_$][\w$]*)\s*$/.exec(source);
6099
+ if (match === null) return null;
6100
+ const slots = match[1].split(",").map((slot) => slot.trim());
6101
+ if (slots.length > arity) return null;
6102
+ const result = match[2];
6103
+ let selected = -1;
6104
+ for (let i = 0; i < slots.length; i++) {
6105
+ const slot = slots[i];
6106
+ if (slot === "") continue;
6107
+ if (!/^[A-Za-z_$][\w$]*$/.test(slot)) return null;
6108
+ if (slot === result) {
6109
+ if (selected >= 0) return null;
6110
+ selected = i;
6111
+ }
6112
+ }
6113
+ return selected >= 0 ? selected : null;
6114
+ }
6115
+
5364
6116
  // src/table/encode.ts
5365
- function emittableConst(v) {
5366
- const scalar = (x) => x === null || typeof x === "string" || typeof x === "number" || typeof x === "boolean";
5367
- if (scalar(v) || v instanceof RegExp) return true;
5368
- if (Array.isArray(v)) return v.every(scalar);
5369
- if (typeof v === "object" && v !== null) {
5370
- const proto = Object.getPrototypeOf(v);
5371
- if (proto !== Object.prototype && proto !== null) return false;
5372
- return Object.values(v).every((x) => scalar(x) || Array.isArray(x) && x.every(scalar));
5373
- }
5374
- return false;
6117
+ import {
6118
+ assertLexicalCapabilityClosure,
6119
+ collectLexicalCapabilities,
6120
+ winnerWrapsReference as winnerWrapsReference2
6121
+ } from "./compiler/token-capability.js";
6122
+
6123
+ // src/compiler/token-alphabet.ts
6124
+ function optionalSuffixLexBody(ir) {
6125
+ if (ir.kind !== "sequence" || ir.parts.length !== 2) return void 0;
6126
+ const [base, suffix] = ir.parts;
6127
+ if (base?.kind !== "regex" || suffix?.kind !== "repeat" || suffix.min !== 0 || suffix.max !== 1 || !suffix.greedy || suffix.mode !== "possessive" || suffix.body.kind !== "literal" || suffix.body.caseInsensitive || suffix.body.value.length !== 1) return void 0;
6128
+ return {
6129
+ kind: "regex-optional-code-unit",
6130
+ source: base.source,
6131
+ flags: base.flags,
6132
+ suffix: suffix.body.value
6133
+ };
5375
6134
  }
5376
- function wrapsRef(winner, p) {
5377
- let cur = winner;
5378
- for (let n = 0; n < 16; n++) {
5379
- if (cur === p) return true;
5380
- const d = cur._def;
5381
- if (d.tag !== "grammar" && d.tag !== "trivia") return false;
5382
- cur = d.parser;
6135
+ function selectOptionalSuffixLexBody(ir) {
6136
+ const body = optionalSuffixLexBody(ir);
6137
+ const character = { strategy: "character", estimatedOps: 5 };
6138
+ if (body === void 0) return character;
6139
+ const token2 = { strategy: "token", estimatedOps: 2, body };
6140
+ return token2.estimatedOps < character.estimatedOps ? token2 : character;
6141
+ }
6142
+ function directTokenBodyParser(parser2, resolve) {
6143
+ const outer = parser2._def;
6144
+ if (outer.tag !== "token") return void 0;
6145
+ let body = outer.parser;
6146
+ const seen = /* @__PURE__ */ new Set();
6147
+ while (!seen.has(body)) {
6148
+ seen.add(body);
6149
+ const wrapper = body._def;
6150
+ if (wrapper.tag === "grammar") {
6151
+ if (wrapper.clearTrivia !== true || wrapper.triviaParser !== void 0 || wrapper.captureTrivia === true || wrapper.rootCapture === "opaque" || wrapper.constructionTrackLines !== "inherit" || wrapper.constructionCaptureTriviaKinds !== void 0) return void 0;
6152
+ body = wrapper.parser;
6153
+ continue;
6154
+ }
6155
+ if (wrapper.tag === "lazy") {
6156
+ const target = resolvedLazyTarget(body, resolve);
6157
+ if (target === void 0) return void 0;
6158
+ body = target;
6159
+ continue;
6160
+ }
6161
+ return body;
6162
+ }
6163
+ return void 0;
6164
+ }
6165
+ function directOptionalSuffixTokenBody(parser2, resolve) {
6166
+ const inner = directTokenBodyParser(parser2, resolve);
6167
+ if (inner === void 0) return void 0;
6168
+ const sequence6 = inner._def;
6169
+ if (sequence6.tag !== "sequence" || sequence6.parsers.length !== 2) return void 0;
6170
+ let baseParser = sequence6.parsers[0];
6171
+ const seenBase = /* @__PURE__ */ new Set();
6172
+ while (baseParser !== void 0 && baseParser._def.tag === "lazy" && !seenBase.has(baseParser)) {
6173
+ seenBase.add(baseParser);
6174
+ baseParser = resolvedLazyTarget(baseParser, resolve);
6175
+ }
6176
+ const base = baseParser?._def;
6177
+ const optional2 = sequence6.parsers[1]?._def;
6178
+ if (base?.tag !== "regex" || optional2?.tag !== "optional") return void 0;
6179
+ const suffix = optional2.parser._def;
6180
+ if (suffix.tag !== "literal" || suffix.caseInsensitive || suffix.value.length !== 1) return void 0;
6181
+ const selected = selectOptionalSuffixLexBody({
6182
+ kind: "sequence",
6183
+ parts: [
6184
+ { kind: "regex", source: base.source, flags: base.flags },
6185
+ {
6186
+ kind: "repeat",
6187
+ body: { kind: "literal", value: suffix.value, caseInsensitive: false },
6188
+ min: 0,
6189
+ max: 1,
6190
+ greedy: true,
6191
+ mode: "possessive"
6192
+ }
6193
+ ]
6194
+ });
6195
+ return selected.strategy === "token" ? {
6196
+ ...selected.body,
6197
+ baseCanMatchNewline: baseParser._meta.canMatchNewline,
6198
+ suffixCanMatchNewline: optional2.parser._meta.canMatchNewline,
6199
+ expected: directTerminalFailureExpected(base)
6200
+ } : void 0;
6201
+ }
6202
+ function directTerminalTokenBody(parser2, resolve) {
6203
+ const outer = parser2._def;
6204
+ if (outer.tag !== "token") return void 0;
6205
+ const body = directTokenBodyParser(parser2, resolve);
6206
+ if (body === void 0) return void 0;
6207
+ const def = body._def;
6208
+ if (def.tag === "regex") return {
6209
+ kind: "regex-terminal",
6210
+ source: def.source,
6211
+ flags: def.flags,
6212
+ canMatchNewline: body._meta.canMatchNewline,
6213
+ expected: directTerminalFailureExpected(def)
6214
+ };
6215
+ if (def.tag !== "keywords") return void 0;
6216
+ const re = keywordsRegExp(def.words, def.boundary, def.caseInsensitive);
6217
+ return {
6218
+ kind: "regex-terminal",
6219
+ source: re.source,
6220
+ flags: re.flags,
6221
+ canMatchNewline: body._meta.canMatchNewline,
6222
+ expected: directTerminalFailureExpected(def)
6223
+ };
6224
+ }
6225
+ function directTerminalParser(parser2, resolve) {
6226
+ const seen = /* @__PURE__ */ new Set();
6227
+ while (!seen.has(parser2)) {
6228
+ seen.add(parser2);
6229
+ const def = parser2._def;
6230
+ if (def.tag === "lazy") {
6231
+ const target = resolvedLazyTarget(parser2, resolve);
6232
+ if (target === void 0) return void 0;
6233
+ parser2 = target;
6234
+ continue;
6235
+ }
6236
+ if (def.tag === "token") {
6237
+ parser2 = def.parser;
6238
+ continue;
6239
+ }
6240
+ if (def.tag === "grammar") return void 0;
6241
+ return parser2;
6242
+ }
6243
+ return void 0;
6244
+ }
6245
+ function directTerminalLexBody(parser2, resolve) {
6246
+ const terminal = directTerminalParser(parser2, resolve);
6247
+ if (terminal === void 0) return void 0;
6248
+ const def = terminal._def;
6249
+ if (def.tag === "literal") {
6250
+ if (def.caseInsensitive) return void 0;
6251
+ const source = def.value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6252
+ return {
6253
+ kind: "regex-terminal",
6254
+ source,
6255
+ flags: "",
6256
+ canMatchNewline: terminal._meta.canMatchNewline,
6257
+ expected: directTerminalFailureExpected(def)
6258
+ };
6259
+ }
6260
+ if (def.tag === "regex") return {
6261
+ kind: "regex-terminal",
6262
+ source: def.source,
6263
+ flags: def.flags,
6264
+ canMatchNewline: terminal._meta.canMatchNewline,
6265
+ expected: directTerminalFailureExpected(def)
6266
+ };
6267
+ if (def.tag !== "keywords") return void 0;
6268
+ const re = keywordsRegExp(def.words, def.boundary, def.caseInsensitive);
6269
+ return {
6270
+ kind: "regex-terminal",
6271
+ source: re.source,
6272
+ flags: re.flags,
6273
+ canMatchNewline: terminal._meta.canMatchNewline,
6274
+ expected: directTerminalFailureExpected(def)
6275
+ };
6276
+ }
6277
+ function directOrdered4TokenBody(parser2, resolve) {
6278
+ const body = directTokenBodyParser(parser2, resolve);
6279
+ return body === void 0 ? void 0 : directOrdered4Body(body, resolve);
6280
+ }
6281
+ function directOrdered4Body(body, resolve) {
6282
+ if (body === void 0) return void 0;
6283
+ const choice2 = body._def;
6284
+ if (choice2.tag !== "choice" || choice2.parsers.length !== 4 || choice2.strategy.tag !== "firstMatch" || choice2.gates.some((gate2) => gate2 !== null) || choice2.autoNot.some((check) => check !== null)) return void 0;
6285
+ const arms = [];
6286
+ let common;
6287
+ for (const arm of choice2.parsers) {
6288
+ const selected = directTerminalLexBody(arm, resolve);
6289
+ if (selected === void 0) return void 0;
6290
+ if (selected.canMatchNewline) return void 0;
6291
+ const terminal = directTerminalParser(arm, resolve);
6292
+ const first = firstSetOf(terminal, /* @__PURE__ */ new Set(), resolve);
6293
+ if (first.kind !== "ranges" || first.ranges.length === 0) return void 0;
6294
+ if (common === void 0) common = first;
6295
+ else if (JSON.stringify(common) !== JSON.stringify(first)) return void 0;
6296
+ arms.push(selected);
6297
+ }
6298
+ return {
6299
+ kind: "ordered4-terminals",
6300
+ commonFirstSet: common,
6301
+ commonMissExpected: deriveExpected(body),
6302
+ expected: arms.flatMap((arm) => arm.expected),
6303
+ arms
6304
+ };
6305
+ }
6306
+ function directNot2TokenBody(parser2, resolve) {
6307
+ const body = directTokenBodyParser(parser2, resolve);
6308
+ const sequence6 = body?._def;
6309
+ if (sequence6?.tag !== "sequence" || sequence6.parsers.length !== 3) return void 0;
6310
+ const [guard0Parser, guard1Parser, terminalParser] = sequence6.parsers;
6311
+ const guard0Def = guard0Parser?._def;
6312
+ const guard1Def = guard1Parser?._def;
6313
+ if (guard0Def?.tag !== "not" || guard1Def?.tag !== "not") return void 0;
6314
+ const ordered = directTokenBodyParser(guard0Def.parser, resolve) ?? directTerminalParser(guard0Def.parser, resolve);
6315
+ const guard0Body = ordered === void 0 ? void 0 : directOrdered4Body(ordered, resolve);
6316
+ const guard1 = directTerminalLexBody(guard1Def.parser, resolve);
6317
+ const terminal = terminalParser === void 0 ? void 0 : directTerminalLexBody(terminalParser, resolve);
6318
+ if (guard0Body === void 0 || guard1 === void 0 || terminal === void 0 || guard1.canMatchNewline || terminal.canMatchNewline) return void 0;
6319
+ return {
6320
+ kind: "not2-ordered4-terminal",
6321
+ guard0Expected: assertionFailureExpected(false, guard0Def.parser._tag),
6322
+ guard1Expected: assertionFailureExpected(false, guard1Def.parser._tag),
6323
+ terminalExpected: terminal.expected,
6324
+ guard0: guard0Body.arms,
6325
+ guard1,
6326
+ terminal
6327
+ };
6328
+ }
6329
+ function directFixedLexNode(parser2, resolve, active, pureOnly = false) {
6330
+ let current = parser2;
6331
+ const wrappers = /* @__PURE__ */ new Set();
6332
+ while (!wrappers.has(current)) {
6333
+ wrappers.add(current);
6334
+ const def = current._def;
6335
+ if (def.tag === "lazy") {
6336
+ const target = resolvedLazyTarget(current, resolve);
6337
+ if (target === void 0) return void 0;
6338
+ current = target;
6339
+ continue;
6340
+ }
6341
+ if (def.tag === "token") {
6342
+ current = def.parser;
6343
+ continue;
6344
+ }
6345
+ break;
6346
+ }
6347
+ if (wrappers.has(current) && current !== parser2 && current._def.tag === "lazy") return void 0;
6348
+ if (active.has(current)) return void 0;
6349
+ active.add(current);
6350
+ try {
6351
+ const terminal = directTerminalLexBody(current, resolve);
6352
+ if (terminal !== void 0) return { kind: "terminal", terminal };
6353
+ const def = current._def;
6354
+ if (def.tag === "grammar") {
6355
+ if (!pureOnly || def.parser._def.tag !== "token" && (def.clearTrivia !== true || def.triviaParser !== void 0 || def.captureTrivia === true || def.rootCapture === "opaque")) return void 0;
6356
+ return directFixedLexNode(def.parser, resolve, active, true);
6357
+ }
6358
+ if (def.tag === "sequence") {
6359
+ if (def.parsers.length < 2 || def.parsers.length > 5) return void 0;
6360
+ const parts = def.parsers.map((part) => directFixedLexNode(part, resolve, active, pureOnly));
6361
+ if (parts.some((part) => part === void 0)) return void 0;
6362
+ return { kind: "sequence", parts };
6363
+ }
6364
+ if (def.tag === "choice") {
6365
+ if (def.parsers.length !== 2 && def.parsers.length !== 4 && def.parsers.length !== 8 || def.strategy.tag !== "firstMatch" || def.gates.some((gate2) => gate2 !== null) || def.autoNot.some((check) => check !== null)) return void 0;
6366
+ const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve, active, pureOnly));
6367
+ if (arms.some((arm) => arm === void 0)) return void 0;
6368
+ const final = classifyFinalChoice(def.parsers, resolve);
6369
+ return {
6370
+ kind: "choice",
6371
+ arms,
6372
+ firstSets: final.firstSets,
6373
+ armExpected: def.parsers.map(deriveExpected),
6374
+ expected: def.parsers.flatMap(deriveExpected)
6375
+ };
6376
+ }
6377
+ if (def.tag === "not") {
6378
+ const body = directFixedLexNode(def.parser, resolve, active, true);
6379
+ return body === void 0 ? void 0 : {
6380
+ kind: "not",
6381
+ body,
6382
+ expected: assertionFailureExpected(false, def.parser._tag)
6383
+ };
6384
+ }
6385
+ if (def.tag === "optional") {
6386
+ const body = directFixedLexNode(def.parser, resolve, active, pureOnly);
6387
+ return body === void 0 ? void 0 : { kind: "optional", body };
6388
+ }
6389
+ return void 0;
6390
+ } finally {
6391
+ active.delete(current);
6392
+ }
6393
+ }
6394
+ function directFixedTokenBody(parser2, resolve) {
6395
+ const body = directTokenBodyParser(parser2, resolve);
6396
+ if (body === void 0) return void 0;
6397
+ const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set());
6398
+ return root === void 0 ? void 0 : { kind: "fixed-tree", root };
6399
+ }
6400
+ function directBalancedTokenBody(parser2, resolve) {
6401
+ if (directTokenBodyParser(parser2, resolve) === void 0) return void 0;
6402
+ const spec = balancedSpecOf(parser2);
6403
+ return spec === void 0 ? void 0 : {
6404
+ kind: "balanced-scan",
6405
+ open: spec.open,
6406
+ close: spec.close,
6407
+ raw: spec.raw,
6408
+ strict: spec.strict,
6409
+ ownSkip: spec.ownSkip
6410
+ };
6411
+ }
6412
+ function directExecutableTokenBody(parser2, resolve) {
6413
+ return directOptionalSuffixTokenBody(parser2, resolve) ?? directTerminalTokenBody(parser2, resolve) ?? directOrdered4TokenBody(parser2, resolve) ?? directNot2TokenBody(parser2, resolve) ?? directBalancedTokenBody(parser2, resolve) ?? directFixedTokenBody(parser2, resolve);
6414
+ }
6415
+ function winnerWrapsReference(winner, reference) {
6416
+ let current = winner;
6417
+ const seen = /* @__PURE__ */ new Set();
6418
+ while (!seen.has(current)) {
6419
+ if (current === reference) return true;
6420
+ seen.add(current);
6421
+ const def = current._def;
6422
+ if (def.tag !== "grammar" && def.tag !== "trivia") return false;
6423
+ current = def.parser;
6424
+ }
6425
+ return false;
6426
+ }
6427
+ function resolvedLazyTarget(parser2, resolve) {
6428
+ const def = parser2._def;
6429
+ if (def.tag !== "lazy") return void 0;
6430
+ const name = parser2._ruleName;
6431
+ if (name !== void 0 && resolve !== void 0) {
6432
+ const winner = resolve(name);
6433
+ if (winner !== void 0 && !winnerWrapsReference(winner, parser2)) return winner;
6434
+ }
6435
+ try {
6436
+ return def.thunk();
6437
+ } catch {
6438
+ return void 0;
6439
+ }
6440
+ }
6441
+ function balancedSpecOf(parser2) {
6442
+ let current = parser2;
6443
+ let spec = current._balancedSpec;
6444
+ const seen = /* @__PURE__ */ new Set();
6445
+ while (spec === void 0 && current._def.tag === "token" && !seen.has(current)) {
6446
+ seen.add(current);
6447
+ current = current._def.parser;
6448
+ spec = current._balancedSpec;
6449
+ }
6450
+ return spec;
6451
+ }
6452
+
6453
+ // src/table/encode.ts
6454
+ function emittableConst(v) {
6455
+ const scalar = (x) => x === null || typeof x === "string" || typeof x === "number" || typeof x === "boolean";
6456
+ if (scalar(v) || v instanceof RegExp) return true;
6457
+ if (Array.isArray(v)) return v.every(scalar);
6458
+ if (typeof v === "object" && v !== null) {
6459
+ const proto = Object.getPrototypeOf(v);
6460
+ if (proto !== Object.prototype && proto !== null) return false;
6461
+ return Object.values(v).every((x) => scalar(x) || Array.isArray(x) && x.every(scalar));
5383
6462
  }
5384
6463
  return false;
5385
6464
  }
@@ -5414,6 +6493,10 @@ var Encoder = class {
5414
6493
  fx = [];
5415
6494
  disp = [];
5416
6495
  dsp = [];
6496
+ lex = [];
6497
+ lexIndex = /* @__PURE__ */ new Map();
6498
+ lexPrograms = [];
6499
+ lexProgramIndex = /* @__PURE__ */ new Map();
5417
6500
  labels = void 0;
5418
6501
  /** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
5419
6502
  activeTrivia = void 0;
@@ -5484,6 +6567,146 @@ var Encoder = class {
5484
6567
  this.triviaSpecs.push(this.triviaSpecOf(t));
5485
6568
  return idx;
5486
6569
  }
6570
+ lexicalBodySlot(p) {
6571
+ if (!this.selectLexicalBodies) return void 0;
6572
+ const body = directExecutableTokenBody(p, (name) => this.winners?.[name]);
6573
+ if (body === void 0) return void 0;
6574
+ const tokenDef = p._def;
6575
+ if (tokenDef.tag !== "token") throw new Error("parseman: selected lexical body lost token boundary");
6576
+ const matcher = (arm) => {
6577
+ const flags2 = arm.flags.includes("y") ? arm.flags : `${arm.flags.replace(/g/g, "")}y`;
6578
+ const regex3 = this.constant(new RegExp(arm.source, flags2));
6579
+ const key2 = `${regex3}:-1`;
6580
+ const prior2 = this.lexIndex.get(key2);
6581
+ if (prior2 !== void 0) return prior2;
6582
+ const id2 = this.lex.length;
6583
+ this.lexIndex.set(key2, id2);
6584
+ this.lex.push([regex3, -1]);
6585
+ return id2;
6586
+ };
6587
+ if (body.kind === "balanced-scan") {
6588
+ const scan = this.scanSlot({
6589
+ kind: 1,
6590
+ flags: (body.raw ? 1 : 0) | (body.strict ? 4 : 0),
6591
+ skip: body.ownSkip.map((combinator) => this.subtree(combinator)),
6592
+ open: body.open,
6593
+ close: body.close
6594
+ });
6595
+ const words = [scan];
6596
+ const spec = [3, lexProgramDigest(words), scan];
6597
+ const key2 = spec.join(",");
6598
+ const prior2 = this.lexProgramIndex.get(key2);
6599
+ if (prior2 !== void 0) return { kind: "program", program: prior2 };
6600
+ const id2 = this.lexPrograms.length;
6601
+ this.lexProgramIndex.set(key2, id2);
6602
+ this.lexPrograms.push(spec);
6603
+ return { kind: "program", program: id2 };
6604
+ }
6605
+ if (body.kind === "fixed-tree") {
6606
+ const words = [];
6607
+ const emitNode = (node2) => {
6608
+ switch (node2.kind) {
6609
+ case "terminal":
6610
+ words.push(
6611
+ LEX_NODE_TERMINAL,
6612
+ matcher(node2.terminal),
6613
+ this.expected(node2.terminal.expected),
6614
+ this.track ? 1 : 0
6615
+ );
6616
+ return true;
6617
+ case "sequence": {
6618
+ for (const part of node2.parts) if (!emitNode(part)) return false;
6619
+ const op = node2.parts.length === 2 ? LEX_NODE_SEQUENCE2 : node2.parts.length === 3 ? LEX_NODE_SEQUENCE3 : node2.parts.length === 4 ? LEX_NODE_SEQUENCE4 : node2.parts.length === 5 ? LEX_NODE_SEQUENCE5 : -1;
6620
+ if (op < 0) return false;
6621
+ words.push(op);
6622
+ return true;
6623
+ }
6624
+ case "choice": {
6625
+ for (const arm of node2.arms) if (!emitNode(arm)) return false;
6626
+ const op = node2.arms.length === 2 ? LEX_NODE_CHOICE2 : node2.arms.length === 4 ? LEX_NODE_CHOICE4 : node2.arms.length === 8 ? LEX_NODE_CHOICE8 : -1;
6627
+ if (op < 0) return false;
6628
+ words.push(op, this.expected(node2.expected));
6629
+ for (let i = 0; i < node2.arms.length; i++) {
6630
+ const first = node2.firstSets[i];
6631
+ words.push(first.kind === "ranges" ? this.charClass(first) : -1);
6632
+ words.push(this.expected(node2.armExpected[i]));
6633
+ }
6634
+ return true;
6635
+ }
6636
+ case "not":
6637
+ if (!emitNode(node2.body)) return false;
6638
+ words.push(LEX_NODE_NOT, this.expected(node2.expected));
6639
+ return true;
6640
+ case "optional":
6641
+ if (!emitNode(node2.body)) return false;
6642
+ words.push(LEX_NODE_OPTIONAL);
6643
+ return true;
6644
+ }
6645
+ };
6646
+ if (!emitNode(body.root)) return void 0;
6647
+ const spec = [2, lexProgramDigest(words), ...words];
6648
+ const key2 = spec.join(",");
6649
+ const prior2 = this.lexProgramIndex.get(key2);
6650
+ if (prior2 !== void 0) return { kind: "program", program: prior2 };
6651
+ const id2 = this.lexPrograms.length;
6652
+ this.lexProgramIndex.set(key2, id2);
6653
+ this.lexPrograms.push(spec);
6654
+ return { kind: "program", program: id2 };
6655
+ }
6656
+ if (body.kind === "not2-ordered4-terminal") {
6657
+ const words = [
6658
+ ...body.guard0.map(matcher),
6659
+ this.expected(body.guard0Expected),
6660
+ matcher(body.guard1),
6661
+ this.expected(body.guard1Expected),
6662
+ matcher(body.terminal),
6663
+ this.expected(body.terminalExpected),
6664
+ this.track ? 1 : 0
6665
+ ];
6666
+ const spec = [1, lexProgramDigest(words), ...words];
6667
+ const key2 = spec.join(",");
6668
+ const prior2 = this.lexProgramIndex.get(key2);
6669
+ if (prior2 !== void 0) return { kind: "program", program: prior2 };
6670
+ const id2 = this.lexPrograms.length;
6671
+ this.lexProgramIndex.set(key2, id2);
6672
+ this.lexPrograms.push(spec);
6673
+ return { kind: "program", program: id2 };
6674
+ }
6675
+ if (body.kind === "ordered4-terminals") {
6676
+ const commonClass = this.charClass(body.commonFirstSet);
6677
+ if (commonClass < 0) return void 0;
6678
+ const words = [commonClass, this.expected(body.commonMissExpected)];
6679
+ for (const arm of body.arms) {
6680
+ words.push(matcher(arm), this.expected(arm.expected));
6681
+ }
6682
+ words.push(this.track ? 1 : 0);
6683
+ const spec = [0, lexProgramDigest(words), ...words];
6684
+ const key2 = spec.join(",");
6685
+ const prior2 = this.lexProgramIndex.get(key2);
6686
+ if (prior2 !== void 0) return { kind: "program", program: prior2 };
6687
+ const id2 = this.lexPrograms.length;
6688
+ this.lexProgramIndex.set(key2, id2);
6689
+ this.lexPrograms.push(spec);
6690
+ return { kind: "program", program: id2 };
6691
+ }
6692
+ const expectedFx = this.expected(body.expected);
6693
+ const flags = body.flags.includes("y") ? body.flags : `${body.flags.replace(/g/g, "")}y`;
6694
+ const regex2 = this.constant(new RegExp(body.source, flags));
6695
+ const suffix = body.kind === "regex-terminal" ? -1 : body.suffix.charCodeAt(0);
6696
+ const key = `${regex2}:${suffix}`;
6697
+ const prior = this.lexIndex.get(key);
6698
+ const suffixFx = this.expected(body.kind === "regex-terminal" ? [] : directTerminalFailureExpected({
6699
+ tag: "literal",
6700
+ value: body.suffix,
6701
+ caseInsensitive: false
6702
+ }));
6703
+ const lineFlags = this.track ? body.kind === "regex-terminal" ? 1 : 1 | 2 | 4 : body.kind === "regex-terminal" ? 0 : 4;
6704
+ if (prior !== void 0) return { kind: "body", body: prior, expectedFx, suffixFx, lineFlags };
6705
+ const id = this.lex.length;
6706
+ this.lexIndex.set(key, id);
6707
+ this.lex.push([regex2, suffix]);
6708
+ return { kind: "body", body: id, expectedFx, suffixFx, lineFlags };
6709
+ }
5487
6710
  triviaSpecOf(t) {
5488
6711
  const unlowered = (why) => {
5489
6712
  this.runtimeOnly.add(`rules({ trivia }) \u2014 ${why}`);
@@ -5567,6 +6790,9 @@ var Encoder = class {
5567
6790
  settings;
5568
6791
  /** Resolved once, HERE, at table-build time — never consulted at run time. */
5569
6792
  track;
6793
+ /** TOKEN bodies are an all-program decision. A complete occurrence inside an
6794
+ * otherwise incomplete final graph stays on CHARACTER with every sibling. */
6795
+ selectLexicalBodies;
5570
6796
  /**
5571
6797
  * Decides the extra operands laid down below. ALWAYS TRUE — see
5572
6798
  * `TableSettings.recovery`. Kept as a field rather than folded away because it
@@ -5574,9 +6800,10 @@ var Encoder = class {
5574
6800
  * row is stated.
5575
6801
  */
5576
6802
  rec;
5577
- constructor(settings) {
6803
+ constructor(settings, selectLexicalBodies) {
5578
6804
  this.settings = settings;
5579
6805
  this.track = settings.trackLines === true;
6806
+ this.selectLexicalBodies = selectLexicalBodies;
5580
6807
  this.rec = true;
5581
6808
  this.plan = settings.coverage;
5582
6809
  this.cov = settings.coverage === void 0 ? void 0 : settings.coverage.definitions.map((d) => [d.id, covKindCode(d.kind)]);
@@ -5691,6 +6918,13 @@ var Encoder = class {
5691
6918
  this.ccIndex.set(spec, i);
5692
6919
  return i;
5693
6920
  }
6921
+ /** Bind a guard only when its class is already part of the program. Repeat
6922
+ * gating must not grow the compact artifact merely to avoid a failed call. */
6923
+ existingCharClass(fs) {
6924
+ if (fs.kind !== "ranges" || fs.ranges.length === 0) return -1;
6925
+ const hit = this.ccIndex.get(encodeClassSpec(fs.ranges));
6926
+ return hit !== void 0 && hit < 100 ? hit : -1;
6927
+ }
5694
6928
  /**
5695
6929
  * Wrap one choice arm in its `autoNot` checks (`OP_REJECT`).
5696
6930
  *
@@ -5779,7 +7013,7 @@ var Encoder = class {
5779
7013
  * in the target rule's own ambient trivia when that differs from the trivia
5780
7014
  * lexically active at the reference.
5781
7015
  *
5782
- * `encodeRule` wraps a rule ENTRY in `OP_SCOPE`, but only the entry: a `g.X`
7016
+ * `encodeRule` wraps a rule ENTRY in `OP_SCOPE_PLAIN`, but only the entry: a `g.X`
5783
7017
  * reference resolves straight to the body's offset and jumps past it (the note
5784
7018
  * at `encodeRule`). So a rule referenced from inside a `noTrivia(...)` region ran
5785
7019
  * with NO ambient trivia of its own — the table scoped trivia DYNAMICALLY, by
@@ -5856,6 +7090,19 @@ var Encoder = class {
5856
7090
  }
5857
7091
  encodeDef(p) {
5858
7092
  const d = p._def;
7093
+ if (d.tag === "token") {
7094
+ const selected = this.lexicalBodySlot(p);
7095
+ if (selected !== void 0) {
7096
+ if (selected.kind === "program") return this.emit(OP_LEX_PROGRAM, selected.program);
7097
+ return this.emit(
7098
+ OP_LEX_BODY,
7099
+ selected.body,
7100
+ selected.expectedFx,
7101
+ selected.suffixFx,
7102
+ selected.lineFlags
7103
+ );
7104
+ }
7105
+ }
5859
7106
  const bal = p._balancedSpec;
5860
7107
  if (bal !== void 0) return this.emit(OP_SCAN, this.scanSlot({
5861
7108
  kind: 1,
@@ -5877,13 +7124,13 @@ var Encoder = class {
5877
7124
  switch (d.tag) {
5878
7125
  case "literal": {
5879
7126
  if (d.caseInsensitive) {
5880
- return this.emit(this.track ? OP_LIT_CI_TRACK : OP_LIT_CI, this.constant(d.value), this.expected(deriveExpected(p)));
7127
+ return this.emit(this.track ? OP_LIT_CI_TRACK : OP_LIT_CI, this.constant(d.value), this.expected(directTerminalFailureExpected(d)));
5881
7128
  }
5882
- return this.emit(this.track ? OP_LIT_TRACK : OP_LIT, this.constant(d.value), this.expected(deriveExpected(p)));
7129
+ return this.emit(this.track ? OP_LIT_TRACK : OP_LIT, this.constant(d.value), this.expected(directTerminalFailureExpected(d)));
5883
7130
  }
5884
7131
  case "regex": {
5885
7132
  const flags = d.flags.includes("y") ? d.flags : `${d.flags}y`;
5886
- return this.emit(this.track ? OP_RX_TRACK : OP_RX, this.constant(new RegExp(d.source, flags)), this.expected(deriveExpected(p)));
7133
+ return this.emit(this.track ? OP_RX_TRACK : OP_RX, this.constant(new RegExp(d.source, flags)), this.expected(directTerminalFailureExpected(d)));
5887
7134
  }
5888
7135
  case "keywords": {
5889
7136
  const alt = d.words.map((w) => w.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
@@ -5897,7 +7144,7 @@ var Encoder = class {
5897
7144
  // failing keyword arm names the CATEGORY rather than reciting every
5898
7145
  // literal in the family. `deriveExpected` reports the literals, so the
5899
7146
  // table said `'"media"'` where both other engines say `'keyword'`.
5900
- this.expected(["keyword"])
7147
+ this.expected(directTerminalFailureExpected(d))
5901
7148
  );
5902
7149
  }
5903
7150
  case "expect": {
@@ -5944,7 +7191,8 @@ var Encoder = class {
5944
7191
  return this.covWrap(gated, armCovIds?.[src], 1);
5945
7192
  });
5946
7193
  const rr = this.refResolver();
5947
- const classes = arms.map((a) => matchesEmpty(a, /* @__PURE__ */ new Set(), rr) ? -1 : this.charClass(firstSetOf(a, /* @__PURE__ */ new Set(), rr)));
7194
+ const finalChoice = classifyFinalChoice(arms, rr);
7195
+ const classes = arms.map((_, i) => finalChoice.nullable[i] ? -1 : this.charClass(finalChoice.firstSets[i]));
5948
7196
  const dispIdx = this.disp.length;
5949
7197
  this.disp.push(classes);
5950
7198
  const head = this.emitHead(OP_CHOICE, 3 + 2 * kids.length);
@@ -5960,9 +7208,11 @@ var Encoder = class {
5960
7208
  case "many":
5961
7209
  case "oneOrMore": {
5962
7210
  const child = this.node(d.parser).ip;
7211
+ const rr = this.refResolver();
7212
+ const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.existingCharClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr));
5963
7213
  const op = d.valueUnused ? OP_REPV : OP_REP;
5964
7214
  const min = d.tag === "many" ? 0 : d.min;
5965
- return this.rec ? this.emit(op, child, min, d.max ?? -1, -1, 0, this.expected(deriveExpected(d.parser)), -1) : this.emit(op, child, min, d.max ?? -1, -1, 0);
7215
+ return this.rec ? this.emit(op, child, min, d.max ?? -1, -1, 0, this.expected(deriveExpected(d.parser)), itemClass) : this.emit(op, child, min, d.max ?? -1, -1, 0);
5966
7216
  }
5967
7217
  case "sepBy": {
5968
7218
  const child = this.node(d.parser).ip;
@@ -5989,7 +7239,8 @@ var Encoder = class {
5989
7239
  if (inner.tag === "sequence" && !this.memo.has(d.parser) && !this.pending.has(d.parser)) {
5990
7240
  const kids = inner.parsers.map((c) => this.node(c).ip);
5991
7241
  const head = this.emitHead(OP_SEQX, 2 + kids.length + (this.rec ? kids.length : 0));
5992
- this.code[head + 1] = this.fn(d.fn, d.fnSrc ?? null);
7242
+ const projection = directArrayProjection(d.fn, d.fnSrc, kids.length);
7243
+ this.code[head + 1] = projection === null ? this.fn(d.fn, d.fnSrc ?? null) : ~projection;
5993
7244
  this.code[head + 2] = kids.length;
5994
7245
  for (let i = 0; i < kids.length; i++) this.code[head + 3 + i] = kids[i];
5995
7246
  if (this.rec) {
@@ -6010,10 +7261,11 @@ var Encoder = class {
6010
7261
  const cstOut = this.settings.hostMode === "cst";
6011
7262
  const noBuildCaptures = d.project === void 0;
6012
7263
  const derivedTrivia = d.build !== void 0 ? buildReadsTrivia(d) : noBuildCaptures;
7264
+ const omitsRaw = d.build !== void 0 && !buildReadsRaw(d);
6013
7265
  const derivedState = d.build !== void 0 ? buildReadsState(d) : noBuildCaptures;
6014
7266
  const derivedFields = d.build !== void 0 ? buildReadsFields(d) : noBuildCaptures;
6015
7267
  const wantsFields = parserHasOwnFields(d.parser) && (cstOut || derivedFields);
6016
- const flags = (cstOut || d.captureTrivia === true || d.trailingTrivia === true || derivedTrivia ? 4 : 0) | (cstOut || derivedState ? 8 : 0) | (wantsFields ? 16 : 0) | (d.collapse === true ? 32 : 0) | (d.unwrap === true ? 64 : 0) | (d.trailingTrivia === true ? 128 : 0) | (d.captureTrivia === true ? 1 : 0);
7268
+ const flags = (cstOut || d.captureTrivia === true || d.trailingTrivia === true || derivedTrivia ? 4 : 0) | (!cstOut && omitsRaw ? 2 : 0) | (cstOut || derivedState ? 8 : 0) | (wantsFields ? 16 : 0) | (d.collapse === true ? 32 : 0) | (d.unwrap === true ? 64 : 0) | (d.trailingTrivia === true ? 128 : 0) | (d.captureTrivia === true ? 1 : 0);
6017
7269
  const body = this.emit(
6018
7270
  this.track ? OP_NODE_TRACK : OP_NODE,
6019
7271
  d.build === void 0 ? -1 : this.fn(d.build, d.buildSrc ?? null),
@@ -6034,8 +7286,9 @@ var Encoder = class {
6034
7286
  const e = deriveExpected(d.parser);
6035
7287
  return this.emit(OP_GATE, cls, body, this.expected(e.length > 0 ? e : [d.parser._tag]));
6036
7288
  }
6037
- case "token":
7289
+ case "token": {
6038
7290
  return this.emit(OP_TOKEN, this.node(d.parser).ip);
7291
+ }
6039
7292
  case "routed":
6040
7293
  return this.emit(OP_ROUTED, d.fallback === void 0 ? -1 : this.node(d.fallback).ip);
6041
7294
  case "dispatch": {
@@ -6100,7 +7353,7 @@ var Encoder = class {
6100
7353
  case "lazy": {
6101
7354
  const refName = p._ruleName;
6102
7355
  const winner = refName === void 0 ? void 0 : this.winners?.[refName];
6103
- if (winner !== void 0 && !wrapsRef(winner, p)) return this.scopedRef(p, winner);
7356
+ if (winner !== void 0 && !winnerWrapsReference2(winner, p)) return this.scopedRef(p, winner);
6104
7357
  let resolved;
6105
7358
  try {
6106
7359
  resolved = d.thunk();
@@ -6116,7 +7369,7 @@ var Encoder = class {
6116
7369
  // other engine reported `['not(literal)']`. It hid because `expected` is a
6117
7370
  // TOP-LEVEL field on `RunResult` and is NOT part of the identity digest.
6118
7371
  case "not":
6119
- return this.emit(OP_NOT, this.node(d.parser).ip, this.expected([`not(${d.parser._tag})`]));
7372
+ return this.emit(OP_NOT, this.node(d.parser).ip, this.expected(assertionFailureExpected(false, d.parser._tag)));
6120
7373
  case "guard":
6121
7374
  return this.emit(OP_GUARD, this.fn(d.predicate, d.predSrc ?? null), this.expected(["gate"]));
6122
7375
  case "adjacency":
@@ -6134,7 +7387,7 @@ var Encoder = class {
6134
7387
  return this.emit(OP_WITHCTX, this.constant(d.extra), this.node(d.parser).ip);
6135
7388
  }
6136
7389
  case "peek":
6137
- return this.emit(OP_PEEK, this.node(d.parser).ip, this.expected([`peek(${d.parser._tag})`]));
7390
+ return this.emit(OP_PEEK, this.node(d.parser).ip, this.expected(assertionFailureExpected(true, d.parser._tag)));
6138
7391
  // A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
6139
7392
  // lowering was correct only for a choice arm.
6140
7393
  case "attempt": {
@@ -6295,6 +7548,8 @@ var Encoder = class {
6295
7548
  disp: this.disp,
6296
7549
  dsp: this.dsp,
6297
7550
  rules: this.rules,
7551
+ ...this.lex.length === 0 ? {} : { lex: this.lex },
7552
+ ...this.lexPrograms.length === 0 ? {} : { lexPrograms: this.lexPrograms },
6298
7553
  ...this.labels === void 0 ? {} : { labels: this.labels },
6299
7554
  ...this.classified ? { classified: 1 } : {},
6300
7555
  ...this.scanSkipSets.length === 0 ? {} : { scanSkip: this.scanSkipSets, scanSkipOf: this.scanSkipOf },
@@ -6349,7 +7604,11 @@ function encodeTableProgram(ruleMap, settings = {}) {
6349
7604
  ...hostMode === void 0 ? {} : { hostMode },
6350
7605
  ...track ? { trackLines: true } : {}
6351
7606
  };
6352
- const enc = new Encoder(resolvedSettings);
7607
+ const lexicalRoots = [...names].sort().map((name) => ruleMap[name]);
7608
+ const resolveLexical = (name) => ruleMap[name];
7609
+ const capabilities = collectLexicalCapabilities(lexicalRoots, resolveLexical);
7610
+ assertLexicalCapabilityClosure(lexicalRoots, capabilities, resolveLexical);
7611
+ const enc = new Encoder(resolvedSettings, capabilities.capabilityComplete);
6353
7612
  enc.winners = ruleMap;
6354
7613
  for (const name of names) enc.encodeRule(name, ruleMap[name]);
6355
7614
  const prog = enc.finish();
@@ -7394,6 +8653,8 @@ function childSlots(code, ip, out) {
7394
8653
  case OP_GUARD:
7395
8654
  case OP_ADJ:
7396
8655
  case OP_LIVE:
8656
+ case OP_LEX_BODY:
8657
+ case OP_LEX_PROGRAM:
7397
8658
  return true;
7398
8659
  // Single child at `ip + 1`. `OP_COV` is a wrapper on the same footing as the
7399
8660
  // rest — a coverage-encoded program is a program, and omitting it made
@@ -7511,7 +8772,12 @@ function transfer(code, ip, at, hostCst) {
7511
8772
  return { tri, buf: at.buf, cap };
7512
8773
  }
7513
8774
  if (op === OP_NODE || op === OP_NODE_TRACK) {
7514
- const cap = (code[ip + 3] & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
8775
+ const flags = code[ip + 3];
8776
+ const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
8777
+ if (directChildren) {
8778
+ return { tri: at.tri, buf: false, cap: CAP_OFF };
8779
+ }
8780
+ const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
7515
8781
  if (at.buf && cap === at.cap) return at;
7516
8782
  return { tri: at.tri, buf: true, cap };
7517
8783
  }
@@ -7552,6 +8818,43 @@ function computeSiteLabels(code, roots, hostCst) {
7552
8818
  return { at: (ip) => labels.get(ip) ?? TOP };
7553
8819
  }
7554
8820
 
8821
+ // src/table/scalar-terminal.ts
8822
+ function makeScalarRecognizer(op, spec) {
8823
+ if (op === OP_RX && spec instanceof RegExp) {
8824
+ return (input, pos) => {
8825
+ spec.lastIndex = pos;
8826
+ return spec.test(input) ? spec.lastIndex : -1;
8827
+ };
8828
+ }
8829
+ if (op !== OP_LIT || typeof spec !== "string") return void 0;
8830
+ const len = spec.length;
8831
+ if (len === 1) {
8832
+ const c0 = spec.charCodeAt(0);
8833
+ return (input, pos) => input.charCodeAt(pos) === c0 ? pos + 1 : -1;
8834
+ }
8835
+ if (len === 2) {
8836
+ const c0 = spec.charCodeAt(0), c1 = spec.charCodeAt(1);
8837
+ return (input, pos) => input.charCodeAt(pos) === c0 && input.charCodeAt(pos + 1) === c1 ? pos + 2 : -1;
8838
+ }
8839
+ if (len === 3) {
8840
+ const c0 = spec.charCodeAt(0), c1 = spec.charCodeAt(1), c2 = spec.charCodeAt(2);
8841
+ return (input, pos) => input.charCodeAt(pos) === c0 && input.charCodeAt(pos + 1) === c1 && input.charCodeAt(pos + 2) === c2 ? pos + 3 : -1;
8842
+ }
8843
+ return (input, pos) => input.startsWith(spec, pos) ? pos + len : -1;
8844
+ }
8845
+ function scalarTerminalNodeChild(code, ip) {
8846
+ if (code[ip + 1] < 0 || code[ip + 3] !== 0 || code[ip + 4] !== -1) return -1;
8847
+ const child = code[ip + 2];
8848
+ const op = code[child];
8849
+ return op === OP_RX || op === OP_LIT ? child : -1;
8850
+ }
8851
+ function scalarTerminalNotChild(code, ip) {
8852
+ if (code[ip] !== OP_NOT) return -1;
8853
+ const child = code[ip + 1];
8854
+ const op = code[child];
8855
+ return op === OP_RX || op === OP_LIT ? child : -1;
8856
+ }
8857
+
7555
8858
  // src/table/emit-assembly.ts
7556
8859
  var Unemittable = class extends Error {
7557
8860
  construct;
@@ -7613,7 +8916,19 @@ var EMITTED_PARAMS = [
7613
8916
  "matchesAt",
7614
8917
  "recoverScan",
7615
8918
  "orSentinel",
7616
- "captureError"
8919
+ "captureError",
8920
+ // Pure scalar terminal recognizers, indexed by the terminal's existing const
8921
+ // operand. Appended for compatibility with older precompiled factories.
8922
+ "RECOG",
8923
+ // Appended so precompiled factories produced by earlier runtimes keep every
8924
+ // positional helper binding. Older factories ignore this trailing argument.
8925
+ "commitTriviaScan",
8926
+ "scanTriviaCompact",
8927
+ "LEX",
8928
+ // Appended for old precompiled-factory ABI: old factories ignore it.
8929
+ "adjacencyHolds",
8930
+ // Appended for selected composite lexical programs; old factories ignore it.
8931
+ "LEXPROG"
7617
8932
  ];
7618
8933
  var RUNTIME_PRELUDE = `
7619
8934
  let _pfScan=null
@@ -7624,7 +8939,7 @@ function _skipTrivia(input,cur,ctx){
7624
8939
  const s=_pfScan
7625
8940
  if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
7626
8941
  if(s!==null)return skipTriviaScanned(s,input,cur,ctx)
7627
- if(needsDeferredTriviaCommit(ctx)){const sc=scanTrivia(input,cur,ctx);sc.commit();return sc.end}
8942
+ if(needsDeferredTriviaCommit(ctx))return commitTriviaScan(scanTriviaCompact(input,cur,ctx))
7628
8943
  return advanceTrivia(input,cur,ctx)
7629
8944
  }
7630
8945
  function _pushLeaf(ctx,value,s,e){pushCstLeaf(ctx,{_tag:'leaf',value,span:{start:s,end:e}})}
@@ -7638,6 +8953,13 @@ if(b.raw!==undefined)b.raw.push(l)
7638
8953
  else if(b.rawSingle!==undefined){b.raw=[b.rawSingle,l];b.rawSingle=undefined}
7639
8954
  else b.rawSingle=l
7640
8955
  }
8956
+ function _capturedFlatChildren(children){
8957
+ if(children.length===0)return EMPTY_CH
8958
+ if(children[0]!==undefined)return children
8959
+ let first=1
8960
+ while(first<children.length&&children[first]===undefined)first++
8961
+ return first===children.length?EMPTY_CH:children.slice(first)
8962
+ }
7641
8963
  function _accSet(ax,acc){
7642
8964
  if(ax===undefined||ax.length===0)return acc
7643
8965
  if(acc===undefined)return ax.slice()
@@ -7772,12 +9094,16 @@ function maskForClassRow(gates) {
7772
9094
  }
7773
9095
  return m;
7774
9096
  }
7775
- function rebuildPools(cc, fx, plan) {
9097
+ function rebuildPools(cc, fx, disp, plan) {
7776
9098
  const classes = plan.classes.map((row) => row.map((i) => i < 0 ? null : cc[i] ?? null));
7777
9099
  return {
7778
9100
  classes,
7779
9101
  armExpected: plan.armExpected.map((row) => row.map((i) => fx[i] ?? [])),
7780
- masks: plan.masks.map((ci) => maskForClassRow(classes[ci]))
9102
+ masks: plan.masks.map((source) => {
9103
+ const row = source >= 0 ? classes[source] : disp[~source]?.armCls;
9104
+ if (row === void 0) throw new TypeError(`table emitter: invalid MASK plan source ${source}`);
9105
+ return maskForClassRow(row);
9106
+ })
7781
9107
  };
7782
9108
  }
7783
9109
  function emitAssemblySource(t, prog, cfg, extraIps = []) {
@@ -7788,6 +9114,14 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
7788
9114
  if (cfg.coverage) throw new Unemittable("a coverage assembly");
7789
9115
  const roots = [...Object.values(prog.rules), ...extraIps];
7790
9116
  const labels = computeSiteLabels(code, roots, hostCst);
9117
+ const scalarSpecs = /* @__PURE__ */ new Set();
9118
+ if (!hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
9119
+ for (const ip of reachableSites(code, roots)) {
9120
+ if (code[ip] !== OP_NODE) continue;
9121
+ const child = scalarTerminalNodeChild(code, ip);
9122
+ if (child >= 0) scalarSpecs.add(code[child + 1]);
9123
+ }
9124
+ }
7791
9125
  const sinks = (() => {
7792
9126
  let fd = false;
7793
9127
  let er = REC2;
@@ -7808,6 +9142,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
7808
9142
  const reached = /* @__PURE__ */ new Set();
7809
9143
  const prelude = [];
7810
9144
  const skipDefs = [];
9145
+ const choiceDefs = [];
7811
9146
  const skipPool = /* @__PURE__ */ new Map();
7812
9147
  const pool = /* @__PURE__ */ new Map();
7813
9148
  const masks = [];
@@ -7827,6 +9162,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
7827
9162
  const kRef = (i) => hoist("k", `K[${i}]`);
7828
9163
  const fxRef = (i) => hoist("fx", `FX[${i}]`);
7829
9164
  const fnRef = (i) => hoist("fn", `FNS[${i}]`);
9165
+ const recognizerRef = (i) => hoist("rec", `RECOG[${i}]`);
7830
9166
  const sentRef = (cls) => cls < 0 ? "undefined" : hoist("sent", `SENTS[${cls}]`);
7831
9167
  let uid = 0;
7832
9168
  const tmp = () => `_t${uid++}_`;
@@ -7840,8 +9176,8 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
7840
9176
  const nm = `_sk${skipPool.size}`;
7841
9177
  skipPool.set(key, nm);
7842
9178
  if (!hasScan) {
7843
- skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){const s=scanTrivia(input,cur,ctx);s.commit();return s.end}` : `function ${nm}(input,cur,ctx){
7844
- if(needsDeferredTriviaCommit(ctx)){const s=scanTrivia(input,cur,ctx);s.commit();return s.end}
9179
+ skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return commitTriviaScan(scanTriviaCompact(input,cur,ctx))}` : `function ${nm}(input,cur,ctx){
9180
+ if(needsDeferredTriviaCommit(ctx))return commitTriviaScan(scanTriviaCompact(input,cur,ctx))
7845
9181
  return advanceTrivia(input,cur,ctx)}`);
7846
9182
  return nm;
7847
9183
  }
@@ -7928,6 +9264,19 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
7928
9264
  const s = k[code[ip + 1]];
7929
9265
  const xf = fxRef(code[ip + 2]);
7930
9266
  const track = op === OP_LIT_TRACK;
9267
+ if (!track && scalarSpecs.has(code[ip + 1])) {
9268
+ const recognize = recognizerRef(code[ip + 1]);
9269
+ return `${head}
9270
+ const e=${recognize}(input,pos)
9271
+ if(e>=0){
9272
+ ${captureLeaf(q(s))}
9273
+ EC.e=e
9274
+ return ${q(s)}
9275
+ }
9276
+ ctx._fe=pos;ctx._fx=${xf}
9277
+ return FAIL
9278
+ }`;
9279
+ }
7931
9280
  const test = s.length === 1 ? `input.charCodeAt(pos)===${s.charCodeAt(0)}` : s.length === 2 ? `input.charCodeAt(pos)===${s.charCodeAt(0)}&&input.charCodeAt(pos+1)===${s.charCodeAt(1)}` : `input.startsWith(${q(s)},pos)`;
7932
9281
  return `${head}
7933
9282
  if(${test}){
@@ -7977,6 +9326,20 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
7977
9326
  case OP_RX_TRACK: {
7978
9327
  const xf = fxRef(code[ip + 2]);
7979
9328
  const track = op === OP_RX_TRACK;
9329
+ if (!track && scalarSpecs.has(code[ip + 1])) {
9330
+ const recognize = recognizerRef(code[ip + 1]);
9331
+ return `${head}
9332
+ const e=${recognize}(input,pos)
9333
+ if(e>=0){
9334
+ const v=input.slice(pos,e)
9335
+ ${captureLeaf("v")}
9336
+ EC.e=e
9337
+ return v
9338
+ }
9339
+ ctx._fe=pos;ctx._fx=${xf}
9340
+ return FAIL
9341
+ }`;
9342
+ }
7980
9343
  const scanned = emitScan(code[ip + 1], xf, track, captureLeaf);
7981
9344
  if (scanned !== void 0) return `${head}${scanned}}`;
7982
9345
  const rxk = k[code[ip + 1]];
@@ -8138,6 +9501,73 @@ const out=${isToken ? "input.slice(pos,e)" : `${fn}(v,{start:pos,end:e})`}
8138
9501
  if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:out,span:{start:pos,end:e}})
8139
9502
  EC.e=e
8140
9503
  return out
9504
+ }`;
9505
+ }
9506
+ case OP_LEX_BODY: {
9507
+ const recognize = hoist("lex", `LEX[${code[ip + 1]}]`);
9508
+ const expected = fxRef(code[ip + 2]);
9509
+ const suffixExpected = fxRef(code[ip + 3]);
9510
+ const lineFlags = code[ip + 4];
9511
+ const hasSuffix = (lineFlags & 4) !== 0;
9512
+ return `${head}
9513
+ const r=${recognize}(input,pos)
9514
+ if(r<0){ctx._fe=pos;ctx._fx=${expected};if(ctx._probe!==undefined)failAt(ctx,${expected},pos);return FAIL}
9515
+ const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
9516
+ ${(lineFlags & 1) !== 0 ? "_trackLines(ctx,input,sm?e-1:e)" : ""}
9517
+ ${hasSuffix ? "ctx._fc=false" : ""}
9518
+ ${hasSuffix && (lineFlags & 2) !== 0 ? "if(sm)_trackLines(ctx,input,e)" : ""}
9519
+ ${hasSuffix ? `if(!sm){ctx._fe=e;ctx._fx=${suffixExpected};if(ctx._probe!==undefined)failAt(ctx,${suffixExpected},e)}` : ""}
9520
+ const v=input.slice(pos,e)
9521
+ if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
9522
+ EC.e=e
9523
+ return v
9524
+ }`;
9525
+ }
9526
+ case OP_LEX_PROGRAM: {
9527
+ const programId = code[ip + 1];
9528
+ const run3 = hoist("lexProgram", `LEXPROG[${programId}]`);
9529
+ const scanId = t.lexPrograms[programId].scan;
9530
+ if (scanId !== void 0) return `${head}
9531
+ const sTri=ctx.trivia,sKinds=ctx.triviaKindLabels,sScan=_pfScan
9532
+ const sBuf=ctx._cstBuf,sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
9533
+ const sOtl=ctx._triviaLog,sRtl=ctx._rootTriviaLog
9534
+ const wasCap=ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined
9535
+ _pfScan=null
9536
+ ctx.trivia=undefined
9537
+ ctx.triviaKindLabels=undefined
9538
+ ctx._cstBuf=undefined
9539
+ ctx._cstChildren=undefined
9540
+ ctx._cstLeaves=undefined
9541
+ ctx._cstRawChildren=undefined
9542
+ ctx._cstTriviaLog=undefined
9543
+ ctx._triviaLog=undefined
9544
+ ctx._rootTriviaLog=undefined
9545
+ let e
9546
+ try{e=${run3}(input,pos,ctx,SCANS[${scanId}])}finally{
9547
+ _pfScan=sScan
9548
+ ctx.trivia=sTri
9549
+ ctx.triviaKindLabels=sKinds
9550
+ ctx._cstBuf=sBuf
9551
+ ctx._cstChildren=sCh
9552
+ ctx._cstLeaves=sLv
9553
+ ctx._cstRawChildren=sRaw
9554
+ ctx._cstTriviaLog=sTl
9555
+ ctx._triviaLog=sOtl
9556
+ ctx._rootTriviaLog=sRtl
9557
+ }
9558
+ if(e<0)return FAIL
9559
+ const v=input.slice(pos,e)
9560
+ if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
9561
+ EC.e=e
9562
+ return v
9563
+ }`;
9564
+ return `${head}
9565
+ const e=${run3}(input,pos,ctx)
9566
+ if(e<0)return FAIL
9567
+ const v=input.slice(pos,e)
9568
+ if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
9569
+ EC.e=e
9570
+ return v
8141
9571
  }`;
8142
9572
  }
8143
9573
  /* ── transaction ─────────────────────────────────────────────────────── */
@@ -8155,6 +9585,18 @@ return FAIL
8155
9585
  }`;
8156
9586
  }
8157
9587
  case OP_NOT: {
9588
+ const scalarChild = scalarTerminalNotChild(code, ip);
9589
+ if (scalarChild >= 0) {
9590
+ const recognize = recognizerRef(code[scalarChild + 1]);
9591
+ const xf2 = fxRef(code[ip + 2]);
9592
+ return `${head}
9593
+ if(${recognize}(input,pos)<0){EC.e=pos;return null}
9594
+ ctx._fe=pos
9595
+ ctx._fx=${xf2}
9596
+ EC.e=pos
9597
+ return FAIL
9598
+ }`;
9599
+ }
8158
9600
  const child = link(code[ip + 1]);
8159
9601
  const xf = fxRef(code[ip + 2]);
8160
9602
  const p = tmp();
@@ -8204,14 +9646,14 @@ return v
8204
9646
  const base = fused ? ip + 3 : ip + 2;
8205
9647
  const n = code[fused ? ip + 2 : ip + 1];
8206
9648
  const wantValues = op !== OP_SEQV;
8207
- for (let i = 1; i < n; i++) {
8208
- if (code[code[base + i]] === OP_ADJ) {
8209
- throw new Unemittable("a sequence carrying an adjacency assertion (OP_ADJ)");
8210
- }
8211
- }
8212
- const fn = fused ? fnRef(code[ip + 1]) : void 0;
9649
+ const reducer = fused ? code[ip + 1] : -1;
9650
+ const projection = reducer < 0 ? ~reducer : -1;
9651
+ const fn = fused && projection < 0 ? fnRef(reducer) : void 0;
8213
9652
  const kids = [];
8214
- for (let i = 0; i < n; i++) kids.push(link(code[base + i]));
9653
+ for (let i = 0; i < n; i++) {
9654
+ const childIp = code[base + i];
9655
+ kids.push(code[childIp] === OP_ADJ ? "" : link(childIp));
9656
+ }
8215
9657
  const sy = REC2 ? `${tmp()}sy` : "";
8216
9658
  const pub = (i) => {
8217
9659
  const s = sentRef(code[base + n + i]);
@@ -8225,7 +9667,7 @@ return v
8225
9667
  }` : `${parts.join("\n")}
8226
9668
  }`;
8227
9669
  if (n === 1) {
8228
- parts.push(fused ? `return ${fn}([v0],{start:pos,end:EC.e})` : wantValues ? "return [v0]" : "return undefined");
9670
+ parts.push(fused ? projection === 0 ? "return v0" : `return ${fn}([v0],{start:pos,end:EC.e})` : wantValues ? "return [v0]" : "return undefined");
8229
9671
  return close();
8230
9672
  }
8231
9673
  parts.push("let cur=EC.e");
@@ -8234,11 +9676,21 @@ return v
8234
9676
  const vn = `v${i}`;
8235
9677
  parts.push(`let ${vn}`);
8236
9678
  if (REC2) parts.push(pub(i));
8237
- parts.push(emitTerm(kids[i], vn, tmp(), L, skipFor(L)));
9679
+ const childIp = code[base + i];
9680
+ if (code[childIp] === OP_ADJ) {
9681
+ const negated = code[childIp + 1] === 1;
9682
+ const ki = code[childIp + 2];
9683
+ const kinds = ki < 0 ? "undefined" : `K[${ki}]`;
9684
+ const expected = fxRef(code[childIp + 3]);
9685
+ parts.push(
9686
+ `if(!adjacencyHolds(input,cur,ctx,${negated ? "true" : "false"},${kinds})){ctx._fe=cur;ctx._fx=${expected};return FAIL}`,
9687
+ `${vn}=null`
9688
+ );
9689
+ } else parts.push(emitTerm(kids[i], vn, tmp(), L, skipFor(L)));
8238
9690
  names.push(vn);
8239
9691
  }
8240
9692
  parts.push("EC.e=cur");
8241
- parts.push(fused ? `return ${fn}([${names.join(",")}],{start:pos,end:cur})` : wantValues ? `return [${names.join(",")}]` : "return undefined");
9693
+ parts.push(fused ? projection >= 0 ? `return ${names[projection]}` : `return ${fn}([${names.join(",")}],{start:pos,end:cur})` : wantValues ? `return [${names.join(",")}]` : "return undefined");
8242
9694
  return close();
8243
9695
  }
8244
9696
  case OP_CHOICE: {
@@ -8248,11 +9700,6 @@ return v
8248
9700
  const base = ip + 4;
8249
9701
  const arms = [];
8250
9702
  for (let i = 0; i < n; i++) arms.push(link(code[base + i]));
8251
- const axi = armExpected.push(
8252
- Array.from({ length: n }, (_, i) => t.fx[code[base + n + i]])
8253
- ) - 1;
8254
- armExpectedPlan.push(Array.from({ length: n }, (_, i) => code[base + n + i]));
8255
- const afx = hoist("afx", `AFX[${axi}]`);
8256
9703
  if (table.exclusive) {
8257
9704
  const di = code[ip + 1];
8258
9705
  const asc = hoist("as", `DISP[${di}].ascii`);
@@ -8279,53 +9726,65 @@ ctx._fe=pos;ctx._fx=${choiceFx}
8279
9726
  return FAIL
8280
9727
  }`;
8281
9728
  }
8282
- const ci = classes.push(Array.from({ length: n }, (_, i) => table.armCls[i] ?? null)) - 1;
8283
- classPlan.push(Array.from({ length: n }, (_, i) => prog.disp[code[ip + 1]][i] ?? -1));
8284
- const gates = classes[ci];
8285
- const gRef = hoist("g", `CLS[${ci}]`);
8286
- const maskable = n <= 32;
8287
- let maskName = "";
8288
- if (maskable) {
8289
- maskName = hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`);
8290
- maskPlan.push(ci);
8291
- }
8292
- const p = tmp();
8293
- const maskArms = arms.map((a, i) => `
8294
- if((bits&${1 << i})!==0){
9729
+ {
9730
+ const di = code[ip + 1];
9731
+ const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
9732
+ const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
9733
+ const gateRefs = Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
9734
+ const maskable = n <= 32;
9735
+ const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
9736
+ if (maskable) maskPlan.push(~di);
9737
+ const p = tmp();
9738
+ const catchName = maskable ? `_cx${uid++}_` : "";
9739
+ if (maskable) {
9740
+ const catchCases = expected.map((e, i) => `case ${i}:if(target<=${i})return acc;acc=_accSet(${e},acc)`).join("\n");
9741
+ choiceDefs.push(`function ${catchName}(target,prev,acc){switch(prev){
9742
+ ${catchCases}
9743
+ }return acc}`);
9744
+ }
9745
+ const maskArms = maskable ? arms.map((arm, i) => {
9746
+ return `if((bits&${1 << i})!==0){
8295
9747
  ctx._fc=false
8296
- {const v=${a}(input,pos,ctx)
9748
+ {const v=${arm}(input,pos,ctx)
8297
9749
  if(v!==FAIL)return v}
8298
- for(let j=prev;j<${i};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
9750
+ if(best===pos)acc=${catchName}(${i},prev,acc)
8299
9751
  prev=${i + 1}
8300
- acc=_accSet(ctx._fx,acc)
9752
+ {const at=ctx._fe??pos
9753
+ if(at>best){best=at;acc=undefined}
9754
+ if(at===best)acc=_accSet(ctx._fx,acc)}
8301
9755
  if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
8302
9756
  ${emitRollback(p, L.buf, sinks)}
8303
- }`).join("");
8304
- const generalArms = arms.map((a, i) => `
8305
- if(${gRef}[${i}]===null||classHas(${gRef}[${i}],c)){
9757
+ }`;
9758
+ }).join("\n") : "";
9759
+ const generalArms = arms.map((arm, i) => `if(${gateRefs[i]}===null||classHas(${gateRefs[i]},c)){
8306
9760
  ctx._fc=false
8307
- {const v=${a}(input,pos,ctx)
9761
+ {const v=${arm}(input,pos,ctx)
8308
9762
  if(v!==FAIL)return v}
8309
- acc=_accSet(ctx._fx,acc)
9763
+ {const at=ctx._fe??pos
9764
+ if(at>best){best=at;acc=undefined}
9765
+ if(at===best)acc=_accSet(ctx._fx,acc)}
8310
9766
  if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
8311
9767
  ${emitRollback(p, L.buf, sinks)}
8312
- }else acc=_accSet(${afx}[${i}],acc)`).join("");
8313
- return `${head}
9768
+ }else if(best===pos)acc=_accSet(${expected[i]},acc)`).join("\n");
9769
+ return `${head}
8314
9770
  const c=lead(input,pos)
8315
9771
  ${emitMark(p, L.buf, sinks)}
8316
9772
  let acc
9773
+ let best=pos
8317
9774
  ${maskable ? `if(c<128){
8318
9775
  const bits=${maskName}[c<0?128:c]
8319
9776
  let prev=0
8320
9777
  ${maskArms}
8321
- for(let j=prev;j<${n};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
9778
+ if(best===pos)acc=${catchName}(${n},prev,acc)
8322
9779
  ctx._fe=pos;ctx._fx=acc??${choiceFx}
8323
9780
  return FAIL
8324
9781
  }
8325
- ` : ""}${generalArms}
9782
+ ` : ""}
9783
+ ${generalArms}
8326
9784
  ctx._fe=pos;ctx._fx=acc??${choiceFx}
8327
9785
  return FAIL
8328
9786
  }`;
9787
+ }
8329
9788
  }
8330
9789
  case OP_DISPATCH: {
8331
9790
  const di = code[ip + 2];
@@ -8351,8 +9810,16 @@ return FAIL
8351
9810
  return `asciiFoldKey(key).startsWith(${q(m[1])})`;
8352
9811
  case 4:
8353
9812
  return `asciiFoldKey(key).endsWith(${q(m[1])})`;
8354
- default:
9813
+ default: {
9814
+ if (!m[2].includes("g") && !m[2].includes("y")) {
9815
+ try {
9816
+ new RegExp(m[1], m[2]);
9817
+ return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
9818
+ } catch {
9819
+ }
9820
+ }
8355
9821
  return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
9822
+ }
8356
9823
  }
8357
9824
  };
8358
9825
  const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
@@ -8410,6 +9877,15 @@ return [key,v]
8410
9877
  const reportItem = (flags & 4) !== 0;
8411
9878
  const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
8412
9879
  const collect = op === OP_REP;
9880
+ let itemCls;
9881
+ if (!REC2) {
9882
+ const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
9883
+ if (itemClassIndex >= 0) {
9884
+ const ci = classes.push([t.cc[itemClassIndex]]) - 1;
9885
+ classPlan.push([itemClassIndex]);
9886
+ itemCls = hoist("ri", `CLS[${ci}][0]`);
9887
+ }
9888
+ }
8413
9889
  const skipBeforeFirst = sepIp < 0 && min === 0;
8414
9890
  const p = tmp();
8415
9891
  const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
@@ -8417,7 +9893,6 @@ return [key,v]
8417
9893
  const skip = skipFor(L);
8418
9894
  const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
8419
9895
  const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
8420
- const needMark = L.buf ? "true" : "needMark";
8421
9896
  const pfd = sinks.fd ? `${p}fd` : "0";
8422
9897
  const per = sinks.er ? `${p}er` : "undefined";
8423
9898
  const rb = L.buf ? `_rbBuf(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
@@ -8462,11 +9937,13 @@ continue
8462
9937
  return `${head}
8463
9938
  const out=${collect ? "[]" : "undefined"}
8464
9939
  ${knownTrivia === void 0 ? "const hasTrivia=ctx.trivia!==undefined\n" : ""}${L.buf ? "" : "const needMark=_rollbackNeeded(ctx)\n"}${REC2 ? `const ${my}=ctx._sync
8465
- ` : ""}let cur=pos
9940
+ ` : ""}${itemCls === void 0 ? "" : `const ${p}gate=ctx._probe===undefined
9941
+ `}let cur=pos
8466
9942
  let count=0
8467
9943
  for(;;){
8468
9944
  ${max >= 0 ? `if(count>=${max})break
8469
9945
  ` : ""}${sep !== void 0 ? `if(count>0&&count>=${min}&&cur>=input.length)break
9946
+ ` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}&&!classHas(${itemCls},lead(input,cur)))break
8470
9947
  ` : ""}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` : ""}
8471
9948
  ${markBody}
8472
9949
  let itemStart=cur
@@ -8491,7 +9968,11 @@ itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(inp
8491
9968
  ${rb}
8492
9969
  ${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
8493
9970
  }
8494
- ctx._fc=false
9971
+ ${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&!classHas(${itemCls},lead(input,itemStart))){
9972
+ ${rb}
9973
+ ${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
9974
+ }
9975
+ `}ctx._fc=false
8495
9976
  const v=${child}(input,itemStart,ctx)
8496
9977
  if(v===FAIL){
8497
9978
  ${REC2 ? `if(ctx._fc===true){
@@ -8520,6 +10001,26 @@ return out
8520
10001
  case OP_NODE:
8521
10002
  case OP_NODE_TRACK: {
8522
10003
  const flags = code[ip + 3];
10004
+ const scalarChild = scalarTerminalNodeChild(code, ip);
10005
+ if (scalarChild >= 0 && scalarSpecs.has(code[scalarChild + 1])) {
10006
+ const recognize = recognizerRef(code[scalarChild + 1]);
10007
+ const spec = code[scalarChild] === OP_RX ? null : k[code[scalarChild + 1]];
10008
+ const value2 = spec === null ? "input.slice(pos,end)" : q(spec);
10009
+ const xf = fxRef(code[scalarChild + 2]);
10010
+ const build2 = fnRef(code[ip + 1]);
10011
+ return `${head}
10012
+ const end=${recognize}(input,pos)
10013
+ if(end<0){ctx._fe=pos;ctx._fx=${xf};return FAIL}
10014
+ const value=${value2}
10015
+ const leaf={_tag:'leaf',value,span:{start:pos,end}}
10016
+ const kids=[leaf],rawKids=[leaf],span={start:pos,end}
10017
+ EC.e=end
10018
+ const nd=${build2}(kids,undefined,span,rawKids,EMPTY_TL,undefined)
10019
+ ${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))"}
10020
+ EC.e=end
10021
+ return nd
10022
+ }`;
10023
+ }
8523
10024
  const child = link(code[ip + 2]);
8524
10025
  const proj = code[ip + 4];
8525
10026
  const buildIdx = code[ip + 1];
@@ -8534,6 +10035,51 @@ return out
8534
10035
  const unwrap = (flags & 64) !== 0;
8535
10036
  const trailingTrivia = (flags & 128) !== 0;
8536
10037
  const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
10038
+ if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
10039
+ const fields = flags === 18;
10040
+ const collapseChildren = flags === 34;
10041
+ const publish = `if(sBuf!==undefined){
10042
+ if(sBuf.rawOnly!==true){
10043
+ if(sBuf.ch!==undefined)sBuf.ch.push(nd)
10044
+ else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
10045
+ else sBuf.single=nd
10046
+ }
10047
+ const rawNd=rawEntry(nd,input,pos,end)
10048
+ if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
10049
+ else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
10050
+ else sBuf.rawSingle=rawNd
10051
+ }else if(sCh!==undefined){
10052
+ sCh.push(nd)
10053
+ if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
10054
+ }`;
10055
+ return `${head}
10056
+ const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
10057
+ const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf,sFields=ctx._fields
10058
+ const flat=[]
10059
+ ctx._cstBuf=undefined
10060
+ ctx._cstChildren=flat
10061
+ ctx._cstLeaves=flat
10062
+ ctx._cstRawChildren=undefined
10063
+ ctx._cstTriviaLog=undefined
10064
+ ctx.captureTrivia=false
10065
+ ctx._fields=${fields ? "[]" : "undefined"}
10066
+ const v=${child}(input,pos,ctx)
10067
+ const captured=_capturedFlatChildren(flat)
10068
+ ${fields ? "const fieldMap=buildFieldMap(ctx._fields)\n" : ""}ctx._fields=sFields
10069
+ ctx._cstBuf=sBuf
10070
+ ctx._cstChildren=sCh
10071
+ ctx._cstLeaves=sLv
10072
+ ctx._cstRawChildren=sRaw
10073
+ ctx._cstTriviaLog=sTl
10074
+ ctx.captureTrivia=sCap
10075
+ if(v===FAIL)return FAIL
10076
+ const end=EC.e
10077
+ ${collapseChildren ? `const nd=captured.length===1?captured[0]:${build}(captured,undefined,{start:pos,end},EMPTY_CH,EMPTY_TL,undefined)` : `const nd=${build}(captured,${fields ? "fieldMap" : "undefined"},{start:pos,end},EMPTY_CH,EMPTY_TL,undefined)`}
10078
+ ${publish}
10079
+ EC.e=end
10080
+ return nd
10081
+ }`;
10082
+ }
8537
10083
  const structural = build === void 0 && proj < 0;
8538
10084
  const grammarCapture = (flags & 1) !== 0 || trailingTrivia;
8539
10085
  const hostCapturesThisType = structural && cfg.hostCaptureTrivia !== void 0 ? cfg.hostCaptureTrivia(type) : void 0;
@@ -8619,6 +10165,7 @@ return nd
8619
10165
  const source = `${RUNTIME_PRELUDE}
8620
10166
  ${prelude.join("\n")}
8621
10167
  ${skipDefs.join("\n")}
10168
+ ${choiceDefs.join("\n")}
8622
10169
  ${bodies.join("\n")}
8623
10170
  function _begin(ctx){
8624
10171
  const host=ctx.build
@@ -8859,7 +10406,7 @@ function reachableIps(prog) {
8859
10406
 
8860
10407
  // src/table/stamp.ts
8861
10408
  var EMPTY_FX = [];
8862
- function committed(c) {
10409
+ function committed2(c) {
8863
10410
  return c._fc === true;
8864
10411
  }
8865
10412
  function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(prog)) {
@@ -8909,7 +10456,7 @@ function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(pr
8909
10456
  const fe = ctx._fe;
8910
10457
  const at = fe === void 0 || fe < 0 ? pos : fe;
8911
10458
  const fspan = lines ? spanLines(ctx, at, at) : { start: at, end: at };
8912
- return committed(ctx) ? { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan, committed: true } : { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan };
10459
+ return committed2(ctx) ? { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan, committed: true } : { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan };
8913
10460
  }
8914
10461
  return { ok: true, value: d.lastValue(), span: lines ? spanLines(ctx, pos, end) : { start: pos, end } };
8915
10462
  };
@@ -8955,11 +10502,15 @@ function linkMatcher(m) {
8955
10502
  return (key) => asciiFoldKey(key).startsWith(value);
8956
10503
  case 4:
8957
10504
  return (key) => asciiFoldKey(key).endsWith(value);
8958
- // A fresh RegExp per test, as `matchesDispatchMatcher` builds — a cached one
8959
- // would carry `lastIndex` across parses whenever the author's pattern was
8960
- // sticky or global.
8961
10505
  default: {
8962
10506
  const flags = m[2];
10507
+ if (!flags.includes("g") && !flags.includes("y")) {
10508
+ try {
10509
+ const pattern = new RegExp(value, flags);
10510
+ return (key) => pattern.test(key);
10511
+ } catch {
10512
+ }
10513
+ }
8963
10514
  return (key) => new RegExp(value, flags).test(key);
8964
10515
  }
8965
10516
  }
@@ -8990,6 +10541,17 @@ function assemble(t, prog, cfg) {
8990
10541
  return made;
8991
10542
  }
8992
10543
  const EC = newEndCell();
10544
+ const scalarRecognizers = [];
10545
+ const rawScalarSpecs = /* @__PURE__ */ new Set();
10546
+ function scalarFor(child) {
10547
+ const spec = code[child + 1];
10548
+ let recognize = scalarRecognizers[spec];
10549
+ if (recognize === void 0) {
10550
+ recognize = makeScalarRecognizer(code[child], k[spec]);
10551
+ scalarRecognizers[spec] = recognize;
10552
+ }
10553
+ return recognize;
10554
+ }
8993
10555
  let SCAN = null;
8994
10556
  const memo = /* @__PURE__ */ new Map();
8995
10557
  const reached = /* @__PURE__ */ new Set();
@@ -8997,21 +10559,249 @@ function assemble(t, prog, cfg) {
8997
10559
  const lf = { _tag: "leaf", value, span: { start: s, end: e } };
8998
10560
  pushCstLeaf(ctx, lf);
8999
10561
  }
9000
- function rollbackNeeded(ctx) {
9001
- 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;
10562
+ function plainBuildNode(child, build) {
10563
+ return (input, pos, ctx) => {
10564
+ const sCh = ctx._cstChildren;
10565
+ const sLv = ctx._cstLeaves;
10566
+ const sRaw = ctx._cstRawChildren;
10567
+ const sTl = ctx._cstTriviaLog;
10568
+ const sCap = ctx.captureTrivia;
10569
+ const sBuf = ctx._cstBuf;
10570
+ const savedFields = ctx._fields;
10571
+ const buf = {};
10572
+ ctx._cstBuf = buf;
10573
+ ctx._cstChildren = void 0;
10574
+ ctx._cstLeaves = void 0;
10575
+ ctx._cstRawChildren = void 0;
10576
+ ctx._cstTriviaLog = void 0;
10577
+ ctx.captureTrivia = false;
10578
+ ctx._fields = void 0;
10579
+ const value = child(input, pos, ctx);
10580
+ const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
10581
+ const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
10582
+ ctx._fields = savedFields;
10583
+ ctx._cstBuf = sBuf;
10584
+ ctx._cstChildren = sCh;
10585
+ ctx._cstLeaves = sLv;
10586
+ ctx._cstRawChildren = sRaw;
10587
+ ctx._cstTriviaLog = sTl;
10588
+ ctx.captureTrivia = sCap;
10589
+ if (value === FAIL) return FAIL;
10590
+ const end = EC.e;
10591
+ const span = { start: pos, end };
10592
+ const node2 = build(kids, void 0, span, rawKids, EMPTY_TL2, void 0);
10593
+ if (sBuf !== void 0 || sCh !== void 0) {
10594
+ pushCstChild(ctx, node2, rawEntry(node2, input, pos, end));
10595
+ }
10596
+ EC.e = end;
10597
+ return node2;
10598
+ };
9002
10599
  }
9003
- let MRAW = 0;
9004
- let MTL = 0;
9005
- let MLV = 0;
9006
- function markCst(ctx) {
9007
- const b = ctx._cstBuf;
9008
- if (b !== void 0) {
9009
- const raw = b.raw;
9010
- MRAW = raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
9011
- const ch2 = b.ch;
9012
- MLV = ch2 !== void 0 ? ch2.length : b.single !== void 0 ? 1 : 0;
9013
- const tl = b.tl;
9014
- MTL = tl !== void 0 ? tl.length : 0;
10600
+ function capturedFlatChildren(children2) {
10601
+ if (children2.length === 0) return EMPTY_CH;
10602
+ if (children2[0] !== void 0) return children2;
10603
+ let first = 1;
10604
+ while (first < children2.length && children2[first] === void 0) first++;
10605
+ return first === children2.length ? EMPTY_CH : children2.slice(first);
10606
+ }
10607
+ function childrenOnlyBuildNode(child, build) {
10608
+ return (input, pos, ctx) => {
10609
+ const sCh = ctx._cstChildren;
10610
+ const sLv = ctx._cstLeaves;
10611
+ const sRaw = ctx._cstRawChildren;
10612
+ const sTl = ctx._cstTriviaLog;
10613
+ const sCap = ctx.captureTrivia;
10614
+ const sBuf = ctx._cstBuf;
10615
+ const savedFields = ctx._fields;
10616
+ const kids = [];
10617
+ ctx._cstBuf = void 0;
10618
+ ctx._cstChildren = kids;
10619
+ ctx._cstLeaves = kids;
10620
+ ctx._cstRawChildren = void 0;
10621
+ ctx._cstTriviaLog = void 0;
10622
+ ctx.captureTrivia = false;
10623
+ ctx._fields = void 0;
10624
+ const value = child(input, pos, ctx);
10625
+ const captured = capturedFlatChildren(kids);
10626
+ ctx._fields = savedFields;
10627
+ ctx._cstBuf = sBuf;
10628
+ ctx._cstChildren = sCh;
10629
+ ctx._cstLeaves = sLv;
10630
+ ctx._cstRawChildren = sRaw;
10631
+ ctx._cstTriviaLog = sTl;
10632
+ ctx.captureTrivia = sCap;
10633
+ if (value === FAIL) return FAIL;
10634
+ const end = EC.e;
10635
+ const node2 = build(captured, void 0, { start: pos, end }, EMPTY_CH, EMPTY_TL2, void 0);
10636
+ if (sBuf !== void 0 || sCh !== void 0) {
10637
+ pushCstChild(ctx, node2, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node2, input, pos, end) : void 0);
10638
+ }
10639
+ EC.e = end;
10640
+ return node2;
10641
+ };
10642
+ }
10643
+ function childrenOnlyFieldsBuildNode(child, build) {
10644
+ return (input, pos, ctx) => {
10645
+ const sCh = ctx._cstChildren;
10646
+ const sLv = ctx._cstLeaves;
10647
+ const sRaw = ctx._cstRawChildren;
10648
+ const sTl = ctx._cstTriviaLog;
10649
+ const sCap = ctx.captureTrivia;
10650
+ const sBuf = ctx._cstBuf;
10651
+ const savedFields = ctx._fields;
10652
+ const kids = [];
10653
+ ctx._cstBuf = void 0;
10654
+ ctx._cstChildren = kids;
10655
+ ctx._cstLeaves = kids;
10656
+ ctx._cstRawChildren = void 0;
10657
+ ctx._cstTriviaLog = void 0;
10658
+ ctx.captureTrivia = false;
10659
+ ctx._fields = [];
10660
+ const value = child(input, pos, ctx);
10661
+ const captured = capturedFlatChildren(kids);
10662
+ const fieldMap = buildFieldMap(ctx._fields);
10663
+ ctx._fields = savedFields;
10664
+ ctx._cstBuf = sBuf;
10665
+ ctx._cstChildren = sCh;
10666
+ ctx._cstLeaves = sLv;
10667
+ ctx._cstRawChildren = sRaw;
10668
+ ctx._cstTriviaLog = sTl;
10669
+ ctx.captureTrivia = sCap;
10670
+ if (value === FAIL) return FAIL;
10671
+ const end = EC.e;
10672
+ const node2 = build(captured, fieldMap, { start: pos, end }, EMPTY_CH, EMPTY_TL2, void 0);
10673
+ if (sBuf !== void 0 || sCh !== void 0) {
10674
+ pushCstChild(ctx, node2, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node2, input, pos, end) : void 0);
10675
+ }
10676
+ EC.e = end;
10677
+ return node2;
10678
+ };
10679
+ }
10680
+ function collapseBuildNode(child, build) {
10681
+ return (input, pos, ctx) => {
10682
+ const sCh = ctx._cstChildren;
10683
+ const sLv = ctx._cstLeaves;
10684
+ const sRaw = ctx._cstRawChildren;
10685
+ const sTl = ctx._cstTriviaLog;
10686
+ const sCap = ctx.captureTrivia;
10687
+ const sBuf = ctx._cstBuf;
10688
+ const savedFields = ctx._fields;
10689
+ const buf = {};
10690
+ ctx._cstBuf = buf;
10691
+ ctx._cstChildren = void 0;
10692
+ ctx._cstLeaves = void 0;
10693
+ ctx._cstRawChildren = void 0;
10694
+ ctx._cstTriviaLog = void 0;
10695
+ ctx.captureTrivia = false;
10696
+ ctx._fields = void 0;
10697
+ const value = child(input, pos, ctx);
10698
+ const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
10699
+ const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
10700
+ ctx._fields = savedFields;
10701
+ ctx._cstBuf = sBuf;
10702
+ ctx._cstChildren = sCh;
10703
+ ctx._cstLeaves = sLv;
10704
+ ctx._cstRawChildren = sRaw;
10705
+ ctx._cstTriviaLog = sTl;
10706
+ ctx.captureTrivia = sCap;
10707
+ if (value === FAIL) return FAIL;
10708
+ const end = EC.e;
10709
+ const span = { start: pos, end };
10710
+ const node2 = kids.length === 1 ? kids[0] : build(kids, void 0, span, rawKids, EMPTY_TL2, void 0);
10711
+ if (sBuf !== void 0 || sCh !== void 0) {
10712
+ pushCstChild(ctx, node2, rawEntry(node2, input, pos, end));
10713
+ }
10714
+ EC.e = end;
10715
+ return node2;
10716
+ };
10717
+ }
10718
+ function childrenOnlyCollapseBuildNode(child, build) {
10719
+ return (input, pos, ctx) => {
10720
+ const sCh = ctx._cstChildren;
10721
+ const sLv = ctx._cstLeaves;
10722
+ const sRaw = ctx._cstRawChildren;
10723
+ const sTl = ctx._cstTriviaLog;
10724
+ const sCap = ctx.captureTrivia;
10725
+ const sBuf = ctx._cstBuf;
10726
+ const savedFields = ctx._fields;
10727
+ const kids = [];
10728
+ ctx._cstBuf = void 0;
10729
+ ctx._cstChildren = kids;
10730
+ ctx._cstLeaves = kids;
10731
+ ctx._cstRawChildren = void 0;
10732
+ ctx._cstTriviaLog = void 0;
10733
+ ctx.captureTrivia = false;
10734
+ ctx._fields = void 0;
10735
+ const value = child(input, pos, ctx);
10736
+ const captured = capturedFlatChildren(kids);
10737
+ ctx._fields = savedFields;
10738
+ ctx._cstBuf = sBuf;
10739
+ ctx._cstChildren = sCh;
10740
+ ctx._cstLeaves = sLv;
10741
+ ctx._cstRawChildren = sRaw;
10742
+ ctx._cstTriviaLog = sTl;
10743
+ ctx.captureTrivia = sCap;
10744
+ if (value === FAIL) return FAIL;
10745
+ const end = EC.e;
10746
+ const node2 = captured.length === 1 ? captured[0] : build(captured, void 0, { start: pos, end }, EMPTY_CH, EMPTY_TL2, void 0);
10747
+ if (sBuf !== void 0 || sCh !== void 0) {
10748
+ pushCstChild(ctx, node2, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node2, input, pos, end) : void 0);
10749
+ }
10750
+ EC.e = end;
10751
+ return node2;
10752
+ };
10753
+ }
10754
+ function plainProjectNode(child, projection, type) {
10755
+ return (input, pos, ctx) => {
10756
+ const sCh = ctx._cstChildren;
10757
+ const sLv = ctx._cstLeaves;
10758
+ const sRaw = ctx._cstRawChildren;
10759
+ const sTl = ctx._cstTriviaLog;
10760
+ const sCap = ctx.captureTrivia;
10761
+ const sBuf = ctx._cstBuf;
10762
+ const savedFields = ctx._fields;
10763
+ const buf = {};
10764
+ ctx._cstBuf = buf;
10765
+ ctx._cstChildren = void 0;
10766
+ ctx._cstLeaves = void 0;
10767
+ ctx._cstRawChildren = void 0;
10768
+ ctx._cstTriviaLog = void 0;
10769
+ ctx.captureTrivia = false;
10770
+ ctx._fields = void 0;
10771
+ const value = child(input, pos, ctx);
10772
+ const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
10773
+ ctx._fields = savedFields;
10774
+ ctx._cstBuf = sBuf;
10775
+ ctx._cstChildren = sCh;
10776
+ ctx._cstLeaves = sLv;
10777
+ ctx._cstRawChildren = sRaw;
10778
+ ctx._cstTriviaLog = sTl;
10779
+ ctx.captureTrivia = sCap;
10780
+ if (value === FAIL) return FAIL;
10781
+ const end = EC.e;
10782
+ const node2 = projectChild(kids, projection, type);
10783
+ if (sBuf !== void 0 || sCh !== void 0) {
10784
+ pushCstChild(ctx, node2, rawEntry(node2, input, pos, end));
10785
+ }
10786
+ EC.e = end;
10787
+ return node2;
10788
+ };
10789
+ }
10790
+ function rollbackNeeded(ctx) {
10791
+ 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;
10792
+ }
10793
+ let MRAW = 0;
10794
+ let MTL = 0;
10795
+ let MLV = 0;
10796
+ function markCst(ctx) {
10797
+ const b = ctx._cstBuf;
10798
+ if (b !== void 0) {
10799
+ const raw = b.raw;
10800
+ MRAW = raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
10801
+ const ch2 = b.ch;
10802
+ MLV = ch2 !== void 0 ? ch2.length : b.single !== void 0 ? 1 : 0;
10803
+ const tl = b.tl;
10804
+ MTL = tl !== void 0 ? tl.length : 0;
9015
10805
  return true;
9016
10806
  }
9017
10807
  if (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) {
@@ -9053,9 +10843,7 @@ function assemble(t, prog, cfg) {
9053
10843
  }
9054
10844
  if (s !== null) return skipTriviaScanned(s, input, cur, ctx);
9055
10845
  if (needsDeferredTriviaCommit(ctx)) {
9056
- const scan = scanTrivia(input, cur, ctx);
9057
- scan.commit();
9058
- return scan.end;
10846
+ return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
9059
10847
  }
9060
10848
  return advanceTrivia(input, cur, ctx);
9061
10849
  }
@@ -9093,7 +10881,7 @@ function assemble(t, prog, cfg) {
9093
10881
  if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
9094
10882
  return cur;
9095
10883
  }
9096
- function committed2(c) {
10884
+ function committed3(c) {
9097
10885
  return c._fc === true;
9098
10886
  }
9099
10887
  function accSet(ax, acc) {
@@ -9102,6 +10890,247 @@ function assemble(t, prog, cfg) {
9102
10890
  for (const s of ax) acc.push(s);
9103
10891
  return acc;
9104
10892
  }
10893
+ const NEVER_PIECE = () => FAIL;
10894
+ const NEVER_CLASS = { ascii: new Uint8Array(128), hi: [] };
10895
+ const EMPTY_EXPECTED_PREFIX = (_target, _prev, acc) => acc;
10896
+ function expectedBlock(start, e0, e1, e2, e3, prior) {
10897
+ return (target, prev, acc) => {
10898
+ if (prev < start) {
10899
+ acc = prior(start, prev, acc);
10900
+ prev = start;
10901
+ }
10902
+ if (target > start && prev < start + 1) acc = accSet(e0, acc);
10903
+ if (target > start + 1 && prev < start + 2) acc = accSet(e1, acc);
10904
+ if (target > start + 2 && prev < start + 3) acc = accSet(e2, acc);
10905
+ if (target > start + 3 && prev < start + 4) acc = accSet(e3, acc);
10906
+ return acc;
10907
+ };
10908
+ }
10909
+ function maskedChoiceBlock(start, a0, a1, a2, a3, through, next, total, choiceFx) {
10910
+ return (input, pos, ctx, bits, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best) => {
10911
+ if ((bits & 1 << start) !== 0) {
10912
+ ctx._fc = false;
10913
+ const v = a0(input, pos, ctx);
10914
+ if (v !== FAIL) return v;
10915
+ if (best === pos) acc = through(start, prev, acc);
10916
+ prev = start + 1;
10917
+ const at = ctx._fe ?? pos;
10918
+ if (at > best) {
10919
+ best = at;
10920
+ acc = void 0;
10921
+ }
10922
+ if (at === best) acc = accSet(ctx._fx, acc);
10923
+ if (committed3(ctx)) {
10924
+ if (acc !== void 0) ctx._fx = acc;
10925
+ return FAIL;
10926
+ }
10927
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10928
+ }
10929
+ if ((bits & 1 << start + 1) !== 0) {
10930
+ ctx._fc = false;
10931
+ const v = a1(input, pos, ctx);
10932
+ if (v !== FAIL) return v;
10933
+ if (best === pos) acc = through(start + 1, prev, acc);
10934
+ prev = start + 2;
10935
+ const at = ctx._fe ?? pos;
10936
+ if (at > best) {
10937
+ best = at;
10938
+ acc = void 0;
10939
+ }
10940
+ if (at === best) acc = accSet(ctx._fx, acc);
10941
+ if (committed3(ctx)) {
10942
+ if (acc !== void 0) ctx._fx = acc;
10943
+ return FAIL;
10944
+ }
10945
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10946
+ }
10947
+ if ((bits & 1 << start + 2) !== 0) {
10948
+ ctx._fc = false;
10949
+ const v = a2(input, pos, ctx);
10950
+ if (v !== FAIL) return v;
10951
+ if (best === pos) acc = through(start + 2, prev, acc);
10952
+ prev = start + 3;
10953
+ const at = ctx._fe ?? pos;
10954
+ if (at > best) {
10955
+ best = at;
10956
+ acc = void 0;
10957
+ }
10958
+ if (at === best) acc = accSet(ctx._fx, acc);
10959
+ if (committed3(ctx)) {
10960
+ if (acc !== void 0) ctx._fx = acc;
10961
+ return FAIL;
10962
+ }
10963
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10964
+ }
10965
+ if ((bits & 1 << start + 3) !== 0) {
10966
+ ctx._fc = false;
10967
+ const v = a3(input, pos, ctx);
10968
+ if (v !== FAIL) return v;
10969
+ if (best === pos) acc = through(start + 3, prev, acc);
10970
+ prev = start + 4;
10971
+ const at = ctx._fe ?? pos;
10972
+ if (at > best) {
10973
+ best = at;
10974
+ acc = void 0;
10975
+ }
10976
+ if (at === best) acc = accSet(ctx._fx, acc);
10977
+ if (committed3(ctx)) {
10978
+ if (acc !== void 0) ctx._fx = acc;
10979
+ return FAIL;
10980
+ }
10981
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10982
+ }
10983
+ if (next !== void 0) {
10984
+ return next(input, pos, ctx, bits, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
10985
+ }
10986
+ if (best === pos) acc = through(total, prev, acc);
10987
+ ctx._fe = pos;
10988
+ ctx._fx = acc ?? choiceFx;
10989
+ return FAIL;
10990
+ };
10991
+ }
10992
+ function generalChoiceBlock(start, a0, a1, a2, a3, g0, g1, g2, g3, through, next, total, choiceFx) {
10993
+ return (input, pos, ctx, c, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best) => {
10994
+ if (g0 === null || classHas2(g0, c)) {
10995
+ ctx._fc = false;
10996
+ const v = a0(input, pos, ctx);
10997
+ if (v !== FAIL) return v;
10998
+ if (best === pos) acc = through(start, prev, acc);
10999
+ prev = start + 1;
11000
+ const at = ctx._fe ?? pos;
11001
+ if (at > best) {
11002
+ best = at;
11003
+ acc = void 0;
11004
+ }
11005
+ if (at === best) acc = accSet(ctx._fx, acc);
11006
+ if (committed3(ctx)) {
11007
+ if (acc !== void 0) ctx._fx = acc;
11008
+ return FAIL;
11009
+ }
11010
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
11011
+ }
11012
+ if (g1 === null || classHas2(g1, c)) {
11013
+ ctx._fc = false;
11014
+ const v = a1(input, pos, ctx);
11015
+ if (v !== FAIL) return v;
11016
+ if (best === pos) acc = through(start + 1, prev, acc);
11017
+ prev = start + 2;
11018
+ const at = ctx._fe ?? pos;
11019
+ if (at > best) {
11020
+ best = at;
11021
+ acc = void 0;
11022
+ }
11023
+ if (at === best) acc = accSet(ctx._fx, acc);
11024
+ if (committed3(ctx)) {
11025
+ if (acc !== void 0) ctx._fx = acc;
11026
+ return FAIL;
11027
+ }
11028
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
11029
+ }
11030
+ if (g2 === null || classHas2(g2, c)) {
11031
+ ctx._fc = false;
11032
+ const v = a2(input, pos, ctx);
11033
+ if (v !== FAIL) return v;
11034
+ if (best === pos) acc = through(start + 2, prev, acc);
11035
+ prev = start + 3;
11036
+ const at = ctx._fe ?? pos;
11037
+ if (at > best) {
11038
+ best = at;
11039
+ acc = void 0;
11040
+ }
11041
+ if (at === best) acc = accSet(ctx._fx, acc);
11042
+ if (committed3(ctx)) {
11043
+ if (acc !== void 0) ctx._fx = acc;
11044
+ return FAIL;
11045
+ }
11046
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
11047
+ }
11048
+ if (g3 === null || classHas2(g3, c)) {
11049
+ ctx._fc = false;
11050
+ const v = a3(input, pos, ctx);
11051
+ if (v !== FAIL) return v;
11052
+ if (best === pos) acc = through(start + 3, prev, acc);
11053
+ prev = start + 4;
11054
+ const at = ctx._fe ?? pos;
11055
+ if (at > best) {
11056
+ best = at;
11057
+ acc = void 0;
11058
+ }
11059
+ if (at === best) acc = accSet(ctx._fx, acc);
11060
+ if (committed3(ctx)) {
11061
+ if (acc !== void 0) ctx._fx = acc;
11062
+ return FAIL;
11063
+ }
11064
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
11065
+ }
11066
+ if (next !== void 0) {
11067
+ return next(input, pos, ctx, c, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
11068
+ }
11069
+ if (best === pos) acc = through(total, prev, acc);
11070
+ ctx._fe = pos;
11071
+ ctx._fx = acc ?? choiceFx;
11072
+ return FAIL;
11073
+ };
11074
+ }
11075
+ function exclusiveChoiceBlock(start, a0, a1, a2, a3, next) {
11076
+ return (arm, input, pos, ctx) => {
11077
+ if (arm === start) return a0(input, pos, ctx);
11078
+ if (arm === start + 1) return a1(input, pos, ctx);
11079
+ if (arm === start + 2) return a2(input, pos, ctx);
11080
+ if (arm === start + 3) return a3(input, pos, ctx);
11081
+ return next === void 0 ? FAIL : next(arm, input, pos, ctx);
11082
+ };
11083
+ }
11084
+ function dispatchMatcherBlock(m0, a0, m1, a1, m2, a2, m3, a3, next) {
11085
+ return (key) => {
11086
+ if (m0(key)) return a0;
11087
+ if (m1(key)) return a1;
11088
+ if (m2(key)) return a2;
11089
+ if (m3(key)) return a3;
11090
+ return next?.(key);
11091
+ };
11092
+ }
11093
+ function dispatchBranch(child, usesRouted) {
11094
+ if (!usesRouted) {
11095
+ return (input, _pos, selEnd, key, _selectorMark, ctx) => {
11096
+ const mark = saveTriviaMark(ctx);
11097
+ const v = child(input, selEnd, ctx);
11098
+ if (v === FAIL) {
11099
+ rollbackTrivia(ctx, mark);
11100
+ ctx._fc = true;
11101
+ return FAIL;
11102
+ }
11103
+ return [key, v];
11104
+ };
11105
+ }
11106
+ return (input, pos, selEnd, key, selectorMark, ctx) => {
11107
+ const savedRouted = ctx._routed;
11108
+ rollbackTrivia(ctx, selectorMark);
11109
+ const mark = saveTriviaMark(ctx);
11110
+ ctx._routed = { value: key, span: { start: pos, end: selEnd } };
11111
+ let v;
11112
+ try {
11113
+ v = child(input, pos, ctx);
11114
+ } finally {
11115
+ ctx._routed = savedRouted;
11116
+ }
11117
+ if (v === FAIL) {
11118
+ rollbackTrivia(ctx, mark);
11119
+ ctx._fc = true;
11120
+ return FAIL;
11121
+ }
11122
+ return [key, v];
11123
+ };
11124
+ }
11125
+ function dispatchArmBlock(start, a0, a1, a2, a3, next) {
11126
+ return (arm, input, pos, selEnd, key, selectorMark, ctx) => {
11127
+ if (arm === start) return a0(input, pos, selEnd, key, selectorMark, ctx);
11128
+ if (arm === start + 1) return a1(input, pos, selEnd, key, selectorMark, ctx);
11129
+ if (arm === start + 2) return a2(input, pos, selEnd, key, selectorMark, ctx);
11130
+ if (arm === start + 3) return a3(input, pos, selEnd, key, selectorMark, ctx);
11131
+ return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key, selectorMark, ctx);
11132
+ };
11133
+ }
9105
11134
  function trackLinesInto(ctx, input, end) {
9106
11135
  const from = ctx._lineScannedTo ?? 0;
9107
11136
  if (end <= from) return;
@@ -9137,6 +11166,21 @@ function assemble(t, prog, cfg) {
9137
11166
  const s = k[code[ip + 1]];
9138
11167
  const len = s.length;
9139
11168
  const xf = fx[code[ip + 2]];
11169
+ const shared = rawScalarSpecs.has(code[ip + 1]) ? scalarFor(ip) : void 0;
11170
+ if (shared !== void 0) {
11171
+ return (input, pos, ctx) => {
11172
+ const e = shared(input, pos);
11173
+ if (e >= 0) {
11174
+ if (cstCaptureActive(ctx)) pushLeaf(ctx, s, pos, e);
11175
+ EC.e = e;
11176
+ return s;
11177
+ }
11178
+ ctx._fe = pos;
11179
+ ctx._fx = xf;
11180
+ if (ctx._probe !== void 0) failAt(ctx, xf, pos);
11181
+ return FAIL;
11182
+ };
11183
+ }
9140
11184
  if (len === 1) {
9141
11185
  const c0 = s.charCodeAt(0);
9142
11186
  return (input, pos, ctx) => {
@@ -9264,6 +11308,22 @@ function assemble(t, prog, cfg) {
9264
11308
  case OP_RX: {
9265
11309
  const re = k[code[ip + 1]];
9266
11310
  const xf = fx[code[ip + 2]];
11311
+ const shared = rawScalarSpecs.has(code[ip + 1]) ? scalarFor(ip) : void 0;
11312
+ if (shared !== void 0) {
11313
+ return (input, pos, ctx) => {
11314
+ const e = shared(input, pos);
11315
+ if (e >= 0) {
11316
+ const v = input.slice(pos, e);
11317
+ if (cstCaptureActive(ctx)) pushLeaf(ctx, v, pos, e);
11318
+ EC.e = e;
11319
+ return v;
11320
+ }
11321
+ ctx._fe = pos;
11322
+ ctx._fx = xf;
11323
+ if (ctx._probe !== void 0) failAt(ctx, xf, pos);
11324
+ return FAIL;
11325
+ };
11326
+ }
9267
11327
  return (input, pos, ctx) => {
9268
11328
  re.lastIndex = pos;
9269
11329
  if (re.test(input)) {
@@ -9373,7 +11433,7 @@ function assemble(t, prog, cfg) {
9373
11433
  const child = link(code[ip + 2]);
9374
11434
  if (cfg.tolerant || cfg.probe) return child;
9375
11435
  return (input, pos, ctx) => {
9376
- if (!classHas(cls, lead(input, pos))) {
11436
+ if (!classHas2(cls, lead(input, pos))) {
9377
11437
  ctx._fe = pos;
9378
11438
  ctx._fx = xf;
9379
11439
  return FAIL;
@@ -9572,13 +11632,28 @@ function assemble(t, prog, cfg) {
9572
11632
  const v = child(input, pos, ctx);
9573
11633
  if (v !== FAIL) return v;
9574
11634
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
9575
- if (committed2(ctx)) return FAIL;
11635
+ if (committed3(ctx)) return FAIL;
9576
11636
  ctx._fe = pos;
9577
11637
  return FAIL;
9578
11638
  };
9579
11639
  }
9580
11640
  /* ── zero-width ──────────────────────────────────────────────────────── */
9581
11641
  case OP_NOT: {
11642
+ const scalarChild = scalarTerminalNotChild(code, ip);
11643
+ if (scalarChild >= 0) {
11644
+ const recognize = scalarFor(scalarChild);
11645
+ const xf2 = fx[code[ip + 2]];
11646
+ return (input, pos, ctx) => {
11647
+ if (recognize(input, pos) < 0) {
11648
+ EC.e = pos;
11649
+ return null;
11650
+ }
11651
+ ctx._fe = pos;
11652
+ ctx._fx = xf2;
11653
+ EC.e = pos;
11654
+ return FAIL;
11655
+ };
11656
+ }
9582
11657
  const child = link(code[ip + 1]);
9583
11658
  const xf = fx[code[ip + 2]];
9584
11659
  return (input, pos, ctx) => {
@@ -9638,7 +11713,7 @@ function assemble(t, prog, cfg) {
9638
11713
  ctx._fc = false;
9639
11714
  const v = child(input, pos, ctx);
9640
11715
  if (v === FAIL) {
9641
- if (committed2(ctx)) return FAIL;
11716
+ if (committed3(ctx)) return FAIL;
9642
11717
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
9643
11718
  EC.e = pos;
9644
11719
  return null;
@@ -9689,6 +11764,92 @@ function assemble(t, prog, cfg) {
9689
11764
  return value;
9690
11765
  };
9691
11766
  }
11767
+ case OP_LEX_BODY: {
11768
+ const recognize = t.lex[code[ip + 1]];
11769
+ const expected = fx[code[ip + 2]];
11770
+ return (input, pos, ctx) => {
11771
+ const recognized = recognize(input, pos);
11772
+ if (recognized < 0) {
11773
+ ctx._fe = pos;
11774
+ ctx._fx = expected;
11775
+ if (ctx._probe !== void 0) failAt(ctx, expected, pos);
11776
+ return FAIL;
11777
+ }
11778
+ const lineFlags = code[ip + 4];
11779
+ const hasSuffix = (lineFlags & 4) !== 0;
11780
+ const suffixMatched = hasSuffix && recognized % 2 === 1;
11781
+ const end = (recognized - (suffixMatched ? 1 : 0)) / 2;
11782
+ if ((lineFlags & 1) !== 0) {
11783
+ trackLinesInto(ctx, input, suffixMatched ? end - 1 : end);
11784
+ }
11785
+ if (hasSuffix) ctx._fc = false;
11786
+ if (hasSuffix && suffixMatched && (lineFlags & 2) !== 0) {
11787
+ trackLinesInto(ctx, input, end);
11788
+ }
11789
+ if (hasSuffix && !suffixMatched) {
11790
+ const suffixExpected = fx[code[ip + 3]];
11791
+ ctx._fe = end;
11792
+ ctx._fx = suffixExpected;
11793
+ if (ctx._probe !== void 0) failAt(ctx, suffixExpected, end);
11794
+ }
11795
+ const value = input.slice(pos, end);
11796
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
11797
+ EC.e = end;
11798
+ return value;
11799
+ };
11800
+ }
11801
+ case OP_LEX_PROGRAM: {
11802
+ const run3 = t.lexPrograms[code[ip + 1]];
11803
+ const scanId = run3.scan;
11804
+ if (scanId !== void 0) {
11805
+ return (input, pos, ctx) => {
11806
+ const sTrivia = ctx.trivia, sKinds = ctx.triviaKindLabels;
11807
+ const sBuf = ctx._cstBuf, sChildren = ctx._cstChildren, sLeaves = ctx._cstLeaves;
11808
+ const sRaw = ctx._cstRawChildren, sTl = ctx._cstTriviaLog;
11809
+ const sOuterTl = ctx._triviaLog, sRootTl = ctx._rootTriviaLog;
11810
+ const wasCapturing = cstCaptureActive(ctx);
11811
+ const sScan = SCAN;
11812
+ SCAN = null;
11813
+ ctx.trivia = void 0;
11814
+ ctx.triviaKindLabels = void 0;
11815
+ ctx._cstBuf = void 0;
11816
+ ctx._cstChildren = void 0;
11817
+ ctx._cstLeaves = void 0;
11818
+ ctx._cstRawChildren = void 0;
11819
+ ctx._cstTriviaLog = void 0;
11820
+ ctx._triviaLog = void 0;
11821
+ ctx._rootTriviaLog = void 0;
11822
+ let end;
11823
+ try {
11824
+ end = run3(input, pos, ctx, scans[scanId]);
11825
+ } finally {
11826
+ SCAN = sScan;
11827
+ ctx.trivia = sTrivia;
11828
+ ctx.triviaKindLabels = sKinds;
11829
+ ctx._cstBuf = sBuf;
11830
+ ctx._cstChildren = sChildren;
11831
+ ctx._cstLeaves = sLeaves;
11832
+ ctx._cstRawChildren = sRaw;
11833
+ ctx._cstTriviaLog = sTl;
11834
+ ctx._triviaLog = sOuterTl;
11835
+ ctx._rootTriviaLog = sRootTl;
11836
+ }
11837
+ if (end < 0) return FAIL;
11838
+ const value = input.slice(pos, end);
11839
+ if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
11840
+ EC.e = end;
11841
+ return value;
11842
+ };
11843
+ }
11844
+ return (input, pos, ctx) => {
11845
+ const end = run3(input, pos, ctx);
11846
+ if (end < 0) return FAIL;
11847
+ const value = input.slice(pos, end);
11848
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
11849
+ EC.e = end;
11850
+ return value;
11851
+ };
11852
+ }
9692
11853
  case OP_LEAF: {
9693
11854
  const fn = fns[code[ip + 1]];
9694
11855
  const child = link(code[ip + 2]);
@@ -9729,38 +11890,73 @@ function assemble(t, prog, cfg) {
9729
11890
  const fused = op === OP_SEQX;
9730
11891
  const base = fused ? ip + 3 : ip + 2;
9731
11892
  const n = code[fused ? ip + 2 : ip + 1];
9732
- const kids = new Array(n);
9733
- for (let i = 0; i < n; i++) kids[i] = link(code[base + i]);
9734
11893
  const wantValues = op !== OP_SEQV;
9735
- const fn = fused ? fns[code[ip + 1]] : void 0;
9736
- const runTerms = (input, pos, ctx, values) => {
9737
- const v0 = kids[0](input, pos, ctx);
9738
- if (v0 === FAIL) return -1;
9739
- if (values !== void 0) values.push(v0);
9740
- let cur = EC.e;
9741
- for (let i = 1; i < n; i++) {
9742
- cur = nextTerm(kids[i], input, cur, ctx);
11894
+ const reducer = fused ? code[ip + 1] : -1;
11895
+ const projection = reducer < 0 ? ~reducer : -1;
11896
+ const fn = fused && projection < 0 ? fns[reducer] : void 0;
11897
+ const runnerBlock = (count, r0, r1, r2, r3, next) => {
11898
+ if (count === 1) return (input, cur, ctx, values, inherited) => {
11899
+ cur = r0(input, cur, ctx, inherited);
9743
11900
  if (cur < 0) return -1;
9744
11901
  if (values !== void 0) values.push(TERMV);
9745
- }
9746
- return cur;
11902
+ return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
11903
+ };
11904
+ if (count === 2) return (input, cur, ctx, values, inherited) => {
11905
+ cur = r0(input, cur, ctx, inherited);
11906
+ if (cur < 0) return -1;
11907
+ if (values !== void 0) values.push(TERMV);
11908
+ cur = r1(input, cur, ctx, inherited);
11909
+ if (cur < 0) return -1;
11910
+ if (values !== void 0) values.push(TERMV);
11911
+ return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
11912
+ };
11913
+ if (count === 3) return (input, cur, ctx, values, inherited) => {
11914
+ cur = r0(input, cur, ctx, inherited);
11915
+ if (cur < 0) return -1;
11916
+ if (values !== void 0) values.push(TERMV);
11917
+ cur = r1(input, cur, ctx, inherited);
11918
+ if (cur < 0) return -1;
11919
+ if (values !== void 0) values.push(TERMV);
11920
+ cur = r2(input, cur, ctx, inherited);
11921
+ if (cur < 0) return -1;
11922
+ if (values !== void 0) values.push(TERMV);
11923
+ return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
11924
+ };
11925
+ return (input, cur, ctx, values, inherited) => {
11926
+ cur = r0(input, cur, ctx, inherited);
11927
+ if (cur < 0) return -1;
11928
+ if (values !== void 0) values.push(TERMV);
11929
+ cur = r1(input, cur, ctx, inherited);
11930
+ if (cur < 0) return -1;
11931
+ if (values !== void 0) values.push(TERMV);
11932
+ cur = r2(input, cur, ctx, inherited);
11933
+ if (cur < 0) return -1;
11934
+ if (values !== void 0) values.push(TERMV);
11935
+ cur = r3(input, cur, ctx, inherited);
11936
+ if (cur < 0) return -1;
11937
+ if (values !== void 0) values.push(TERMV);
11938
+ return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
11939
+ };
9747
11940
  };
9748
11941
  if (REC2) {
9749
- const syncs = new Array(n);
9750
- for (let i = 0; i < n; i++) syncs[i] = sentinelFor(code[base + n + i]);
9751
- const runners = new Array(n);
9752
- for (let i = 1; i < n; i++) {
11942
+ const first2 = link(code[base]);
11943
+ const firstSync = sentinelFor(code[base + n]);
11944
+ const runnerAt = (i) => {
11945
+ const sync = sentinelFor(code[base + n + i]);
9753
11946
  const kidIp = code[base + i];
9754
11947
  if (code[kidIp] !== OP_ADJ) {
9755
- const kid = kids[i];
9756
- runners[i] = (input, cur, ctx) => nextTerm(kid, input, cur, ctx);
9757
- continue;
11948
+ const kid = link(kidIp);
11949
+ return (input, cur, ctx, inherited) => {
11950
+ ctx._sync = sync ?? inherited;
11951
+ return nextTerm(kid, input, cur, ctx);
11952
+ };
9758
11953
  }
9759
11954
  const negated = code[kidIp + 1] === 1;
9760
11955
  const ki = code[kidIp + 2];
9761
11956
  const kinds = ki < 0 ? void 0 : k[ki];
9762
11957
  const xf = fx[code[kidIp + 3]];
9763
- runners[i] = (input, cur, ctx) => {
11958
+ return (input, cur, ctx, inherited) => {
11959
+ ctx._sync = sync ?? inherited;
9764
11960
  if (!adjacencyHolds(input, cur, ctx, negated, kinds)) {
9765
11961
  ctx._fe = cur;
9766
11962
  ctx._fx = xf;
@@ -9769,25 +11965,34 @@ function assemble(t, prog, cfg) {
9769
11965
  TERMV = null;
9770
11966
  return cur;
9771
11967
  };
9772
- }
11968
+ };
11969
+ const bindRunners = (start) => {
11970
+ const count = Math.min(4, n - start);
11971
+ const at = (offset) => runnerAt(start + offset);
11972
+ const never = () => -1;
11973
+ return runnerBlock(
11974
+ count,
11975
+ at(0),
11976
+ count > 1 ? at(1) : never,
11977
+ count > 2 ? at(2) : never,
11978
+ count > 3 ? at(3) : never,
11979
+ start + count < n ? bindRunners(start + count) : void 0
11980
+ );
11981
+ };
11982
+ const tail2 = n > 1 ? bindRunners(1) : void 0;
9773
11983
  const runSyncTerms = (input, pos, ctx, values) => {
9774
11984
  const inherited = ctx._sync;
9775
- ctx._sync = syncs[0] ?? inherited;
9776
- const v0 = kids[0](input, pos, ctx);
11985
+ ctx._sync = firstSync ?? inherited;
11986
+ const v0 = first2(input, pos, ctx);
9777
11987
  if (v0 === FAIL) {
9778
11988
  ctx._sync = inherited;
9779
11989
  return -1;
9780
11990
  }
9781
11991
  if (values !== void 0) values.push(v0);
9782
- let cur = EC.e;
9783
- for (let i = 1; i < n; i++) {
9784
- ctx._sync = syncs[i] ?? inherited;
9785
- cur = runners[i](input, cur, ctx);
9786
- if (cur < 0) {
9787
- ctx._sync = inherited;
9788
- return -1;
9789
- }
9790
- if (values !== void 0) values.push(TERMV);
11992
+ const cur = tail2 === void 0 ? EC.e : tail2(input, EC.e, ctx, values, inherited);
11993
+ if (cur < 0) {
11994
+ ctx._sync = inherited;
11995
+ return -1;
9791
11996
  }
9792
11997
  ctx._sync = inherited;
9793
11998
  return cur;
@@ -9798,7 +12003,7 @@ function assemble(t, prog, cfg) {
9798
12003
  const cur = runSyncTerms(input, pos, ctx, values);
9799
12004
  if (cur < 0) return FAIL;
9800
12005
  EC.e = cur;
9801
- return fn(values, { start: pos, end: cur });
12006
+ return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
9802
12007
  };
9803
12008
  }
9804
12009
  if (wantValues) {
@@ -9823,19 +12028,18 @@ function assemble(t, prog, cfg) {
9823
12028
  break;
9824
12029
  }
9825
12030
  if (hasAdj) {
9826
- const runners = new Array(n);
9827
- for (let i = 1; i < n; i++) {
12031
+ const first2 = link(code[base]);
12032
+ const runnerAt = (i) => {
9828
12033
  const kidIp = code[base + i];
9829
12034
  if (code[kidIp] !== OP_ADJ) {
9830
- const kid = kids[i];
9831
- runners[i] = (input, cur, ctx) => nextTerm(kid, input, cur, ctx);
9832
- continue;
12035
+ const kid = link(kidIp);
12036
+ return (input, cur, ctx) => nextTerm(kid, input, cur, ctx);
9833
12037
  }
9834
12038
  const negated = code[kidIp + 1] === 1;
9835
12039
  const ki = code[kidIp + 2];
9836
12040
  const kinds = ki < 0 ? void 0 : k[ki];
9837
12041
  const xf = fx[code[kidIp + 3]];
9838
- runners[i] = (input, cur, ctx) => {
12042
+ return (input, cur, ctx) => {
9839
12043
  if (!adjacencyHolds(input, cur, ctx, negated, kinds)) {
9840
12044
  ctx._fe = cur;
9841
12045
  ctx._fx = xf;
@@ -9844,18 +12048,26 @@ function assemble(t, prog, cfg) {
9844
12048
  TERMV = null;
9845
12049
  return cur;
9846
12050
  };
9847
- }
12051
+ };
12052
+ const bindRunners = (start) => {
12053
+ const count = Math.min(4, n - start);
12054
+ const at = (offset) => runnerAt(start + offset);
12055
+ const never = () => -1;
12056
+ return runnerBlock(
12057
+ count,
12058
+ at(0),
12059
+ count > 1 ? at(1) : never,
12060
+ count > 2 ? at(2) : never,
12061
+ count > 3 ? at(3) : never,
12062
+ start + count < n ? bindRunners(start + count) : void 0
12063
+ );
12064
+ };
12065
+ const tail2 = bindRunners(1);
9848
12066
  const runAdjTerms = (input, pos, ctx, values) => {
9849
- const v0 = kids[0](input, pos, ctx);
12067
+ const v0 = first2(input, pos, ctx);
9850
12068
  if (v0 === FAIL) return -1;
9851
12069
  if (values !== void 0) values.push(v0);
9852
- let cur = EC.e;
9853
- for (let i = 1; i < n; i++) {
9854
- cur = runners[i](input, cur, ctx);
9855
- if (cur < 0) return -1;
9856
- if (values !== void 0) values.push(TERMV);
9857
- }
9858
- return cur;
12070
+ return tail2(input, EC.e, ctx, values);
9859
12071
  };
9860
12072
  if (fused) {
9861
12073
  return (input, pos, ctx) => {
@@ -9863,7 +12075,7 @@ function assemble(t, prog, cfg) {
9863
12075
  const cur = runAdjTerms(input, pos, ctx, values);
9864
12076
  if (cur < 0) return FAIL;
9865
12077
  EC.e = cur;
9866
- return fn(values, { start: pos, end: cur });
12078
+ return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
9867
12079
  };
9868
12080
  }
9869
12081
  if (wantValues) {
@@ -9883,12 +12095,12 @@ function assemble(t, prog, cfg) {
9883
12095
  };
9884
12096
  }
9885
12097
  if (n === 1) {
9886
- const k0 = kids[0];
12098
+ const k0 = link(code[base]);
9887
12099
  if (fused) {
9888
12100
  return (input, pos, ctx) => {
9889
12101
  const v = k0(input, pos, ctx);
9890
12102
  if (v === FAIL) return FAIL;
9891
- return fn([v], { start: pos, end: EC.e });
12103
+ return projection === 0 ? v : fn([v], { start: pos, end: EC.e });
9892
12104
  };
9893
12105
  }
9894
12106
  if (wantValues) {
@@ -9905,7 +12117,7 @@ function assemble(t, prog, cfg) {
9905
12117
  };
9906
12118
  }
9907
12119
  if (n === 2) {
9908
- const k0 = kids[0], k1 = kids[1];
12120
+ const k0 = link(code[base]), k1 = link(code[base + 1]);
9909
12121
  if (fused) {
9910
12122
  return (input, pos, ctx) => {
9911
12123
  const v0 = k0(input, pos, ctx);
@@ -9913,7 +12125,7 @@ function assemble(t, prog, cfg) {
9913
12125
  const cur = nextTerm(k1, input, EC.e, ctx);
9914
12126
  if (cur < 0) return FAIL;
9915
12127
  EC.e = cur;
9916
- return fn([v0, TERMV], { start: pos, end: cur });
12128
+ return projection === 0 ? v0 : projection === 1 ? TERMV : fn([v0, TERMV], { start: pos, end: cur });
9917
12129
  };
9918
12130
  }
9919
12131
  if (wantValues) {
@@ -9936,7 +12148,7 @@ function assemble(t, prog, cfg) {
9936
12148
  };
9937
12149
  }
9938
12150
  if (n === 3) {
9939
- const k0 = kids[0], k1 = kids[1], k2 = kids[2];
12151
+ const k0 = link(code[base]), k1 = link(code[base + 1]), k2 = link(code[base + 2]);
9940
12152
  if (fused) {
9941
12153
  return (input, pos, ctx) => {
9942
12154
  const v0 = k0(input, pos, ctx);
@@ -9947,7 +12159,7 @@ function assemble(t, prog, cfg) {
9947
12159
  cur = nextTerm(k2, input, cur, ctx);
9948
12160
  if (cur < 0) return FAIL;
9949
12161
  EC.e = cur;
9950
- return fn([v0, v1, TERMV], { start: pos, end: cur });
12162
+ return projection === 0 ? v0 : projection === 1 ? v1 : projection === 2 ? TERMV : fn([v0, v1, TERMV], { start: pos, end: cur });
9951
12163
  };
9952
12164
  }
9953
12165
  if (wantValues) {
@@ -9974,26 +12186,90 @@ function assemble(t, prog, cfg) {
9974
12186
  return void 0;
9975
12187
  };
9976
12188
  }
12189
+ const block = (count, k0, k1, k2, k3, next) => {
12190
+ if (count === 1) return (input, cur, ctx, values) => {
12191
+ cur = nextTerm(k0, input, cur, ctx);
12192
+ if (cur < 0) return -1;
12193
+ if (values !== void 0) values.push(TERMV);
12194
+ return next === void 0 ? cur : next(input, cur, ctx, values);
12195
+ };
12196
+ if (count === 2) return (input, cur, ctx, values) => {
12197
+ cur = nextTerm(k0, input, cur, ctx);
12198
+ if (cur < 0) return -1;
12199
+ if (values !== void 0) values.push(TERMV);
12200
+ cur = nextTerm(k1, input, cur, ctx);
12201
+ if (cur < 0) return -1;
12202
+ if (values !== void 0) values.push(TERMV);
12203
+ return next === void 0 ? cur : next(input, cur, ctx, values);
12204
+ };
12205
+ if (count === 3) return (input, cur, ctx, values) => {
12206
+ cur = nextTerm(k0, input, cur, ctx);
12207
+ if (cur < 0) return -1;
12208
+ if (values !== void 0) values.push(TERMV);
12209
+ cur = nextTerm(k1, input, cur, ctx);
12210
+ if (cur < 0) return -1;
12211
+ if (values !== void 0) values.push(TERMV);
12212
+ cur = nextTerm(k2, input, cur, ctx);
12213
+ if (cur < 0) return -1;
12214
+ if (values !== void 0) values.push(TERMV);
12215
+ return next === void 0 ? cur : next(input, cur, ctx, values);
12216
+ };
12217
+ return (input, cur, ctx, values) => {
12218
+ cur = nextTerm(k0, input, cur, ctx);
12219
+ if (cur < 0) return -1;
12220
+ if (values !== void 0) values.push(TERMV);
12221
+ cur = nextTerm(k1, input, cur, ctx);
12222
+ if (cur < 0) return -1;
12223
+ if (values !== void 0) values.push(TERMV);
12224
+ cur = nextTerm(k2, input, cur, ctx);
12225
+ if (cur < 0) return -1;
12226
+ if (values !== void 0) values.push(TERMV);
12227
+ cur = nextTerm(k3, input, cur, ctx);
12228
+ if (cur < 0) return -1;
12229
+ if (values !== void 0) values.push(TERMV);
12230
+ return next === void 0 ? cur : next(input, cur, ctx, values);
12231
+ };
12232
+ };
12233
+ const bind = (start) => {
12234
+ const count = Math.min(4, n - start);
12235
+ const child = (offset) => link(code[base + start + offset]);
12236
+ return block(
12237
+ count,
12238
+ child(0),
12239
+ count > 1 ? child(1) : NEVER_PIECE,
12240
+ count > 2 ? child(2) : NEVER_PIECE,
12241
+ count > 3 ? child(3) : NEVER_PIECE,
12242
+ start + count < n ? bind(start + count) : void 0
12243
+ );
12244
+ };
12245
+ const first = link(code[base]);
12246
+ const tail = bind(1);
12247
+ const runDirectTerms = (input, pos, ctx, values) => {
12248
+ const v0 = first(input, pos, ctx);
12249
+ if (v0 === FAIL) return -1;
12250
+ if (values !== void 0) values.push(v0);
12251
+ return tail(input, EC.e, ctx, values);
12252
+ };
9977
12253
  if (fused) {
9978
12254
  return (input, pos, ctx) => {
9979
12255
  const values = [];
9980
- const cur = runTerms(input, pos, ctx, values);
12256
+ const cur = runDirectTerms(input, pos, ctx, values);
9981
12257
  if (cur < 0) return FAIL;
9982
12258
  EC.e = cur;
9983
- return fn(values, { start: pos, end: cur });
12259
+ return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
9984
12260
  };
9985
12261
  }
9986
12262
  if (wantValues) {
9987
12263
  return (input, pos, ctx) => {
9988
12264
  const values = [];
9989
- const cur = runTerms(input, pos, ctx, values);
12265
+ const cur = runDirectTerms(input, pos, ctx, values);
9990
12266
  if (cur < 0) return FAIL;
9991
12267
  EC.e = cur;
9992
12268
  return values;
9993
12269
  };
9994
12270
  }
9995
12271
  return (input, pos, ctx) => {
9996
- const cur = runTerms(input, pos, ctx, void 0);
12272
+ const cur = runDirectTerms(input, pos, ctx, void 0);
9997
12273
  if (cur < 0) return FAIL;
9998
12274
  EC.e = cur;
9999
12275
  return void 0;
@@ -10005,13 +12281,86 @@ function assemble(t, prog, cfg) {
10005
12281
  const n = code[ip + 2];
10006
12282
  const choiceFx = fx[code[ip + 3]];
10007
12283
  const base = ip + 4;
10008
- const arms = new Array(n);
10009
- for (let i = 0; i < n; i++) arms[i] = link(code[base + i]);
10010
- const armFx = new Array(n);
10011
- for (let i = 0; i < n; i++) armFx[i] = fx[code[base + n + i]];
10012
12284
  if (table.exclusive) {
10013
12285
  const ascii = table.ascii;
10014
12286
  const hi = table.hi;
12287
+ if (n === 2) {
12288
+ const a0 = link(code[base]), a1 = link(code[base + 1]);
12289
+ return (input, pos, ctx) => {
12290
+ const c = lead(input, pos);
12291
+ let arm = -1;
12292
+ if (c >= 0 && c < 128) {
12293
+ const a = ascii[c];
12294
+ if (a !== 0) arm = a - 1;
12295
+ } else if (c >= 128) {
12296
+ for (let i = 0; i < hi.length; i += 3) {
12297
+ if (c >= hi[i] && c <= hi[i + 1]) {
12298
+ arm = hi[i + 2];
12299
+ break;
12300
+ }
12301
+ }
12302
+ }
12303
+ if (arm >= 0) {
12304
+ ctx._fc = false;
12305
+ const v = arm === 0 ? a0(input, pos, ctx) : a1(input, pos, ctx);
12306
+ if (v !== FAIL) return v;
12307
+ if (committed3(ctx)) return FAIL;
12308
+ const failed = ctx._fx;
12309
+ if (failed !== void 0 && failed.length > 0) {
12310
+ ctx._fe = pos;
12311
+ return FAIL;
12312
+ }
12313
+ }
12314
+ ctx._fe = pos;
12315
+ ctx._fx = choiceFx;
12316
+ return FAIL;
12317
+ };
12318
+ }
12319
+ if (n === 3) {
12320
+ const a0 = link(code[base]), a1 = link(code[base + 1]), a2 = link(code[base + 2]);
12321
+ return (input, pos, ctx) => {
12322
+ const c = lead(input, pos);
12323
+ let arm = -1;
12324
+ if (c >= 0 && c < 128) {
12325
+ const a = ascii[c];
12326
+ if (a !== 0) arm = a - 1;
12327
+ } else if (c >= 128) {
12328
+ for (let i = 0; i < hi.length; i += 3) {
12329
+ if (c >= hi[i] && c <= hi[i + 1]) {
12330
+ arm = hi[i + 2];
12331
+ break;
12332
+ }
12333
+ }
12334
+ }
12335
+ if (arm >= 0) {
12336
+ ctx._fc = false;
12337
+ const v = arm === 0 ? a0(input, pos, ctx) : arm === 1 ? a1(input, pos, ctx) : a2(input, pos, ctx);
12338
+ if (v !== FAIL) return v;
12339
+ if (committed3(ctx)) return FAIL;
12340
+ const failed = ctx._fx;
12341
+ if (failed !== void 0 && failed.length > 0) {
12342
+ ctx._fe = pos;
12343
+ return FAIL;
12344
+ }
12345
+ }
12346
+ ctx._fe = pos;
12347
+ ctx._fx = choiceFx;
12348
+ return FAIL;
12349
+ };
12350
+ }
12351
+ const bindExclusive = (start) => {
12352
+ const at = (i) => i < n ? link(code[base + i]) : NEVER_PIECE;
12353
+ const next = start + 4 < n ? bindExclusive(start + 4) : void 0;
12354
+ return exclusiveChoiceBlock(
12355
+ start,
12356
+ at(start),
12357
+ at(start + 1),
12358
+ at(start + 2),
12359
+ at(start + 3),
12360
+ next
12361
+ );
12362
+ };
12363
+ const selected = bindExclusive(0);
10015
12364
  return (input, pos, ctx) => {
10016
12365
  const c = lead(input, pos);
10017
12366
  let arm = -1;
@@ -10028,11 +12377,11 @@ function assemble(t, prog, cfg) {
10028
12377
  }
10029
12378
  if (arm >= 0) {
10030
12379
  ctx._fc = false;
10031
- const v = arms[arm](input, pos, ctx);
12380
+ const v = selected(arm, input, pos, ctx);
10032
12381
  if (v !== FAIL) return v;
10033
- if (committed2(ctx)) return FAIL;
10034
- const armFx2 = ctx._fx;
10035
- if (armFx2 !== void 0 && armFx2.length > 0) {
12382
+ if (committed3(ctx)) return FAIL;
12383
+ const armFx = ctx._fx;
12384
+ if (armFx !== void 0 && armFx.length > 0) {
10036
12385
  ctx._fe = pos;
10037
12386
  return FAIL;
10038
12387
  }
@@ -10043,25 +12392,25 @@ function assemble(t, prog, cfg) {
10043
12392
  };
10044
12393
  }
10045
12394
  const armCls = table.armCls;
10046
- const gates = new Array(n);
10047
- for (let i = 0; i < n; i++) gates[i] = armCls[i] ?? null;
10048
- const maskable = n <= 32;
10049
- let cand;
10050
- if (maskable) {
10051
- const m = new Uint32Array(129);
10052
- for (let i = 0; i < n; i++) {
10053
- const cls = gates[i];
10054
- const bit = 1 << i;
12395
+ if (n === 2 || n === 3) {
12396
+ const a0 = link(code[base]), a1 = link(code[base + 1]);
12397
+ const a2 = n === 3 ? link(code[base + 2]) : void 0;
12398
+ const e0 = fx[code[base + n]];
12399
+ const e1 = fx[code[base + n + 1]];
12400
+ const e2 = n === 3 ? fx[code[base + n + 2]] : void 0;
12401
+ const g0 = armCls[0] ?? null, g1 = armCls[1] ?? null;
12402
+ const g2 = n === 3 ? armCls[2] ?? null : null;
12403
+ const mask = new Uint32Array(129);
12404
+ const addGate = (cls, bit) => {
10055
12405
  if (cls === null) {
10056
- for (let c = 0; c < 129; c++) m[c] |= bit;
10057
- continue;
12406
+ for (let c = 0; c < 129; c++) mask[c] |= bit;
12407
+ return;
10058
12408
  }
10059
- for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) m[c] |= bit;
10060
- }
10061
- cand = m;
10062
- }
10063
- if (cand !== void 0) {
10064
- const mask = cand;
12409
+ for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) mask[c] |= bit;
12410
+ };
12411
+ addGate(g0, 1);
12412
+ addGate(g1, 2);
12413
+ if (n === 3) addGate(g2, 4);
10065
12414
  return (input, pos, ctx) => {
10066
12415
  const c = lead(input, pos);
10067
12416
  const need = markCst(ctx);
@@ -10073,51 +12422,240 @@ function assemble(t, prog, cfg) {
10073
12422
  const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
10074
12423
  const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
10075
12424
  let acc;
12425
+ let best = pos;
10076
12426
  if (c < 128) {
10077
- const bits0 = mask[c < 0 ? 128 : c];
10078
- let bits = bits0;
12427
+ const bits = mask[c < 0 ? 128 : c];
10079
12428
  let prev = 0;
10080
- while (bits !== 0) {
10081
- const i = 31 - Math.clz32(bits & -bits);
10082
- bits &= bits - 1;
12429
+ if ((bits & 1) !== 0) {
10083
12430
  ctx._fc = false;
10084
- const v = arms[i](input, pos, ctx);
12431
+ const v = a0(input, pos, ctx);
10085
12432
  if (v !== FAIL) return v;
10086
- for (let j = prev; j < i; j++) if ((bits0 & 1 << j) === 0) acc = accSet(armFx[j], acc);
10087
- prev = i + 1;
10088
- acc = accSet(ctx._fx, acc);
10089
- if (committed2(ctx)) {
12433
+ prev = 1;
12434
+ const at = ctx._fe ?? pos;
12435
+ if (at > best) {
12436
+ best = at;
12437
+ acc = void 0;
12438
+ }
12439
+ if (at === best) acc = accSet(ctx._fx, acc);
12440
+ if (committed3(ctx)) {
10090
12441
  if (acc !== void 0) ctx._fx = acc;
10091
12442
  return FAIL;
10092
12443
  }
10093
12444
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10094
12445
  }
10095
- for (let j = prev; j < n; j++) if ((bits0 & 1 << j) === 0) acc = accSet(armFx[j], acc);
12446
+ if ((bits & 2) !== 0) {
12447
+ ctx._fc = false;
12448
+ const v = a1(input, pos, ctx);
12449
+ if (v !== FAIL) return v;
12450
+ if (best === pos && prev < 1) acc = accSet(e0, acc);
12451
+ prev = 2;
12452
+ const at = ctx._fe ?? pos;
12453
+ if (at > best) {
12454
+ best = at;
12455
+ acc = void 0;
12456
+ }
12457
+ if (at === best) acc = accSet(ctx._fx, acc);
12458
+ if (committed3(ctx)) {
12459
+ if (acc !== void 0) ctx._fx = acc;
12460
+ return FAIL;
12461
+ }
12462
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12463
+ }
12464
+ if (n === 3 && (bits & 4) !== 0) {
12465
+ ctx._fc = false;
12466
+ const v = a2(input, pos, ctx);
12467
+ if (v !== FAIL) return v;
12468
+ if (best === pos && prev < 1) acc = accSet(e0, acc);
12469
+ if (best === pos && prev < 2) acc = accSet(e1, acc);
12470
+ prev = 3;
12471
+ const at = ctx._fe ?? pos;
12472
+ if (at > best) {
12473
+ best = at;
12474
+ acc = void 0;
12475
+ }
12476
+ if (at === best) acc = accSet(ctx._fx, acc);
12477
+ if (committed3(ctx)) {
12478
+ if (acc !== void 0) ctx._fx = acc;
12479
+ return FAIL;
12480
+ }
12481
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12482
+ }
12483
+ if (best === pos && prev < 1) acc = accSet(e0, acc);
12484
+ if (best === pos && prev < 2) acc = accSet(e1, acc);
12485
+ if (best === pos && n === 3 && prev < 3) acc = accSet(e2, acc);
10096
12486
  ctx._fe = pos;
10097
12487
  ctx._fx = acc ?? choiceFx;
10098
12488
  return FAIL;
10099
12489
  }
10100
- for (let i = 0; i < n; i++) {
10101
- const cls = gates[i];
10102
- if (cls !== null && !classHas(cls, c)) {
10103
- acc = accSet(armFx[i], acc);
10104
- continue;
12490
+ if (g0 === null || classHas2(g0, c)) {
12491
+ ctx._fc = false;
12492
+ const v = a0(input, pos, ctx);
12493
+ if (v !== FAIL) return v;
12494
+ const at = ctx._fe ?? pos;
12495
+ if (at > best) {
12496
+ best = at;
12497
+ acc = void 0;
10105
12498
  }
12499
+ if (at === best) acc = accSet(ctx._fx, acc);
12500
+ if (committed3(ctx)) {
12501
+ if (acc !== void 0) ctx._fx = acc;
12502
+ return FAIL;
12503
+ }
12504
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12505
+ } else if (best === pos) acc = accSet(e0, acc);
12506
+ if (g1 === null || classHas2(g1, c)) {
10106
12507
  ctx._fc = false;
10107
- const v = arms[i](input, pos, ctx);
12508
+ const v = a1(input, pos, ctx);
10108
12509
  if (v !== FAIL) return v;
10109
- acc = accSet(ctx._fx, acc);
10110
- if (committed2(ctx)) {
12510
+ const at = ctx._fe ?? pos;
12511
+ if (at > best) {
12512
+ best = at;
12513
+ acc = void 0;
12514
+ }
12515
+ if (at === best) acc = accSet(ctx._fx, acc);
12516
+ if (committed3(ctx)) {
10111
12517
  if (acc !== void 0) ctx._fx = acc;
10112
12518
  return FAIL;
10113
12519
  }
10114
12520
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12521
+ } else if (best === pos) acc = accSet(e1, acc);
12522
+ if (n === 3) {
12523
+ if (g2 === null || classHas2(g2, c)) {
12524
+ ctx._fc = false;
12525
+ const v = a2(input, pos, ctx);
12526
+ if (v !== FAIL) return v;
12527
+ const at = ctx._fe ?? pos;
12528
+ if (at > best) {
12529
+ best = at;
12530
+ acc = void 0;
12531
+ }
12532
+ if (at === best) acc = accSet(ctx._fx, acc);
12533
+ if (committed3(ctx)) {
12534
+ if (acc !== void 0) ctx._fx = acc;
12535
+ return FAIL;
12536
+ }
12537
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12538
+ } else if (best === pos) acc = accSet(e2, acc);
10115
12539
  }
10116
12540
  ctx._fe = pos;
10117
12541
  ctx._fx = acc ?? choiceFx;
10118
12542
  return FAIL;
10119
12543
  };
10120
12544
  }
12545
+ const bindGeneral = (start, prior) => {
12546
+ const arm = (i) => i < n ? link(code[base + i]) : NEVER_PIECE;
12547
+ const expected = (i) => i < n ? fx[code[base + n + i]] : EMPTY_FX2;
12548
+ const gate2 = (i) => i < n ? armCls[i] ?? null : NEVER_CLASS;
12549
+ const through = expectedBlock(
12550
+ start,
12551
+ expected(start),
12552
+ expected(start + 1),
12553
+ expected(start + 2),
12554
+ expected(start + 3),
12555
+ prior
12556
+ );
12557
+ const next = start + 4 < n ? bindGeneral(start + 4, through) : void 0;
12558
+ return generalChoiceBlock(
12559
+ start,
12560
+ arm(start),
12561
+ arm(start + 1),
12562
+ arm(start + 2),
12563
+ arm(start + 3),
12564
+ gate2(start),
12565
+ gate2(start + 1),
12566
+ gate2(start + 2),
12567
+ gate2(start + 3),
12568
+ through,
12569
+ next,
12570
+ n,
12571
+ choiceFx
12572
+ );
12573
+ };
12574
+ const general = bindGeneral(0, EMPTY_EXPECTED_PREFIX);
12575
+ if (n <= 32) {
12576
+ const mask = new Uint32Array(129);
12577
+ for (let i = 0; i < n; i++) {
12578
+ const cls = armCls[i] ?? null;
12579
+ const bit = 1 << i;
12580
+ if (cls === null) {
12581
+ for (let c = 0; c < 129; c++) mask[c] |= bit;
12582
+ continue;
12583
+ }
12584
+ for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) mask[c] |= bit;
12585
+ }
12586
+ const bindMasked = (start, prior) => {
12587
+ const arm = (i) => i < n ? link(code[base + i]) : NEVER_PIECE;
12588
+ const expected = (i) => i < n ? fx[code[base + n + i]] : EMPTY_FX2;
12589
+ const through = expectedBlock(
12590
+ start,
12591
+ expected(start),
12592
+ expected(start + 1),
12593
+ expected(start + 2),
12594
+ expected(start + 3),
12595
+ prior
12596
+ );
12597
+ const next = start + 4 < n ? bindMasked(start + 4, through) : void 0;
12598
+ return maskedChoiceBlock(
12599
+ start,
12600
+ arm(start),
12601
+ arm(start + 1),
12602
+ arm(start + 2),
12603
+ arm(start + 3),
12604
+ through,
12605
+ next,
12606
+ n,
12607
+ choiceFx
12608
+ );
12609
+ };
12610
+ const masked = bindMasked(0, EMPTY_EXPECTED_PREFIX);
12611
+ return (input, pos, ctx) => {
12612
+ const c = lead(input, pos);
12613
+ const need = markCst(ctx);
12614
+ const mRaw = MRAW;
12615
+ const mTl = MTL;
12616
+ const mLv = MLV;
12617
+ const mFl = need ? ctx._fields?.length ?? 0 : 0;
12618
+ const mEr = need ? ctx._errors?.length ?? 0 : 0;
12619
+ const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
12620
+ const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
12621
+ if (c < 128) {
12622
+ return masked(
12623
+ input,
12624
+ pos,
12625
+ ctx,
12626
+ mask[c < 0 ? 128 : c],
12627
+ need,
12628
+ mRaw,
12629
+ mTl,
12630
+ mLv,
12631
+ mFl,
12632
+ mEr,
12633
+ mLog,
12634
+ mRoot,
12635
+ void 0,
12636
+ 0,
12637
+ pos
12638
+ );
12639
+ }
12640
+ return general(
12641
+ input,
12642
+ pos,
12643
+ ctx,
12644
+ c,
12645
+ need,
12646
+ mRaw,
12647
+ mTl,
12648
+ mLv,
12649
+ mFl,
12650
+ mEr,
12651
+ mLog,
12652
+ mRoot,
12653
+ void 0,
12654
+ 0,
12655
+ pos
12656
+ );
12657
+ };
12658
+ }
10121
12659
  return (input, pos, ctx) => {
10122
12660
  const c = lead(input, pos);
10123
12661
  const need = markCst(ctx);
@@ -10128,26 +12666,23 @@ function assemble(t, prog, cfg) {
10128
12666
  const mEr = need ? ctx._errors?.length ?? 0 : 0;
10129
12667
  const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
10130
12668
  const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
10131
- let acc;
10132
- for (let i = 0; i < n; i++) {
10133
- const cls = gates[i];
10134
- if (cls !== null && !classHas(cls, c)) {
10135
- acc = accSet(armFx[i], acc);
10136
- continue;
10137
- }
10138
- ctx._fc = false;
10139
- const v = arms[i](input, pos, ctx);
10140
- if (v !== FAIL) return v;
10141
- acc = accSet(ctx._fx, acc);
10142
- if (committed2(ctx)) {
10143
- if (acc !== void 0) ctx._fx = acc;
10144
- return FAIL;
10145
- }
10146
- if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10147
- }
10148
- ctx._fe = pos;
10149
- ctx._fx = acc ?? choiceFx;
10150
- return FAIL;
12669
+ return general(
12670
+ input,
12671
+ pos,
12672
+ ctx,
12673
+ c,
12674
+ need,
12675
+ mRaw,
12676
+ mTl,
12677
+ mLv,
12678
+ mFl,
12679
+ mEr,
12680
+ mLog,
12681
+ mRoot,
12682
+ void 0,
12683
+ 0,
12684
+ pos
12685
+ );
10151
12686
  };
10152
12687
  }
10153
12688
  /* ── greedyClassify / autoNot ────────────────────────────────────────── */
@@ -10216,7 +12751,7 @@ function assemble(t, prog, cfg) {
10216
12751
  if (nc !== 0) {
10217
12752
  const c = lead(input, end);
10218
12753
  for (let i = 0; i < nc; i++) {
10219
- if (!classHas(clss[i], c)) continue;
12754
+ if (!classHas2(clss[i], c)) continue;
10220
12755
  ctx._fc = false;
10221
12756
  ctx._fx = void 0;
10222
12757
  return FAIL;
@@ -10240,6 +12775,9 @@ function assemble(t, prog, cfg) {
10240
12775
  const reportItem = (flags & 4) !== 0;
10241
12776
  const itemFx = reportItem ? fx[code[ip + 6]] : EMPTY_FX2;
10242
12777
  const collect = op === OP_REP;
12778
+ const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
12779
+ const itemClass = !REC2 && itemClassIndex >= 0 ? cc[itemClassIndex] : void 0;
12780
+ const itemMayStart = itemClass === void 0 ? void 0 : (input, pos) => classHas2(itemClass, lead(input, pos));
10243
12781
  const skipBeforeFirst = sepIp < 0 && min === 0;
10244
12782
  if (REC2) {
10245
12783
  const itemFx2 = fx[code[ip + 6]];
@@ -10273,7 +12811,7 @@ function assemble(t, prog, cfg) {
10273
12811
  const sv = sep(input, sp, ctx);
10274
12812
  if (sv === FAIL) {
10275
12813
  if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10276
- if (committed2(ctx)) return FAIL;
12814
+ if (committed3(ctx)) return FAIL;
10277
12815
  break;
10278
12816
  }
10279
12817
  if (!keepSeparators) demoteCapturedToRaw(ctx, leavesBefore);
@@ -10290,7 +12828,7 @@ function assemble(t, prog, cfg) {
10290
12828
  ctx._fc = false;
10291
12829
  const v = child(input, itemStart, ctx);
10292
12830
  if (v === FAIL) {
10293
- if (committed2(ctx)) {
12831
+ if (committed3(ctx)) {
10294
12832
  if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10295
12833
  return FAIL;
10296
12834
  }
@@ -10336,11 +12874,13 @@ function assemble(t, prog, cfg) {
10336
12874
  const out = collect ? [] : void 0;
10337
12875
  const hasTrivia = ctx.trivia !== void 0;
10338
12876
  const needMark = rollbackNeeded(ctx);
12877
+ const gateItems = itemMayStart !== void 0 && ctx._probe === void 0;
10339
12878
  let cur = pos;
10340
12879
  let count = 0;
10341
12880
  for (; ; ) {
10342
12881
  if (max >= 0 && count >= max) break;
10343
12882
  if (sep !== void 0 && count > 0 && count >= min && cur >= input.length) break;
12883
+ if (count >= min && sep === void 0 && !hasTrivia && gateItems && !itemMayStart(input, cur)) break;
10344
12884
  if (needMark) markCst(ctx);
10345
12885
  const mRaw = needMark ? MRAW : 0;
10346
12886
  const mTl = needMark ? MTL : 0;
@@ -10360,7 +12900,7 @@ function assemble(t, prog, cfg) {
10360
12900
  const sv = sep(input, sp, ctx);
10361
12901
  if (sv === FAIL) {
10362
12902
  if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10363
- if (committed2(ctx)) return FAIL;
12903
+ if (committed3(ctx)) return FAIL;
10364
12904
  break;
10365
12905
  }
10366
12906
  if (!keepSeparators) demoteCapturedToRaw(ctx, leavesBefore);
@@ -10374,11 +12914,16 @@ function assemble(t, prog, cfg) {
10374
12914
  if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
10375
12915
  break;
10376
12916
  }
12917
+ if (count >= min && gateItems && !itemMayStart(input, itemStart)) {
12918
+ if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12919
+ if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
12920
+ break;
12921
+ }
10377
12922
  ctx._fc = false;
10378
12923
  const v = child(input, itemStart, ctx);
10379
12924
  if (v === FAIL) {
10380
12925
  if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10381
- if (committed2(ctx)) return FAIL;
12926
+ if (committed3(ctx)) return FAIL;
10382
12927
  if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
10383
12928
  break;
10384
12929
  }
@@ -10410,78 +12955,103 @@ function assemble(t, prog, cfg) {
10410
12955
  const otherRouted = code[ip + 4] === 1;
10411
12956
  const n = code[ip + 5];
10412
12957
  const armBase = ip + 6;
10413
- const arms = new Array(n);
10414
- for (let i = 0; i < n; i++) arms[i] = link(code[armBase + i]);
10415
12958
  const byKey = spec.byKey;
10416
12959
  const byFold = spec.byFold;
10417
12960
  const hasFold = spec.byFold.size > 0;
10418
12961
  const match = spec.match;
10419
12962
  const matchN = match.length;
10420
- const matchFn = new Array(matchN);
10421
- const matchArm = new Array(matchN);
10422
- for (let i = 0; i < matchN; i++) {
10423
- matchFn[i] = linkMatcher(match[i]);
10424
- matchArm[i] = match[i][3];
10425
- }
10426
12963
  const routed2 = spec.routed;
10427
12964
  const expected = spec.expected;
12965
+ const validArm = (arm) => Number.isInteger(arm) && arm >= 0 && arm < n;
12966
+ if (routed2.length !== n) throw new TypeError("table assembler: malformed dispatch routed arity");
12967
+ for (const arm of byKey.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch exact arm");
12968
+ for (const arm of byFold.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch folded arm");
12969
+ for (const m of match) if (!validArm(m[3])) throw new TypeError("table assembler: malformed dispatch matcher arm");
12970
+ const neverMatch = () => false;
12971
+ const bindMatchers = (start) => {
12972
+ const pred = (i) => i < matchN ? linkMatcher(match[i]) : neverMatch;
12973
+ const arm = (i) => i < matchN ? match[i][3] : -1;
12974
+ const next = start + 4 < matchN ? bindMatchers(start + 4) : void 0;
12975
+ return dispatchMatcherBlock(
12976
+ pred(start),
12977
+ arm(start),
12978
+ pred(start + 1),
12979
+ arm(start + 1),
12980
+ pred(start + 2),
12981
+ arm(start + 2),
12982
+ pred(start + 3),
12983
+ arm(start + 3),
12984
+ next
12985
+ );
12986
+ };
12987
+ const matchBlock = matchN === 0 ? void 0 : bindMatchers(0);
12988
+ 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);
12989
+ const neverBranch = () => FAIL;
12990
+ const bindArms = (start) => {
12991
+ const branch = (i) => i < n ? dispatchBranch(link(code[armBase + i]), routed2[i] === 1) : neverBranch;
12992
+ const next = start + 4 < n ? bindArms(start + 4) : void 0;
12993
+ return dispatchArmBlock(
12994
+ start,
12995
+ branch(start),
12996
+ branch(start + 1),
12997
+ branch(start + 2),
12998
+ branch(start + 3),
12999
+ next
13000
+ );
13001
+ };
13002
+ const runArm = n === 0 ? void 0 : bindArms(0);
13003
+ const runOther = other === void 0 ? void 0 : dispatchBranch(other, otherRouted);
10428
13004
  return (input, pos, ctx) => {
10429
13005
  const selectorMark = saveTriviaMark(ctx);
10430
13006
  const selVal = selector(input, pos, ctx);
10431
13007
  if (selVal === FAIL) return FAIL;
10432
13008
  const selEnd = EC.e;
10433
13009
  const key = selVal;
10434
- let arm = byKey.get(key);
10435
- if (arm === void 0 && hasFold) arm = byFold.get(asciiFoldKey(key));
10436
- if (arm === void 0) {
10437
- for (let i = 0; i < matchN; i++) {
10438
- if (matchFn[i](key)) {
10439
- arm = matchArm[i];
10440
- break;
10441
- }
10442
- }
10443
- }
10444
- let target;
10445
- let usesRouted;
13010
+ const arm = classify(key);
10446
13011
  if (arm === void 0) {
10447
- if (other === void 0) {
13012
+ if (runOther === void 0) {
10448
13013
  ctx._fe = selEnd;
10449
13014
  ctx._fx = expected;
10450
13015
  return FAIL;
10451
13016
  }
10452
- target = other;
10453
- usesRouted = otherRouted;
10454
- } else {
10455
- target = arms[arm];
10456
- usesRouted = routed2[arm] === 1;
10457
- }
10458
- let mark = saveTriviaMark(ctx);
10459
- let v;
10460
- if (usesRouted) {
10461
- const savedRouted = ctx._routed;
10462
- rollbackTrivia(ctx, selectorMark);
10463
- mark = saveTriviaMark(ctx);
10464
- ctx._routed = { value: key, span: { start: pos, end: selEnd } };
10465
- try {
10466
- v = target(input, pos, ctx);
10467
- } finally {
10468
- ctx._routed = savedRouted;
10469
- }
10470
- } else {
10471
- v = target(input, selEnd, ctx);
10472
- }
10473
- if (v === FAIL) {
10474
- rollbackTrivia(ctx, mark);
10475
- ctx._fc = true;
10476
- return FAIL;
13017
+ return runOther(input, pos, selEnd, key, selectorMark, ctx);
10477
13018
  }
10478
- return [key, v];
13019
+ return runArm(arm, input, pos, selEnd, key, selectorMark, ctx);
10479
13020
  };
10480
13021
  }
10481
13022
  /* ── node ────────────────────────────────────────────────────────────── */
10482
13023
  case OP_NODE:
10483
13024
  case OP_NODE_TRACK: {
10484
13025
  const flags = code[ip + 3];
13026
+ const scalarChild = !hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines ? scalarTerminalNodeChild(code, ip) : -1;
13027
+ if (scalarChild >= 0) {
13028
+ const recognize = scalarFor(scalarChild);
13029
+ const spec = k[code[scalarChild + 1]];
13030
+ const regexValue = code[scalarChild] === OP_RX;
13031
+ const xf = fx[code[scalarChild + 2]];
13032
+ const build2 = fns[code[ip + 1]];
13033
+ return (input, pos, ctx) => {
13034
+ const end = recognize(input, pos);
13035
+ if (end < 0) {
13036
+ ctx._fe = pos;
13037
+ ctx._fx = xf;
13038
+ if (ctx._probe !== void 0) failAt(ctx, xf, pos);
13039
+ return FAIL;
13040
+ }
13041
+ const value = regexValue ? input.slice(pos, end) : spec;
13042
+ const leaf2 = { _tag: "leaf", value, span: { start: pos, end } };
13043
+ const kids = [leaf2];
13044
+ const rawKids = [leaf2];
13045
+ const span = { start: pos, end };
13046
+ EC.e = end;
13047
+ const nd = build2(kids, void 0, span, rawKids, EMPTY_TL2, void 0);
13048
+ if (ctx._cstBuf !== void 0 || ctx._cstChildren !== void 0) {
13049
+ pushCstChild(ctx, nd, ctx._cstRawChildren !== void 0 || ctx._cstBuf !== void 0 ? rawEntry(nd, input, pos, end) : void 0);
13050
+ }
13051
+ EC.e = end;
13052
+ return nd;
13053
+ };
13054
+ }
10485
13055
  const child = link(code[ip + 2]);
10486
13056
  const proj = code[ip + 4];
10487
13057
  const buildIdx = code[ip + 1];
@@ -10496,6 +13066,26 @@ function assemble(t, prog, cfg) {
10496
13066
  const unwrap = (flags & 64) !== 0;
10497
13067
  const trailingTrivia = (flags & 128) !== 0;
10498
13068
  const build = buildIdx >= 0 ? fns[buildIdx] : void 0;
13069
+ if (!hostCst && !tracked) {
13070
+ if (build !== void 0 && proj < 0 && flags === 0) {
13071
+ return plainBuildNode(child, build);
13072
+ }
13073
+ if (build !== void 0 && proj < 0 && flags === 2) {
13074
+ return childrenOnlyBuildNode(child, build);
13075
+ }
13076
+ if (build !== void 0 && proj < 0 && flags === 18) {
13077
+ return childrenOnlyFieldsBuildNode(child, build);
13078
+ }
13079
+ if (build !== void 0 && proj < 0 && flags === 32) {
13080
+ return collapseBuildNode(child, build);
13081
+ }
13082
+ if (build !== void 0 && proj < 0 && flags === 34) {
13083
+ return childrenOnlyCollapseBuildNode(child, build);
13084
+ }
13085
+ if (build === void 0 && proj >= 0 && flags === 0) {
13086
+ return plainProjectNode(child, proj, type);
13087
+ }
13088
+ }
10499
13089
  const structural = build === void 0 && proj < 0;
10500
13090
  const grammarCapture = (flags & 1) !== 0 || trailingTrivia;
10501
13091
  const hostCapturesThisType = structural && cfg.hostCaptureTrivia !== void 0 ? cfg.hostCaptureTrivia(type) : void 0;
@@ -10615,14 +13205,27 @@ function assemble(t, prog, cfg) {
10615
13205
  if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
10616
13206
  }
10617
13207
  for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
10618
- const validationRoots = [...Object.values(prog.rules), ...extraIps];
10619
- for (const ip of reachableSites(code, validationRoots)) {
10620
- if (code[ip] !== OP_DISPATCH) continue;
10621
- validateDispatchSpec(dsp[code[ip + 2]], code[ip + 5], code[ip + 4]);
13208
+ const roots = [...Object.values(prog.rules), ...extraIps];
13209
+ for (const ip of reachableSites(code, roots)) {
13210
+ if (code[ip] === OP_DISPATCH) {
13211
+ const spec = dsp[code[ip + 2]];
13212
+ validateDispatchSpec(spec, code[ip + 5], code[ip + 4]);
13213
+ }
13214
+ if (!hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
13215
+ if (code[ip] === OP_NODE) {
13216
+ const child = scalarTerminalNodeChild(code, ip);
13217
+ if (child >= 0) {
13218
+ rawScalarSpecs.add(code[child + 1]);
13219
+ scalarFor(child);
13220
+ }
13221
+ }
13222
+ }
13223
+ const notChild = scalarTerminalNotChild(code, ip);
13224
+ if (notChild >= 0) scalarFor(notChild);
10622
13225
  }
10623
13226
  const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
10624
13227
  if (pre !== void 0) {
10625
- const pools = rebuildPools(t.cc, t.fx, pre.plan);
13228
+ const pools = rebuildPools(t.cc, t.fx, t.disp, pre.plan);
10626
13229
  emitted = pre.factory(
10627
13230
  EC,
10628
13231
  FAIL,
@@ -10648,7 +13251,7 @@ function assemble(t, prog, cfg) {
10648
13251
  rollbackTriviaAt,
10649
13252
  rollbackScannedTriviaAt,
10650
13253
  failAt,
10651
- classHas,
13254
+ classHas2,
10652
13255
  consumeTrivia,
10653
13256
  buildFieldMap,
10654
13257
  projectChild,
@@ -10669,7 +13272,13 @@ function assemble(t, prog, cfg) {
10669
13272
  matchesAt,
10670
13273
  recoverScan,
10671
13274
  orSentinel,
10672
- captureError
13275
+ captureError,
13276
+ scalarRecognizers,
13277
+ commitTriviaScan,
13278
+ scanTriviaCompact,
13279
+ t.lex,
13280
+ adjacencyHolds,
13281
+ t.lexPrograms
10673
13282
  );
10674
13283
  emitReached = new Set(pre.reached);
10675
13284
  }
@@ -10719,7 +13328,7 @@ function assemble(t, prog, cfg) {
10719
13328
  rollbackTriviaAt,
10720
13329
  rollbackScannedTriviaAt,
10721
13330
  failAt,
10722
- classHas,
13331
+ classHas2,
10723
13332
  consumeTrivia,
10724
13333
  buildFieldMap,
10725
13334
  projectChild,
@@ -10745,7 +13354,13 @@ function assemble(t, prog, cfg) {
10745
13354
  matchesAt,
10746
13355
  recoverScan,
10747
13356
  orSentinel,
10748
- captureError
13357
+ captureError,
13358
+ scalarRecognizers,
13359
+ commitTriviaScan,
13360
+ scanTriviaCompact,
13361
+ t.lex,
13362
+ adjacencyHolds,
13363
+ t.lexPrograms
10749
13364
  );
10750
13365
  emitReached = em.reached;
10751
13366
  } catch (e) {
@@ -10996,6 +13611,17 @@ function emitScanSpec(s) {
10996
13611
  function emitDispatchSpec(d) {
10997
13612
  return `{key:[${d.key.map(jsString).join(",")}],keyArm:[${d.keyArm.join(",")}],fold:[${d.fold.map(jsString).join(",")}],foldArm:[${d.foldArm.join(",")}],match:[${d.match.map((m) => `[${m[0]},${jsString(m[1])},${jsString(m[2])},${m[3]}]`).join(",")}],routed:[${d.routed.join(",")}],expected:[${d.expected.map(jsString).join(",")}]}`;
10998
13613
  }
13614
+ function defaultAssemblyCfgs(prog) {
13615
+ const hostCst = prog.hostMode === "cst";
13616
+ const trackLines = prog.lines === 1;
13617
+ return [false, true].map((tolerant) => ({
13618
+ hostCst,
13619
+ trackLines,
13620
+ tolerant,
13621
+ coverage: false,
13622
+ probe: false
13623
+ }));
13624
+ }
10999
13625
  function emitAssemblies(prog, cfgs) {
11000
13626
  if (cfgs.length === 0) return ["a:[],"];
11001
13627
  const t = resolveTable(prog);
@@ -11048,6 +13674,8 @@ function programFields(prog, fns, opts = {}) {
11048
13674
  // `run({ rootTrivia })` rejected a grammar that plainly has labels — the
11049
13675
  // exact failure the root-trivia work exists to prevent, one hop downstream.
11050
13676
  ...prog.dsp.length === 0 ? [] : [`p:[${prog.dsp.map(emitDispatchSpec).join(",")}],`],
13677
+ ...prog.lex === void 0 ? [] : [`lx:[${prog.lex.map((row) => `[${row.join(",")}]`).join(",")}],`],
13678
+ ...prog.lexPrograms === void 0 ? [] : [`lp:[${prog.lexPrograms.map((row) => `[${row.join(",")}]`).join(",")}],`],
11051
13679
  ...prog.labels === void 0 ? [] : [`lb:[${prog.labels.map(jsString).join(",")}],`],
11052
13680
  ...prog.classified === 1 ? ["rc:1,"] : [],
11053
13681
  // Without this a recovery table's MODULE loads as a strict one: the extra
@@ -13271,6 +15899,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
13271
15899
  };
13272
15900
 
13273
15901
  // src/table/compile-rule-map.ts
15902
+ var DEFAULT_PRECOMPILE_MIN_WORDS = 1024;
13274
15903
  function resolveHostMode(ruleMap, explicit) {
13275
15904
  return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
13276
15905
  }
@@ -13360,10 +15989,11 @@ function compileRuleMap(ruleMap, opts = {}) {
13360
15989
  `compileRuleMap: got ${supplied.length} fnSources for a pool of ${fnSrcs.length}. The list is positional, in prog.fns order, so a longer one means it belongs to a different encode \u2014 and the entries would be silently misassigned.`
13361
15990
  );
13362
15991
  }
13363
- const replacementWithMetadata = (metadataSource) => emitTableExpression(artifact, {
15992
+ const replacementWithMetadata = (metadataSource, options = {}) => emitTableExpression(artifact, {
13364
15993
  entry: null,
13365
15994
  runtimeRef: opts.runtimeRef ?? "tableRules",
13366
15995
  fnSources: sources,
15996
+ ...options.precompileDefault === true && hostMode === "ast" && prog.lines !== 1 && prog.code.length >= DEFAULT_PRECOMPILE_MIN_WORDS ? { assemblies: defaultAssemblyCfgs(artifact).slice(0, 1) } : {},
13367
15997
  ...metadataSource === void 0 ? {} : { metadataSource }
13368
15998
  });
13369
15999
  const replacement = replacementWithMetadata();
@@ -13388,7 +16018,7 @@ function compileRuleMap(ruleMap, opts = {}) {
13388
16018
  }
13389
16019
 
13390
16020
  // src/version.ts
13391
- var PARSEMAN_VERSION = "0.47.1";
16021
+ var PARSEMAN_VERSION = "0.48.1";
13392
16022
 
13393
16023
  // src/compiler/compile-linkable-table.ts
13394
16024
  function isLocal(rule) {