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.
- package/README.md +27 -21
- package/dist/analysis/diagnostics.js +2964 -347
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +2960 -343
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/expect.d.ts +1 -0
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/expected.d.ts +8 -0
- package/dist/combinators/expected.d.ts.map +1 -0
- package/dist/combinators/first-set.d.ts +8 -0
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/keywords.d.ts +4 -0
- package/dist/combinators/keywords.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/not.d.ts.map +1 -1
- package/dist/combinators/peek.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/repeat.d.ts.map +1 -1
- package/dist/combinators/sequence.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +16 -3
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/direct-projection.d.ts +12 -0
- package/dist/compiler/direct-projection.d.ts.map +1 -0
- package/dist/compiler/token-alphabet.d.ts +845 -5
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.d.ts +3 -0
- package/dist/compiler/token-capability.d.ts.map +1 -0
- package/dist/compiler/token-capability.js +3192 -0
- package/dist/compiler/token-capability.js.map +6 -0
- package/dist/cst/trivia-charscan.d.ts +3 -0
- package/dist/cst/trivia-charscan.d.ts.map +1 -1
- package/dist/cst/trivia-css-scanner.d.ts +5 -0
- package/dist/cst/trivia-css-scanner.d.ts.map +1 -0
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/index.js +2973 -343
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +5 -1
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/index.js +2982 -352
- package/dist/plugin/index.js.map +3 -3
- package/dist/spec/index.js +325 -47
- package/dist/spec/index.js.map +3 -3
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/child-slots.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +3 -1
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +12 -13
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec-baseline.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/index.js +2937 -311
- package/dist/table/index.js.map +3 -3
- package/dist/table/lex-body.d.ts +9 -0
- package/dist/table/lex-body.d.ts.map +1 -0
- package/dist/table/lex-program.d.ts +25 -0
- package/dist/table/lex-program.d.ts.map +1 -0
- package/dist/table/ops.d.ts +47 -11
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +50 -2
- package/dist/table/program.d.ts.map +1 -1
- package/dist/table/scalar-terminal.d.ts +13 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -0
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +11 -11
- package/src/combinators/choice.ts +10 -1
- package/src/combinators/expect.ts +1 -0
- package/src/combinators/expected.ts +17 -0
- package/src/combinators/first-set.ts +58 -5
- package/src/combinators/grammar.ts +8 -3
- package/src/combinators/keywords.ts +22 -6
- package/src/combinators/literal.ts +2 -1
- package/src/combinators/not.ts +5 -1
- package/src/combinators/peek.ts +5 -1
- package/src/combinators/regex.ts +5 -3
- package/src/combinators/repeat.ts +4 -10
- package/src/combinators/sequence.ts +17 -14
- package/src/combinators/trivia-skip.ts +46 -13
- package/src/compiler/direct-projection.ts +43 -0
- package/src/compiler/token-alphabet.ts +4316 -12
- package/src/compiler/token-capability.ts +6 -0
- package/src/cst/trivia-charscan.ts +34 -0
- package/src/cst/trivia-css-scanner.ts +142 -0
- package/src/cst/trivia-kinds.ts +3 -1
- package/src/plugin/index.ts +4 -4
- package/src/table/assemble.ts +1253 -240
- package/src/table/child-slots.ts +2 -1
- package/src/table/compile-rule-map.ts +21 -3
- package/src/table/emit-assembly.ts +335 -87
- package/src/table/emit.ts +16 -2
- package/src/table/encode.ts +248 -60
- package/src/table/exec-baseline.ts +3 -7
- package/src/table/exec.ts +134 -25
- package/src/table/lex-body.ts +30 -0
- package/src/table/lex-program.ts +431 -0
- package/src/table/ops.ts +49 -11
- package/src/table/program.ts +46 -2
- package/src/table/scalar-terminal.ts +51 -0
- package/src/table/site-labels.ts +11 -1
- package/src/table/stamp.ts +1 -1
- package/src/types.ts +1 -1
- package/src/version.ts +1 -1
- package/dist/analysis/diagnostics.cjs +0 -13824
- package/dist/analysis/diagnostics.cjs.map +0 -6
- package/dist/cli/index.cjs +0 -14925
- package/dist/cli/index.cjs.map +0 -6
- package/dist/index.cjs +0 -16391
- package/dist/index.cjs.map +0 -6
- package/dist/language-service/index.cjs +0 -1304
- package/dist/language-service/index.cjs.map +0 -6
- package/dist/oracle/index.cjs +0 -254
- package/dist/oracle/index.cjs.map +0 -6
- package/dist/plugin/index.cjs +0 -16097
- package/dist/plugin/index.cjs.map +0 -6
- package/dist/run/index.cjs +0 -577
- package/dist/run/index.cjs.map +0 -6
- package/dist/spec/index.cjs +0 -6236
- package/dist/spec/index.cjs.map +0 -6
- package/dist/table/index.cjs +0 -11463
- package/dist/table/index.cjs.map +0 -6
package/dist/table/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;
|
|
@@ -430,6 +466,21 @@ function pushTriviaLogEntry(ctx, start, end, kindIndex) {
|
|
|
430
466
|
}
|
|
431
467
|
}
|
|
432
468
|
|
|
469
|
+
// src/combinators/expected.ts
|
|
470
|
+
function directTerminalFailureExpected(def) {
|
|
471
|
+
switch (def.tag) {
|
|
472
|
+
case "literal":
|
|
473
|
+
return [JSON.stringify(def.value)];
|
|
474
|
+
case "regex":
|
|
475
|
+
return [`/${def.source}/`];
|
|
476
|
+
case "keywords":
|
|
477
|
+
return ["keyword"];
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
function assertionFailureExpected(positive, childTag) {
|
|
481
|
+
return [`${positive ? "peek" : "not"}(${childTag})`];
|
|
482
|
+
}
|
|
483
|
+
|
|
433
484
|
// src/combinators/literal.ts
|
|
434
485
|
function asciiFoldEq(a, b) {
|
|
435
486
|
if (a.length !== b.length) return false;
|
|
@@ -461,7 +512,7 @@ function literal(value, opts = {}) {
|
|
|
461
512
|
{ lo: firstUpper, hi: firstUpper }
|
|
462
513
|
] } : firstSet2;
|
|
463
514
|
}
|
|
464
|
-
const expected =
|
|
515
|
+
const expected = directTerminalFailureExpected({ tag: "literal", value, caseInsensitive });
|
|
465
516
|
const parse = !caseInsensitive && value.length === 1 ? (() => {
|
|
466
517
|
const code = value.charCodeAt(0);
|
|
467
518
|
return function parse2(input, pos, ctx) {
|
|
@@ -939,14 +990,15 @@ function regex(pattern, flags = "") {
|
|
|
939
990
|
const firstSet2 = !resolvedFlags.includes("i") ? raw.firstSet : resolvedFlags.includes("u") || resolvedFlags.includes("v") ? any() : asciiCaseFold(raw.firstSet);
|
|
940
991
|
const canMatchNewline = raw.canMatchNewline;
|
|
941
992
|
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
993
|
+
const def = { tag: "regex", source, flags: resolvedFlags };
|
|
942
994
|
return {
|
|
943
995
|
_tag: "regex",
|
|
944
996
|
_meta: meta,
|
|
945
|
-
_def:
|
|
997
|
+
_def: def,
|
|
946
998
|
parse(input, pos, ctx) {
|
|
947
999
|
const scanEnd = scan?.(input, pos);
|
|
948
1000
|
if (scanEnd !== void 0) {
|
|
949
|
-
if (scanEnd === null) return failAt(ctx,
|
|
1001
|
+
if (scanEnd === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
950
1002
|
const value = input.slice(pos, scanEnd);
|
|
951
1003
|
const span2 = { start: pos, end: scanEnd };
|
|
952
1004
|
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, scanEnd);
|
|
@@ -956,7 +1008,7 @@ function regex(pattern, flags = "") {
|
|
|
956
1008
|
anchored.lastIndex = pos;
|
|
957
1009
|
const m = anchored.exec(input);
|
|
958
1010
|
if (m === null) {
|
|
959
|
-
return failAt(ctx,
|
|
1011
|
+
return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
960
1012
|
}
|
|
961
1013
|
const span = { start: pos, end: pos + m[0].length };
|
|
962
1014
|
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
@@ -1011,6 +1063,179 @@ function createDetachedParseContext(trackLines, state) {
|
|
|
1011
1063
|
return ctx;
|
|
1012
1064
|
}
|
|
1013
1065
|
|
|
1066
|
+
// src/cst/trivia-css-scanner.ts
|
|
1067
|
+
var CSS_WS_SOURCE = "[ \\t\\n\\r\\f]+";
|
|
1068
|
+
var CSS_LINE_COMMENT_SOURCE = "\\/\\/[^\\n\\r]*";
|
|
1069
|
+
var CSS_BLOCK_COMMENT_SOURCE = "\\/\\*(?:[^*]|\\*(?!\\/))*\\*\\/";
|
|
1070
|
+
function scanWhitespace(input, cur) {
|
|
1071
|
+
let pos = cur;
|
|
1072
|
+
while (pos < input.length) {
|
|
1073
|
+
const c = input.charCodeAt(pos);
|
|
1074
|
+
if (c !== 32 && c !== 9 && c !== 10 && c !== 13 && c !== 12) break;
|
|
1075
|
+
pos++;
|
|
1076
|
+
}
|
|
1077
|
+
return pos;
|
|
1078
|
+
}
|
|
1079
|
+
function scanLineComment(input, cur) {
|
|
1080
|
+
if (input.charCodeAt(cur) !== 47 || input.charCodeAt(cur + 1) !== 47) return cur;
|
|
1081
|
+
let pos = cur + 2;
|
|
1082
|
+
while (pos < input.length) {
|
|
1083
|
+
const c = input.charCodeAt(pos);
|
|
1084
|
+
if (c === 10 || c === 13) break;
|
|
1085
|
+
pos++;
|
|
1086
|
+
}
|
|
1087
|
+
return pos;
|
|
1088
|
+
}
|
|
1089
|
+
function scanBlockComment(input, cur) {
|
|
1090
|
+
if (input.charCodeAt(cur) !== 47 || input.charCodeAt(cur + 1) !== 42) return cur;
|
|
1091
|
+
const close = input.indexOf("*/", cur + 2);
|
|
1092
|
+
return close < 0 ? cur : close + 2;
|
|
1093
|
+
}
|
|
1094
|
+
function scanWsLineBlockTrivia(input, cur) {
|
|
1095
|
+
let pos = cur;
|
|
1096
|
+
for (; ; ) {
|
|
1097
|
+
const ws = scanWhitespace(input, pos);
|
|
1098
|
+
if (ws !== pos) {
|
|
1099
|
+
pos = ws;
|
|
1100
|
+
continue;
|
|
1101
|
+
}
|
|
1102
|
+
const line = scanLineComment(input, pos);
|
|
1103
|
+
if (line !== pos) {
|
|
1104
|
+
pos = line;
|
|
1105
|
+
continue;
|
|
1106
|
+
}
|
|
1107
|
+
const block = scanBlockComment(input, pos);
|
|
1108
|
+
if (block !== pos) {
|
|
1109
|
+
pos = block;
|
|
1110
|
+
continue;
|
|
1111
|
+
}
|
|
1112
|
+
return pos;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
function scanWsBlockTrivia(input, cur) {
|
|
1116
|
+
let pos = cur;
|
|
1117
|
+
for (; ; ) {
|
|
1118
|
+
const ws = scanWhitespace(input, pos);
|
|
1119
|
+
if (ws !== pos) {
|
|
1120
|
+
pos = ws;
|
|
1121
|
+
continue;
|
|
1122
|
+
}
|
|
1123
|
+
const block = scanBlockComment(input, pos);
|
|
1124
|
+
if (block !== pos) {
|
|
1125
|
+
pos = block;
|
|
1126
|
+
continue;
|
|
1127
|
+
}
|
|
1128
|
+
return pos;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
function scanLineBlockTrivia(input, cur) {
|
|
1132
|
+
let pos = cur;
|
|
1133
|
+
for (; ; ) {
|
|
1134
|
+
const line = scanLineComment(input, pos);
|
|
1135
|
+
if (line !== pos) {
|
|
1136
|
+
pos = line;
|
|
1137
|
+
continue;
|
|
1138
|
+
}
|
|
1139
|
+
const block = scanBlockComment(input, pos);
|
|
1140
|
+
if (block !== pos) {
|
|
1141
|
+
pos = block;
|
|
1142
|
+
continue;
|
|
1143
|
+
}
|
|
1144
|
+
return pos;
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
function scanBlockTrivia(input, cur) {
|
|
1148
|
+
let pos = cur;
|
|
1149
|
+
for (; ; ) {
|
|
1150
|
+
const block = scanBlockComment(input, pos);
|
|
1151
|
+
if (block === pos) return pos;
|
|
1152
|
+
pos = block;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
function visitWsLineBlock(input, cur, visit) {
|
|
1156
|
+
let pos = cur;
|
|
1157
|
+
for (; ; ) {
|
|
1158
|
+
let end = scanWhitespace(input, pos);
|
|
1159
|
+
if (end !== pos) {
|
|
1160
|
+
visit(pos, end, 0);
|
|
1161
|
+
pos = end;
|
|
1162
|
+
continue;
|
|
1163
|
+
}
|
|
1164
|
+
end = scanLineComment(input, pos);
|
|
1165
|
+
if (end !== pos) {
|
|
1166
|
+
visit(pos, end, 1);
|
|
1167
|
+
pos = end;
|
|
1168
|
+
continue;
|
|
1169
|
+
}
|
|
1170
|
+
end = scanBlockComment(input, pos);
|
|
1171
|
+
if (end !== pos) {
|
|
1172
|
+
visit(pos, end, 2);
|
|
1173
|
+
pos = end;
|
|
1174
|
+
continue;
|
|
1175
|
+
}
|
|
1176
|
+
return pos;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
function visitWsBlock(input, cur, visit) {
|
|
1180
|
+
let pos = cur;
|
|
1181
|
+
for (; ; ) {
|
|
1182
|
+
let end = scanWhitespace(input, pos);
|
|
1183
|
+
if (end !== pos) {
|
|
1184
|
+
visit(pos, end, 0);
|
|
1185
|
+
pos = end;
|
|
1186
|
+
continue;
|
|
1187
|
+
}
|
|
1188
|
+
end = scanBlockComment(input, pos);
|
|
1189
|
+
if (end !== pos) {
|
|
1190
|
+
visit(pos, end, 1);
|
|
1191
|
+
pos = end;
|
|
1192
|
+
continue;
|
|
1193
|
+
}
|
|
1194
|
+
return pos;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
function visitLineBlock(input, cur, visit) {
|
|
1198
|
+
let pos = cur;
|
|
1199
|
+
for (; ; ) {
|
|
1200
|
+
let end = scanLineComment(input, pos);
|
|
1201
|
+
if (end !== pos) {
|
|
1202
|
+
visit(pos, end, 0);
|
|
1203
|
+
pos = end;
|
|
1204
|
+
continue;
|
|
1205
|
+
}
|
|
1206
|
+
end = scanBlockComment(input, pos);
|
|
1207
|
+
if (end !== pos) {
|
|
1208
|
+
visit(pos, end, 1);
|
|
1209
|
+
pos = end;
|
|
1210
|
+
continue;
|
|
1211
|
+
}
|
|
1212
|
+
return pos;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
function visitBlock(input, cur, visit) {
|
|
1216
|
+
let pos = cur;
|
|
1217
|
+
for (; ; ) {
|
|
1218
|
+
const end = scanBlockComment(input, pos);
|
|
1219
|
+
if (end === pos) return pos;
|
|
1220
|
+
visit(pos, end, 0);
|
|
1221
|
+
pos = end;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
function commonCssTriviaScanner(sources) {
|
|
1225
|
+
if (sources.length === 3 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_LINE_COMMENT_SOURCE && sources[2] === CSS_BLOCK_COMMENT_SOURCE) return scanWsLineBlockTrivia;
|
|
1226
|
+
if (sources.length === 2 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return scanWsBlockTrivia;
|
|
1227
|
+
if (sources.length === 2 && sources[0] === CSS_LINE_COMMENT_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return scanLineBlockTrivia;
|
|
1228
|
+
if (sources.length === 1 && sources[0] === CSS_BLOCK_COMMENT_SOURCE) return scanBlockTrivia;
|
|
1229
|
+
return null;
|
|
1230
|
+
}
|
|
1231
|
+
function commonCssTriviaVisitor(sources) {
|
|
1232
|
+
if (sources.length === 3 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_LINE_COMMENT_SOURCE && sources[2] === CSS_BLOCK_COMMENT_SOURCE) return visitWsLineBlock;
|
|
1233
|
+
if (sources.length === 2 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return visitWsBlock;
|
|
1234
|
+
if (sources.length === 2 && sources[0] === CSS_LINE_COMMENT_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return visitLineBlock;
|
|
1235
|
+
if (sources.length === 1 && sources[0] === CSS_BLOCK_COMMENT_SOURCE) return visitBlock;
|
|
1236
|
+
return null;
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1014
1239
|
// src/cst/trivia-charscan.ts
|
|
1015
1240
|
function inRanges2(cp, ranges) {
|
|
1016
1241
|
for (let i = 0; i < ranges.length; i++) {
|
|
@@ -1164,6 +1389,35 @@ function classifyParser(p) {
|
|
|
1164
1389
|
if (d.tag !== "regex" || d.flags) return null;
|
|
1165
1390
|
return classifyArm(d.source);
|
|
1166
1391
|
}
|
|
1392
|
+
function plainRegexSource(p) {
|
|
1393
|
+
const d = p._def;
|
|
1394
|
+
return d.tag === "regex" && d.flags === "" ? d.source : null;
|
|
1395
|
+
}
|
|
1396
|
+
var visitSpec0;
|
|
1397
|
+
var visitSpec1;
|
|
1398
|
+
var visitSpec2;
|
|
1399
|
+
var visitSpec3;
|
|
1400
|
+
var visitValue0;
|
|
1401
|
+
var visitValue1;
|
|
1402
|
+
var visitValue2;
|
|
1403
|
+
var visitValue3;
|
|
1404
|
+
function commonLabeledTriviaVisitor(spec) {
|
|
1405
|
+
if (spec === visitSpec0) return visitValue0;
|
|
1406
|
+
if (spec === visitSpec1) return visitValue1;
|
|
1407
|
+
if (spec === visitSpec2) return visitValue2;
|
|
1408
|
+
if (spec === visitSpec3) return visitValue3;
|
|
1409
|
+
const sources = spec.minRepeats <= 1 ? spec.arms.map((arm) => plainRegexSource(arm.parser)) : [];
|
|
1410
|
+
const visitor = commonCssTriviaVisitor(sources);
|
|
1411
|
+
visitSpec3 = visitSpec2;
|
|
1412
|
+
visitValue3 = visitValue2;
|
|
1413
|
+
visitSpec2 = visitSpec1;
|
|
1414
|
+
visitValue2 = visitValue1;
|
|
1415
|
+
visitSpec1 = visitSpec0;
|
|
1416
|
+
visitValue1 = visitValue0;
|
|
1417
|
+
visitSpec0 = spec;
|
|
1418
|
+
visitValue0 = visitor;
|
|
1419
|
+
return visitor;
|
|
1420
|
+
}
|
|
1167
1421
|
var armSpec0;
|
|
1168
1422
|
var armSpec1;
|
|
1169
1423
|
var armSpec2;
|
|
@@ -1362,6 +1616,8 @@ function scanLabeledTriviaEnd(input, cur, spec, state) {
|
|
|
1362
1616
|
}
|
|
1363
1617
|
function visitLabeledTrivia(input, cur, spec, state, visit) {
|
|
1364
1618
|
if (spec.minRepeats > 1) return void 0;
|
|
1619
|
+
const common = commonLabeledTriviaVisitor(spec);
|
|
1620
|
+
if (common !== null) return common(input, cur, visit);
|
|
1365
1621
|
const chars = charArmsFor(spec);
|
|
1366
1622
|
if (chars !== null) return charTriviaVisit(input, cur, chars, visit);
|
|
1367
1623
|
let pos = cur;
|
|
@@ -1452,6 +1708,14 @@ function triviaKindMaskAt(input, pos, spec, state) {
|
|
|
1452
1708
|
// src/combinators/trivia-skip.ts
|
|
1453
1709
|
var NOOP_COMMIT = () => {
|
|
1454
1710
|
};
|
|
1711
|
+
function triviaScanEnd(scan) {
|
|
1712
|
+
return typeof scan === "number" ? scan : scan.end;
|
|
1713
|
+
}
|
|
1714
|
+
function commitTriviaScan(scan) {
|
|
1715
|
+
if (typeof scan === "number") return scan;
|
|
1716
|
+
scan.commit();
|
|
1717
|
+
return scan.end;
|
|
1718
|
+
}
|
|
1455
1719
|
var fastTrivia0;
|
|
1456
1720
|
var fastTrivia1;
|
|
1457
1721
|
var fastTrivia2;
|
|
@@ -1514,7 +1778,7 @@ function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
|
1514
1778
|
function scanWithLabels(input, cur, ctx) {
|
|
1515
1779
|
const triviaP = ctx.trivia;
|
|
1516
1780
|
const spec = analyzeLabeledTrivia(triviaP);
|
|
1517
|
-
if (!spec) return
|
|
1781
|
+
if (!spec) return cur;
|
|
1518
1782
|
const log = ctx._triviaLog;
|
|
1519
1783
|
const rootLog = ctx._rootTriviaLog;
|
|
1520
1784
|
const rootKinds = ctx._rootTriviaKindIndex;
|
|
@@ -1532,7 +1796,8 @@ function scanWithLabels(input, cur, ctx) {
|
|
|
1532
1796
|
}
|
|
1533
1797
|
});
|
|
1534
1798
|
if (visitedEnd !== void 0) {
|
|
1535
|
-
if (visitedEnd === cur) return
|
|
1799
|
+
if (visitedEnd === cur) return cur;
|
|
1800
|
+
if (fullRows === void 0 && rootRows === void 0 && cstRows === void 0) return visitedEnd;
|
|
1536
1801
|
return {
|
|
1537
1802
|
end: visitedEnd,
|
|
1538
1803
|
commit: () => {
|
|
@@ -1551,7 +1816,7 @@ function scanWithLabels(input, cur, ctx) {
|
|
|
1551
1816
|
};
|
|
1552
1817
|
}
|
|
1553
1818
|
const { end, chunks } = scanLabeledTriviaChunks(input, cur, spec, ctx.state);
|
|
1554
|
-
if (end === cur) return
|
|
1819
|
+
if (end === cur) return cur;
|
|
1555
1820
|
return {
|
|
1556
1821
|
end,
|
|
1557
1822
|
commit: () => recordTriviaChunks(ctx, chunks)
|
|
@@ -1592,7 +1857,7 @@ function advanceTrivia(input, cur, ctx) {
|
|
|
1592
1857
|
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1593
1858
|
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1594
1859
|
}
|
|
1595
|
-
function
|
|
1860
|
+
function scanTriviaCompact(input, cur, ctx) {
|
|
1596
1861
|
const triviaP = ctx.trivia;
|
|
1597
1862
|
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1598
1863
|
const log = ctx._triviaLog;
|
|
@@ -1633,7 +1898,7 @@ function scanTrivia(input, cur, ctx) {
|
|
|
1633
1898
|
}
|
|
1634
1899
|
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1635
1900
|
const scan = scanWithLabels(input, cur, ctx);
|
|
1636
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan
|
|
1901
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, triviaScanEnd(scan));
|
|
1637
1902
|
return scan;
|
|
1638
1903
|
}
|
|
1639
1904
|
if (ctx.triviaKindLabels) {
|
|
@@ -1663,6 +1928,10 @@ function scanTrivia(input, cur, ctx) {
|
|
|
1663
1928
|
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1664
1929
|
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1665
1930
|
}
|
|
1931
|
+
function scanTrivia(input, cur, ctx) {
|
|
1932
|
+
const scan = scanTriviaCompact(input, cur, ctx);
|
|
1933
|
+
return typeof scan === "number" ? { end: scan, commit: NOOP_COMMIT } : scan;
|
|
1934
|
+
}
|
|
1666
1935
|
function skipTriviaScanned(s, input, cur, ctx) {
|
|
1667
1936
|
const end = s(input, cur);
|
|
1668
1937
|
if (end !== cur) {
|
|
@@ -1675,14 +1944,12 @@ function skipTriviaScanned(s, input, cur, ctx) {
|
|
|
1675
1944
|
}
|
|
1676
1945
|
function consumeTrivia(input, cur, ctx) {
|
|
1677
1946
|
if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
|
|
1678
|
-
|
|
1679
|
-
scan.commit();
|
|
1680
|
-
return scan.end;
|
|
1947
|
+
return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
1681
1948
|
}
|
|
1682
1949
|
function probeTriviaEnd(input, cur, ctx) {
|
|
1683
1950
|
if (!ctx.trivia) return cur;
|
|
1684
1951
|
const probeCtx = { ...ctx, trackLines: false };
|
|
1685
|
-
if (needsDeferredTriviaCommit(probeCtx)) return
|
|
1952
|
+
if (needsDeferredTriviaCommit(probeCtx)) return triviaScanEnd(scanTriviaCompact(input, cur, probeCtx));
|
|
1686
1953
|
return advanceTrivia(input, cur, probeCtx);
|
|
1687
1954
|
}
|
|
1688
1955
|
function fastTriviaScanner(trivia2) {
|
|
@@ -1710,10 +1977,16 @@ function buildFastTriviaScanner(trivia2) {
|
|
|
1710
1977
|
const one = regexTriviaScanner(repeat);
|
|
1711
1978
|
if (one) return loopScanner([one]);
|
|
1712
1979
|
if (repeat._def.tag !== "choice") return null;
|
|
1980
|
+
const fused = commonCssTriviaScanner(repeat._def.parsers.map(triviaRegexSource));
|
|
1981
|
+
if (fused !== null) return fused;
|
|
1713
1982
|
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1714
1983
|
if (arms.some((s) => s === null)) return null;
|
|
1715
1984
|
return loopScanner(arms);
|
|
1716
1985
|
}
|
|
1986
|
+
function triviaRegexSource(parser) {
|
|
1987
|
+
const d = parser._def.tag === "label" ? parser._def.parser._def : parser._def;
|
|
1988
|
+
return d.tag === "regex" && d.flags === "" ? d.source : null;
|
|
1989
|
+
}
|
|
1717
1990
|
function loopScanner(arms) {
|
|
1718
1991
|
return (input, cur) => {
|
|
1719
1992
|
let pos = cur;
|
|
@@ -2166,9 +2439,7 @@ function sequence(...parsers) {
|
|
|
2166
2439
|
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2167
2440
|
let scanEnd;
|
|
2168
2441
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
2169
|
-
|
|
2170
|
-
scan.commit();
|
|
2171
|
-
scanEnd = scan.end;
|
|
2442
|
+
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
2172
2443
|
} else {
|
|
2173
2444
|
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2174
2445
|
}
|
|
@@ -2178,7 +2449,15 @@ function sequence(...parsers) {
|
|
|
2178
2449
|
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2179
2450
|
if (!result2.ok) return result2;
|
|
2180
2451
|
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2181
|
-
else rollbackScannedTriviaAt(
|
|
2452
|
+
else rollbackScannedTriviaAt(
|
|
2453
|
+
ctx,
|
|
2454
|
+
mTlog,
|
|
2455
|
+
scanTlog,
|
|
2456
|
+
mLog,
|
|
2457
|
+
scanLog,
|
|
2458
|
+
mRootLog,
|
|
2459
|
+
scanRootLog
|
|
2460
|
+
);
|
|
2182
2461
|
if (values !== void 0) values.push(result2.value);
|
|
2183
2462
|
continue;
|
|
2184
2463
|
}
|
|
@@ -2213,9 +2492,7 @@ function sequence(...parsers) {
|
|
|
2213
2492
|
const mLog = ctx._triviaLog?.length ?? 0;
|
|
2214
2493
|
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2215
2494
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
2216
|
-
|
|
2217
|
-
scan.commit();
|
|
2218
|
-
scanEnd = scan.end;
|
|
2495
|
+
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
2219
2496
|
} else {
|
|
2220
2497
|
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2221
2498
|
}
|
|
@@ -2225,7 +2502,15 @@ function sequence(...parsers) {
|
|
|
2225
2502
|
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2226
2503
|
if (!result2.ok) return result2;
|
|
2227
2504
|
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2228
|
-
else rollbackScannedTriviaAt(
|
|
2505
|
+
else rollbackScannedTriviaAt(
|
|
2506
|
+
ctx,
|
|
2507
|
+
mTlog,
|
|
2508
|
+
scanTlog,
|
|
2509
|
+
mLog,
|
|
2510
|
+
scanLog,
|
|
2511
|
+
mRootLog,
|
|
2512
|
+
scanRootLog
|
|
2513
|
+
);
|
|
2229
2514
|
if (values !== void 0) values.push(result2.value);
|
|
2230
2515
|
continue;
|
|
2231
2516
|
}
|
|
@@ -2257,9 +2542,7 @@ function sequence(...parsers) {
|
|
|
2257
2542
|
const mLog = ctx._triviaLog?.length ?? 0;
|
|
2258
2543
|
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2259
2544
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
2260
|
-
|
|
2261
|
-
scan.commit();
|
|
2262
|
-
scanEnd = scan.end;
|
|
2545
|
+
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
2263
2546
|
} else {
|
|
2264
2547
|
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2265
2548
|
}
|
|
@@ -2271,7 +2554,15 @@ function sequence(...parsers) {
|
|
|
2271
2554
|
if (result2.span.end > scanEnd) {
|
|
2272
2555
|
cur = result2.span.end;
|
|
2273
2556
|
} else {
|
|
2274
|
-
rollbackScannedTriviaAt(
|
|
2557
|
+
rollbackScannedTriviaAt(
|
|
2558
|
+
ctx,
|
|
2559
|
+
mTlog,
|
|
2560
|
+
scanTlog,
|
|
2561
|
+
mLog,
|
|
2562
|
+
scanLog,
|
|
2563
|
+
mRootLog,
|
|
2564
|
+
scanRootLog
|
|
2565
|
+
);
|
|
2275
2566
|
}
|
|
2276
2567
|
if (values !== void 0) values.push(result2.value);
|
|
2277
2568
|
continue;
|
|
@@ -2438,6 +2729,7 @@ function choice(...args) {
|
|
|
2438
2729
|
},
|
|
2439
2730
|
parse(input, pos, ctx) {
|
|
2440
2731
|
const expected = [];
|
|
2732
|
+
let expectedAt = pos;
|
|
2441
2733
|
if (disjoint) {
|
|
2442
2734
|
const code = pos < input.length ? input.codePointAt(pos) : -1;
|
|
2443
2735
|
let idx = code >= 0 && code < 128 ? asciiDispatch[code] : -1;
|
|
@@ -2495,7 +2787,12 @@ function choice(...args) {
|
|
|
2495
2787
|
const result = parsers[i].parse(input, pos, ctx);
|
|
2496
2788
|
if (!result.ok) {
|
|
2497
2789
|
rollbackTrivia(ctx, mark);
|
|
2498
|
-
|
|
2790
|
+
const at = result.span.start;
|
|
2791
|
+
if (at > expectedAt) {
|
|
2792
|
+
expectedAt = at;
|
|
2793
|
+
expected.length = 0;
|
|
2794
|
+
}
|
|
2795
|
+
if (at === expectedAt) expected.push(...result.expected);
|
|
2499
2796
|
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
2500
2797
|
continue;
|
|
2501
2798
|
}
|
|
@@ -2506,6 +2803,9 @@ function choice(...args) {
|
|
|
2506
2803
|
}
|
|
2507
2804
|
return result;
|
|
2508
2805
|
}
|
|
2806
|
+
if (expected.length === 0) {
|
|
2807
|
+
for (const parser of parsers) expected.push(...deriveExpected(parser));
|
|
2808
|
+
}
|
|
2509
2809
|
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
2510
2810
|
}
|
|
2511
2811
|
};
|
|
@@ -2692,9 +2992,7 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
|
2692
2992
|
let pos = cur;
|
|
2693
2993
|
if (ctx.trivia) {
|
|
2694
2994
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
2695
|
-
|
|
2696
|
-
scan.commit();
|
|
2697
|
-
pos = scan.end;
|
|
2995
|
+
pos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
2698
2996
|
} else {
|
|
2699
2997
|
pos = advanceTrivia(input, cur, ctx);
|
|
2700
2998
|
}
|
|
@@ -3411,6 +3709,12 @@ function confirmedArityForDef(def) {
|
|
|
3411
3709
|
});
|
|
3412
3710
|
return null;
|
|
3413
3711
|
}
|
|
3712
|
+
function buildReadsRaw(def) {
|
|
3713
|
+
if (!def.build) return true;
|
|
3714
|
+
const arity = confirmedArityForDef(def);
|
|
3715
|
+
if (arity === null) return true;
|
|
3716
|
+
return arity >= 4;
|
|
3717
|
+
}
|
|
3414
3718
|
function buildReadsTrivia(def) {
|
|
3415
3719
|
if (!def.build) return true;
|
|
3416
3720
|
const arity = confirmedArityForDef(def);
|
|
@@ -3606,6 +3910,8 @@ var OP_ATTEMPT = 38;
|
|
|
3606
3910
|
var OP_LABEL = 39;
|
|
3607
3911
|
var OP_COV = 40;
|
|
3608
3912
|
var OP_SCOPE_PLAIN = 41;
|
|
3913
|
+
var OP_LEX_BODY = 42;
|
|
3914
|
+
var OP_LEX_PROGRAM = 43;
|
|
3609
3915
|
var OP_DISPATCH = 25;
|
|
3610
3916
|
var OP_ROUTED = 26;
|
|
3611
3917
|
var OP_NAMES = {
|
|
@@ -3649,9 +3955,409 @@ var OP_NAMES = {
|
|
|
3649
3955
|
[OP_ATTEMPT]: "ATTEMPT",
|
|
3650
3956
|
[OP_LABEL]: "LABEL",
|
|
3651
3957
|
[OP_COV]: "COV",
|
|
3652
|
-
[OP_SCOPE_PLAIN]: "SCOPE_PLAIN"
|
|
3958
|
+
[OP_SCOPE_PLAIN]: "SCOPE_PLAIN",
|
|
3959
|
+
[OP_LEX_BODY]: "LEX_BODY",
|
|
3960
|
+
[OP_LEX_PROGRAM]: "LEX_PROGRAM"
|
|
3653
3961
|
};
|
|
3654
3962
|
|
|
3963
|
+
// src/table/lex-body.ts
|
|
3964
|
+
function buildLexBodyRecognizer(spec, constants) {
|
|
3965
|
+
const raw = constants[spec[0]];
|
|
3966
|
+
if (!(raw instanceof RegExp)) {
|
|
3967
|
+
throw new TypeError("table lexical body does not reference a RegExp constant");
|
|
3968
|
+
}
|
|
3969
|
+
if (!Number.isInteger(spec[1]) || spec[1] < -1 || spec[1] > 65535) {
|
|
3970
|
+
throw new TypeError("table lexical body suffix is not absent or one UTF-16 code unit");
|
|
3971
|
+
}
|
|
3972
|
+
const re = raw.sticky ? new RegExp(raw.source, raw.flags) : new RegExp(raw.source, `${raw.flags.replace(/[gy]/g, "")}y`);
|
|
3973
|
+
const suffix = spec[1];
|
|
3974
|
+
return (input, pos) => {
|
|
3975
|
+
re.lastIndex = pos;
|
|
3976
|
+
if (!re.test(input)) return -1;
|
|
3977
|
+
const end = re.lastIndex;
|
|
3978
|
+
if (suffix < 0) return end * 2;
|
|
3979
|
+
return input.charCodeAt(end) === suffix ? (end + 1) * 2 + 1 : end * 2;
|
|
3980
|
+
};
|
|
3981
|
+
}
|
|
3982
|
+
|
|
3983
|
+
// src/table/lex-program.ts
|
|
3984
|
+
var LEX_NODE_TERMINAL = 0;
|
|
3985
|
+
var LEX_NODE_SEQUENCE2 = 1;
|
|
3986
|
+
var LEX_NODE_SEQUENCE3 = 2;
|
|
3987
|
+
var LEX_NODE_SEQUENCE4 = 3;
|
|
3988
|
+
var LEX_NODE_SEQUENCE5 = 4;
|
|
3989
|
+
var LEX_NODE_CHOICE2 = 5;
|
|
3990
|
+
var LEX_NODE_CHOICE4 = 6;
|
|
3991
|
+
var LEX_NODE_CHOICE8 = 7;
|
|
3992
|
+
var LEX_NODE_NOT = 8;
|
|
3993
|
+
var LEX_NODE_OPTIONAL = 9;
|
|
3994
|
+
function lexProgramDigest(words) {
|
|
3995
|
+
let hash = 2166136261;
|
|
3996
|
+
for (const word of words) {
|
|
3997
|
+
hash ^= word | 0;
|
|
3998
|
+
hash = Math.imul(hash, 16777619);
|
|
3999
|
+
}
|
|
4000
|
+
return hash | 0;
|
|
4001
|
+
}
|
|
4002
|
+
function classHas(cls, code) {
|
|
4003
|
+
if (code < 0) return false;
|
|
4004
|
+
if (code < 128) return cls.ascii[code] === 1;
|
|
4005
|
+
for (let i = 0; i < cls.hi.length; i += 2) {
|
|
4006
|
+
if (code >= cls.hi[i] && code <= cls.hi[i + 1]) return true;
|
|
4007
|
+
}
|
|
4008
|
+
return false;
|
|
4009
|
+
}
|
|
4010
|
+
var committed = (ctx) => ctx._fc === true;
|
|
4011
|
+
function trackLexLines(ctx, input, end) {
|
|
4012
|
+
let at = ctx._lineScannedTo ?? 0;
|
|
4013
|
+
const starts = ctx._lineStarts;
|
|
4014
|
+
if (starts === void 0 || end <= at) return;
|
|
4015
|
+
while (at < end) {
|
|
4016
|
+
if (input.charCodeAt(at) === 10) starts.push(at + 1);
|
|
4017
|
+
at++;
|
|
4018
|
+
}
|
|
4019
|
+
ctx._lineScannedTo = end;
|
|
4020
|
+
}
|
|
4021
|
+
function terminalNode(matcher, failure, tracksLines) {
|
|
4022
|
+
const match = (input, pos) => {
|
|
4023
|
+
const result = matcher(input, pos);
|
|
4024
|
+
return result < 0 ? -1 : result / 2;
|
|
4025
|
+
};
|
|
4026
|
+
return {
|
|
4027
|
+
match,
|
|
4028
|
+
run: (input, pos, ctx) => {
|
|
4029
|
+
const end = match(input, pos);
|
|
4030
|
+
if (end < 0) {
|
|
4031
|
+
ctx._fe = pos;
|
|
4032
|
+
ctx._fx = failure;
|
|
4033
|
+
if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
|
|
4034
|
+
return -1;
|
|
4035
|
+
}
|
|
4036
|
+
if (tracksLines) trackLexLines(ctx, input, end);
|
|
4037
|
+
return end;
|
|
4038
|
+
}
|
|
4039
|
+
};
|
|
4040
|
+
}
|
|
4041
|
+
function sequence2(a, b) {
|
|
4042
|
+
return {
|
|
4043
|
+
match: (input, pos) => {
|
|
4044
|
+
const e0 = a.match(input, pos);
|
|
4045
|
+
return e0 < 0 ? -1 : b.match(input, e0);
|
|
4046
|
+
},
|
|
4047
|
+
run: (input, pos, ctx) => {
|
|
4048
|
+
const e0 = a.run(input, pos, ctx);
|
|
4049
|
+
if (e0 < 0) return -1;
|
|
4050
|
+
ctx._fc = false;
|
|
4051
|
+
return b.run(input, e0, ctx);
|
|
4052
|
+
}
|
|
4053
|
+
};
|
|
4054
|
+
}
|
|
4055
|
+
function sequence3(a, b, c) {
|
|
4056
|
+
return {
|
|
4057
|
+
match: (input, pos) => {
|
|
4058
|
+
const e0 = a.match(input, pos);
|
|
4059
|
+
if (e0 < 0) return -1;
|
|
4060
|
+
const e1 = b.match(input, e0);
|
|
4061
|
+
return e1 < 0 ? -1 : c.match(input, e1);
|
|
4062
|
+
},
|
|
4063
|
+
run: (input, pos, ctx) => {
|
|
4064
|
+
const e0 = a.run(input, pos, ctx);
|
|
4065
|
+
if (e0 < 0) return -1;
|
|
4066
|
+
ctx._fc = false;
|
|
4067
|
+
const e1 = b.run(input, e0, ctx);
|
|
4068
|
+
if (e1 < 0) return -1;
|
|
4069
|
+
ctx._fc = false;
|
|
4070
|
+
return c.run(input, e1, ctx);
|
|
4071
|
+
}
|
|
4072
|
+
};
|
|
4073
|
+
}
|
|
4074
|
+
function sequence4(a, b, c, d) {
|
|
4075
|
+
const abc = sequence3(a, b, c);
|
|
4076
|
+
return {
|
|
4077
|
+
match: (input, pos) => {
|
|
4078
|
+
const end = abc.match(input, pos);
|
|
4079
|
+
return end < 0 ? -1 : d.match(input, end);
|
|
4080
|
+
},
|
|
4081
|
+
run: (input, pos, ctx) => {
|
|
4082
|
+
const end = abc.run(input, pos, ctx);
|
|
4083
|
+
if (end < 0) return -1;
|
|
4084
|
+
ctx._fc = false;
|
|
4085
|
+
return d.run(input, end, ctx);
|
|
4086
|
+
}
|
|
4087
|
+
};
|
|
4088
|
+
}
|
|
4089
|
+
function sequence5(a, b, c, d, e) {
|
|
4090
|
+
const abcd = sequence4(a, b, c, d);
|
|
4091
|
+
return {
|
|
4092
|
+
match: (input, pos) => {
|
|
4093
|
+
const end = abcd.match(input, pos);
|
|
4094
|
+
return end < 0 ? -1 : e.match(input, end);
|
|
4095
|
+
},
|
|
4096
|
+
run: (input, pos, ctx) => {
|
|
4097
|
+
const end = abcd.run(input, pos, ctx);
|
|
4098
|
+
if (end < 0) return -1;
|
|
4099
|
+
ctx._fc = false;
|
|
4100
|
+
return e.run(input, end, ctx);
|
|
4101
|
+
}
|
|
4102
|
+
};
|
|
4103
|
+
}
|
|
4104
|
+
function appendExpected(acc, values) {
|
|
4105
|
+
if (values === void 0 || values.length === 0) return acc;
|
|
4106
|
+
if (acc === void 0) return values.slice();
|
|
4107
|
+
acc.push(...values);
|
|
4108
|
+
return acc;
|
|
4109
|
+
}
|
|
4110
|
+
function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
4111
|
+
let matchTail = () => -1;
|
|
4112
|
+
for (let i = arms.length - 1; i >= 0; i--) {
|
|
4113
|
+
const arm = arms[i], next = matchTail;
|
|
4114
|
+
matchTail = (input, pos) => {
|
|
4115
|
+
const end = arm.match(input, pos);
|
|
4116
|
+
return end < 0 ? next(input, pos) : end;
|
|
4117
|
+
};
|
|
4118
|
+
}
|
|
4119
|
+
let tail = (_input, pos, ctx, _lead, acc) => {
|
|
4120
|
+
ctx._fe = pos;
|
|
4121
|
+
ctx._fx = acc ?? choiceExpected;
|
|
4122
|
+
return -1;
|
|
4123
|
+
};
|
|
4124
|
+
for (let i = arms.length - 1; i >= 0; i--) {
|
|
4125
|
+
const arm = arms[i], cls = classes[i], staticExpected = armExpected[i], next = tail;
|
|
4126
|
+
tail = (input, pos, ctx, lead2, acc, best) => {
|
|
4127
|
+
if (cls !== void 0 && !classHas(cls, lead2)) {
|
|
4128
|
+
return next(
|
|
4129
|
+
input,
|
|
4130
|
+
pos,
|
|
4131
|
+
ctx,
|
|
4132
|
+
lead2,
|
|
4133
|
+
best === pos ? appendExpected(acc, staticExpected) : acc,
|
|
4134
|
+
best
|
|
4135
|
+
);
|
|
4136
|
+
}
|
|
4137
|
+
ctx._fc = false;
|
|
4138
|
+
const end = arm.run(input, pos, ctx);
|
|
4139
|
+
if (end >= 0) return end;
|
|
4140
|
+
const at = ctx._fe ?? pos;
|
|
4141
|
+
if (at > best) {
|
|
4142
|
+
best = at;
|
|
4143
|
+
acc = void 0;
|
|
4144
|
+
}
|
|
4145
|
+
const nextAcc = at === best ? appendExpected(acc, ctx._fx) : acc;
|
|
4146
|
+
if (committed(ctx)) {
|
|
4147
|
+
if (nextAcc !== void 0) ctx._fx = nextAcc;
|
|
4148
|
+
return -1;
|
|
4149
|
+
}
|
|
4150
|
+
return next(input, pos, ctx, lead2, nextAcc, best);
|
|
4151
|
+
};
|
|
4152
|
+
}
|
|
4153
|
+
return {
|
|
4154
|
+
match: matchTail,
|
|
4155
|
+
run: (input, pos, ctx) => tail(
|
|
4156
|
+
input,
|
|
4157
|
+
pos,
|
|
4158
|
+
ctx,
|
|
4159
|
+
pos < input.length ? input.codePointAt(pos) : -1,
|
|
4160
|
+
void 0,
|
|
4161
|
+
pos
|
|
4162
|
+
)
|
|
4163
|
+
};
|
|
4164
|
+
}
|
|
4165
|
+
function notNode(body, failure) {
|
|
4166
|
+
return {
|
|
4167
|
+
match: (input, pos) => body.match(input, pos) < 0 ? pos : -1,
|
|
4168
|
+
run: (input, pos, ctx) => {
|
|
4169
|
+
if (body.match(input, pos) < 0) return pos;
|
|
4170
|
+
ctx._fe = pos;
|
|
4171
|
+
ctx._fx = failure;
|
|
4172
|
+
return -1;
|
|
4173
|
+
}
|
|
4174
|
+
};
|
|
4175
|
+
}
|
|
4176
|
+
function optionalNode(body) {
|
|
4177
|
+
return {
|
|
4178
|
+
match: (input, pos) => {
|
|
4179
|
+
const end = body.match(input, pos);
|
|
4180
|
+
return end < 0 ? pos : end;
|
|
4181
|
+
},
|
|
4182
|
+
run: (input, pos, ctx) => {
|
|
4183
|
+
ctx._fc = false;
|
|
4184
|
+
const end = body.run(input, pos, ctx);
|
|
4185
|
+
return end < 0 && !committed(ctx) ? pos : end;
|
|
4186
|
+
}
|
|
4187
|
+
};
|
|
4188
|
+
}
|
|
4189
|
+
function fixedTreeRunner(words, matchers, classes, expected) {
|
|
4190
|
+
const stack = [];
|
|
4191
|
+
const pop = () => {
|
|
4192
|
+
const value = stack.pop();
|
|
4193
|
+
if (value === void 0) throw new TypeError("table lexical tree has an incomplete fixed body");
|
|
4194
|
+
return value;
|
|
4195
|
+
};
|
|
4196
|
+
for (let at = 0; at < words.length; ) {
|
|
4197
|
+
const op = words[at++];
|
|
4198
|
+
if (op === LEX_NODE_TERMINAL) {
|
|
4199
|
+
const matcher = matchers[words[at++]], failure = expected[words[at++]];
|
|
4200
|
+
const tracks = words[at++];
|
|
4201
|
+
if (matcher === void 0 || failure === void 0 || tracks !== 0 && tracks !== 1) {
|
|
4202
|
+
throw new TypeError("table lexical tree terminal references an invalid pool entry");
|
|
4203
|
+
}
|
|
4204
|
+
stack.push(terminalNode(matcher, failure, tracks === 1));
|
|
4205
|
+
continue;
|
|
4206
|
+
}
|
|
4207
|
+
if (op >= LEX_NODE_SEQUENCE2 && op <= LEX_NODE_SEQUENCE5) {
|
|
4208
|
+
const count = op - LEX_NODE_SEQUENCE2 + 2;
|
|
4209
|
+
const nodes = Array.from({ length: count }, pop).reverse();
|
|
4210
|
+
if (count === 2) stack.push(sequence2(nodes[0], nodes[1]));
|
|
4211
|
+
else if (count === 3) stack.push(sequence3(nodes[0], nodes[1], nodes[2]));
|
|
4212
|
+
else if (count === 4) stack.push(sequence4(nodes[0], nodes[1], nodes[2], nodes[3]));
|
|
4213
|
+
else stack.push(sequence5(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4]));
|
|
4214
|
+
continue;
|
|
4215
|
+
}
|
|
4216
|
+
if (op >= LEX_NODE_CHOICE2 && op <= LEX_NODE_CHOICE8) {
|
|
4217
|
+
const count = op === LEX_NODE_CHOICE2 ? 2 : op === LEX_NODE_CHOICE4 ? 4 : 8;
|
|
4218
|
+
const choiceFx = expected[words[at++]];
|
|
4219
|
+
if (choiceFx === void 0) throw new TypeError("table lexical tree choice has an invalid expected set");
|
|
4220
|
+
const armClasses = [];
|
|
4221
|
+
const armFx = [];
|
|
4222
|
+
for (let i = 0; i < count; i++) {
|
|
4223
|
+
const cls = words[at++], fx = expected[words[at++]];
|
|
4224
|
+
if (cls < -1 || cls >= 0 && classes[cls] === void 0 || fx === void 0) {
|
|
4225
|
+
throw new TypeError("table lexical tree choice references an invalid pool entry");
|
|
4226
|
+
}
|
|
4227
|
+
armClasses.push(cls < 0 ? void 0 : classes[cls]);
|
|
4228
|
+
armFx.push(fx);
|
|
4229
|
+
}
|
|
4230
|
+
const arms = Array.from({ length: count }, pop).reverse();
|
|
4231
|
+
stack.push(choiceNode(arms, armClasses, armFx, choiceFx));
|
|
4232
|
+
continue;
|
|
4233
|
+
}
|
|
4234
|
+
if (op === LEX_NODE_NOT) {
|
|
4235
|
+
const failure = expected[words[at++]];
|
|
4236
|
+
if (failure === void 0) throw new TypeError("table lexical tree assertion has an invalid expected set");
|
|
4237
|
+
stack.push(notNode(pop(), failure));
|
|
4238
|
+
continue;
|
|
4239
|
+
}
|
|
4240
|
+
if (op === LEX_NODE_OPTIONAL) {
|
|
4241
|
+
stack.push(optionalNode(pop()));
|
|
4242
|
+
continue;
|
|
4243
|
+
}
|
|
4244
|
+
throw new TypeError("table lexical tree has an unknown fixed body");
|
|
4245
|
+
}
|
|
4246
|
+
if (stack.length !== 1) throw new TypeError("table lexical tree does not resolve to one root body");
|
|
4247
|
+
return stack[0].run;
|
|
4248
|
+
}
|
|
4249
|
+
function buildLexProgramRunner(spec, matchers, classes, expected) {
|
|
4250
|
+
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) {
|
|
4251
|
+
throw new TypeError("table lexical program has an invalid fixed body width");
|
|
4252
|
+
}
|
|
4253
|
+
if (spec[1] !== lexProgramDigest(spec.slice(2))) {
|
|
4254
|
+
throw new TypeError("table lexical program semantic digest is inconsistent");
|
|
4255
|
+
}
|
|
4256
|
+
if (spec[0] === 3) {
|
|
4257
|
+
if (!Number.isInteger(spec[2]) || spec[2] < 0) {
|
|
4258
|
+
throw new TypeError("table balanced lexical program has an invalid scan reference");
|
|
4259
|
+
}
|
|
4260
|
+
const run = (_input, _pos, ctx, scan) => {
|
|
4261
|
+
if (scan === void 0) throw new TypeError("table balanced lexical program lost its scan body");
|
|
4262
|
+
const result = scan.parse(_input, _pos, ctx);
|
|
4263
|
+
if (!result.ok) {
|
|
4264
|
+
ctx._fe = result.span.start;
|
|
4265
|
+
ctx._fx = result.expected ?? [];
|
|
4266
|
+
return -1;
|
|
4267
|
+
}
|
|
4268
|
+
return result.span.end;
|
|
4269
|
+
};
|
|
4270
|
+
return Object.assign(run, { scan: spec[2] });
|
|
4271
|
+
}
|
|
4272
|
+
if (spec[0] === 2) return fixedTreeRunner(spec.slice(2), matchers, classes, expected);
|
|
4273
|
+
if (spec[0] === 1) {
|
|
4274
|
+
const g00 = matchers[spec[2]], g01 = matchers[spec[3]];
|
|
4275
|
+
const g02 = matchers[spec[4]], g03 = matchers[spec[5]];
|
|
4276
|
+
const guard0Fx = expected[spec[6]];
|
|
4277
|
+
const g1 = matchers[spec[7]], guard1Fx = expected[spec[8]];
|
|
4278
|
+
const terminal = matchers[spec[9]], terminalFx = expected[spec[10]];
|
|
4279
|
+
const tracks2 = spec[11];
|
|
4280
|
+
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) {
|
|
4281
|
+
throw new TypeError("table lexical program references an invalid pool entry");
|
|
4282
|
+
}
|
|
4283
|
+
return (input, pos, ctx) => {
|
|
4284
|
+
ctx._fc = false;
|
|
4285
|
+
if (g00(input, pos) >= 0 || g01(input, pos) >= 0 || g02(input, pos) >= 0 || g03(input, pos) >= 0) {
|
|
4286
|
+
ctx._fe = pos;
|
|
4287
|
+
ctx._fx = guard0Fx;
|
|
4288
|
+
return -1;
|
|
4289
|
+
}
|
|
4290
|
+
ctx._fc = false;
|
|
4291
|
+
if (g1(input, pos) >= 0) {
|
|
4292
|
+
ctx._fe = pos;
|
|
4293
|
+
ctx._fx = guard1Fx;
|
|
4294
|
+
return -1;
|
|
4295
|
+
}
|
|
4296
|
+
ctx._fc = false;
|
|
4297
|
+
const result = terminal(input, pos);
|
|
4298
|
+
if (result < 0) {
|
|
4299
|
+
ctx._fe = pos;
|
|
4300
|
+
ctx._fx = terminalFx;
|
|
4301
|
+
if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
|
|
4302
|
+
return -1;
|
|
4303
|
+
}
|
|
4304
|
+
const end = result / 2;
|
|
4305
|
+
if (tracks2 === 1) trackLexLines(ctx, input, end);
|
|
4306
|
+
return end;
|
|
4307
|
+
};
|
|
4308
|
+
}
|
|
4309
|
+
const cls = classes[spec[2]];
|
|
4310
|
+
const choiceFx = expected[spec[3]];
|
|
4311
|
+
const m0 = matchers[spec[4]], x0 = expected[spec[5]];
|
|
4312
|
+
const m1 = matchers[spec[6]], x1 = expected[spec[7]];
|
|
4313
|
+
const m2 = matchers[spec[8]], x2 = expected[spec[9]];
|
|
4314
|
+
const m3 = matchers[spec[10]], x3 = expected[spec[11]];
|
|
4315
|
+
const tracks = spec[12];
|
|
4316
|
+
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) {
|
|
4317
|
+
throw new TypeError("table lexical program references an invalid pool entry");
|
|
4318
|
+
}
|
|
4319
|
+
return (input, pos, ctx) => {
|
|
4320
|
+
const lead2 = pos < input.length ? input.codePointAt(pos) : -1;
|
|
4321
|
+
if (!classHas(cls, lead2)) {
|
|
4322
|
+
ctx._fe = pos;
|
|
4323
|
+
ctx._fx = choiceFx.slice();
|
|
4324
|
+
return -1;
|
|
4325
|
+
}
|
|
4326
|
+
let acc;
|
|
4327
|
+
const failed = (fx) => {
|
|
4328
|
+
ctx._fe = pos;
|
|
4329
|
+
ctx._fx = fx;
|
|
4330
|
+
if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
|
|
4331
|
+
if (acc === void 0) acc = fx.slice();
|
|
4332
|
+
else acc.push(...fx);
|
|
4333
|
+
};
|
|
4334
|
+
ctx._fc = false;
|
|
4335
|
+
const success = (result2) => {
|
|
4336
|
+
const end = result2 / 2;
|
|
4337
|
+
if (tracks === 1) trackLexLines(ctx, input, end);
|
|
4338
|
+
return end;
|
|
4339
|
+
};
|
|
4340
|
+
let result = m0(input, pos);
|
|
4341
|
+
if (result >= 0) return success(result);
|
|
4342
|
+
failed(x0);
|
|
4343
|
+
ctx._fc = false;
|
|
4344
|
+
result = m1(input, pos);
|
|
4345
|
+
if (result >= 0) return success(result);
|
|
4346
|
+
failed(x1);
|
|
4347
|
+
ctx._fc = false;
|
|
4348
|
+
result = m2(input, pos);
|
|
4349
|
+
if (result >= 0) return success(result);
|
|
4350
|
+
failed(x2);
|
|
4351
|
+
ctx._fc = false;
|
|
4352
|
+
result = m3(input, pos);
|
|
4353
|
+
if (result >= 0) return success(result);
|
|
4354
|
+
failed(x3);
|
|
4355
|
+
ctx._fe = pos;
|
|
4356
|
+
ctx._fx = acc ?? choiceFx;
|
|
4357
|
+
return -1;
|
|
4358
|
+
};
|
|
4359
|
+
}
|
|
4360
|
+
|
|
3655
4361
|
// src/table/program.ts
|
|
3656
4362
|
function closureArtifact(prog) {
|
|
3657
4363
|
return { ...prog, asm: [] };
|
|
@@ -3695,6 +4401,8 @@ function expandCompact(p) {
|
|
|
3695
4401
|
fns: p.f,
|
|
3696
4402
|
lines: p.l ?? 0,
|
|
3697
4403
|
dsp: p.p ?? [],
|
|
4404
|
+
...p.lx === void 0 ? {} : { lex: p.lx },
|
|
4405
|
+
...p.lp === void 0 ? {} : { lexPrograms: p.lp },
|
|
3698
4406
|
...p.lb === void 0 ? {} : { labels: p.lb },
|
|
3699
4407
|
...p.rc === void 0 ? {} : { classified: p.rc },
|
|
3700
4408
|
...p.h === void 0 ? {} : { hostMode: p.h },
|
|
@@ -3786,7 +4494,7 @@ function resolveClass(spec) {
|
|
|
3786
4494
|
}
|
|
3787
4495
|
return { ascii, hi };
|
|
3788
4496
|
}
|
|
3789
|
-
function
|
|
4497
|
+
function classHas2(cls, code) {
|
|
3790
4498
|
if (code < 0) return false;
|
|
3791
4499
|
if (code < 128) return cls.ascii[code] === 1;
|
|
3792
4500
|
const hi = cls.hi;
|
|
@@ -3839,6 +4547,7 @@ function resolveTable(prog) {
|
|
|
3839
4547
|
if (hit !== void 0) return hit;
|
|
3840
4548
|
const cc = prog.cc.map(resolveClass);
|
|
3841
4549
|
const triviaBuilt = (prog.triviaSpecs ?? []).map(buildTrivia);
|
|
4550
|
+
const lex = (prog.lex ?? []).map((spec) => buildLexBodyRecognizer(spec, prog.k));
|
|
3842
4551
|
const built = {
|
|
3843
4552
|
prog,
|
|
3844
4553
|
code: Int32Array.from(prog.code),
|
|
@@ -3857,6 +4566,8 @@ function resolveTable(prog) {
|
|
|
3857
4566
|
routed: d.routed,
|
|
3858
4567
|
expected: d.expected
|
|
3859
4568
|
})),
|
|
4569
|
+
lex,
|
|
4570
|
+
lexPrograms: (prog.lexPrograms ?? []).map((spec) => buildLexProgramRunner(spec, lex, cc, prog.fx)),
|
|
3860
4571
|
rules: prog.rules
|
|
3861
4572
|
};
|
|
3862
4573
|
if (owner !== void 0) owner.resolved = built;
|
|
@@ -3872,6 +4583,8 @@ var SHARED_FIELDS = [
|
|
|
3872
4583
|
"fx",
|
|
3873
4584
|
"disp",
|
|
3874
4585
|
"dsp",
|
|
4586
|
+
"lex",
|
|
4587
|
+
"lexPrograms",
|
|
3875
4588
|
"rules",
|
|
3876
4589
|
"labels",
|
|
3877
4590
|
"classified",
|
|
@@ -5018,6 +5731,8 @@ function childSlots(code, ip, out) {
|
|
|
5018
5731
|
case OP_GUARD:
|
|
5019
5732
|
case OP_ADJ:
|
|
5020
5733
|
case OP_LIVE:
|
|
5734
|
+
case OP_LEX_BODY:
|
|
5735
|
+
case OP_LEX_PROGRAM:
|
|
5021
5736
|
return true;
|
|
5022
5737
|
// Single child at `ip + 1`. `OP_COV` is a wrapper on the same footing as the
|
|
5023
5738
|
// rest — a coverage-encoded program is a program, and omitting it made
|
|
@@ -5135,7 +5850,12 @@ function transfer(code, ip, at, hostCst) {
|
|
|
5135
5850
|
return { tri, buf: at.buf, cap };
|
|
5136
5851
|
}
|
|
5137
5852
|
if (op === OP_NODE || op === OP_NODE_TRACK) {
|
|
5138
|
-
const
|
|
5853
|
+
const flags = code[ip + 3];
|
|
5854
|
+
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
|
|
5855
|
+
if (directChildren) {
|
|
5856
|
+
return { tri: at.tri, buf: false, cap: CAP_OFF };
|
|
5857
|
+
}
|
|
5858
|
+
const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
|
|
5139
5859
|
if (at.buf && cap === at.cap) return at;
|
|
5140
5860
|
return { tri: at.tri, buf: true, cap };
|
|
5141
5861
|
}
|
|
@@ -5176,6 +5896,43 @@ function computeSiteLabels(code, roots, hostCst) {
|
|
|
5176
5896
|
return { at: (ip) => labels.get(ip) ?? TOP };
|
|
5177
5897
|
}
|
|
5178
5898
|
|
|
5899
|
+
// src/table/scalar-terminal.ts
|
|
5900
|
+
function makeScalarRecognizer(op, spec) {
|
|
5901
|
+
if (op === OP_RX && spec instanceof RegExp) {
|
|
5902
|
+
return (input, pos) => {
|
|
5903
|
+
spec.lastIndex = pos;
|
|
5904
|
+
return spec.test(input) ? spec.lastIndex : -1;
|
|
5905
|
+
};
|
|
5906
|
+
}
|
|
5907
|
+
if (op !== OP_LIT || typeof spec !== "string") return void 0;
|
|
5908
|
+
const len = spec.length;
|
|
5909
|
+
if (len === 1) {
|
|
5910
|
+
const c0 = spec.charCodeAt(0);
|
|
5911
|
+
return (input, pos) => input.charCodeAt(pos) === c0 ? pos + 1 : -1;
|
|
5912
|
+
}
|
|
5913
|
+
if (len === 2) {
|
|
5914
|
+
const c0 = spec.charCodeAt(0), c1 = spec.charCodeAt(1);
|
|
5915
|
+
return (input, pos) => input.charCodeAt(pos) === c0 && input.charCodeAt(pos + 1) === c1 ? pos + 2 : -1;
|
|
5916
|
+
}
|
|
5917
|
+
if (len === 3) {
|
|
5918
|
+
const c0 = spec.charCodeAt(0), c1 = spec.charCodeAt(1), c2 = spec.charCodeAt(2);
|
|
5919
|
+
return (input, pos) => input.charCodeAt(pos) === c0 && input.charCodeAt(pos + 1) === c1 && input.charCodeAt(pos + 2) === c2 ? pos + 3 : -1;
|
|
5920
|
+
}
|
|
5921
|
+
return (input, pos) => input.startsWith(spec, pos) ? pos + len : -1;
|
|
5922
|
+
}
|
|
5923
|
+
function scalarTerminalNodeChild(code, ip) {
|
|
5924
|
+
if (code[ip + 1] < 0 || code[ip + 3] !== 0 || code[ip + 4] !== -1) return -1;
|
|
5925
|
+
const child = code[ip + 2];
|
|
5926
|
+
const op = code[child];
|
|
5927
|
+
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
5928
|
+
}
|
|
5929
|
+
function scalarTerminalNotChild(code, ip) {
|
|
5930
|
+
if (code[ip] !== OP_NOT) return -1;
|
|
5931
|
+
const child = code[ip + 1];
|
|
5932
|
+
const op = code[child];
|
|
5933
|
+
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
5934
|
+
}
|
|
5935
|
+
|
|
5179
5936
|
// src/table/emit-assembly.ts
|
|
5180
5937
|
var Unemittable = class extends Error {
|
|
5181
5938
|
construct;
|
|
@@ -5237,7 +5994,19 @@ var EMITTED_PARAMS = [
|
|
|
5237
5994
|
"matchesAt",
|
|
5238
5995
|
"recoverScan",
|
|
5239
5996
|
"orSentinel",
|
|
5240
|
-
"captureError"
|
|
5997
|
+
"captureError",
|
|
5998
|
+
// Pure scalar terminal recognizers, indexed by the terminal's existing const
|
|
5999
|
+
// operand. Appended for compatibility with older precompiled factories.
|
|
6000
|
+
"RECOG",
|
|
6001
|
+
// Appended so precompiled factories produced by earlier runtimes keep every
|
|
6002
|
+
// positional helper binding. Older factories ignore this trailing argument.
|
|
6003
|
+
"commitTriviaScan",
|
|
6004
|
+
"scanTriviaCompact",
|
|
6005
|
+
"LEX",
|
|
6006
|
+
// Appended for old precompiled-factory ABI: old factories ignore it.
|
|
6007
|
+
"adjacencyHolds",
|
|
6008
|
+
// Appended for selected composite lexical programs; old factories ignore it.
|
|
6009
|
+
"LEXPROG"
|
|
5241
6010
|
];
|
|
5242
6011
|
var RUNTIME_PRELUDE = `
|
|
5243
6012
|
let _pfScan=null
|
|
@@ -5248,7 +6017,7 @@ function _skipTrivia(input,cur,ctx){
|
|
|
5248
6017
|
const s=_pfScan
|
|
5249
6018
|
if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
|
|
5250
6019
|
if(s!==null)return skipTriviaScanned(s,input,cur,ctx)
|
|
5251
|
-
if(needsDeferredTriviaCommit(ctx))
|
|
6020
|
+
if(needsDeferredTriviaCommit(ctx))return commitTriviaScan(scanTriviaCompact(input,cur,ctx))
|
|
5252
6021
|
return advanceTrivia(input,cur,ctx)
|
|
5253
6022
|
}
|
|
5254
6023
|
function _pushLeaf(ctx,value,s,e){pushCstLeaf(ctx,{_tag:'leaf',value,span:{start:s,end:e}})}
|
|
@@ -5262,6 +6031,13 @@ if(b.raw!==undefined)b.raw.push(l)
|
|
|
5262
6031
|
else if(b.rawSingle!==undefined){b.raw=[b.rawSingle,l];b.rawSingle=undefined}
|
|
5263
6032
|
else b.rawSingle=l
|
|
5264
6033
|
}
|
|
6034
|
+
function _capturedFlatChildren(children){
|
|
6035
|
+
if(children.length===0)return EMPTY_CH
|
|
6036
|
+
if(children[0]!==undefined)return children
|
|
6037
|
+
let first=1
|
|
6038
|
+
while(first<children.length&&children[first]===undefined)first++
|
|
6039
|
+
return first===children.length?EMPTY_CH:children.slice(first)
|
|
6040
|
+
}
|
|
5265
6041
|
function _accSet(ax,acc){
|
|
5266
6042
|
if(ax===undefined||ax.length===0)return acc
|
|
5267
6043
|
if(acc===undefined)return ax.slice()
|
|
@@ -5396,12 +6172,16 @@ function maskForClassRow(gates) {
|
|
|
5396
6172
|
}
|
|
5397
6173
|
return m;
|
|
5398
6174
|
}
|
|
5399
|
-
function rebuildPools(cc, fx, plan) {
|
|
6175
|
+
function rebuildPools(cc, fx, disp, plan) {
|
|
5400
6176
|
const classes = plan.classes.map((row) => row.map((i) => i < 0 ? null : cc[i] ?? null));
|
|
5401
6177
|
return {
|
|
5402
6178
|
classes,
|
|
5403
6179
|
armExpected: plan.armExpected.map((row) => row.map((i) => fx[i] ?? [])),
|
|
5404
|
-
masks: plan.masks.map((
|
|
6180
|
+
masks: plan.masks.map((source) => {
|
|
6181
|
+
const row = source >= 0 ? classes[source] : disp[~source]?.armCls;
|
|
6182
|
+
if (row === void 0) throw new TypeError(`table emitter: invalid MASK plan source ${source}`);
|
|
6183
|
+
return maskForClassRow(row);
|
|
6184
|
+
})
|
|
5405
6185
|
};
|
|
5406
6186
|
}
|
|
5407
6187
|
function emitAssemblySource(t, prog, cfg, extraIps = []) {
|
|
@@ -5412,6 +6192,14 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
|
|
|
5412
6192
|
if (cfg.coverage) throw new Unemittable("a coverage assembly");
|
|
5413
6193
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
5414
6194
|
const labels = computeSiteLabels(code, roots, hostCst);
|
|
6195
|
+
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
6196
|
+
if (!hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
|
|
6197
|
+
for (const ip of reachableSites(code, roots)) {
|
|
6198
|
+
if (code[ip] !== OP_NODE) continue;
|
|
6199
|
+
const child = scalarTerminalNodeChild(code, ip);
|
|
6200
|
+
if (child >= 0) scalarSpecs.add(code[child + 1]);
|
|
6201
|
+
}
|
|
6202
|
+
}
|
|
5415
6203
|
const sinks = (() => {
|
|
5416
6204
|
let fd = false;
|
|
5417
6205
|
let er = REC;
|
|
@@ -5432,6 +6220,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
|
|
|
5432
6220
|
const reached = /* @__PURE__ */ new Set();
|
|
5433
6221
|
const prelude = [];
|
|
5434
6222
|
const skipDefs = [];
|
|
6223
|
+
const choiceDefs = [];
|
|
5435
6224
|
const skipPool = /* @__PURE__ */ new Map();
|
|
5436
6225
|
const pool = /* @__PURE__ */ new Map();
|
|
5437
6226
|
const masks = [];
|
|
@@ -5451,6 +6240,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
|
|
|
5451
6240
|
const kRef = (i) => hoist("k", `K[${i}]`);
|
|
5452
6241
|
const fxRef = (i) => hoist("fx", `FX[${i}]`);
|
|
5453
6242
|
const fnRef = (i) => hoist("fn", `FNS[${i}]`);
|
|
6243
|
+
const recognizerRef = (i) => hoist("rec", `RECOG[${i}]`);
|
|
5454
6244
|
const sentRef = (cls) => cls < 0 ? "undefined" : hoist("sent", `SENTS[${cls}]`);
|
|
5455
6245
|
let uid = 0;
|
|
5456
6246
|
const tmp = () => `_t${uid++}_`;
|
|
@@ -5464,8 +6254,8 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
|
|
|
5464
6254
|
const nm = `_sk${skipPool.size}`;
|
|
5465
6255
|
skipPool.set(key, nm);
|
|
5466
6256
|
if (!hasScan) {
|
|
5467
|
-
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){
|
|
5468
|
-
if(needsDeferredTriviaCommit(ctx))
|
|
6257
|
+
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return commitTriviaScan(scanTriviaCompact(input,cur,ctx))}` : `function ${nm}(input,cur,ctx){
|
|
6258
|
+
if(needsDeferredTriviaCommit(ctx))return commitTriviaScan(scanTriviaCompact(input,cur,ctx))
|
|
5469
6259
|
return advanceTrivia(input,cur,ctx)}`);
|
|
5470
6260
|
return nm;
|
|
5471
6261
|
}
|
|
@@ -5552,6 +6342,19 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
5552
6342
|
const s = k[code[ip + 1]];
|
|
5553
6343
|
const xf = fxRef(code[ip + 2]);
|
|
5554
6344
|
const track = op === OP_LIT_TRACK;
|
|
6345
|
+
if (!track && scalarSpecs.has(code[ip + 1])) {
|
|
6346
|
+
const recognize = recognizerRef(code[ip + 1]);
|
|
6347
|
+
return `${head}
|
|
6348
|
+
const e=${recognize}(input,pos)
|
|
6349
|
+
if(e>=0){
|
|
6350
|
+
${captureLeaf(q(s))}
|
|
6351
|
+
EC.e=e
|
|
6352
|
+
return ${q(s)}
|
|
6353
|
+
}
|
|
6354
|
+
ctx._fe=pos;ctx._fx=${xf}
|
|
6355
|
+
return FAIL
|
|
6356
|
+
}`;
|
|
6357
|
+
}
|
|
5555
6358
|
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)`;
|
|
5556
6359
|
return `${head}
|
|
5557
6360
|
if(${test}){
|
|
@@ -5601,12 +6404,26 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
5601
6404
|
case OP_RX_TRACK: {
|
|
5602
6405
|
const xf = fxRef(code[ip + 2]);
|
|
5603
6406
|
const track = op === OP_RX_TRACK;
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
6407
|
+
if (!track && scalarSpecs.has(code[ip + 1])) {
|
|
6408
|
+
const recognize = recognizerRef(code[ip + 1]);
|
|
6409
|
+
return `${head}
|
|
6410
|
+
const e=${recognize}(input,pos)
|
|
6411
|
+
if(e>=0){
|
|
6412
|
+
const v=input.slice(pos,e)
|
|
6413
|
+
${captureLeaf("v")}
|
|
6414
|
+
EC.e=e
|
|
6415
|
+
return v
|
|
6416
|
+
}
|
|
6417
|
+
ctx._fe=pos;ctx._fx=${xf}
|
|
6418
|
+
return FAIL
|
|
6419
|
+
}`;
|
|
6420
|
+
}
|
|
6421
|
+
const scanned = emitScan(code[ip + 1], xf, track, captureLeaf);
|
|
6422
|
+
if (scanned !== void 0) return `${head}${scanned}}`;
|
|
6423
|
+
const rxk = k[code[ip + 1]];
|
|
6424
|
+
if (!(rxk instanceof RegExp) || !rxk.sticky) throw new Unemittable("a non-sticky regex row");
|
|
6425
|
+
const re = kRef(code[ip + 1]);
|
|
6426
|
+
return `${head}
|
|
5610
6427
|
${re}.lastIndex=pos
|
|
5611
6428
|
if(${re}.test(input)){
|
|
5612
6429
|
const e=${re}.lastIndex
|
|
@@ -5762,6 +6579,73 @@ const out=${isToken ? "input.slice(pos,e)" : `${fn}(v,{start:pos,end:e})`}
|
|
|
5762
6579
|
if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:out,span:{start:pos,end:e}})
|
|
5763
6580
|
EC.e=e
|
|
5764
6581
|
return out
|
|
6582
|
+
}`;
|
|
6583
|
+
}
|
|
6584
|
+
case OP_LEX_BODY: {
|
|
6585
|
+
const recognize = hoist("lex", `LEX[${code[ip + 1]}]`);
|
|
6586
|
+
const expected = fxRef(code[ip + 2]);
|
|
6587
|
+
const suffixExpected = fxRef(code[ip + 3]);
|
|
6588
|
+
const lineFlags = code[ip + 4];
|
|
6589
|
+
const hasSuffix = (lineFlags & 4) !== 0;
|
|
6590
|
+
return `${head}
|
|
6591
|
+
const r=${recognize}(input,pos)
|
|
6592
|
+
if(r<0){ctx._fe=pos;ctx._fx=${expected};if(ctx._probe!==undefined)failAt(ctx,${expected},pos);return FAIL}
|
|
6593
|
+
const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
|
|
6594
|
+
${(lineFlags & 1) !== 0 ? "_trackLines(ctx,input,sm?e-1:e)" : ""}
|
|
6595
|
+
${hasSuffix ? "ctx._fc=false" : ""}
|
|
6596
|
+
${hasSuffix && (lineFlags & 2) !== 0 ? "if(sm)_trackLines(ctx,input,e)" : ""}
|
|
6597
|
+
${hasSuffix ? `if(!sm){ctx._fe=e;ctx._fx=${suffixExpected};if(ctx._probe!==undefined)failAt(ctx,${suffixExpected},e)}` : ""}
|
|
6598
|
+
const v=input.slice(pos,e)
|
|
6599
|
+
if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
|
|
6600
|
+
EC.e=e
|
|
6601
|
+
return v
|
|
6602
|
+
}`;
|
|
6603
|
+
}
|
|
6604
|
+
case OP_LEX_PROGRAM: {
|
|
6605
|
+
const programId = code[ip + 1];
|
|
6606
|
+
const run = hoist("lexProgram", `LEXPROG[${programId}]`);
|
|
6607
|
+
const scanId = t.lexPrograms[programId].scan;
|
|
6608
|
+
if (scanId !== void 0) return `${head}
|
|
6609
|
+
const sTri=ctx.trivia,sKinds=ctx.triviaKindLabels,sScan=_pfScan
|
|
6610
|
+
const sBuf=ctx._cstBuf,sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
6611
|
+
const sOtl=ctx._triviaLog,sRtl=ctx._rootTriviaLog
|
|
6612
|
+
const wasCap=ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined
|
|
6613
|
+
_pfScan=null
|
|
6614
|
+
ctx.trivia=undefined
|
|
6615
|
+
ctx.triviaKindLabels=undefined
|
|
6616
|
+
ctx._cstBuf=undefined
|
|
6617
|
+
ctx._cstChildren=undefined
|
|
6618
|
+
ctx._cstLeaves=undefined
|
|
6619
|
+
ctx._cstRawChildren=undefined
|
|
6620
|
+
ctx._cstTriviaLog=undefined
|
|
6621
|
+
ctx._triviaLog=undefined
|
|
6622
|
+
ctx._rootTriviaLog=undefined
|
|
6623
|
+
let e
|
|
6624
|
+
try{e=${run}(input,pos,ctx,SCANS[${scanId}])}finally{
|
|
6625
|
+
_pfScan=sScan
|
|
6626
|
+
ctx.trivia=sTri
|
|
6627
|
+
ctx.triviaKindLabels=sKinds
|
|
6628
|
+
ctx._cstBuf=sBuf
|
|
6629
|
+
ctx._cstChildren=sCh
|
|
6630
|
+
ctx._cstLeaves=sLv
|
|
6631
|
+
ctx._cstRawChildren=sRaw
|
|
6632
|
+
ctx._cstTriviaLog=sTl
|
|
6633
|
+
ctx._triviaLog=sOtl
|
|
6634
|
+
ctx._rootTriviaLog=sRtl
|
|
6635
|
+
}
|
|
6636
|
+
if(e<0)return FAIL
|
|
6637
|
+
const v=input.slice(pos,e)
|
|
6638
|
+
if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
|
|
6639
|
+
EC.e=e
|
|
6640
|
+
return v
|
|
6641
|
+
}`;
|
|
6642
|
+
return `${head}
|
|
6643
|
+
const e=${run}(input,pos,ctx)
|
|
6644
|
+
if(e<0)return FAIL
|
|
6645
|
+
const v=input.slice(pos,e)
|
|
6646
|
+
if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
|
|
6647
|
+
EC.e=e
|
|
6648
|
+
return v
|
|
5765
6649
|
}`;
|
|
5766
6650
|
}
|
|
5767
6651
|
/* ── transaction ─────────────────────────────────────────────────────── */
|
|
@@ -5779,6 +6663,18 @@ return FAIL
|
|
|
5779
6663
|
}`;
|
|
5780
6664
|
}
|
|
5781
6665
|
case OP_NOT: {
|
|
6666
|
+
const scalarChild = scalarTerminalNotChild(code, ip);
|
|
6667
|
+
if (scalarChild >= 0) {
|
|
6668
|
+
const recognize = recognizerRef(code[scalarChild + 1]);
|
|
6669
|
+
const xf2 = fxRef(code[ip + 2]);
|
|
6670
|
+
return `${head}
|
|
6671
|
+
if(${recognize}(input,pos)<0){EC.e=pos;return null}
|
|
6672
|
+
ctx._fe=pos
|
|
6673
|
+
ctx._fx=${xf2}
|
|
6674
|
+
EC.e=pos
|
|
6675
|
+
return FAIL
|
|
6676
|
+
}`;
|
|
6677
|
+
}
|
|
5782
6678
|
const child = link(code[ip + 1]);
|
|
5783
6679
|
const xf = fxRef(code[ip + 2]);
|
|
5784
6680
|
const p = tmp();
|
|
@@ -5828,14 +6724,14 @@ return v
|
|
|
5828
6724
|
const base = fused ? ip + 3 : ip + 2;
|
|
5829
6725
|
const n = code[fused ? ip + 2 : ip + 1];
|
|
5830
6726
|
const wantValues = op !== OP_SEQV;
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
}
|
|
5835
|
-
}
|
|
5836
|
-
const fn = fused ? fnRef(code[ip + 1]) : void 0;
|
|
6727
|
+
const reducer = fused ? code[ip + 1] : -1;
|
|
6728
|
+
const projection = reducer < 0 ? ~reducer : -1;
|
|
6729
|
+
const fn = fused && projection < 0 ? fnRef(reducer) : void 0;
|
|
5837
6730
|
const kids = [];
|
|
5838
|
-
for (let i = 0; i < n; i++)
|
|
6731
|
+
for (let i = 0; i < n; i++) {
|
|
6732
|
+
const childIp = code[base + i];
|
|
6733
|
+
kids.push(code[childIp] === OP_ADJ ? "" : link(childIp));
|
|
6734
|
+
}
|
|
5839
6735
|
const sy = REC ? `${tmp()}sy` : "";
|
|
5840
6736
|
const pub = (i) => {
|
|
5841
6737
|
const s = sentRef(code[base + n + i]);
|
|
@@ -5849,7 +6745,7 @@ return v
|
|
|
5849
6745
|
}` : `${parts.join("\n")}
|
|
5850
6746
|
}`;
|
|
5851
6747
|
if (n === 1) {
|
|
5852
|
-
parts.push(fused ? `return ${fn}([v0],{start:pos,end:EC.e})` : wantValues ? "return [v0]" : "return undefined");
|
|
6748
|
+
parts.push(fused ? projection === 0 ? "return v0" : `return ${fn}([v0],{start:pos,end:EC.e})` : wantValues ? "return [v0]" : "return undefined");
|
|
5853
6749
|
return close();
|
|
5854
6750
|
}
|
|
5855
6751
|
parts.push("let cur=EC.e");
|
|
@@ -5858,11 +6754,21 @@ return v
|
|
|
5858
6754
|
const vn = `v${i}`;
|
|
5859
6755
|
parts.push(`let ${vn}`);
|
|
5860
6756
|
if (REC) parts.push(pub(i));
|
|
5861
|
-
|
|
6757
|
+
const childIp = code[base + i];
|
|
6758
|
+
if (code[childIp] === OP_ADJ) {
|
|
6759
|
+
const negated = code[childIp + 1] === 1;
|
|
6760
|
+
const ki = code[childIp + 2];
|
|
6761
|
+
const kinds = ki < 0 ? "undefined" : `K[${ki}]`;
|
|
6762
|
+
const expected = fxRef(code[childIp + 3]);
|
|
6763
|
+
parts.push(
|
|
6764
|
+
`if(!adjacencyHolds(input,cur,ctx,${negated ? "true" : "false"},${kinds})){ctx._fe=cur;ctx._fx=${expected};return FAIL}`,
|
|
6765
|
+
`${vn}=null`
|
|
6766
|
+
);
|
|
6767
|
+
} else parts.push(emitTerm(kids[i], vn, tmp(), L, skipFor(L)));
|
|
5862
6768
|
names.push(vn);
|
|
5863
6769
|
}
|
|
5864
6770
|
parts.push("EC.e=cur");
|
|
5865
|
-
parts.push(fused ? `return ${fn}([${names.join(",")}],{start:pos,end:cur})` : wantValues ? `return [${names.join(",")}]` : "return undefined");
|
|
6771
|
+
parts.push(fused ? projection >= 0 ? `return ${names[projection]}` : `return ${fn}([${names.join(",")}],{start:pos,end:cur})` : wantValues ? `return [${names.join(",")}]` : "return undefined");
|
|
5866
6772
|
return close();
|
|
5867
6773
|
}
|
|
5868
6774
|
case OP_CHOICE: {
|
|
@@ -5872,11 +6778,6 @@ return v
|
|
|
5872
6778
|
const base = ip + 4;
|
|
5873
6779
|
const arms = [];
|
|
5874
6780
|
for (let i = 0; i < n; i++) arms.push(link(code[base + i]));
|
|
5875
|
-
const axi = armExpected.push(
|
|
5876
|
-
Array.from({ length: n }, (_, i) => t.fx[code[base + n + i]])
|
|
5877
|
-
) - 1;
|
|
5878
|
-
armExpectedPlan.push(Array.from({ length: n }, (_, i) => code[base + n + i]));
|
|
5879
|
-
const afx = hoist("afx", `AFX[${axi}]`);
|
|
5880
6781
|
if (table.exclusive) {
|
|
5881
6782
|
const di = code[ip + 1];
|
|
5882
6783
|
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
@@ -5903,53 +6804,65 @@ ctx._fe=pos;ctx._fx=${choiceFx}
|
|
|
5903
6804
|
return FAIL
|
|
5904
6805
|
}`;
|
|
5905
6806
|
}
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
6807
|
+
{
|
|
6808
|
+
const di = code[ip + 1];
|
|
6809
|
+
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
6810
|
+
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
6811
|
+
const gateRefs = Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
6812
|
+
const maskable = n <= 32;
|
|
6813
|
+
const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
|
|
6814
|
+
if (maskable) maskPlan.push(~di);
|
|
6815
|
+
const p = tmp();
|
|
6816
|
+
const catchName = maskable ? `_cx${uid++}_` : "";
|
|
6817
|
+
if (maskable) {
|
|
6818
|
+
const catchCases = expected.map((e, i) => `case ${i}:if(target<=${i})return acc;acc=_accSet(${e},acc)`).join("\n");
|
|
6819
|
+
choiceDefs.push(`function ${catchName}(target,prev,acc){switch(prev){
|
|
6820
|
+
${catchCases}
|
|
6821
|
+
}return acc}`);
|
|
6822
|
+
}
|
|
6823
|
+
const maskArms = maskable ? arms.map((arm, i) => {
|
|
6824
|
+
return `if((bits&${1 << i})!==0){
|
|
5919
6825
|
ctx._fc=false
|
|
5920
|
-
{const v=${
|
|
6826
|
+
{const v=${arm}(input,pos,ctx)
|
|
5921
6827
|
if(v!==FAIL)return v}
|
|
5922
|
-
|
|
6828
|
+
if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
5923
6829
|
prev=${i + 1}
|
|
5924
|
-
|
|
6830
|
+
{const at=ctx._fe??pos
|
|
6831
|
+
if(at>best){best=at;acc=undefined}
|
|
6832
|
+
if(at===best)acc=_accSet(ctx._fx,acc)}
|
|
5925
6833
|
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
5926
6834
|
${emitRollback(p, L.buf, sinks)}
|
|
5927
|
-
}
|
|
5928
|
-
|
|
5929
|
-
if(${
|
|
6835
|
+
}`;
|
|
6836
|
+
}).join("\n") : "";
|
|
6837
|
+
const generalArms = arms.map((arm, i) => `if(${gateRefs[i]}===null||classHas(${gateRefs[i]},c)){
|
|
5930
6838
|
ctx._fc=false
|
|
5931
|
-
{const v=${
|
|
6839
|
+
{const v=${arm}(input,pos,ctx)
|
|
5932
6840
|
if(v!==FAIL)return v}
|
|
5933
|
-
|
|
6841
|
+
{const at=ctx._fe??pos
|
|
6842
|
+
if(at>best){best=at;acc=undefined}
|
|
6843
|
+
if(at===best)acc=_accSet(ctx._fx,acc)}
|
|
5934
6844
|
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
5935
6845
|
${emitRollback(p, L.buf, sinks)}
|
|
5936
|
-
}else acc=_accSet(${
|
|
5937
|
-
|
|
6846
|
+
}else if(best===pos)acc=_accSet(${expected[i]},acc)`).join("\n");
|
|
6847
|
+
return `${head}
|
|
5938
6848
|
const c=lead(input,pos)
|
|
5939
6849
|
${emitMark(p, L.buf, sinks)}
|
|
5940
6850
|
let acc
|
|
6851
|
+
let best=pos
|
|
5941
6852
|
${maskable ? `if(c<128){
|
|
5942
6853
|
const bits=${maskName}[c<0?128:c]
|
|
5943
6854
|
let prev=0
|
|
5944
6855
|
${maskArms}
|
|
5945
|
-
|
|
6856
|
+
if(best===pos)acc=${catchName}(${n},prev,acc)
|
|
5946
6857
|
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
5947
6858
|
return FAIL
|
|
5948
6859
|
}
|
|
5949
|
-
` : ""}
|
|
6860
|
+
` : ""}
|
|
6861
|
+
${generalArms}
|
|
5950
6862
|
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
5951
6863
|
return FAIL
|
|
5952
6864
|
}`;
|
|
6865
|
+
}
|
|
5953
6866
|
}
|
|
5954
6867
|
case OP_DISPATCH: {
|
|
5955
6868
|
const di = code[ip + 2];
|
|
@@ -5975,8 +6888,16 @@ return FAIL
|
|
|
5975
6888
|
return `asciiFoldKey(key).startsWith(${q(m[1])})`;
|
|
5976
6889
|
case 4:
|
|
5977
6890
|
return `asciiFoldKey(key).endsWith(${q(m[1])})`;
|
|
5978
|
-
default:
|
|
6891
|
+
default: {
|
|
6892
|
+
if (!m[2].includes("g") && !m[2].includes("y")) {
|
|
6893
|
+
try {
|
|
6894
|
+
new RegExp(m[1], m[2]);
|
|
6895
|
+
return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
|
|
6896
|
+
} catch {
|
|
6897
|
+
}
|
|
6898
|
+
}
|
|
5979
6899
|
return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
|
|
6900
|
+
}
|
|
5980
6901
|
}
|
|
5981
6902
|
};
|
|
5982
6903
|
const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
|
|
@@ -6034,6 +6955,15 @@ return [key,v]
|
|
|
6034
6955
|
const reportItem = (flags & 4) !== 0;
|
|
6035
6956
|
const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
|
|
6036
6957
|
const collect = op === OP_REP;
|
|
6958
|
+
let itemCls;
|
|
6959
|
+
if (!REC) {
|
|
6960
|
+
const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
|
|
6961
|
+
if (itemClassIndex >= 0) {
|
|
6962
|
+
const ci = classes.push([t.cc[itemClassIndex]]) - 1;
|
|
6963
|
+
classPlan.push([itemClassIndex]);
|
|
6964
|
+
itemCls = hoist("ri", `CLS[${ci}][0]`);
|
|
6965
|
+
}
|
|
6966
|
+
}
|
|
6037
6967
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
6038
6968
|
const p = tmp();
|
|
6039
6969
|
const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
|
|
@@ -6041,7 +6971,6 @@ return [key,v]
|
|
|
6041
6971
|
const skip = skipFor(L);
|
|
6042
6972
|
const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
|
|
6043
6973
|
const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
|
|
6044
|
-
const needMark = L.buf ? "true" : "needMark";
|
|
6045
6974
|
const pfd = sinks.fd ? `${p}fd` : "0";
|
|
6046
6975
|
const per = sinks.er ? `${p}er` : "undefined";
|
|
6047
6976
|
const rb = L.buf ? `_rbBuf(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
|
|
@@ -6086,11 +7015,13 @@ continue
|
|
|
6086
7015
|
return `${head}
|
|
6087
7016
|
const out=${collect ? "[]" : "undefined"}
|
|
6088
7017
|
${knownTrivia === void 0 ? "const hasTrivia=ctx.trivia!==undefined\n" : ""}${L.buf ? "" : "const needMark=_rollbackNeeded(ctx)\n"}${REC ? `const ${my}=ctx._sync
|
|
6089
|
-
` : ""}
|
|
7018
|
+
` : ""}${itemCls === void 0 ? "" : `const ${p}gate=ctx._probe===undefined
|
|
7019
|
+
`}let cur=pos
|
|
6090
7020
|
let count=0
|
|
6091
7021
|
for(;;){
|
|
6092
7022
|
${max >= 0 ? `if(count>=${max})break
|
|
6093
7023
|
` : ""}${sep !== void 0 ? `if(count>0&&count>=${min}&&cur>=input.length)break
|
|
7024
|
+
` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}&&!classHas(${itemCls},lead(input,cur)))break
|
|
6094
7025
|
` : ""}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` : ""}
|
|
6095
7026
|
${markBody}
|
|
6096
7027
|
let itemStart=cur
|
|
@@ -6115,7 +7046,11 @@ itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(inp
|
|
|
6115
7046
|
${rb}
|
|
6116
7047
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
6117
7048
|
}
|
|
6118
|
-
|
|
7049
|
+
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&!classHas(${itemCls},lead(input,itemStart))){
|
|
7050
|
+
${rb}
|
|
7051
|
+
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
7052
|
+
}
|
|
7053
|
+
`}ctx._fc=false
|
|
6119
7054
|
const v=${child}(input,itemStart,ctx)
|
|
6120
7055
|
if(v===FAIL){
|
|
6121
7056
|
${REC ? `if(ctx._fc===true){
|
|
@@ -6144,6 +7079,26 @@ return out
|
|
|
6144
7079
|
case OP_NODE:
|
|
6145
7080
|
case OP_NODE_TRACK: {
|
|
6146
7081
|
const flags = code[ip + 3];
|
|
7082
|
+
const scalarChild = scalarTerminalNodeChild(code, ip);
|
|
7083
|
+
if (scalarChild >= 0 && scalarSpecs.has(code[scalarChild + 1])) {
|
|
7084
|
+
const recognize = recognizerRef(code[scalarChild + 1]);
|
|
7085
|
+
const spec = code[scalarChild] === OP_RX ? null : k[code[scalarChild + 1]];
|
|
7086
|
+
const value2 = spec === null ? "input.slice(pos,end)" : q(spec);
|
|
7087
|
+
const xf = fxRef(code[scalarChild + 2]);
|
|
7088
|
+
const build2 = fnRef(code[ip + 1]);
|
|
7089
|
+
return `${head}
|
|
7090
|
+
const end=${recognize}(input,pos)
|
|
7091
|
+
if(end<0){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
7092
|
+
const value=${value2}
|
|
7093
|
+
const leaf={_tag:'leaf',value,span:{start:pos,end}}
|
|
7094
|
+
const kids=[leaf],rawKids=[leaf],span={start:pos,end}
|
|
7095
|
+
EC.e=end
|
|
7096
|
+
const nd=${build2}(kids,undefined,span,rawKids,EMPTY_TL,undefined)
|
|
7097
|
+
${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))"}
|
|
7098
|
+
EC.e=end
|
|
7099
|
+
return nd
|
|
7100
|
+
}`;
|
|
7101
|
+
}
|
|
6147
7102
|
const child = link(code[ip + 2]);
|
|
6148
7103
|
const proj = code[ip + 4];
|
|
6149
7104
|
const buildIdx = code[ip + 1];
|
|
@@ -6158,6 +7113,51 @@ return out
|
|
|
6158
7113
|
const unwrap = (flags & 64) !== 0;
|
|
6159
7114
|
const trailingTrivia = (flags & 128) !== 0;
|
|
6160
7115
|
const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
|
|
7116
|
+
if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
|
|
7117
|
+
const fields = flags === 18;
|
|
7118
|
+
const collapseChildren = flags === 34;
|
|
7119
|
+
const publish = `if(sBuf!==undefined){
|
|
7120
|
+
if(sBuf.rawOnly!==true){
|
|
7121
|
+
if(sBuf.ch!==undefined)sBuf.ch.push(nd)
|
|
7122
|
+
else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
|
|
7123
|
+
else sBuf.single=nd
|
|
7124
|
+
}
|
|
7125
|
+
const rawNd=rawEntry(nd,input,pos,end)
|
|
7126
|
+
if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
|
|
7127
|
+
else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
|
|
7128
|
+
else sBuf.rawSingle=rawNd
|
|
7129
|
+
}else if(sCh!==undefined){
|
|
7130
|
+
sCh.push(nd)
|
|
7131
|
+
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
7132
|
+
}`;
|
|
7133
|
+
return `${head}
|
|
7134
|
+
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
7135
|
+
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf,sFields=ctx._fields
|
|
7136
|
+
const flat=[]
|
|
7137
|
+
ctx._cstBuf=undefined
|
|
7138
|
+
ctx._cstChildren=flat
|
|
7139
|
+
ctx._cstLeaves=flat
|
|
7140
|
+
ctx._cstRawChildren=undefined
|
|
7141
|
+
ctx._cstTriviaLog=undefined
|
|
7142
|
+
ctx.captureTrivia=false
|
|
7143
|
+
ctx._fields=${fields ? "[]" : "undefined"}
|
|
7144
|
+
const v=${child}(input,pos,ctx)
|
|
7145
|
+
const captured=_capturedFlatChildren(flat)
|
|
7146
|
+
${fields ? "const fieldMap=buildFieldMap(ctx._fields)\n" : ""}ctx._fields=sFields
|
|
7147
|
+
ctx._cstBuf=sBuf
|
|
7148
|
+
ctx._cstChildren=sCh
|
|
7149
|
+
ctx._cstLeaves=sLv
|
|
7150
|
+
ctx._cstRawChildren=sRaw
|
|
7151
|
+
ctx._cstTriviaLog=sTl
|
|
7152
|
+
ctx.captureTrivia=sCap
|
|
7153
|
+
if(v===FAIL)return FAIL
|
|
7154
|
+
const end=EC.e
|
|
7155
|
+
${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)`}
|
|
7156
|
+
${publish}
|
|
7157
|
+
EC.e=end
|
|
7158
|
+
return nd
|
|
7159
|
+
}`;
|
|
7160
|
+
}
|
|
6161
7161
|
const structural = build === void 0 && proj < 0;
|
|
6162
7162
|
const grammarCapture = (flags & 1) !== 0 || trailingTrivia;
|
|
6163
7163
|
const hostCapturesThisType = structural && cfg.hostCaptureTrivia !== void 0 ? cfg.hostCaptureTrivia(type) : void 0;
|
|
@@ -6243,6 +7243,7 @@ return nd
|
|
|
6243
7243
|
const source = `${RUNTIME_PRELUDE}
|
|
6244
7244
|
${prelude.join("\n")}
|
|
6245
7245
|
${skipDefs.join("\n")}
|
|
7246
|
+
${choiceDefs.join("\n")}
|
|
6246
7247
|
${bodies.join("\n")}
|
|
6247
7248
|
function _begin(ctx){
|
|
6248
7249
|
const host=ctx.build
|
|
@@ -6350,7 +7351,7 @@ function opHistogram(prog) {
|
|
|
6350
7351
|
|
|
6351
7352
|
// src/table/stamp.ts
|
|
6352
7353
|
var EMPTY_FX = [];
|
|
6353
|
-
function
|
|
7354
|
+
function committed2(c) {
|
|
6354
7355
|
return c._fc === true;
|
|
6355
7356
|
}
|
|
6356
7357
|
function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(prog)) {
|
|
@@ -6400,7 +7401,7 @@ function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(pr
|
|
|
6400
7401
|
const fe = ctx._fe;
|
|
6401
7402
|
const at = fe === void 0 || fe < 0 ? pos : fe;
|
|
6402
7403
|
const fspan = lines ? spanLines(ctx, at, at) : { start: at, end: at };
|
|
6403
|
-
return
|
|
7404
|
+
return committed2(ctx) ? { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan, committed: true } : { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan };
|
|
6404
7405
|
}
|
|
6405
7406
|
return { ok: true, value: d.lastValue(), span: lines ? spanLines(ctx, pos, end) : { start: pos, end } };
|
|
6406
7407
|
};
|
|
@@ -6452,11 +7453,15 @@ function linkMatcher(m) {
|
|
|
6452
7453
|
return (key) => asciiFoldKey(key).startsWith(value);
|
|
6453
7454
|
case 4:
|
|
6454
7455
|
return (key) => asciiFoldKey(key).endsWith(value);
|
|
6455
|
-
// A fresh RegExp per test, as `matchesDispatchMatcher` builds — a cached one
|
|
6456
|
-
// would carry `lastIndex` across parses whenever the author's pattern was
|
|
6457
|
-
// sticky or global.
|
|
6458
7456
|
default: {
|
|
6459
7457
|
const flags = m[2];
|
|
7458
|
+
if (!flags.includes("g") && !flags.includes("y")) {
|
|
7459
|
+
try {
|
|
7460
|
+
const pattern = new RegExp(value, flags);
|
|
7461
|
+
return (key) => pattern.test(key);
|
|
7462
|
+
} catch {
|
|
7463
|
+
}
|
|
7464
|
+
}
|
|
6460
7465
|
return (key) => new RegExp(value, flags).test(key);
|
|
6461
7466
|
}
|
|
6462
7467
|
}
|
|
@@ -6487,6 +7492,17 @@ function assemble(t, prog, cfg) {
|
|
|
6487
7492
|
return made;
|
|
6488
7493
|
}
|
|
6489
7494
|
const EC = newEndCell();
|
|
7495
|
+
const scalarRecognizers = [];
|
|
7496
|
+
const rawScalarSpecs = /* @__PURE__ */ new Set();
|
|
7497
|
+
function scalarFor(child) {
|
|
7498
|
+
const spec = code[child + 1];
|
|
7499
|
+
let recognize = scalarRecognizers[spec];
|
|
7500
|
+
if (recognize === void 0) {
|
|
7501
|
+
recognize = makeScalarRecognizer(code[child], k[spec]);
|
|
7502
|
+
scalarRecognizers[spec] = recognize;
|
|
7503
|
+
}
|
|
7504
|
+
return recognize;
|
|
7505
|
+
}
|
|
6490
7506
|
let SCAN = null;
|
|
6491
7507
|
const memo = /* @__PURE__ */ new Map();
|
|
6492
7508
|
const reached = /* @__PURE__ */ new Set();
|
|
@@ -6494,6 +7510,234 @@ function assemble(t, prog, cfg) {
|
|
|
6494
7510
|
const lf = { _tag: "leaf", value, span: { start: s, end: e } };
|
|
6495
7511
|
pushCstLeaf(ctx, lf);
|
|
6496
7512
|
}
|
|
7513
|
+
function plainBuildNode(child, build) {
|
|
7514
|
+
return (input, pos, ctx) => {
|
|
7515
|
+
const sCh = ctx._cstChildren;
|
|
7516
|
+
const sLv = ctx._cstLeaves;
|
|
7517
|
+
const sRaw = ctx._cstRawChildren;
|
|
7518
|
+
const sTl = ctx._cstTriviaLog;
|
|
7519
|
+
const sCap = ctx.captureTrivia;
|
|
7520
|
+
const sBuf = ctx._cstBuf;
|
|
7521
|
+
const savedFields = ctx._fields;
|
|
7522
|
+
const buf = {};
|
|
7523
|
+
ctx._cstBuf = buf;
|
|
7524
|
+
ctx._cstChildren = void 0;
|
|
7525
|
+
ctx._cstLeaves = void 0;
|
|
7526
|
+
ctx._cstRawChildren = void 0;
|
|
7527
|
+
ctx._cstTriviaLog = void 0;
|
|
7528
|
+
ctx.captureTrivia = false;
|
|
7529
|
+
ctx._fields = void 0;
|
|
7530
|
+
const value = child(input, pos, ctx);
|
|
7531
|
+
const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
|
|
7532
|
+
const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
|
|
7533
|
+
ctx._fields = savedFields;
|
|
7534
|
+
ctx._cstBuf = sBuf;
|
|
7535
|
+
ctx._cstChildren = sCh;
|
|
7536
|
+
ctx._cstLeaves = sLv;
|
|
7537
|
+
ctx._cstRawChildren = sRaw;
|
|
7538
|
+
ctx._cstTriviaLog = sTl;
|
|
7539
|
+
ctx.captureTrivia = sCap;
|
|
7540
|
+
if (value === FAIL) return FAIL;
|
|
7541
|
+
const end = EC.e;
|
|
7542
|
+
const span = { start: pos, end };
|
|
7543
|
+
const node = build(kids, void 0, span, rawKids, EMPTY_TL, void 0);
|
|
7544
|
+
if (sBuf !== void 0 || sCh !== void 0) {
|
|
7545
|
+
pushCstChild(ctx, node, rawEntry(node, input, pos, end));
|
|
7546
|
+
}
|
|
7547
|
+
EC.e = end;
|
|
7548
|
+
return node;
|
|
7549
|
+
};
|
|
7550
|
+
}
|
|
7551
|
+
function capturedFlatChildren(children2) {
|
|
7552
|
+
if (children2.length === 0) return EMPTY_CH;
|
|
7553
|
+
if (children2[0] !== void 0) return children2;
|
|
7554
|
+
let first = 1;
|
|
7555
|
+
while (first < children2.length && children2[first] === void 0) first++;
|
|
7556
|
+
return first === children2.length ? EMPTY_CH : children2.slice(first);
|
|
7557
|
+
}
|
|
7558
|
+
function childrenOnlyBuildNode(child, build) {
|
|
7559
|
+
return (input, pos, ctx) => {
|
|
7560
|
+
const sCh = ctx._cstChildren;
|
|
7561
|
+
const sLv = ctx._cstLeaves;
|
|
7562
|
+
const sRaw = ctx._cstRawChildren;
|
|
7563
|
+
const sTl = ctx._cstTriviaLog;
|
|
7564
|
+
const sCap = ctx.captureTrivia;
|
|
7565
|
+
const sBuf = ctx._cstBuf;
|
|
7566
|
+
const savedFields = ctx._fields;
|
|
7567
|
+
const kids = [];
|
|
7568
|
+
ctx._cstBuf = void 0;
|
|
7569
|
+
ctx._cstChildren = kids;
|
|
7570
|
+
ctx._cstLeaves = kids;
|
|
7571
|
+
ctx._cstRawChildren = void 0;
|
|
7572
|
+
ctx._cstTriviaLog = void 0;
|
|
7573
|
+
ctx.captureTrivia = false;
|
|
7574
|
+
ctx._fields = void 0;
|
|
7575
|
+
const value = child(input, pos, ctx);
|
|
7576
|
+
const captured = capturedFlatChildren(kids);
|
|
7577
|
+
ctx._fields = savedFields;
|
|
7578
|
+
ctx._cstBuf = sBuf;
|
|
7579
|
+
ctx._cstChildren = sCh;
|
|
7580
|
+
ctx._cstLeaves = sLv;
|
|
7581
|
+
ctx._cstRawChildren = sRaw;
|
|
7582
|
+
ctx._cstTriviaLog = sTl;
|
|
7583
|
+
ctx.captureTrivia = sCap;
|
|
7584
|
+
if (value === FAIL) return FAIL;
|
|
7585
|
+
const end = EC.e;
|
|
7586
|
+
const node = build(captured, void 0, { start: pos, end }, EMPTY_CH, EMPTY_TL, void 0);
|
|
7587
|
+
if (sBuf !== void 0 || sCh !== void 0) {
|
|
7588
|
+
pushCstChild(ctx, node, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node, input, pos, end) : void 0);
|
|
7589
|
+
}
|
|
7590
|
+
EC.e = end;
|
|
7591
|
+
return node;
|
|
7592
|
+
};
|
|
7593
|
+
}
|
|
7594
|
+
function childrenOnlyFieldsBuildNode(child, build) {
|
|
7595
|
+
return (input, pos, ctx) => {
|
|
7596
|
+
const sCh = ctx._cstChildren;
|
|
7597
|
+
const sLv = ctx._cstLeaves;
|
|
7598
|
+
const sRaw = ctx._cstRawChildren;
|
|
7599
|
+
const sTl = ctx._cstTriviaLog;
|
|
7600
|
+
const sCap = ctx.captureTrivia;
|
|
7601
|
+
const sBuf = ctx._cstBuf;
|
|
7602
|
+
const savedFields = ctx._fields;
|
|
7603
|
+
const kids = [];
|
|
7604
|
+
ctx._cstBuf = void 0;
|
|
7605
|
+
ctx._cstChildren = kids;
|
|
7606
|
+
ctx._cstLeaves = kids;
|
|
7607
|
+
ctx._cstRawChildren = void 0;
|
|
7608
|
+
ctx._cstTriviaLog = void 0;
|
|
7609
|
+
ctx.captureTrivia = false;
|
|
7610
|
+
ctx._fields = [];
|
|
7611
|
+
const value = child(input, pos, ctx);
|
|
7612
|
+
const captured = capturedFlatChildren(kids);
|
|
7613
|
+
const fieldMap = buildFieldMap(ctx._fields);
|
|
7614
|
+
ctx._fields = savedFields;
|
|
7615
|
+
ctx._cstBuf = sBuf;
|
|
7616
|
+
ctx._cstChildren = sCh;
|
|
7617
|
+
ctx._cstLeaves = sLv;
|
|
7618
|
+
ctx._cstRawChildren = sRaw;
|
|
7619
|
+
ctx._cstTriviaLog = sTl;
|
|
7620
|
+
ctx.captureTrivia = sCap;
|
|
7621
|
+
if (value === FAIL) return FAIL;
|
|
7622
|
+
const end = EC.e;
|
|
7623
|
+
const node = build(captured, fieldMap, { start: pos, end }, EMPTY_CH, EMPTY_TL, void 0);
|
|
7624
|
+
if (sBuf !== void 0 || sCh !== void 0) {
|
|
7625
|
+
pushCstChild(ctx, node, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node, input, pos, end) : void 0);
|
|
7626
|
+
}
|
|
7627
|
+
EC.e = end;
|
|
7628
|
+
return node;
|
|
7629
|
+
};
|
|
7630
|
+
}
|
|
7631
|
+
function collapseBuildNode(child, build) {
|
|
7632
|
+
return (input, pos, ctx) => {
|
|
7633
|
+
const sCh = ctx._cstChildren;
|
|
7634
|
+
const sLv = ctx._cstLeaves;
|
|
7635
|
+
const sRaw = ctx._cstRawChildren;
|
|
7636
|
+
const sTl = ctx._cstTriviaLog;
|
|
7637
|
+
const sCap = ctx.captureTrivia;
|
|
7638
|
+
const sBuf = ctx._cstBuf;
|
|
7639
|
+
const savedFields = ctx._fields;
|
|
7640
|
+
const buf = {};
|
|
7641
|
+
ctx._cstBuf = buf;
|
|
7642
|
+
ctx._cstChildren = void 0;
|
|
7643
|
+
ctx._cstLeaves = void 0;
|
|
7644
|
+
ctx._cstRawChildren = void 0;
|
|
7645
|
+
ctx._cstTriviaLog = void 0;
|
|
7646
|
+
ctx.captureTrivia = false;
|
|
7647
|
+
ctx._fields = void 0;
|
|
7648
|
+
const value = child(input, pos, ctx);
|
|
7649
|
+
const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
|
|
7650
|
+
const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
|
|
7651
|
+
ctx._fields = savedFields;
|
|
7652
|
+
ctx._cstBuf = sBuf;
|
|
7653
|
+
ctx._cstChildren = sCh;
|
|
7654
|
+
ctx._cstLeaves = sLv;
|
|
7655
|
+
ctx._cstRawChildren = sRaw;
|
|
7656
|
+
ctx._cstTriviaLog = sTl;
|
|
7657
|
+
ctx.captureTrivia = sCap;
|
|
7658
|
+
if (value === FAIL) return FAIL;
|
|
7659
|
+
const end = EC.e;
|
|
7660
|
+
const span = { start: pos, end };
|
|
7661
|
+
const node = kids.length === 1 ? kids[0] : build(kids, void 0, span, rawKids, EMPTY_TL, void 0);
|
|
7662
|
+
if (sBuf !== void 0 || sCh !== void 0) {
|
|
7663
|
+
pushCstChild(ctx, node, rawEntry(node, input, pos, end));
|
|
7664
|
+
}
|
|
7665
|
+
EC.e = end;
|
|
7666
|
+
return node;
|
|
7667
|
+
};
|
|
7668
|
+
}
|
|
7669
|
+
function childrenOnlyCollapseBuildNode(child, build) {
|
|
7670
|
+
return (input, pos, ctx) => {
|
|
7671
|
+
const sCh = ctx._cstChildren;
|
|
7672
|
+
const sLv = ctx._cstLeaves;
|
|
7673
|
+
const sRaw = ctx._cstRawChildren;
|
|
7674
|
+
const sTl = ctx._cstTriviaLog;
|
|
7675
|
+
const sCap = ctx.captureTrivia;
|
|
7676
|
+
const sBuf = ctx._cstBuf;
|
|
7677
|
+
const savedFields = ctx._fields;
|
|
7678
|
+
const kids = [];
|
|
7679
|
+
ctx._cstBuf = void 0;
|
|
7680
|
+
ctx._cstChildren = kids;
|
|
7681
|
+
ctx._cstLeaves = kids;
|
|
7682
|
+
ctx._cstRawChildren = void 0;
|
|
7683
|
+
ctx._cstTriviaLog = void 0;
|
|
7684
|
+
ctx.captureTrivia = false;
|
|
7685
|
+
ctx._fields = void 0;
|
|
7686
|
+
const value = child(input, pos, ctx);
|
|
7687
|
+
const captured = capturedFlatChildren(kids);
|
|
7688
|
+
ctx._fields = savedFields;
|
|
7689
|
+
ctx._cstBuf = sBuf;
|
|
7690
|
+
ctx._cstChildren = sCh;
|
|
7691
|
+
ctx._cstLeaves = sLv;
|
|
7692
|
+
ctx._cstRawChildren = sRaw;
|
|
7693
|
+
ctx._cstTriviaLog = sTl;
|
|
7694
|
+
ctx.captureTrivia = sCap;
|
|
7695
|
+
if (value === FAIL) return FAIL;
|
|
7696
|
+
const end = EC.e;
|
|
7697
|
+
const node = captured.length === 1 ? captured[0] : build(captured, void 0, { start: pos, end }, EMPTY_CH, EMPTY_TL, void 0);
|
|
7698
|
+
if (sBuf !== void 0 || sCh !== void 0) {
|
|
7699
|
+
pushCstChild(ctx, node, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node, input, pos, end) : void 0);
|
|
7700
|
+
}
|
|
7701
|
+
EC.e = end;
|
|
7702
|
+
return node;
|
|
7703
|
+
};
|
|
7704
|
+
}
|
|
7705
|
+
function plainProjectNode(child, projection, type) {
|
|
7706
|
+
return (input, pos, ctx) => {
|
|
7707
|
+
const sCh = ctx._cstChildren;
|
|
7708
|
+
const sLv = ctx._cstLeaves;
|
|
7709
|
+
const sRaw = ctx._cstRawChildren;
|
|
7710
|
+
const sTl = ctx._cstTriviaLog;
|
|
7711
|
+
const sCap = ctx.captureTrivia;
|
|
7712
|
+
const sBuf = ctx._cstBuf;
|
|
7713
|
+
const savedFields = ctx._fields;
|
|
7714
|
+
const buf = {};
|
|
7715
|
+
ctx._cstBuf = buf;
|
|
7716
|
+
ctx._cstChildren = void 0;
|
|
7717
|
+
ctx._cstLeaves = void 0;
|
|
7718
|
+
ctx._cstRawChildren = void 0;
|
|
7719
|
+
ctx._cstTriviaLog = void 0;
|
|
7720
|
+
ctx.captureTrivia = false;
|
|
7721
|
+
ctx._fields = void 0;
|
|
7722
|
+
const value = child(input, pos, ctx);
|
|
7723
|
+
const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
|
|
7724
|
+
ctx._fields = savedFields;
|
|
7725
|
+
ctx._cstBuf = sBuf;
|
|
7726
|
+
ctx._cstChildren = sCh;
|
|
7727
|
+
ctx._cstLeaves = sLv;
|
|
7728
|
+
ctx._cstRawChildren = sRaw;
|
|
7729
|
+
ctx._cstTriviaLog = sTl;
|
|
7730
|
+
ctx.captureTrivia = sCap;
|
|
7731
|
+
if (value === FAIL) return FAIL;
|
|
7732
|
+
const end = EC.e;
|
|
7733
|
+
const node = projectChild(kids, projection, type);
|
|
7734
|
+
if (sBuf !== void 0 || sCh !== void 0) {
|
|
7735
|
+
pushCstChild(ctx, node, rawEntry(node, input, pos, end));
|
|
7736
|
+
}
|
|
7737
|
+
EC.e = end;
|
|
7738
|
+
return node;
|
|
7739
|
+
};
|
|
7740
|
+
}
|
|
6497
7741
|
function rollbackNeeded(ctx) {
|
|
6498
7742
|
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;
|
|
6499
7743
|
}
|
|
@@ -6550,9 +7794,7 @@ function assemble(t, prog, cfg) {
|
|
|
6550
7794
|
}
|
|
6551
7795
|
if (s !== null) return skipTriviaScanned(s, input, cur, ctx);
|
|
6552
7796
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
6553
|
-
|
|
6554
|
-
scan.commit();
|
|
6555
|
-
return scan.end;
|
|
7797
|
+
return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
6556
7798
|
}
|
|
6557
7799
|
return advanceTrivia(input, cur, ctx);
|
|
6558
7800
|
}
|
|
@@ -6590,7 +7832,7 @@ function assemble(t, prog, cfg) {
|
|
|
6590
7832
|
if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
6591
7833
|
return cur;
|
|
6592
7834
|
}
|
|
6593
|
-
function
|
|
7835
|
+
function committed3(c) {
|
|
6594
7836
|
return c._fc === true;
|
|
6595
7837
|
}
|
|
6596
7838
|
function accSet(ax, acc) {
|
|
@@ -6599,6 +7841,247 @@ function assemble(t, prog, cfg) {
|
|
|
6599
7841
|
for (const s of ax) acc.push(s);
|
|
6600
7842
|
return acc;
|
|
6601
7843
|
}
|
|
7844
|
+
const NEVER_PIECE = () => FAIL;
|
|
7845
|
+
const NEVER_CLASS = { ascii: new Uint8Array(128), hi: [] };
|
|
7846
|
+
const EMPTY_EXPECTED_PREFIX = (_target, _prev, acc) => acc;
|
|
7847
|
+
function expectedBlock(start, e0, e1, e2, e3, prior) {
|
|
7848
|
+
return (target, prev, acc) => {
|
|
7849
|
+
if (prev < start) {
|
|
7850
|
+
acc = prior(start, prev, acc);
|
|
7851
|
+
prev = start;
|
|
7852
|
+
}
|
|
7853
|
+
if (target > start && prev < start + 1) acc = accSet(e0, acc);
|
|
7854
|
+
if (target > start + 1 && prev < start + 2) acc = accSet(e1, acc);
|
|
7855
|
+
if (target > start + 2 && prev < start + 3) acc = accSet(e2, acc);
|
|
7856
|
+
if (target > start + 3 && prev < start + 4) acc = accSet(e3, acc);
|
|
7857
|
+
return acc;
|
|
7858
|
+
};
|
|
7859
|
+
}
|
|
7860
|
+
function maskedChoiceBlock(start, a0, a1, a2, a3, through, next, total, choiceFx) {
|
|
7861
|
+
return (input, pos, ctx, bits, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best) => {
|
|
7862
|
+
if ((bits & 1 << start) !== 0) {
|
|
7863
|
+
ctx._fc = false;
|
|
7864
|
+
const v = a0(input, pos, ctx);
|
|
7865
|
+
if (v !== FAIL) return v;
|
|
7866
|
+
if (best === pos) acc = through(start, prev, acc);
|
|
7867
|
+
prev = start + 1;
|
|
7868
|
+
const at = ctx._fe ?? pos;
|
|
7869
|
+
if (at > best) {
|
|
7870
|
+
best = at;
|
|
7871
|
+
acc = void 0;
|
|
7872
|
+
}
|
|
7873
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
7874
|
+
if (committed3(ctx)) {
|
|
7875
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
7876
|
+
return FAIL;
|
|
7877
|
+
}
|
|
7878
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7879
|
+
}
|
|
7880
|
+
if ((bits & 1 << start + 1) !== 0) {
|
|
7881
|
+
ctx._fc = false;
|
|
7882
|
+
const v = a1(input, pos, ctx);
|
|
7883
|
+
if (v !== FAIL) return v;
|
|
7884
|
+
if (best === pos) acc = through(start + 1, prev, acc);
|
|
7885
|
+
prev = start + 2;
|
|
7886
|
+
const at = ctx._fe ?? pos;
|
|
7887
|
+
if (at > best) {
|
|
7888
|
+
best = at;
|
|
7889
|
+
acc = void 0;
|
|
7890
|
+
}
|
|
7891
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
7892
|
+
if (committed3(ctx)) {
|
|
7893
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
7894
|
+
return FAIL;
|
|
7895
|
+
}
|
|
7896
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7897
|
+
}
|
|
7898
|
+
if ((bits & 1 << start + 2) !== 0) {
|
|
7899
|
+
ctx._fc = false;
|
|
7900
|
+
const v = a2(input, pos, ctx);
|
|
7901
|
+
if (v !== FAIL) return v;
|
|
7902
|
+
if (best === pos) acc = through(start + 2, prev, acc);
|
|
7903
|
+
prev = start + 3;
|
|
7904
|
+
const at = ctx._fe ?? pos;
|
|
7905
|
+
if (at > best) {
|
|
7906
|
+
best = at;
|
|
7907
|
+
acc = void 0;
|
|
7908
|
+
}
|
|
7909
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
7910
|
+
if (committed3(ctx)) {
|
|
7911
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
7912
|
+
return FAIL;
|
|
7913
|
+
}
|
|
7914
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7915
|
+
}
|
|
7916
|
+
if ((bits & 1 << start + 3) !== 0) {
|
|
7917
|
+
ctx._fc = false;
|
|
7918
|
+
const v = a3(input, pos, ctx);
|
|
7919
|
+
if (v !== FAIL) return v;
|
|
7920
|
+
if (best === pos) acc = through(start + 3, prev, acc);
|
|
7921
|
+
prev = start + 4;
|
|
7922
|
+
const at = ctx._fe ?? pos;
|
|
7923
|
+
if (at > best) {
|
|
7924
|
+
best = at;
|
|
7925
|
+
acc = void 0;
|
|
7926
|
+
}
|
|
7927
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
7928
|
+
if (committed3(ctx)) {
|
|
7929
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
7930
|
+
return FAIL;
|
|
7931
|
+
}
|
|
7932
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7933
|
+
}
|
|
7934
|
+
if (next !== void 0) {
|
|
7935
|
+
return next(input, pos, ctx, bits, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
7936
|
+
}
|
|
7937
|
+
if (best === pos) acc = through(total, prev, acc);
|
|
7938
|
+
ctx._fe = pos;
|
|
7939
|
+
ctx._fx = acc ?? choiceFx;
|
|
7940
|
+
return FAIL;
|
|
7941
|
+
};
|
|
7942
|
+
}
|
|
7943
|
+
function generalChoiceBlock(start, a0, a1, a2, a3, g0, g1, g2, g3, through, next, total, choiceFx) {
|
|
7944
|
+
return (input, pos, ctx, c, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best) => {
|
|
7945
|
+
if (g0 === null || classHas2(g0, c)) {
|
|
7946
|
+
ctx._fc = false;
|
|
7947
|
+
const v = a0(input, pos, ctx);
|
|
7948
|
+
if (v !== FAIL) return v;
|
|
7949
|
+
if (best === pos) acc = through(start, prev, acc);
|
|
7950
|
+
prev = start + 1;
|
|
7951
|
+
const at = ctx._fe ?? pos;
|
|
7952
|
+
if (at > best) {
|
|
7953
|
+
best = at;
|
|
7954
|
+
acc = void 0;
|
|
7955
|
+
}
|
|
7956
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
7957
|
+
if (committed3(ctx)) {
|
|
7958
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
7959
|
+
return FAIL;
|
|
7960
|
+
}
|
|
7961
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7962
|
+
}
|
|
7963
|
+
if (g1 === null || classHas2(g1, c)) {
|
|
7964
|
+
ctx._fc = false;
|
|
7965
|
+
const v = a1(input, pos, ctx);
|
|
7966
|
+
if (v !== FAIL) return v;
|
|
7967
|
+
if (best === pos) acc = through(start + 1, prev, acc);
|
|
7968
|
+
prev = start + 2;
|
|
7969
|
+
const at = ctx._fe ?? pos;
|
|
7970
|
+
if (at > best) {
|
|
7971
|
+
best = at;
|
|
7972
|
+
acc = void 0;
|
|
7973
|
+
}
|
|
7974
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
7975
|
+
if (committed3(ctx)) {
|
|
7976
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
7977
|
+
return FAIL;
|
|
7978
|
+
}
|
|
7979
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7980
|
+
}
|
|
7981
|
+
if (g2 === null || classHas2(g2, c)) {
|
|
7982
|
+
ctx._fc = false;
|
|
7983
|
+
const v = a2(input, pos, ctx);
|
|
7984
|
+
if (v !== FAIL) return v;
|
|
7985
|
+
if (best === pos) acc = through(start + 2, prev, acc);
|
|
7986
|
+
prev = start + 3;
|
|
7987
|
+
const at = ctx._fe ?? pos;
|
|
7988
|
+
if (at > best) {
|
|
7989
|
+
best = at;
|
|
7990
|
+
acc = void 0;
|
|
7991
|
+
}
|
|
7992
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
7993
|
+
if (committed3(ctx)) {
|
|
7994
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
7995
|
+
return FAIL;
|
|
7996
|
+
}
|
|
7997
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7998
|
+
}
|
|
7999
|
+
if (g3 === null || classHas2(g3, c)) {
|
|
8000
|
+
ctx._fc = false;
|
|
8001
|
+
const v = a3(input, pos, ctx);
|
|
8002
|
+
if (v !== FAIL) return v;
|
|
8003
|
+
if (best === pos) acc = through(start + 3, prev, acc);
|
|
8004
|
+
prev = start + 4;
|
|
8005
|
+
const at = ctx._fe ?? pos;
|
|
8006
|
+
if (at > best) {
|
|
8007
|
+
best = at;
|
|
8008
|
+
acc = void 0;
|
|
8009
|
+
}
|
|
8010
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
8011
|
+
if (committed3(ctx)) {
|
|
8012
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
8013
|
+
return FAIL;
|
|
8014
|
+
}
|
|
8015
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
8016
|
+
}
|
|
8017
|
+
if (next !== void 0) {
|
|
8018
|
+
return next(input, pos, ctx, c, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
8019
|
+
}
|
|
8020
|
+
if (best === pos) acc = through(total, prev, acc);
|
|
8021
|
+
ctx._fe = pos;
|
|
8022
|
+
ctx._fx = acc ?? choiceFx;
|
|
8023
|
+
return FAIL;
|
|
8024
|
+
};
|
|
8025
|
+
}
|
|
8026
|
+
function exclusiveChoiceBlock(start, a0, a1, a2, a3, next) {
|
|
8027
|
+
return (arm, input, pos, ctx) => {
|
|
8028
|
+
if (arm === start) return a0(input, pos, ctx);
|
|
8029
|
+
if (arm === start + 1) return a1(input, pos, ctx);
|
|
8030
|
+
if (arm === start + 2) return a2(input, pos, ctx);
|
|
8031
|
+
if (arm === start + 3) return a3(input, pos, ctx);
|
|
8032
|
+
return next === void 0 ? FAIL : next(arm, input, pos, ctx);
|
|
8033
|
+
};
|
|
8034
|
+
}
|
|
8035
|
+
function dispatchMatcherBlock(m0, a0, m1, a1, m2, a2, m3, a3, next) {
|
|
8036
|
+
return (key) => {
|
|
8037
|
+
if (m0(key)) return a0;
|
|
8038
|
+
if (m1(key)) return a1;
|
|
8039
|
+
if (m2(key)) return a2;
|
|
8040
|
+
if (m3(key)) return a3;
|
|
8041
|
+
return next?.(key);
|
|
8042
|
+
};
|
|
8043
|
+
}
|
|
8044
|
+
function dispatchBranch(child, usesRouted) {
|
|
8045
|
+
if (!usesRouted) {
|
|
8046
|
+
return (input, _pos, selEnd, key, _selectorMark, ctx) => {
|
|
8047
|
+
const mark = saveTriviaMark(ctx);
|
|
8048
|
+
const v = child(input, selEnd, ctx);
|
|
8049
|
+
if (v === FAIL) {
|
|
8050
|
+
rollbackTrivia(ctx, mark);
|
|
8051
|
+
ctx._fc = true;
|
|
8052
|
+
return FAIL;
|
|
8053
|
+
}
|
|
8054
|
+
return [key, v];
|
|
8055
|
+
};
|
|
8056
|
+
}
|
|
8057
|
+
return (input, pos, selEnd, key, selectorMark, ctx) => {
|
|
8058
|
+
const savedRouted = ctx._routed;
|
|
8059
|
+
rollbackTrivia(ctx, selectorMark);
|
|
8060
|
+
const mark = saveTriviaMark(ctx);
|
|
8061
|
+
ctx._routed = { value: key, span: { start: pos, end: selEnd } };
|
|
8062
|
+
let v;
|
|
8063
|
+
try {
|
|
8064
|
+
v = child(input, pos, ctx);
|
|
8065
|
+
} finally {
|
|
8066
|
+
ctx._routed = savedRouted;
|
|
8067
|
+
}
|
|
8068
|
+
if (v === FAIL) {
|
|
8069
|
+
rollbackTrivia(ctx, mark);
|
|
8070
|
+
ctx._fc = true;
|
|
8071
|
+
return FAIL;
|
|
8072
|
+
}
|
|
8073
|
+
return [key, v];
|
|
8074
|
+
};
|
|
8075
|
+
}
|
|
8076
|
+
function dispatchArmBlock(start, a0, a1, a2, a3, next) {
|
|
8077
|
+
return (arm, input, pos, selEnd, key, selectorMark, ctx) => {
|
|
8078
|
+
if (arm === start) return a0(input, pos, selEnd, key, selectorMark, ctx);
|
|
8079
|
+
if (arm === start + 1) return a1(input, pos, selEnd, key, selectorMark, ctx);
|
|
8080
|
+
if (arm === start + 2) return a2(input, pos, selEnd, key, selectorMark, ctx);
|
|
8081
|
+
if (arm === start + 3) return a3(input, pos, selEnd, key, selectorMark, ctx);
|
|
8082
|
+
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key, selectorMark, ctx);
|
|
8083
|
+
};
|
|
8084
|
+
}
|
|
6602
8085
|
function trackLinesInto(ctx, input, end) {
|
|
6603
8086
|
const from = ctx._lineScannedTo ?? 0;
|
|
6604
8087
|
if (end <= from) return;
|
|
@@ -6634,6 +8117,21 @@ function assemble(t, prog, cfg) {
|
|
|
6634
8117
|
const s = k[code[ip + 1]];
|
|
6635
8118
|
const len = s.length;
|
|
6636
8119
|
const xf = fx[code[ip + 2]];
|
|
8120
|
+
const shared = rawScalarSpecs.has(code[ip + 1]) ? scalarFor(ip) : void 0;
|
|
8121
|
+
if (shared !== void 0) {
|
|
8122
|
+
return (input, pos, ctx) => {
|
|
8123
|
+
const e = shared(input, pos);
|
|
8124
|
+
if (e >= 0) {
|
|
8125
|
+
if (cstCaptureActive(ctx)) pushLeaf(ctx, s, pos, e);
|
|
8126
|
+
EC.e = e;
|
|
8127
|
+
return s;
|
|
8128
|
+
}
|
|
8129
|
+
ctx._fe = pos;
|
|
8130
|
+
ctx._fx = xf;
|
|
8131
|
+
if (ctx._probe !== void 0) failAt(ctx, xf, pos);
|
|
8132
|
+
return FAIL;
|
|
8133
|
+
};
|
|
8134
|
+
}
|
|
6637
8135
|
if (len === 1) {
|
|
6638
8136
|
const c0 = s.charCodeAt(0);
|
|
6639
8137
|
return (input, pos, ctx) => {
|
|
@@ -6761,6 +8259,22 @@ function assemble(t, prog, cfg) {
|
|
|
6761
8259
|
case OP_RX: {
|
|
6762
8260
|
const re = k[code[ip + 1]];
|
|
6763
8261
|
const xf = fx[code[ip + 2]];
|
|
8262
|
+
const shared = rawScalarSpecs.has(code[ip + 1]) ? scalarFor(ip) : void 0;
|
|
8263
|
+
if (shared !== void 0) {
|
|
8264
|
+
return (input, pos, ctx) => {
|
|
8265
|
+
const e = shared(input, pos);
|
|
8266
|
+
if (e >= 0) {
|
|
8267
|
+
const v = input.slice(pos, e);
|
|
8268
|
+
if (cstCaptureActive(ctx)) pushLeaf(ctx, v, pos, e);
|
|
8269
|
+
EC.e = e;
|
|
8270
|
+
return v;
|
|
8271
|
+
}
|
|
8272
|
+
ctx._fe = pos;
|
|
8273
|
+
ctx._fx = xf;
|
|
8274
|
+
if (ctx._probe !== void 0) failAt(ctx, xf, pos);
|
|
8275
|
+
return FAIL;
|
|
8276
|
+
};
|
|
8277
|
+
}
|
|
6764
8278
|
return (input, pos, ctx) => {
|
|
6765
8279
|
re.lastIndex = pos;
|
|
6766
8280
|
if (re.test(input)) {
|
|
@@ -6870,7 +8384,7 @@ function assemble(t, prog, cfg) {
|
|
|
6870
8384
|
const child = link(code[ip + 2]);
|
|
6871
8385
|
if (cfg.tolerant || cfg.probe) return child;
|
|
6872
8386
|
return (input, pos, ctx) => {
|
|
6873
|
-
if (!
|
|
8387
|
+
if (!classHas2(cls, lead(input, pos))) {
|
|
6874
8388
|
ctx._fe = pos;
|
|
6875
8389
|
ctx._fx = xf;
|
|
6876
8390
|
return FAIL;
|
|
@@ -7069,13 +8583,28 @@ function assemble(t, prog, cfg) {
|
|
|
7069
8583
|
const v = child(input, pos, ctx);
|
|
7070
8584
|
if (v !== FAIL) return v;
|
|
7071
8585
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7072
|
-
if (
|
|
8586
|
+
if (committed3(ctx)) return FAIL;
|
|
7073
8587
|
ctx._fe = pos;
|
|
7074
8588
|
return FAIL;
|
|
7075
8589
|
};
|
|
7076
8590
|
}
|
|
7077
8591
|
/* ── zero-width ──────────────────────────────────────────────────────── */
|
|
7078
8592
|
case OP_NOT: {
|
|
8593
|
+
const scalarChild = scalarTerminalNotChild(code, ip);
|
|
8594
|
+
if (scalarChild >= 0) {
|
|
8595
|
+
const recognize = scalarFor(scalarChild);
|
|
8596
|
+
const xf2 = fx[code[ip + 2]];
|
|
8597
|
+
return (input, pos, ctx) => {
|
|
8598
|
+
if (recognize(input, pos) < 0) {
|
|
8599
|
+
EC.e = pos;
|
|
8600
|
+
return null;
|
|
8601
|
+
}
|
|
8602
|
+
ctx._fe = pos;
|
|
8603
|
+
ctx._fx = xf2;
|
|
8604
|
+
EC.e = pos;
|
|
8605
|
+
return FAIL;
|
|
8606
|
+
};
|
|
8607
|
+
}
|
|
7079
8608
|
const child = link(code[ip + 1]);
|
|
7080
8609
|
const xf = fx[code[ip + 2]];
|
|
7081
8610
|
return (input, pos, ctx) => {
|
|
@@ -7135,7 +8664,7 @@ function assemble(t, prog, cfg) {
|
|
|
7135
8664
|
ctx._fc = false;
|
|
7136
8665
|
const v = child(input, pos, ctx);
|
|
7137
8666
|
if (v === FAIL) {
|
|
7138
|
-
if (
|
|
8667
|
+
if (committed3(ctx)) return FAIL;
|
|
7139
8668
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7140
8669
|
EC.e = pos;
|
|
7141
8670
|
return null;
|
|
@@ -7186,6 +8715,92 @@ function assemble(t, prog, cfg) {
|
|
|
7186
8715
|
return value;
|
|
7187
8716
|
};
|
|
7188
8717
|
}
|
|
8718
|
+
case OP_LEX_BODY: {
|
|
8719
|
+
const recognize = t.lex[code[ip + 1]];
|
|
8720
|
+
const expected = fx[code[ip + 2]];
|
|
8721
|
+
return (input, pos, ctx) => {
|
|
8722
|
+
const recognized = recognize(input, pos);
|
|
8723
|
+
if (recognized < 0) {
|
|
8724
|
+
ctx._fe = pos;
|
|
8725
|
+
ctx._fx = expected;
|
|
8726
|
+
if (ctx._probe !== void 0) failAt(ctx, expected, pos);
|
|
8727
|
+
return FAIL;
|
|
8728
|
+
}
|
|
8729
|
+
const lineFlags = code[ip + 4];
|
|
8730
|
+
const hasSuffix = (lineFlags & 4) !== 0;
|
|
8731
|
+
const suffixMatched = hasSuffix && recognized % 2 === 1;
|
|
8732
|
+
const end = (recognized - (suffixMatched ? 1 : 0)) / 2;
|
|
8733
|
+
if ((lineFlags & 1) !== 0) {
|
|
8734
|
+
trackLinesInto(ctx, input, suffixMatched ? end - 1 : end);
|
|
8735
|
+
}
|
|
8736
|
+
if (hasSuffix) ctx._fc = false;
|
|
8737
|
+
if (hasSuffix && suffixMatched && (lineFlags & 2) !== 0) {
|
|
8738
|
+
trackLinesInto(ctx, input, end);
|
|
8739
|
+
}
|
|
8740
|
+
if (hasSuffix && !suffixMatched) {
|
|
8741
|
+
const suffixExpected = fx[code[ip + 3]];
|
|
8742
|
+
ctx._fe = end;
|
|
8743
|
+
ctx._fx = suffixExpected;
|
|
8744
|
+
if (ctx._probe !== void 0) failAt(ctx, suffixExpected, end);
|
|
8745
|
+
}
|
|
8746
|
+
const value = input.slice(pos, end);
|
|
8747
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
|
|
8748
|
+
EC.e = end;
|
|
8749
|
+
return value;
|
|
8750
|
+
};
|
|
8751
|
+
}
|
|
8752
|
+
case OP_LEX_PROGRAM: {
|
|
8753
|
+
const run = t.lexPrograms[code[ip + 1]];
|
|
8754
|
+
const scanId = run.scan;
|
|
8755
|
+
if (scanId !== void 0) {
|
|
8756
|
+
return (input, pos, ctx) => {
|
|
8757
|
+
const sTrivia = ctx.trivia, sKinds = ctx.triviaKindLabels;
|
|
8758
|
+
const sBuf = ctx._cstBuf, sChildren = ctx._cstChildren, sLeaves = ctx._cstLeaves;
|
|
8759
|
+
const sRaw = ctx._cstRawChildren, sTl = ctx._cstTriviaLog;
|
|
8760
|
+
const sOuterTl = ctx._triviaLog, sRootTl = ctx._rootTriviaLog;
|
|
8761
|
+
const wasCapturing = cstCaptureActive(ctx);
|
|
8762
|
+
const sScan = SCAN;
|
|
8763
|
+
SCAN = null;
|
|
8764
|
+
ctx.trivia = void 0;
|
|
8765
|
+
ctx.triviaKindLabels = void 0;
|
|
8766
|
+
ctx._cstBuf = void 0;
|
|
8767
|
+
ctx._cstChildren = void 0;
|
|
8768
|
+
ctx._cstLeaves = void 0;
|
|
8769
|
+
ctx._cstRawChildren = void 0;
|
|
8770
|
+
ctx._cstTriviaLog = void 0;
|
|
8771
|
+
ctx._triviaLog = void 0;
|
|
8772
|
+
ctx._rootTriviaLog = void 0;
|
|
8773
|
+
let end;
|
|
8774
|
+
try {
|
|
8775
|
+
end = run(input, pos, ctx, scans[scanId]);
|
|
8776
|
+
} finally {
|
|
8777
|
+
SCAN = sScan;
|
|
8778
|
+
ctx.trivia = sTrivia;
|
|
8779
|
+
ctx.triviaKindLabels = sKinds;
|
|
8780
|
+
ctx._cstBuf = sBuf;
|
|
8781
|
+
ctx._cstChildren = sChildren;
|
|
8782
|
+
ctx._cstLeaves = sLeaves;
|
|
8783
|
+
ctx._cstRawChildren = sRaw;
|
|
8784
|
+
ctx._cstTriviaLog = sTl;
|
|
8785
|
+
ctx._triviaLog = sOuterTl;
|
|
8786
|
+
ctx._rootTriviaLog = sRootTl;
|
|
8787
|
+
}
|
|
8788
|
+
if (end < 0) return FAIL;
|
|
8789
|
+
const value = input.slice(pos, end);
|
|
8790
|
+
if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
|
|
8791
|
+
EC.e = end;
|
|
8792
|
+
return value;
|
|
8793
|
+
};
|
|
8794
|
+
}
|
|
8795
|
+
return (input, pos, ctx) => {
|
|
8796
|
+
const end = run(input, pos, ctx);
|
|
8797
|
+
if (end < 0) return FAIL;
|
|
8798
|
+
const value = input.slice(pos, end);
|
|
8799
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
|
|
8800
|
+
EC.e = end;
|
|
8801
|
+
return value;
|
|
8802
|
+
};
|
|
8803
|
+
}
|
|
7189
8804
|
case OP_LEAF: {
|
|
7190
8805
|
const fn = fns[code[ip + 1]];
|
|
7191
8806
|
const child = link(code[ip + 2]);
|
|
@@ -7226,38 +8841,73 @@ function assemble(t, prog, cfg) {
|
|
|
7226
8841
|
const fused = op === OP_SEQX;
|
|
7227
8842
|
const base = fused ? ip + 3 : ip + 2;
|
|
7228
8843
|
const n = code[fused ? ip + 2 : ip + 1];
|
|
7229
|
-
const kids = new Array(n);
|
|
7230
|
-
for (let i = 0; i < n; i++) kids[i] = link(code[base + i]);
|
|
7231
8844
|
const wantValues = op !== OP_SEQV;
|
|
7232
|
-
const
|
|
7233
|
-
const
|
|
7234
|
-
|
|
7235
|
-
|
|
7236
|
-
if (
|
|
7237
|
-
|
|
7238
|
-
for (let i = 1; i < n; i++) {
|
|
7239
|
-
cur = nextTerm(kids[i], input, cur, ctx);
|
|
8845
|
+
const reducer = fused ? code[ip + 1] : -1;
|
|
8846
|
+
const projection = reducer < 0 ? ~reducer : -1;
|
|
8847
|
+
const fn = fused && projection < 0 ? fns[reducer] : void 0;
|
|
8848
|
+
const runnerBlock = (count, r0, r1, r2, r3, next) => {
|
|
8849
|
+
if (count === 1) return (input, cur, ctx, values, inherited) => {
|
|
8850
|
+
cur = r0(input, cur, ctx, inherited);
|
|
7240
8851
|
if (cur < 0) return -1;
|
|
7241
8852
|
if (values !== void 0) values.push(TERMV);
|
|
7242
|
-
|
|
7243
|
-
|
|
8853
|
+
return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
|
|
8854
|
+
};
|
|
8855
|
+
if (count === 2) return (input, cur, ctx, values, inherited) => {
|
|
8856
|
+
cur = r0(input, cur, ctx, inherited);
|
|
8857
|
+
if (cur < 0) return -1;
|
|
8858
|
+
if (values !== void 0) values.push(TERMV);
|
|
8859
|
+
cur = r1(input, cur, ctx, inherited);
|
|
8860
|
+
if (cur < 0) return -1;
|
|
8861
|
+
if (values !== void 0) values.push(TERMV);
|
|
8862
|
+
return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
|
|
8863
|
+
};
|
|
8864
|
+
if (count === 3) return (input, cur, ctx, values, inherited) => {
|
|
8865
|
+
cur = r0(input, cur, ctx, inherited);
|
|
8866
|
+
if (cur < 0) return -1;
|
|
8867
|
+
if (values !== void 0) values.push(TERMV);
|
|
8868
|
+
cur = r1(input, cur, ctx, inherited);
|
|
8869
|
+
if (cur < 0) return -1;
|
|
8870
|
+
if (values !== void 0) values.push(TERMV);
|
|
8871
|
+
cur = r2(input, cur, ctx, inherited);
|
|
8872
|
+
if (cur < 0) return -1;
|
|
8873
|
+
if (values !== void 0) values.push(TERMV);
|
|
8874
|
+
return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
|
|
8875
|
+
};
|
|
8876
|
+
return (input, cur, ctx, values, inherited) => {
|
|
8877
|
+
cur = r0(input, cur, ctx, inherited);
|
|
8878
|
+
if (cur < 0) return -1;
|
|
8879
|
+
if (values !== void 0) values.push(TERMV);
|
|
8880
|
+
cur = r1(input, cur, ctx, inherited);
|
|
8881
|
+
if (cur < 0) return -1;
|
|
8882
|
+
if (values !== void 0) values.push(TERMV);
|
|
8883
|
+
cur = r2(input, cur, ctx, inherited);
|
|
8884
|
+
if (cur < 0) return -1;
|
|
8885
|
+
if (values !== void 0) values.push(TERMV);
|
|
8886
|
+
cur = r3(input, cur, ctx, inherited);
|
|
8887
|
+
if (cur < 0) return -1;
|
|
8888
|
+
if (values !== void 0) values.push(TERMV);
|
|
8889
|
+
return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
|
|
8890
|
+
};
|
|
7244
8891
|
};
|
|
7245
8892
|
if (REC) {
|
|
7246
|
-
const
|
|
7247
|
-
|
|
7248
|
-
const
|
|
7249
|
-
|
|
8893
|
+
const first2 = link(code[base]);
|
|
8894
|
+
const firstSync = sentinelFor(code[base + n]);
|
|
8895
|
+
const runnerAt = (i) => {
|
|
8896
|
+
const sync = sentinelFor(code[base + n + i]);
|
|
7250
8897
|
const kidIp = code[base + i];
|
|
7251
8898
|
if (code[kidIp] !== OP_ADJ) {
|
|
7252
|
-
const kid =
|
|
7253
|
-
|
|
7254
|
-
|
|
8899
|
+
const kid = link(kidIp);
|
|
8900
|
+
return (input, cur, ctx, inherited) => {
|
|
8901
|
+
ctx._sync = sync ?? inherited;
|
|
8902
|
+
return nextTerm(kid, input, cur, ctx);
|
|
8903
|
+
};
|
|
7255
8904
|
}
|
|
7256
8905
|
const negated = code[kidIp + 1] === 1;
|
|
7257
8906
|
const ki = code[kidIp + 2];
|
|
7258
8907
|
const kinds = ki < 0 ? void 0 : k[ki];
|
|
7259
8908
|
const xf = fx[code[kidIp + 3]];
|
|
7260
|
-
|
|
8909
|
+
return (input, cur, ctx, inherited) => {
|
|
8910
|
+
ctx._sync = sync ?? inherited;
|
|
7261
8911
|
if (!adjacencyHolds(input, cur, ctx, negated, kinds)) {
|
|
7262
8912
|
ctx._fe = cur;
|
|
7263
8913
|
ctx._fx = xf;
|
|
@@ -7266,25 +8916,34 @@ function assemble(t, prog, cfg) {
|
|
|
7266
8916
|
TERMV = null;
|
|
7267
8917
|
return cur;
|
|
7268
8918
|
};
|
|
7269
|
-
}
|
|
8919
|
+
};
|
|
8920
|
+
const bindRunners = (start) => {
|
|
8921
|
+
const count = Math.min(4, n - start);
|
|
8922
|
+
const at = (offset) => runnerAt(start + offset);
|
|
8923
|
+
const never = () => -1;
|
|
8924
|
+
return runnerBlock(
|
|
8925
|
+
count,
|
|
8926
|
+
at(0),
|
|
8927
|
+
count > 1 ? at(1) : never,
|
|
8928
|
+
count > 2 ? at(2) : never,
|
|
8929
|
+
count > 3 ? at(3) : never,
|
|
8930
|
+
start + count < n ? bindRunners(start + count) : void 0
|
|
8931
|
+
);
|
|
8932
|
+
};
|
|
8933
|
+
const tail2 = n > 1 ? bindRunners(1) : void 0;
|
|
7270
8934
|
const runSyncTerms = (input, pos, ctx, values) => {
|
|
7271
8935
|
const inherited = ctx._sync;
|
|
7272
|
-
ctx._sync =
|
|
7273
|
-
const v0 =
|
|
8936
|
+
ctx._sync = firstSync ?? inherited;
|
|
8937
|
+
const v0 = first2(input, pos, ctx);
|
|
7274
8938
|
if (v0 === FAIL) {
|
|
7275
8939
|
ctx._sync = inherited;
|
|
7276
8940
|
return -1;
|
|
7277
8941
|
}
|
|
7278
8942
|
if (values !== void 0) values.push(v0);
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
ctx._sync =
|
|
7282
|
-
|
|
7283
|
-
if (cur < 0) {
|
|
7284
|
-
ctx._sync = inherited;
|
|
7285
|
-
return -1;
|
|
7286
|
-
}
|
|
7287
|
-
if (values !== void 0) values.push(TERMV);
|
|
8943
|
+
const cur = tail2 === void 0 ? EC.e : tail2(input, EC.e, ctx, values, inherited);
|
|
8944
|
+
if (cur < 0) {
|
|
8945
|
+
ctx._sync = inherited;
|
|
8946
|
+
return -1;
|
|
7288
8947
|
}
|
|
7289
8948
|
ctx._sync = inherited;
|
|
7290
8949
|
return cur;
|
|
@@ -7295,7 +8954,7 @@ function assemble(t, prog, cfg) {
|
|
|
7295
8954
|
const cur = runSyncTerms(input, pos, ctx, values);
|
|
7296
8955
|
if (cur < 0) return FAIL;
|
|
7297
8956
|
EC.e = cur;
|
|
7298
|
-
return fn(values, { start: pos, end: cur });
|
|
8957
|
+
return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
|
|
7299
8958
|
};
|
|
7300
8959
|
}
|
|
7301
8960
|
if (wantValues) {
|
|
@@ -7320,19 +8979,18 @@ function assemble(t, prog, cfg) {
|
|
|
7320
8979
|
break;
|
|
7321
8980
|
}
|
|
7322
8981
|
if (hasAdj) {
|
|
7323
|
-
const
|
|
7324
|
-
|
|
8982
|
+
const first2 = link(code[base]);
|
|
8983
|
+
const runnerAt = (i) => {
|
|
7325
8984
|
const kidIp = code[base + i];
|
|
7326
8985
|
if (code[kidIp] !== OP_ADJ) {
|
|
7327
|
-
const kid =
|
|
7328
|
-
|
|
7329
|
-
continue;
|
|
8986
|
+
const kid = link(kidIp);
|
|
8987
|
+
return (input, cur, ctx) => nextTerm(kid, input, cur, ctx);
|
|
7330
8988
|
}
|
|
7331
8989
|
const negated = code[kidIp + 1] === 1;
|
|
7332
8990
|
const ki = code[kidIp + 2];
|
|
7333
8991
|
const kinds = ki < 0 ? void 0 : k[ki];
|
|
7334
8992
|
const xf = fx[code[kidIp + 3]];
|
|
7335
|
-
|
|
8993
|
+
return (input, cur, ctx) => {
|
|
7336
8994
|
if (!adjacencyHolds(input, cur, ctx, negated, kinds)) {
|
|
7337
8995
|
ctx._fe = cur;
|
|
7338
8996
|
ctx._fx = xf;
|
|
@@ -7341,18 +8999,26 @@ function assemble(t, prog, cfg) {
|
|
|
7341
8999
|
TERMV = null;
|
|
7342
9000
|
return cur;
|
|
7343
9001
|
};
|
|
7344
|
-
}
|
|
9002
|
+
};
|
|
9003
|
+
const bindRunners = (start) => {
|
|
9004
|
+
const count = Math.min(4, n - start);
|
|
9005
|
+
const at = (offset) => runnerAt(start + offset);
|
|
9006
|
+
const never = () => -1;
|
|
9007
|
+
return runnerBlock(
|
|
9008
|
+
count,
|
|
9009
|
+
at(0),
|
|
9010
|
+
count > 1 ? at(1) : never,
|
|
9011
|
+
count > 2 ? at(2) : never,
|
|
9012
|
+
count > 3 ? at(3) : never,
|
|
9013
|
+
start + count < n ? bindRunners(start + count) : void 0
|
|
9014
|
+
);
|
|
9015
|
+
};
|
|
9016
|
+
const tail2 = bindRunners(1);
|
|
7345
9017
|
const runAdjTerms = (input, pos, ctx, values) => {
|
|
7346
|
-
const v0 =
|
|
9018
|
+
const v0 = first2(input, pos, ctx);
|
|
7347
9019
|
if (v0 === FAIL) return -1;
|
|
7348
9020
|
if (values !== void 0) values.push(v0);
|
|
7349
|
-
|
|
7350
|
-
for (let i = 1; i < n; i++) {
|
|
7351
|
-
cur = runners[i](input, cur, ctx);
|
|
7352
|
-
if (cur < 0) return -1;
|
|
7353
|
-
if (values !== void 0) values.push(TERMV);
|
|
7354
|
-
}
|
|
7355
|
-
return cur;
|
|
9021
|
+
return tail2(input, EC.e, ctx, values);
|
|
7356
9022
|
};
|
|
7357
9023
|
if (fused) {
|
|
7358
9024
|
return (input, pos, ctx) => {
|
|
@@ -7360,7 +9026,7 @@ function assemble(t, prog, cfg) {
|
|
|
7360
9026
|
const cur = runAdjTerms(input, pos, ctx, values);
|
|
7361
9027
|
if (cur < 0) return FAIL;
|
|
7362
9028
|
EC.e = cur;
|
|
7363
|
-
return fn(values, { start: pos, end: cur });
|
|
9029
|
+
return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
|
|
7364
9030
|
};
|
|
7365
9031
|
}
|
|
7366
9032
|
if (wantValues) {
|
|
@@ -7380,12 +9046,12 @@ function assemble(t, prog, cfg) {
|
|
|
7380
9046
|
};
|
|
7381
9047
|
}
|
|
7382
9048
|
if (n === 1) {
|
|
7383
|
-
const k0 =
|
|
9049
|
+
const k0 = link(code[base]);
|
|
7384
9050
|
if (fused) {
|
|
7385
9051
|
return (input, pos, ctx) => {
|
|
7386
9052
|
const v = k0(input, pos, ctx);
|
|
7387
9053
|
if (v === FAIL) return FAIL;
|
|
7388
|
-
return fn([v], { start: pos, end: EC.e });
|
|
9054
|
+
return projection === 0 ? v : fn([v], { start: pos, end: EC.e });
|
|
7389
9055
|
};
|
|
7390
9056
|
}
|
|
7391
9057
|
if (wantValues) {
|
|
@@ -7402,7 +9068,7 @@ function assemble(t, prog, cfg) {
|
|
|
7402
9068
|
};
|
|
7403
9069
|
}
|
|
7404
9070
|
if (n === 2) {
|
|
7405
|
-
const k0 =
|
|
9071
|
+
const k0 = link(code[base]), k1 = link(code[base + 1]);
|
|
7406
9072
|
if (fused) {
|
|
7407
9073
|
return (input, pos, ctx) => {
|
|
7408
9074
|
const v0 = k0(input, pos, ctx);
|
|
@@ -7410,7 +9076,7 @@ function assemble(t, prog, cfg) {
|
|
|
7410
9076
|
const cur = nextTerm(k1, input, EC.e, ctx);
|
|
7411
9077
|
if (cur < 0) return FAIL;
|
|
7412
9078
|
EC.e = cur;
|
|
7413
|
-
return fn([v0, TERMV], { start: pos, end: cur });
|
|
9079
|
+
return projection === 0 ? v0 : projection === 1 ? TERMV : fn([v0, TERMV], { start: pos, end: cur });
|
|
7414
9080
|
};
|
|
7415
9081
|
}
|
|
7416
9082
|
if (wantValues) {
|
|
@@ -7433,7 +9099,7 @@ function assemble(t, prog, cfg) {
|
|
|
7433
9099
|
};
|
|
7434
9100
|
}
|
|
7435
9101
|
if (n === 3) {
|
|
7436
|
-
const k0 =
|
|
9102
|
+
const k0 = link(code[base]), k1 = link(code[base + 1]), k2 = link(code[base + 2]);
|
|
7437
9103
|
if (fused) {
|
|
7438
9104
|
return (input, pos, ctx) => {
|
|
7439
9105
|
const v0 = k0(input, pos, ctx);
|
|
@@ -7444,7 +9110,7 @@ function assemble(t, prog, cfg) {
|
|
|
7444
9110
|
cur = nextTerm(k2, input, cur, ctx);
|
|
7445
9111
|
if (cur < 0) return FAIL;
|
|
7446
9112
|
EC.e = cur;
|
|
7447
|
-
return fn([v0, v1, TERMV], { start: pos, end: cur });
|
|
9113
|
+
return projection === 0 ? v0 : projection === 1 ? v1 : projection === 2 ? TERMV : fn([v0, v1, TERMV], { start: pos, end: cur });
|
|
7448
9114
|
};
|
|
7449
9115
|
}
|
|
7450
9116
|
if (wantValues) {
|
|
@@ -7470,27 +9136,91 @@ function assemble(t, prog, cfg) {
|
|
|
7470
9136
|
EC.e = cur;
|
|
7471
9137
|
return void 0;
|
|
7472
9138
|
};
|
|
7473
|
-
}
|
|
9139
|
+
}
|
|
9140
|
+
const block = (count, k0, k1, k2, k3, next) => {
|
|
9141
|
+
if (count === 1) return (input, cur, ctx, values) => {
|
|
9142
|
+
cur = nextTerm(k0, input, cur, ctx);
|
|
9143
|
+
if (cur < 0) return -1;
|
|
9144
|
+
if (values !== void 0) values.push(TERMV);
|
|
9145
|
+
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
9146
|
+
};
|
|
9147
|
+
if (count === 2) return (input, cur, ctx, values) => {
|
|
9148
|
+
cur = nextTerm(k0, input, cur, ctx);
|
|
9149
|
+
if (cur < 0) return -1;
|
|
9150
|
+
if (values !== void 0) values.push(TERMV);
|
|
9151
|
+
cur = nextTerm(k1, input, cur, ctx);
|
|
9152
|
+
if (cur < 0) return -1;
|
|
9153
|
+
if (values !== void 0) values.push(TERMV);
|
|
9154
|
+
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
9155
|
+
};
|
|
9156
|
+
if (count === 3) return (input, cur, ctx, values) => {
|
|
9157
|
+
cur = nextTerm(k0, input, cur, ctx);
|
|
9158
|
+
if (cur < 0) return -1;
|
|
9159
|
+
if (values !== void 0) values.push(TERMV);
|
|
9160
|
+
cur = nextTerm(k1, input, cur, ctx);
|
|
9161
|
+
if (cur < 0) return -1;
|
|
9162
|
+
if (values !== void 0) values.push(TERMV);
|
|
9163
|
+
cur = nextTerm(k2, input, cur, ctx);
|
|
9164
|
+
if (cur < 0) return -1;
|
|
9165
|
+
if (values !== void 0) values.push(TERMV);
|
|
9166
|
+
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
9167
|
+
};
|
|
9168
|
+
return (input, cur, ctx, values) => {
|
|
9169
|
+
cur = nextTerm(k0, input, cur, ctx);
|
|
9170
|
+
if (cur < 0) return -1;
|
|
9171
|
+
if (values !== void 0) values.push(TERMV);
|
|
9172
|
+
cur = nextTerm(k1, input, cur, ctx);
|
|
9173
|
+
if (cur < 0) return -1;
|
|
9174
|
+
if (values !== void 0) values.push(TERMV);
|
|
9175
|
+
cur = nextTerm(k2, input, cur, ctx);
|
|
9176
|
+
if (cur < 0) return -1;
|
|
9177
|
+
if (values !== void 0) values.push(TERMV);
|
|
9178
|
+
cur = nextTerm(k3, input, cur, ctx);
|
|
9179
|
+
if (cur < 0) return -1;
|
|
9180
|
+
if (values !== void 0) values.push(TERMV);
|
|
9181
|
+
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
9182
|
+
};
|
|
9183
|
+
};
|
|
9184
|
+
const bind = (start) => {
|
|
9185
|
+
const count = Math.min(4, n - start);
|
|
9186
|
+
const child = (offset) => link(code[base + start + offset]);
|
|
9187
|
+
return block(
|
|
9188
|
+
count,
|
|
9189
|
+
child(0),
|
|
9190
|
+
count > 1 ? child(1) : NEVER_PIECE,
|
|
9191
|
+
count > 2 ? child(2) : NEVER_PIECE,
|
|
9192
|
+
count > 3 ? child(3) : NEVER_PIECE,
|
|
9193
|
+
start + count < n ? bind(start + count) : void 0
|
|
9194
|
+
);
|
|
9195
|
+
};
|
|
9196
|
+
const first = link(code[base]);
|
|
9197
|
+
const tail = bind(1);
|
|
9198
|
+
const runDirectTerms = (input, pos, ctx, values) => {
|
|
9199
|
+
const v0 = first(input, pos, ctx);
|
|
9200
|
+
if (v0 === FAIL) return -1;
|
|
9201
|
+
if (values !== void 0) values.push(v0);
|
|
9202
|
+
return tail(input, EC.e, ctx, values);
|
|
9203
|
+
};
|
|
7474
9204
|
if (fused) {
|
|
7475
9205
|
return (input, pos, ctx) => {
|
|
7476
9206
|
const values = [];
|
|
7477
|
-
const cur =
|
|
9207
|
+
const cur = runDirectTerms(input, pos, ctx, values);
|
|
7478
9208
|
if (cur < 0) return FAIL;
|
|
7479
9209
|
EC.e = cur;
|
|
7480
|
-
return fn(values, { start: pos, end: cur });
|
|
9210
|
+
return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
|
|
7481
9211
|
};
|
|
7482
9212
|
}
|
|
7483
9213
|
if (wantValues) {
|
|
7484
9214
|
return (input, pos, ctx) => {
|
|
7485
9215
|
const values = [];
|
|
7486
|
-
const cur =
|
|
9216
|
+
const cur = runDirectTerms(input, pos, ctx, values);
|
|
7487
9217
|
if (cur < 0) return FAIL;
|
|
7488
9218
|
EC.e = cur;
|
|
7489
9219
|
return values;
|
|
7490
9220
|
};
|
|
7491
9221
|
}
|
|
7492
9222
|
return (input, pos, ctx) => {
|
|
7493
|
-
const cur =
|
|
9223
|
+
const cur = runDirectTerms(input, pos, ctx, void 0);
|
|
7494
9224
|
if (cur < 0) return FAIL;
|
|
7495
9225
|
EC.e = cur;
|
|
7496
9226
|
return void 0;
|
|
@@ -7502,13 +9232,86 @@ function assemble(t, prog, cfg) {
|
|
|
7502
9232
|
const n = code[ip + 2];
|
|
7503
9233
|
const choiceFx = fx[code[ip + 3]];
|
|
7504
9234
|
const base = ip + 4;
|
|
7505
|
-
const arms = new Array(n);
|
|
7506
|
-
for (let i = 0; i < n; i++) arms[i] = link(code[base + i]);
|
|
7507
|
-
const armFx = new Array(n);
|
|
7508
|
-
for (let i = 0; i < n; i++) armFx[i] = fx[code[base + n + i]];
|
|
7509
9235
|
if (table.exclusive) {
|
|
7510
9236
|
const ascii = table.ascii;
|
|
7511
9237
|
const hi = table.hi;
|
|
9238
|
+
if (n === 2) {
|
|
9239
|
+
const a0 = link(code[base]), a1 = link(code[base + 1]);
|
|
9240
|
+
return (input, pos, ctx) => {
|
|
9241
|
+
const c = lead(input, pos);
|
|
9242
|
+
let arm = -1;
|
|
9243
|
+
if (c >= 0 && c < 128) {
|
|
9244
|
+
const a = ascii[c];
|
|
9245
|
+
if (a !== 0) arm = a - 1;
|
|
9246
|
+
} else if (c >= 128) {
|
|
9247
|
+
for (let i = 0; i < hi.length; i += 3) {
|
|
9248
|
+
if (c >= hi[i] && c <= hi[i + 1]) {
|
|
9249
|
+
arm = hi[i + 2];
|
|
9250
|
+
break;
|
|
9251
|
+
}
|
|
9252
|
+
}
|
|
9253
|
+
}
|
|
9254
|
+
if (arm >= 0) {
|
|
9255
|
+
ctx._fc = false;
|
|
9256
|
+
const v = arm === 0 ? a0(input, pos, ctx) : a1(input, pos, ctx);
|
|
9257
|
+
if (v !== FAIL) return v;
|
|
9258
|
+
if (committed3(ctx)) return FAIL;
|
|
9259
|
+
const failed = ctx._fx;
|
|
9260
|
+
if (failed !== void 0 && failed.length > 0) {
|
|
9261
|
+
ctx._fe = pos;
|
|
9262
|
+
return FAIL;
|
|
9263
|
+
}
|
|
9264
|
+
}
|
|
9265
|
+
ctx._fe = pos;
|
|
9266
|
+
ctx._fx = choiceFx;
|
|
9267
|
+
return FAIL;
|
|
9268
|
+
};
|
|
9269
|
+
}
|
|
9270
|
+
if (n === 3) {
|
|
9271
|
+
const a0 = link(code[base]), a1 = link(code[base + 1]), a2 = link(code[base + 2]);
|
|
9272
|
+
return (input, pos, ctx) => {
|
|
9273
|
+
const c = lead(input, pos);
|
|
9274
|
+
let arm = -1;
|
|
9275
|
+
if (c >= 0 && c < 128) {
|
|
9276
|
+
const a = ascii[c];
|
|
9277
|
+
if (a !== 0) arm = a - 1;
|
|
9278
|
+
} else if (c >= 128) {
|
|
9279
|
+
for (let i = 0; i < hi.length; i += 3) {
|
|
9280
|
+
if (c >= hi[i] && c <= hi[i + 1]) {
|
|
9281
|
+
arm = hi[i + 2];
|
|
9282
|
+
break;
|
|
9283
|
+
}
|
|
9284
|
+
}
|
|
9285
|
+
}
|
|
9286
|
+
if (arm >= 0) {
|
|
9287
|
+
ctx._fc = false;
|
|
9288
|
+
const v = arm === 0 ? a0(input, pos, ctx) : arm === 1 ? a1(input, pos, ctx) : a2(input, pos, ctx);
|
|
9289
|
+
if (v !== FAIL) return v;
|
|
9290
|
+
if (committed3(ctx)) return FAIL;
|
|
9291
|
+
const failed = ctx._fx;
|
|
9292
|
+
if (failed !== void 0 && failed.length > 0) {
|
|
9293
|
+
ctx._fe = pos;
|
|
9294
|
+
return FAIL;
|
|
9295
|
+
}
|
|
9296
|
+
}
|
|
9297
|
+
ctx._fe = pos;
|
|
9298
|
+
ctx._fx = choiceFx;
|
|
9299
|
+
return FAIL;
|
|
9300
|
+
};
|
|
9301
|
+
}
|
|
9302
|
+
const bindExclusive = (start) => {
|
|
9303
|
+
const at = (i) => i < n ? link(code[base + i]) : NEVER_PIECE;
|
|
9304
|
+
const next = start + 4 < n ? bindExclusive(start + 4) : void 0;
|
|
9305
|
+
return exclusiveChoiceBlock(
|
|
9306
|
+
start,
|
|
9307
|
+
at(start),
|
|
9308
|
+
at(start + 1),
|
|
9309
|
+
at(start + 2),
|
|
9310
|
+
at(start + 3),
|
|
9311
|
+
next
|
|
9312
|
+
);
|
|
9313
|
+
};
|
|
9314
|
+
const selected = bindExclusive(0);
|
|
7512
9315
|
return (input, pos, ctx) => {
|
|
7513
9316
|
const c = lead(input, pos);
|
|
7514
9317
|
let arm = -1;
|
|
@@ -7525,11 +9328,11 @@ function assemble(t, prog, cfg) {
|
|
|
7525
9328
|
}
|
|
7526
9329
|
if (arm >= 0) {
|
|
7527
9330
|
ctx._fc = false;
|
|
7528
|
-
const v =
|
|
9331
|
+
const v = selected(arm, input, pos, ctx);
|
|
7529
9332
|
if (v !== FAIL) return v;
|
|
7530
|
-
if (
|
|
7531
|
-
const
|
|
7532
|
-
if (
|
|
9333
|
+
if (committed3(ctx)) return FAIL;
|
|
9334
|
+
const armFx = ctx._fx;
|
|
9335
|
+
if (armFx !== void 0 && armFx.length > 0) {
|
|
7533
9336
|
ctx._fe = pos;
|
|
7534
9337
|
return FAIL;
|
|
7535
9338
|
}
|
|
@@ -7540,25 +9343,25 @@ function assemble(t, prog, cfg) {
|
|
|
7540
9343
|
};
|
|
7541
9344
|
}
|
|
7542
9345
|
const armCls = table.armCls;
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
const
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
9346
|
+
if (n === 2 || n === 3) {
|
|
9347
|
+
const a0 = link(code[base]), a1 = link(code[base + 1]);
|
|
9348
|
+
const a2 = n === 3 ? link(code[base + 2]) : void 0;
|
|
9349
|
+
const e0 = fx[code[base + n]];
|
|
9350
|
+
const e1 = fx[code[base + n + 1]];
|
|
9351
|
+
const e2 = n === 3 ? fx[code[base + n + 2]] : void 0;
|
|
9352
|
+
const g0 = armCls[0] ?? null, g1 = armCls[1] ?? null;
|
|
9353
|
+
const g2 = n === 3 ? armCls[2] ?? null : null;
|
|
9354
|
+
const mask = new Uint32Array(129);
|
|
9355
|
+
const addGate = (cls, bit) => {
|
|
7552
9356
|
if (cls === null) {
|
|
7553
|
-
for (let c = 0; c < 129; c++)
|
|
7554
|
-
|
|
9357
|
+
for (let c = 0; c < 129; c++) mask[c] |= bit;
|
|
9358
|
+
return;
|
|
7555
9359
|
}
|
|
7556
|
-
for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1)
|
|
7557
|
-
}
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
const mask = cand;
|
|
9360
|
+
for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) mask[c] |= bit;
|
|
9361
|
+
};
|
|
9362
|
+
addGate(g0, 1);
|
|
9363
|
+
addGate(g1, 2);
|
|
9364
|
+
if (n === 3) addGate(g2, 4);
|
|
7562
9365
|
return (input, pos, ctx) => {
|
|
7563
9366
|
const c = lead(input, pos);
|
|
7564
9367
|
const need = markCst(ctx);
|
|
@@ -7570,51 +9373,240 @@ function assemble(t, prog, cfg) {
|
|
|
7570
9373
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
7571
9374
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
7572
9375
|
let acc;
|
|
9376
|
+
let best = pos;
|
|
7573
9377
|
if (c < 128) {
|
|
7574
|
-
const
|
|
7575
|
-
let bits = bits0;
|
|
9378
|
+
const bits = mask[c < 0 ? 128 : c];
|
|
7576
9379
|
let prev = 0;
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
9380
|
+
if ((bits & 1) !== 0) {
|
|
9381
|
+
ctx._fc = false;
|
|
9382
|
+
const v = a0(input, pos, ctx);
|
|
9383
|
+
if (v !== FAIL) return v;
|
|
9384
|
+
prev = 1;
|
|
9385
|
+
const at = ctx._fe ?? pos;
|
|
9386
|
+
if (at > best) {
|
|
9387
|
+
best = at;
|
|
9388
|
+
acc = void 0;
|
|
9389
|
+
}
|
|
9390
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
9391
|
+
if (committed3(ctx)) {
|
|
9392
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
9393
|
+
return FAIL;
|
|
9394
|
+
}
|
|
9395
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9396
|
+
}
|
|
9397
|
+
if ((bits & 2) !== 0) {
|
|
9398
|
+
ctx._fc = false;
|
|
9399
|
+
const v = a1(input, pos, ctx);
|
|
9400
|
+
if (v !== FAIL) return v;
|
|
9401
|
+
if (best === pos && prev < 1) acc = accSet(e0, acc);
|
|
9402
|
+
prev = 2;
|
|
9403
|
+
const at = ctx._fe ?? pos;
|
|
9404
|
+
if (at > best) {
|
|
9405
|
+
best = at;
|
|
9406
|
+
acc = void 0;
|
|
9407
|
+
}
|
|
9408
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
9409
|
+
if (committed3(ctx)) {
|
|
9410
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
9411
|
+
return FAIL;
|
|
9412
|
+
}
|
|
9413
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9414
|
+
}
|
|
9415
|
+
if (n === 3 && (bits & 4) !== 0) {
|
|
7580
9416
|
ctx._fc = false;
|
|
7581
|
-
const v =
|
|
9417
|
+
const v = a2(input, pos, ctx);
|
|
7582
9418
|
if (v !== FAIL) return v;
|
|
7583
|
-
|
|
7584
|
-
prev =
|
|
7585
|
-
|
|
7586
|
-
|
|
9419
|
+
if (best === pos && prev < 1) acc = accSet(e0, acc);
|
|
9420
|
+
if (best === pos && prev < 2) acc = accSet(e1, acc);
|
|
9421
|
+
prev = 3;
|
|
9422
|
+
const at = ctx._fe ?? pos;
|
|
9423
|
+
if (at > best) {
|
|
9424
|
+
best = at;
|
|
9425
|
+
acc = void 0;
|
|
9426
|
+
}
|
|
9427
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
9428
|
+
if (committed3(ctx)) {
|
|
7587
9429
|
if (acc !== void 0) ctx._fx = acc;
|
|
7588
9430
|
return FAIL;
|
|
7589
9431
|
}
|
|
7590
9432
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7591
9433
|
}
|
|
7592
|
-
|
|
9434
|
+
if (best === pos && prev < 1) acc = accSet(e0, acc);
|
|
9435
|
+
if (best === pos && prev < 2) acc = accSet(e1, acc);
|
|
9436
|
+
if (best === pos && n === 3 && prev < 3) acc = accSet(e2, acc);
|
|
7593
9437
|
ctx._fe = pos;
|
|
7594
9438
|
ctx._fx = acc ?? choiceFx;
|
|
7595
9439
|
return FAIL;
|
|
7596
9440
|
}
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
9441
|
+
if (g0 === null || classHas2(g0, c)) {
|
|
9442
|
+
ctx._fc = false;
|
|
9443
|
+
const v = a0(input, pos, ctx);
|
|
9444
|
+
if (v !== FAIL) return v;
|
|
9445
|
+
const at = ctx._fe ?? pos;
|
|
9446
|
+
if (at > best) {
|
|
9447
|
+
best = at;
|
|
9448
|
+
acc = void 0;
|
|
9449
|
+
}
|
|
9450
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
9451
|
+
if (committed3(ctx)) {
|
|
9452
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
9453
|
+
return FAIL;
|
|
7602
9454
|
}
|
|
9455
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9456
|
+
} else if (best === pos) acc = accSet(e0, acc);
|
|
9457
|
+
if (g1 === null || classHas2(g1, c)) {
|
|
7603
9458
|
ctx._fc = false;
|
|
7604
|
-
const v =
|
|
9459
|
+
const v = a1(input, pos, ctx);
|
|
7605
9460
|
if (v !== FAIL) return v;
|
|
7606
|
-
|
|
7607
|
-
if (
|
|
9461
|
+
const at = ctx._fe ?? pos;
|
|
9462
|
+
if (at > best) {
|
|
9463
|
+
best = at;
|
|
9464
|
+
acc = void 0;
|
|
9465
|
+
}
|
|
9466
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
9467
|
+
if (committed3(ctx)) {
|
|
7608
9468
|
if (acc !== void 0) ctx._fx = acc;
|
|
7609
9469
|
return FAIL;
|
|
7610
9470
|
}
|
|
7611
9471
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9472
|
+
} else if (best === pos) acc = accSet(e1, acc);
|
|
9473
|
+
if (n === 3) {
|
|
9474
|
+
if (g2 === null || classHas2(g2, c)) {
|
|
9475
|
+
ctx._fc = false;
|
|
9476
|
+
const v = a2(input, pos, ctx);
|
|
9477
|
+
if (v !== FAIL) return v;
|
|
9478
|
+
const at = ctx._fe ?? pos;
|
|
9479
|
+
if (at > best) {
|
|
9480
|
+
best = at;
|
|
9481
|
+
acc = void 0;
|
|
9482
|
+
}
|
|
9483
|
+
if (at === best) acc = accSet(ctx._fx, acc);
|
|
9484
|
+
if (committed3(ctx)) {
|
|
9485
|
+
if (acc !== void 0) ctx._fx = acc;
|
|
9486
|
+
return FAIL;
|
|
9487
|
+
}
|
|
9488
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9489
|
+
} else if (best === pos) acc = accSet(e2, acc);
|
|
7612
9490
|
}
|
|
7613
9491
|
ctx._fe = pos;
|
|
7614
9492
|
ctx._fx = acc ?? choiceFx;
|
|
7615
9493
|
return FAIL;
|
|
7616
9494
|
};
|
|
7617
9495
|
}
|
|
9496
|
+
const bindGeneral = (start, prior) => {
|
|
9497
|
+
const arm = (i) => i < n ? link(code[base + i]) : NEVER_PIECE;
|
|
9498
|
+
const expected = (i) => i < n ? fx[code[base + n + i]] : EMPTY_FX2;
|
|
9499
|
+
const gate = (i) => i < n ? armCls[i] ?? null : NEVER_CLASS;
|
|
9500
|
+
const through = expectedBlock(
|
|
9501
|
+
start,
|
|
9502
|
+
expected(start),
|
|
9503
|
+
expected(start + 1),
|
|
9504
|
+
expected(start + 2),
|
|
9505
|
+
expected(start + 3),
|
|
9506
|
+
prior
|
|
9507
|
+
);
|
|
9508
|
+
const next = start + 4 < n ? bindGeneral(start + 4, through) : void 0;
|
|
9509
|
+
return generalChoiceBlock(
|
|
9510
|
+
start,
|
|
9511
|
+
arm(start),
|
|
9512
|
+
arm(start + 1),
|
|
9513
|
+
arm(start + 2),
|
|
9514
|
+
arm(start + 3),
|
|
9515
|
+
gate(start),
|
|
9516
|
+
gate(start + 1),
|
|
9517
|
+
gate(start + 2),
|
|
9518
|
+
gate(start + 3),
|
|
9519
|
+
through,
|
|
9520
|
+
next,
|
|
9521
|
+
n,
|
|
9522
|
+
choiceFx
|
|
9523
|
+
);
|
|
9524
|
+
};
|
|
9525
|
+
const general = bindGeneral(0, EMPTY_EXPECTED_PREFIX);
|
|
9526
|
+
if (n <= 32) {
|
|
9527
|
+
const mask = new Uint32Array(129);
|
|
9528
|
+
for (let i = 0; i < n; i++) {
|
|
9529
|
+
const cls = armCls[i] ?? null;
|
|
9530
|
+
const bit = 1 << i;
|
|
9531
|
+
if (cls === null) {
|
|
9532
|
+
for (let c = 0; c < 129; c++) mask[c] |= bit;
|
|
9533
|
+
continue;
|
|
9534
|
+
}
|
|
9535
|
+
for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) mask[c] |= bit;
|
|
9536
|
+
}
|
|
9537
|
+
const bindMasked = (start, prior) => {
|
|
9538
|
+
const arm = (i) => i < n ? link(code[base + i]) : NEVER_PIECE;
|
|
9539
|
+
const expected = (i) => i < n ? fx[code[base + n + i]] : EMPTY_FX2;
|
|
9540
|
+
const through = expectedBlock(
|
|
9541
|
+
start,
|
|
9542
|
+
expected(start),
|
|
9543
|
+
expected(start + 1),
|
|
9544
|
+
expected(start + 2),
|
|
9545
|
+
expected(start + 3),
|
|
9546
|
+
prior
|
|
9547
|
+
);
|
|
9548
|
+
const next = start + 4 < n ? bindMasked(start + 4, through) : void 0;
|
|
9549
|
+
return maskedChoiceBlock(
|
|
9550
|
+
start,
|
|
9551
|
+
arm(start),
|
|
9552
|
+
arm(start + 1),
|
|
9553
|
+
arm(start + 2),
|
|
9554
|
+
arm(start + 3),
|
|
9555
|
+
through,
|
|
9556
|
+
next,
|
|
9557
|
+
n,
|
|
9558
|
+
choiceFx
|
|
9559
|
+
);
|
|
9560
|
+
};
|
|
9561
|
+
const masked = bindMasked(0, EMPTY_EXPECTED_PREFIX);
|
|
9562
|
+
return (input, pos, ctx) => {
|
|
9563
|
+
const c = lead(input, pos);
|
|
9564
|
+
const need = markCst(ctx);
|
|
9565
|
+
const mRaw = MRAW;
|
|
9566
|
+
const mTl = MTL;
|
|
9567
|
+
const mLv = MLV;
|
|
9568
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
9569
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
9570
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
9571
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
9572
|
+
if (c < 128) {
|
|
9573
|
+
return masked(
|
|
9574
|
+
input,
|
|
9575
|
+
pos,
|
|
9576
|
+
ctx,
|
|
9577
|
+
mask[c < 0 ? 128 : c],
|
|
9578
|
+
need,
|
|
9579
|
+
mRaw,
|
|
9580
|
+
mTl,
|
|
9581
|
+
mLv,
|
|
9582
|
+
mFl,
|
|
9583
|
+
mEr,
|
|
9584
|
+
mLog,
|
|
9585
|
+
mRoot,
|
|
9586
|
+
void 0,
|
|
9587
|
+
0,
|
|
9588
|
+
pos
|
|
9589
|
+
);
|
|
9590
|
+
}
|
|
9591
|
+
return general(
|
|
9592
|
+
input,
|
|
9593
|
+
pos,
|
|
9594
|
+
ctx,
|
|
9595
|
+
c,
|
|
9596
|
+
need,
|
|
9597
|
+
mRaw,
|
|
9598
|
+
mTl,
|
|
9599
|
+
mLv,
|
|
9600
|
+
mFl,
|
|
9601
|
+
mEr,
|
|
9602
|
+
mLog,
|
|
9603
|
+
mRoot,
|
|
9604
|
+
void 0,
|
|
9605
|
+
0,
|
|
9606
|
+
pos
|
|
9607
|
+
);
|
|
9608
|
+
};
|
|
9609
|
+
}
|
|
7618
9610
|
return (input, pos, ctx) => {
|
|
7619
9611
|
const c = lead(input, pos);
|
|
7620
9612
|
const need = markCst(ctx);
|
|
@@ -7625,26 +9617,23 @@ function assemble(t, prog, cfg) {
|
|
|
7625
9617
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
7626
9618
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
7627
9619
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
ctx._fe = pos;
|
|
7646
|
-
ctx._fx = acc ?? choiceFx;
|
|
7647
|
-
return FAIL;
|
|
9620
|
+
return general(
|
|
9621
|
+
input,
|
|
9622
|
+
pos,
|
|
9623
|
+
ctx,
|
|
9624
|
+
c,
|
|
9625
|
+
need,
|
|
9626
|
+
mRaw,
|
|
9627
|
+
mTl,
|
|
9628
|
+
mLv,
|
|
9629
|
+
mFl,
|
|
9630
|
+
mEr,
|
|
9631
|
+
mLog,
|
|
9632
|
+
mRoot,
|
|
9633
|
+
void 0,
|
|
9634
|
+
0,
|
|
9635
|
+
pos
|
|
9636
|
+
);
|
|
7648
9637
|
};
|
|
7649
9638
|
}
|
|
7650
9639
|
/* ── greedyClassify / autoNot ────────────────────────────────────────── */
|
|
@@ -7713,7 +9702,7 @@ function assemble(t, prog, cfg) {
|
|
|
7713
9702
|
if (nc !== 0) {
|
|
7714
9703
|
const c = lead(input, end);
|
|
7715
9704
|
for (let i = 0; i < nc; i++) {
|
|
7716
|
-
if (!
|
|
9705
|
+
if (!classHas2(clss[i], c)) continue;
|
|
7717
9706
|
ctx._fc = false;
|
|
7718
9707
|
ctx._fx = void 0;
|
|
7719
9708
|
return FAIL;
|
|
@@ -7737,6 +9726,9 @@ function assemble(t, prog, cfg) {
|
|
|
7737
9726
|
const reportItem = (flags & 4) !== 0;
|
|
7738
9727
|
const itemFx = reportItem ? fx[code[ip + 6]] : EMPTY_FX2;
|
|
7739
9728
|
const collect = op === OP_REP;
|
|
9729
|
+
const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
|
|
9730
|
+
const itemClass = !REC && itemClassIndex >= 0 ? cc[itemClassIndex] : void 0;
|
|
9731
|
+
const itemMayStart = itemClass === void 0 ? void 0 : (input, pos) => classHas2(itemClass, lead(input, pos));
|
|
7740
9732
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
7741
9733
|
if (REC) {
|
|
7742
9734
|
const itemFx2 = fx[code[ip + 6]];
|
|
@@ -7770,7 +9762,7 @@ function assemble(t, prog, cfg) {
|
|
|
7770
9762
|
const sv = sep(input, sp, ctx);
|
|
7771
9763
|
if (sv === FAIL) {
|
|
7772
9764
|
if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7773
|
-
if (
|
|
9765
|
+
if (committed3(ctx)) return FAIL;
|
|
7774
9766
|
break;
|
|
7775
9767
|
}
|
|
7776
9768
|
if (!keepSeparators) demoteCapturedToRaw(ctx, leavesBefore);
|
|
@@ -7787,7 +9779,7 @@ function assemble(t, prog, cfg) {
|
|
|
7787
9779
|
ctx._fc = false;
|
|
7788
9780
|
const v = child(input, itemStart, ctx);
|
|
7789
9781
|
if (v === FAIL) {
|
|
7790
|
-
if (
|
|
9782
|
+
if (committed3(ctx)) {
|
|
7791
9783
|
if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7792
9784
|
return FAIL;
|
|
7793
9785
|
}
|
|
@@ -7833,11 +9825,13 @@ function assemble(t, prog, cfg) {
|
|
|
7833
9825
|
const out = collect ? [] : void 0;
|
|
7834
9826
|
const hasTrivia = ctx.trivia !== void 0;
|
|
7835
9827
|
const needMark = rollbackNeeded(ctx);
|
|
9828
|
+
const gateItems = itemMayStart !== void 0 && ctx._probe === void 0;
|
|
7836
9829
|
let cur = pos;
|
|
7837
9830
|
let count = 0;
|
|
7838
9831
|
for (; ; ) {
|
|
7839
9832
|
if (max >= 0 && count >= max) break;
|
|
7840
9833
|
if (sep !== void 0 && count > 0 && count >= min && cur >= input.length) break;
|
|
9834
|
+
if (count >= min && sep === void 0 && !hasTrivia && gateItems && !itemMayStart(input, cur)) break;
|
|
7841
9835
|
if (needMark) markCst(ctx);
|
|
7842
9836
|
const mRaw = needMark ? MRAW : 0;
|
|
7843
9837
|
const mTl = needMark ? MTL : 0;
|
|
@@ -7857,7 +9851,7 @@ function assemble(t, prog, cfg) {
|
|
|
7857
9851
|
const sv = sep(input, sp, ctx);
|
|
7858
9852
|
if (sv === FAIL) {
|
|
7859
9853
|
if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7860
|
-
if (
|
|
9854
|
+
if (committed3(ctx)) return FAIL;
|
|
7861
9855
|
break;
|
|
7862
9856
|
}
|
|
7863
9857
|
if (!keepSeparators) demoteCapturedToRaw(ctx, leavesBefore);
|
|
@@ -7871,11 +9865,16 @@ function assemble(t, prog, cfg) {
|
|
|
7871
9865
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
7872
9866
|
break;
|
|
7873
9867
|
}
|
|
9868
|
+
if (count >= min && gateItems && !itemMayStart(input, itemStart)) {
|
|
9869
|
+
if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9870
|
+
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
9871
|
+
break;
|
|
9872
|
+
}
|
|
7874
9873
|
ctx._fc = false;
|
|
7875
9874
|
const v = child(input, itemStart, ctx);
|
|
7876
9875
|
if (v === FAIL) {
|
|
7877
9876
|
if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
7878
|
-
if (
|
|
9877
|
+
if (committed3(ctx)) return FAIL;
|
|
7879
9878
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
7880
9879
|
break;
|
|
7881
9880
|
}
|
|
@@ -7907,78 +9906,103 @@ function assemble(t, prog, cfg) {
|
|
|
7907
9906
|
const otherRouted = code[ip + 4] === 1;
|
|
7908
9907
|
const n = code[ip + 5];
|
|
7909
9908
|
const armBase = ip + 6;
|
|
7910
|
-
const arms = new Array(n);
|
|
7911
|
-
for (let i = 0; i < n; i++) arms[i] = link(code[armBase + i]);
|
|
7912
9909
|
const byKey = spec.byKey;
|
|
7913
9910
|
const byFold = spec.byFold;
|
|
7914
9911
|
const hasFold = spec.byFold.size > 0;
|
|
7915
9912
|
const match = spec.match;
|
|
7916
9913
|
const matchN = match.length;
|
|
7917
|
-
const matchFn = new Array(matchN);
|
|
7918
|
-
const matchArm = new Array(matchN);
|
|
7919
|
-
for (let i = 0; i < matchN; i++) {
|
|
7920
|
-
matchFn[i] = linkMatcher(match[i]);
|
|
7921
|
-
matchArm[i] = match[i][3];
|
|
7922
|
-
}
|
|
7923
9914
|
const routed = spec.routed;
|
|
7924
9915
|
const expected = spec.expected;
|
|
9916
|
+
const validArm = (arm) => Number.isInteger(arm) && arm >= 0 && arm < n;
|
|
9917
|
+
if (routed.length !== n) throw new TypeError("table assembler: malformed dispatch routed arity");
|
|
9918
|
+
for (const arm of byKey.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch exact arm");
|
|
9919
|
+
for (const arm of byFold.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch folded arm");
|
|
9920
|
+
for (const m of match) if (!validArm(m[3])) throw new TypeError("table assembler: malformed dispatch matcher arm");
|
|
9921
|
+
const neverMatch = () => false;
|
|
9922
|
+
const bindMatchers = (start) => {
|
|
9923
|
+
const pred = (i) => i < matchN ? linkMatcher(match[i]) : neverMatch;
|
|
9924
|
+
const arm = (i) => i < matchN ? match[i][3] : -1;
|
|
9925
|
+
const next = start + 4 < matchN ? bindMatchers(start + 4) : void 0;
|
|
9926
|
+
return dispatchMatcherBlock(
|
|
9927
|
+
pred(start),
|
|
9928
|
+
arm(start),
|
|
9929
|
+
pred(start + 1),
|
|
9930
|
+
arm(start + 1),
|
|
9931
|
+
pred(start + 2),
|
|
9932
|
+
arm(start + 2),
|
|
9933
|
+
pred(start + 3),
|
|
9934
|
+
arm(start + 3),
|
|
9935
|
+
next
|
|
9936
|
+
);
|
|
9937
|
+
};
|
|
9938
|
+
const matchBlock = matchN === 0 ? void 0 : bindMatchers(0);
|
|
9939
|
+
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);
|
|
9940
|
+
const neverBranch = () => FAIL;
|
|
9941
|
+
const bindArms = (start) => {
|
|
9942
|
+
const branch = (i) => i < n ? dispatchBranch(link(code[armBase + i]), routed[i] === 1) : neverBranch;
|
|
9943
|
+
const next = start + 4 < n ? bindArms(start + 4) : void 0;
|
|
9944
|
+
return dispatchArmBlock(
|
|
9945
|
+
start,
|
|
9946
|
+
branch(start),
|
|
9947
|
+
branch(start + 1),
|
|
9948
|
+
branch(start + 2),
|
|
9949
|
+
branch(start + 3),
|
|
9950
|
+
next
|
|
9951
|
+
);
|
|
9952
|
+
};
|
|
9953
|
+
const runArm = n === 0 ? void 0 : bindArms(0);
|
|
9954
|
+
const runOther = other === void 0 ? void 0 : dispatchBranch(other, otherRouted);
|
|
7925
9955
|
return (input, pos, ctx) => {
|
|
7926
9956
|
const selectorMark = saveTriviaMark(ctx);
|
|
7927
9957
|
const selVal = selector(input, pos, ctx);
|
|
7928
9958
|
if (selVal === FAIL) return FAIL;
|
|
7929
9959
|
const selEnd = EC.e;
|
|
7930
9960
|
const key = selVal;
|
|
7931
|
-
|
|
7932
|
-
if (arm === void 0 && hasFold) arm = byFold.get(asciiFoldKey(key));
|
|
7933
|
-
if (arm === void 0) {
|
|
7934
|
-
for (let i = 0; i < matchN; i++) {
|
|
7935
|
-
if (matchFn[i](key)) {
|
|
7936
|
-
arm = matchArm[i];
|
|
7937
|
-
break;
|
|
7938
|
-
}
|
|
7939
|
-
}
|
|
7940
|
-
}
|
|
7941
|
-
let target;
|
|
7942
|
-
let usesRouted;
|
|
9961
|
+
const arm = classify(key);
|
|
7943
9962
|
if (arm === void 0) {
|
|
7944
|
-
if (
|
|
9963
|
+
if (runOther === void 0) {
|
|
7945
9964
|
ctx._fe = selEnd;
|
|
7946
9965
|
ctx._fx = expected;
|
|
7947
9966
|
return FAIL;
|
|
7948
9967
|
}
|
|
7949
|
-
|
|
7950
|
-
usesRouted = otherRouted;
|
|
7951
|
-
} else {
|
|
7952
|
-
target = arms[arm];
|
|
7953
|
-
usesRouted = routed[arm] === 1;
|
|
7954
|
-
}
|
|
7955
|
-
let mark = saveTriviaMark(ctx);
|
|
7956
|
-
let v;
|
|
7957
|
-
if (usesRouted) {
|
|
7958
|
-
const savedRouted = ctx._routed;
|
|
7959
|
-
rollbackTrivia(ctx, selectorMark);
|
|
7960
|
-
mark = saveTriviaMark(ctx);
|
|
7961
|
-
ctx._routed = { value: key, span: { start: pos, end: selEnd } };
|
|
7962
|
-
try {
|
|
7963
|
-
v = target(input, pos, ctx);
|
|
7964
|
-
} finally {
|
|
7965
|
-
ctx._routed = savedRouted;
|
|
7966
|
-
}
|
|
7967
|
-
} else {
|
|
7968
|
-
v = target(input, selEnd, ctx);
|
|
7969
|
-
}
|
|
7970
|
-
if (v === FAIL) {
|
|
7971
|
-
rollbackTrivia(ctx, mark);
|
|
7972
|
-
ctx._fc = true;
|
|
7973
|
-
return FAIL;
|
|
9968
|
+
return runOther(input, pos, selEnd, key, selectorMark, ctx);
|
|
7974
9969
|
}
|
|
7975
|
-
return
|
|
9970
|
+
return runArm(arm, input, pos, selEnd, key, selectorMark, ctx);
|
|
7976
9971
|
};
|
|
7977
9972
|
}
|
|
7978
9973
|
/* ── node ────────────────────────────────────────────────────────────── */
|
|
7979
9974
|
case OP_NODE:
|
|
7980
9975
|
case OP_NODE_TRACK: {
|
|
7981
9976
|
const flags = code[ip + 3];
|
|
9977
|
+
const scalarChild = !hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines ? scalarTerminalNodeChild(code, ip) : -1;
|
|
9978
|
+
if (scalarChild >= 0) {
|
|
9979
|
+
const recognize = scalarFor(scalarChild);
|
|
9980
|
+
const spec = k[code[scalarChild + 1]];
|
|
9981
|
+
const regexValue = code[scalarChild] === OP_RX;
|
|
9982
|
+
const xf = fx[code[scalarChild + 2]];
|
|
9983
|
+
const build2 = fns[code[ip + 1]];
|
|
9984
|
+
return (input, pos, ctx) => {
|
|
9985
|
+
const end = recognize(input, pos);
|
|
9986
|
+
if (end < 0) {
|
|
9987
|
+
ctx._fe = pos;
|
|
9988
|
+
ctx._fx = xf;
|
|
9989
|
+
if (ctx._probe !== void 0) failAt(ctx, xf, pos);
|
|
9990
|
+
return FAIL;
|
|
9991
|
+
}
|
|
9992
|
+
const value = regexValue ? input.slice(pos, end) : spec;
|
|
9993
|
+
const leaf = { _tag: "leaf", value, span: { start: pos, end } };
|
|
9994
|
+
const kids = [leaf];
|
|
9995
|
+
const rawKids = [leaf];
|
|
9996
|
+
const span = { start: pos, end };
|
|
9997
|
+
EC.e = end;
|
|
9998
|
+
const nd = build2(kids, void 0, span, rawKids, EMPTY_TL, void 0);
|
|
9999
|
+
if (ctx._cstBuf !== void 0 || ctx._cstChildren !== void 0) {
|
|
10000
|
+
pushCstChild(ctx, nd, ctx._cstRawChildren !== void 0 || ctx._cstBuf !== void 0 ? rawEntry(nd, input, pos, end) : void 0);
|
|
10001
|
+
}
|
|
10002
|
+
EC.e = end;
|
|
10003
|
+
return nd;
|
|
10004
|
+
};
|
|
10005
|
+
}
|
|
7982
10006
|
const child = link(code[ip + 2]);
|
|
7983
10007
|
const proj = code[ip + 4];
|
|
7984
10008
|
const buildIdx = code[ip + 1];
|
|
@@ -7993,6 +10017,26 @@ function assemble(t, prog, cfg) {
|
|
|
7993
10017
|
const unwrap = (flags & 64) !== 0;
|
|
7994
10018
|
const trailingTrivia = (flags & 128) !== 0;
|
|
7995
10019
|
const build = buildIdx >= 0 ? fns[buildIdx] : void 0;
|
|
10020
|
+
if (!hostCst && !tracked) {
|
|
10021
|
+
if (build !== void 0 && proj < 0 && flags === 0) {
|
|
10022
|
+
return plainBuildNode(child, build);
|
|
10023
|
+
}
|
|
10024
|
+
if (build !== void 0 && proj < 0 && flags === 2) {
|
|
10025
|
+
return childrenOnlyBuildNode(child, build);
|
|
10026
|
+
}
|
|
10027
|
+
if (build !== void 0 && proj < 0 && flags === 18) {
|
|
10028
|
+
return childrenOnlyFieldsBuildNode(child, build);
|
|
10029
|
+
}
|
|
10030
|
+
if (build !== void 0 && proj < 0 && flags === 32) {
|
|
10031
|
+
return collapseBuildNode(child, build);
|
|
10032
|
+
}
|
|
10033
|
+
if (build !== void 0 && proj < 0 && flags === 34) {
|
|
10034
|
+
return childrenOnlyCollapseBuildNode(child, build);
|
|
10035
|
+
}
|
|
10036
|
+
if (build === void 0 && proj >= 0 && flags === 0) {
|
|
10037
|
+
return plainProjectNode(child, proj, type);
|
|
10038
|
+
}
|
|
10039
|
+
}
|
|
7996
10040
|
const structural = build === void 0 && proj < 0;
|
|
7997
10041
|
const grammarCapture = (flags & 1) !== 0 || trailingTrivia;
|
|
7998
10042
|
const hostCapturesThisType = structural && cfg.hostCaptureTrivia !== void 0 ? cfg.hostCaptureTrivia(type) : void 0;
|
|
@@ -8112,14 +10156,27 @@ function assemble(t, prog, cfg) {
|
|
|
8112
10156
|
if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
|
|
8113
10157
|
}
|
|
8114
10158
|
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
8115
|
-
const
|
|
8116
|
-
for (const ip of reachableSites(code,
|
|
8117
|
-
if (code[ip]
|
|
8118
|
-
|
|
10159
|
+
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
10160
|
+
for (const ip of reachableSites(code, roots)) {
|
|
10161
|
+
if (code[ip] === OP_DISPATCH) {
|
|
10162
|
+
const spec = dsp[code[ip + 2]];
|
|
10163
|
+
validateDispatchSpec(spec, code[ip + 5], code[ip + 4]);
|
|
10164
|
+
}
|
|
10165
|
+
if (!hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
|
|
10166
|
+
if (code[ip] === OP_NODE) {
|
|
10167
|
+
const child = scalarTerminalNodeChild(code, ip);
|
|
10168
|
+
if (child >= 0) {
|
|
10169
|
+
rawScalarSpecs.add(code[child + 1]);
|
|
10170
|
+
scalarFor(child);
|
|
10171
|
+
}
|
|
10172
|
+
}
|
|
10173
|
+
}
|
|
10174
|
+
const notChild = scalarTerminalNotChild(code, ip);
|
|
10175
|
+
if (notChild >= 0) scalarFor(notChild);
|
|
8119
10176
|
}
|
|
8120
10177
|
const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
|
|
8121
10178
|
if (pre !== void 0) {
|
|
8122
|
-
const pools = rebuildPools(t.cc, t.fx, pre.plan);
|
|
10179
|
+
const pools = rebuildPools(t.cc, t.fx, t.disp, pre.plan);
|
|
8123
10180
|
emitted = pre.factory(
|
|
8124
10181
|
EC,
|
|
8125
10182
|
FAIL,
|
|
@@ -8145,7 +10202,7 @@ function assemble(t, prog, cfg) {
|
|
|
8145
10202
|
rollbackTriviaAt,
|
|
8146
10203
|
rollbackScannedTriviaAt,
|
|
8147
10204
|
failAt,
|
|
8148
|
-
|
|
10205
|
+
classHas2,
|
|
8149
10206
|
consumeTrivia,
|
|
8150
10207
|
buildFieldMap,
|
|
8151
10208
|
projectChild,
|
|
@@ -8166,7 +10223,13 @@ function assemble(t, prog, cfg) {
|
|
|
8166
10223
|
matchesAt,
|
|
8167
10224
|
recoverScan,
|
|
8168
10225
|
orSentinel,
|
|
8169
|
-
captureError
|
|
10226
|
+
captureError,
|
|
10227
|
+
scalarRecognizers,
|
|
10228
|
+
commitTriviaScan,
|
|
10229
|
+
scanTriviaCompact,
|
|
10230
|
+
t.lex,
|
|
10231
|
+
adjacencyHolds,
|
|
10232
|
+
t.lexPrograms
|
|
8170
10233
|
);
|
|
8171
10234
|
emitReached = new Set(pre.reached);
|
|
8172
10235
|
}
|
|
@@ -8216,7 +10279,7 @@ function assemble(t, prog, cfg) {
|
|
|
8216
10279
|
rollbackTriviaAt,
|
|
8217
10280
|
rollbackScannedTriviaAt,
|
|
8218
10281
|
failAt,
|
|
8219
|
-
|
|
10282
|
+
classHas2,
|
|
8220
10283
|
consumeTrivia,
|
|
8221
10284
|
buildFieldMap,
|
|
8222
10285
|
projectChild,
|
|
@@ -8242,7 +10305,13 @@ function assemble(t, prog, cfg) {
|
|
|
8242
10305
|
matchesAt,
|
|
8243
10306
|
recoverScan,
|
|
8244
10307
|
orSentinel,
|
|
8245
|
-
captureError
|
|
10308
|
+
captureError,
|
|
10309
|
+
scalarRecognizers,
|
|
10310
|
+
commitTriviaScan,
|
|
10311
|
+
scanTriviaCompact,
|
|
10312
|
+
t.lex,
|
|
10313
|
+
adjacencyHolds,
|
|
10314
|
+
t.lexPrograms
|
|
8246
10315
|
);
|
|
8247
10316
|
emitReached = em.reached;
|
|
8248
10317
|
} catch (e) {
|
|
@@ -8493,6 +10562,378 @@ function firstSetToString(fs) {
|
|
|
8493
10562
|
return fs.ranges.map((r) => r.lo === r.hi ? ch(r.lo) : `${ch(r.lo)}-${ch(r.hi)}`).join(",");
|
|
8494
10563
|
}
|
|
8495
10564
|
|
|
10565
|
+
// src/compiler/direct-projection.ts
|
|
10566
|
+
function directArrayProjection(fn, fnSrc, arity) {
|
|
10567
|
+
let source = fnSrc;
|
|
10568
|
+
if (source === void 0) {
|
|
10569
|
+
source = Function.prototype.toString.call(fn);
|
|
10570
|
+
if (source.includes("[native code]")) return null;
|
|
10571
|
+
}
|
|
10572
|
+
const match = /^\s*\(\s*\[([^\]]*)\]\s*\)\s*=>\s*([A-Za-z_$][\w$]*)\s*$/.exec(source);
|
|
10573
|
+
if (match === null) return null;
|
|
10574
|
+
const slots = match[1].split(",").map((slot) => slot.trim());
|
|
10575
|
+
if (slots.length > arity) return null;
|
|
10576
|
+
const result = match[2];
|
|
10577
|
+
let selected = -1;
|
|
10578
|
+
for (let i = 0; i < slots.length; i++) {
|
|
10579
|
+
const slot = slots[i];
|
|
10580
|
+
if (slot === "") continue;
|
|
10581
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(slot)) return null;
|
|
10582
|
+
if (slot === result) {
|
|
10583
|
+
if (selected >= 0) return null;
|
|
10584
|
+
selected = i;
|
|
10585
|
+
}
|
|
10586
|
+
}
|
|
10587
|
+
return selected >= 0 ? selected : null;
|
|
10588
|
+
}
|
|
10589
|
+
|
|
10590
|
+
// src/table/encode.ts
|
|
10591
|
+
import {
|
|
10592
|
+
assertLexicalCapabilityClosure,
|
|
10593
|
+
collectLexicalCapabilities,
|
|
10594
|
+
winnerWrapsReference as winnerWrapsReference2
|
|
10595
|
+
} from "../compiler/token-capability.js";
|
|
10596
|
+
|
|
10597
|
+
// src/combinators/keywords.ts
|
|
10598
|
+
function escapeRe(s) {
|
|
10599
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
10600
|
+
}
|
|
10601
|
+
function keywordsRegExp(words, boundary, caseInsensitive) {
|
|
10602
|
+
const alt = words.map(escapeRe).join("|");
|
|
10603
|
+
const boundarySource = boundary ? `(?![${boundary}])` : "";
|
|
10604
|
+
return new RegExp(`(?:${alt})${boundarySource}`, caseInsensitive ? "iy" : "uy");
|
|
10605
|
+
}
|
|
10606
|
+
|
|
10607
|
+
// src/compiler/token-alphabet.ts
|
|
10608
|
+
function optionalSuffixLexBody(ir) {
|
|
10609
|
+
if (ir.kind !== "sequence" || ir.parts.length !== 2) return void 0;
|
|
10610
|
+
const [base, suffix] = ir.parts;
|
|
10611
|
+
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;
|
|
10612
|
+
return {
|
|
10613
|
+
kind: "regex-optional-code-unit",
|
|
10614
|
+
source: base.source,
|
|
10615
|
+
flags: base.flags,
|
|
10616
|
+
suffix: suffix.body.value
|
|
10617
|
+
};
|
|
10618
|
+
}
|
|
10619
|
+
function selectOptionalSuffixLexBody(ir) {
|
|
10620
|
+
const body = optionalSuffixLexBody(ir);
|
|
10621
|
+
const character = { strategy: "character", estimatedOps: 5 };
|
|
10622
|
+
if (body === void 0) return character;
|
|
10623
|
+
const token2 = { strategy: "token", estimatedOps: 2, body };
|
|
10624
|
+
return token2.estimatedOps < character.estimatedOps ? token2 : character;
|
|
10625
|
+
}
|
|
10626
|
+
function directTokenBodyParser(parser, resolve) {
|
|
10627
|
+
const outer = parser._def;
|
|
10628
|
+
if (outer.tag !== "token") return void 0;
|
|
10629
|
+
let body = outer.parser;
|
|
10630
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10631
|
+
while (!seen.has(body)) {
|
|
10632
|
+
seen.add(body);
|
|
10633
|
+
const wrapper = body._def;
|
|
10634
|
+
if (wrapper.tag === "grammar") {
|
|
10635
|
+
if (wrapper.clearTrivia !== true || wrapper.triviaParser !== void 0 || wrapper.captureTrivia === true || wrapper.rootCapture === "opaque" || wrapper.constructionTrackLines !== "inherit" || wrapper.constructionCaptureTriviaKinds !== void 0) return void 0;
|
|
10636
|
+
body = wrapper.parser;
|
|
10637
|
+
continue;
|
|
10638
|
+
}
|
|
10639
|
+
if (wrapper.tag === "lazy") {
|
|
10640
|
+
const target = resolvedLazyTarget(body, resolve);
|
|
10641
|
+
if (target === void 0) return void 0;
|
|
10642
|
+
body = target;
|
|
10643
|
+
continue;
|
|
10644
|
+
}
|
|
10645
|
+
return body;
|
|
10646
|
+
}
|
|
10647
|
+
return void 0;
|
|
10648
|
+
}
|
|
10649
|
+
function directOptionalSuffixTokenBody(parser, resolve) {
|
|
10650
|
+
const inner = directTokenBodyParser(parser, resolve);
|
|
10651
|
+
if (inner === void 0) return void 0;
|
|
10652
|
+
const sequence6 = inner._def;
|
|
10653
|
+
if (sequence6.tag !== "sequence" || sequence6.parsers.length !== 2) return void 0;
|
|
10654
|
+
let baseParser = sequence6.parsers[0];
|
|
10655
|
+
const seenBase = /* @__PURE__ */ new Set();
|
|
10656
|
+
while (baseParser !== void 0 && baseParser._def.tag === "lazy" && !seenBase.has(baseParser)) {
|
|
10657
|
+
seenBase.add(baseParser);
|
|
10658
|
+
baseParser = resolvedLazyTarget(baseParser, resolve);
|
|
10659
|
+
}
|
|
10660
|
+
const base = baseParser?._def;
|
|
10661
|
+
const optional = sequence6.parsers[1]?._def;
|
|
10662
|
+
if (base?.tag !== "regex" || optional?.tag !== "optional") return void 0;
|
|
10663
|
+
const suffix = optional.parser._def;
|
|
10664
|
+
if (suffix.tag !== "literal" || suffix.caseInsensitive || suffix.value.length !== 1) return void 0;
|
|
10665
|
+
const selected = selectOptionalSuffixLexBody({
|
|
10666
|
+
kind: "sequence",
|
|
10667
|
+
parts: [
|
|
10668
|
+
{ kind: "regex", source: base.source, flags: base.flags },
|
|
10669
|
+
{
|
|
10670
|
+
kind: "repeat",
|
|
10671
|
+
body: { kind: "literal", value: suffix.value, caseInsensitive: false },
|
|
10672
|
+
min: 0,
|
|
10673
|
+
max: 1,
|
|
10674
|
+
greedy: true,
|
|
10675
|
+
mode: "possessive"
|
|
10676
|
+
}
|
|
10677
|
+
]
|
|
10678
|
+
});
|
|
10679
|
+
return selected.strategy === "token" ? {
|
|
10680
|
+
...selected.body,
|
|
10681
|
+
baseCanMatchNewline: baseParser._meta.canMatchNewline,
|
|
10682
|
+
suffixCanMatchNewline: optional.parser._meta.canMatchNewline,
|
|
10683
|
+
expected: directTerminalFailureExpected(base)
|
|
10684
|
+
} : void 0;
|
|
10685
|
+
}
|
|
10686
|
+
function directTerminalTokenBody(parser, resolve) {
|
|
10687
|
+
const outer = parser._def;
|
|
10688
|
+
if (outer.tag !== "token") return void 0;
|
|
10689
|
+
const body = directTokenBodyParser(parser, resolve);
|
|
10690
|
+
if (body === void 0) return void 0;
|
|
10691
|
+
const def = body._def;
|
|
10692
|
+
if (def.tag === "regex") return {
|
|
10693
|
+
kind: "regex-terminal",
|
|
10694
|
+
source: def.source,
|
|
10695
|
+
flags: def.flags,
|
|
10696
|
+
canMatchNewline: body._meta.canMatchNewline,
|
|
10697
|
+
expected: directTerminalFailureExpected(def)
|
|
10698
|
+
};
|
|
10699
|
+
if (def.tag !== "keywords") return void 0;
|
|
10700
|
+
const re = keywordsRegExp(def.words, def.boundary, def.caseInsensitive);
|
|
10701
|
+
return {
|
|
10702
|
+
kind: "regex-terminal",
|
|
10703
|
+
source: re.source,
|
|
10704
|
+
flags: re.flags,
|
|
10705
|
+
canMatchNewline: body._meta.canMatchNewline,
|
|
10706
|
+
expected: directTerminalFailureExpected(def)
|
|
10707
|
+
};
|
|
10708
|
+
}
|
|
10709
|
+
function directTerminalParser(parser, resolve) {
|
|
10710
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10711
|
+
while (!seen.has(parser)) {
|
|
10712
|
+
seen.add(parser);
|
|
10713
|
+
const def = parser._def;
|
|
10714
|
+
if (def.tag === "lazy") {
|
|
10715
|
+
const target = resolvedLazyTarget(parser, resolve);
|
|
10716
|
+
if (target === void 0) return void 0;
|
|
10717
|
+
parser = target;
|
|
10718
|
+
continue;
|
|
10719
|
+
}
|
|
10720
|
+
if (def.tag === "token") {
|
|
10721
|
+
parser = def.parser;
|
|
10722
|
+
continue;
|
|
10723
|
+
}
|
|
10724
|
+
if (def.tag === "grammar") return void 0;
|
|
10725
|
+
return parser;
|
|
10726
|
+
}
|
|
10727
|
+
return void 0;
|
|
10728
|
+
}
|
|
10729
|
+
function directTerminalLexBody(parser, resolve) {
|
|
10730
|
+
const terminal = directTerminalParser(parser, resolve);
|
|
10731
|
+
if (terminal === void 0) return void 0;
|
|
10732
|
+
const def = terminal._def;
|
|
10733
|
+
if (def.tag === "literal") {
|
|
10734
|
+
if (def.caseInsensitive) return void 0;
|
|
10735
|
+
const source = def.value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
10736
|
+
return {
|
|
10737
|
+
kind: "regex-terminal",
|
|
10738
|
+
source,
|
|
10739
|
+
flags: "",
|
|
10740
|
+
canMatchNewline: terminal._meta.canMatchNewline,
|
|
10741
|
+
expected: directTerminalFailureExpected(def)
|
|
10742
|
+
};
|
|
10743
|
+
}
|
|
10744
|
+
if (def.tag === "regex") return {
|
|
10745
|
+
kind: "regex-terminal",
|
|
10746
|
+
source: def.source,
|
|
10747
|
+
flags: def.flags,
|
|
10748
|
+
canMatchNewline: terminal._meta.canMatchNewline,
|
|
10749
|
+
expected: directTerminalFailureExpected(def)
|
|
10750
|
+
};
|
|
10751
|
+
if (def.tag !== "keywords") return void 0;
|
|
10752
|
+
const re = keywordsRegExp(def.words, def.boundary, def.caseInsensitive);
|
|
10753
|
+
return {
|
|
10754
|
+
kind: "regex-terminal",
|
|
10755
|
+
source: re.source,
|
|
10756
|
+
flags: re.flags,
|
|
10757
|
+
canMatchNewline: terminal._meta.canMatchNewline,
|
|
10758
|
+
expected: directTerminalFailureExpected(def)
|
|
10759
|
+
};
|
|
10760
|
+
}
|
|
10761
|
+
function directOrdered4TokenBody(parser, resolve) {
|
|
10762
|
+
const body = directTokenBodyParser(parser, resolve);
|
|
10763
|
+
return body === void 0 ? void 0 : directOrdered4Body(body, resolve);
|
|
10764
|
+
}
|
|
10765
|
+
function directOrdered4Body(body, resolve) {
|
|
10766
|
+
if (body === void 0) return void 0;
|
|
10767
|
+
const choice2 = body._def;
|
|
10768
|
+
if (choice2.tag !== "choice" || choice2.parsers.length !== 4 || choice2.strategy.tag !== "firstMatch" || choice2.gates.some((gate) => gate !== null) || choice2.autoNot.some((check) => check !== null)) return void 0;
|
|
10769
|
+
const arms = [];
|
|
10770
|
+
let common;
|
|
10771
|
+
for (const arm of choice2.parsers) {
|
|
10772
|
+
const selected = directTerminalLexBody(arm, resolve);
|
|
10773
|
+
if (selected === void 0) return void 0;
|
|
10774
|
+
if (selected.canMatchNewline) return void 0;
|
|
10775
|
+
const terminal = directTerminalParser(arm, resolve);
|
|
10776
|
+
const first = firstSetOf(terminal, /* @__PURE__ */ new Set(), resolve);
|
|
10777
|
+
if (first.kind !== "ranges" || first.ranges.length === 0) return void 0;
|
|
10778
|
+
if (common === void 0) common = first;
|
|
10779
|
+
else if (JSON.stringify(common) !== JSON.stringify(first)) return void 0;
|
|
10780
|
+
arms.push(selected);
|
|
10781
|
+
}
|
|
10782
|
+
return {
|
|
10783
|
+
kind: "ordered4-terminals",
|
|
10784
|
+
commonFirstSet: common,
|
|
10785
|
+
commonMissExpected: deriveExpected(body),
|
|
10786
|
+
expected: arms.flatMap((arm) => arm.expected),
|
|
10787
|
+
arms
|
|
10788
|
+
};
|
|
10789
|
+
}
|
|
10790
|
+
function directNot2TokenBody(parser, resolve) {
|
|
10791
|
+
const body = directTokenBodyParser(parser, resolve);
|
|
10792
|
+
const sequence6 = body?._def;
|
|
10793
|
+
if (sequence6?.tag !== "sequence" || sequence6.parsers.length !== 3) return void 0;
|
|
10794
|
+
const [guard0Parser, guard1Parser, terminalParser] = sequence6.parsers;
|
|
10795
|
+
const guard0Def = guard0Parser?._def;
|
|
10796
|
+
const guard1Def = guard1Parser?._def;
|
|
10797
|
+
if (guard0Def?.tag !== "not" || guard1Def?.tag !== "not") return void 0;
|
|
10798
|
+
const ordered = directTokenBodyParser(guard0Def.parser, resolve) ?? directTerminalParser(guard0Def.parser, resolve);
|
|
10799
|
+
const guard0Body = ordered === void 0 ? void 0 : directOrdered4Body(ordered, resolve);
|
|
10800
|
+
const guard1 = directTerminalLexBody(guard1Def.parser, resolve);
|
|
10801
|
+
const terminal = terminalParser === void 0 ? void 0 : directTerminalLexBody(terminalParser, resolve);
|
|
10802
|
+
if (guard0Body === void 0 || guard1 === void 0 || terminal === void 0 || guard1.canMatchNewline || terminal.canMatchNewline) return void 0;
|
|
10803
|
+
return {
|
|
10804
|
+
kind: "not2-ordered4-terminal",
|
|
10805
|
+
guard0Expected: assertionFailureExpected(false, guard0Def.parser._tag),
|
|
10806
|
+
guard1Expected: assertionFailureExpected(false, guard1Def.parser._tag),
|
|
10807
|
+
terminalExpected: terminal.expected,
|
|
10808
|
+
guard0: guard0Body.arms,
|
|
10809
|
+
guard1,
|
|
10810
|
+
terminal
|
|
10811
|
+
};
|
|
10812
|
+
}
|
|
10813
|
+
function directFixedLexNode(parser, resolve, active, pureOnly = false) {
|
|
10814
|
+
let current = parser;
|
|
10815
|
+
const wrappers = /* @__PURE__ */ new Set();
|
|
10816
|
+
while (!wrappers.has(current)) {
|
|
10817
|
+
wrappers.add(current);
|
|
10818
|
+
const def = current._def;
|
|
10819
|
+
if (def.tag === "lazy") {
|
|
10820
|
+
const target = resolvedLazyTarget(current, resolve);
|
|
10821
|
+
if (target === void 0) return void 0;
|
|
10822
|
+
current = target;
|
|
10823
|
+
continue;
|
|
10824
|
+
}
|
|
10825
|
+
if (def.tag === "token") {
|
|
10826
|
+
current = def.parser;
|
|
10827
|
+
continue;
|
|
10828
|
+
}
|
|
10829
|
+
break;
|
|
10830
|
+
}
|
|
10831
|
+
if (wrappers.has(current) && current !== parser && current._def.tag === "lazy") return void 0;
|
|
10832
|
+
if (active.has(current)) return void 0;
|
|
10833
|
+
active.add(current);
|
|
10834
|
+
try {
|
|
10835
|
+
const terminal = directTerminalLexBody(current, resolve);
|
|
10836
|
+
if (terminal !== void 0) return { kind: "terminal", terminal };
|
|
10837
|
+
const def = current._def;
|
|
10838
|
+
if (def.tag === "grammar") {
|
|
10839
|
+
if (!pureOnly || def.parser._def.tag !== "token" && (def.clearTrivia !== true || def.triviaParser !== void 0 || def.captureTrivia === true || def.rootCapture === "opaque")) return void 0;
|
|
10840
|
+
return directFixedLexNode(def.parser, resolve, active, true);
|
|
10841
|
+
}
|
|
10842
|
+
if (def.tag === "sequence") {
|
|
10843
|
+
if (def.parsers.length < 2 || def.parsers.length > 5) return void 0;
|
|
10844
|
+
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve, active, pureOnly));
|
|
10845
|
+
if (parts.some((part) => part === void 0)) return void 0;
|
|
10846
|
+
return { kind: "sequence", parts };
|
|
10847
|
+
}
|
|
10848
|
+
if (def.tag === "choice") {
|
|
10849
|
+
if (def.parsers.length !== 2 && def.parsers.length !== 4 && def.parsers.length !== 8 || def.strategy.tag !== "firstMatch" || def.gates.some((gate) => gate !== null) || def.autoNot.some((check) => check !== null)) return void 0;
|
|
10850
|
+
const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve, active, pureOnly));
|
|
10851
|
+
if (arms.some((arm) => arm === void 0)) return void 0;
|
|
10852
|
+
const final = classifyFinalChoice(def.parsers, resolve);
|
|
10853
|
+
return {
|
|
10854
|
+
kind: "choice",
|
|
10855
|
+
arms,
|
|
10856
|
+
firstSets: final.firstSets,
|
|
10857
|
+
armExpected: def.parsers.map(deriveExpected),
|
|
10858
|
+
expected: def.parsers.flatMap(deriveExpected)
|
|
10859
|
+
};
|
|
10860
|
+
}
|
|
10861
|
+
if (def.tag === "not") {
|
|
10862
|
+
const body = directFixedLexNode(def.parser, resolve, active, true);
|
|
10863
|
+
return body === void 0 ? void 0 : {
|
|
10864
|
+
kind: "not",
|
|
10865
|
+
body,
|
|
10866
|
+
expected: assertionFailureExpected(false, def.parser._tag)
|
|
10867
|
+
};
|
|
10868
|
+
}
|
|
10869
|
+
if (def.tag === "optional") {
|
|
10870
|
+
const body = directFixedLexNode(def.parser, resolve, active, pureOnly);
|
|
10871
|
+
return body === void 0 ? void 0 : { kind: "optional", body };
|
|
10872
|
+
}
|
|
10873
|
+
return void 0;
|
|
10874
|
+
} finally {
|
|
10875
|
+
active.delete(current);
|
|
10876
|
+
}
|
|
10877
|
+
}
|
|
10878
|
+
function directFixedTokenBody(parser, resolve) {
|
|
10879
|
+
const body = directTokenBodyParser(parser, resolve);
|
|
10880
|
+
if (body === void 0) return void 0;
|
|
10881
|
+
const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set());
|
|
10882
|
+
return root === void 0 ? void 0 : { kind: "fixed-tree", root };
|
|
10883
|
+
}
|
|
10884
|
+
function directBalancedTokenBody(parser, resolve) {
|
|
10885
|
+
if (directTokenBodyParser(parser, resolve) === void 0) return void 0;
|
|
10886
|
+
const spec = balancedSpecOf(parser);
|
|
10887
|
+
return spec === void 0 ? void 0 : {
|
|
10888
|
+
kind: "balanced-scan",
|
|
10889
|
+
open: spec.open,
|
|
10890
|
+
close: spec.close,
|
|
10891
|
+
raw: spec.raw,
|
|
10892
|
+
strict: spec.strict,
|
|
10893
|
+
ownSkip: spec.ownSkip
|
|
10894
|
+
};
|
|
10895
|
+
}
|
|
10896
|
+
function directExecutableTokenBody(parser, resolve) {
|
|
10897
|
+
return directOptionalSuffixTokenBody(parser, resolve) ?? directTerminalTokenBody(parser, resolve) ?? directOrdered4TokenBody(parser, resolve) ?? directNot2TokenBody(parser, resolve) ?? directBalancedTokenBody(parser, resolve) ?? directFixedTokenBody(parser, resolve);
|
|
10898
|
+
}
|
|
10899
|
+
function winnerWrapsReference(winner, reference) {
|
|
10900
|
+
let current = winner;
|
|
10901
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10902
|
+
while (!seen.has(current)) {
|
|
10903
|
+
if (current === reference) return true;
|
|
10904
|
+
seen.add(current);
|
|
10905
|
+
const def = current._def;
|
|
10906
|
+
if (def.tag !== "grammar" && def.tag !== "trivia") return false;
|
|
10907
|
+
current = def.parser;
|
|
10908
|
+
}
|
|
10909
|
+
return false;
|
|
10910
|
+
}
|
|
10911
|
+
function resolvedLazyTarget(parser, resolve) {
|
|
10912
|
+
const def = parser._def;
|
|
10913
|
+
if (def.tag !== "lazy") return void 0;
|
|
10914
|
+
const name = parser._ruleName;
|
|
10915
|
+
if (name !== void 0 && resolve !== void 0) {
|
|
10916
|
+
const winner = resolve(name);
|
|
10917
|
+
if (winner !== void 0 && !winnerWrapsReference(winner, parser)) return winner;
|
|
10918
|
+
}
|
|
10919
|
+
try {
|
|
10920
|
+
return def.thunk();
|
|
10921
|
+
} catch {
|
|
10922
|
+
return void 0;
|
|
10923
|
+
}
|
|
10924
|
+
}
|
|
10925
|
+
function balancedSpecOf(parser) {
|
|
10926
|
+
let current = parser;
|
|
10927
|
+
let spec = current._balancedSpec;
|
|
10928
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10929
|
+
while (spec === void 0 && current._def.tag === "token" && !seen.has(current)) {
|
|
10930
|
+
seen.add(current);
|
|
10931
|
+
current = current._def.parser;
|
|
10932
|
+
spec = current._balancedSpec;
|
|
10933
|
+
}
|
|
10934
|
+
return spec;
|
|
10935
|
+
}
|
|
10936
|
+
|
|
8496
10937
|
// src/table/encode.ts
|
|
8497
10938
|
function emittableConst(v) {
|
|
8498
10939
|
const scalar = (x) => x === null || typeof x === "string" || typeof x === "number" || typeof x === "boolean";
|
|
@@ -8505,16 +10946,6 @@ function emittableConst(v) {
|
|
|
8505
10946
|
}
|
|
8506
10947
|
return false;
|
|
8507
10948
|
}
|
|
8508
|
-
function wrapsRef(winner, p) {
|
|
8509
|
-
let cur = winner;
|
|
8510
|
-
for (let n = 0; n < 16; n++) {
|
|
8511
|
-
if (cur === p) return true;
|
|
8512
|
-
const d = cur._def;
|
|
8513
|
-
if (d.tag !== "grammar" && d.tag !== "trivia") return false;
|
|
8514
|
-
cur = d.parser;
|
|
8515
|
-
}
|
|
8516
|
-
return false;
|
|
8517
|
-
}
|
|
8518
10949
|
var UnsupportedConstruct = class extends Error {
|
|
8519
10950
|
tag;
|
|
8520
10951
|
constructor(tag) {
|
|
@@ -8546,6 +10977,10 @@ var Encoder = class {
|
|
|
8546
10977
|
fx = [];
|
|
8547
10978
|
disp = [];
|
|
8548
10979
|
dsp = [];
|
|
10980
|
+
lex = [];
|
|
10981
|
+
lexIndex = /* @__PURE__ */ new Map();
|
|
10982
|
+
lexPrograms = [];
|
|
10983
|
+
lexProgramIndex = /* @__PURE__ */ new Map();
|
|
8549
10984
|
labels = void 0;
|
|
8550
10985
|
/** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
|
|
8551
10986
|
activeTrivia = void 0;
|
|
@@ -8616,6 +11051,146 @@ var Encoder = class {
|
|
|
8616
11051
|
this.triviaSpecs.push(this.triviaSpecOf(t));
|
|
8617
11052
|
return idx;
|
|
8618
11053
|
}
|
|
11054
|
+
lexicalBodySlot(p) {
|
|
11055
|
+
if (!this.selectLexicalBodies) return void 0;
|
|
11056
|
+
const body = directExecutableTokenBody(p, (name) => this.winners?.[name]);
|
|
11057
|
+
if (body === void 0) return void 0;
|
|
11058
|
+
const tokenDef = p._def;
|
|
11059
|
+
if (tokenDef.tag !== "token") throw new Error("parseman: selected lexical body lost token boundary");
|
|
11060
|
+
const matcher = (arm) => {
|
|
11061
|
+
const flags2 = arm.flags.includes("y") ? arm.flags : `${arm.flags.replace(/g/g, "")}y`;
|
|
11062
|
+
const regex3 = this.constant(new RegExp(arm.source, flags2));
|
|
11063
|
+
const key2 = `${regex3}:-1`;
|
|
11064
|
+
const prior2 = this.lexIndex.get(key2);
|
|
11065
|
+
if (prior2 !== void 0) return prior2;
|
|
11066
|
+
const id2 = this.lex.length;
|
|
11067
|
+
this.lexIndex.set(key2, id2);
|
|
11068
|
+
this.lex.push([regex3, -1]);
|
|
11069
|
+
return id2;
|
|
11070
|
+
};
|
|
11071
|
+
if (body.kind === "balanced-scan") {
|
|
11072
|
+
const scan = this.scanSlot({
|
|
11073
|
+
kind: 1,
|
|
11074
|
+
flags: (body.raw ? 1 : 0) | (body.strict ? 4 : 0),
|
|
11075
|
+
skip: body.ownSkip.map((combinator) => this.subtree(combinator)),
|
|
11076
|
+
open: body.open,
|
|
11077
|
+
close: body.close
|
|
11078
|
+
});
|
|
11079
|
+
const words = [scan];
|
|
11080
|
+
const spec = [3, lexProgramDigest(words), scan];
|
|
11081
|
+
const key2 = spec.join(",");
|
|
11082
|
+
const prior2 = this.lexProgramIndex.get(key2);
|
|
11083
|
+
if (prior2 !== void 0) return { kind: "program", program: prior2 };
|
|
11084
|
+
const id2 = this.lexPrograms.length;
|
|
11085
|
+
this.lexProgramIndex.set(key2, id2);
|
|
11086
|
+
this.lexPrograms.push(spec);
|
|
11087
|
+
return { kind: "program", program: id2 };
|
|
11088
|
+
}
|
|
11089
|
+
if (body.kind === "fixed-tree") {
|
|
11090
|
+
const words = [];
|
|
11091
|
+
const emitNode = (node) => {
|
|
11092
|
+
switch (node.kind) {
|
|
11093
|
+
case "terminal":
|
|
11094
|
+
words.push(
|
|
11095
|
+
LEX_NODE_TERMINAL,
|
|
11096
|
+
matcher(node.terminal),
|
|
11097
|
+
this.expected(node.terminal.expected),
|
|
11098
|
+
this.track ? 1 : 0
|
|
11099
|
+
);
|
|
11100
|
+
return true;
|
|
11101
|
+
case "sequence": {
|
|
11102
|
+
for (const part of node.parts) if (!emitNode(part)) return false;
|
|
11103
|
+
const op = node.parts.length === 2 ? LEX_NODE_SEQUENCE2 : node.parts.length === 3 ? LEX_NODE_SEQUENCE3 : node.parts.length === 4 ? LEX_NODE_SEQUENCE4 : node.parts.length === 5 ? LEX_NODE_SEQUENCE5 : -1;
|
|
11104
|
+
if (op < 0) return false;
|
|
11105
|
+
words.push(op);
|
|
11106
|
+
return true;
|
|
11107
|
+
}
|
|
11108
|
+
case "choice": {
|
|
11109
|
+
for (const arm of node.arms) if (!emitNode(arm)) return false;
|
|
11110
|
+
const op = node.arms.length === 2 ? LEX_NODE_CHOICE2 : node.arms.length === 4 ? LEX_NODE_CHOICE4 : node.arms.length === 8 ? LEX_NODE_CHOICE8 : -1;
|
|
11111
|
+
if (op < 0) return false;
|
|
11112
|
+
words.push(op, this.expected(node.expected));
|
|
11113
|
+
for (let i = 0; i < node.arms.length; i++) {
|
|
11114
|
+
const first = node.firstSets[i];
|
|
11115
|
+
words.push(first.kind === "ranges" ? this.charClass(first) : -1);
|
|
11116
|
+
words.push(this.expected(node.armExpected[i]));
|
|
11117
|
+
}
|
|
11118
|
+
return true;
|
|
11119
|
+
}
|
|
11120
|
+
case "not":
|
|
11121
|
+
if (!emitNode(node.body)) return false;
|
|
11122
|
+
words.push(LEX_NODE_NOT, this.expected(node.expected));
|
|
11123
|
+
return true;
|
|
11124
|
+
case "optional":
|
|
11125
|
+
if (!emitNode(node.body)) return false;
|
|
11126
|
+
words.push(LEX_NODE_OPTIONAL);
|
|
11127
|
+
return true;
|
|
11128
|
+
}
|
|
11129
|
+
};
|
|
11130
|
+
if (!emitNode(body.root)) return void 0;
|
|
11131
|
+
const spec = [2, lexProgramDigest(words), ...words];
|
|
11132
|
+
const key2 = spec.join(",");
|
|
11133
|
+
const prior2 = this.lexProgramIndex.get(key2);
|
|
11134
|
+
if (prior2 !== void 0) return { kind: "program", program: prior2 };
|
|
11135
|
+
const id2 = this.lexPrograms.length;
|
|
11136
|
+
this.lexProgramIndex.set(key2, id2);
|
|
11137
|
+
this.lexPrograms.push(spec);
|
|
11138
|
+
return { kind: "program", program: id2 };
|
|
11139
|
+
}
|
|
11140
|
+
if (body.kind === "not2-ordered4-terminal") {
|
|
11141
|
+
const words = [
|
|
11142
|
+
...body.guard0.map(matcher),
|
|
11143
|
+
this.expected(body.guard0Expected),
|
|
11144
|
+
matcher(body.guard1),
|
|
11145
|
+
this.expected(body.guard1Expected),
|
|
11146
|
+
matcher(body.terminal),
|
|
11147
|
+
this.expected(body.terminalExpected),
|
|
11148
|
+
this.track ? 1 : 0
|
|
11149
|
+
];
|
|
11150
|
+
const spec = [1, lexProgramDigest(words), ...words];
|
|
11151
|
+
const key2 = spec.join(",");
|
|
11152
|
+
const prior2 = this.lexProgramIndex.get(key2);
|
|
11153
|
+
if (prior2 !== void 0) return { kind: "program", program: prior2 };
|
|
11154
|
+
const id2 = this.lexPrograms.length;
|
|
11155
|
+
this.lexProgramIndex.set(key2, id2);
|
|
11156
|
+
this.lexPrograms.push(spec);
|
|
11157
|
+
return { kind: "program", program: id2 };
|
|
11158
|
+
}
|
|
11159
|
+
if (body.kind === "ordered4-terminals") {
|
|
11160
|
+
const commonClass = this.charClass(body.commonFirstSet);
|
|
11161
|
+
if (commonClass < 0) return void 0;
|
|
11162
|
+
const words = [commonClass, this.expected(body.commonMissExpected)];
|
|
11163
|
+
for (const arm of body.arms) {
|
|
11164
|
+
words.push(matcher(arm), this.expected(arm.expected));
|
|
11165
|
+
}
|
|
11166
|
+
words.push(this.track ? 1 : 0);
|
|
11167
|
+
const spec = [0, lexProgramDigest(words), ...words];
|
|
11168
|
+
const key2 = spec.join(",");
|
|
11169
|
+
const prior2 = this.lexProgramIndex.get(key2);
|
|
11170
|
+
if (prior2 !== void 0) return { kind: "program", program: prior2 };
|
|
11171
|
+
const id2 = this.lexPrograms.length;
|
|
11172
|
+
this.lexProgramIndex.set(key2, id2);
|
|
11173
|
+
this.lexPrograms.push(spec);
|
|
11174
|
+
return { kind: "program", program: id2 };
|
|
11175
|
+
}
|
|
11176
|
+
const expectedFx = this.expected(body.expected);
|
|
11177
|
+
const flags = body.flags.includes("y") ? body.flags : `${body.flags.replace(/g/g, "")}y`;
|
|
11178
|
+
const regex2 = this.constant(new RegExp(body.source, flags));
|
|
11179
|
+
const suffix = body.kind === "regex-terminal" ? -1 : body.suffix.charCodeAt(0);
|
|
11180
|
+
const key = `${regex2}:${suffix}`;
|
|
11181
|
+
const prior = this.lexIndex.get(key);
|
|
11182
|
+
const suffixFx = this.expected(body.kind === "regex-terminal" ? [] : directTerminalFailureExpected({
|
|
11183
|
+
tag: "literal",
|
|
11184
|
+
value: body.suffix,
|
|
11185
|
+
caseInsensitive: false
|
|
11186
|
+
}));
|
|
11187
|
+
const lineFlags = this.track ? body.kind === "regex-terminal" ? 1 : 1 | 2 | 4 : body.kind === "regex-terminal" ? 0 : 4;
|
|
11188
|
+
if (prior !== void 0) return { kind: "body", body: prior, expectedFx, suffixFx, lineFlags };
|
|
11189
|
+
const id = this.lex.length;
|
|
11190
|
+
this.lexIndex.set(key, id);
|
|
11191
|
+
this.lex.push([regex2, suffix]);
|
|
11192
|
+
return { kind: "body", body: id, expectedFx, suffixFx, lineFlags };
|
|
11193
|
+
}
|
|
8619
11194
|
triviaSpecOf(t) {
|
|
8620
11195
|
const unlowered = (why) => {
|
|
8621
11196
|
this.runtimeOnly.add(`rules({ trivia }) \u2014 ${why}`);
|
|
@@ -8699,6 +11274,9 @@ var Encoder = class {
|
|
|
8699
11274
|
settings;
|
|
8700
11275
|
/** Resolved once, HERE, at table-build time — never consulted at run time. */
|
|
8701
11276
|
track;
|
|
11277
|
+
/** TOKEN bodies are an all-program decision. A complete occurrence inside an
|
|
11278
|
+
* otherwise incomplete final graph stays on CHARACTER with every sibling. */
|
|
11279
|
+
selectLexicalBodies;
|
|
8702
11280
|
/**
|
|
8703
11281
|
* Decides the extra operands laid down below. ALWAYS TRUE — see
|
|
8704
11282
|
* `TableSettings.recovery`. Kept as a field rather than folded away because it
|
|
@@ -8706,9 +11284,10 @@ var Encoder = class {
|
|
|
8706
11284
|
* row is stated.
|
|
8707
11285
|
*/
|
|
8708
11286
|
rec;
|
|
8709
|
-
constructor(settings) {
|
|
11287
|
+
constructor(settings, selectLexicalBodies) {
|
|
8710
11288
|
this.settings = settings;
|
|
8711
11289
|
this.track = settings.trackLines === true;
|
|
11290
|
+
this.selectLexicalBodies = selectLexicalBodies;
|
|
8712
11291
|
this.rec = true;
|
|
8713
11292
|
this.plan = settings.coverage;
|
|
8714
11293
|
this.cov = settings.coverage === void 0 ? void 0 : settings.coverage.definitions.map((d) => [d.id, covKindCode(d.kind)]);
|
|
@@ -8823,6 +11402,13 @@ var Encoder = class {
|
|
|
8823
11402
|
this.ccIndex.set(spec, i);
|
|
8824
11403
|
return i;
|
|
8825
11404
|
}
|
|
11405
|
+
/** Bind a guard only when its class is already part of the program. Repeat
|
|
11406
|
+
* gating must not grow the compact artifact merely to avoid a failed call. */
|
|
11407
|
+
existingCharClass(fs) {
|
|
11408
|
+
if (fs.kind !== "ranges" || fs.ranges.length === 0) return -1;
|
|
11409
|
+
const hit = this.ccIndex.get(encodeClassSpec(fs.ranges));
|
|
11410
|
+
return hit !== void 0 && hit < 100 ? hit : -1;
|
|
11411
|
+
}
|
|
8826
11412
|
/**
|
|
8827
11413
|
* Wrap one choice arm in its `autoNot` checks (`OP_REJECT`).
|
|
8828
11414
|
*
|
|
@@ -8911,7 +11497,7 @@ var Encoder = class {
|
|
|
8911
11497
|
* in the target rule's own ambient trivia when that differs from the trivia
|
|
8912
11498
|
* lexically active at the reference.
|
|
8913
11499
|
*
|
|
8914
|
-
* `encodeRule` wraps a rule ENTRY in `
|
|
11500
|
+
* `encodeRule` wraps a rule ENTRY in `OP_SCOPE_PLAIN`, but only the entry: a `g.X`
|
|
8915
11501
|
* reference resolves straight to the body's offset and jumps past it (the note
|
|
8916
11502
|
* at `encodeRule`). So a rule referenced from inside a `noTrivia(...)` region ran
|
|
8917
11503
|
* with NO ambient trivia of its own — the table scoped trivia DYNAMICALLY, by
|
|
@@ -8988,6 +11574,19 @@ var Encoder = class {
|
|
|
8988
11574
|
}
|
|
8989
11575
|
encodeDef(p) {
|
|
8990
11576
|
const d = p._def;
|
|
11577
|
+
if (d.tag === "token") {
|
|
11578
|
+
const selected = this.lexicalBodySlot(p);
|
|
11579
|
+
if (selected !== void 0) {
|
|
11580
|
+
if (selected.kind === "program") return this.emit(OP_LEX_PROGRAM, selected.program);
|
|
11581
|
+
return this.emit(
|
|
11582
|
+
OP_LEX_BODY,
|
|
11583
|
+
selected.body,
|
|
11584
|
+
selected.expectedFx,
|
|
11585
|
+
selected.suffixFx,
|
|
11586
|
+
selected.lineFlags
|
|
11587
|
+
);
|
|
11588
|
+
}
|
|
11589
|
+
}
|
|
8991
11590
|
const bal = p._balancedSpec;
|
|
8992
11591
|
if (bal !== void 0) return this.emit(OP_SCAN, this.scanSlot({
|
|
8993
11592
|
kind: 1,
|
|
@@ -9009,13 +11608,13 @@ var Encoder = class {
|
|
|
9009
11608
|
switch (d.tag) {
|
|
9010
11609
|
case "literal": {
|
|
9011
11610
|
if (d.caseInsensitive) {
|
|
9012
|
-
return this.emit(this.track ? OP_LIT_CI_TRACK : OP_LIT_CI, this.constant(d.value), this.expected(
|
|
11611
|
+
return this.emit(this.track ? OP_LIT_CI_TRACK : OP_LIT_CI, this.constant(d.value), this.expected(directTerminalFailureExpected(d)));
|
|
9013
11612
|
}
|
|
9014
|
-
return this.emit(this.track ? OP_LIT_TRACK : OP_LIT, this.constant(d.value), this.expected(
|
|
11613
|
+
return this.emit(this.track ? OP_LIT_TRACK : OP_LIT, this.constant(d.value), this.expected(directTerminalFailureExpected(d)));
|
|
9015
11614
|
}
|
|
9016
11615
|
case "regex": {
|
|
9017
11616
|
const flags = d.flags.includes("y") ? d.flags : `${d.flags}y`;
|
|
9018
|
-
return this.emit(this.track ? OP_RX_TRACK : OP_RX, this.constant(new RegExp(d.source, flags)), this.expected(
|
|
11617
|
+
return this.emit(this.track ? OP_RX_TRACK : OP_RX, this.constant(new RegExp(d.source, flags)), this.expected(directTerminalFailureExpected(d)));
|
|
9019
11618
|
}
|
|
9020
11619
|
case "keywords": {
|
|
9021
11620
|
const alt = d.words.map((w) => w.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
|
|
@@ -9029,7 +11628,7 @@ var Encoder = class {
|
|
|
9029
11628
|
// failing keyword arm names the CATEGORY rather than reciting every
|
|
9030
11629
|
// literal in the family. `deriveExpected` reports the literals, so the
|
|
9031
11630
|
// table said `'"media"'` where both other engines say `'keyword'`.
|
|
9032
|
-
this.expected(
|
|
11631
|
+
this.expected(directTerminalFailureExpected(d))
|
|
9033
11632
|
);
|
|
9034
11633
|
}
|
|
9035
11634
|
case "expect": {
|
|
@@ -9076,7 +11675,8 @@ var Encoder = class {
|
|
|
9076
11675
|
return this.covWrap(gated, armCovIds?.[src], 1);
|
|
9077
11676
|
});
|
|
9078
11677
|
const rr = this.refResolver();
|
|
9079
|
-
const
|
|
11678
|
+
const finalChoice = classifyFinalChoice(arms, rr);
|
|
11679
|
+
const classes = arms.map((_, i) => finalChoice.nullable[i] ? -1 : this.charClass(finalChoice.firstSets[i]));
|
|
9080
11680
|
const dispIdx = this.disp.length;
|
|
9081
11681
|
this.disp.push(classes);
|
|
9082
11682
|
const head = this.emitHead(OP_CHOICE, 3 + 2 * kids.length);
|
|
@@ -9092,9 +11692,11 @@ var Encoder = class {
|
|
|
9092
11692
|
case "many":
|
|
9093
11693
|
case "oneOrMore": {
|
|
9094
11694
|
const child = this.node(d.parser).ip;
|
|
11695
|
+
const rr = this.refResolver();
|
|
11696
|
+
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.existingCharClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr));
|
|
9095
11697
|
const op = d.valueUnused ? OP_REPV : OP_REP;
|
|
9096
11698
|
const min = d.tag === "many" ? 0 : d.min;
|
|
9097
|
-
return this.rec ? this.emit(op, child, min, d.max ?? -1, -1, 0, this.expected(deriveExpected(d.parser)),
|
|
11699
|
+
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);
|
|
9098
11700
|
}
|
|
9099
11701
|
case "sepBy": {
|
|
9100
11702
|
const child = this.node(d.parser).ip;
|
|
@@ -9121,7 +11723,8 @@ var Encoder = class {
|
|
|
9121
11723
|
if (inner.tag === "sequence" && !this.memo.has(d.parser) && !this.pending.has(d.parser)) {
|
|
9122
11724
|
const kids = inner.parsers.map((c) => this.node(c).ip);
|
|
9123
11725
|
const head = this.emitHead(OP_SEQX, 2 + kids.length + (this.rec ? kids.length : 0));
|
|
9124
|
-
|
|
11726
|
+
const projection = directArrayProjection(d.fn, d.fnSrc, kids.length);
|
|
11727
|
+
this.code[head + 1] = projection === null ? this.fn(d.fn, d.fnSrc ?? null) : ~projection;
|
|
9125
11728
|
this.code[head + 2] = kids.length;
|
|
9126
11729
|
for (let i = 0; i < kids.length; i++) this.code[head + 3 + i] = kids[i];
|
|
9127
11730
|
if (this.rec) {
|
|
@@ -9142,10 +11745,11 @@ var Encoder = class {
|
|
|
9142
11745
|
const cstOut = this.settings.hostMode === "cst";
|
|
9143
11746
|
const noBuildCaptures = d.project === void 0;
|
|
9144
11747
|
const derivedTrivia = d.build !== void 0 ? buildReadsTrivia(d) : noBuildCaptures;
|
|
11748
|
+
const omitsRaw = d.build !== void 0 && !buildReadsRaw(d);
|
|
9145
11749
|
const derivedState = d.build !== void 0 ? buildReadsState(d) : noBuildCaptures;
|
|
9146
11750
|
const derivedFields = d.build !== void 0 ? buildReadsFields(d) : noBuildCaptures;
|
|
9147
11751
|
const wantsFields = parserHasOwnFields(d.parser) && (cstOut || derivedFields);
|
|
9148
|
-
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);
|
|
11752
|
+
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);
|
|
9149
11753
|
const body = this.emit(
|
|
9150
11754
|
this.track ? OP_NODE_TRACK : OP_NODE,
|
|
9151
11755
|
d.build === void 0 ? -1 : this.fn(d.build, d.buildSrc ?? null),
|
|
@@ -9166,8 +11770,9 @@ var Encoder = class {
|
|
|
9166
11770
|
const e = deriveExpected(d.parser);
|
|
9167
11771
|
return this.emit(OP_GATE, cls, body, this.expected(e.length > 0 ? e : [d.parser._tag]));
|
|
9168
11772
|
}
|
|
9169
|
-
case "token":
|
|
11773
|
+
case "token": {
|
|
9170
11774
|
return this.emit(OP_TOKEN, this.node(d.parser).ip);
|
|
11775
|
+
}
|
|
9171
11776
|
case "routed":
|
|
9172
11777
|
return this.emit(OP_ROUTED, d.fallback === void 0 ? -1 : this.node(d.fallback).ip);
|
|
9173
11778
|
case "dispatch": {
|
|
@@ -9232,7 +11837,7 @@ var Encoder = class {
|
|
|
9232
11837
|
case "lazy": {
|
|
9233
11838
|
const refName = p._ruleName;
|
|
9234
11839
|
const winner = refName === void 0 ? void 0 : this.winners?.[refName];
|
|
9235
|
-
if (winner !== void 0 && !
|
|
11840
|
+
if (winner !== void 0 && !winnerWrapsReference2(winner, p)) return this.scopedRef(p, winner);
|
|
9236
11841
|
let resolved;
|
|
9237
11842
|
try {
|
|
9238
11843
|
resolved = d.thunk();
|
|
@@ -9248,7 +11853,7 @@ var Encoder = class {
|
|
|
9248
11853
|
// other engine reported `['not(literal)']`. It hid because `expected` is a
|
|
9249
11854
|
// TOP-LEVEL field on `RunResult` and is NOT part of the identity digest.
|
|
9250
11855
|
case "not":
|
|
9251
|
-
return this.emit(OP_NOT, this.node(d.parser).ip, this.expected(
|
|
11856
|
+
return this.emit(OP_NOT, this.node(d.parser).ip, this.expected(assertionFailureExpected(false, d.parser._tag)));
|
|
9252
11857
|
case "guard":
|
|
9253
11858
|
return this.emit(OP_GUARD, this.fn(d.predicate, d.predSrc ?? null), this.expected(["gate"]));
|
|
9254
11859
|
case "adjacency":
|
|
@@ -9266,7 +11871,7 @@ var Encoder = class {
|
|
|
9266
11871
|
return this.emit(OP_WITHCTX, this.constant(d.extra), this.node(d.parser).ip);
|
|
9267
11872
|
}
|
|
9268
11873
|
case "peek":
|
|
9269
|
-
return this.emit(OP_PEEK, this.node(d.parser).ip, this.expected(
|
|
11874
|
+
return this.emit(OP_PEEK, this.node(d.parser).ip, this.expected(assertionFailureExpected(true, d.parser._tag)));
|
|
9270
11875
|
// A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
|
|
9271
11876
|
// lowering was correct only for a choice arm.
|
|
9272
11877
|
case "attempt": {
|
|
@@ -9427,6 +12032,8 @@ var Encoder = class {
|
|
|
9427
12032
|
disp: this.disp,
|
|
9428
12033
|
dsp: this.dsp,
|
|
9429
12034
|
rules: this.rules,
|
|
12035
|
+
...this.lex.length === 0 ? {} : { lex: this.lex },
|
|
12036
|
+
...this.lexPrograms.length === 0 ? {} : { lexPrograms: this.lexPrograms },
|
|
9430
12037
|
...this.labels === void 0 ? {} : { labels: this.labels },
|
|
9431
12038
|
...this.classified ? { classified: 1 } : {},
|
|
9432
12039
|
...this.scanSkipSets.length === 0 ? {} : { scanSkip: this.scanSkipSets, scanSkipOf: this.scanSkipOf },
|
|
@@ -9481,7 +12088,11 @@ function encodeTableProgram(ruleMap, settings = {}) {
|
|
|
9481
12088
|
...hostMode === void 0 ? {} : { hostMode },
|
|
9482
12089
|
...track ? { trackLines: true } : {}
|
|
9483
12090
|
};
|
|
9484
|
-
const
|
|
12091
|
+
const lexicalRoots = [...names].sort().map((name) => ruleMap[name]);
|
|
12092
|
+
const resolveLexical = (name) => ruleMap[name];
|
|
12093
|
+
const capabilities = collectLexicalCapabilities(lexicalRoots, resolveLexical);
|
|
12094
|
+
assertLexicalCapabilityClosure(lexicalRoots, capabilities, resolveLexical);
|
|
12095
|
+
const enc = new Encoder(resolvedSettings, capabilities.capabilityComplete);
|
|
9485
12096
|
enc.winners = ruleMap;
|
|
9486
12097
|
for (const name of names) enc.encodeRule(name, ruleMap[name]);
|
|
9487
12098
|
const prog = enc.finish();
|
|
@@ -9538,6 +12149,17 @@ function emitScanSpec(s) {
|
|
|
9538
12149
|
function emitDispatchSpec(d) {
|
|
9539
12150
|
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(",")}]}`;
|
|
9540
12151
|
}
|
|
12152
|
+
function defaultAssemblyCfgs(prog) {
|
|
12153
|
+
const hostCst = prog.hostMode === "cst";
|
|
12154
|
+
const trackLines = prog.lines === 1;
|
|
12155
|
+
return [false, true].map((tolerant) => ({
|
|
12156
|
+
hostCst,
|
|
12157
|
+
trackLines,
|
|
12158
|
+
tolerant,
|
|
12159
|
+
coverage: false,
|
|
12160
|
+
probe: false
|
|
12161
|
+
}));
|
|
12162
|
+
}
|
|
9541
12163
|
function emitAssemblies(prog, cfgs) {
|
|
9542
12164
|
if (cfgs.length === 0) return ["a:[],"];
|
|
9543
12165
|
const t = resolveTable(prog);
|
|
@@ -9590,6 +12212,8 @@ function programFields(prog, fns, opts = {}) {
|
|
|
9590
12212
|
// `run({ rootTrivia })` rejected a grammar that plainly has labels — the
|
|
9591
12213
|
// exact failure the root-trivia work exists to prevent, one hop downstream.
|
|
9592
12214
|
...prog.dsp.length === 0 ? [] : [`p:[${prog.dsp.map(emitDispatchSpec).join(",")}],`],
|
|
12215
|
+
...prog.lex === void 0 ? [] : [`lx:[${prog.lex.map((row) => `[${row.join(",")}]`).join(",")}],`],
|
|
12216
|
+
...prog.lexPrograms === void 0 ? [] : [`lp:[${prog.lexPrograms.map((row) => `[${row.join(",")}]`).join(",")}],`],
|
|
9593
12217
|
...prog.labels === void 0 ? [] : [`lb:[${prog.labels.map(jsString).join(",")}],`],
|
|
9594
12218
|
...prog.classified === 1 ? ["rc:1,"] : [],
|
|
9595
12219
|
// Without this a recovery table's MODULE loads as a strict one: the extra
|
|
@@ -11308,6 +13932,7 @@ function collectGrammarReflection(ruleMap, opts) {
|
|
|
11308
13932
|
}
|
|
11309
13933
|
|
|
11310
13934
|
// src/table/compile-rule-map.ts
|
|
13935
|
+
var DEFAULT_PRECOMPILE_MIN_WORDS = 1024;
|
|
11311
13936
|
function resolveHostMode(ruleMap, explicit) {
|
|
11312
13937
|
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
11313
13938
|
}
|
|
@@ -11382,10 +14007,11 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
11382
14007
|
`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.`
|
|
11383
14008
|
);
|
|
11384
14009
|
}
|
|
11385
|
-
const replacementWithMetadata = (metadataSource) => emitTableExpression(artifact, {
|
|
14010
|
+
const replacementWithMetadata = (metadataSource, options = {}) => emitTableExpression(artifact, {
|
|
11386
14011
|
entry: null,
|
|
11387
14012
|
runtimeRef: opts.runtimeRef ?? "tableRules",
|
|
11388
14013
|
fnSources: sources,
|
|
14014
|
+
...options.precompileDefault === true && hostMode === "ast" && prog.lines !== 1 && prog.code.length >= DEFAULT_PRECOMPILE_MIN_WORDS ? { assemblies: defaultAssemblyCfgs(artifact).slice(0, 1) } : {},
|
|
11389
14015
|
...metadataSource === void 0 ? {} : { metadataSource }
|
|
11390
14016
|
});
|
|
11391
14017
|
const replacement = replacementWithMetadata();
|