parseman 0.47.1 → 0.48.0

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 (124) hide show
  1. package/README.md +27 -21
  2. package/dist/analysis/diagnostics.js +2863 -353
  3. package/dist/analysis/diagnostics.js.map +3 -3
  4. package/dist/cli/index.js +2854 -344
  5. package/dist/cli/index.js.map +3 -3
  6. package/dist/combinators/expect.d.ts +1 -0
  7. package/dist/combinators/expect.d.ts.map +1 -1
  8. package/dist/combinators/expected.d.ts +8 -0
  9. package/dist/combinators/expected.d.ts.map +1 -0
  10. package/dist/combinators/first-set.d.ts +8 -0
  11. package/dist/combinators/first-set.d.ts.map +1 -1
  12. package/dist/combinators/grammar.d.ts.map +1 -1
  13. package/dist/combinators/keywords.d.ts +4 -0
  14. package/dist/combinators/keywords.d.ts.map +1 -1
  15. package/dist/combinators/literal.d.ts.map +1 -1
  16. package/dist/combinators/not.d.ts.map +1 -1
  17. package/dist/combinators/peek.d.ts.map +1 -1
  18. package/dist/combinators/regex.d.ts.map +1 -1
  19. package/dist/combinators/repeat.d.ts.map +1 -1
  20. package/dist/combinators/sequence.d.ts.map +1 -1
  21. package/dist/combinators/trivia-skip.d.ts +16 -3
  22. package/dist/combinators/trivia-skip.d.ts.map +1 -1
  23. package/dist/compiler/direct-projection.d.ts +12 -0
  24. package/dist/compiler/direct-projection.d.ts.map +1 -0
  25. package/dist/compiler/token-alphabet.d.ts +845 -5
  26. package/dist/compiler/token-alphabet.d.ts.map +1 -1
  27. package/dist/compiler/token-capability.d.ts +3 -0
  28. package/dist/compiler/token-capability.d.ts.map +1 -0
  29. package/dist/compiler/token-capability.js +3192 -0
  30. package/dist/compiler/token-capability.js.map +6 -0
  31. package/dist/cst/trivia-charscan.d.ts +3 -0
  32. package/dist/cst/trivia-charscan.d.ts.map +1 -1
  33. package/dist/cst/trivia-css-scanner.d.ts +5 -0
  34. package/dist/cst/trivia-css-scanner.d.ts.map +1 -0
  35. package/dist/cst/trivia-kinds.d.ts.map +1 -1
  36. package/dist/index.js +2862 -339
  37. package/dist/index.js.map +3 -3
  38. package/dist/language-service/index.js +5 -1
  39. package/dist/language-service/index.js.map +1 -1
  40. package/dist/plugin/index.js +2870 -347
  41. package/dist/plugin/index.js.map +3 -3
  42. package/dist/spec/index.js +315 -46
  43. package/dist/spec/index.js.map +2 -2
  44. package/dist/table/assemble.d.ts.map +1 -1
  45. package/dist/table/child-slots.d.ts.map +1 -1
  46. package/dist/table/compile-rule-map.d.ts +3 -1
  47. package/dist/table/compile-rule-map.d.ts.map +1 -1
  48. package/dist/table/emit-assembly.d.ts +12 -13
  49. package/dist/table/emit-assembly.d.ts.map +1 -1
  50. package/dist/table/emit.d.ts.map +1 -1
  51. package/dist/table/encode.d.ts.map +1 -1
  52. package/dist/table/exec-baseline.d.ts.map +1 -1
  53. package/dist/table/exec.d.ts.map +1 -1
  54. package/dist/table/index.js +2819 -300
  55. package/dist/table/index.js.map +3 -3
  56. package/dist/table/lex-body.d.ts +9 -0
  57. package/dist/table/lex-body.d.ts.map +1 -0
  58. package/dist/table/lex-program.d.ts +25 -0
  59. package/dist/table/lex-program.d.ts.map +1 -0
  60. package/dist/table/ops.d.ts +43 -7
  61. package/dist/table/ops.d.ts.map +1 -1
  62. package/dist/table/program.d.ts +50 -2
  63. package/dist/table/program.d.ts.map +1 -1
  64. package/dist/table/scalar-terminal.d.ts +13 -0
  65. package/dist/table/scalar-terminal.d.ts.map +1 -0
  66. package/dist/table/site-labels.d.ts.map +1 -1
  67. package/dist/types.d.ts +2 -0
  68. package/dist/types.d.ts.map +1 -1
  69. package/dist/version.d.ts +1 -1
  70. package/package.json +11 -11
  71. package/src/combinators/expect.ts +1 -0
  72. package/src/combinators/expected.ts +17 -0
  73. package/src/combinators/first-set.ts +58 -5
  74. package/src/combinators/grammar.ts +8 -3
  75. package/src/combinators/keywords.ts +22 -6
  76. package/src/combinators/literal.ts +2 -1
  77. package/src/combinators/not.ts +5 -1
  78. package/src/combinators/peek.ts +5 -1
  79. package/src/combinators/regex.ts +5 -3
  80. package/src/combinators/repeat.ts +4 -10
  81. package/src/combinators/sequence.ts +17 -14
  82. package/src/combinators/trivia-skip.ts +46 -13
  83. package/src/compiler/direct-projection.ts +43 -0
  84. package/src/compiler/token-alphabet.ts +4316 -12
  85. package/src/compiler/token-capability.ts +6 -0
  86. package/src/cst/trivia-charscan.ts +34 -0
  87. package/src/cst/trivia-css-scanner.ts +142 -0
  88. package/src/cst/trivia-kinds.ts +3 -1
  89. package/src/plugin/index.ts +4 -4
  90. package/src/table/assemble.ts +1211 -221
  91. package/src/table/child-slots.ts +2 -1
  92. package/src/table/compile-rule-map.ts +21 -3
  93. package/src/table/emit-assembly.ts +328 -85
  94. package/src/table/emit.ts +16 -2
  95. package/src/table/encode.ts +242 -50
  96. package/src/table/exec-baseline.ts +3 -7
  97. package/src/table/exec.ts +121 -7
  98. package/src/table/lex-body.ts +30 -0
  99. package/src/table/lex-program.ts +422 -0
  100. package/src/table/ops.ts +45 -7
  101. package/src/table/program.ts +46 -2
  102. package/src/table/scalar-terminal.ts +51 -0
  103. package/src/table/site-labels.ts +11 -1
  104. package/src/table/stamp.ts +1 -1
  105. package/src/types.ts +1 -1
  106. package/src/version.ts +1 -1
  107. package/dist/analysis/diagnostics.cjs +0 -13824
  108. package/dist/analysis/diagnostics.cjs.map +0 -6
  109. package/dist/cli/index.cjs +0 -14925
  110. package/dist/cli/index.cjs.map +0 -6
  111. package/dist/index.cjs +0 -16391
  112. package/dist/index.cjs.map +0 -6
  113. package/dist/language-service/index.cjs +0 -1304
  114. package/dist/language-service/index.cjs.map +0 -6
  115. package/dist/oracle/index.cjs +0 -254
  116. package/dist/oracle/index.cjs.map +0 -6
  117. package/dist/plugin/index.cjs +0 -16097
  118. package/dist/plugin/index.cjs.map +0 -6
  119. package/dist/run/index.cjs +0 -577
  120. package/dist/run/index.cjs.map +0 -6
  121. package/dist/spec/index.cjs +0 -6236
  122. package/dist/spec/index.cjs.map +0 -6
  123. package/dist/table/index.cjs +0 -11463
  124. package/dist/table/index.cjs.map +0 -6
