parseman 0.43.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/combinators/attempt.d.ts.map +1 -1
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts +7 -0
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/map.d.ts +11 -0
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/token.d.ts +3 -2
- package/dist/combinators/token.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +1 -0
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/scannable-run.d.ts +1 -1
- package/dist/compiler/scannable-run.d.ts.map +1 -1
- package/dist/compiler/trivia-fast-path.d.ts +4 -3
- package/dist/compiler/trivia-fast-path.d.ts.map +1 -1
- package/dist/cst/trivia-entries.d.ts +15 -9
- package/dist/cst/trivia-entries.d.ts.map +1 -1
- package/dist/cst/trivia-kinds.d.ts +15 -11
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/functional/run.d.ts +22 -16
- package/dist/functional/run.d.ts.map +1 -1
- package/dist/index.cjs +1416 -1115
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1416 -1115
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs +161 -102
- package/dist/language-service/index.cjs.map +3 -3
- package/dist/language-service/index.js +161 -102
- package/dist/language-service/index.js.map +3 -3
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +1217 -985
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1217 -985
- package/dist/plugin/index.js.map +4 -4
- package/dist/run/index.cjs +152 -102
- package/dist/run/index.cjs.map +3 -3
- package/dist/run/index.d.ts +1 -1
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +152 -102
- package/dist/run/index.js.map +3 -3
- package/dist/spec/index.cjs +1414 -1286
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +1414 -1286
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +25 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1053,1035 +1053,1099 @@ function keywords(words, opts = {}) {
|
|
|
1053
1053
|
};
|
|
1054
1054
|
}
|
|
1055
1055
|
|
|
1056
|
-
// src/
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
_cstChildren: ctx._cstChildren,
|
|
1063
|
-
_cstRawChildren: ctx._cstRawChildren,
|
|
1064
|
-
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1065
|
-
_triviaLog: ctx._triviaLog,
|
|
1066
|
-
_fields: ctx._fields,
|
|
1067
|
-
_cstBuf: ctx._cstBuf,
|
|
1068
|
-
_tolerant: ctx._tolerant,
|
|
1069
|
-
_sync: ctx._sync
|
|
1070
|
-
};
|
|
1071
|
-
ctx._probe = void 0;
|
|
1072
|
-
ctx._errors = void 0;
|
|
1073
|
-
ctx._cstLeaves = void 0;
|
|
1074
|
-
ctx._cstChildren = void 0;
|
|
1075
|
-
ctx._cstRawChildren = void 0;
|
|
1076
|
-
ctx._cstTriviaLog = void 0;
|
|
1077
|
-
ctx._triviaLog = void 0;
|
|
1078
|
-
ctx._fields = void 0;
|
|
1079
|
-
ctx._cstBuf = void 0;
|
|
1080
|
-
ctx._tolerant = void 0;
|
|
1081
|
-
ctx._sync = void 0;
|
|
1082
|
-
try {
|
|
1083
|
-
return sentinel.parse(input, pos, ctx).ok;
|
|
1084
|
-
} finally {
|
|
1085
|
-
ctx._probe = s._probe;
|
|
1086
|
-
ctx._errors = s._errors;
|
|
1087
|
-
ctx._cstLeaves = s._cstLeaves;
|
|
1088
|
-
ctx._cstChildren = s._cstChildren;
|
|
1089
|
-
ctx._cstRawChildren = s._cstRawChildren;
|
|
1090
|
-
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1091
|
-
ctx._triviaLog = s._triviaLog;
|
|
1092
|
-
ctx._fields = s._fields;
|
|
1093
|
-
ctx._cstBuf = s._cstBuf;
|
|
1094
|
-
ctx._tolerant = s._tolerant;
|
|
1095
|
-
ctx._sync = s._sync;
|
|
1096
|
-
}
|
|
1056
|
+
// src/cst/trivia-kinds.ts
|
|
1057
|
+
var labeledTriviaSpecs = /* @__PURE__ */ new WeakMap();
|
|
1058
|
+
function unwrapTrivia(p) {
|
|
1059
|
+
let cur = p;
|
|
1060
|
+
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1061
|
+
return cur;
|
|
1097
1062
|
}
|
|
1098
|
-
function
|
|
1099
|
-
if (
|
|
1100
|
-
return
|
|
1101
|
-
_tag: "orSentinel",
|
|
1102
|
-
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1103
|
-
_def: { tag: "unknown" },
|
|
1104
|
-
parse(input, pos, ctx) {
|
|
1105
|
-
const ra = a.parse(input, pos, ctx);
|
|
1106
|
-
if (ra.ok) return ra;
|
|
1107
|
-
return b.parse(input, pos, ctx);
|
|
1108
|
-
}
|
|
1109
|
-
};
|
|
1063
|
+
function peelLabel(p) {
|
|
1064
|
+
if (p._def.tag === "label") return { label: p._def.label, parser: p._def.parser };
|
|
1065
|
+
return null;
|
|
1110
1066
|
}
|
|
1111
|
-
function
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1067
|
+
function analyzeLabeledTrivia(trivia2) {
|
|
1068
|
+
const cached = labeledTriviaSpecs.get(trivia2);
|
|
1069
|
+
if (cached !== void 0) return cached;
|
|
1070
|
+
let core = unwrapTrivia(trivia2);
|
|
1071
|
+
let minRepeats = 1;
|
|
1072
|
+
if (core._def.tag === "oneOrMore") {
|
|
1073
|
+
core = core._def.parser;
|
|
1074
|
+
minRepeats = 1;
|
|
1075
|
+
} else if (core._def.tag === "many") {
|
|
1076
|
+
core = core._def.parser;
|
|
1077
|
+
minRepeats = 0;
|
|
1078
|
+
}
|
|
1079
|
+
const arms = [];
|
|
1080
|
+
if (core._def.tag === "choice") {
|
|
1081
|
+
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1082
|
+
const peeled = peelLabel(core._def.parsers[i]);
|
|
1083
|
+
if (!peeled) {
|
|
1084
|
+
labeledTriviaSpecs.set(trivia2, null);
|
|
1085
|
+
return null;
|
|
1124
1086
|
}
|
|
1125
|
-
|
|
1087
|
+
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1088
|
+
}
|
|
1089
|
+
} else {
|
|
1090
|
+
const peeled = peelLabel(core);
|
|
1091
|
+
if (!peeled) {
|
|
1092
|
+
labeledTriviaSpecs.set(trivia2, null);
|
|
1093
|
+
return null;
|
|
1126
1094
|
}
|
|
1095
|
+
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1096
|
+
}
|
|
1097
|
+
const spec = {
|
|
1098
|
+
labels: arms.map((a) => a.label),
|
|
1099
|
+
arms,
|
|
1100
|
+
minRepeats
|
|
1127
1101
|
};
|
|
1102
|
+
labeledTriviaSpecs.set(trivia2, spec);
|
|
1103
|
+
return spec;
|
|
1128
1104
|
}
|
|
1129
|
-
function
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1135
|
-
ctx._errors?.push(error);
|
|
1136
|
-
return { error, end: scanPos };
|
|
1137
|
-
}
|
|
1138
|
-
function matchesAt(sentinel, input, pos, ctx) {
|
|
1139
|
-
return probeAt(sentinel, input, pos, ctx);
|
|
1105
|
+
function matchArmAt(input, pos, arm, state) {
|
|
1106
|
+
if (!startsFirstSet(arm, input, pos)) return null;
|
|
1107
|
+
const r = arm.parse(input, pos, { trackLines: false, state });
|
|
1108
|
+
if (!r.ok || r.span.end <= pos) return null;
|
|
1109
|
+
return { end: r.span.end };
|
|
1140
1110
|
}
|
|
1141
|
-
function
|
|
1142
|
-
|
|
1111
|
+
function scanLabeledTriviaChunks(input, cur, spec, state) {
|
|
1112
|
+
const chunks = [];
|
|
1113
|
+
let pos = cur;
|
|
1114
|
+
while (pos < input.length) {
|
|
1115
|
+
let matched = null;
|
|
1116
|
+
for (const arm of spec.arms) {
|
|
1117
|
+
const m = matchArmAt(input, pos, arm.parser, state);
|
|
1118
|
+
if (m) {
|
|
1119
|
+
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1120
|
+
break;
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
if (!matched) break;
|
|
1124
|
+
chunks.push({ start: pos, end: matched.end, kindIndex: matched.kindIndex });
|
|
1125
|
+
pos = matched.end;
|
|
1126
|
+
}
|
|
1127
|
+
if (chunks.length < spec.minRepeats) {
|
|
1128
|
+
return { end: cur, chunks: [] };
|
|
1129
|
+
}
|
|
1130
|
+
return { end: pos, chunks };
|
|
1143
1131
|
}
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1132
|
+
function scanLabeledTriviaEnd(input, cur, spec, state) {
|
|
1133
|
+
let pos = cur;
|
|
1134
|
+
let count = 0;
|
|
1135
|
+
while (pos < input.length) {
|
|
1136
|
+
let matched = null;
|
|
1137
|
+
for (const arm of spec.arms) {
|
|
1138
|
+
matched = matchArmAt(input, pos, arm.parser, state);
|
|
1139
|
+
if (matched) break;
|
|
1140
|
+
}
|
|
1141
|
+
if (!matched) break;
|
|
1142
|
+
pos = matched.end;
|
|
1143
|
+
count++;
|
|
1144
|
+
}
|
|
1145
|
+
return count < spec.minRepeats ? cur : pos;
|
|
1149
1146
|
}
|
|
1150
|
-
function
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
return [def.label];
|
|
1162
|
-
case "choice":
|
|
1163
|
-
return def.parsers.flatMap(deriveExpected2);
|
|
1164
|
-
case "dispatch":
|
|
1165
|
-
return deriveExpected2(def.selector);
|
|
1166
|
-
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
1167
|
-
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
1168
|
-
// able to fail first — deriving from term 0 alone named a token the parse
|
|
1169
|
-
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
1170
|
-
// nothing (its own expectation is about what must NOT be here), but it is
|
|
1171
|
-
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
1172
|
-
case "sequence": {
|
|
1173
|
-
const out = [];
|
|
1174
|
-
for (const term of def.parsers) {
|
|
1175
|
-
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
1176
|
-
if (!matchesEmpty(term)) break;
|
|
1147
|
+
function visitLabeledTrivia(input, cur, spec, state, visit) {
|
|
1148
|
+
if (spec.minRepeats > 1) return void 0;
|
|
1149
|
+
let pos = cur;
|
|
1150
|
+
let count = 0;
|
|
1151
|
+
while (pos < input.length) {
|
|
1152
|
+
let matched = null;
|
|
1153
|
+
for (const arm of spec.arms) {
|
|
1154
|
+
const match = matchArmAt(input, pos, arm.parser, state);
|
|
1155
|
+
if (match) {
|
|
1156
|
+
matched = { end: match.end, kindIndex: arm.kindIndex };
|
|
1157
|
+
break;
|
|
1177
1158
|
}
|
|
1178
|
-
return out;
|
|
1179
1159
|
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
case "not":
|
|
1203
|
-
case "peek":
|
|
1204
|
-
return deriveExpected2(def.parser);
|
|
1205
|
-
case "routed":
|
|
1206
|
-
return ["routed()"];
|
|
1207
|
-
case "lazy": {
|
|
1208
|
-
const name = c._ruleName;
|
|
1209
|
-
if (seen.has(c)) return name ? [name] : [];
|
|
1210
|
-
seen.add(c);
|
|
1211
|
-
try {
|
|
1212
|
-
return deriveExpected2(def.thunk());
|
|
1213
|
-
} catch {
|
|
1214
|
-
return name ? [name] : [];
|
|
1215
|
-
} finally {
|
|
1216
|
-
seen.delete(c);
|
|
1160
|
+
if (!matched) break;
|
|
1161
|
+
visit(pos, matched.end, matched.kindIndex);
|
|
1162
|
+
pos = matched.end;
|
|
1163
|
+
count++;
|
|
1164
|
+
}
|
|
1165
|
+
return count < spec.minRepeats ? cur : pos;
|
|
1166
|
+
}
|
|
1167
|
+
function recordTriviaChunks(ctx, chunks) {
|
|
1168
|
+
const kinds = ctx.triviaKindLabels;
|
|
1169
|
+
const mask = ctx._triviaCaptureMask;
|
|
1170
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1171
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
1172
|
+
const rootMark = rootLog?.length ?? 0;
|
|
1173
|
+
for (const ch2 of chunks) {
|
|
1174
|
+
pushTriviaLogEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1175
|
+
const rootKindIndex = ctx._rootTriviaCapture === false || rootLog === void 0 || rootKinds === void 0 || kinds === void 0 ? -1 : rootKinds[kinds[ch2.kindIndex] ?? ""] ?? -1;
|
|
1176
|
+
if (rootKindIndex >= 0) {
|
|
1177
|
+
rootLog.push(0, 0, ch2.start, ch2.end, rootKindIndex);
|
|
1178
|
+
}
|
|
1179
|
+
if (ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)) {
|
|
1180
|
+
if (mask === void 0 || kinds === void 0 || (mask & 1 << ch2.kindIndex) !== 0) {
|
|
1181
|
+
pushCstTriviaEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1217
1182
|
}
|
|
1218
1183
|
}
|
|
1219
|
-
default:
|
|
1220
|
-
return [];
|
|
1221
1184
|
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
isTrivia: false
|
|
1229
|
-
};
|
|
1230
|
-
return {
|
|
1231
|
-
_tag: "expect",
|
|
1232
|
-
_meta: meta,
|
|
1233
|
-
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1234
|
-
parse(input, pos, ctx) {
|
|
1235
|
-
const result = combinator.parse(input, pos, ctx);
|
|
1236
|
-
if (result.ok) return result;
|
|
1237
|
-
const span = { start: pos, end: pos };
|
|
1238
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1239
|
-
ctx._errors?.push(error);
|
|
1240
|
-
if (ctx._tolerant) captureError(ctx, error);
|
|
1241
|
-
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1185
|
+
if (rootLog !== void 0 && rootLog.length !== rootMark && chunks.length > 0) {
|
|
1186
|
+
const start = chunks[0].start;
|
|
1187
|
+
const end = chunks[chunks.length - 1].end;
|
|
1188
|
+
for (let offset = rootMark; offset < rootLog.length; offset += 5) {
|
|
1189
|
+
rootLog[offset] = start;
|
|
1190
|
+
rootLog[offset + 1] = end;
|
|
1242
1191
|
}
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
|
-
function isParseError(value) {
|
|
1246
|
-
return typeof value === "object" && value !== null && value._tag === "parseError";
|
|
1192
|
+
}
|
|
1247
1193
|
}
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
const
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
1255
|
-
let combined = { kind: "empty" };
|
|
1256
|
-
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
1257
|
-
const meta = {
|
|
1258
|
-
firstSet: combined,
|
|
1259
|
-
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1260
|
-
isTrivia: false,
|
|
1261
|
-
disjoint
|
|
1262
|
-
};
|
|
1263
|
-
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
1264
|
-
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1265
|
-
let greedyLitMap = null;
|
|
1266
|
-
let sortedParsers = null;
|
|
1267
|
-
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
1268
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1269
|
-
greedyLitMap = /* @__PURE__ */ new Map();
|
|
1270
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1271
|
-
if (i === strategy.superIndex) continue;
|
|
1272
|
-
const litVal = getCoreLiteralValue(parsers[i]);
|
|
1273
|
-
if (litVal !== null) greedyLitMap.set(litVal, i);
|
|
1274
|
-
}
|
|
1275
|
-
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
1276
|
-
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
1194
|
+
function triviaKindMask(labels, keep) {
|
|
1195
|
+
if (!labels) return void 0;
|
|
1196
|
+
let mask = 0;
|
|
1197
|
+
for (const name of keep) {
|
|
1198
|
+
const idx = labels.indexOf(name);
|
|
1199
|
+
if (idx >= 0) mask |= 1 << idx;
|
|
1277
1200
|
}
|
|
1201
|
+
return mask;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
// src/combinators/trivia-skip.ts
|
|
1205
|
+
var NOOP_COMMIT = () => {
|
|
1206
|
+
};
|
|
1207
|
+
var fastTriviaCache = /* @__PURE__ */ new WeakMap();
|
|
1208
|
+
function needsDeferredTriviaCommit(ctx) {
|
|
1209
|
+
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
1210
|
+
}
|
|
1211
|
+
function saveTriviaMark(ctx) {
|
|
1212
|
+
const m = saveCstMark(ctx);
|
|
1278
1213
|
return {
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1214
|
+
raw: m.raw,
|
|
1215
|
+
tlog: m.tlog,
|
|
1216
|
+
leaves: m.leaves,
|
|
1217
|
+
fields: m.fields,
|
|
1218
|
+
errors: m.errors,
|
|
1219
|
+
log: ctx._triviaLog ? ctx._triviaLog.length : 0,
|
|
1220
|
+
rootLog: ctx._rootTriviaLog ? ctx._rootTriviaLog.length : 0
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
function rollbackTrivia(ctx, mark) {
|
|
1224
|
+
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields, errors: mark.errors });
|
|
1225
|
+
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1226
|
+
if (ctx._rootTriviaLog && ctx._rootTriviaLog.length !== mark.rootLog) ctx._rootTriviaLog.length = mark.rootLog;
|
|
1227
|
+
}
|
|
1228
|
+
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1229
|
+
const probeCtx = {
|
|
1230
|
+
trackLines: ctx.trackLines,
|
|
1231
|
+
state: ctx.state,
|
|
1232
|
+
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1233
|
+
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1234
|
+
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1235
|
+
};
|
|
1236
|
+
const result = triviaP.parse(input, cur, probeCtx);
|
|
1237
|
+
ctx._lineScannedTo = probeCtx._lineScannedTo;
|
|
1238
|
+
return result;
|
|
1239
|
+
}
|
|
1240
|
+
function saveLookaheadMark(ctx) {
|
|
1241
|
+
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1242
|
+
}
|
|
1243
|
+
function rollbackLookahead(ctx, mark) {
|
|
1244
|
+
rollbackTrivia(ctx, mark);
|
|
1245
|
+
if (ctx._probe) ctx._probe.best = mark.probeBest;
|
|
1246
|
+
}
|
|
1247
|
+
function scanWithLabels(input, cur, ctx) {
|
|
1248
|
+
const triviaP = ctx.trivia;
|
|
1249
|
+
const spec = analyzeLabeledTrivia(triviaP);
|
|
1250
|
+
if (!spec) return { end: cur, commit: NOOP_COMMIT };
|
|
1251
|
+
const log = ctx._triviaLog;
|
|
1252
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1253
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
1254
|
+
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1255
|
+
const mask = ctx._triviaCaptureMask;
|
|
1256
|
+
let fullRows;
|
|
1257
|
+
let rootRows;
|
|
1258
|
+
let cstRows;
|
|
1259
|
+
const visitedEnd = visitLabeledTrivia(input, cur, spec, ctx.state, (start, matchEnd, kindIndex) => {
|
|
1260
|
+
if (log !== void 0) (fullRows ??= []).push(start, matchEnd, kindIndex);
|
|
1261
|
+
const selectedKind = rootLog === void 0 || rootKinds === void 0 || ctx._rootTriviaCapture === false ? void 0 : rootKinds[spec.labels[kindIndex] ?? ""];
|
|
1262
|
+
if (selectedKind !== void 0) (rootRows ??= []).push(start, matchEnd, selectedKind);
|
|
1263
|
+
if (captureTl && (mask === void 0 || (mask & 1 << kindIndex) !== 0)) {
|
|
1264
|
+
(cstRows ??= []).push(start, matchEnd, kindIndex);
|
|
1265
|
+
}
|
|
1266
|
+
});
|
|
1267
|
+
if (visitedEnd !== void 0) {
|
|
1268
|
+
if (visitedEnd === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1269
|
+
return {
|
|
1270
|
+
end: visitedEnd,
|
|
1271
|
+
commit: () => {
|
|
1272
|
+
if (fullRows !== void 0 && log !== void 0) log.push(...fullRows);
|
|
1273
|
+
if (rootRows !== void 0 && rootLog !== void 0) {
|
|
1274
|
+
for (let i = 0; i < rootRows.length; i += 3) {
|
|
1275
|
+
rootLog.push(cur, visitedEnd, rootRows[i], rootRows[i + 1], rootRows[i + 2]);
|
|
1300
1276
|
}
|
|
1301
1277
|
}
|
|
1302
|
-
if (
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1278
|
+
if (cstRows !== void 0) {
|
|
1279
|
+
for (let i = 0; i < cstRows.length; i += 3) {
|
|
1280
|
+
pushCstTriviaEntry(ctx, cstRows[i], cstRows[i + 1], cstRows[i + 2]);
|
|
1306
1281
|
}
|
|
1307
|
-
const result = parsers[idx].parse(input, pos, ctx);
|
|
1308
|
-
if (result.ok) return result;
|
|
1309
|
-
expected.push(...result.expected);
|
|
1310
|
-
if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
|
|
1311
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1312
|
-
}
|
|
1313
|
-
return {
|
|
1314
|
-
ok: false,
|
|
1315
|
-
expected: parsers.flatMap((p) => {
|
|
1316
|
-
const r = p.parse(input, pos, ctx);
|
|
1317
|
-
return r.ok ? [] : r.expected;
|
|
1318
|
-
}),
|
|
1319
|
-
span: { start: pos, end: pos }
|
|
1320
|
-
};
|
|
1321
|
-
}
|
|
1322
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1323
|
-
const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
|
|
1324
|
-
if (!superResult.ok) return superResult;
|
|
1325
|
-
const end = superResult.span.end;
|
|
1326
|
-
const litIdx = greedyLitMap.get(input.slice(pos, end));
|
|
1327
|
-
if (litIdx !== void 0) {
|
|
1328
|
-
const litVal = getCoreLiteralValue(parsers[litIdx]);
|
|
1329
|
-
const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
|
|
1330
|
-
return { ok: true, value, span: { start: pos, end } };
|
|
1331
|
-
}
|
|
1332
|
-
return superResult;
|
|
1333
|
-
}
|
|
1334
|
-
if (strategy?.tag === "literalsLongestFirst") {
|
|
1335
|
-
for (const p of sortedParsers) {
|
|
1336
|
-
const r = p.parse(input, pos, ctx);
|
|
1337
|
-
if (r.ok) return r;
|
|
1338
|
-
expected.push(...r.expected);
|
|
1339
|
-
}
|
|
1340
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1341
|
-
}
|
|
1342
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1343
|
-
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
1344
|
-
const mark = saveCstMark(ctx);
|
|
1345
|
-
const logLen = ctx._triviaLog?.length;
|
|
1346
|
-
const result = parsers[i].parse(input, pos, ctx);
|
|
1347
|
-
if (!result.ok) {
|
|
1348
|
-
rollbackCstCapture(ctx, mark);
|
|
1349
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1350
|
-
expected.push(...result.expected);
|
|
1351
|
-
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
1352
|
-
continue;
|
|
1353
|
-
}
|
|
1354
|
-
const checks = autoNot[i];
|
|
1355
|
-
if (checks && autoNotFires(input, result.span.end, checks)) {
|
|
1356
|
-
rollbackCstCapture(ctx, mark);
|
|
1357
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1358
|
-
continue;
|
|
1359
1282
|
}
|
|
1360
|
-
return result;
|
|
1361
1283
|
}
|
|
1362
|
-
|
|
1363
|
-
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
const { end, chunks } = scanLabeledTriviaChunks(input, cur, spec, ctx.state);
|
|
1287
|
+
if (end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1288
|
+
return {
|
|
1289
|
+
end,
|
|
1290
|
+
commit: () => recordTriviaChunks(ctx, chunks)
|
|
1364
1291
|
};
|
|
1365
1292
|
}
|
|
1366
|
-
function
|
|
1367
|
-
const
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
const
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
const m = re.exec(litVal);
|
|
1382
|
-
return m !== null && m[0] === litVal;
|
|
1383
|
-
});
|
|
1384
|
-
if (allSubsumed) return { tag: "greedyClassify", superIndex };
|
|
1293
|
+
function skipWithLabels(input, cur, ctx) {
|
|
1294
|
+
const spec = analyzeLabeledTrivia(ctx.trivia);
|
|
1295
|
+
if (spec) return scanLabeledTriviaEnd(input, cur, spec, ctx.state);
|
|
1296
|
+
const tr = parseTriviaNoCapture(ctx.trivia, input, cur, ctx);
|
|
1297
|
+
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1298
|
+
}
|
|
1299
|
+
function advanceTrivia(input, cur, ctx) {
|
|
1300
|
+
const triviaP = ctx.trivia;
|
|
1301
|
+
if (!triviaP) return cur;
|
|
1302
|
+
if (!ctx.trackLines) {
|
|
1303
|
+
const fast2 = fastTriviaScanner(triviaP);
|
|
1304
|
+
if (fast2) return fast2(input, cur);
|
|
1305
|
+
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
1306
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1307
|
+
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1385
1308
|
}
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
);
|
|
1390
|
-
|
|
1309
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1310
|
+
const fast = fastTriviaScanner(triviaP);
|
|
1311
|
+
if (fast) {
|
|
1312
|
+
const end = fast(input, cur);
|
|
1313
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1314
|
+
return end;
|
|
1391
1315
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
function bareLeadingTermKey(term) {
|
|
1397
|
-
const d = term._def;
|
|
1398
|
-
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
1399
|
-
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
1400
|
-
return null;
|
|
1401
|
-
}
|
|
1402
|
-
function detectSharedPrefix(parsers) {
|
|
1403
|
-
if (parsers.length < 2) return null;
|
|
1404
|
-
let key = null;
|
|
1405
|
-
let prefix = null;
|
|
1406
|
-
const members = [];
|
|
1407
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1408
|
-
const term0 = leadingTermOfArm(parsers[i]);
|
|
1409
|
-
if (term0 === null) return null;
|
|
1410
|
-
const k = bareLeadingTermKey(term0);
|
|
1411
|
-
if (k === null) return null;
|
|
1412
|
-
if (key === null) {
|
|
1413
|
-
key = k;
|
|
1414
|
-
prefix = term0;
|
|
1415
|
-
} else if (k !== key) return null;
|
|
1416
|
-
members.push(i);
|
|
1316
|
+
if (ctx.triviaKindLabels) {
|
|
1317
|
+
const end = skipWithLabels(input, cur, ctx);
|
|
1318
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1319
|
+
return end;
|
|
1417
1320
|
}
|
|
1418
|
-
|
|
1419
|
-
return
|
|
1321
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1322
|
+
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1420
1323
|
}
|
|
1421
|
-
function
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1324
|
+
function scanTrivia(input, cur, ctx) {
|
|
1325
|
+
const triviaP = ctx.trivia;
|
|
1326
|
+
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1327
|
+
const log = ctx._triviaLog;
|
|
1328
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1329
|
+
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1330
|
+
if (!ctx.trackLines) {
|
|
1331
|
+
const fast2 = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1332
|
+
if (fast2 && log === void 0 && !captureTl) {
|
|
1333
|
+
return { end: fast2(input, cur), commit: NOOP_COMMIT };
|
|
1427
1334
|
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
1431
|
-
return d.parsers[0];
|
|
1432
|
-
}
|
|
1433
|
-
function computeAutoNot(parsers) {
|
|
1434
|
-
return parsers.map((p, i) => {
|
|
1435
|
-
const litVal = getCoreLiteralValue(p);
|
|
1436
|
-
if (litVal === null) return null;
|
|
1437
|
-
const checks = [];
|
|
1438
|
-
for (let j = i + 1; j < parsers.length; j++) {
|
|
1439
|
-
const other = parsers[j];
|
|
1440
|
-
const otherLit = getCoreLiteralValue(other);
|
|
1441
|
-
if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
|
|
1442
|
-
checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
|
|
1443
|
-
continue;
|
|
1444
|
-
}
|
|
1445
|
-
const regexDef = getCoreRegexDef(other);
|
|
1446
|
-
if (regexDef !== null) {
|
|
1447
|
-
const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
|
|
1448
|
-
if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
|
|
1449
|
-
}
|
|
1335
|
+
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1336
|
+
return scanWithLabels(input, cur, ctx);
|
|
1450
1337
|
}
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1338
|
+
if (ctx.triviaKindLabels) return { end: skipWithLabels(input, cur, ctx), commit: NOOP_COMMIT };
|
|
1339
|
+
if (log !== void 0 || rootLog !== void 0 || captureTl) {
|
|
1340
|
+
const tr3 = triviaP.parse(input, cur, {
|
|
1341
|
+
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1342
|
+
state: ctx.state
|
|
1343
|
+
});
|
|
1344
|
+
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1345
|
+
const end = tr3.span.end;
|
|
1346
|
+
return {
|
|
1347
|
+
end,
|
|
1348
|
+
commit: () => {
|
|
1349
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1350
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1351
|
+
}
|
|
1352
|
+
};
|
|
1461
1353
|
}
|
|
1354
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1355
|
+
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1462
1356
|
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
return null;
|
|
1470
|
-
}
|
|
1471
|
-
function getCoreRegexDef(p) {
|
|
1472
|
-
const def = p._def;
|
|
1473
|
-
if (def.tag === "regex") return { source: def.source, flags: def.flags };
|
|
1474
|
-
if (def.tag === "transform") return getCoreRegexDef(def.parser);
|
|
1475
|
-
if (def.tag === "label") return getCoreRegexDef(def.parser);
|
|
1476
|
-
return null;
|
|
1477
|
-
}
|
|
1478
|
-
function applyTransforms(p, value, span) {
|
|
1479
|
-
const def = p._def;
|
|
1480
|
-
if (def.tag === "transform") {
|
|
1481
|
-
const inner = applyTransforms(def.parser, value, span);
|
|
1482
|
-
return def.fn(inner, span);
|
|
1357
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1358
|
+
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1359
|
+
if (fast && log === void 0 && !captureTl) {
|
|
1360
|
+
const end = fast(input, cur);
|
|
1361
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1362
|
+
return { end, commit: NOOP_COMMIT };
|
|
1483
1363
|
}
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
re.lastIndex = 0;
|
|
1489
|
-
const base = re.exec(lit);
|
|
1490
|
-
if (!base || base[0] !== lit) return null;
|
|
1491
|
-
const contCodes = [];
|
|
1492
|
-
for (let code = 1; code < 128; code++) {
|
|
1493
|
-
re.lastIndex = 0;
|
|
1494
|
-
const m = re.exec(lit + String.fromCharCode(code));
|
|
1495
|
-
if (m && m[0].length > lit.length) contCodes.push(code);
|
|
1364
|
+
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1365
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1366
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1367
|
+
return scan;
|
|
1496
1368
|
}
|
|
1497
|
-
if (
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
codes.sort((a, b) => a - b);
|
|
1502
|
-
const ranges = [];
|
|
1503
|
-
let lo = codes[0], hi = codes[0];
|
|
1504
|
-
for (let i = 1; i < codes.length; i++) {
|
|
1505
|
-
if (codes[i] === hi + 1) {
|
|
1506
|
-
hi = codes[i];
|
|
1507
|
-
} else {
|
|
1508
|
-
ranges.push({ lo, hi });
|
|
1509
|
-
lo = hi = codes[i];
|
|
1510
|
-
}
|
|
1369
|
+
if (ctx.triviaKindLabels) {
|
|
1370
|
+
const end = skipWithLabels(input, cur, ctx);
|
|
1371
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1372
|
+
return { end, commit: NOOP_COMMIT };
|
|
1511
1373
|
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1374
|
+
if (log !== void 0 || rootLog !== void 0 || captureTl) {
|
|
1375
|
+
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1376
|
+
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1377
|
+
const end = tr2.span.end;
|
|
1378
|
+
return {
|
|
1379
|
+
end,
|
|
1380
|
+
commit: () => {
|
|
1381
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1382
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1383
|
+
}
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1387
|
+
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1514
1388
|
}
|
|
1515
|
-
function
|
|
1516
|
-
if (
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
return
|
|
1389
|
+
function consumeTrivia(input, cur, ctx) {
|
|
1390
|
+
if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
|
|
1391
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1392
|
+
scan.commit();
|
|
1393
|
+
return scan.end;
|
|
1520
1394
|
}
|
|
1521
|
-
function
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
return
|
|
1395
|
+
function fastTriviaScanner(trivia2) {
|
|
1396
|
+
const cached = fastTriviaCache.get(trivia2);
|
|
1397
|
+
if (cached !== void 0) return cached;
|
|
1398
|
+
const scanner = buildFastTriviaScanner(trivia2);
|
|
1399
|
+
fastTriviaCache.set(trivia2, scanner);
|
|
1400
|
+
return scanner;
|
|
1527
1401
|
}
|
|
1528
|
-
function
|
|
1529
|
-
const
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1402
|
+
function buildFastTriviaScanner(trivia2) {
|
|
1403
|
+
const core = trivia2._def.tag === "trivia" ? trivia2._def.parser : trivia2;
|
|
1404
|
+
const direct = regexTriviaScanner(core);
|
|
1405
|
+
if (direct) return direct;
|
|
1406
|
+
const repeat = core._def.tag === "oneOrMore" || core._def.tag === "many" && core._def.min >= 1 ? core._def.parser : null;
|
|
1407
|
+
if (!repeat) return null;
|
|
1408
|
+
const one = regexTriviaScanner(repeat);
|
|
1409
|
+
if (one) return loopScanner([one]);
|
|
1410
|
+
if (repeat._def.tag !== "choice") return null;
|
|
1411
|
+
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1412
|
+
if (arms.some((s) => s === null)) return null;
|
|
1413
|
+
return loopScanner(arms);
|
|
1414
|
+
}
|
|
1415
|
+
function loopScanner(arms) {
|
|
1416
|
+
return (input, cur) => {
|
|
1417
|
+
let pos = cur;
|
|
1418
|
+
scan: while (pos < input.length) {
|
|
1419
|
+
for (const arm of arms) {
|
|
1420
|
+
const end = arm(input, pos);
|
|
1421
|
+
if (end > pos) {
|
|
1422
|
+
pos = end;
|
|
1423
|
+
continue scan;
|
|
1424
|
+
}
|
|
1536
1425
|
}
|
|
1426
|
+
break;
|
|
1537
1427
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
}
|
|
1541
|
-
|
|
1542
|
-
// src/cst/trivia-kinds.ts
|
|
1543
|
-
function unwrapTrivia(p) {
|
|
1544
|
-
let cur = p;
|
|
1545
|
-
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1546
|
-
return cur;
|
|
1428
|
+
return pos;
|
|
1429
|
+
};
|
|
1547
1430
|
}
|
|
1548
|
-
function
|
|
1549
|
-
if (
|
|
1550
|
-
|
|
1431
|
+
function regexTriviaScanner(parser2) {
|
|
1432
|
+
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1433
|
+
const source = parser2._def.source;
|
|
1434
|
+
return classRunSource(source) ?? altStarSource(source);
|
|
1551
1435
|
}
|
|
1552
|
-
function
|
|
1553
|
-
let
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
core = core._def.parser;
|
|
1557
|
-
minRepeats = 1;
|
|
1558
|
-
} else if (core._def.tag === "many") {
|
|
1559
|
-
core = core._def.parser;
|
|
1560
|
-
minRepeats = 0;
|
|
1561
|
-
}
|
|
1562
|
-
const arms = [];
|
|
1563
|
-
if (core._def.tag === "choice") {
|
|
1564
|
-
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1565
|
-
const peeled = peelLabel(core._def.parsers[i]);
|
|
1566
|
-
if (!peeled) return null;
|
|
1567
|
-
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1568
|
-
}
|
|
1569
|
-
} else {
|
|
1570
|
-
const peeled = peelLabel(core);
|
|
1571
|
-
if (!peeled) return null;
|
|
1572
|
-
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1436
|
+
function inRanges2(cp, ranges) {
|
|
1437
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
1438
|
+
const r = ranges[i];
|
|
1439
|
+
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1573
1440
|
}
|
|
1574
|
-
return
|
|
1441
|
+
return false;
|
|
1575
1442
|
}
|
|
1576
|
-
function
|
|
1577
|
-
const
|
|
1578
|
-
if (!
|
|
1579
|
-
return
|
|
1443
|
+
function classScanner(classBody) {
|
|
1444
|
+
const ranges = parseClassRanges(classBody);
|
|
1445
|
+
if (!ranges) return null;
|
|
1446
|
+
return (input, cur) => {
|
|
1447
|
+
let pos = cur;
|
|
1448
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1449
|
+
return pos;
|
|
1450
|
+
};
|
|
1580
1451
|
}
|
|
1581
|
-
function
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1590
|
-
break;
|
|
1591
|
-
}
|
|
1452
|
+
function untilLineBreakScanner(leaderCode) {
|
|
1453
|
+
return (input, cur) => {
|
|
1454
|
+
if (input.charCodeAt(cur) !== leaderCode) return cur;
|
|
1455
|
+
let pos = cur + 1;
|
|
1456
|
+
while (pos < input.length) {
|
|
1457
|
+
const cc = input.charCodeAt(pos);
|
|
1458
|
+
if (cc === 10 || cc === 13) break;
|
|
1459
|
+
pos++;
|
|
1592
1460
|
}
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1461
|
+
return pos;
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
function classRunSource(source) {
|
|
1465
|
+
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1466
|
+
return m ? classScanner(m[1]) : null;
|
|
1467
|
+
}
|
|
1468
|
+
function classifyTriviaArm(arm) {
|
|
1469
|
+
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1470
|
+
if (cls) {
|
|
1471
|
+
const ranges = parseClassRanges(cls[1]);
|
|
1472
|
+
return ranges ? { kind: "class", ranges } : null;
|
|
1596
1473
|
}
|
|
1597
|
-
|
|
1598
|
-
|
|
1474
|
+
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1475
|
+
if (lc) {
|
|
1476
|
+
const marker = lc[1];
|
|
1477
|
+
return { kind: "untilLineBreak", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1599
1478
|
}
|
|
1600
|
-
return
|
|
1479
|
+
return null;
|
|
1601
1480
|
}
|
|
1602
|
-
function
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1481
|
+
function armScanner(arm) {
|
|
1482
|
+
if (arm.kind === "untilLineBreak") return untilLineBreakScanner(arm.code);
|
|
1483
|
+
const ranges = arm.ranges;
|
|
1484
|
+
return (input, cur) => {
|
|
1485
|
+
let pos = cur;
|
|
1486
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1487
|
+
return pos;
|
|
1488
|
+
};
|
|
1489
|
+
}
|
|
1490
|
+
function fusedTriviaScanner(ranges, leaders) {
|
|
1491
|
+
const c0 = leaders[0];
|
|
1492
|
+
const single = leaders.length === 1;
|
|
1493
|
+
return (input, cur) => {
|
|
1494
|
+
let pos = cur;
|
|
1495
|
+
const len = input.length;
|
|
1496
|
+
for (; ; ) {
|
|
1497
|
+
const c = input.charCodeAt(pos);
|
|
1498
|
+
if (pos < len && inRanges2(c, ranges)) {
|
|
1499
|
+
pos++;
|
|
1500
|
+
continue;
|
|
1614
1501
|
}
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
const start = pos;
|
|
1623
|
-
pos = j + 2;
|
|
1624
|
-
chunks.push({ start, end: pos, kindIndex: commentKind });
|
|
1502
|
+
if (single ? c === c0 : leaders.includes(c)) {
|
|
1503
|
+
pos++;
|
|
1504
|
+
while (pos < len) {
|
|
1505
|
+
const cc = input.charCodeAt(pos);
|
|
1506
|
+
if (cc === 10 || cc === 13) break;
|
|
1507
|
+
pos++;
|
|
1508
|
+
}
|
|
1625
1509
|
continue;
|
|
1626
1510
|
}
|
|
1627
1511
|
break;
|
|
1628
1512
|
}
|
|
1629
|
-
|
|
1630
|
-
}
|
|
1631
|
-
return { end: pos, chunks };
|
|
1632
|
-
}
|
|
1633
|
-
function tryFastLabeledScan(input, cur, trivia2) {
|
|
1634
|
-
const spec = analyzeLabeledTrivia(trivia2);
|
|
1635
|
-
if (!spec || spec.arms.length !== 2) return null;
|
|
1636
|
-
const wsArm = spec.arms.find((a) => {
|
|
1637
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1638
|
-
return src != null && !src.includes("\\*");
|
|
1639
|
-
});
|
|
1640
|
-
const commentArm = spec.arms.find((a) => {
|
|
1641
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1642
|
-
return src != null && src.includes("\\*");
|
|
1643
|
-
});
|
|
1644
|
-
if (!wsArm || !commentArm) return null;
|
|
1645
|
-
const { chunks } = scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1646
|
-
if (chunks.length < spec.minRepeats) return { end: cur, chunks: [] };
|
|
1647
|
-
return scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1513
|
+
return pos;
|
|
1514
|
+
};
|
|
1648
1515
|
}
|
|
1649
|
-
function
|
|
1650
|
-
const
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1516
|
+
function splitTopLevelAlts(body) {
|
|
1517
|
+
const arms = [];
|
|
1518
|
+
let inClass = false;
|
|
1519
|
+
let start = 0;
|
|
1520
|
+
for (let i = 0; i < body.length; i++) {
|
|
1521
|
+
const c = body[i];
|
|
1522
|
+
if (c === "\\") {
|
|
1523
|
+
i++;
|
|
1524
|
+
continue;
|
|
1525
|
+
}
|
|
1526
|
+
if (inClass) {
|
|
1527
|
+
if (c === "]") inClass = false;
|
|
1528
|
+
continue;
|
|
1529
|
+
}
|
|
1530
|
+
if (c === "[") inClass = true;
|
|
1531
|
+
else if (c === "(") return null;
|
|
1532
|
+
else if (c === "|") {
|
|
1533
|
+
arms.push(body.slice(start, i));
|
|
1534
|
+
start = i + 1;
|
|
1658
1535
|
}
|
|
1659
1536
|
}
|
|
1537
|
+
arms.push(body.slice(start));
|
|
1538
|
+
return arms;
|
|
1660
1539
|
}
|
|
1661
|
-
function
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1540
|
+
function altStarSource(source) {
|
|
1541
|
+
const m = /^\(\?:(.*)\)[*+]$/.exec(source);
|
|
1542
|
+
if (!m) return null;
|
|
1543
|
+
const armSrcs = splitTopLevelAlts(m[1]);
|
|
1544
|
+
if (!armSrcs || armSrcs.length < 2) return null;
|
|
1545
|
+
const arms = [];
|
|
1546
|
+
for (const src of armSrcs) {
|
|
1547
|
+
const arm = classifyTriviaArm(src);
|
|
1548
|
+
if (!arm) return null;
|
|
1549
|
+
arms.push(arm);
|
|
1667
1550
|
}
|
|
1668
|
-
|
|
1551
|
+
const ranges = [];
|
|
1552
|
+
const leaders = [];
|
|
1553
|
+
for (const arm of arms) {
|
|
1554
|
+
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1555
|
+
else leaders.push(arm.code);
|
|
1556
|
+
}
|
|
1557
|
+
if (leaders.some((code) => inRanges2(code, ranges))) {
|
|
1558
|
+
return loopScanner(arms.map(armScanner));
|
|
1559
|
+
}
|
|
1560
|
+
if (leaders.length === 0) return armScanner({ kind: "class", ranges });
|
|
1561
|
+
return fusedTriviaScanner(ranges, leaders);
|
|
1669
1562
|
}
|
|
1670
1563
|
|
|
1671
|
-
// src/
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1687
|
-
const probeCtx = {
|
|
1688
|
-
trackLines: ctx.trackLines,
|
|
1689
|
-
state: ctx.state,
|
|
1690
|
-
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1691
|
-
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1692
|
-
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1564
|
+
// src/recovery/scan.ts
|
|
1565
|
+
function probeAt(sentinel, input, pos, ctx) {
|
|
1566
|
+
const s = {
|
|
1567
|
+
_probe: ctx._probe,
|
|
1568
|
+
_errors: ctx._errors,
|
|
1569
|
+
_cstLeaves: ctx._cstLeaves,
|
|
1570
|
+
_cstChildren: ctx._cstChildren,
|
|
1571
|
+
_cstRawChildren: ctx._cstRawChildren,
|
|
1572
|
+
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1573
|
+
_triviaLog: ctx._triviaLog,
|
|
1574
|
+
_rootTriviaLog: ctx._rootTriviaLog,
|
|
1575
|
+
_fields: ctx._fields,
|
|
1576
|
+
_cstBuf: ctx._cstBuf,
|
|
1577
|
+
_tolerant: ctx._tolerant,
|
|
1578
|
+
_sync: ctx._sync
|
|
1693
1579
|
};
|
|
1694
|
-
|
|
1695
|
-
ctx.
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1580
|
+
ctx._probe = void 0;
|
|
1581
|
+
ctx._errors = void 0;
|
|
1582
|
+
ctx._cstLeaves = void 0;
|
|
1583
|
+
ctx._cstChildren = void 0;
|
|
1584
|
+
ctx._cstRawChildren = void 0;
|
|
1585
|
+
ctx._cstTriviaLog = void 0;
|
|
1586
|
+
ctx._triviaLog = void 0;
|
|
1587
|
+
ctx._rootTriviaLog = void 0;
|
|
1588
|
+
ctx._fields = void 0;
|
|
1589
|
+
ctx._cstBuf = void 0;
|
|
1590
|
+
ctx._tolerant = void 0;
|
|
1591
|
+
ctx._sync = void 0;
|
|
1592
|
+
try {
|
|
1593
|
+
return sentinel.parse(input, pos, ctx).ok;
|
|
1594
|
+
} finally {
|
|
1595
|
+
ctx._probe = s._probe;
|
|
1596
|
+
ctx._errors = s._errors;
|
|
1597
|
+
ctx._cstLeaves = s._cstLeaves;
|
|
1598
|
+
ctx._cstChildren = s._cstChildren;
|
|
1599
|
+
ctx._cstRawChildren = s._cstRawChildren;
|
|
1600
|
+
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1601
|
+
ctx._triviaLog = s._triviaLog;
|
|
1602
|
+
ctx._rootTriviaLog = s._rootTriviaLog;
|
|
1603
|
+
ctx._fields = s._fields;
|
|
1604
|
+
ctx._cstBuf = s._cstBuf;
|
|
1605
|
+
ctx._tolerant = s._tolerant;
|
|
1606
|
+
ctx._sync = s._sync;
|
|
1607
|
+
}
|
|
1704
1608
|
}
|
|
1705
|
-
function
|
|
1706
|
-
|
|
1707
|
-
const spec = analyzeLabeledTrivia(triviaP);
|
|
1708
|
-
if (!spec) return { end: cur, commit: NOOP_COMMIT };
|
|
1709
|
-
const fast = tryFastLabeledScan(input, cur, triviaP);
|
|
1710
|
-
const { end, chunks } = fast ?? scanLabeledTriviaChunks(input, cur, spec);
|
|
1711
|
-
if (end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1609
|
+
function orSentinel(a, b) {
|
|
1610
|
+
if (b === void 0) return a;
|
|
1712
1611
|
return {
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
if (!ctx.trackLines) {
|
|
1721
|
-
const fast2 = fastTriviaScanner(triviaP);
|
|
1722
|
-
if (fast2) return fast2(input, cur);
|
|
1723
|
-
if (ctx.triviaKindLabels) {
|
|
1724
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1725
|
-
return scan.end;
|
|
1612
|
+
_tag: "orSentinel",
|
|
1613
|
+
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1614
|
+
_def: { tag: "unknown" },
|
|
1615
|
+
parse(input, pos, ctx) {
|
|
1616
|
+
const ra = a.parse(input, pos, ctx);
|
|
1617
|
+
if (ra.ok) return ra;
|
|
1618
|
+
return b.parse(input, pos, ctx);
|
|
1726
1619
|
}
|
|
1727
|
-
|
|
1728
|
-
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1729
|
-
}
|
|
1730
|
-
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1731
|
-
const fast = fastTriviaScanner(triviaP);
|
|
1732
|
-
if (fast) {
|
|
1733
|
-
const end = fast(input, cur);
|
|
1734
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1735
|
-
return end;
|
|
1736
|
-
}
|
|
1737
|
-
if (ctx.triviaKindLabels) {
|
|
1738
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1739
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1740
|
-
return scan.end;
|
|
1741
|
-
}
|
|
1742
|
-
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1743
|
-
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1620
|
+
};
|
|
1744
1621
|
}
|
|
1745
|
-
function
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
}
|
|
1758
|
-
if (log !== void 0 || captureTl) {
|
|
1759
|
-
const tr3 = triviaP.parse(input, cur, {
|
|
1760
|
-
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1761
|
-
state: ctx.state
|
|
1762
|
-
});
|
|
1763
|
-
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1764
|
-
const end = tr3.span.end;
|
|
1765
|
-
return {
|
|
1766
|
-
end,
|
|
1767
|
-
commit: () => {
|
|
1768
|
-
pushTriviaLogEntry(ctx, cur, end);
|
|
1769
|
-
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1622
|
+
function firstSetSentinel(fs) {
|
|
1623
|
+
if (fs.kind !== "ranges" || fs.ranges.length === 0) return null;
|
|
1624
|
+
const ranges = fs.ranges;
|
|
1625
|
+
return {
|
|
1626
|
+
_tag: "firstSetSentinel",
|
|
1627
|
+
_meta: { firstSet: fs, canMatchNewline: false, isTrivia: false },
|
|
1628
|
+
_def: { tag: "unknown" },
|
|
1629
|
+
parse(input, pos) {
|
|
1630
|
+
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
1631
|
+
if (code !== void 0) {
|
|
1632
|
+
for (const r of ranges) {
|
|
1633
|
+
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1770
1634
|
}
|
|
1771
|
-
}
|
|
1635
|
+
}
|
|
1636
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
1772
1637
|
}
|
|
1773
|
-
|
|
1774
|
-
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1775
|
-
}
|
|
1776
|
-
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1777
|
-
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1778
|
-
if (fast && log === void 0 && !captureTl) {
|
|
1779
|
-
const end = fast(input, cur);
|
|
1780
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1781
|
-
return { end, commit: NOOP_COMMIT };
|
|
1782
|
-
}
|
|
1783
|
-
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1784
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1785
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1786
|
-
return scan;
|
|
1787
|
-
}
|
|
1788
|
-
if (log !== void 0 || captureTl) {
|
|
1789
|
-
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1790
|
-
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1791
|
-
const end = tr2.span.end;
|
|
1792
|
-
return {
|
|
1793
|
-
end,
|
|
1794
|
-
commit: () => {
|
|
1795
|
-
pushTriviaLogEntry(ctx, cur, end);
|
|
1796
|
-
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1797
|
-
}
|
|
1798
|
-
};
|
|
1799
|
-
}
|
|
1800
|
-
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1801
|
-
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1638
|
+
};
|
|
1802
1639
|
}
|
|
1803
|
-
function
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1640
|
+
function recoverScan(input, from, ctx, sync, expected) {
|
|
1641
|
+
let scanPos = from;
|
|
1642
|
+
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1643
|
+
const span = { start: from, end: scanPos };
|
|
1644
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
1645
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1646
|
+
ctx._errors?.push(error);
|
|
1647
|
+
return { error, end: scanPos };
|
|
1808
1648
|
}
|
|
1809
|
-
function
|
|
1810
|
-
|
|
1811
|
-
if (cached !== void 0) return cached;
|
|
1812
|
-
const scanner = buildFastTriviaScanner(trivia2);
|
|
1813
|
-
fastTriviaCache.set(trivia2, scanner);
|
|
1814
|
-
return scanner;
|
|
1649
|
+
function matchesAt(sentinel, input, pos, ctx) {
|
|
1650
|
+
return probeAt(sentinel, input, pos, ctx);
|
|
1815
1651
|
}
|
|
1816
|
-
function
|
|
1817
|
-
|
|
1818
|
-
const direct = regexTriviaScanner(core);
|
|
1819
|
-
if (direct) return direct;
|
|
1820
|
-
const repeat = core._def.tag === "oneOrMore" || core._def.tag === "many" && core._def.min >= 1 ? core._def.parser : null;
|
|
1821
|
-
if (!repeat) return null;
|
|
1822
|
-
const one = regexTriviaScanner(repeat);
|
|
1823
|
-
if (one) return loopScanner([one]);
|
|
1824
|
-
if (repeat._def.tag !== "choice") return null;
|
|
1825
|
-
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1826
|
-
if (arms.some((s) => s === null)) return null;
|
|
1827
|
-
return loopScanner(arms);
|
|
1652
|
+
function captureError(ctx, error) {
|
|
1653
|
+
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1828
1654
|
}
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1655
|
+
var REC = { scan: recoverScan, at: matchesAt, or: orSentinel, sentinel: firstSetSentinel, capture: captureError };
|
|
1656
|
+
|
|
1657
|
+
// src/combinators/sequence.ts
|
|
1658
|
+
function sequence(...parsers) {
|
|
1659
|
+
const meta = {
|
|
1660
|
+
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
1661
|
+
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
1662
|
+
firstSet: sequenceFirstSet(parsers),
|
|
1663
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1664
|
+
isTrivia: false
|
|
1665
|
+
};
|
|
1666
|
+
const def = { tag: "sequence", parsers };
|
|
1667
|
+
let followSentinels;
|
|
1668
|
+
function parseTolerant(input, pos, ctx) {
|
|
1669
|
+
followSentinels ??= parsers.map((_, i) => {
|
|
1670
|
+
const fs = parsers.slice(i + 1).reduce(
|
|
1671
|
+
(acc, p) => union(acc, firstSetOf(p)),
|
|
1672
|
+
{ kind: "empty" }
|
|
1673
|
+
);
|
|
1674
|
+
return firstSetSentinel(fs);
|
|
1675
|
+
});
|
|
1676
|
+
const values = def.valueUnused ? void 0 : [];
|
|
1677
|
+
let cur = pos;
|
|
1678
|
+
const inheritedSync = ctx._sync;
|
|
1679
|
+
try {
|
|
1680
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1681
|
+
ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
1682
|
+
if (ctx.trivia && i > 0) {
|
|
1683
|
+
const mark = saveTriviaMark(ctx);
|
|
1684
|
+
let scanEnd;
|
|
1685
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
1686
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1687
|
+
scan.commit();
|
|
1688
|
+
scanEnd = scan.end;
|
|
1689
|
+
} else {
|
|
1690
|
+
scanEnd = advanceTrivia(input, cur, ctx);
|
|
1691
|
+
}
|
|
1692
|
+
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
1693
|
+
if (!result2.ok) return result2;
|
|
1694
|
+
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
1695
|
+
else rollbackTrivia(ctx, mark);
|
|
1696
|
+
if (values !== void 0) values.push(result2.value);
|
|
1697
|
+
continue;
|
|
1838
1698
|
}
|
|
1699
|
+
const result = parsers[i].parse(input, cur, ctx);
|
|
1700
|
+
if (!result.ok) return result;
|
|
1701
|
+
if (values !== void 0) values.push(result.value);
|
|
1702
|
+
cur = result.span.end;
|
|
1839
1703
|
}
|
|
1840
|
-
|
|
1704
|
+
} finally {
|
|
1705
|
+
ctx._sync = inheritedSync;
|
|
1706
|
+
}
|
|
1707
|
+
return {
|
|
1708
|
+
ok: true,
|
|
1709
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1710
|
+
value: values ?? void 0,
|
|
1711
|
+
span: { start: pos, end: cur }
|
|
1712
|
+
};
|
|
1713
|
+
}
|
|
1714
|
+
return {
|
|
1715
|
+
_tag: "sequence",
|
|
1716
|
+
_meta: meta,
|
|
1717
|
+
_def: def,
|
|
1718
|
+
parse(input, pos, ctx) {
|
|
1719
|
+
if (ctx._tolerant) return parseTolerant(input, pos, ctx);
|
|
1720
|
+
const values = def.valueUnused ? void 0 : [];
|
|
1721
|
+
let cur = pos;
|
|
1722
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1723
|
+
if (ctx.trivia && i > 0) {
|
|
1724
|
+
let scanEnd;
|
|
1725
|
+
let mark = saveTriviaMark(ctx);
|
|
1726
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
1727
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1728
|
+
scan.commit();
|
|
1729
|
+
scanEnd = scan.end;
|
|
1730
|
+
} else {
|
|
1731
|
+
scanEnd = advanceTrivia(input, cur, ctx);
|
|
1732
|
+
}
|
|
1733
|
+
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
1734
|
+
if (!result2.ok) return result2;
|
|
1735
|
+
if (result2.span.end > scanEnd) {
|
|
1736
|
+
cur = result2.span.end;
|
|
1737
|
+
} else {
|
|
1738
|
+
rollbackTrivia(ctx, mark);
|
|
1739
|
+
}
|
|
1740
|
+
if (values !== void 0) values.push(result2.value);
|
|
1741
|
+
continue;
|
|
1742
|
+
}
|
|
1743
|
+
const result = parsers[i].parse(input, cur, ctx);
|
|
1744
|
+
if (!result.ok) return result;
|
|
1745
|
+
if (values !== void 0) values.push(result.value);
|
|
1746
|
+
cur = result.span.end;
|
|
1747
|
+
}
|
|
1748
|
+
return {
|
|
1749
|
+
ok: true,
|
|
1750
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1751
|
+
value: values ?? void 0,
|
|
1752
|
+
span: { start: pos, end: cur }
|
|
1753
|
+
};
|
|
1841
1754
|
}
|
|
1842
|
-
return pos;
|
|
1843
1755
|
};
|
|
1844
1756
|
}
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
return
|
|
1757
|
+
|
|
1758
|
+
// src/combinators/expect.ts
|
|
1759
|
+
function deriveExpected(c) {
|
|
1760
|
+
return [...new Set(derive(c, /* @__PURE__ */ new Set()))];
|
|
1849
1761
|
}
|
|
1850
|
-
function
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1762
|
+
function derive(c, seen) {
|
|
1763
|
+
const deriveExpected2 = (p) => derive(p, seen);
|
|
1764
|
+
const def = c._def;
|
|
1765
|
+
switch (def.tag) {
|
|
1766
|
+
case "literal":
|
|
1767
|
+
return [JSON.stringify(def.value)];
|
|
1768
|
+
case "regex":
|
|
1769
|
+
return [`/${def.source}/`];
|
|
1770
|
+
case "keywords":
|
|
1771
|
+
return def.words.map((w) => JSON.stringify(w));
|
|
1772
|
+
case "label":
|
|
1773
|
+
return [def.label];
|
|
1774
|
+
case "choice":
|
|
1775
|
+
return def.parsers.flatMap(deriveExpected2);
|
|
1776
|
+
case "dispatch":
|
|
1777
|
+
return deriveExpected2(def.selector);
|
|
1778
|
+
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
1779
|
+
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
1780
|
+
// able to fail first — deriving from term 0 alone named a token the parse
|
|
1781
|
+
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
1782
|
+
// nothing (its own expectation is about what must NOT be here), but it is
|
|
1783
|
+
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
1784
|
+
case "sequence": {
|
|
1785
|
+
const out = [];
|
|
1786
|
+
for (const term of def.parsers) {
|
|
1787
|
+
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
1788
|
+
if (!matchesEmpty(term)) break;
|
|
1789
|
+
}
|
|
1790
|
+
return out;
|
|
1791
|
+
}
|
|
1792
|
+
case "attempt":
|
|
1793
|
+
return deriveExpected2(def.parser);
|
|
1794
|
+
// Delegating wrappers whose first-token failure is their inner parser's — must
|
|
1795
|
+
// pass through so a start-failure (and the first-set-miss fast-path in attempt/
|
|
1796
|
+
// node, which reads this) names the real expected token, not the wrapper tag.
|
|
1797
|
+
case "field":
|
|
1798
|
+
case "withCtx":
|
|
1799
|
+
case "recover":
|
|
1800
|
+
return deriveExpected2(def.parser);
|
|
1801
|
+
case "skip":
|
|
1802
|
+
return deriveExpected2(def.main);
|
|
1803
|
+
case "expect":
|
|
1804
|
+
return def.expected;
|
|
1805
|
+
case "node":
|
|
1806
|
+
case "grammar":
|
|
1807
|
+
case "trivia":
|
|
1808
|
+
case "token":
|
|
1809
|
+
case "leaf":
|
|
1810
|
+
case "optional":
|
|
1811
|
+
case "many":
|
|
1812
|
+
case "oneOrMore":
|
|
1813
|
+
case "transform":
|
|
1814
|
+
case "not":
|
|
1815
|
+
case "peek":
|
|
1816
|
+
return deriveExpected2(def.parser);
|
|
1817
|
+
case "routed":
|
|
1818
|
+
return ["routed()"];
|
|
1819
|
+
case "lazy": {
|
|
1820
|
+
const name = c._ruleName;
|
|
1821
|
+
if (seen.has(c)) return name ? [name] : [];
|
|
1822
|
+
seen.add(c);
|
|
1823
|
+
try {
|
|
1824
|
+
return deriveExpected2(def.thunk());
|
|
1825
|
+
} catch {
|
|
1826
|
+
return name ? [name] : [];
|
|
1827
|
+
} finally {
|
|
1828
|
+
seen.delete(c);
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
default:
|
|
1832
|
+
return [];
|
|
1854
1833
|
}
|
|
1855
|
-
return false;
|
|
1856
1834
|
}
|
|
1857
|
-
function
|
|
1858
|
-
const
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
return pos;
|
|
1835
|
+
function expect(combinator, label2) {
|
|
1836
|
+
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
1837
|
+
const meta = {
|
|
1838
|
+
firstSet: combinator._meta.firstSet,
|
|
1839
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1840
|
+
isTrivia: false
|
|
1864
1841
|
};
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1842
|
+
return {
|
|
1843
|
+
_tag: "expect",
|
|
1844
|
+
_meta: meta,
|
|
1845
|
+
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1846
|
+
parse(input, pos, ctx) {
|
|
1847
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1848
|
+
if (result.ok) return result;
|
|
1849
|
+
const span = { start: pos, end: pos };
|
|
1850
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1851
|
+
ctx._errors?.push(error);
|
|
1852
|
+
if (ctx._tolerant) captureError(ctx, error);
|
|
1853
|
+
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1874
1854
|
}
|
|
1875
|
-
return pos;
|
|
1876
1855
|
};
|
|
1877
1856
|
}
|
|
1878
|
-
function
|
|
1879
|
-
|
|
1880
|
-
return m ? classScanner(m[1]) : null;
|
|
1857
|
+
function isParseError(value) {
|
|
1858
|
+
return typeof value === "object" && value !== null && value._tag === "parseError";
|
|
1881
1859
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1860
|
+
|
|
1861
|
+
// src/combinators/choice.ts
|
|
1862
|
+
function choice(...args) {
|
|
1863
|
+
const parsers = args.map((a) => "gate" in a ? a.combinator : a);
|
|
1864
|
+
const gates = args.map((a) => "gate" in a ? a.gate : null);
|
|
1865
|
+
const hasGates = gates.some((g) => g !== null);
|
|
1866
|
+
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
1867
|
+
let combined = { kind: "empty" };
|
|
1868
|
+
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
1869
|
+
const meta = {
|
|
1870
|
+
firstSet: combined,
|
|
1871
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1872
|
+
isTrivia: false,
|
|
1873
|
+
disjoint
|
|
1874
|
+
};
|
|
1875
|
+
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
1876
|
+
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1877
|
+
let greedyLitMap = null;
|
|
1878
|
+
let sortedParsers = null;
|
|
1879
|
+
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
1880
|
+
if (strategy?.tag === "greedyClassify") {
|
|
1881
|
+
greedyLitMap = /* @__PURE__ */ new Map();
|
|
1882
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1883
|
+
if (i === strategy.superIndex) continue;
|
|
1884
|
+
const litVal = getCoreLiteralValue(parsers[i]);
|
|
1885
|
+
if (litVal !== null) greedyLitMap.set(litVal, i);
|
|
1886
|
+
}
|
|
1887
|
+
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
1888
|
+
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
1887
1889
|
}
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1890
|
+
return {
|
|
1891
|
+
_tag: "choice",
|
|
1892
|
+
_meta: meta,
|
|
1893
|
+
_def: {
|
|
1894
|
+
tag: "choice",
|
|
1895
|
+
parsers,
|
|
1896
|
+
gates,
|
|
1897
|
+
disjoint,
|
|
1898
|
+
strategy: strategy ?? { tag: "firstMatch" },
|
|
1899
|
+
autoNot
|
|
1900
|
+
},
|
|
1901
|
+
parse(input, pos, ctx) {
|
|
1902
|
+
const expected = [];
|
|
1903
|
+
if (disjoint && pos < input.length) {
|
|
1904
|
+
const code = input.codePointAt(pos);
|
|
1905
|
+
let idx = code < 128 ? asciiDispatch[code] : -1;
|
|
1906
|
+
if (idx < 0) {
|
|
1907
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1908
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
1909
|
+
idx = i;
|
|
1910
|
+
break;
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
if (idx >= 0) {
|
|
1915
|
+
const gate2 = gates[idx];
|
|
1916
|
+
if (gate2 && !gate2(ctx.state)) {
|
|
1917
|
+
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1918
|
+
}
|
|
1919
|
+
const result = parsers[idx].parse(input, pos, ctx);
|
|
1920
|
+
if (result.ok) return result;
|
|
1921
|
+
expected.push(...result.expected);
|
|
1922
|
+
if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
|
|
1923
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1924
|
+
}
|
|
1925
|
+
return {
|
|
1926
|
+
ok: false,
|
|
1927
|
+
expected: parsers.flatMap((p) => {
|
|
1928
|
+
const r = p.parse(input, pos, ctx);
|
|
1929
|
+
return r.ok ? [] : r.expected;
|
|
1930
|
+
}),
|
|
1931
|
+
span: { start: pos, end: pos }
|
|
1932
|
+
};
|
|
1933
|
+
}
|
|
1934
|
+
if (strategy?.tag === "greedyClassify") {
|
|
1935
|
+
const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
|
|
1936
|
+
if (!superResult.ok) return superResult;
|
|
1937
|
+
const end = superResult.span.end;
|
|
1938
|
+
const litIdx = greedyLitMap.get(input.slice(pos, end));
|
|
1939
|
+
if (litIdx !== void 0) {
|
|
1940
|
+
const litVal = getCoreLiteralValue(parsers[litIdx]);
|
|
1941
|
+
const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
|
|
1942
|
+
return { ok: true, value, span: { start: pos, end } };
|
|
1943
|
+
}
|
|
1944
|
+
return superResult;
|
|
1945
|
+
}
|
|
1946
|
+
if (strategy?.tag === "literalsLongestFirst") {
|
|
1947
|
+
for (const p of sortedParsers) {
|
|
1948
|
+
const r = p.parse(input, pos, ctx);
|
|
1949
|
+
if (r.ok) return r;
|
|
1950
|
+
expected.push(...r.expected);
|
|
1951
|
+
}
|
|
1952
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1953
|
+
}
|
|
1954
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1955
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
1956
|
+
const mark = saveTriviaMark(ctx);
|
|
1957
|
+
const result = parsers[i].parse(input, pos, ctx);
|
|
1958
|
+
if (!result.ok) {
|
|
1959
|
+
rollbackTrivia(ctx, mark);
|
|
1960
|
+
expected.push(...result.expected);
|
|
1961
|
+
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
1962
|
+
continue;
|
|
1963
|
+
}
|
|
1964
|
+
const checks = autoNot[i];
|
|
1965
|
+
if (checks && autoNotFires(input, result.span.end, checks)) {
|
|
1966
|
+
rollbackTrivia(ctx, mark);
|
|
1967
|
+
continue;
|
|
1968
|
+
}
|
|
1969
|
+
return result;
|
|
1970
|
+
}
|
|
1971
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1972
|
+
}
|
|
1973
|
+
};
|
|
1974
|
+
}
|
|
1975
|
+
function detectStrategy(parsers) {
|
|
1976
|
+
const regexIndices = [];
|
|
1977
|
+
const literalIndices = [];
|
|
1978
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1979
|
+
if (getCoreRegexDef(parsers[i]) !== null) regexIndices.push(i);
|
|
1980
|
+
else if (getCoreLiteralValue(parsers[i]) !== null) literalIndices.push(i);
|
|
1981
|
+
}
|
|
1982
|
+
if (regexIndices.length === 1 && literalIndices.length === parsers.length - 1 && literalIndices.length > 0) {
|
|
1983
|
+
const superIndex = regexIndices[0];
|
|
1984
|
+
const regexDef = getCoreRegexDef(parsers[superIndex]);
|
|
1985
|
+
const flags = "y" + regexDef.flags.replace(/[gy]/g, "");
|
|
1986
|
+
const re = new RegExp(regexDef.source, flags);
|
|
1987
|
+
const allSubsumed = literalIndices.every((i) => {
|
|
1988
|
+
const litVal = getCoreLiteralValue(parsers[i]);
|
|
1989
|
+
re.lastIndex = 0;
|
|
1990
|
+
const m = re.exec(litVal);
|
|
1991
|
+
return m !== null && m[0] === litVal;
|
|
1992
|
+
});
|
|
1993
|
+
if (allSubsumed) return { tag: "greedyClassify", superIndex };
|
|
1994
|
+
}
|
|
1995
|
+
if (parsers.length === literalIndices.length) {
|
|
1996
|
+
const sortedIndices = [...literalIndices].sort(
|
|
1997
|
+
(a, b) => getCoreLiteralValue(parsers[b]).length - getCoreLiteralValue(parsers[a]).length
|
|
1998
|
+
);
|
|
1999
|
+
return { tag: "literalsLongestFirst", sortedIndices };
|
|
1892
2000
|
}
|
|
2001
|
+
const shared = detectSharedPrefix(parsers);
|
|
2002
|
+
if (shared !== null) return shared;
|
|
2003
|
+
return { tag: "firstMatch" };
|
|
2004
|
+
}
|
|
2005
|
+
function bareLeadingTermKey(term) {
|
|
2006
|
+
const d = term._def;
|
|
2007
|
+
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
2008
|
+
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
1893
2009
|
return null;
|
|
1894
2010
|
}
|
|
1895
|
-
function
|
|
1896
|
-
if (
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
2011
|
+
function detectSharedPrefix(parsers) {
|
|
2012
|
+
if (parsers.length < 2) return null;
|
|
2013
|
+
let key = null;
|
|
2014
|
+
let prefix = null;
|
|
2015
|
+
const members = [];
|
|
2016
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2017
|
+
const term0 = leadingTermOfArm(parsers[i]);
|
|
2018
|
+
if (term0 === null) return null;
|
|
2019
|
+
const k = bareLeadingTermKey(term0);
|
|
2020
|
+
if (k === null) return null;
|
|
2021
|
+
if (key === null) {
|
|
2022
|
+
key = k;
|
|
2023
|
+
prefix = term0;
|
|
2024
|
+
} else if (k !== key) return null;
|
|
2025
|
+
members.push(i);
|
|
2026
|
+
}
|
|
2027
|
+
if (prefix === null || members.length < 2) return null;
|
|
2028
|
+
return { tag: "sharedPrefix", prefix, members };
|
|
1903
2029
|
}
|
|
1904
|
-
function
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
2030
|
+
function leadingTermOfArm(arm) {
|
|
2031
|
+
let d = arm._def;
|
|
2032
|
+
for (; ; ) {
|
|
2033
|
+
if (d.tag === "node" || d.tag === "grammar" || d.tag === "transform" || d.tag === "label") {
|
|
2034
|
+
d = d.parser._def;
|
|
2035
|
+
continue;
|
|
2036
|
+
}
|
|
2037
|
+
break;
|
|
2038
|
+
}
|
|
2039
|
+
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
2040
|
+
return d.parsers[0];
|
|
2041
|
+
}
|
|
2042
|
+
function computeAutoNot(parsers) {
|
|
2043
|
+
return parsers.map((p, i) => {
|
|
2044
|
+
const litVal = getCoreLiteralValue(p);
|
|
2045
|
+
if (litVal === null) return null;
|
|
2046
|
+
const checks = [];
|
|
2047
|
+
for (let j = i + 1; j < parsers.length; j++) {
|
|
2048
|
+
const other = parsers[j];
|
|
2049
|
+
const otherLit = getCoreLiteralValue(other);
|
|
2050
|
+
if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
|
|
2051
|
+
checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
|
|
1914
2052
|
continue;
|
|
1915
2053
|
}
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
if (cc === 10 || cc === 13) break;
|
|
1921
|
-
pos++;
|
|
1922
|
-
}
|
|
1923
|
-
continue;
|
|
2054
|
+
const regexDef = getCoreRegexDef(other);
|
|
2055
|
+
if (regexDef !== null) {
|
|
2056
|
+
const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
|
|
2057
|
+
if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
|
|
1924
2058
|
}
|
|
1925
|
-
break;
|
|
1926
2059
|
}
|
|
1927
|
-
return
|
|
1928
|
-
};
|
|
2060
|
+
return checks.length > 0 ? checks : null;
|
|
2061
|
+
});
|
|
1929
2062
|
}
|
|
1930
|
-
function
|
|
1931
|
-
const
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
i++;
|
|
1938
|
-
continue;
|
|
1939
|
-
}
|
|
1940
|
-
if (inClass) {
|
|
1941
|
-
if (c === "]") inClass = false;
|
|
1942
|
-
continue;
|
|
1943
|
-
}
|
|
1944
|
-
if (c === "[") inClass = true;
|
|
1945
|
-
else if (c === "(") return null;
|
|
1946
|
-
else if (c === "|") {
|
|
1947
|
-
arms.push(body.slice(start, i));
|
|
1948
|
-
start = i + 1;
|
|
2063
|
+
function autoNotFires(input, end, checks) {
|
|
2064
|
+
for (const check of checks) {
|
|
2065
|
+
if (check.kind === "firstSet") {
|
|
2066
|
+
const code = end < input.length ? input.codePointAt(end) ?? -1 : -1;
|
|
2067
|
+
if (inFirstSet(code, check.set)) return true;
|
|
2068
|
+
} else {
|
|
2069
|
+
if (input.startsWith(check.value, end)) return true;
|
|
1949
2070
|
}
|
|
1950
2071
|
}
|
|
1951
|
-
|
|
1952
|
-
return arms;
|
|
2072
|
+
return false;
|
|
1953
2073
|
}
|
|
1954
|
-
function
|
|
1955
|
-
const
|
|
1956
|
-
if (!
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
const commentCodes = [];
|
|
1967
|
-
for (const arm of arms) {
|
|
1968
|
-
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1969
|
-
else commentCodes.push(arm.code);
|
|
1970
|
-
}
|
|
1971
|
-
if (commentCodes.some((code) => inRanges2(code, ranges))) {
|
|
1972
|
-
return loopScanner(arms.map(armScanner));
|
|
1973
|
-
}
|
|
1974
|
-
if (commentCodes.length === 0) return armScanner({ kind: "class", ranges });
|
|
1975
|
-
return fusedTriviaScanner(ranges, commentCodes);
|
|
2074
|
+
function getCoreLiteralValue(p) {
|
|
2075
|
+
const def = p._def;
|
|
2076
|
+
if (def.tag === "literal" && !def.caseInsensitive) return def.value;
|
|
2077
|
+
if (def.tag === "transform") return getCoreLiteralValue(def.parser);
|
|
2078
|
+
return null;
|
|
2079
|
+
}
|
|
2080
|
+
function getCoreRegexDef(p) {
|
|
2081
|
+
const def = p._def;
|
|
2082
|
+
if (def.tag === "regex") return { source: def.source, flags: def.flags };
|
|
2083
|
+
if (def.tag === "transform") return getCoreRegexDef(def.parser);
|
|
2084
|
+
if (def.tag === "label") return getCoreRegexDef(def.parser);
|
|
2085
|
+
return null;
|
|
1976
2086
|
}
|
|
1977
|
-
function
|
|
1978
|
-
|
|
2087
|
+
function applyTransforms(p, value, span) {
|
|
2088
|
+
const def = p._def;
|
|
2089
|
+
if (def.tag === "transform") {
|
|
2090
|
+
const inner = applyTransforms(def.parser, value, span);
|
|
2091
|
+
return def.fn(inner, span);
|
|
2092
|
+
}
|
|
2093
|
+
return value;
|
|
1979
2094
|
}
|
|
1980
|
-
function
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
2095
|
+
function continuationFirstSet(lit, source, flags) {
|
|
2096
|
+
const re = new RegExp(source, "y" + flags.replace(/[gy]/g, ""));
|
|
2097
|
+
re.lastIndex = 0;
|
|
2098
|
+
const base = re.exec(lit);
|
|
2099
|
+
if (!base || base[0] !== lit) return null;
|
|
2100
|
+
const contCodes = [];
|
|
2101
|
+
for (let code = 1; code < 128; code++) {
|
|
2102
|
+
re.lastIndex = 0;
|
|
2103
|
+
const m = re.exec(lit + String.fromCharCode(code));
|
|
2104
|
+
if (m && m[0].length > lit.length) contCodes.push(code);
|
|
2105
|
+
}
|
|
2106
|
+
if (contCodes.length === 0) return null;
|
|
2107
|
+
return codesToFirstSet(contCodes);
|
|
1984
2108
|
}
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
const def = { tag: "sequence", parsers };
|
|
1996
|
-
let followSentinels;
|
|
1997
|
-
function parseTolerant(input, pos, ctx) {
|
|
1998
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
1999
|
-
const fs = parsers.slice(i + 1).reduce(
|
|
2000
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
2001
|
-
{ kind: "empty" }
|
|
2002
|
-
);
|
|
2003
|
-
return firstSetSentinel(fs);
|
|
2004
|
-
});
|
|
2005
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2006
|
-
let cur = pos;
|
|
2007
|
-
const inheritedSync = ctx._sync;
|
|
2008
|
-
try {
|
|
2009
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
2010
|
-
ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
2011
|
-
if (ctx.trivia && i > 0) {
|
|
2012
|
-
const mark = saveTriviaMark(ctx);
|
|
2013
|
-
let scanEnd;
|
|
2014
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2015
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
2016
|
-
scan.commit();
|
|
2017
|
-
scanEnd = scan.end;
|
|
2018
|
-
} else {
|
|
2019
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2020
|
-
}
|
|
2021
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2022
|
-
if (!result2.ok) return result2;
|
|
2023
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2024
|
-
else rollbackTrivia(ctx, mark);
|
|
2025
|
-
if (values !== void 0) values.push(result2.value);
|
|
2026
|
-
continue;
|
|
2027
|
-
}
|
|
2028
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2029
|
-
if (!result.ok) return result;
|
|
2030
|
-
if (values !== void 0) values.push(result.value);
|
|
2031
|
-
cur = result.span.end;
|
|
2032
|
-
}
|
|
2033
|
-
} finally {
|
|
2034
|
-
ctx._sync = inheritedSync;
|
|
2109
|
+
function codesToFirstSet(codes) {
|
|
2110
|
+
codes.sort((a, b) => a - b);
|
|
2111
|
+
const ranges = [];
|
|
2112
|
+
let lo = codes[0], hi = codes[0];
|
|
2113
|
+
for (let i = 1; i < codes.length; i++) {
|
|
2114
|
+
if (codes[i] === hi + 1) {
|
|
2115
|
+
hi = codes[i];
|
|
2116
|
+
} else {
|
|
2117
|
+
ranges.push({ lo, hi });
|
|
2118
|
+
lo = hi = codes[i];
|
|
2035
2119
|
}
|
|
2036
|
-
return {
|
|
2037
|
-
ok: true,
|
|
2038
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2039
|
-
value: values ?? void 0,
|
|
2040
|
-
span: { start: pos, end: cur }
|
|
2041
|
-
};
|
|
2042
2120
|
}
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
rollbackTrivia(ctx, mark);
|
|
2068
|
-
}
|
|
2069
|
-
if (values !== void 0) values.push(result2.value);
|
|
2070
|
-
continue;
|
|
2071
|
-
}
|
|
2072
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2073
|
-
if (!result.ok) return result;
|
|
2074
|
-
if (values !== void 0) values.push(result.value);
|
|
2075
|
-
cur = result.span.end;
|
|
2121
|
+
ranges.push({ lo, hi });
|
|
2122
|
+
return { kind: "ranges", ranges };
|
|
2123
|
+
}
|
|
2124
|
+
function inFirstSet(code, fs) {
|
|
2125
|
+
if (fs.kind === "any") return true;
|
|
2126
|
+
if (fs.kind === "empty") return false;
|
|
2127
|
+
for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
2128
|
+
return false;
|
|
2129
|
+
}
|
|
2130
|
+
function areDisjoint(sets) {
|
|
2131
|
+
if (sets.some((s) => s.kind === "any")) return false;
|
|
2132
|
+
for (let i = 0; i < sets.length; i++)
|
|
2133
|
+
for (let j = i + 1; j < sets.length; j++)
|
|
2134
|
+
if (intersects(sets[i], sets[j])) return false;
|
|
2135
|
+
return true;
|
|
2136
|
+
}
|
|
2137
|
+
function buildAsciiDispatch(parsers) {
|
|
2138
|
+
const table = Array(128).fill(-1);
|
|
2139
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2140
|
+
const fs = parsers[i]._meta.firstSet;
|
|
2141
|
+
if (fs.kind !== "ranges") continue;
|
|
2142
|
+
for (const { lo, hi } of fs.ranges) {
|
|
2143
|
+
for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
|
|
2144
|
+
table[code] = i;
|
|
2076
2145
|
}
|
|
2077
|
-
return {
|
|
2078
|
-
ok: true,
|
|
2079
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2080
|
-
value: values ?? void 0,
|
|
2081
|
-
span: { start: pos, end: cur }
|
|
2082
|
-
};
|
|
2083
2146
|
}
|
|
2084
|
-
}
|
|
2147
|
+
}
|
|
2148
|
+
return table;
|
|
2085
2149
|
}
|
|
2086
2150
|
|
|
2087
2151
|
// src/combinators/dispatch.ts
|
|
@@ -2344,10 +2408,12 @@ function attempt(parser2) {
|
|
|
2344
2408
|
}
|
|
2345
2409
|
const mark = saveCstMark(ctx);
|
|
2346
2410
|
const log = ctx._triviaLog?.length;
|
|
2411
|
+
const rootLog = ctx._rootTriviaLog?.length;
|
|
2347
2412
|
const result = parser2.parse(input, pos, ctx);
|
|
2348
2413
|
if (result.ok) return result;
|
|
2349
2414
|
rollbackCstCapture(ctx, mark);
|
|
2350
2415
|
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
2416
|
+
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
2351
2417
|
if (result.committed) return result;
|
|
2352
2418
|
return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
|
|
2353
2419
|
}
|
|
@@ -2788,18 +2854,37 @@ function createParseLineContext(input, pos) {
|
|
|
2788
2854
|
}
|
|
2789
2855
|
function parser(opts, root) {
|
|
2790
2856
|
const clearTrivia = opts.trivia === null;
|
|
2857
|
+
const opaqueRootCapture = opts.rootCapture === "opaque";
|
|
2858
|
+
if (opaqueRootCapture && opts.trivia === void 0) {
|
|
2859
|
+
throw new TypeError("parser({ rootCapture: 'opaque' }) requires an explicit trivia scope.");
|
|
2860
|
+
}
|
|
2791
2861
|
return {
|
|
2792
2862
|
_tag: "grammar",
|
|
2793
|
-
_meta:
|
|
2863
|
+
_meta: {
|
|
2864
|
+
...root._meta,
|
|
2865
|
+
// Trivia classification describes this grammar's own active trivia
|
|
2866
|
+
// scope. A directly nested grammar may have classified trivia of its
|
|
2867
|
+
// own, but that must not advertise classification for this wrapper.
|
|
2868
|
+
triviaKindLabels: void 0,
|
|
2869
|
+
rootTriviaClassified: void 0,
|
|
2870
|
+
...opts.trivia?._meta?.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {},
|
|
2871
|
+
...opts.trivia?._meta?.rootTriviaClassified ? { rootTriviaClassified: true } : {}
|
|
2872
|
+
},
|
|
2794
2873
|
_def: {
|
|
2795
2874
|
tag: "grammar",
|
|
2796
2875
|
parser: root,
|
|
2797
2876
|
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2798
2877
|
clearTrivia,
|
|
2878
|
+
...opaqueRootCapture ? { rootCapture: "opaque" } : {},
|
|
2799
2879
|
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2800
2880
|
trackLines: opts.trackLines ?? false
|
|
2801
2881
|
},
|
|
2802
2882
|
parse(input, pos, _ctx) {
|
|
2883
|
+
if (_ctx?._rootTriviaStrictScopes && opts.trivia !== void 0 && opts.trivia !== null && !opts.trivia._meta.rootTriviaClassified && !opaqueRootCapture) {
|
|
2884
|
+
throw new TypeError(
|
|
2885
|
+
"parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'."
|
|
2886
|
+
);
|
|
2887
|
+
}
|
|
2803
2888
|
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2804
2889
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2805
2890
|
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
@@ -2822,7 +2907,11 @@ function parser(opts, root) {
|
|
|
2822
2907
|
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2823
2908
|
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2824
2909
|
// (capture all).
|
|
2825
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
2910
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {},
|
|
2911
|
+
// This is a property of the local trivia scope, not a post-parse filter:
|
|
2912
|
+
// nested recognition can still skip its trivia, but selected root rows
|
|
2913
|
+
// must never be written for an explicitly opaque region.
|
|
2914
|
+
...opaqueRootCapture ? { _rootTriviaCapture: false } : {}
|
|
2826
2915
|
};
|
|
2827
2916
|
const result = root.parse(input, pos ?? 0, ctx);
|
|
2828
2917
|
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
@@ -3505,6 +3594,25 @@ function trivia(combinator) {
|
|
|
3505
3594
|
parse: combinator.parse.bind(combinator)
|
|
3506
3595
|
};
|
|
3507
3596
|
}
|
|
3597
|
+
function classifiedTrivia(arms) {
|
|
3598
|
+
const entries = Object.entries(arms);
|
|
3599
|
+
if (entries.length === 0) {
|
|
3600
|
+
throw new TypeError("classifiedTrivia() requires at least one named trivia arm.");
|
|
3601
|
+
}
|
|
3602
|
+
for (let i = 0; i < entries.length; i++) {
|
|
3603
|
+
const [name, arm] = entries[i];
|
|
3604
|
+
const first = arm._meta.firstSet;
|
|
3605
|
+
if (matchesEmpty(arm) || first.kind !== "ranges" || first.ranges.length === 0) {
|
|
3606
|
+
throw new TypeError(
|
|
3607
|
+
`classifiedTrivia(): ${JSON.stringify(name)} must be non-nullable with a concrete finite first set.`
|
|
3608
|
+
);
|
|
3609
|
+
}
|
|
3610
|
+
}
|
|
3611
|
+
const labeledArms = entries.map(([name, arm]) => label(name, arm));
|
|
3612
|
+
const result = trivia(oneOrMore(choice(...labeledArms)));
|
|
3613
|
+
result._meta.rootTriviaClassified = true;
|
|
3614
|
+
return result;
|
|
3615
|
+
}
|
|
3508
3616
|
function label(name, combinator) {
|
|
3509
3617
|
return {
|
|
3510
3618
|
_tag: combinator._tag,
|
|
@@ -3551,6 +3659,7 @@ function token(root) {
|
|
|
3551
3659
|
const savedRaw = ctx._cstRawChildren;
|
|
3552
3660
|
const savedTriviaLog = ctx._cstTriviaLog;
|
|
3553
3661
|
const savedOuterTriviaLog = ctx._triviaLog;
|
|
3662
|
+
const savedRootTriviaLog = ctx._rootTriviaLog;
|
|
3554
3663
|
const wasCapturing = cstCaptureActive(ctx);
|
|
3555
3664
|
ctx.trivia = void 0;
|
|
3556
3665
|
ctx.triviaKindLabels = void 0;
|
|
@@ -3560,6 +3669,7 @@ function token(root) {
|
|
|
3560
3669
|
ctx._cstRawChildren = void 0;
|
|
3561
3670
|
ctx._cstTriviaLog = void 0;
|
|
3562
3671
|
delete ctx._triviaLog;
|
|
3672
|
+
delete ctx._rootTriviaLog;
|
|
3563
3673
|
let result;
|
|
3564
3674
|
try {
|
|
3565
3675
|
result = root.parse(input, pos, ctx);
|
|
@@ -3573,6 +3683,8 @@ function token(root) {
|
|
|
3573
3683
|
ctx._cstTriviaLog = savedTriviaLog;
|
|
3574
3684
|
if (savedOuterTriviaLog === void 0) delete ctx._triviaLog;
|
|
3575
3685
|
else ctx._triviaLog = savedOuterTriviaLog;
|
|
3686
|
+
if (savedRootTriviaLog === void 0) delete ctx._rootTriviaLog;
|
|
3687
|
+
else ctx._rootTriviaLog = savedRootTriviaLog;
|
|
3576
3688
|
}
|
|
3577
3689
|
if (!result.ok) return result;
|
|
3578
3690
|
const span = result.span;
|
|
@@ -3627,7 +3739,7 @@ function leaf(root, fn) {
|
|
|
3627
3739
|
}
|
|
3628
3740
|
|
|
3629
3741
|
// src/version.ts
|
|
3630
|
-
var PARSEMAN_VERSION = "0.
|
|
3742
|
+
var PARSEMAN_VERSION = "0.44.0";
|
|
3631
3743
|
|
|
3632
3744
|
// src/cst/host-mode.ts
|
|
3633
3745
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -5525,9 +5637,196 @@ function buildGrammarPlan(entry, winners) {
|
|
|
5525
5637
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
|
|
5526
5638
|
}
|
|
5527
5639
|
|
|
5640
|
+
// src/cst/trivia-entries.ts
|
|
5641
|
+
var EMPTY_INDICES = Object.freeze([]);
|
|
5642
|
+
var EMPTY_GAPS = Object.freeze([]);
|
|
5643
|
+
var SELECTED_ROOT_STRIDE = 5;
|
|
5644
|
+
function entryOffset(i, stride) {
|
|
5645
|
+
return i * stride;
|
|
5646
|
+
}
|
|
5647
|
+
function triviaEntries(log, labels, opts) {
|
|
5648
|
+
const baseStride = opts?.nodeLog ? 3 : 2;
|
|
5649
|
+
const stride = labels ? baseStride + 1 : baseStride;
|
|
5650
|
+
const length = Math.floor(log.length / stride);
|
|
5651
|
+
return {
|
|
5652
|
+
length,
|
|
5653
|
+
labels,
|
|
5654
|
+
stride,
|
|
5655
|
+
start(i) {
|
|
5656
|
+
return log[entryOffset(i, stride)];
|
|
5657
|
+
},
|
|
5658
|
+
end(i) {
|
|
5659
|
+
return log[entryOffset(i, stride) + 1];
|
|
5660
|
+
},
|
|
5661
|
+
insertIndex(i) {
|
|
5662
|
+
return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
|
|
5663
|
+
},
|
|
5664
|
+
kindIndex(i) {
|
|
5665
|
+
if (!labels) return void 0;
|
|
5666
|
+
return log[entryOffset(i, stride) + baseStride];
|
|
5667
|
+
},
|
|
5668
|
+
kind(i) {
|
|
5669
|
+
const ki = labels ? log[entryOffset(i, stride) + baseStride] : void 0;
|
|
5670
|
+
return ki !== void 0 ? labels[ki] : void 0;
|
|
5671
|
+
},
|
|
5672
|
+
text(i, input) {
|
|
5673
|
+
const s = log[entryOffset(i, stride)];
|
|
5674
|
+
const e = log[entryOffset(i, stride) + 1];
|
|
5675
|
+
return input.slice(s, e);
|
|
5676
|
+
}
|
|
5677
|
+
};
|
|
5678
|
+
}
|
|
5679
|
+
function buildRootTriviaIndex(log, labels) {
|
|
5680
|
+
const length = Math.floor(log.length / SELECTED_ROOT_STRIDE);
|
|
5681
|
+
const markerOffset = (i) => i * SELECTED_ROOT_STRIDE;
|
|
5682
|
+
const ownedRangeStart = (i) => log[markerOffset(i)];
|
|
5683
|
+
const ownedRangeEnd = (i) => log[markerOffset(i) + 1];
|
|
5684
|
+
const markerStart = (i) => log[markerOffset(i) + 2];
|
|
5685
|
+
const markerEnd = (i) => log[markerOffset(i) + 3];
|
|
5686
|
+
const markerKind = (i) => log[markerOffset(i) + 4];
|
|
5687
|
+
const entries = {
|
|
5688
|
+
length,
|
|
5689
|
+
labels,
|
|
5690
|
+
stride: SELECTED_ROOT_STRIDE,
|
|
5691
|
+
start: markerStart,
|
|
5692
|
+
end: markerEnd,
|
|
5693
|
+
insertIndex: () => void 0,
|
|
5694
|
+
kindIndex: markerKind,
|
|
5695
|
+
kind(i) {
|
|
5696
|
+
return labels[markerKind(i)];
|
|
5697
|
+
},
|
|
5698
|
+
text(i, input) {
|
|
5699
|
+
return input.slice(markerStart(i), markerEnd(i));
|
|
5700
|
+
}
|
|
5701
|
+
};
|
|
5702
|
+
const lowerBound = (offset, by) => {
|
|
5703
|
+
let lo = 0;
|
|
5704
|
+
let hi = length;
|
|
5705
|
+
while (lo < hi) {
|
|
5706
|
+
const mid = lo + hi >>> 1;
|
|
5707
|
+
if (by(mid) < offset) lo = mid + 1;
|
|
5708
|
+
else hi = mid;
|
|
5709
|
+
}
|
|
5710
|
+
return lo;
|
|
5711
|
+
};
|
|
5712
|
+
const gapRowsAt = (offset, direction) => {
|
|
5713
|
+
const edge = direction === "before" ? ownedRangeEnd : ownedRangeStart;
|
|
5714
|
+
let first = lowerBound(offset, edge);
|
|
5715
|
+
if (first === length || edge(first) !== offset) return void 0;
|
|
5716
|
+
const start = ownedRangeStart(first);
|
|
5717
|
+
const end = ownedRangeEnd(first);
|
|
5718
|
+
while (first > 0 && ownedRangeStart(first - 1) === start && ownedRangeEnd(first - 1) === end) first--;
|
|
5719
|
+
let last = first + 1;
|
|
5720
|
+
while (last < length && ownedRangeStart(last) === start && ownedRangeEnd(last) === end) last++;
|
|
5721
|
+
return [first, last];
|
|
5722
|
+
};
|
|
5723
|
+
const indices = (first, last) => {
|
|
5724
|
+
const out = [];
|
|
5725
|
+
for (let i = first; i < last; i++) out.push(i);
|
|
5726
|
+
return out;
|
|
5727
|
+
};
|
|
5728
|
+
const makeGap = (first, last) => {
|
|
5729
|
+
const start = ownedRangeStart(first);
|
|
5730
|
+
const end = ownedRangeEnd(first);
|
|
5731
|
+
let entryIndices;
|
|
5732
|
+
return {
|
|
5733
|
+
start,
|
|
5734
|
+
end,
|
|
5735
|
+
get entryIndices() {
|
|
5736
|
+
return entryIndices ??= indices(first, last);
|
|
5737
|
+
},
|
|
5738
|
+
hasKind(kind) {
|
|
5739
|
+
for (let i = first; i < last; i++) {
|
|
5740
|
+
if (labels[markerKind(i)] === kind) return true;
|
|
5741
|
+
}
|
|
5742
|
+
return false;
|
|
5743
|
+
},
|
|
5744
|
+
text(input) {
|
|
5745
|
+
return input.slice(start, end);
|
|
5746
|
+
}
|
|
5747
|
+
};
|
|
5748
|
+
};
|
|
5749
|
+
let maps;
|
|
5750
|
+
const getMaps = () => {
|
|
5751
|
+
if (maps !== void 0) return maps;
|
|
5752
|
+
const before = /* @__PURE__ */ new Map();
|
|
5753
|
+
const after = /* @__PURE__ */ new Map();
|
|
5754
|
+
const beforeGaps = /* @__PURE__ */ new Map();
|
|
5755
|
+
const afterGaps = /* @__PURE__ */ new Map();
|
|
5756
|
+
const gaps = [];
|
|
5757
|
+
for (let first = 0; first < length; ) {
|
|
5758
|
+
let last = first + 1;
|
|
5759
|
+
while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
|
|
5760
|
+
const gap = makeGap(first, last);
|
|
5761
|
+
gaps.push(gap);
|
|
5762
|
+
afterGaps.set(gap.start, gap);
|
|
5763
|
+
beforeGaps.set(gap.end, gap);
|
|
5764
|
+
after.set(gap.start, [...gap.entryIndices]);
|
|
5765
|
+
before.set(gap.end, [...gap.entryIndices]);
|
|
5766
|
+
first = last;
|
|
5767
|
+
}
|
|
5768
|
+
maps = { before, after, beforeGaps, afterGaps, gaps };
|
|
5769
|
+
return maps;
|
|
5770
|
+
};
|
|
5771
|
+
return {
|
|
5772
|
+
entries,
|
|
5773
|
+
labels,
|
|
5774
|
+
get before() {
|
|
5775
|
+
return getMaps().before;
|
|
5776
|
+
},
|
|
5777
|
+
get after() {
|
|
5778
|
+
return getMaps().after;
|
|
5779
|
+
},
|
|
5780
|
+
entryIndicesBefore(offset) {
|
|
5781
|
+
const rows = gapRowsAt(offset, "before");
|
|
5782
|
+
return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
|
|
5783
|
+
},
|
|
5784
|
+
entryIndicesAfter(offset) {
|
|
5785
|
+
const rows = gapRowsAt(offset, "after");
|
|
5786
|
+
return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
|
|
5787
|
+
},
|
|
5788
|
+
gapBefore(offset) {
|
|
5789
|
+
const rows = gapRowsAt(offset, "before");
|
|
5790
|
+
return rows ? makeGap(rows[0], rows[1]) : void 0;
|
|
5791
|
+
},
|
|
5792
|
+
gapAfter(offset) {
|
|
5793
|
+
const rows = gapRowsAt(offset, "after");
|
|
5794
|
+
return rows ? makeGap(rows[0], rows[1]) : void 0;
|
|
5795
|
+
},
|
|
5796
|
+
gaps() {
|
|
5797
|
+
return getMaps().gaps;
|
|
5798
|
+
},
|
|
5799
|
+
gapsWithKind(kind) {
|
|
5800
|
+
const kinds = typeof kind === "string" ? [kind] : kind;
|
|
5801
|
+
const matches2 = [];
|
|
5802
|
+
for (let first = 0; first < length; ) {
|
|
5803
|
+
let last = first + 1;
|
|
5804
|
+
while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
|
|
5805
|
+
let matched = false;
|
|
5806
|
+
for (let i = first; i < last && !matched; i++) {
|
|
5807
|
+
const label2 = labels[markerKind(i)];
|
|
5808
|
+
for (const kind2 of kinds) {
|
|
5809
|
+
if (label2 === kind2) {
|
|
5810
|
+
matched = true;
|
|
5811
|
+
break;
|
|
5812
|
+
}
|
|
5813
|
+
}
|
|
5814
|
+
}
|
|
5815
|
+
if (matched) matches2.push(makeGap(first, last));
|
|
5816
|
+
first = last;
|
|
5817
|
+
}
|
|
5818
|
+
return matches2.length === 0 ? EMPTY_GAPS : matches2;
|
|
5819
|
+
}
|
|
5820
|
+
};
|
|
5821
|
+
}
|
|
5822
|
+
|
|
5528
5823
|
// src/compiler/scannable-run.ts
|
|
5529
5824
|
var BACKSLASH = 92;
|
|
5530
5825
|
var META = new Set("()[]{}*+?|^$.".split(""));
|
|
5826
|
+
var SELECTED_ROOT_OWNED_RANGE_PLACEHOLDER = Array.from(
|
|
5827
|
+
{ length: SELECTED_ROOT_STRIDE - 3 },
|
|
5828
|
+
() => "0"
|
|
5829
|
+
).join(", ");
|
|
5531
5830
|
function classToRanges(cls) {
|
|
5532
5831
|
if (cls === "\\d") return shorthandRanges("d");
|
|
5533
5832
|
if (cls === "\\w") return shorthandRanges("w");
|
|
@@ -6566,13 +6865,15 @@ function scanBranch(shape, mint) {
|
|
|
6566
6865
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6567
6866
|
return [...m.setup, ` if (${m.end} > _e) { _e = ${m.end}; continue }`].join("\n");
|
|
6568
6867
|
}
|
|
6569
|
-
function scanBranchLabeled(shape, kindIndex, mint) {
|
|
6868
|
+
function scanBranchLabeled(shape, kindIndex, label2, mint) {
|
|
6570
6869
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6571
6870
|
return [
|
|
6572
6871
|
...m.setup,
|
|
6573
6872
|
` if (${m.end} > _e) {`,
|
|
6574
6873
|
` if (_cap) {`,
|
|
6575
6874
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, ${m.end}, ${kindIndex})`,
|
|
6875
|
+
` const _rk = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(label2)}] ?? -1)`,
|
|
6876
|
+
` if (_rk >= 0) _ctx._rootTriviaLog.push(${SELECTED_ROOT_OWNED_RANGE_PLACEHOLDER}, _e, ${m.end}, _rk)`,
|
|
6576
6877
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << kindIndex}))) _ctx._cstTriviaLog.push(_e, ${m.end}, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${kindIndex})`,
|
|
6577
6878
|
` }`,
|
|
6578
6879
|
` _e = ${m.end}`,
|
|
@@ -6632,6 +6933,11 @@ var CAP_RECORD = [
|
|
|
6632
6933
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
|
|
6633
6934
|
` }`
|
|
6634
6935
|
].join("\n");
|
|
6936
|
+
var SELECTED_ROOT_FINISH = [
|
|
6937
|
+
` if (_cap && _ctx._rootTriviaCapture !== false && _ctx._rootTriviaLog !== undefined && _ctx._rootTriviaLog.length !== _rootMark) {`,
|
|
6938
|
+
` for (let _ri = _rootMark; _ri < _ctx._rootTriviaLog.length; _ri += ${SELECTED_ROOT_STRIDE}) { _ctx._rootTriviaLog[_ri] = _pos; _ctx._rootTriviaLog[_ri + 1] = _e }`,
|
|
6939
|
+
` }`
|
|
6940
|
+
].join("\n");
|
|
6635
6941
|
function composeFastLoop(shapes) {
|
|
6636
6942
|
const mint = makeMint();
|
|
6637
6943
|
return [
|
|
@@ -6660,7 +6966,7 @@ function analyzeLabeledScannableRun(trivia2) {
|
|
|
6660
6966
|
const d = getCoreRegexDef(arm.parser);
|
|
6661
6967
|
const shape = d ? scanShapeFromRegex(d.source, d.flags) : null;
|
|
6662
6968
|
if (!shape) return null;
|
|
6663
|
-
out.push({ shape, kindIndex: arm.kindIndex });
|
|
6969
|
+
out.push({ shape, kindIndex: arm.kindIndex, label: arm.label });
|
|
6664
6970
|
}
|
|
6665
6971
|
return out;
|
|
6666
6972
|
}
|
|
@@ -6669,11 +6975,13 @@ function buildLabeledScannableTriviaFnDecl(fnName, arms) {
|
|
|
6669
6975
|
return [
|
|
6670
6976
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6671
6977
|
` let _e = _pos`,
|
|
6978
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6672
6979
|
` while (_e < input.length) {`,
|
|
6673
6980
|
` const c = input.charCodeAt(_e)`,
|
|
6674
|
-
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, mint)),
|
|
6981
|
+
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, a.label, mint)),
|
|
6675
6982
|
` break`,
|
|
6676
6983
|
` }`,
|
|
6984
|
+
SELECTED_ROOT_FINISH,
|
|
6677
6985
|
` return _e`,
|
|
6678
6986
|
`}`
|
|
6679
6987
|
].join("\n");
|
|
@@ -6689,6 +6997,8 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6689
6997
|
` const _ce = _e + _m${i}[0].length`,
|
|
6690
6998
|
` if (_cap) {`,
|
|
6691
6999
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
|
|
7000
|
+
` const _rk${i} = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(arm.label)}] ?? -1)`,
|
|
7001
|
+
` if (_rk${i} >= 0) _ctx._rootTriviaLog.push(0, 0, _e, _ce, _rk${i})`,
|
|
6692
7002
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
|
|
6693
7003
|
` }`,
|
|
6694
7004
|
` _e = _ce`,
|
|
@@ -6700,11 +7010,13 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6700
7010
|
return [
|
|
6701
7011
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6702
7012
|
` let _e = _pos`,
|
|
7013
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6703
7014
|
` while (_e < input.length) {`,
|
|
6704
7015
|
` let _matched = false`,
|
|
6705
7016
|
tryArms,
|
|
6706
7017
|
` if (!_matched) break`,
|
|
6707
7018
|
` }`,
|
|
7019
|
+
SELECTED_ROOT_FINISH,
|
|
6708
7020
|
` return _e`,
|
|
6709
7021
|
`}`
|
|
6710
7022
|
].join("\n");
|
|
@@ -6727,6 +7039,8 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6727
7039
|
` const _ce = _r${i}.span.end`,
|
|
6728
7040
|
` if (_cap) {`,
|
|
6729
7041
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
|
|
7042
|
+
` const _rk${i} = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(arm.label)}] ?? -1)`,
|
|
7043
|
+
` if (_rk${i} >= 0) _ctx._rootTriviaLog.push(0, 0, _e, _ce, _rk${i})`,
|
|
6730
7044
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
|
|
6731
7045
|
` }`,
|
|
6732
7046
|
` _e = _ce`,
|
|
@@ -6738,11 +7052,13 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6738
7052
|
return [
|
|
6739
7053
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6740
7054
|
` let _e = _pos`,
|
|
7055
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6741
7056
|
` while (_e < input.length) {`,
|
|
6742
7057
|
` let _matched = false`,
|
|
6743
7058
|
tryArms,
|
|
6744
7059
|
` if (!_matched) break`,
|
|
6745
7060
|
` }`,
|
|
7061
|
+
SELECTED_ROOT_FINISH,
|
|
6746
7062
|
` return _e`,
|
|
6747
7063
|
`}`
|
|
6748
7064
|
].join("\n");
|
|
@@ -6965,6 +7281,9 @@ var HOST_READS_DECL = "const _hostReads = (b, n) => { if (b === undefined) retur
|
|
|
6965
7281
|
var LINE_TRACK_DECL = "const _trackLines = (_ctx, input, start, end) => { const from = _ctx._lineScannedTo ?? 0; if (end <= from) return; for (let i = from; i < end; i++) if (input.charCodeAt(i) === 10) _ctx._lineStarts.push(i + 1); _ctx._lineScannedTo = end }";
|
|
6966
7282
|
var LINE_SPAN_DECL = "const _lineCol = (_ctx, offset) => { const starts = _ctx._lineStarts; let lo = 0, hi = starts.length - 1; while (lo < hi) { const mid = (lo + hi + 1) >> 1; if (starts[mid] <= offset) lo = mid; else hi = mid - 1 } return [lo + 1, offset - starts[lo] + 1] }\nconst _spanLines = (_ctx, start, end) => { const s = _lineCol(_ctx, start), e = _lineCol(_ctx, end); return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] } }";
|
|
6967
7283
|
var _loweringSink = null;
|
|
7284
|
+
function hasSelectedRootTrivia(ctx) {
|
|
7285
|
+
return ctx.rootTriviaClassified === true;
|
|
7286
|
+
}
|
|
6968
7287
|
function v(ctx, prefix = "_v") {
|
|
6969
7288
|
return `${prefix}${ctx.vars++}`;
|
|
6970
7289
|
}
|
|
@@ -7274,10 +7593,12 @@ function planDisjointDispatch(parsers) {
|
|
|
7274
7593
|
}
|
|
7275
7594
|
return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
7276
7595
|
}
|
|
7277
|
-
function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
|
|
7596
|
+
function captureRestoreBody(ctx, mL, mR, mTl, mLg, mF = null, mRootLg = null) {
|
|
7278
7597
|
const fieldRestore = mF ? `; if (_ctx._fields && _ctx._fields.length !== ${mF}) _ctx._fields.length = ${mF}` : "";
|
|
7279
7598
|
const base = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${mL}) _ctx._cstLeaves.length = ${mL}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${mR}) _ctx._cstRawChildren.length = ${mR}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${mTl}) _ctx._cstTriviaLog.length = ${mTl}${fieldRestore}`;
|
|
7280
|
-
|
|
7599
|
+
const logRestore = mLg ? `; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${mLg}) _ctx._triviaLog.length = ${mLg}` : "";
|
|
7600
|
+
const rootLogRestore = hasSelectedRootTrivia(ctx) && mRootLg ? `; if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${mRootLg}) _ctx._rootTriviaLog.length = ${mRootLg}` : "";
|
|
7601
|
+
return `${base}${logRestore}${rootLogRestore}`;
|
|
7281
7602
|
}
|
|
7282
7603
|
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
7283
7604
|
if (seen.has(p)) return false;
|
|
@@ -7487,7 +7808,7 @@ function emitFallible(inner, ctx, pos, swallow = false) {
|
|
|
7487
7808
|
`${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
|
|
7488
7809
|
`${ind0}}`,
|
|
7489
7810
|
...mL ? [
|
|
7490
|
-
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
|
|
7811
|
+
`${ind0}if (!${okV}) { ${captureRestoreBody(ctx, mL, mR, mTl, null, mF)} }`
|
|
7491
7812
|
] : []
|
|
7492
7813
|
];
|
|
7493
7814
|
return { stmts, okVar: okV, valVar: valV, endVar: endV, mayCommit };
|
|
@@ -7684,11 +8005,13 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7684
8005
|
const markV = v(ctx, "_mk");
|
|
7685
8006
|
const markTl = v(ctx, "_mktl");
|
|
7686
8007
|
const markLog = v(ctx, "_mklg");
|
|
8008
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7687
8009
|
const scanEndV = v(ctx, "_sne");
|
|
7688
8010
|
stmts.push(
|
|
7689
8011
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7690
8012
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7691
8013
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8014
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7692
8015
|
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7693
8016
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7694
8017
|
);
|
|
@@ -7697,17 +8020,19 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7697
8020
|
const endAfterV = v(ctx, "_sea");
|
|
7698
8021
|
stmts.push(
|
|
7699
8022
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7700
|
-
`${ind(ctx)}if (${endAfterV} > ${scanEndV}) { ${curV} = ${endAfterV} } else { if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}
|
|
8023
|
+
`${ind(ctx)}if (${endAfterV} > ${scanEndV}) { ${curV} = ${endAfterV} } else { if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog};${markRootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog};` : ""} }`
|
|
7701
8024
|
);
|
|
7702
8025
|
valueVars.push(r2.valueVar);
|
|
7703
8026
|
continue;
|
|
7704
8027
|
} else {
|
|
7705
8028
|
const trivFn = ensureTriviaFn(ctx);
|
|
7706
8029
|
const markLog = v(ctx, "_mklg");
|
|
8030
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7707
8031
|
const scanEndV = v(ctx, "_sne");
|
|
7708
|
-
const capArg = ctx.noHoist ? "0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
8032
|
+
const capArg = ctx.noHoist ? "0" : hasSelectedRootTrivia(ctx) ? "(_ctx._triviaLog !== undefined || _ctx._rootTriviaLog !== undefined) ? 2 : 0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7709
8033
|
stmts.push(
|
|
7710
8034
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8035
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7711
8036
|
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7712
8037
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7713
8038
|
);
|
|
@@ -7716,7 +8041,7 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7716
8041
|
const endAfterV = v(ctx, "_sea");
|
|
7717
8042
|
stmts.push(
|
|
7718
8043
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7719
|
-
`${ind(ctx)}if (${endAfterV} > ${scanEndV}) ${curV} = ${endAfterV}; else if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}`
|
|
8044
|
+
`${ind(ctx)}if (${endAfterV} > ${scanEndV}) ${curV} = ${endAfterV}; else { if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog};${markRootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog};` : ""} }`
|
|
7720
8045
|
);
|
|
7721
8046
|
valueVars.push(r2.valueVar);
|
|
7722
8047
|
continue;
|
|
@@ -7958,6 +8283,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7958
8283
|
const selectorRawMark = selectorNeedsRollback ? v(ctx, "_dsr") : null;
|
|
7959
8284
|
const selectorTriviaMark = selectorNeedsRollback ? v(ctx, "_dst") : null;
|
|
7960
8285
|
const selectorLogMark = selectorNeedsRollback ? v(ctx, "_dsg") : null;
|
|
8286
|
+
const selectorRootLogMark = selectorNeedsRollback && hasSelectedRootTrivia(ctx) ? v(ctx, "_dsrg") : null;
|
|
7961
8287
|
const selectorFieldMark = selectorNeedsRollback ? v(ctx, "_dsf") : null;
|
|
7962
8288
|
const selectorErrorMark = selectorNeedsRollback ? v(ctx, "_dse") : null;
|
|
7963
8289
|
const selector = emit(def.selector, ctx, pos);
|
|
@@ -7970,6 +8296,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7970
8296
|
`${ind(ctx)}const ${selectorRawMark} = _ctx._cstRawChildren?.length ?? 0`,
|
|
7971
8297
|
`${ind(ctx)}const ${selectorTriviaMark} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
7972
8298
|
`${ind(ctx)}const ${selectorLogMark} = _ctx._triviaLog?.length ?? 0`,
|
|
8299
|
+
...selectorRootLogMark ? [`${ind(ctx)}const ${selectorRootLogMark} = _ctx._rootTriviaLog?.length ?? 0`] : [],
|
|
7973
8300
|
`${ind(ctx)}const ${selectorFieldMark} = _ctx._fields?.length ?? 0`,
|
|
7974
8301
|
`${ind(ctx)}const ${selectorErrorMark} = _ctx._errors?.length ?? 0`
|
|
7975
8302
|
] : [],
|
|
@@ -7989,16 +8316,18 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7989
8316
|
const mayError = mayRecordRecoveryError(parser3, !!ctx.recovery);
|
|
7990
8317
|
const errMark = mayError ? v(ctx, "_derr") : null;
|
|
7991
8318
|
const logMark = ctx.activeTrivia ? v(ctx, "_dlog") : null;
|
|
8319
|
+
const rootLogMark = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_drlog") : null;
|
|
7992
8320
|
if (usesRouted) {
|
|
7993
8321
|
stmts.push(
|
|
7994
8322
|
...routedV ? [`${ind(ctx)}const ${routedV} = _ctx._routed; _ctx._routed = { value: ${selector.valueVar}, span: { start: ${pos}, end: ${selector.endVar} } }`] : [],
|
|
7995
8323
|
...selectorLeafMark ? [
|
|
7996
|
-
`${ind(ctx)}if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${selectorLeafMark}) _ctx._cstLeaves.length = ${selectorLeafMark}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${selectorRawMark}) _ctx._cstRawChildren.length = ${selectorRawMark}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${selectorTriviaMark}) _ctx._cstTriviaLog.length = ${selectorTriviaMark}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${selectorLogMark}) _ctx._triviaLog.length = ${selectorLogMark}
|
|
8324
|
+
`${ind(ctx)}if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${selectorLeafMark}) _ctx._cstLeaves.length = ${selectorLeafMark}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${selectorRawMark}) _ctx._cstRawChildren.length = ${selectorRawMark}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${selectorTriviaMark}) _ctx._cstTriviaLog.length = ${selectorTriviaMark}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${selectorLogMark}) _ctx._triviaLog.length = ${selectorLogMark};${selectorRootLogMark ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${selectorRootLogMark}) _ctx._rootTriviaLog.length = ${selectorRootLogMark};` : ""} if (_ctx._fields && _ctx._fields.length !== ${selectorFieldMark}) _ctx._fields.length = ${selectorFieldMark}; if (_ctx._errors && _ctx._errors.length !== ${selectorErrorMark}) _ctx._errors.length = ${selectorErrorMark}`
|
|
7997
8325
|
] : []
|
|
7998
8326
|
);
|
|
7999
8327
|
}
|
|
8000
8328
|
if (errMark) stmts.push(`${ind(ctx)}const ${errMark} = _ctx._errors?.length ?? 0`);
|
|
8001
8329
|
if (logMark) stmts.push(`${ind(ctx)}const ${logMark} = _ctx._triviaLog?.length ?? 0`);
|
|
8330
|
+
if (rootLogMark) stmts.push(`${ind(ctx)}const ${rootLogMark} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
8002
8331
|
const savedRoutedLocal = ctx.routedLocal;
|
|
8003
8332
|
const savedNoHoist = ctx.noHoist;
|
|
8004
8333
|
if (usesRouted && !needsRoutedContext) {
|
|
@@ -8013,11 +8342,12 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
8013
8342
|
stmts.push(...coverageAttempt(ctx, coverageId, pos));
|
|
8014
8343
|
const errorRollback = errMark ? `if (_ctx._errors && _ctx._errors.length !== ${errMark}) _ctx._errors.length = ${errMark}; ` : "";
|
|
8015
8344
|
const logRollback = logMark ? `if (_ctx._triviaLog && _ctx._triviaLog.length !== ${logMark}) _ctx._triviaLog.length = ${logMark}; ` : "";
|
|
8345
|
+
const rootLogRollback = rootLogMark ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${rootLogMark}) _ctx._rootTriviaLog.length = ${rootLogMark}; ` : "";
|
|
8016
8346
|
const routedRollback = routedV ? `_ctx._routed = ${routedV}; ` : "";
|
|
8017
8347
|
const coverageFailure = coverageId === void 0 ? "" : `_ctx._grammarTrace?.write({ id: ${JSON.stringify(coverageId)}, phase: 'failure', offset: _ctx._fe }); `;
|
|
8018
8348
|
stmts.push(
|
|
8019
8349
|
...tail.stmts,
|
|
8020
|
-
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8350
|
+
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${rootLogRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8021
8351
|
...routedV ? [`${ind(ctx)}_ctx._routed = ${routedV}`] : [],
|
|
8022
8352
|
`${ind(ctx)}${outV} = ${valueMode === "tail" ? tail.valVar : `[${selector.valueVar}, ${tail.valVar}]`}`,
|
|
8023
8353
|
`${ind(ctx)}${outE} = ${tail.endVar}`,
|
|
@@ -8198,11 +8528,13 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8198
8528
|
const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
|
|
8199
8529
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
8200
8530
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
8531
|
+
const markRootLog = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_cmlrg") : null;
|
|
8201
8532
|
const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
|
|
8202
8533
|
const markErrors = armMayRecordError ? v(ctx, "_cme") : null;
|
|
8203
|
-
const captureRollback = markLeaves ? captureRestoreBody(markLeaves, markRaw, markTl, markLog, markFields) : "";
|
|
8534
|
+
const captureRollback = markLeaves ? captureRestoreBody(ctx, markLeaves, markRaw, markTl, markLog, markFields, markRootLog) : "";
|
|
8535
|
+
const rootRollback = markRootLog && !markLeaves ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}` : "";
|
|
8204
8536
|
const errorRollback = markErrors ? `if (_ctx._errors && _ctx._errors.length !== ${markErrors}) _ctx._errors.length = ${markErrors}` : "";
|
|
8205
|
-
const rollback = [captureRollback, errorRollback].filter(Boolean).join("; ");
|
|
8537
|
+
const rollback = [captureRollback, rootRollback, errorRollback].filter(Boolean).join("; ");
|
|
8206
8538
|
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
8207
8539
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
8208
8540
|
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
@@ -8217,6 +8549,7 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8217
8549
|
...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
|
|
8218
8550
|
);
|
|
8219
8551
|
}
|
|
8552
|
+
if (markRootLog) stmts.push(`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
8220
8553
|
if (markErrors) stmts.push(`${ind(ctx)}const ${markErrors} = _ctx._errors?.length ?? 0`);
|
|
8221
8554
|
const arm = emitFallible(p, ctx, pos, atStart);
|
|
8222
8555
|
const { stmts: armStmts, okVar, valVar, endVar } = arm;
|
|
@@ -8404,21 +8737,29 @@ function emitMany(def, ctx, pos) {
|
|
|
8404
8737
|
const markV = v(ctx, "_mk");
|
|
8405
8738
|
const markTl = v(ctx, "_mktl");
|
|
8406
8739
|
const markLog = v(ctx, "_mklg");
|
|
8740
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8407
8741
|
const npV = v(ctx, "_np");
|
|
8408
8742
|
stmts.push(
|
|
8409
8743
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8410
8744
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8411
8745
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8746
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8412
8747
|
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8413
8748
|
...emitLineTrack(ctx, curV, npV)
|
|
8414
8749
|
);
|
|
8415
8750
|
itemPos = npV;
|
|
8416
|
-
rollback = `if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}
|
|
8751
|
+
rollback = `if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog};${markRootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog};` : ""} `;
|
|
8417
8752
|
} else {
|
|
8418
8753
|
const trivFn = ensureTriviaFn(ctx);
|
|
8754
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8419
8755
|
const npV = v(ctx, "_np");
|
|
8420
|
-
stmts.push(
|
|
8756
|
+
stmts.push(
|
|
8757
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8758
|
+
`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8759
|
+
...emitLineTrack(ctx, curV, npV)
|
|
8760
|
+
);
|
|
8421
8761
|
itemPos = npV;
|
|
8762
|
+
rollback = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8422
8763
|
}
|
|
8423
8764
|
}
|
|
8424
8765
|
if (!ctx.recovery && !ctx.coverage && !failsAtStart(def.parser) && needsFirstSetGuard(def.parser)) {
|
|
@@ -8478,9 +8819,10 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8478
8819
|
const raw = v(ctx, "_atr");
|
|
8479
8820
|
const trivia2 = v(ctx, "_att");
|
|
8480
8821
|
const log = v(ctx, "_atg");
|
|
8822
|
+
const rootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_atrg") : null;
|
|
8481
8823
|
const fields = v(ctx, "_atf");
|
|
8482
8824
|
const errors = v(ctx, "_ate");
|
|
8483
|
-
const rollback = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${leaves}) _ctx._cstLeaves.length = ${leaves}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${raw}) _ctx._cstRawChildren.length = ${raw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${trivia2}) _ctx._cstTriviaLog.length = ${trivia2}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${log}) _ctx._triviaLog.length = ${log}
|
|
8825
|
+
const rollback = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${leaves}) _ctx._cstLeaves.length = ${leaves}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${raw}) _ctx._cstRawChildren.length = ${raw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${trivia2}) _ctx._cstTriviaLog.length = ${trivia2}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${log}) _ctx._triviaLog.length = ${log};${rootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${rootLog}) _ctx._rootTriviaLog.length = ${rootLog};` : ""} if (_ctx._fields && _ctx._fields.length !== ${fields}) _ctx._fields.length = ${fields}; if (_ctx._errors && _ctx._errors.length !== ${errors}) _ctx._errors.length = ${errors}`;
|
|
8484
8826
|
const traceId = ctx.coverage?.plan.attempts.get(p);
|
|
8485
8827
|
const traceRollback = traceId === void 0 ? "" : ` _ctx._grammarTrace?.write({ id: ${JSON.stringify(traceId)}, phase: 'rollback', offset: ${pos} });`;
|
|
8486
8828
|
const preGuard = [];
|
|
@@ -8496,7 +8838,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8496
8838
|
return {
|
|
8497
8839
|
stmts: [
|
|
8498
8840
|
...preGuard,
|
|
8499
|
-
`${ind(ctx)}const ${leaves} = _ctx._cstLeaves?.length ?? 0, ${raw} = _ctx._cstRawChildren?.length ?? 0, ${trivia2} = _ctx._cstTriviaLog?.length ?? 0, ${log} = _ctx._triviaLog?.length ?? 0, ${fields} = _ctx._fields?.length ?? 0, ${errors} = _ctx._errors?.length ?? 0`,
|
|
8841
|
+
`${ind(ctx)}const ${leaves} = _ctx._cstLeaves?.length ?? 0, ${raw} = _ctx._cstRawChildren?.length ?? 0, ${trivia2} = _ctx._cstTriviaLog?.length ?? 0, ${log} = _ctx._triviaLog?.length ?? 0${rootLog ? `, ${rootLog} = _ctx._rootTriviaLog?.length ?? 0` : ""}, ${fields} = _ctx._fields?.length ?? 0, ${errors} = _ctx._errors?.length ?? 0`,
|
|
8500
8842
|
...inner.stmts,
|
|
8501
8843
|
...emitIfFail(ctx, `!${inner.okVar}`, `{ ${rollback};${traceRollback}${inner.mayCommit ? ` if (_ctx._fc) ${committedFailBody(ctx)};` : ""} _ctx._fe = ${pos}; ${propagateFailBody(ctx)} }`)
|
|
8502
8844
|
],
|
|
@@ -8538,16 +8880,17 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8538
8880
|
const itemFailBreak = (sepEndVar, sepRb, postSepRb) => def.trailing === void 0 ? `${sepRb}break` : `${postSepRb}${curV} = ${sepEndVar}; break`;
|
|
8539
8881
|
const postSepMarks = () => {
|
|
8540
8882
|
if (def.trailing === void 0 || !ctx.capturing) return { decl: [], rb: "" };
|
|
8541
|
-
const lv = v(ctx, "_tlv"), rw = v(ctx, "_trw"), tl = v(ctx, "_ttl"), lg = v(ctx, "_tlg"), fl = v(ctx, "_tlf");
|
|
8883
|
+
const lv = v(ctx, "_tlv"), rw = v(ctx, "_trw"), tl = v(ctx, "_ttl"), lg = v(ctx, "_tlg"), rlg = hasSelectedRootTrivia(ctx) ? v(ctx, "_trlg") : null, fl = v(ctx, "_tlf");
|
|
8542
8884
|
return {
|
|
8543
8885
|
decl: [
|
|
8544
8886
|
`${ind(ctx)}const ${lv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8545
8887
|
`${ind(ctx)}const ${rw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8546
8888
|
`${ind(ctx)}const ${tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8547
8889
|
`${ind(ctx)}const ${lg} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8890
|
+
...rlg ? [`${ind(ctx)}const ${rlg} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8548
8891
|
`${ind(ctx)}const ${fl} = _ctx._fields ? _ctx._fields.length : 0`
|
|
8549
8892
|
],
|
|
8550
|
-
rb: `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${lv}) _ctx._cstLeaves.length = ${lv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${rw}) _ctx._cstRawChildren.length = ${rw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${tl}) _ctx._cstTriviaLog.length = ${tl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${lg}) _ctx._triviaLog.length = ${lg}
|
|
8893
|
+
rb: `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${lv}) _ctx._cstLeaves.length = ${lv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${rw}) _ctx._cstRawChildren.length = ${rw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${tl}) _ctx._cstTriviaLog.length = ${tl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${lg}) _ctx._triviaLog.length = ${lg};${rlg ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${rlg}) _ctx._rootTriviaLog.length = ${rlg};` : ""} if (_ctx._fields && _ctx._fields.length !== ${fl}) _ctx._fields.length = ${fl}; `
|
|
8551
8894
|
};
|
|
8552
8895
|
};
|
|
8553
8896
|
if (rec) {
|
|
@@ -8585,6 +8928,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8585
8928
|
const markV = v(ctx, "_mk");
|
|
8586
8929
|
const markTl = v(ctx, "_mktl");
|
|
8587
8930
|
const markLog = v(ctx, "_mklg");
|
|
8931
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8588
8932
|
const markLv = v(ctx, "_mklv");
|
|
8589
8933
|
const markFld = v(ctx, "_mkf");
|
|
8590
8934
|
const spV = v(ctx, "_sp");
|
|
@@ -8592,13 +8936,14 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8592
8936
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8593
8937
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8594
8938
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8939
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8595
8940
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8596
8941
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8597
8942
|
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8598
8943
|
...emitLineTrack(ctx, curV, spV)
|
|
8599
8944
|
);
|
|
8600
8945
|
sepAtPos = spV;
|
|
8601
|
-
const rollbackToSep = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${markLv}) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}
|
|
8946
|
+
const rollbackToSep = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${markLv}) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog};${markRootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog};` : ""} if (_ctx._fields && _ctx._fields.length !== ${markFld}) _ctx._fields.length = ${markFld}; `;
|
|
8602
8947
|
const sep = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8603
8948
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep;
|
|
8604
8949
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
@@ -8616,19 +8961,30 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8616
8961
|
);
|
|
8617
8962
|
} else {
|
|
8618
8963
|
const trivFn = ensureTriviaFn(ctx);
|
|
8964
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8619
8965
|
const spV = v(ctx, "_sp");
|
|
8620
|
-
stmts.push(
|
|
8966
|
+
stmts.push(
|
|
8967
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8968
|
+
`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8969
|
+
...emitLineTrack(ctx, curV, spV)
|
|
8970
|
+
);
|
|
8621
8971
|
sepAtPos = spV;
|
|
8622
8972
|
const sep = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8623
8973
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep;
|
|
8624
|
-
|
|
8974
|
+
const rollbackToSep = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8975
|
+
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
8976
|
+
const postRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_psrlg") : null;
|
|
8625
8977
|
const npV = v(ctx, "_np");
|
|
8626
|
-
stmts.push(
|
|
8978
|
+
stmts.push(
|
|
8979
|
+
...postRootLog ? [`${ind(ctx)}const ${postRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8980
|
+
`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8981
|
+
...emitLineTrack(ctx, sepEnd, npV)
|
|
8982
|
+
);
|
|
8627
8983
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8628
8984
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8629
8985
|
stmts.push(
|
|
8630
8986
|
...nextStmts,
|
|
8631
|
-
...failItem(nextOk, next.mayCommit, npV, itemFailBreak(sepEnd,
|
|
8987
|
+
...failItem(nextOk, next.mayCommit, npV, itemFailBreak(sepEnd, rollbackToSep, postRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${postRootLog}) _ctx._rootTriviaLog.length = ${postRootLog}; ` : "")),
|
|
8632
8988
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
8633
8989
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
8634
8990
|
);
|
|
@@ -8723,6 +9079,7 @@ function emitNot(def, ctx, pos) {
|
|
|
8723
9079
|
const raw = sinksLive ? v(ctx, "_ntr") : null;
|
|
8724
9080
|
const tl = sinksLive ? v(ctx, "_ntt") : null;
|
|
8725
9081
|
const log = sinksLive ? v(ctx, "_ntg") : null;
|
|
9082
|
+
const rootLog = sinksLive && hasSelectedRootTrivia(ctx) ? v(ctx, "_ntrg") : null;
|
|
8726
9083
|
const fields = sinksLive ? v(ctx, "_ntf") : null;
|
|
8727
9084
|
const errors = sinksLive ? v(ctx, "_nte") : null;
|
|
8728
9085
|
const { stmts, okVar } = emitFallible(def.parser, ctx, pos, true);
|
|
@@ -8730,11 +9087,11 @@ function emitNot(def, ctx, pos) {
|
|
|
8730
9087
|
return {
|
|
8731
9088
|
stmts: [
|
|
8732
9089
|
...sinksLive ? [
|
|
8733
|
-
`${ind(ctx)}const ${leaves} = _ctx._cstLeaves?.length ?? 0, ${raw} = _ctx._cstRawChildren?.length ?? 0, ${tl} = _ctx._cstTriviaLog?.length ?? 0, ${log} = _ctx._triviaLog?.length ?? 0, ${fields} = _ctx._fields?.length ?? 0, ${errors} = _ctx._errors?.length ?? 0`
|
|
9090
|
+
`${ind(ctx)}const ${leaves} = _ctx._cstLeaves?.length ?? 0, ${raw} = _ctx._cstRawChildren?.length ?? 0, ${tl} = _ctx._cstTriviaLog?.length ?? 0, ${log} = _ctx._triviaLog?.length ?? 0${rootLog ? `, ${rootLog} = _ctx._rootTriviaLog?.length ?? 0` : ""}, ${fields} = _ctx._fields?.length ?? 0, ${errors} = _ctx._errors?.length ?? 0`
|
|
8734
9091
|
] : [],
|
|
8735
9092
|
...stmts,
|
|
8736
9093
|
...sinksLive ? [
|
|
8737
|
-
`${ind(ctx)}if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${leaves}) _ctx._cstLeaves.length = ${leaves}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${raw}) _ctx._cstRawChildren.length = ${raw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${tl}) _ctx._cstTriviaLog.length = ${tl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${log}) _ctx._triviaLog.length = ${log}
|
|
9094
|
+
`${ind(ctx)}if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${leaves}) _ctx._cstLeaves.length = ${leaves}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${raw}) _ctx._cstRawChildren.length = ${raw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${tl}) _ctx._cstTriviaLog.length = ${tl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${log}) _ctx._triviaLog.length = ${log};${rootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${rootLog}) _ctx._rootTriviaLog.length = ${rootLog};` : ""} if (_ctx._fields && _ctx._fields.length !== ${fields}) _ctx._fields.length = ${fields}; if (_ctx._errors && _ctx._errors.length !== ${errors}) _ctx._errors.length = ${errors}`
|
|
8738
9095
|
] : [],
|
|
8739
9096
|
...emitIfFail(ctx, okVar, failBody(ctx, label2, pos))
|
|
8740
9097
|
],
|
|
@@ -8870,16 +9227,17 @@ function emitToken(def, ctx, pos) {
|
|
|
8870
9227
|
const sk = v(ctx, "_tokKinds");
|
|
8871
9228
|
const stl = v(ctx, "_tokTl");
|
|
8872
9229
|
const sol = v(ctx, "_tokLog");
|
|
9230
|
+
const srl = hasSelectedRootTrivia(ctx) ? v(ctx, "_tokRootLog") : null;
|
|
8873
9231
|
const sb = v(ctx, "_tokBuf");
|
|
8874
9232
|
const valV = v(ctx, "_tok");
|
|
8875
9233
|
return {
|
|
8876
9234
|
stmts: [
|
|
8877
|
-
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${sv} = _ctx.trivia, ${sk} = _ctx.triviaKindLabels, ${stl} = _ctx._cstTriviaLog, ${sol} = _ctx._triviaLog, ${sb} = _ctx._cstBuf`,
|
|
8878
|
-
`${i}_ctx.trivia = undefined; _ctx.triviaKindLabels = undefined; _ctx._cstChildren = undefined; _ctx._cstLeaves = undefined; _ctx._cstRawChildren = undefined; _ctx._cstTriviaLog = undefined; _ctx._triviaLog = undefined; _ctx._cstBuf = undefined`,
|
|
9235
|
+
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${sv} = _ctx.trivia, ${sk} = _ctx.triviaKindLabels, ${stl} = _ctx._cstTriviaLog, ${sol} = _ctx._triviaLog${srl ? `, ${srl} = _ctx._rootTriviaLog` : ""}, ${sb} = _ctx._cstBuf`,
|
|
9236
|
+
`${i}_ctx.trivia = undefined; _ctx.triviaKindLabels = undefined; _ctx._cstChildren = undefined; _ctx._cstLeaves = undefined; _ctx._cstRawChildren = undefined; _ctx._cstTriviaLog = undefined; _ctx._triviaLog = undefined;${srl ? " _ctx._rootTriviaLog = undefined;" : ""} _ctx._cstBuf = undefined`,
|
|
8879
9237
|
`${i}try {`,
|
|
8880
9238
|
...reindentStmts(inner.stmts, ctx.indent + 1).map((stmt) => stmt.replace(/^(\s*)(?:const|let)\s+/, "$1var ")),
|
|
8881
9239
|
`${i}} finally {`,
|
|
8882
|
-
`${i} _ctx.trivia = ${sv}; _ctx.triviaKindLabels = ${sk}; _ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx._cstTriviaLog = ${stl}; _ctx._triviaLog = ${sol}
|
|
9240
|
+
`${i} _ctx.trivia = ${sv}; _ctx.triviaKindLabels = ${sk}; _ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx._cstTriviaLog = ${stl}; _ctx._triviaLog = ${sol};${srl ? ` _ctx._rootTriviaLog = ${srl};` : ""} _ctx._cstBuf = ${sb}`,
|
|
8883
9241
|
`${i}}`,
|
|
8884
9242
|
...emitIfFail(ctx, `!${inner.okVar}`, propagateFailBody(ctx)),
|
|
8885
9243
|
`${i}const ${valV} = input.slice(${pos}, ${inner.endVar})`,
|
|
@@ -9358,6 +9716,8 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9358
9716
|
case "grammar": {
|
|
9359
9717
|
const savedTrivia = ctx.activeTrivia;
|
|
9360
9718
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
9719
|
+
const opaqueRootCapture = hasSelectedRootTrivia(ctx) && def.rootCapture === "opaque";
|
|
9720
|
+
const strictScopeCheck = hasSelectedRootTrivia(ctx) && def.triviaParser !== void 0 && !def.triviaParser._meta.rootTriviaClassified && !opaqueRootCapture ? `${ind(ctx)}if (_ctx._rootTriviaStrictScopes) throw new TypeError(${JSON.stringify("parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'.")})` : void 0;
|
|
9361
9721
|
if (def.clearTrivia) {
|
|
9362
9722
|
ctx.activeTrivia = void 0;
|
|
9363
9723
|
ctx.triviaKindLabels = void 0;
|
|
@@ -9368,13 +9728,38 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9368
9728
|
}
|
|
9369
9729
|
}
|
|
9370
9730
|
const savedCapture = def.captureTrivia ? v(ctx, "_gcap") : null;
|
|
9731
|
+
const savedRootCapture = opaqueRootCapture ? v(ctx, "_grtc") : null;
|
|
9732
|
+
const opaqueValue = opaqueRootCapture ? v(ctx, "_grtv") : null;
|
|
9733
|
+
const opaqueEnd = opaqueRootCapture ? v(ctx, "_grte") : null;
|
|
9734
|
+
if (opaqueRootCapture) ctx.indent++;
|
|
9371
9735
|
const r = emit(def.parser, ctx, pos);
|
|
9736
|
+
if (opaqueRootCapture) ctx.indent--;
|
|
9372
9737
|
ctx.activeTrivia = savedTrivia;
|
|
9373
9738
|
ctx.triviaKindLabels = savedKindLabels;
|
|
9374
|
-
if (!savedCapture) return r
|
|
9739
|
+
if (!savedCapture && !opaqueRootCapture) return strictScopeCheck === void 0 ? r : {
|
|
9740
|
+
...r,
|
|
9741
|
+
stmts: [strictScopeCheck, ...r.stmts]
|
|
9742
|
+
};
|
|
9743
|
+
if (opaqueRootCapture) {
|
|
9744
|
+
return {
|
|
9745
|
+
stmts: [
|
|
9746
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9747
|
+
`${ind(ctx)}let ${opaqueValue}, ${opaqueEnd}`,
|
|
9748
|
+
`${ind(ctx)}${savedCapture ? `const ${savedCapture} = _ctx.captureTrivia; ` : ""}const ${savedRootCapture} = _ctx._rootTriviaCapture; _ctx._rootTriviaCapture = false`,
|
|
9749
|
+
`${ind(ctx)}try {`,
|
|
9750
|
+
...savedCapture ? [`${ind(ctx)} _ctx.captureTrivia = true`] : [],
|
|
9751
|
+
...r.stmts,
|
|
9752
|
+
`${ind(ctx)} ${opaqueValue} = ${r.valueVar}; ${opaqueEnd} = ${r.endVar}`,
|
|
9753
|
+
`${ind(ctx)}} finally { ${savedCapture ? `_ctx.captureTrivia = ${savedCapture}; ` : ""}_ctx._rootTriviaCapture = ${savedRootCapture} }`
|
|
9754
|
+
],
|
|
9755
|
+
valueVar: opaqueValue,
|
|
9756
|
+
endVar: opaqueEnd
|
|
9757
|
+
};
|
|
9758
|
+
}
|
|
9375
9759
|
return {
|
|
9376
9760
|
...r,
|
|
9377
9761
|
stmts: [
|
|
9762
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9378
9763
|
`${ind(ctx)}const ${savedCapture} = _ctx.captureTrivia; _ctx.captureTrivia = true`,
|
|
9379
9764
|
...r.stmts,
|
|
9380
9765
|
`${ind(ctx)}_ctx.captureTrivia = ${savedCapture}`
|
|
@@ -9859,6 +10244,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9859
10244
|
runDuplicationDiagnostic(combinator, opts?.duplication);
|
|
9860
10245
|
markUnusedValues(combinator);
|
|
9861
10246
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
10247
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || combinator._meta.rootTriviaClassified === true;
|
|
9862
10248
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9863
10249
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9864
10250
|
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
@@ -9885,7 +10271,11 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9885
10271
|
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9886
10272
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9887
10273
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9888
|
-
...
|
|
10274
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10275
|
+
...grammarTrivia ? {
|
|
10276
|
+
activeTrivia: grammarTrivia,
|
|
10277
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10278
|
+
} : {},
|
|
9889
10279
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
9890
10280
|
};
|
|
9891
10281
|
const r = emit(combinator, ctx, "_pos");
|
|
@@ -10033,10 +10423,11 @@ function assertRuleName(name) {
|
|
|
10033
10423
|
);
|
|
10034
10424
|
}
|
|
10035
10425
|
}
|
|
10036
|
-
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels) {
|
|
10037
|
-
const labels = rule._meta.triviaKindLabels
|
|
10038
|
-
|
|
10039
|
-
|
|
10426
|
+
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels, ambientRootTriviaClassified) {
|
|
10427
|
+
const labels = ambientTriviaKindLabels ?? rule._meta.triviaKindLabels;
|
|
10428
|
+
const classified = ambientRootTriviaClassified ?? rule._meta.rootTriviaClassified;
|
|
10429
|
+
if (labels === void 0 && classified === void 0) return fnSource;
|
|
10430
|
+
return `Object.assign(${fnSource}, { _meta: {${labels === void 0 ? "" : ` triviaKindLabels: ${JSON.stringify(labels)},`}${classified === void 0 ? "" : " rootTriviaClassified: true,"} } })`;
|
|
10040
10431
|
}
|
|
10041
10432
|
function compileLinkable(ruleMapArg, ns, opts) {
|
|
10042
10433
|
if (!ns) throw new Error("compileLinkable: ns must be a non-empty namespace");
|
|
@@ -10044,6 +10435,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10044
10435
|
if (opts?.duplication !== void 0) runDuplicationDiagnosticRules(ruleMapArg, opts.duplication);
|
|
10045
10436
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
10046
10437
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
10438
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || ruleMapArg.some(([, rule]) => rule._meta.rootTriviaClassified === true);
|
|
10047
10439
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
10048
10440
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10049
10441
|
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -10087,7 +10479,11 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10087
10479
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10088
10480
|
ns,
|
|
10089
10481
|
deferFirstSetRefs: true,
|
|
10090
|
-
...
|
|
10482
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10483
|
+
...grammarTrivia ? {
|
|
10484
|
+
activeTrivia: grammarTrivia,
|
|
10485
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10486
|
+
} : {},
|
|
10091
10487
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
10092
10488
|
};
|
|
10093
10489
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -10219,7 +10615,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10219
10615
|
...r.stmts,
|
|
10220
10616
|
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
10221
10617
|
`}`
|
|
10222
|
-
].join("\n"), ctx.triviaKindLabels));
|
|
10618
|
+
].join("\n"), ctx.triviaKindLabels, ctx.rootTriviaClassified));
|
|
10223
10619
|
}
|
|
10224
10620
|
const firstSets = /* @__PURE__ */ new Map();
|
|
10225
10621
|
const firstSetRecipes = /* @__PURE__ */ new Map();
|
|
@@ -10568,6 +10964,7 @@ function evalRuleMapIR(ir) {
|
|
|
10568
10964
|
"transform",
|
|
10569
10965
|
"skip",
|
|
10570
10966
|
"trivia",
|
|
10967
|
+
"classifiedTrivia",
|
|
10571
10968
|
"label",
|
|
10572
10969
|
"field",
|
|
10573
10970
|
"expect",
|
|
@@ -10608,6 +11005,7 @@ function evalRuleMapIR(ir) {
|
|
|
10608
11005
|
transform,
|
|
10609
11006
|
skip,
|
|
10610
11007
|
trivia,
|
|
11008
|
+
classifiedTrivia,
|
|
10611
11009
|
label,
|
|
10612
11010
|
field,
|
|
10613
11011
|
expect,
|
|
@@ -10854,8 +11252,11 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10854
11252
|
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
10855
11253
|
}
|
|
10856
11254
|
case "grammar": {
|
|
10857
|
-
const
|
|
10858
|
-
|
|
11255
|
+
const classified = def.triviaParser?._meta.rootTriviaClassified === true;
|
|
11256
|
+
const spec = classified && def.triviaParser ? analyzeLabeledTrivia(def.triviaParser) : null;
|
|
11257
|
+
if (classified && !spec) throw new Unserializable("classified trivia without labeled arms");
|
|
11258
|
+
const trivia2 = def.clearTrivia ? "null" : spec ? `classifiedTrivia({ ${spec.arms.map((arm) => `${JSON.stringify(arm.label)}: ${kid(arm.parser)}`).join(", ")} })` : def.triviaParser ? kid(def.triviaParser) : "undefined";
|
|
11259
|
+
return `parser({ trivia: ${trivia2}${def.captureTrivia ? ", captureTrivia: true" : ""}${def.rootCapture ? `, rootCapture: ${JSON.stringify(def.rootCapture)}` : ""}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(def.parser)})`;
|
|
10859
11260
|
}
|
|
10860
11261
|
case "withCtx": {
|
|
10861
11262
|
if (def.extraSrc === void 0) throw new Unserializable("withCtx without extraSrc");
|
|
@@ -11752,157 +12153,26 @@ function parseDoc(registry, rootRule, input, opts = {}) {
|
|
|
11752
12153
|
return new ParseDocImpl(registry, rootRule, opts, { abs: null }, [fail], null, input);
|
|
11753
12154
|
}
|
|
11754
12155
|
|
|
11755
|
-
// src/cst/trivia-entries.ts
|
|
11756
|
-
var EMPTY_INDICES = Object.freeze([]);
|
|
11757
|
-
var EMPTY_GAPS = Object.freeze([]);
|
|
11758
|
-
function entryOffset(i, stride) {
|
|
11759
|
-
return i * stride;
|
|
11760
|
-
}
|
|
11761
|
-
function triviaEntries(log, labels, opts) {
|
|
11762
|
-
const baseStride = opts?.nodeLog ? 3 : 2;
|
|
11763
|
-
const stride = labels ? baseStride + 1 : baseStride;
|
|
11764
|
-
const length = Math.floor(log.length / stride);
|
|
11765
|
-
return {
|
|
11766
|
-
length,
|
|
11767
|
-
labels,
|
|
11768
|
-
stride,
|
|
11769
|
-
start(i) {
|
|
11770
|
-
return log[entryOffset(i, stride)];
|
|
11771
|
-
},
|
|
11772
|
-
end(i) {
|
|
11773
|
-
return log[entryOffset(i, stride) + 1];
|
|
11774
|
-
},
|
|
11775
|
-
insertIndex(i) {
|
|
11776
|
-
return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
|
|
11777
|
-
},
|
|
11778
|
-
kindIndex(i) {
|
|
11779
|
-
if (!labels) return void 0;
|
|
11780
|
-
return log[entryOffset(i, stride) + baseStride];
|
|
11781
|
-
},
|
|
11782
|
-
kind(i) {
|
|
11783
|
-
const ki = labels ? log[entryOffset(i, stride) + baseStride] : void 0;
|
|
11784
|
-
return ki !== void 0 ? labels[ki] : void 0;
|
|
11785
|
-
},
|
|
11786
|
-
text(i, input) {
|
|
11787
|
-
const s = log[entryOffset(i, stride)];
|
|
11788
|
-
const e = log[entryOffset(i, stride) + 1];
|
|
11789
|
-
return input.slice(s, e);
|
|
11790
|
-
}
|
|
11791
|
-
};
|
|
11792
|
-
}
|
|
11793
|
-
function appendEntryRange(map, key, first, last) {
|
|
11794
|
-
let indices = map.get(key);
|
|
11795
|
-
if (!indices) {
|
|
11796
|
-
indices = [];
|
|
11797
|
-
map.set(key, indices);
|
|
11798
|
-
}
|
|
11799
|
-
for (let i = first; i <= last; i++) indices.push(i);
|
|
11800
|
-
}
|
|
11801
|
-
function buildGap(entries, start, end, first, last) {
|
|
11802
|
-
const entryIndices = [];
|
|
11803
|
-
for (let i = first; i <= last; i++) entryIndices.push(i);
|
|
11804
|
-
return {
|
|
11805
|
-
start,
|
|
11806
|
-
end,
|
|
11807
|
-
entryIndices,
|
|
11808
|
-
hasKind(kind) {
|
|
11809
|
-
for (const i of entryIndices) {
|
|
11810
|
-
if (entries.kind(i) === kind) return true;
|
|
11811
|
-
}
|
|
11812
|
-
return false;
|
|
11813
|
-
},
|
|
11814
|
-
text(input) {
|
|
11815
|
-
return input.slice(start, end);
|
|
11816
|
-
}
|
|
11817
|
-
};
|
|
11818
|
-
}
|
|
11819
|
-
function buildRootMaps(entries) {
|
|
11820
|
-
const before = /* @__PURE__ */ new Map();
|
|
11821
|
-
const after = /* @__PURE__ */ new Map();
|
|
11822
|
-
const beforeGaps = /* @__PURE__ */ new Map();
|
|
11823
|
-
const afterGaps = /* @__PURE__ */ new Map();
|
|
11824
|
-
const gaps = [];
|
|
11825
|
-
if (entries.length === 0) return { before, after, beforeGaps, afterGaps, gaps };
|
|
11826
|
-
const appendGap = (first2, last, start2, end2) => {
|
|
11827
|
-
const gap = buildGap(entries, start2, end2, first2, last);
|
|
11828
|
-
gaps.push(gap);
|
|
11829
|
-
afterGaps.set(start2, gap);
|
|
11830
|
-
beforeGaps.set(end2, gap);
|
|
11831
|
-
appendEntryRange(after, start2, first2, last);
|
|
11832
|
-
appendEntryRange(before, end2, first2, last);
|
|
11833
|
-
};
|
|
11834
|
-
let first = 0;
|
|
11835
|
-
let start = entries.start(0);
|
|
11836
|
-
let end = entries.end(0);
|
|
11837
|
-
for (let i = 1; i < entries.length; i++) {
|
|
11838
|
-
const nextStart = entries.start(i);
|
|
11839
|
-
const nextEnd = entries.end(i);
|
|
11840
|
-
if (nextStart === end) {
|
|
11841
|
-
end = nextEnd;
|
|
11842
|
-
continue;
|
|
11843
|
-
}
|
|
11844
|
-
appendGap(first, i - 1, start, end);
|
|
11845
|
-
first = i;
|
|
11846
|
-
start = nextStart;
|
|
11847
|
-
end = nextEnd;
|
|
11848
|
-
}
|
|
11849
|
-
appendGap(first, entries.length - 1, start, end);
|
|
11850
|
-
return { before, after, beforeGaps, afterGaps, gaps };
|
|
11851
|
-
}
|
|
11852
|
-
function buildRootTriviaIndex(log, labels) {
|
|
11853
|
-
const entries = triviaEntries(log, labels);
|
|
11854
|
-
let maps;
|
|
11855
|
-
const getMaps = () => {
|
|
11856
|
-
maps ??= buildRootMaps(entries);
|
|
11857
|
-
return maps;
|
|
11858
|
-
};
|
|
11859
|
-
return {
|
|
11860
|
-
entries,
|
|
11861
|
-
labels,
|
|
11862
|
-
get before() {
|
|
11863
|
-
return getMaps().before;
|
|
11864
|
-
},
|
|
11865
|
-
get after() {
|
|
11866
|
-
return getMaps().after;
|
|
11867
|
-
},
|
|
11868
|
-
entryIndicesBefore(offset) {
|
|
11869
|
-
return getMaps().before.get(offset) ?? EMPTY_INDICES;
|
|
11870
|
-
},
|
|
11871
|
-
entryIndicesAfter(offset) {
|
|
11872
|
-
return getMaps().after.get(offset) ?? EMPTY_INDICES;
|
|
11873
|
-
},
|
|
11874
|
-
gapBefore(offset) {
|
|
11875
|
-
return getMaps().beforeGaps.get(offset);
|
|
11876
|
-
},
|
|
11877
|
-
gapAfter(offset) {
|
|
11878
|
-
return getMaps().afterGaps.get(offset);
|
|
11879
|
-
},
|
|
11880
|
-
gaps() {
|
|
11881
|
-
return getMaps().gaps;
|
|
11882
|
-
},
|
|
11883
|
-
gapsWithKind(kind) {
|
|
11884
|
-
const kinds = typeof kind === "string" ? [kind] : kind;
|
|
11885
|
-
const matches2 = [];
|
|
11886
|
-
for (const gap of getMaps().gaps) {
|
|
11887
|
-
for (const k of kinds) {
|
|
11888
|
-
if (gap.hasKind(k)) {
|
|
11889
|
-
matches2.push(gap);
|
|
11890
|
-
break;
|
|
11891
|
-
}
|
|
11892
|
-
}
|
|
11893
|
-
}
|
|
11894
|
-
return matches2.length === 0 ? EMPTY_GAPS : matches2;
|
|
11895
|
-
}
|
|
11896
|
-
};
|
|
11897
|
-
}
|
|
11898
|
-
|
|
11899
12156
|
// src/functional/run.ts
|
|
11900
12157
|
var invoke = (r, input, pos, ctx) => typeof r === "function" ? r(input, pos, ctx) : r.parse(input, pos, ctx);
|
|
11901
12158
|
function triviaKindLabelsFromRunnable(r) {
|
|
11902
12159
|
if (!r) return void 0;
|
|
11903
12160
|
if (typeof r === "function") return r._meta?.triviaKindLabels;
|
|
11904
12161
|
const grammarTrivia = r._meta.grammarTrivia;
|
|
11905
|
-
return
|
|
12162
|
+
return grammarTrivia?._meta.triviaKindLabels ?? r._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
|
|
12163
|
+
}
|
|
12164
|
+
function rootTriviaClassifiedFromRunnable(r) {
|
|
12165
|
+
if (!r) return false;
|
|
12166
|
+
if (typeof r === "function") return r._meta?.rootTriviaClassified === true;
|
|
12167
|
+
const grammarTrivia = r._meta.grammarTrivia;
|
|
12168
|
+
return grammarTrivia?._meta.rootTriviaClassified === true || r._meta.rootTriviaClassified === true;
|
|
12169
|
+
}
|
|
12170
|
+
function makeSelectedRootLabelIndex(labels) {
|
|
12171
|
+
const index = /* @__PURE__ */ Object.create(null);
|
|
12172
|
+
for (let i = 0; i < labels.length; i++) {
|
|
12173
|
+
if (index[labels[i]] === void 0) index[labels[i]] = i;
|
|
12174
|
+
}
|
|
12175
|
+
return index;
|
|
11906
12176
|
}
|
|
11907
12177
|
function runOnce(entry, input, options, phase, profileState) {
|
|
11908
12178
|
if (typeof entry !== "function" && typeof entry?.parse !== "function") {
|
|
@@ -11910,13 +12180,31 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
11910
12180
|
`run(): start production is ${entry === null ? "null" : typeof entry}, not a rule \u2014 the requested grammar rule does not exist (check the rule name).`
|
|
11911
12181
|
);
|
|
11912
12182
|
}
|
|
11913
|
-
const
|
|
12183
|
+
const rootTriviaSelection = options.rootTrivia?.select;
|
|
12184
|
+
const captureRootTrivia = rootTriviaSelection !== void 0 && rootTriviaSelection.length > 0;
|
|
12185
|
+
const selectedRootLog = captureRootTrivia ? [] : void 0;
|
|
12186
|
+
const selectedRootLabelIndex = captureRootTrivia ? makeSelectedRootLabelIndex(rootTriviaSelection) : void 0;
|
|
11914
12187
|
const errors = [];
|
|
11915
12188
|
const profile = profileState ?? (phase === void 0 ? void 0 : { phase, nodes: 0, childSlots: 0, rawSlots: 0, triviaSlots: 0, fieldSlots: 0, hostCalls: 0 });
|
|
11916
12189
|
const skipGlobalSinks = phase === "recognizer" || phase === "capture";
|
|
11917
12190
|
const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
|
|
11918
12191
|
const grammarScanSkip = typeof entry !== "function" ? entry._meta.grammarScanSkip : void 0;
|
|
11919
12192
|
const triviaKindLabels = triviaKindLabelsFromRunnable(entry) ?? triviaKindLabelsFromRunnable(options.trivia);
|
|
12193
|
+
if (captureRootTrivia && triviaKindLabels === void 0) {
|
|
12194
|
+
throw new TypeError("run(): rootTrivia.select requires labeled grammar trivia.");
|
|
12195
|
+
}
|
|
12196
|
+
if (captureRootTrivia) {
|
|
12197
|
+
for (const label2 of rootTriviaSelection) {
|
|
12198
|
+
if (!triviaKindLabels.includes(label2)) {
|
|
12199
|
+
throw new TypeError(`run(): rootTrivia.select contains unknown trivia label ${JSON.stringify(label2)}.`);
|
|
12200
|
+
}
|
|
12201
|
+
}
|
|
12202
|
+
}
|
|
12203
|
+
if (captureRootTrivia && !rootTriviaClassifiedFromRunnable(entry) && !rootTriviaClassifiedFromRunnable(options.trivia)) {
|
|
12204
|
+
throw new TypeError(
|
|
12205
|
+
"run(): rootTrivia.select requires classifiedTrivia() at the root."
|
|
12206
|
+
);
|
|
12207
|
+
}
|
|
11920
12208
|
const stamped = entry;
|
|
11921
12209
|
assertHostModeCompatible(
|
|
11922
12210
|
typeof entry === "function" ? stamped[FUSED_HOST_MODE] ?? "ast" : entry._meta.grammarHostMode ?? "ast",
|
|
@@ -11925,7 +12213,15 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
11925
12213
|
);
|
|
11926
12214
|
const ctx = {
|
|
11927
12215
|
trackLines: false,
|
|
11928
|
-
...skipGlobalSinks ? { _pmProfile: profile } : {
|
|
12216
|
+
...skipGlobalSinks ? { _pmProfile: profile } : {
|
|
12217
|
+
...captureRootTrivia ? {
|
|
12218
|
+
_rootTriviaLog: selectedRootLog,
|
|
12219
|
+
_rootTriviaKindIndex: selectedRootLabelIndex,
|
|
12220
|
+
_rootTriviaStrictScopes: true
|
|
12221
|
+
} : {},
|
|
12222
|
+
_errors: errors,
|
|
12223
|
+
...profile === void 0 ? {} : { _pmProfile: profile }
|
|
12224
|
+
},
|
|
11929
12225
|
build: options.build,
|
|
11930
12226
|
state: options.state,
|
|
11931
12227
|
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...triviaKindLabels ? { triviaKindLabels } : {} } : triviaKindLabels ? { triviaKindLabels } : {},
|
|
@@ -11950,9 +12246,13 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
11950
12246
|
span: r.span ?? { start: 0, end: 0 },
|
|
11951
12247
|
expected: r.ok ? [] : r.expected ?? [],
|
|
11952
12248
|
errors,
|
|
11953
|
-
|
|
11954
|
-
|
|
11955
|
-
|
|
12249
|
+
...selectedRootLog !== void 0 && selectedRootLog.length > 0 ? {
|
|
12250
|
+
rootTrivia: {
|
|
12251
|
+
rows: selectedRootLog,
|
|
12252
|
+
select: rootTriviaSelection,
|
|
12253
|
+
index: buildRootTriviaIndex(selectedRootLog, rootTriviaSelection)
|
|
12254
|
+
}
|
|
12255
|
+
} : {},
|
|
11956
12256
|
unconsumedFrom
|
|
11957
12257
|
};
|
|
11958
12258
|
}
|
|
@@ -12638,6 +12938,7 @@ export {
|
|
|
12638
12938
|
buildTriviaIndex,
|
|
12639
12939
|
charClassMembers,
|
|
12640
12940
|
choice,
|
|
12941
|
+
classifiedTrivia,
|
|
12641
12942
|
collectLeafSlots,
|
|
12642
12943
|
commentsIn,
|
|
12643
12944
|
compile,
|