@@ -817,6 +817,179 @@ function parseClassRanges(body) {
817
817
  return ranges.length ? ranges : null;
818
818
  }
819
819
 
820
+ // src/cst/trivia-css-scanner.ts
821
+ var CSS_WS_SOURCE = "[ \\t\\n\\r\\f]+";
822
+ var CSS_LINE_COMMENT_SOURCE = "\\/\\/[^\\n\\r]*";
823
+ var CSS_BLOCK_COMMENT_SOURCE = "\\/\\*(?:[^*]|\\*(?!\\/))*\\*\\/";
824
+ function scanWhitespace(input, cur) {
825
+ let pos = cur;
826
+ while (pos < input.length) {
827
+ const c = input.charCodeAt(pos);
828
+ if (c !== 32 && c !== 9 && c !== 10 && c !== 13 && c !== 12) break;
829
+ pos++;
830
+ }
831
+ return pos;
832
+ }
833
+ function scanLineComment(input, cur) {
834
+ if (input.charCodeAt(cur) !== 47 || input.charCodeAt(cur + 1) !== 47) return cur;
835
+ let pos = cur + 2;
836
+ while (pos < input.length) {
837
+ const c = input.charCodeAt(pos);
838
+ if (c === 10 || c === 13) break;
839
+ pos++;
840
+ }
841
+ return pos;
842
+ }
843
+ function scanBlockComment(input, cur) {
844
+ if (input.charCodeAt(cur) !== 47 || input.charCodeAt(cur + 1) !== 42) return cur;
845
+ const close = input.indexOf("*/", cur + 2);
846
+ return close < 0 ? cur : close + 2;
847
+ }
848
+ function scanWsLineBlockTrivia(input, cur) {
849
+ let pos = cur;
850
+ for (; ; ) {
851
+ const ws = scanWhitespace(input, pos);
852
+ if (ws !== pos) {
853
+ pos = ws;
854
+ continue;
855
+ }
856
+ const line = scanLineComment(input, pos);
857
+ if (line !== pos) {
858
+ pos = line;
859
+ continue;
860
+ }
861
+ const block = scanBlockComment(input, pos);
862
+ if (block !== pos) {
863
+ pos = block;
864
+ continue;
865
+ }
866
+ return pos;
867
+ }
868
+ }
869
+ function scanWsBlockTrivia(input, cur) {
870
+ let pos = cur;
871
+ for (; ; ) {
872
+ const ws = scanWhitespace(input, pos);
873
+ if (ws !== pos) {
874
+ pos = ws;
875
+ continue;
876
+ }
877
+ const block = scanBlockComment(input, pos);
878
+ if (block !== pos) {
879
+ pos = block;
880
+ continue;
881
+ }
882
+ return pos;
883
+ }
884
+ }
885
+ function scanLineBlockTrivia(input, cur) {
886
+ let pos = cur;
887
+ for (; ; ) {
888
+ const line = scanLineComment(input, pos);
889
+ if (line !== pos) {
890
+ pos = line;
891
+ continue;
892
+ }
893
+ const block = scanBlockComment(input, pos);
894
+ if (block !== pos) {
895
+ pos = block;
896
+ continue;
897
+ }
898
+ return pos;
899
+ }
900
+ }
901
+ function scanBlockTrivia(input, cur) {
902
+ let pos = cur;
903
+ for (; ; ) {
904
+ const block = scanBlockComment(input, pos);
905
+ if (block === pos) return pos;
906
+ pos = block;
907
+ }
908
+ }
909
+ function visitWsLineBlock(input, cur, visit) {
910
+ let pos = cur;
911
+ for (; ; ) {
912
+ let end = scanWhitespace(input, pos);
913
+ if (end !== pos) {
914
+ visit(pos, end, 0);
915
+ pos = end;
916
+ continue;
917
+ }
918
+ end = scanLineComment(input, pos);
919
+ if (end !== pos) {
920
+ visit(pos, end, 1);
921
+ pos = end;
922
+ continue;
923
+ }
924
+ end = scanBlockComment(input, pos);
925
+ if (end !== pos) {
926
+ visit(pos, end, 2);
927
+ pos = end;
928
+ continue;
929
+ }
930
+ return pos;
931
+ }
932
+ }
933
+ function visitWsBlock(input, cur, visit) {
934
+ let pos = cur;
935
+ for (; ; ) {
936
+ let end = scanWhitespace(input, pos);
937
+ if (end !== pos) {
938
+ visit(pos, end, 0);
939
+ pos = end;
940
+ continue;
941
+ }
942
+ end = scanBlockComment(input, pos);
943
+ if (end !== pos) {
944
+ visit(pos, end, 1);
945
+ pos = end;
946
+ continue;
947
+ }
948
+ return pos;
949
+ }
950
+ }
951
+ function visitLineBlock(input, cur, visit) {
952
+ let pos = cur;
953
+ for (; ; ) {
954
+ let end = scanLineComment(input, pos);
955
+ if (end !== pos) {
956
+ visit(pos, end, 0);
957
+ pos = end;
958
+ continue;
959
+ }
960
+ end = scanBlockComment(input, pos);
961
+ if (end !== pos) {
962
+ visit(pos, end, 1);
963
+ pos = end;
964
+ continue;
965
+ }
966
+ return pos;
967
+ }
968
+ }
969
+ function visitBlock(input, cur, visit) {
970
+ let pos = cur;
971
+ for (; ; ) {
972
+ const end = scanBlockComment(input, pos);
973
+ if (end === pos) return pos;
974
+ visit(pos, end, 0);
975
+ pos = end;
976
+ }
977
+ }
978
+ function commonCssTriviaScanner(sources) {
979
+ if (sources.length === 3 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_LINE_COMMENT_SOURCE && sources[2] === CSS_BLOCK_COMMENT_SOURCE) return scanWsLineBlockTrivia;
980
+ if (sources.length === 2 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return scanWsBlockTrivia;
981
+ if (sources.length === 2 && sources[0] === CSS_LINE_COMMENT_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return scanLineBlockTrivia;
982
+ if (sources.length === 1 && sources[0] === CSS_BLOCK_COMMENT_SOURCE) return scanBlockTrivia;
983
+ return null;
984
+ }
985
+ function commonCssTriviaVisitor(sources) {
986
+ if (sources.length === 3 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_LINE_COMMENT_SOURCE && sources[2] === CSS_BLOCK_COMMENT_SOURCE) return visitWsLineBlock;
987
+ if (sources.length === 2 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return visitWsBlock;
988
+ if (sources.length === 2 && sources[0] === CSS_LINE_COMMENT_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return visitLineBlock;
989
+ if (sources.length === 1 && sources[0] === CSS_BLOCK_COMMENT_SOURCE) return visitBlock;
990
+ return null;
991
+ }
992
+
820
993
  // src/cst/trivia-charscan.ts
821
994
  function inRanges(cp, ranges) {
822
995
  for (let i = 0; i < ranges.length; i++) {
@@ -970,6 +1143,35 @@ function classifyParser(p) {
970
1143
  if (d.tag !== "regex" || d.flags) return null;
971
1144
  return classifyArm(d.source);
972
1145
  }
1146
+ function plainRegexSource(p) {
1147
+ const d = p._def;
1148
+ return d.tag === "regex" && d.flags === "" ? d.source : null;
1149
+ }
1150
+ var visitSpec0;
1151
+ var visitSpec1;
1152
+ var visitSpec2;
1153
+ var visitSpec3;
1154
+ var visitValue0;
1155
+ var visitValue1;
1156
+ var visitValue2;
1157
+ var visitValue3;
1158
+ function commonLabeledTriviaVisitor(spec) {
1159
+ if (spec === visitSpec0) return visitValue0;
1160
+ if (spec === visitSpec1) return visitValue1;
1161
+ if (spec === visitSpec2) return visitValue2;
1162
+ if (spec === visitSpec3) return visitValue3;
1163
+ const sources = spec.minRepeats <= 1 ? spec.arms.map((arm) => plainRegexSource(arm.parser)) : [];
1164
+ const visitor = commonCssTriviaVisitor(sources);
1165
+ visitSpec3 = visitSpec2;
1166
+ visitValue3 = visitValue2;
1167
+ visitSpec2 = visitSpec1;
1168
+ visitValue2 = visitValue1;
1169
+ visitSpec1 = visitSpec0;
1170
+ visitValue1 = visitValue0;
1171
+ visitSpec0 = spec;
1172
+ visitValue0 = visitor;
1173
+ return visitor;
1174
+ }
973
1175
  var armSpec0;
974
1176
  var armSpec1;
975
1177
  var armSpec2;
@@ -1168,6 +1370,8 @@ function scanLabeledTriviaEnd(input, cur, spec, state) {
1168
1370
  }
1169
1371
  function visitLabeledTrivia(input, cur, spec, state, visit) {
1170
1372
  if (spec.minRepeats > 1) return void 0;
1373
+ const common = commonLabeledTriviaVisitor(spec);
1374
+ if (common !== null) return common(input, cur, visit);
1171
1375
  const chars = charArmsFor(spec);
1172
1376
  if (chars !== null) return charTriviaVisit(input, cur, chars, visit);
1173
1377
  let pos = cur;
@@ -1301,11 +1505,12 @@ function parser(opts, root) {
1301
1505
  const scopeLabels = scopeTrivia?._meta?.triviaKindLabels;
1302
1506
  const refuseUnclassified = scopeTrivia !== void 0 && !scopeTrivia._meta?.rootTriviaClassified && !opaqueRootCapture;
1303
1507
  const forceCaptureTrivia = opts.captureTrivia === true;
1304
- const trackLinesOf = opts.trackLines === true ? TRACK_LINES_ON : opts.trackLines === false ? TRACK_LINES_OFF : TRACK_LINES_INHERIT;
1508
+ const trackLinesPolicy = opts.trackLines === true ? "on" : opts.trackLines === false ? "off" : "inherit";
1509
+ const trackLinesOf = trackLinesPolicy === "on" ? TRACK_LINES_ON : trackLinesPolicy === "off" ? TRACK_LINES_OFF : TRACK_LINES_INHERIT;
1305
1510
  const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
1306
1511
  const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
1307
1512
  const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
1308
- return {
1513
+ const grammar = {
1309
1514
  _tag: "grammar",
1310
1515
  _meta: {
1311
1516
  ...root._meta,
@@ -1324,7 +1529,9 @@ function parser(opts, root) {
1324
1529
  clearTrivia,
1325
1530
  ...opaqueRootCapture ? { rootCapture: "opaque" } : {},
1326
1531
  ...opts.captureTrivia ? { captureTrivia: true } : {},
1327
- trackLines: opts.trackLines ?? false
1532
+ trackLines: opts.trackLines ?? false,
1533
+ constructionTrackLines: trackLinesPolicy,
1534
+ ...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
1328
1535
  },
1329
1536
  parse(input, pos, _ctx) {
1330
1537
  if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
@@ -1353,6 +1560,7 @@ function parser(opts, root) {
1353
1560
  return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
1354
1561
  }
1355
1562
  };
1563
+ return grammar;
1356
1564
  }
1357
1565
 
1358
1566
  // src/cst/reflection-symbols.ts
@@ -1831,6 +2039,21 @@ function firstSetFromRegex(source) {
1831
2039
  return { firstSet: firstSet(ast), canMatchNewline: canConsumeNewline(ast) };
1832
2040
  }
1833
2041
 
2042
+ // src/combinators/expected.ts
2043
+ function directTerminalFailureExpected(def) {
2044
+ switch (def.tag) {
2045
+ case "literal":
2046
+ return [JSON.stringify(def.value)];
2047
+ case "regex":
2048
+ return [`/${def.source}/`];
2049
+ case "keywords":
2050
+ return ["keyword"];
2051
+ }
2052
+ }
2053
+ function assertionFailureExpected(positive, childTag) {
2054
+ return [`${positive ? "peek" : "not"}(${childTag})`];
2055
+ }
2056
+
1834
2057
  // src/combinators/regex.ts
1835
2058
  var SCAN_BAIL_AT = 64;
1836
2059
  function inRanges2(cp, ranges) {
@@ -1902,14 +2125,15 @@ function regex(pattern, flags = "") {
1902
2125
  const firstSet2 = !resolvedFlags.includes("i") ? raw.firstSet : resolvedFlags.includes("u") || resolvedFlags.includes("v") ? any() : asciiCaseFold(raw.firstSet);
1903
2126
  const canMatchNewline = raw.canMatchNewline;
1904
2127
  const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
2128
+ const def = { tag: "regex", source, flags: resolvedFlags };
1905
2129
  return {
1906
2130
  _tag: "regex",
1907
2131
  _meta: meta,
1908
- _def: { tag: "regex", source, flags: resolvedFlags },
2132
+ _def: def,
1909
2133
  parse(input, pos, ctx) {
1910
2134
  const scanEnd = scan?.(input, pos);
1911
2135
  if (scanEnd !== void 0) {
1912
- if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
2136
+ if (scanEnd === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
1913
2137
  const value = input.slice(pos, scanEnd);
1914
2138
  const span2 = { start: pos, end: scanEnd };
1915
2139
  if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, scanEnd);
@@ -1919,7 +2143,7 @@ function regex(pattern, flags = "") {
1919
2143
  anchored.lastIndex = pos;
1920
2144
  const m = anchored.exec(input);
1921
2145
  if (m === null) {
1922
- return failAt(ctx, [`/${source}/`], pos);
2146
+ return failAt(ctx, directTerminalFailureExpected(def), pos);
1923
2147
  }
1924
2148
  const span = { start: pos, end: pos + m[0].length };
1925
2149
  if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
@@ -1960,7 +2184,7 @@ function literal(value, opts = {}) {
1960
2184
  { lo: firstUpper, hi: firstUpper }
1961
2185
  ] } : firstSet2;
1962
2186
  }
1963
- const expected = [JSON.stringify(value)];
2187
+ const expected = directTerminalFailureExpected({ tag: "literal", value, caseInsensitive });
1964
2188
  const parse = !caseInsensitive && value.length === 1 ? (() => {
1965
2189
  const code = value.charCodeAt(0);
1966
2190
  return function parse2(input, pos, ctx) {
@@ -2033,12 +2257,14 @@ function caseFoldVariants(cp) {
2033
2257
  function escapeRe(s) {
2034
2258
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2035
2259
  }
2260
+ function keywordsRegExp(words, boundary, caseInsensitive) {
2261
+ const alt = words.map(escapeRe).join("|");
2262
+ const boundarySource = boundary ? `(?![${boundary}])` : "";
2263
+ return new RegExp(`(?:${alt})${boundarySource}`, caseInsensitive ? "iy" : "uy");
2264
+ }
2036
2265
  function keywords(words, opts = {}) {
2037
2266
  const sorted = [...new Set(words)].sort((a, b) => b.length - a.length);
2038
- const alt = sorted.map(escapeRe).join("|");
2039
- const boundary = opts.boundary ? `(?![${opts.boundary}])` : "";
2040
- const flags = opts.caseInsensitive ? "iy" : "uy";
2041
- const re = new RegExp(`(?:${alt})${boundary}`, flags);
2267
+ const re = keywordsRegExp(sorted, opts.boundary, opts.caseInsensitive ?? false);
2042
2268
  let firstSet2 = empty();
2043
2269
  for (const w of sorted) {
2044
2270
  if (w.length === 0) continue;
@@ -2049,15 +2275,21 @@ function keywords(words, opts = {}) {
2049
2275
  }
2050
2276
  }
2051
2277
  const meta = { firstSet: firstSet2, canMatchNewline: false, isTrivia: false };
2278
+ const def = {
2279
+ tag: "keywords",
2280
+ words: sorted,
2281
+ caseInsensitive: opts.caseInsensitive ?? false,
2282
+ boundary: opts.boundary
2283
+ };
2052
2284
  return {
2053
2285
  _tag: "keywords",
2054
2286
  _meta: meta,
2055
- _def: { tag: "keywords", words: sorted, caseInsensitive: opts.caseInsensitive ?? false, boundary: opts.boundary },
2287
+ _def: def,
2056
2288
  parse(input, pos, ctx) {
2057
2289
  re.lastIndex = pos;
2058
2290
  const m = re.exec(input);
2059
2291
  if (m === null || m.index !== pos) {
2060
- return failAt(ctx, ["keyword"], pos);
2292
+ return failAt(ctx, directTerminalFailureExpected(def), pos);
2061
2293
  }
2062
2294
  const value = m[0];
2063
2295
  const span = { start: pos, end: pos + value.length };
@@ -2070,6 +2302,14 @@ function keywords(words, opts = {}) {
2070
2302
  // src/combinators/trivia-skip.ts
2071
2303
  var NOOP_COMMIT = () => {
2072
2304
  };
2305
+ function triviaScanEnd(scan) {
2306
+ return typeof scan === "number" ? scan : scan.end;
2307
+ }
2308
+ function commitTriviaScan(scan) {
2309
+ if (typeof scan === "number") return scan;
2310
+ scan.commit();
2311
+ return scan.end;
2312
+ }
2073
2313
  var fastTrivia0;
2074
2314
  var fastTrivia1;
2075
2315
  var fastTrivia2;
@@ -2134,7 +2374,7 @@ function rollbackLookahead(ctx, mark) {
2134
2374
  function scanWithLabels(input, cur, ctx) {
2135
2375
  const triviaP = ctx.trivia;
2136
2376
  const spec = analyzeLabeledTrivia(triviaP);
2137
- if (!spec) return { end: cur, commit: NOOP_COMMIT };
2377
+ if (!spec) return cur;
2138
2378
  const log = ctx._triviaLog;
2139
2379
  const rootLog = ctx._rootTriviaLog;
2140
2380
  const rootKinds = ctx._rootTriviaKindIndex;
@@ -2152,7 +2392,8 @@ function scanWithLabels(input, cur, ctx) {
2152
2392
  }
2153
2393
  });
2154
2394
  if (visitedEnd !== void 0) {
2155
- if (visitedEnd === cur) return { end: cur, commit: NOOP_COMMIT };
2395
+ if (visitedEnd === cur) return cur;
2396
+ if (fullRows === void 0 && rootRows === void 0 && cstRows === void 0) return visitedEnd;
2156
2397
  return {
2157
2398
  end: visitedEnd,
2158
2399
  commit: () => {
@@ -2171,7 +2412,7 @@ function scanWithLabels(input, cur, ctx) {
2171
2412
  };
2172
2413
  }
2173
2414
  const { end, chunks } = scanLabeledTriviaChunks(input, cur, spec, ctx.state);
2174
- if (end === cur) return { end: cur, commit: NOOP_COMMIT };
2415
+ if (end === cur) return cur;
2175
2416
  return {
2176
2417
  end,
2177
2418
  commit: () => recordTriviaChunks(ctx, chunks)
@@ -2212,7 +2453,7 @@ function advanceTrivia(input, cur, ctx) {
2212
2453
  const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
2213
2454
  return tr.ok && tr.span.end > cur ? tr.span.end : cur;
2214
2455
  }
2215
- function scanTrivia(input, cur, ctx) {
2456
+ function scanTriviaCompact(input, cur, ctx) {
2216
2457
  const triviaP = ctx.trivia;
2217
2458
  if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
2218
2459
  const log = ctx._triviaLog;
@@ -2253,7 +2494,7 @@ function scanTrivia(input, cur, ctx) {
2253
2494
  }
2254
2495
  if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
2255
2496
  const scan = scanWithLabels(input, cur, ctx);
2256
- if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
2497
+ if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, triviaScanEnd(scan));
2257
2498
  return scan;
2258
2499
  }
2259
2500
  if (ctx.triviaKindLabels) {
@@ -2285,14 +2526,12 @@ function scanTrivia(input, cur, ctx) {
2285
2526
  }
2286
2527
  function consumeTrivia(input, cur, ctx) {
2287
2528
  if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
2288
- const scan = scanTrivia(input, cur, ctx);
2289
- scan.commit();
2290
- return scan.end;
2529
+ return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
2291
2530
  }
2292
2531
  function probeTriviaEnd(input, cur, ctx) {
2293
2532
  if (!ctx.trivia) return cur;
2294
2533
  const probeCtx = { ...ctx, trackLines: false };
2295
- if (needsDeferredTriviaCommit(probeCtx)) return scanTrivia(input, cur, probeCtx).end;
2534
+ if (needsDeferredTriviaCommit(probeCtx)) return triviaScanEnd(scanTriviaCompact(input, cur, probeCtx));
2296
2535
  return advanceTrivia(input, cur, probeCtx);
2297
2536
  }
2298
2537
  function fastTriviaScanner(trivia2) {
@@ -2320,10 +2559,16 @@ function buildFastTriviaScanner(trivia2) {
2320
2559
  const one = regexTriviaScanner(repeat);
2321
2560
  if (one) return loopScanner([one]);
2322
2561
  if (repeat._def.tag !== "choice") return null;
2562
+ const fused = commonCssTriviaScanner(repeat._def.parsers.map(triviaRegexSource));
2563
+ if (fused !== null) return fused;
2323
2564
  const arms = repeat._def.parsers.map(regexTriviaScanner);
2324
2565
  if (arms.some((s) => s === null)) return null;
2325
2566
  return loopScanner(arms);
2326
2567
  }
2568
+ function triviaRegexSource(parser2) {
2569
+ const d = parser2._def.tag === "label" ? parser2._def.parser._def : parser2._def;
2570
+ return d.tag === "regex" && d.flags === "" ? d.source : null;
2571
+ }
2327
2572
  function loopScanner(arms) {
2328
2573
  return (input, cur) => {
2329
2574
  let pos = cur;
@@ -2813,9 +3058,7 @@ function sequence(...parsers) {
2813
3058
  const mRootLog = ctx._rootTriviaLog?.length ?? 0;
2814
3059
  let scanEnd;
2815
3060
  if (needsDeferredTriviaCommit(ctx)) {
2816
- const scan = scanTrivia(input, cur, ctx);
2817
- scan.commit();
2818
- scanEnd = scan.end;
3061
+ scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
2819
3062
  } else {
2820
3063
  scanEnd = advanceTrivia(input, cur, ctx);
2821
3064
  }
@@ -2825,7 +3068,15 @@ function sequence(...parsers) {
2825
3068
  const result2 = parsers[i].parse(input, scanEnd, ctx);
2826
3069
  if (!result2.ok) return result2;
2827
3070
  if (result2.span.end > scanEnd) cur = result2.span.end;
2828
- else rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
3071
+ else rollbackScannedTriviaAt(
3072
+ ctx,
3073
+ mTlog,
3074
+ scanTlog,
3075
+ mLog,
3076
+ scanLog,
3077
+ mRootLog,
3078
+ scanRootLog
3079
+ );
2829
3080
  if (values !== void 0) values.push(result2.value);
2830
3081
  continue;
2831
3082
  }
@@ -2860,9 +3111,7 @@ function sequence(...parsers) {
2860
3111
  const mLog = ctx._triviaLog?.length ?? 0;
2861
3112
  const mRootLog = ctx._rootTriviaLog?.length ?? 0;
2862
3113
  if (needsDeferredTriviaCommit(ctx)) {
2863
- const scan = scanTrivia(input, cur, ctx);
2864
- scan.commit();
2865
- scanEnd = scan.end;
3114
+ scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
2866
3115
  } else {
2867
3116
  scanEnd = advanceTrivia(input, cur, ctx);
2868
3117
  }
@@ -2872,7 +3121,15 @@ function sequence(...parsers) {
2872
3121
  const result2 = parsers[i].parse(input, scanEnd, ctx);
2873
3122
  if (!result2.ok) return result2;
2874
3123
  if (result2.span.end > scanEnd) cur = result2.span.end;
2875
- else rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
3124
+ else rollbackScannedTriviaAt(
3125
+ ctx,
3126
+ mTlog,
3127
+ scanTlog,
3128
+ mLog,
3129
+ scanLog,
3130
+ mRootLog,
3131
+ scanRootLog
3132
+ );
2876
3133
  if (values !== void 0) values.push(result2.value);
2877
3134
  continue;
2878
3135
  }
@@ -2904,9 +3161,7 @@ function sequence(...parsers) {
2904
3161
  const mLog = ctx._triviaLog?.length ?? 0;
2905
3162
  const mRootLog = ctx._rootTriviaLog?.length ?? 0;
2906
3163
  if (needsDeferredTriviaCommit(ctx)) {
2907
- const scan = scanTrivia(input, cur, ctx);
2908
- scan.commit();
2909
- scanEnd = scan.end;
3164
+ scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
2910
3165
  } else {
2911
3166
  scanEnd = advanceTrivia(input, cur, ctx);
2912
3167
  }
@@ -2918,7 +3173,15 @@ function sequence(...parsers) {
2918
3173
  if (result2.span.end > scanEnd) {
2919
3174
  cur = result2.span.end;
2920
3175
  } else {
2921
- rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
3176
+ rollbackScannedTriviaAt(
3177
+ ctx,
3178
+ mTlog,
3179
+ scanTlog,
3180
+ mLog,
3181
+ scanLog,
3182
+ mRootLog,
3183
+ scanRootLog
3184
+ );
2922
3185
  }
2923
3186
  if (values !== void 0) values.push(result2.value);
2924
3187
  continue;
@@ -3610,9 +3873,7 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
3610
3873
  let pos = cur;
3611
3874
  if (ctx.trivia) {
3612
3875
  if (needsDeferredTriviaCommit(ctx)) {
3613
- const scan = scanTrivia(input, cur, ctx);
3614
- scan.commit();
3615
- pos = scan.end;
3876
+ pos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
3616
3877
  } else {
3617
3878
  pos = advanceTrivia(input, cur, ctx);
3618
3879
  }
@@ -3835,9 +4096,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
3835
4096
  let sepPos = cur;
3836
4097
  if (ctx.trivia) {
3837
4098
  if (needsDeferredTriviaCommit(ctx)) {
3838
- const scan = scanTrivia(input, cur, ctx);
3839
- scan.commit();
3840
- sepPos = scan.end;
4099
+ sepPos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
3841
4100
  } else {
3842
4101
  sepPos = advanceTrivia(input, cur, ctx);
3843
4102
  }
@@ -3853,9 +4112,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
3853
4112
  let nextPos = sep.span.end;
3854
4113
  if (ctx.trivia) {
3855
4114
  if (needsDeferredTriviaCommit(ctx)) {
3856
- const scan = scanTrivia(input, sep.span.end, ctx);
3857
- scan.commit();
3858
- nextPos = scan.end;
4115
+ nextPos = commitTriviaScan(scanTriviaCompact(input, sep.span.end, ctx));
3859
4116
  } else {
3860
4117
  nextPos = advanceTrivia(input, sep.span.end, ctx);
3861
4118
  }
@@ -3906,7 +4163,11 @@ function not(combinator) {
3906
4163
  const result = combinator.parse(input, pos, ctx);
3907
4164
  rollbackLookahead(ctx, mark);
3908
4165
  if (result.ok) {
3909
- return { ok: false, expected: [`not(${combinator._tag})`], span: { start: pos, end: pos } };
4166
+ return {
4167
+ ok: false,
4168
+ expected: assertionFailureExpected(false, combinator._tag),
4169
+ span: { start: pos, end: pos }
4170
+ };
3910
4171
  }
3911
4172
  return { ok: true, value: null, span: { start: pos, end: pos } };
3912
4173
  }
@@ -3930,7 +4191,11 @@ function peek(combinator) {
3930
4191
  const result = combinator.parse(input, pos, ctx);
3931
4192
  rollbackLookahead(ctx, mark);
3932
4193
  if (result.ok) return { ok: true, value: null, span: { start: pos, end: pos } };
3933
- return { ok: false, expected: [`peek(${combinator._tag})`], span: { start: pos, end: pos } };
4194
+ return {
4195
+ ok: false,
4196
+ expected: assertionFailureExpected(true, combinator._tag),
4197
+ span: { start: pos, end: pos }
4198
+ };
3934
4199
  }
3935
4200
  };
3936
4201
  }
@@ -4857,6 +5122,8 @@ var OP_ATTEMPT = 38;
4857
5122
  var OP_LABEL = 39;
4858
5123
  var OP_COV = 40;
4859
5124
  var OP_SCOPE_PLAIN = 41;
5125
+ var OP_LEX_BODY = 42;
5126
+ var OP_LEX_PROGRAM = 43;
4860
5127
  var OP_DISPATCH = 25;
4861
5128
  var OP_ROUTED = 26;
4862
5129
  var OP_NAMES = {
@@ -4900,7 +5167,9 @@ var OP_NAMES = {
4900
5167
  [OP_ATTEMPT]: "ATTEMPT",
4901
5168
  [OP_LABEL]: "LABEL",
4902
5169
  [OP_COV]: "COV",
4903
- [OP_SCOPE_PLAIN]: "SCOPE_PLAIN"
5170
+ [OP_SCOPE_PLAIN]: "SCOPE_PLAIN",
5171
+ [OP_LEX_BODY]: "LEX_BODY",
5172
+ [OP_LEX_PROGRAM]: "LEX_PROGRAM"
4904
5173
  };
4905
5174
 
4906
5175
  // src/table/scan-shapes.ts