parseman 0.42.1 → 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/node.d.ts +21 -7
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +17 -2
- package/dist/combinators/parser.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 +4 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +6 -1
- package/dist/compiler/linker.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/reflection.d.ts +24 -0
- package/dist/cst/reflection.d.ts.map +1 -0
- 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/cst/types.d.ts +2 -0
- package/dist/cst/types.d.ts.map +1 -1
- package/dist/cst/walk.d.ts +27 -62
- package/dist/cst/walk.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 +1651 -1207
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1651 -1207
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs +186 -135
- package/dist/language-service/index.cjs.map +4 -4
- package/dist/language-service/index.d.ts +1 -1
- package/dist/language-service/index.d.ts.map +1 -1
- package/dist/language-service/index.js +186 -135
- package/dist/language-service/index.js.map +4 -4
- package/dist/plugin/evaluator.d.ts +1 -0
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +1525 -1048
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1525 -1048
- 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 +1381 -1152
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +1381 -1152
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +27 -1
- 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
|
-
|
|
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);
|
|
1619
|
+
}
|
|
1715
1620
|
};
|
|
1716
1621
|
}
|
|
1717
|
-
function
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
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 } };
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
1726
1637
|
}
|
|
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;
|
|
1638
|
+
};
|
|
1744
1639
|
}
|
|
1745
|
-
function
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
const
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
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 };
|
|
1648
|
+
}
|
|
1649
|
+
function matchesAt(sentinel, input, pos, ctx) {
|
|
1650
|
+
return probeAt(sentinel, input, pos, ctx);
|
|
1651
|
+
}
|
|
1652
|
+
function captureError(ctx, error) {
|
|
1653
|
+
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1654
|
+
}
|
|
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;
|
|
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;
|
|
1703
|
+
}
|
|
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
|
+
};
|
|
1754
|
+
}
|
|
1755
|
+
};
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
// src/combinators/expect.ts
|
|
1759
|
+
function deriveExpected(c) {
|
|
1760
|
+
return [...new Set(derive(c, /* @__PURE__ */ new Set()))];
|
|
1761
|
+
}
|
|
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 [];
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
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
|
|
1841
|
+
};
|
|
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 } };
|
|
1854
|
+
}
|
|
1855
|
+
};
|
|
1856
|
+
}
|
|
1857
|
+
function isParseError(value) {
|
|
1858
|
+
return typeof value === "object" && value !== null && value._tag === "parseError";
|
|
1859
|
+
}
|
|
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]);
|
|
1889
|
+
}
|
|
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 } };
|
|
1770
1943
|
}
|
|
1771
|
-
|
|
1772
|
-
}
|
|
1773
|
-
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
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);
|
|
1944
|
+
return superResult;
|
|
1797
1945
|
}
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
function consumeTrivia(input, cur, ctx) {
|
|
1804
|
-
if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
|
|
1805
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
1806
|
-
scan.commit();
|
|
1807
|
-
return scan.end;
|
|
1808
|
-
}
|
|
1809
|
-
function fastTriviaScanner(trivia2) {
|
|
1810
|
-
const cached = fastTriviaCache.get(trivia2);
|
|
1811
|
-
if (cached !== void 0) return cached;
|
|
1812
|
-
const scanner = buildFastTriviaScanner(trivia2);
|
|
1813
|
-
fastTriviaCache.set(trivia2, scanner);
|
|
1814
|
-
return scanner;
|
|
1815
|
-
}
|
|
1816
|
-
function buildFastTriviaScanner(trivia2) {
|
|
1817
|
-
const core = trivia2._def.tag === "trivia" ? trivia2._def.parser : trivia2;
|
|
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);
|
|
1828
|
-
}
|
|
1829
|
-
function loopScanner(arms) {
|
|
1830
|
-
return (input, cur) => {
|
|
1831
|
-
let pos = cur;
|
|
1832
|
-
scan: while (pos < input.length) {
|
|
1833
|
-
for (const arm of arms) {
|
|
1834
|
-
const end = arm(input, pos);
|
|
1835
|
-
if (end > pos) {
|
|
1836
|
-
pos = end;
|
|
1837
|
-
continue scan;
|
|
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);
|
|
1838
1951
|
}
|
|
1952
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1839
1953
|
}
|
|
1840
|
-
|
|
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 } };
|
|
1841
1972
|
}
|
|
1842
|
-
return pos;
|
|
1843
1973
|
};
|
|
1844
1974
|
}
|
|
1845
|
-
function
|
|
1846
|
-
|
|
1847
|
-
const
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
for (let i = 0; i < ranges.length; i++) {
|
|
1852
|
-
const r = ranges[i];
|
|
1853
|
-
if (cp >= r[0] && cp <= r[1]) return true;
|
|
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);
|
|
1854
1981
|
}
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
}
|
|
1866
|
-
|
|
1867
|
-
return (input, cur) => {
|
|
1868
|
-
if (input.charCodeAt(cur) !== commentCode) return cur;
|
|
1869
|
-
let pos = cur + 1;
|
|
1870
|
-
while (pos < input.length) {
|
|
1871
|
-
const cc = input.charCodeAt(pos);
|
|
1872
|
-
if (cc === 10 || cc === 13) break;
|
|
1873
|
-
pos++;
|
|
1874
|
-
}
|
|
1875
|
-
return pos;
|
|
1876
|
-
};
|
|
1877
|
-
}
|
|
1878
|
-
function classRunSource(source) {
|
|
1879
|
-
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1880
|
-
return m ? classScanner(m[1]) : null;
|
|
1881
|
-
}
|
|
1882
|
-
function classifyTriviaArm(arm) {
|
|
1883
|
-
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1884
|
-
if (cls) {
|
|
1885
|
-
const ranges = parseClassRanges(cls[1]);
|
|
1886
|
-
return ranges ? { kind: "class", ranges } : null;
|
|
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 };
|
|
1887
1994
|
}
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
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
|
}
|
|
1893
|
-
|
|
2001
|
+
const shared = detectSharedPrefix(parsers);
|
|
2002
|
+
if (shared !== null) return shared;
|
|
2003
|
+
return { tag: "firstMatch" };
|
|
1894
2004
|
}
|
|
1895
|
-
function
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1901
|
-
return pos;
|
|
1902
|
-
};
|
|
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}`;
|
|
2009
|
+
return null;
|
|
1903
2010
|
}
|
|
1904
|
-
function
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
}
|
|
1923
|
-
continue;
|
|
1924
|
-
}
|
|
1925
|
-
break;
|
|
1926
|
-
}
|
|
1927
|
-
return pos;
|
|
1928
|
-
};
|
|
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 };
|
|
1929
2029
|
}
|
|
1930
|
-
function
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
const c = body[i];
|
|
1936
|
-
if (c === "\\") {
|
|
1937
|
-
i++;
|
|
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;
|
|
1938
2035
|
continue;
|
|
1939
2036
|
}
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
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) });
|
|
2052
|
+
continue;
|
|
2053
|
+
}
|
|
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 });
|
|
2058
|
+
}
|
|
1943
2059
|
}
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
2060
|
+
return checks.length > 0 ? checks : null;
|
|
2061
|
+
});
|
|
2062
|
+
}
|
|
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
|
-
|
|
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;
|
|
2086
|
+
}
|
|
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);
|
|
1964
2092
|
}
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
2093
|
+
return value;
|
|
2094
|
+
}
|
|
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);
|
|
1970
2105
|
}
|
|
1971
|
-
if (
|
|
1972
|
-
|
|
2106
|
+
if (contCodes.length === 0) return null;
|
|
2107
|
+
return codesToFirstSet(contCodes);
|
|
2108
|
+
}
|
|
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];
|
|
2119
|
+
}
|
|
1973
2120
|
}
|
|
1974
|
-
|
|
1975
|
-
return
|
|
2121
|
+
ranges.push({ lo, hi });
|
|
2122
|
+
return { kind: "ranges", ranges };
|
|
1976
2123
|
}
|
|
1977
|
-
function
|
|
1978
|
-
|
|
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;
|
|
1979
2129
|
}
|
|
1980
|
-
function
|
|
1981
|
-
if (
|
|
1982
|
-
|
|
1983
|
-
|
|
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;
|
|
1984
2136
|
}
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
isTrivia: false
|
|
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;
|
|
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;
|
|
2032
2145
|
}
|
|
2033
|
-
} finally {
|
|
2034
|
-
ctx._sync = inheritedSync;
|
|
2035
2146
|
}
|
|
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
2147
|
}
|
|
2043
|
-
return
|
|
2044
|
-
_tag: "sequence",
|
|
2045
|
-
_meta: meta,
|
|
2046
|
-
_def: def,
|
|
2047
|
-
parse(input, pos, ctx) {
|
|
2048
|
-
if (ctx._tolerant) return parseTolerant(input, pos, ctx);
|
|
2049
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2050
|
-
let cur = pos;
|
|
2051
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
2052
|
-
if (ctx.trivia && i > 0) {
|
|
2053
|
-
let scanEnd;
|
|
2054
|
-
let mark = saveTriviaMark(ctx);
|
|
2055
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2056
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
2057
|
-
scan.commit();
|
|
2058
|
-
scanEnd = scan.end;
|
|
2059
|
-
} else {
|
|
2060
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2061
|
-
}
|
|
2062
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2063
|
-
if (!result2.ok) return result2;
|
|
2064
|
-
if (result2.span.end > scanEnd) {
|
|
2065
|
-
cur = result2.span.end;
|
|
2066
|
-
} else {
|
|
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;
|
|
2076
|
-
}
|
|
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
|
-
}
|
|
2084
|
-
};
|
|
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) {
|
|
@@ -2863,6 +2952,126 @@ function parse(combinator, input, opts = {}) {
|
|
|
2863
2952
|
return lineIndex ? annotateResultLines(withErrors, normalizeLineIndex(lineIndex)) : withErrors;
|
|
2864
2953
|
}
|
|
2865
2954
|
|
|
2955
|
+
// src/cst/reflection.ts
|
|
2956
|
+
var GRAMMAR_REFLECTION = /* @__PURE__ */ Symbol.for("parseman.grammarReflection");
|
|
2957
|
+
function childrenOf(def) {
|
|
2958
|
+
switch (def.tag) {
|
|
2959
|
+
case "sequence":
|
|
2960
|
+
case "choice":
|
|
2961
|
+
return def.parsers;
|
|
2962
|
+
case "dispatch":
|
|
2963
|
+
return [
|
|
2964
|
+
def.selector,
|
|
2965
|
+
...def.cases.map((c) => c.parser),
|
|
2966
|
+
...def.matchers ? def.matchers.map((c) => c.parser) : [],
|
|
2967
|
+
...def.otherwise ? [def.otherwise] : []
|
|
2968
|
+
];
|
|
2969
|
+
case "many":
|
|
2970
|
+
case "oneOrMore":
|
|
2971
|
+
case "optional":
|
|
2972
|
+
case "attempt":
|
|
2973
|
+
case "transform":
|
|
2974
|
+
case "trivia":
|
|
2975
|
+
case "token":
|
|
2976
|
+
case "leaf":
|
|
2977
|
+
case "label":
|
|
2978
|
+
case "field":
|
|
2979
|
+
case "not":
|
|
2980
|
+
case "peek":
|
|
2981
|
+
case "node":
|
|
2982
|
+
case "withCtx":
|
|
2983
|
+
case "recover":
|
|
2984
|
+
case "expect":
|
|
2985
|
+
return [def.parser];
|
|
2986
|
+
case "grammar":
|
|
2987
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
2988
|
+
case "sepBy":
|
|
2989
|
+
return [def.parser, def.separator];
|
|
2990
|
+
case "skip":
|
|
2991
|
+
return [def.main, def.skipped];
|
|
2992
|
+
case "scanTo":
|
|
2993
|
+
return [def.sentinel, ...def.skip];
|
|
2994
|
+
case "literal":
|
|
2995
|
+
case "regex":
|
|
2996
|
+
case "keywords":
|
|
2997
|
+
case "routed":
|
|
2998
|
+
case "guard":
|
|
2999
|
+
case "lazy":
|
|
3000
|
+
case "unknown":
|
|
3001
|
+
return [];
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
function addNode(out, def) {
|
|
3005
|
+
if (def.type === void 0) return;
|
|
3006
|
+
const existing = out.get(def.type);
|
|
3007
|
+
if (existing === void 0) {
|
|
3008
|
+
out.set(def.type, def.tags === void 0 ? [] : [...def.tags]);
|
|
3009
|
+
return;
|
|
3010
|
+
}
|
|
3011
|
+
if (def.tags === void 0) return;
|
|
3012
|
+
for (const tag of def.tags) {
|
|
3013
|
+
if (!existing.includes(tag)) existing.push(tag);
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
3016
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
3017
|
+
if (seen.has(parser2)) return;
|
|
3018
|
+
seen.add(parser2);
|
|
3019
|
+
const def = parser2._def;
|
|
3020
|
+
if (def.tag === "lazy") {
|
|
3021
|
+
if (followLazy) {
|
|
3022
|
+
try {
|
|
3023
|
+
collectFromCombinator(def.thunk(), out, seen, followLazy);
|
|
3024
|
+
} catch {
|
|
3025
|
+
}
|
|
3026
|
+
}
|
|
3027
|
+
return;
|
|
3028
|
+
}
|
|
3029
|
+
if (def.tag === "node") addNode(out, def);
|
|
3030
|
+
for (const child of childrenOf(def)) collectFromCombinator(child, out, seen, followLazy);
|
|
3031
|
+
}
|
|
3032
|
+
function collectGrammarReflection(ruleMap, opts) {
|
|
3033
|
+
const byType = /* @__PURE__ */ new Map();
|
|
3034
|
+
const followLazy = opts?.followLazy !== false;
|
|
3035
|
+
for (const [, rule] of ruleMap) {
|
|
3036
|
+
if (!followLazy && rule._def.tag === "lazy") {
|
|
3037
|
+
try {
|
|
3038
|
+
const resolved = rule._def.thunk();
|
|
3039
|
+
if (resolved._def.tag !== "lazy") collectFromCombinator(resolved, byType, /* @__PURE__ */ new Set(), false);
|
|
3040
|
+
} catch {
|
|
3041
|
+
}
|
|
3042
|
+
continue;
|
|
3043
|
+
}
|
|
3044
|
+
collectFromCombinator(rule, byType, /* @__PURE__ */ new Set(), followLazy);
|
|
3045
|
+
}
|
|
3046
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
3047
|
+
}
|
|
3048
|
+
function mergeGrammarReflections(reflections) {
|
|
3049
|
+
const byType = /* @__PURE__ */ new Map();
|
|
3050
|
+
for (const reflection of reflections) {
|
|
3051
|
+
for (const node2 of reflection.nodes) {
|
|
3052
|
+
const tags = byType.get(node2.type);
|
|
3053
|
+
if (tags === void 0) {
|
|
3054
|
+
byType.set(node2.type, [...node2.tags]);
|
|
3055
|
+
continue;
|
|
3056
|
+
}
|
|
3057
|
+
for (const tag of node2.tags) {
|
|
3058
|
+
if (!tags.includes(tag)) tags.push(tag);
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
3063
|
+
}
|
|
3064
|
+
function attachGrammarReflection(grammar, reflection) {
|
|
3065
|
+
Object.defineProperty(grammar, GRAMMAR_REFLECTION, { value: reflection, enumerable: false, configurable: true });
|
|
3066
|
+
return grammar;
|
|
3067
|
+
}
|
|
3068
|
+
function grammarReflectionOf(grammar) {
|
|
3069
|
+
return grammar[GRAMMAR_REFLECTION];
|
|
3070
|
+
}
|
|
3071
|
+
function grammarReflectionSource(reflection) {
|
|
3072
|
+
return `{ nodes: ${JSON.stringify(reflection.nodes)} }`;
|
|
3073
|
+
}
|
|
3074
|
+
|
|
2866
3075
|
// src/combinators/parser.ts
|
|
2867
3076
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2868
3077
|
function tagRule(r, key) {
|
|
@@ -2961,6 +3170,7 @@ function rules(a, b) {
|
|
|
2961
3170
|
enumerable: false,
|
|
2962
3171
|
configurable: true
|
|
2963
3172
|
});
|
|
3173
|
+
attachGrammarReflection(cache, collectGrammarReflection(Object.keys(definitions).map((key) => [key, cache[key]])));
|
|
2964
3174
|
return cache;
|
|
2965
3175
|
}
|
|
2966
3176
|
|
|
@@ -3281,13 +3491,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3281
3491
|
const collapse = opts?.collapse === true;
|
|
3282
3492
|
const captureTrivia = opts?.captureTrivia === true;
|
|
3283
3493
|
const trailingTrivia = opts?.trailingTrivia === true;
|
|
3494
|
+
const tags = opts?.tags;
|
|
3284
3495
|
if (unwrap && collapse) {
|
|
3285
3496
|
throw new Error("node() options cannot set both unwrap and collapse");
|
|
3286
3497
|
}
|
|
3287
3498
|
if (project !== void 0 && (unwrap || collapse)) {
|
|
3288
3499
|
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
3289
3500
|
}
|
|
3290
|
-
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {} } : baseDef;
|
|
3501
|
+
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
|
|
3291
3502
|
const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
3292
3503
|
const clonesState = build ? buildReadsState(def) : project === void 0;
|
|
3293
3504
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
@@ -3333,7 +3544,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3333
3544
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3334
3545
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3335
3546
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3336
|
-
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
3547
|
+
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
3337
3548
|
const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
|
|
3338
3549
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3339
3550
|
pushCstChild(ctx, built, rawEntry);
|
|
@@ -3383,6 +3594,25 @@ function trivia(combinator) {
|
|
|
3383
3594
|
parse: combinator.parse.bind(combinator)
|
|
3384
3595
|
};
|
|
3385
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
|
+
}
|
|
3386
3616
|
function label(name, combinator) {
|
|
3387
3617
|
return {
|
|
3388
3618
|
_tag: combinator._tag,
|
|
@@ -3429,6 +3659,7 @@ function token(root) {
|
|
|
3429
3659
|
const savedRaw = ctx._cstRawChildren;
|
|
3430
3660
|
const savedTriviaLog = ctx._cstTriviaLog;
|
|
3431
3661
|
const savedOuterTriviaLog = ctx._triviaLog;
|
|
3662
|
+
const savedRootTriviaLog = ctx._rootTriviaLog;
|
|
3432
3663
|
const wasCapturing = cstCaptureActive(ctx);
|
|
3433
3664
|
ctx.trivia = void 0;
|
|
3434
3665
|
ctx.triviaKindLabels = void 0;
|
|
@@ -3438,6 +3669,7 @@ function token(root) {
|
|
|
3438
3669
|
ctx._cstRawChildren = void 0;
|
|
3439
3670
|
ctx._cstTriviaLog = void 0;
|
|
3440
3671
|
delete ctx._triviaLog;
|
|
3672
|
+
delete ctx._rootTriviaLog;
|
|
3441
3673
|
let result;
|
|
3442
3674
|
try {
|
|
3443
3675
|
result = root.parse(input, pos, ctx);
|
|
@@ -3451,6 +3683,8 @@ function token(root) {
|
|
|
3451
3683
|
ctx._cstTriviaLog = savedTriviaLog;
|
|
3452
3684
|
if (savedOuterTriviaLog === void 0) delete ctx._triviaLog;
|
|
3453
3685
|
else ctx._triviaLog = savedOuterTriviaLog;
|
|
3686
|
+
if (savedRootTriviaLog === void 0) delete ctx._rootTriviaLog;
|
|
3687
|
+
else ctx._rootTriviaLog = savedRootTriviaLog;
|
|
3454
3688
|
}
|
|
3455
3689
|
if (!result.ok) return result;
|
|
3456
3690
|
const span = result.span;
|
|
@@ -3505,7 +3739,7 @@ function leaf(root, fn) {
|
|
|
3505
3739
|
}
|
|
3506
3740
|
|
|
3507
3741
|
// src/version.ts
|
|
3508
|
-
var PARSEMAN_VERSION = "0.
|
|
3742
|
+
var PARSEMAN_VERSION = "0.44.0";
|
|
3509
3743
|
|
|
3510
3744
|
// src/cst/host-mode.ts
|
|
3511
3745
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -3571,7 +3805,7 @@ var SUGGESTIONS = {
|
|
|
3571
3805
|
function classifyBroadArm(arm, resolve) {
|
|
3572
3806
|
const seen = /* @__PURE__ */ new Set();
|
|
3573
3807
|
const relabel = (inner, cause, detail) => ({ cause, detail, ...inner?.unresolvedExternal ? { unresolvedExternal: true } : {} });
|
|
3574
|
-
const
|
|
3808
|
+
const walk = (p) => {
|
|
3575
3809
|
if (seen.has(p)) return { cause: "ref-cycle", detail: "ref cycle" };
|
|
3576
3810
|
seen.add(p);
|
|
3577
3811
|
const d = p._def;
|
|
@@ -3585,7 +3819,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3585
3819
|
// peek() CARRIES its body's first-set, so it is only broad when the body is
|
|
3586
3820
|
// (or the body is nullable) — walk in for the real cause.
|
|
3587
3821
|
case "peek":
|
|
3588
|
-
return
|
|
3822
|
+
return walk(d.parser);
|
|
3589
3823
|
case "scanTo":
|
|
3590
3824
|
return { cause: "broad-recognizer", detail: "scanTo (any first char)" };
|
|
3591
3825
|
// `guard` (the `gate()` state predicate) has a genuinely-`any` first-set of
|
|
@@ -3599,7 +3833,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3599
3833
|
case "attempt":
|
|
3600
3834
|
case "withCtx":
|
|
3601
3835
|
case "recover":
|
|
3602
|
-
return
|
|
3836
|
+
return walk(d.parser);
|
|
3603
3837
|
case "lazy": {
|
|
3604
3838
|
const name = p._ruleName;
|
|
3605
3839
|
let target;
|
|
@@ -3611,13 +3845,13 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3611
3845
|
return { cause: "cross-artifact-ref", detail: `unresolved ref${name ? ` g.${name}` : ""}`, unresolvedExternal: name !== void 0 };
|
|
3612
3846
|
target = bound;
|
|
3613
3847
|
}
|
|
3614
|
-
const inner =
|
|
3848
|
+
const inner = walk(target);
|
|
3615
3849
|
if (name !== void 0) return inner ? relabel(inner, "cross-artifact-ref", `via ref g.${name} \u2192 ${inner.detail}`) : null;
|
|
3616
3850
|
return inner;
|
|
3617
3851
|
}
|
|
3618
3852
|
case "optional":
|
|
3619
3853
|
case "many": {
|
|
3620
|
-
const inner =
|
|
3854
|
+
const inner = walk(d.parser);
|
|
3621
3855
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3622
3856
|
}
|
|
3623
3857
|
case "oneOrMore":
|
|
@@ -3630,9 +3864,9 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3630
3864
|
case "node":
|
|
3631
3865
|
case "grammar":
|
|
3632
3866
|
case "expect":
|
|
3633
|
-
return
|
|
3867
|
+
return walk(d.parser);
|
|
3634
3868
|
case "skip":
|
|
3635
|
-
return
|
|
3869
|
+
return walk(d.main);
|
|
3636
3870
|
case "sequence": {
|
|
3637
3871
|
let sawNullablePrefix = false;
|
|
3638
3872
|
for (const t of d.parsers) {
|
|
@@ -3641,7 +3875,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3641
3875
|
continue;
|
|
3642
3876
|
}
|
|
3643
3877
|
if (isAny(firstSetOf(t, /* @__PURE__ */ new Set(), resolve))) {
|
|
3644
|
-
const inner =
|
|
3878
|
+
const inner = walk(t);
|
|
3645
3879
|
if (sawNullablePrefix)
|
|
3646
3880
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3647
3881
|
return inner ?? { cause: "broad-recognizer", detail: "sequence leading term is broad" };
|
|
@@ -3656,18 +3890,18 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3656
3890
|
}
|
|
3657
3891
|
case "choice": {
|
|
3658
3892
|
for (const a of d.parsers) {
|
|
3659
|
-
const r =
|
|
3893
|
+
const r = walk(a);
|
|
3660
3894
|
if (r) return relabel(r, r.cause, `choice arm \u2192 ${r.detail}`);
|
|
3661
3895
|
}
|
|
3662
3896
|
return null;
|
|
3663
3897
|
}
|
|
3664
3898
|
case "dispatch":
|
|
3665
|
-
return
|
|
3899
|
+
return walk(d.selector);
|
|
3666
3900
|
default:
|
|
3667
3901
|
return { cause: "broad-recognizer", detail: `unmodeled construct (${d.tag})` };
|
|
3668
3902
|
}
|
|
3669
3903
|
};
|
|
3670
|
-
return
|
|
3904
|
+
return walk(arm) ?? { cause: "broad-recognizer", detail: "broad (cause not localized)" };
|
|
3671
3905
|
}
|
|
3672
3906
|
function peelToLeading(arm) {
|
|
3673
3907
|
let d = arm._def;
|
|
@@ -3869,7 +4103,7 @@ function formatGatingWarnings(report) {
|
|
|
3869
4103
|
|
|
3870
4104
|
// src/analysis/duplication.ts
|
|
3871
4105
|
var siteToString = (s) => s.path === "" ? s.rule : `${s.rule} \u203A ${s.path}`;
|
|
3872
|
-
function
|
|
4106
|
+
function childrenOf2(d) {
|
|
3873
4107
|
switch (d.tag) {
|
|
3874
4108
|
case "sequence":
|
|
3875
4109
|
case "choice":
|
|
@@ -4003,7 +4237,7 @@ function render(p, depth = 3) {
|
|
|
4003
4237
|
break;
|
|
4004
4238
|
}
|
|
4005
4239
|
if (depth <= 0) return `${d.tag}(\u2026)`;
|
|
4006
|
-
const kids =
|
|
4240
|
+
const kids = childrenOf2(d).map((k) => render(k, depth - 1));
|
|
4007
4241
|
switch (d.tag) {
|
|
4008
4242
|
case "sequence":
|
|
4009
4243
|
return `sequence(${kids.join(", ")})`;
|
|
@@ -4198,7 +4432,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4198
4432
|
if (hit !== void 0) return hit;
|
|
4199
4433
|
const d = p._def;
|
|
4200
4434
|
shapeCache.set(p, interner.hole);
|
|
4201
|
-
const kids =
|
|
4435
|
+
const kids = childrenOf2(d);
|
|
4202
4436
|
const id = interner.of(`${payloadKey(p, d)}|${kids.map(shapeOf).join(",")}`);
|
|
4203
4437
|
shapeCache.set(p, id);
|
|
4204
4438
|
return id;
|
|
@@ -4208,7 +4442,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4208
4442
|
if (hit !== void 0) return hit;
|
|
4209
4443
|
sizeCache.set(p, 1);
|
|
4210
4444
|
let n = 1;
|
|
4211
|
-
for (const k of
|
|
4445
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4212
4446
|
sizeCache.set(p, n);
|
|
4213
4447
|
return n;
|
|
4214
4448
|
};
|
|
@@ -4221,7 +4455,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4221
4455
|
visited.set(p, { p, d, site: here, shape: shapeOf(p), size: sizeOf(p), enclosingNode, enclosingReducer });
|
|
4222
4456
|
const inner = d.tag === "node" ? d.type ?? "(anonymous)" : enclosingNode;
|
|
4223
4457
|
const innerReducer = enclosingReducer || d.tag === "node" && (d.build !== void 0 || d.buildSrc !== void 0) || d.tag === "transform" || d.tag === "leaf";
|
|
4224
|
-
const kids =
|
|
4458
|
+
const kids = childrenOf2(d);
|
|
4225
4459
|
kids.forEach((k, i) => {
|
|
4226
4460
|
const seg = segment(d, i);
|
|
4227
4461
|
visit(k, here.rule, here.path === "" ? seg : `${here.path} \u203A ${seg}`, inner, innerReducer);
|
|
@@ -4281,7 +4515,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4281
4515
|
function markSubtree(p, into) {
|
|
4282
4516
|
if (into.has(p)) return;
|
|
4283
4517
|
into.add(p);
|
|
4284
|
-
for (const k of
|
|
4518
|
+
for (const k of childrenOf2(p._def)) markSubtree(k, into);
|
|
4285
4519
|
}
|
|
4286
4520
|
var stripMembers = (f) => {
|
|
4287
4521
|
const { _members, ...rest } = f;
|
|
@@ -4321,7 +4555,7 @@ function findNearDuplicates(visited, interner, shapeOf, minSize) {
|
|
|
4321
4555
|
if (hit !== void 0) return hit;
|
|
4322
4556
|
holeCache.set(p, []);
|
|
4323
4557
|
const d = p._def;
|
|
4324
|
-
const kids =
|
|
4558
|
+
const kids = childrenOf2(d);
|
|
4325
4559
|
const kidShapes = kids.map(shapeOf);
|
|
4326
4560
|
const payload = payloadKey(p, d);
|
|
4327
4561
|
const out2 = [];
|
|
@@ -4382,7 +4616,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4382
4616
|
let cur = [...members];
|
|
4383
4617
|
for (let guard2 = 0; guard2 < 64; guard2++) {
|
|
4384
4618
|
const d0 = cur[0]._def;
|
|
4385
|
-
const kidLists = cur.map((c) =>
|
|
4619
|
+
const kidLists = cur.map((c) => childrenOf2(c._def));
|
|
4386
4620
|
const arity = kidLists[0].length;
|
|
4387
4621
|
if (kidLists.some((k) => k.length !== arity) || arity === 0) break;
|
|
4388
4622
|
const diff = [];
|
|
@@ -4395,7 +4629,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4395
4629
|
path.push(i);
|
|
4396
4630
|
defs.push(d0);
|
|
4397
4631
|
cur = kidLists.map((k) => k[i]);
|
|
4398
|
-
const nextArity =
|
|
4632
|
+
const nextArity = childrenOf2(cur[0]._def).length;
|
|
4399
4633
|
const samePayload = cur.every((c) => payloadKey(c, c._def) === payloadKey(cur[0], cur[0]._def));
|
|
4400
4634
|
if (!samePayload || nextArity === 0) break;
|
|
4401
4635
|
}
|
|
@@ -4403,7 +4637,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4403
4637
|
let slotSize = 0;
|
|
4404
4638
|
const sizeOf = (p) => {
|
|
4405
4639
|
let n = 1;
|
|
4406
|
-
for (const k of
|
|
4640
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4407
4641
|
return n;
|
|
4408
4642
|
};
|
|
4409
4643
|
for (const c of cur) slotSize = Math.max(slotSize, sizeOf(c));
|
|
@@ -4412,7 +4646,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4412
4646
|
function renderWithHole(p, path, depth = 0) {
|
|
4413
4647
|
if (depth === path.length) return "\u2039slot\u203A";
|
|
4414
4648
|
const d = p._def;
|
|
4415
|
-
const kids =
|
|
4649
|
+
const kids = childrenOf2(d);
|
|
4416
4650
|
const idx = path[depth];
|
|
4417
4651
|
const parts = kids.map((k, i) => i === idx ? renderWithHole(k, path, depth + 1) : render(k, 2));
|
|
4418
4652
|
switch (d.tag) {
|
|
@@ -4870,7 +5104,7 @@ function capturesPositionally(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4870
5104
|
seen.add(p);
|
|
4871
5105
|
const d = p._def;
|
|
4872
5106
|
if (d.tag === "field" || d.tag === "label") return true;
|
|
4873
|
-
for (const k of
|
|
5107
|
+
for (const k of childrenOf2(d)) if (capturesPositionally(k, seen)) return true;
|
|
4874
5108
|
return false;
|
|
4875
5109
|
}
|
|
4876
5110
|
function detectHandRolledSepBy(terms, shapeOf) {
|
|
@@ -4976,7 +5210,7 @@ function nestedNodeTypes(root, out, seen, isRoot) {
|
|
|
4976
5210
|
}
|
|
4977
5211
|
return;
|
|
4978
5212
|
}
|
|
4979
|
-
for (const k of
|
|
5213
|
+
for (const k of childrenOf2(d)) nestedNodeTypes(k, out, seen, false);
|
|
4980
5214
|
}
|
|
4981
5215
|
var MAX_LOST_TYPES = 8;
|
|
4982
5216
|
function findStructureLoss(visited, resolve) {
|
|
@@ -5403,9 +5637,196 @@ function buildGrammarPlan(entry, winners) {
|
|
|
5403
5637
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
|
|
5404
5638
|
}
|
|
5405
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
|
+
|
|
5406
5823
|
// src/compiler/scannable-run.ts
|
|
5407
5824
|
var BACKSLASH = 92;
|
|
5408
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(", ");
|
|
5409
5830
|
function classToRanges(cls) {
|
|
5410
5831
|
if (cls === "\\d") return shorthandRanges("d");
|
|
5411
5832
|
if (cls === "\\w") return shorthandRanges("w");
|
|
@@ -6444,13 +6865,15 @@ function scanBranch(shape, mint) {
|
|
|
6444
6865
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6445
6866
|
return [...m.setup, ` if (${m.end} > _e) { _e = ${m.end}; continue }`].join("\n");
|
|
6446
6867
|
}
|
|
6447
|
-
function scanBranchLabeled(shape, kindIndex, mint) {
|
|
6868
|
+
function scanBranchLabeled(shape, kindIndex, label2, mint) {
|
|
6448
6869
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6449
6870
|
return [
|
|
6450
6871
|
...m.setup,
|
|
6451
6872
|
` if (${m.end} > _e) {`,
|
|
6452
6873
|
` if (_cap) {`,
|
|
6453
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)`,
|
|
6454
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})`,
|
|
6455
6878
|
` }`,
|
|
6456
6879
|
` _e = ${m.end}`,
|
|
@@ -6510,6 +6933,11 @@ var CAP_RECORD = [
|
|
|
6510
6933
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
|
|
6511
6934
|
` }`
|
|
6512
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");
|
|
6513
6941
|
function composeFastLoop(shapes) {
|
|
6514
6942
|
const mint = makeMint();
|
|
6515
6943
|
return [
|
|
@@ -6538,7 +6966,7 @@ function analyzeLabeledScannableRun(trivia2) {
|
|
|
6538
6966
|
const d = getCoreRegexDef(arm.parser);
|
|
6539
6967
|
const shape = d ? scanShapeFromRegex(d.source, d.flags) : null;
|
|
6540
6968
|
if (!shape) return null;
|
|
6541
|
-
out.push({ shape, kindIndex: arm.kindIndex });
|
|
6969
|
+
out.push({ shape, kindIndex: arm.kindIndex, label: arm.label });
|
|
6542
6970
|
}
|
|
6543
6971
|
return out;
|
|
6544
6972
|
}
|
|
@@ -6547,11 +6975,13 @@ function buildLabeledScannableTriviaFnDecl(fnName, arms) {
|
|
|
6547
6975
|
return [
|
|
6548
6976
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6549
6977
|
` let _e = _pos`,
|
|
6978
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6550
6979
|
` while (_e < input.length) {`,
|
|
6551
6980
|
` const c = input.charCodeAt(_e)`,
|
|
6552
|
-
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, mint)),
|
|
6981
|
+
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, a.label, mint)),
|
|
6553
6982
|
` break`,
|
|
6554
6983
|
` }`,
|
|
6984
|
+
SELECTED_ROOT_FINISH,
|
|
6555
6985
|
` return _e`,
|
|
6556
6986
|
`}`
|
|
6557
6987
|
].join("\n");
|
|
@@ -6567,6 +6997,8 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6567
6997
|
` const _ce = _e + _m${i}[0].length`,
|
|
6568
6998
|
` if (_cap) {`,
|
|
6569
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})`,
|
|
6570
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})`,
|
|
6571
7003
|
` }`,
|
|
6572
7004
|
` _e = _ce`,
|
|
@@ -6578,11 +7010,13 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6578
7010
|
return [
|
|
6579
7011
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6580
7012
|
` let _e = _pos`,
|
|
7013
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6581
7014
|
` while (_e < input.length) {`,
|
|
6582
7015
|
` let _matched = false`,
|
|
6583
7016
|
tryArms,
|
|
6584
7017
|
` if (!_matched) break`,
|
|
6585
7018
|
` }`,
|
|
7019
|
+
SELECTED_ROOT_FINISH,
|
|
6586
7020
|
` return _e`,
|
|
6587
7021
|
`}`
|
|
6588
7022
|
].join("\n");
|
|
@@ -6605,6 +7039,8 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6605
7039
|
` const _ce = _r${i}.span.end`,
|
|
6606
7040
|
` if (_cap) {`,
|
|
6607
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})`,
|
|
6608
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})`,
|
|
6609
7045
|
` }`,
|
|
6610
7046
|
` _e = _ce`,
|
|
@@ -6616,11 +7052,13 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6616
7052
|
return [
|
|
6617
7053
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6618
7054
|
` let _e = _pos`,
|
|
7055
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6619
7056
|
` while (_e < input.length) {`,
|
|
6620
7057
|
` let _matched = false`,
|
|
6621
7058
|
tryArms,
|
|
6622
7059
|
` if (!_matched) break`,
|
|
6623
7060
|
` }`,
|
|
7061
|
+
SELECTED_ROOT_FINISH,
|
|
6624
7062
|
` return _e`,
|
|
6625
7063
|
`}`
|
|
6626
7064
|
].join("\n");
|
|
@@ -6843,6 +7281,9 @@ var HOST_READS_DECL = "const _hostReads = (b, n) => { if (b === undefined) retur
|
|
|
6843
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 }";
|
|
6844
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] } }";
|
|
6845
7283
|
var _loweringSink = null;
|
|
7284
|
+
function hasSelectedRootTrivia(ctx) {
|
|
7285
|
+
return ctx.rootTriviaClassified === true;
|
|
7286
|
+
}
|
|
6846
7287
|
function v(ctx, prefix = "_v") {
|
|
6847
7288
|
return `${prefix}${ctx.vars++}`;
|
|
6848
7289
|
}
|
|
@@ -7152,10 +7593,12 @@ function planDisjointDispatch(parsers) {
|
|
|
7152
7593
|
}
|
|
7153
7594
|
return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
7154
7595
|
}
|
|
7155
|
-
function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
|
|
7596
|
+
function captureRestoreBody(ctx, mL, mR, mTl, mLg, mF = null, mRootLg = null) {
|
|
7156
7597
|
const fieldRestore = mF ? `; if (_ctx._fields && _ctx._fields.length !== ${mF}) _ctx._fields.length = ${mF}` : "";
|
|
7157
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}`;
|
|
7158
|
-
|
|
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}`;
|
|
7159
7602
|
}
|
|
7160
7603
|
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
7161
7604
|
if (seen.has(p)) return false;
|
|
@@ -7365,7 +7808,7 @@ function emitFallible(inner, ctx, pos, swallow = false) {
|
|
|
7365
7808
|
`${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
|
|
7366
7809
|
`${ind0}}`,
|
|
7367
7810
|
...mL ? [
|
|
7368
|
-
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
|
|
7811
|
+
`${ind0}if (!${okV}) { ${captureRestoreBody(ctx, mL, mR, mTl, null, mF)} }`
|
|
7369
7812
|
] : []
|
|
7370
7813
|
];
|
|
7371
7814
|
return { stmts, okVar: okV, valVar: valV, endVar: endV, mayCommit };
|
|
@@ -7562,11 +8005,13 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7562
8005
|
const markV = v(ctx, "_mk");
|
|
7563
8006
|
const markTl = v(ctx, "_mktl");
|
|
7564
8007
|
const markLog = v(ctx, "_mklg");
|
|
8008
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7565
8009
|
const scanEndV = v(ctx, "_sne");
|
|
7566
8010
|
stmts.push(
|
|
7567
8011
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7568
8012
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7569
8013
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8014
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7570
8015
|
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7571
8016
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7572
8017
|
);
|
|
@@ -7575,17 +8020,19 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7575
8020
|
const endAfterV = v(ctx, "_sea");
|
|
7576
8021
|
stmts.push(
|
|
7577
8022
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7578
|
-
`${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};` : ""} }`
|
|
7579
8024
|
);
|
|
7580
8025
|
valueVars.push(r2.valueVar);
|
|
7581
8026
|
continue;
|
|
7582
8027
|
} else {
|
|
7583
8028
|
const trivFn = ensureTriviaFn(ctx);
|
|
7584
8029
|
const markLog = v(ctx, "_mklg");
|
|
8030
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7585
8031
|
const scanEndV = v(ctx, "_sne");
|
|
7586
|
-
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";
|
|
7587
8033
|
stmts.push(
|
|
7588
8034
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8035
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7589
8036
|
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7590
8037
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7591
8038
|
);
|
|
@@ -7594,7 +8041,7 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7594
8041
|
const endAfterV = v(ctx, "_sea");
|
|
7595
8042
|
stmts.push(
|
|
7596
8043
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7597
|
-
`${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};` : ""} }`
|
|
7598
8045
|
);
|
|
7599
8046
|
valueVars.push(r2.valueVar);
|
|
7600
8047
|
continue;
|
|
@@ -7836,6 +8283,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7836
8283
|
const selectorRawMark = selectorNeedsRollback ? v(ctx, "_dsr") : null;
|
|
7837
8284
|
const selectorTriviaMark = selectorNeedsRollback ? v(ctx, "_dst") : null;
|
|
7838
8285
|
const selectorLogMark = selectorNeedsRollback ? v(ctx, "_dsg") : null;
|
|
8286
|
+
const selectorRootLogMark = selectorNeedsRollback && hasSelectedRootTrivia(ctx) ? v(ctx, "_dsrg") : null;
|
|
7839
8287
|
const selectorFieldMark = selectorNeedsRollback ? v(ctx, "_dsf") : null;
|
|
7840
8288
|
const selectorErrorMark = selectorNeedsRollback ? v(ctx, "_dse") : null;
|
|
7841
8289
|
const selector = emit(def.selector, ctx, pos);
|
|
@@ -7848,6 +8296,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7848
8296
|
`${ind(ctx)}const ${selectorRawMark} = _ctx._cstRawChildren?.length ?? 0`,
|
|
7849
8297
|
`${ind(ctx)}const ${selectorTriviaMark} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
7850
8298
|
`${ind(ctx)}const ${selectorLogMark} = _ctx._triviaLog?.length ?? 0`,
|
|
8299
|
+
...selectorRootLogMark ? [`${ind(ctx)}const ${selectorRootLogMark} = _ctx._rootTriviaLog?.length ?? 0`] : [],
|
|
7851
8300
|
`${ind(ctx)}const ${selectorFieldMark} = _ctx._fields?.length ?? 0`,
|
|
7852
8301
|
`${ind(ctx)}const ${selectorErrorMark} = _ctx._errors?.length ?? 0`
|
|
7853
8302
|
] : [],
|
|
@@ -7867,16 +8316,18 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7867
8316
|
const mayError = mayRecordRecoveryError(parser3, !!ctx.recovery);
|
|
7868
8317
|
const errMark = mayError ? v(ctx, "_derr") : null;
|
|
7869
8318
|
const logMark = ctx.activeTrivia ? v(ctx, "_dlog") : null;
|
|
8319
|
+
const rootLogMark = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_drlog") : null;
|
|
7870
8320
|
if (usesRouted) {
|
|
7871
8321
|
stmts.push(
|
|
7872
8322
|
...routedV ? [`${ind(ctx)}const ${routedV} = _ctx._routed; _ctx._routed = { value: ${selector.valueVar}, span: { start: ${pos}, end: ${selector.endVar} } }`] : [],
|
|
7873
8323
|
...selectorLeafMark ? [
|
|
7874
|
-
`${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}`
|
|
7875
8325
|
] : []
|
|
7876
8326
|
);
|
|
7877
8327
|
}
|
|
7878
8328
|
if (errMark) stmts.push(`${ind(ctx)}const ${errMark} = _ctx._errors?.length ?? 0`);
|
|
7879
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`);
|
|
7880
8331
|
const savedRoutedLocal = ctx.routedLocal;
|
|
7881
8332
|
const savedNoHoist = ctx.noHoist;
|
|
7882
8333
|
if (usesRouted && !needsRoutedContext) {
|
|
@@ -7891,11 +8342,12 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7891
8342
|
stmts.push(...coverageAttempt(ctx, coverageId, pos));
|
|
7892
8343
|
const errorRollback = errMark ? `if (_ctx._errors && _ctx._errors.length !== ${errMark}) _ctx._errors.length = ${errMark}; ` : "";
|
|
7893
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}; ` : "";
|
|
7894
8346
|
const routedRollback = routedV ? `_ctx._routed = ${routedV}; ` : "";
|
|
7895
8347
|
const coverageFailure = coverageId === void 0 ? "" : `_ctx._grammarTrace?.write({ id: ${JSON.stringify(coverageId)}, phase: 'failure', offset: _ctx._fe }); `;
|
|
7896
8348
|
stmts.push(
|
|
7897
8349
|
...tail.stmts,
|
|
7898
|
-
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8350
|
+
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${rootLogRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
7899
8351
|
...routedV ? [`${ind(ctx)}_ctx._routed = ${routedV}`] : [],
|
|
7900
8352
|
`${ind(ctx)}${outV} = ${valueMode === "tail" ? tail.valVar : `[${selector.valueVar}, ${tail.valVar}]`}`,
|
|
7901
8353
|
`${ind(ctx)}${outE} = ${tail.endVar}`,
|
|
@@ -8076,11 +8528,13 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8076
8528
|
const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
|
|
8077
8529
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
8078
8530
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
8531
|
+
const markRootLog = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_cmlrg") : null;
|
|
8079
8532
|
const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
|
|
8080
8533
|
const markErrors = armMayRecordError ? v(ctx, "_cme") : null;
|
|
8081
|
-
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}` : "";
|
|
8082
8536
|
const errorRollback = markErrors ? `if (_ctx._errors && _ctx._errors.length !== ${markErrors}) _ctx._errors.length = ${markErrors}` : "";
|
|
8083
|
-
const rollback = [captureRollback, errorRollback].filter(Boolean).join("; ");
|
|
8537
|
+
const rollback = [captureRollback, rootRollback, errorRollback].filter(Boolean).join("; ");
|
|
8084
8538
|
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
8085
8539
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
8086
8540
|
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
@@ -8095,6 +8549,7 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8095
8549
|
...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
|
|
8096
8550
|
);
|
|
8097
8551
|
}
|
|
8552
|
+
if (markRootLog) stmts.push(`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
8098
8553
|
if (markErrors) stmts.push(`${ind(ctx)}const ${markErrors} = _ctx._errors?.length ?? 0`);
|
|
8099
8554
|
const arm = emitFallible(p, ctx, pos, atStart);
|
|
8100
8555
|
const { stmts: armStmts, okVar, valVar, endVar } = arm;
|
|
@@ -8163,7 +8618,7 @@ function routedNeedsContextBridge(p, ctx, seen = /* @__PURE__ */ new Set()) {
|
|
|
8163
8618
|
const d = p._def;
|
|
8164
8619
|
if (d.tag === "dispatch") return false;
|
|
8165
8620
|
if (d.tag === "withCtx") return parserUsesRouted2(d.parser);
|
|
8166
|
-
return
|
|
8621
|
+
return childrenOf3(d).some((child) => routedNeedsContextBridge(child, ctx, seen));
|
|
8167
8622
|
}
|
|
8168
8623
|
function armReplayInScope(arm, ctx) {
|
|
8169
8624
|
let p = arm;
|
|
@@ -8282,21 +8737,29 @@ function emitMany(def, ctx, pos) {
|
|
|
8282
8737
|
const markV = v(ctx, "_mk");
|
|
8283
8738
|
const markTl = v(ctx, "_mktl");
|
|
8284
8739
|
const markLog = v(ctx, "_mklg");
|
|
8740
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8285
8741
|
const npV = v(ctx, "_np");
|
|
8286
8742
|
stmts.push(
|
|
8287
8743
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8288
8744
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8289
8745
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8746
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8290
8747
|
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8291
8748
|
...emitLineTrack(ctx, curV, npV)
|
|
8292
8749
|
);
|
|
8293
8750
|
itemPos = npV;
|
|
8294
|
-
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};` : ""} `;
|
|
8295
8752
|
} else {
|
|
8296
8753
|
const trivFn = ensureTriviaFn(ctx);
|
|
8754
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8297
8755
|
const npV = v(ctx, "_np");
|
|
8298
|
-
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
|
+
);
|
|
8299
8761
|
itemPos = npV;
|
|
8762
|
+
rollback = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8300
8763
|
}
|
|
8301
8764
|
}
|
|
8302
8765
|
if (!ctx.recovery && !ctx.coverage && !failsAtStart(def.parser) && needsFirstSetGuard(def.parser)) {
|
|
@@ -8356,9 +8819,10 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8356
8819
|
const raw = v(ctx, "_atr");
|
|
8357
8820
|
const trivia2 = v(ctx, "_att");
|
|
8358
8821
|
const log = v(ctx, "_atg");
|
|
8822
|
+
const rootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_atrg") : null;
|
|
8359
8823
|
const fields = v(ctx, "_atf");
|
|
8360
8824
|
const errors = v(ctx, "_ate");
|
|
8361
|
-
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}`;
|
|
8362
8826
|
const traceId = ctx.coverage?.plan.attempts.get(p);
|
|
8363
8827
|
const traceRollback = traceId === void 0 ? "" : ` _ctx._grammarTrace?.write({ id: ${JSON.stringify(traceId)}, phase: 'rollback', offset: ${pos} });`;
|
|
8364
8828
|
const preGuard = [];
|
|
@@ -8374,7 +8838,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8374
8838
|
return {
|
|
8375
8839
|
stmts: [
|
|
8376
8840
|
...preGuard,
|
|
8377
|
-
`${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`,
|
|
8378
8842
|
...inner.stmts,
|
|
8379
8843
|
...emitIfFail(ctx, `!${inner.okVar}`, `{ ${rollback};${traceRollback}${inner.mayCommit ? ` if (_ctx._fc) ${committedFailBody(ctx)};` : ""} _ctx._fe = ${pos}; ${propagateFailBody(ctx)} }`)
|
|
8380
8844
|
],
|
|
@@ -8416,16 +8880,17 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8416
8880
|
const itemFailBreak = (sepEndVar, sepRb, postSepRb) => def.trailing === void 0 ? `${sepRb}break` : `${postSepRb}${curV} = ${sepEndVar}; break`;
|
|
8417
8881
|
const postSepMarks = () => {
|
|
8418
8882
|
if (def.trailing === void 0 || !ctx.capturing) return { decl: [], rb: "" };
|
|
8419
|
-
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");
|
|
8420
8884
|
return {
|
|
8421
8885
|
decl: [
|
|
8422
8886
|
`${ind(ctx)}const ${lv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8423
8887
|
`${ind(ctx)}const ${rw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8424
8888
|
`${ind(ctx)}const ${tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8425
8889
|
`${ind(ctx)}const ${lg} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8890
|
+
...rlg ? [`${ind(ctx)}const ${rlg} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8426
8891
|
`${ind(ctx)}const ${fl} = _ctx._fields ? _ctx._fields.length : 0`
|
|
8427
8892
|
],
|
|
8428
|
-
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}; `
|
|
8429
8894
|
};
|
|
8430
8895
|
};
|
|
8431
8896
|
if (rec) {
|
|
@@ -8463,6 +8928,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8463
8928
|
const markV = v(ctx, "_mk");
|
|
8464
8929
|
const markTl = v(ctx, "_mktl");
|
|
8465
8930
|
const markLog = v(ctx, "_mklg");
|
|
8931
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8466
8932
|
const markLv = v(ctx, "_mklv");
|
|
8467
8933
|
const markFld = v(ctx, "_mkf");
|
|
8468
8934
|
const spV = v(ctx, "_sp");
|
|
@@ -8470,13 +8936,14 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8470
8936
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8471
8937
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8472
8938
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8939
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8473
8940
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8474
8941
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8475
8942
|
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8476
8943
|
...emitLineTrack(ctx, curV, spV)
|
|
8477
8944
|
);
|
|
8478
8945
|
sepAtPos = spV;
|
|
8479
|
-
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}; `;
|
|
8480
8947
|
const sep = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8481
8948
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep;
|
|
8482
8949
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
@@ -8494,19 +8961,30 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8494
8961
|
);
|
|
8495
8962
|
} else {
|
|
8496
8963
|
const trivFn = ensureTriviaFn(ctx);
|
|
8964
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8497
8965
|
const spV = v(ctx, "_sp");
|
|
8498
|
-
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
|
+
);
|
|
8499
8971
|
sepAtPos = spV;
|
|
8500
8972
|
const sep = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8501
8973
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep;
|
|
8502
|
-
|
|
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;
|
|
8503
8977
|
const npV = v(ctx, "_np");
|
|
8504
|
-
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
|
+
);
|
|
8505
8983
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8506
8984
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8507
8985
|
stmts.push(
|
|
8508
8986
|
...nextStmts,
|
|
8509
|
-
...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}; ` : "")),
|
|
8510
8988
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
8511
8989
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
8512
8990
|
);
|
|
@@ -8601,6 +9079,7 @@ function emitNot(def, ctx, pos) {
|
|
|
8601
9079
|
const raw = sinksLive ? v(ctx, "_ntr") : null;
|
|
8602
9080
|
const tl = sinksLive ? v(ctx, "_ntt") : null;
|
|
8603
9081
|
const log = sinksLive ? v(ctx, "_ntg") : null;
|
|
9082
|
+
const rootLog = sinksLive && hasSelectedRootTrivia(ctx) ? v(ctx, "_ntrg") : null;
|
|
8604
9083
|
const fields = sinksLive ? v(ctx, "_ntf") : null;
|
|
8605
9084
|
const errors = sinksLive ? v(ctx, "_nte") : null;
|
|
8606
9085
|
const { stmts, okVar } = emitFallible(def.parser, ctx, pos, true);
|
|
@@ -8608,11 +9087,11 @@ function emitNot(def, ctx, pos) {
|
|
|
8608
9087
|
return {
|
|
8609
9088
|
stmts: [
|
|
8610
9089
|
...sinksLive ? [
|
|
8611
|
-
`${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`
|
|
8612
9091
|
] : [],
|
|
8613
9092
|
...stmts,
|
|
8614
9093
|
...sinksLive ? [
|
|
8615
|
-
`${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}`
|
|
8616
9095
|
] : [],
|
|
8617
9096
|
...emitIfFail(ctx, okVar, failBody(ctx, label2, pos))
|
|
8618
9097
|
],
|
|
@@ -8748,16 +9227,17 @@ function emitToken(def, ctx, pos) {
|
|
|
8748
9227
|
const sk = v(ctx, "_tokKinds");
|
|
8749
9228
|
const stl = v(ctx, "_tokTl");
|
|
8750
9229
|
const sol = v(ctx, "_tokLog");
|
|
9230
|
+
const srl = hasSelectedRootTrivia(ctx) ? v(ctx, "_tokRootLog") : null;
|
|
8751
9231
|
const sb = v(ctx, "_tokBuf");
|
|
8752
9232
|
const valV = v(ctx, "_tok");
|
|
8753
9233
|
return {
|
|
8754
9234
|
stmts: [
|
|
8755
|
-
`${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`,
|
|
8756
|
-
`${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`,
|
|
8757
9237
|
`${i}try {`,
|
|
8758
9238
|
...reindentStmts(inner.stmts, ctx.indent + 1).map((stmt) => stmt.replace(/^(\s*)(?:const|let)\s+/, "$1var ")),
|
|
8759
9239
|
`${i}} finally {`,
|
|
8760
|
-
`${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}`,
|
|
8761
9241
|
`${i}}`,
|
|
8762
9242
|
...emitIfFail(ctx, `!${inner.okVar}`, propagateFailBody(ctx)),
|
|
8763
9243
|
`${i}const ${valV} = input.slice(${pos}, ${inner.endVar})`,
|
|
@@ -8926,7 +9406,8 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8926
9406
|
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
8927
9407
|
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
8928
9408
|
const buildExpr = structural ? `{ _tag: 'node', type: ${JSON.stringify(def.type)}, span: ${nodeSpanV}, state: ${stV} ?? null, children: ${chV} }` : mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, nodeSpanV, tlV) : def.project !== void 0 ? emitNodeProjectExpr(def.type, def.project, chV) : `${buildRef(ctx)}[${buildIdx}](${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV})`;
|
|
8929
|
-
const
|
|
9409
|
+
const hostBuildArgs = `${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV}${def.tags !== void 0 && def.tags.length > 0 ? `, ${JSON.stringify(def.tags)}` : ""}`;
|
|
9410
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${hostBuildArgs})`;
|
|
8930
9411
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
8931
9412
|
const hostCollapseExpr = structural ? `_ctx.build !== undefined && _ctx.build._parsemanCstCollapse !== undefined && ${chV}.length === 1 && ${rawV}.length === 1 && _ctx.build._parsemanCstCollapse(${JSON.stringify(def.type)}, ${chV}[0], ${chV}, ${rawV}) ? ${chV}[0] : (${ndExpr})` : ndExpr;
|
|
8932
9413
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -9235,6 +9716,8 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9235
9716
|
case "grammar": {
|
|
9236
9717
|
const savedTrivia = ctx.activeTrivia;
|
|
9237
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;
|
|
9238
9721
|
if (def.clearTrivia) {
|
|
9239
9722
|
ctx.activeTrivia = void 0;
|
|
9240
9723
|
ctx.triviaKindLabels = void 0;
|
|
@@ -9245,13 +9728,38 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9245
9728
|
}
|
|
9246
9729
|
}
|
|
9247
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++;
|
|
9248
9735
|
const r = emit(def.parser, ctx, pos);
|
|
9736
|
+
if (opaqueRootCapture) ctx.indent--;
|
|
9249
9737
|
ctx.activeTrivia = savedTrivia;
|
|
9250
9738
|
ctx.triviaKindLabels = savedKindLabels;
|
|
9251
|
-
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
|
+
}
|
|
9252
9759
|
return {
|
|
9253
9760
|
...r,
|
|
9254
9761
|
stmts: [
|
|
9762
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9255
9763
|
`${ind(ctx)}const ${savedCapture} = _ctx.captureTrivia; _ctx.captureTrivia = true`,
|
|
9256
9764
|
...r.stmts,
|
|
9257
9765
|
`${ind(ctx)}_ctx.captureTrivia = ${savedCapture}`
|
|
@@ -9389,7 +9897,7 @@ function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9389
9897
|
return false;
|
|
9390
9898
|
}
|
|
9391
9899
|
}
|
|
9392
|
-
return
|
|
9900
|
+
return childrenOf3(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9393
9901
|
}
|
|
9394
9902
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9395
9903
|
if (seen.has(p)) return false;
|
|
@@ -9408,7 +9916,7 @@ function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9408
9916
|
case "dispatch":
|
|
9409
9917
|
return false;
|
|
9410
9918
|
default:
|
|
9411
|
-
return
|
|
9919
|
+
return childrenOf3(d).some((child) => parserUsesRouted2(child, seen));
|
|
9412
9920
|
}
|
|
9413
9921
|
}
|
|
9414
9922
|
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -9423,9 +9931,9 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9423
9931
|
return false;
|
|
9424
9932
|
}
|
|
9425
9933
|
}
|
|
9426
|
-
return
|
|
9934
|
+
return childrenOf3(d).some((child) => hasDirectBuildDef(child, seen));
|
|
9427
9935
|
}
|
|
9428
|
-
function
|
|
9936
|
+
function childrenOf3(def) {
|
|
9429
9937
|
switch (def.tag) {
|
|
9430
9938
|
case "sequence":
|
|
9431
9939
|
case "choice":
|
|
@@ -9500,7 +10008,7 @@ function subtreeSizes(roots) {
|
|
|
9500
10008
|
const def = p._def;
|
|
9501
10009
|
let s = 1;
|
|
9502
10010
|
if (def.tag !== "lazy") {
|
|
9503
|
-
for (const child of
|
|
10011
|
+
for (const child of childrenOf3(def)) s += child._def.tag === "lazy" ? 1 : sz(child);
|
|
9504
10012
|
}
|
|
9505
10013
|
sizes.set(p, s);
|
|
9506
10014
|
return s;
|
|
@@ -9521,7 +10029,7 @@ function subtreeSizes(roots) {
|
|
|
9521
10029
|
return;
|
|
9522
10030
|
}
|
|
9523
10031
|
sz(p);
|
|
9524
|
-
for (const child of
|
|
10032
|
+
for (const child of childrenOf3(def)) visit(child);
|
|
9525
10033
|
};
|
|
9526
10034
|
for (const root of roots) visit(root);
|
|
9527
10035
|
return sizes;
|
|
@@ -9531,7 +10039,7 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9531
10039
|
const recursive = /* @__PURE__ */ new Set();
|
|
9532
10040
|
const descended = /* @__PURE__ */ new Set();
|
|
9533
10041
|
const active = /* @__PURE__ */ new Set();
|
|
9534
|
-
function
|
|
10042
|
+
function walk(p) {
|
|
9535
10043
|
const def = p._def;
|
|
9536
10044
|
if (def.tag === "lazy") {
|
|
9537
10045
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
@@ -9548,17 +10056,17 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9548
10056
|
return;
|
|
9549
10057
|
}
|
|
9550
10058
|
active.add(p);
|
|
9551
|
-
|
|
10059
|
+
walk(resolved);
|
|
9552
10060
|
active.delete(p);
|
|
9553
10061
|
return;
|
|
9554
10062
|
}
|
|
9555
10063
|
if (isHoistableTag(def.tag)) {
|
|
9556
10064
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
9557
10065
|
}
|
|
9558
|
-
for (const child of
|
|
10066
|
+
for (const child of childrenOf3(def)) walk(child);
|
|
9559
10067
|
}
|
|
9560
10068
|
const rootsArr = [...roots];
|
|
9561
|
-
for (const root of rootsArr)
|
|
10069
|
+
for (const root of rootsArr) walk(root);
|
|
9562
10070
|
return { counts, recursive, sizes: subtreeSizes(rootsArr) };
|
|
9563
10071
|
}
|
|
9564
10072
|
function ruleDependencies(ruleMap) {
|
|
@@ -9568,7 +10076,7 @@ function ruleDependencies(ruleMap) {
|
|
|
9568
10076
|
for (const [name, comb] of ruleMap) {
|
|
9569
10077
|
const found = /* @__PURE__ */ new Set();
|
|
9570
10078
|
const seen = /* @__PURE__ */ new Set();
|
|
9571
|
-
const
|
|
10079
|
+
const walk = (p, isRoot) => {
|
|
9572
10080
|
const def = p._def;
|
|
9573
10081
|
const boundary = def.tag === "lazy" ? nameOf.get(p) ?? p._ruleName : nameOf.get(p);
|
|
9574
10082
|
if (!isRoot && boundary !== void 0) {
|
|
@@ -9584,12 +10092,12 @@ function ruleDependencies(ruleMap) {
|
|
|
9584
10092
|
} catch {
|
|
9585
10093
|
return;
|
|
9586
10094
|
}
|
|
9587
|
-
|
|
10095
|
+
walk(resolved, false);
|
|
9588
10096
|
return;
|
|
9589
10097
|
}
|
|
9590
|
-
for (const child of
|
|
10098
|
+
for (const child of childrenOf3(def)) walk(child, false);
|
|
9591
10099
|
};
|
|
9592
|
-
|
|
10100
|
+
walk(comb, true);
|
|
9593
10101
|
deps.set(name, [...found]);
|
|
9594
10102
|
}
|
|
9595
10103
|
return deps;
|
|
@@ -9736,6 +10244,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9736
10244
|
runDuplicationDiagnostic(combinator, opts?.duplication);
|
|
9737
10245
|
markUnusedValues(combinator);
|
|
9738
10246
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
10247
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || combinator._meta.rootTriviaClassified === true;
|
|
9739
10248
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9740
10249
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9741
10250
|
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
@@ -9762,7 +10271,11 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9762
10271
|
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9763
10272
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9764
10273
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9765
|
-
...
|
|
10274
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10275
|
+
...grammarTrivia ? {
|
|
10276
|
+
activeTrivia: grammarTrivia,
|
|
10277
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10278
|
+
} : {},
|
|
9766
10279
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
9767
10280
|
};
|
|
9768
10281
|
const r = emit(combinator, ctx, "_pos");
|
|
@@ -9910,10 +10423,11 @@ function assertRuleName(name) {
|
|
|
9910
10423
|
);
|
|
9911
10424
|
}
|
|
9912
10425
|
}
|
|
9913
|
-
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels) {
|
|
9914
|
-
const labels = rule._meta.triviaKindLabels
|
|
9915
|
-
|
|
9916
|
-
|
|
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,"} } })`;
|
|
9917
10431
|
}
|
|
9918
10432
|
function compileLinkable(ruleMapArg, ns, opts) {
|
|
9919
10433
|
if (!ns) throw new Error("compileLinkable: ns must be a non-empty namespace");
|
|
@@ -9921,6 +10435,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9921
10435
|
if (opts?.duplication !== void 0) runDuplicationDiagnosticRules(ruleMapArg, opts.duplication);
|
|
9922
10436
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
9923
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);
|
|
9924
10439
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9925
10440
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
9926
10441
|
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -9934,6 +10449,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9934
10449
|
return false;
|
|
9935
10450
|
}
|
|
9936
10451
|
});
|
|
10452
|
+
const nodeMeta = new Map(ruleMap.map(([name, rule]) => [name, collectGrammarReflection([[name, rule]], { followLazy: false })]));
|
|
9937
10453
|
const ctx = {
|
|
9938
10454
|
vars: 0,
|
|
9939
10455
|
indent: 1,
|
|
@@ -9963,7 +10479,11 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9963
10479
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
9964
10480
|
ns,
|
|
9965
10481
|
deferFirstSetRefs: true,
|
|
9966
|
-
...
|
|
10482
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10483
|
+
...grammarTrivia ? {
|
|
10484
|
+
activeTrivia: grammarTrivia,
|
|
10485
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10486
|
+
} : {},
|
|
9967
10487
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
9968
10488
|
};
|
|
9969
10489
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -10009,7 +10529,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10009
10529
|
scanExternal(resolved);
|
|
10010
10530
|
return;
|
|
10011
10531
|
}
|
|
10012
|
-
for (const child of
|
|
10532
|
+
for (const child of childrenOf3(def)) scanExternal(child);
|
|
10013
10533
|
};
|
|
10014
10534
|
for (const [, rule] of ruleMap) scanExternal(rule);
|
|
10015
10535
|
}
|
|
@@ -10095,7 +10615,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10095
10615
|
...r.stmts,
|
|
10096
10616
|
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
10097
10617
|
`}`
|
|
10098
|
-
].join("\n"), ctx.triviaKindLabels));
|
|
10618
|
+
].join("\n"), ctx.triviaKindLabels, ctx.rootTriviaClassified));
|
|
10099
10619
|
}
|
|
10100
10620
|
const firstSets = /* @__PURE__ */ new Map();
|
|
10101
10621
|
const firstSetRecipes = /* @__PURE__ */ new Map();
|
|
@@ -10131,6 +10651,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10131
10651
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10132
10652
|
hasDirectBuilders: ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
10133
10653
|
isRecognitionOnly: !hasSemanticReduction(ruleMap.map(([, rule]) => rule), externalRefs),
|
|
10654
|
+
nodeMeta,
|
|
10134
10655
|
mfFns: mfSrcs ? [] : ctx.mapFns,
|
|
10135
10656
|
buildFns: buildSrcs ? [] : ctx.buildFns
|
|
10136
10657
|
};
|
|
@@ -10151,7 +10672,7 @@ function hasExternalRuleRef(ruleMap) {
|
|
|
10151
10672
|
if (resolved === void 0) return p._ruleName !== void 0;
|
|
10152
10673
|
return visit(resolved);
|
|
10153
10674
|
}
|
|
10154
|
-
return
|
|
10675
|
+
return childrenOf3(def).some(visit);
|
|
10155
10676
|
};
|
|
10156
10677
|
return ruleMap.some(([, rule]) => visit(rule));
|
|
10157
10678
|
}
|
|
@@ -10173,7 +10694,7 @@ function hasSemanticReduction(roots, externalRefs) {
|
|
|
10173
10694
|
return true;
|
|
10174
10695
|
}
|
|
10175
10696
|
}
|
|
10176
|
-
return
|
|
10697
|
+
return childrenOf3(def).some(visit);
|
|
10177
10698
|
};
|
|
10178
10699
|
return roots.some(visit);
|
|
10179
10700
|
}
|
|
@@ -10246,7 +10767,7 @@ function withCtx(extra, combinator) {
|
|
|
10246
10767
|
}
|
|
10247
10768
|
|
|
10248
10769
|
// src/compiler/ir-serialize.ts
|
|
10249
|
-
function
|
|
10770
|
+
function childrenOf4(def) {
|
|
10250
10771
|
switch (def.tag) {
|
|
10251
10772
|
case "sequence":
|
|
10252
10773
|
case "choice":
|
|
@@ -10310,6 +10831,10 @@ function projectOpt(project) {
|
|
|
10310
10831
|
if (project === void 0) return void 0;
|
|
10311
10832
|
return `project: ${project}`;
|
|
10312
10833
|
}
|
|
10834
|
+
function tagsOpt(tags) {
|
|
10835
|
+
if (tags === void 0 || tags.length === 0) return void 0;
|
|
10836
|
+
return `tags: ${JSON.stringify(tags)}`;
|
|
10837
|
+
}
|
|
10313
10838
|
function matcherExpr(entry) {
|
|
10314
10839
|
switch (entry.kind) {
|
|
10315
10840
|
case "startsWith":
|
|
@@ -10439,6 +10964,7 @@ function evalRuleMapIR(ir) {
|
|
|
10439
10964
|
"transform",
|
|
10440
10965
|
"skip",
|
|
10441
10966
|
"trivia",
|
|
10967
|
+
"classifiedTrivia",
|
|
10442
10968
|
"label",
|
|
10443
10969
|
"field",
|
|
10444
10970
|
"expect",
|
|
@@ -10479,6 +11005,7 @@ function evalRuleMapIR(ir) {
|
|
|
10479
11005
|
transform,
|
|
10480
11006
|
skip,
|
|
10481
11007
|
trivia,
|
|
11008
|
+
classifiedTrivia,
|
|
10482
11009
|
label,
|
|
10483
11010
|
field,
|
|
10484
11011
|
expect,
|
|
@@ -10523,7 +11050,7 @@ var Serializer = class {
|
|
|
10523
11050
|
if (target) this.assertNoRuleRef(target, seen);
|
|
10524
11051
|
return;
|
|
10525
11052
|
}
|
|
10526
|
-
for (const child of
|
|
11053
|
+
for (const child of childrenOf4(c._def)) this.assertNoRuleRef(child, seen);
|
|
10527
11054
|
}
|
|
10528
11055
|
/** A `rules()` map wraps each rule value in a named `lazy` proxy; the real body is
|
|
10529
11056
|
* its target (compileLinkable unwraps the same way). A ref INSIDE a body stays a
|
|
@@ -10587,7 +11114,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10587
11114
|
this.counts.set(c, (this.counts.get(c) ?? 0) + 1);
|
|
10588
11115
|
if ((this.counts.get(c) ?? 0) > 1) return;
|
|
10589
11116
|
active.add(c);
|
|
10590
|
-
for (const child of
|
|
11117
|
+
for (const child of childrenOf4(def)) this.analyze(child, active);
|
|
10591
11118
|
active.delete(c);
|
|
10592
11119
|
}
|
|
10593
11120
|
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
@@ -10704,12 +11231,14 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10704
11231
|
case "node": {
|
|
10705
11232
|
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
10706
11233
|
const projectEntry = projectOpt(def.project);
|
|
11234
|
+
const tagEntry = tagsOpt(def.tags);
|
|
10707
11235
|
const optEntries = [
|
|
10708
11236
|
...def.unwrap ? ["unwrap: true"] : [],
|
|
10709
11237
|
...def.collapse ? ["collapse: true"] : [],
|
|
10710
11238
|
...projectEntry === void 0 ? [] : [projectEntry],
|
|
10711
11239
|
...def.captureTrivia ? ["captureTrivia: true"] : [],
|
|
10712
|
-
...def.trailingTrivia ? ["trailingTrivia: true"] : []
|
|
11240
|
+
...def.trailingTrivia ? ["trailingTrivia: true"] : [],
|
|
11241
|
+
...tagEntry === void 0 ? [] : [tagEntry]
|
|
10713
11242
|
];
|
|
10714
11243
|
const opts = optEntries.length > 0 ? `, { ${optEntries.join(", ")} }` : "";
|
|
10715
11244
|
if (def.type === void 0) {
|
|
@@ -10723,8 +11252,11 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10723
11252
|
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
10724
11253
|
}
|
|
10725
11254
|
case "grammar": {
|
|
10726
|
-
const
|
|
10727
|
-
|
|
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)})`;
|
|
10728
11260
|
}
|
|
10729
11261
|
case "withCtx": {
|
|
10730
11262
|
if (def.extraSrc === void 0) throw new Unserializable("withCtx without extraSrc");
|
|
@@ -10757,15 +11289,16 @@ function normalizeCstCollapse(collapse) {
|
|
|
10757
11289
|
}
|
|
10758
11290
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10759
11291
|
}
|
|
10760
|
-
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10761
|
-
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
11292
|
+
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
11293
|
+
return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children2] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
10762
11294
|
}
|
|
10763
|
-
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
11295
|
+
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
10764
11296
|
if (typeof typeOrOptions === "string") {
|
|
10765
11297
|
return buildCstNode(typeOrOptions, children2 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
10766
11298
|
}
|
|
10767
11299
|
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
10768
|
-
const
|
|
11300
|
+
const materializeTags = typeOrOptions?.tags === true;
|
|
11301
|
+
const host = (type, children3, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children3 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
10769
11302
|
host._parsemanCstOutput = true;
|
|
10770
11303
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
10771
11304
|
return host;
|
|
@@ -10807,6 +11340,7 @@ function fusedBody(pieces) {
|
|
|
10807
11340
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
10808
11341
|
];
|
|
10809
11342
|
const wrapperEntries = [...winner].map(([k, p]) => `${JSON.stringify(k)}: ${p.wrappers.get(k)}`);
|
|
11343
|
+
const reflection = mergeGrammarReflections([...winner].map(([k, p]) => p.nodeMeta.get(k) ?? { nodes: [] }));
|
|
10810
11344
|
const { mode, elided } = hostModeOfPieces(pieces);
|
|
10811
11345
|
const rawBody = [
|
|
10812
11346
|
...lines,
|
|
@@ -10815,6 +11349,7 @@ function fusedBody(pieces) {
|
|
|
10815
11349
|
"}",
|
|
10816
11350
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_MODE.description)}), { value: ${JSON.stringify(mode)}, enumerable: false })`,
|
|
10817
11351
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_ELIDED.description)}), { value: ${JSON.stringify(elided)}, enumerable: false })`,
|
|
11352
|
+
`Object.defineProperty(_map, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`,
|
|
10818
11353
|
// …and on each rule FUNCTION, because `run(map.Rule, …)` is handed the rule, not the
|
|
10819
11354
|
// map, and would otherwise have nothing to check against. Done once at fuse time,
|
|
10820
11355
|
// before any rule has been called, so it costs nothing per parse.
|
|
@@ -11618,157 +12153,26 @@ function parseDoc(registry, rootRule, input, opts = {}) {
|
|
|
11618
12153
|
return new ParseDocImpl(registry, rootRule, opts, { abs: null }, [fail], null, input);
|
|
11619
12154
|
}
|
|
11620
12155
|
|
|
11621
|
-
// src/cst/trivia-entries.ts
|
|
11622
|
-
var EMPTY_INDICES = Object.freeze([]);
|
|
11623
|
-
var EMPTY_GAPS = Object.freeze([]);
|
|
11624
|
-
function entryOffset(i, stride) {
|
|
11625
|
-
return i * stride;
|
|
11626
|
-
}
|
|
11627
|
-
function triviaEntries(log, labels, opts) {
|
|
11628
|
-
const baseStride = opts?.nodeLog ? 3 : 2;
|
|
11629
|
-
const stride = labels ? baseStride + 1 : baseStride;
|
|
11630
|
-
const length = Math.floor(log.length / stride);
|
|
11631
|
-
return {
|
|
11632
|
-
length,
|
|
11633
|
-
labels,
|
|
11634
|
-
stride,
|
|
11635
|
-
start(i) {
|
|
11636
|
-
return log[entryOffset(i, stride)];
|
|
11637
|
-
},
|
|
11638
|
-
end(i) {
|
|
11639
|
-
return log[entryOffset(i, stride) + 1];
|
|
11640
|
-
},
|
|
11641
|
-
insertIndex(i) {
|
|
11642
|
-
return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
|
|
11643
|
-
},
|
|
11644
|
-
kindIndex(i) {
|
|
11645
|
-
if (!labels) return void 0;
|
|
11646
|
-
return log[entryOffset(i, stride) + baseStride];
|
|
11647
|
-
},
|
|
11648
|
-
kind(i) {
|
|
11649
|
-
const ki = labels ? log[entryOffset(i, stride) + baseStride] : void 0;
|
|
11650
|
-
return ki !== void 0 ? labels[ki] : void 0;
|
|
11651
|
-
},
|
|
11652
|
-
text(i, input) {
|
|
11653
|
-
const s = log[entryOffset(i, stride)];
|
|
11654
|
-
const e = log[entryOffset(i, stride) + 1];
|
|
11655
|
-
return input.slice(s, e);
|
|
11656
|
-
}
|
|
11657
|
-
};
|
|
11658
|
-
}
|
|
11659
|
-
function appendEntryRange(map, key, first, last) {
|
|
11660
|
-
let indices = map.get(key);
|
|
11661
|
-
if (!indices) {
|
|
11662
|
-
indices = [];
|
|
11663
|
-
map.set(key, indices);
|
|
11664
|
-
}
|
|
11665
|
-
for (let i = first; i <= last; i++) indices.push(i);
|
|
11666
|
-
}
|
|
11667
|
-
function buildGap(entries, start, end, first, last) {
|
|
11668
|
-
const entryIndices = [];
|
|
11669
|
-
for (let i = first; i <= last; i++) entryIndices.push(i);
|
|
11670
|
-
return {
|
|
11671
|
-
start,
|
|
11672
|
-
end,
|
|
11673
|
-
entryIndices,
|
|
11674
|
-
hasKind(kind) {
|
|
11675
|
-
for (const i of entryIndices) {
|
|
11676
|
-
if (entries.kind(i) === kind) return true;
|
|
11677
|
-
}
|
|
11678
|
-
return false;
|
|
11679
|
-
},
|
|
11680
|
-
text(input) {
|
|
11681
|
-
return input.slice(start, end);
|
|
11682
|
-
}
|
|
11683
|
-
};
|
|
11684
|
-
}
|
|
11685
|
-
function buildRootMaps(entries) {
|
|
11686
|
-
const before = /* @__PURE__ */ new Map();
|
|
11687
|
-
const after = /* @__PURE__ */ new Map();
|
|
11688
|
-
const beforeGaps = /* @__PURE__ */ new Map();
|
|
11689
|
-
const afterGaps = /* @__PURE__ */ new Map();
|
|
11690
|
-
const gaps = [];
|
|
11691
|
-
if (entries.length === 0) return { before, after, beforeGaps, afterGaps, gaps };
|
|
11692
|
-
const appendGap = (first2, last, start2, end2) => {
|
|
11693
|
-
const gap = buildGap(entries, start2, end2, first2, last);
|
|
11694
|
-
gaps.push(gap);
|
|
11695
|
-
afterGaps.set(start2, gap);
|
|
11696
|
-
beforeGaps.set(end2, gap);
|
|
11697
|
-
appendEntryRange(after, start2, first2, last);
|
|
11698
|
-
appendEntryRange(before, end2, first2, last);
|
|
11699
|
-
};
|
|
11700
|
-
let first = 0;
|
|
11701
|
-
let start = entries.start(0);
|
|
11702
|
-
let end = entries.end(0);
|
|
11703
|
-
for (let i = 1; i < entries.length; i++) {
|
|
11704
|
-
const nextStart = entries.start(i);
|
|
11705
|
-
const nextEnd = entries.end(i);
|
|
11706
|
-
if (nextStart === end) {
|
|
11707
|
-
end = nextEnd;
|
|
11708
|
-
continue;
|
|
11709
|
-
}
|
|
11710
|
-
appendGap(first, i - 1, start, end);
|
|
11711
|
-
first = i;
|
|
11712
|
-
start = nextStart;
|
|
11713
|
-
end = nextEnd;
|
|
11714
|
-
}
|
|
11715
|
-
appendGap(first, entries.length - 1, start, end);
|
|
11716
|
-
return { before, after, beforeGaps, afterGaps, gaps };
|
|
11717
|
-
}
|
|
11718
|
-
function buildRootTriviaIndex(log, labels) {
|
|
11719
|
-
const entries = triviaEntries(log, labels);
|
|
11720
|
-
let maps;
|
|
11721
|
-
const getMaps = () => {
|
|
11722
|
-
maps ??= buildRootMaps(entries);
|
|
11723
|
-
return maps;
|
|
11724
|
-
};
|
|
11725
|
-
return {
|
|
11726
|
-
entries,
|
|
11727
|
-
labels,
|
|
11728
|
-
get before() {
|
|
11729
|
-
return getMaps().before;
|
|
11730
|
-
},
|
|
11731
|
-
get after() {
|
|
11732
|
-
return getMaps().after;
|
|
11733
|
-
},
|
|
11734
|
-
entryIndicesBefore(offset) {
|
|
11735
|
-
return getMaps().before.get(offset) ?? EMPTY_INDICES;
|
|
11736
|
-
},
|
|
11737
|
-
entryIndicesAfter(offset) {
|
|
11738
|
-
return getMaps().after.get(offset) ?? EMPTY_INDICES;
|
|
11739
|
-
},
|
|
11740
|
-
gapBefore(offset) {
|
|
11741
|
-
return getMaps().beforeGaps.get(offset);
|
|
11742
|
-
},
|
|
11743
|
-
gapAfter(offset) {
|
|
11744
|
-
return getMaps().afterGaps.get(offset);
|
|
11745
|
-
},
|
|
11746
|
-
gaps() {
|
|
11747
|
-
return getMaps().gaps;
|
|
11748
|
-
},
|
|
11749
|
-
gapsWithKind(kind) {
|
|
11750
|
-
const kinds = typeof kind === "string" ? [kind] : kind;
|
|
11751
|
-
const matches2 = [];
|
|
11752
|
-
for (const gap of getMaps().gaps) {
|
|
11753
|
-
for (const k of kinds) {
|
|
11754
|
-
if (gap.hasKind(k)) {
|
|
11755
|
-
matches2.push(gap);
|
|
11756
|
-
break;
|
|
11757
|
-
}
|
|
11758
|
-
}
|
|
11759
|
-
}
|
|
11760
|
-
return matches2.length === 0 ? EMPTY_GAPS : matches2;
|
|
11761
|
-
}
|
|
11762
|
-
};
|
|
11763
|
-
}
|
|
11764
|
-
|
|
11765
12156
|
// src/functional/run.ts
|
|
11766
12157
|
var invoke = (r, input, pos, ctx) => typeof r === "function" ? r(input, pos, ctx) : r.parse(input, pos, ctx);
|
|
11767
12158
|
function triviaKindLabelsFromRunnable(r) {
|
|
11768
12159
|
if (!r) return void 0;
|
|
11769
12160
|
if (typeof r === "function") return r._meta?.triviaKindLabels;
|
|
11770
12161
|
const grammarTrivia = r._meta.grammarTrivia;
|
|
11771
|
-
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;
|
|
11772
12176
|
}
|
|
11773
12177
|
function runOnce(entry, input, options, phase, profileState) {
|
|
11774
12178
|
if (typeof entry !== "function" && typeof entry?.parse !== "function") {
|
|
@@ -11776,13 +12180,31 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
11776
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).`
|
|
11777
12181
|
);
|
|
11778
12182
|
}
|
|
11779
|
-
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;
|
|
11780
12187
|
const errors = [];
|
|
11781
12188
|
const profile = profileState ?? (phase === void 0 ? void 0 : { phase, nodes: 0, childSlots: 0, rawSlots: 0, triviaSlots: 0, fieldSlots: 0, hostCalls: 0 });
|
|
11782
12189
|
const skipGlobalSinks = phase === "recognizer" || phase === "capture";
|
|
11783
12190
|
const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
|
|
11784
12191
|
const grammarScanSkip = typeof entry !== "function" ? entry._meta.grammarScanSkip : void 0;
|
|
11785
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
|
+
}
|
|
11786
12208
|
const stamped = entry;
|
|
11787
12209
|
assertHostModeCompatible(
|
|
11788
12210
|
typeof entry === "function" ? stamped[FUSED_HOST_MODE] ?? "ast" : entry._meta.grammarHostMode ?? "ast",
|
|
@@ -11791,7 +12213,15 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
11791
12213
|
);
|
|
11792
12214
|
const ctx = {
|
|
11793
12215
|
trackLines: false,
|
|
11794
|
-
...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
|
+
},
|
|
11795
12225
|
build: options.build,
|
|
11796
12226
|
state: options.state,
|
|
11797
12227
|
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...triviaKindLabels ? { triviaKindLabels } : {} } : triviaKindLabels ? { triviaKindLabels } : {},
|
|
@@ -11816,9 +12246,13 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
11816
12246
|
span: r.span ?? { start: 0, end: 0 },
|
|
11817
12247
|
expected: r.ok ? [] : r.expected ?? [],
|
|
11818
12248
|
errors,
|
|
11819
|
-
|
|
11820
|
-
|
|
11821
|
-
|
|
12249
|
+
...selectedRootLog !== void 0 && selectedRootLog.length > 0 ? {
|
|
12250
|
+
rootTrivia: {
|
|
12251
|
+
rows: selectedRootLog,
|
|
12252
|
+
select: rootTriviaSelection,
|
|
12253
|
+
index: buildRootTriviaIndex(selectedRootLog, rootTriviaSelection)
|
|
12254
|
+
}
|
|
12255
|
+
} : {},
|
|
11822
12256
|
unconsumedFrom
|
|
11823
12257
|
};
|
|
11824
12258
|
}
|
|
@@ -12243,38 +12677,48 @@ function buildTriviaIndex(root, input = "", opts) {
|
|
|
12243
12677
|
}
|
|
12244
12678
|
|
|
12245
12679
|
// src/cst/walk.ts
|
|
12246
|
-
function
|
|
12247
|
-
|
|
12248
|
-
|
|
12249
|
-
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
|
|
12256
|
-
|
|
12257
|
-
|
|
12258
|
-
const
|
|
12259
|
-
|
|
12260
|
-
|
|
12261
|
-
|
|
12262
|
-
|
|
12263
|
-
|
|
12264
|
-
|
|
12265
|
-
|
|
12266
|
-
|
|
12267
|
-
|
|
12268
|
-
|
|
12269
|
-
|
|
12270
|
-
|
|
12271
|
-
|
|
12680
|
+
function isCombinator(value) {
|
|
12681
|
+
return !!value && typeof value === "object" && "_def" in value && "_meta" in value && typeof value.parse === "function";
|
|
12682
|
+
}
|
|
12683
|
+
function reflectionFor(grammar) {
|
|
12684
|
+
const stamped = grammarReflectionOf(grammar);
|
|
12685
|
+
if (stamped) return stamped;
|
|
12686
|
+
const entries = Object.entries(grammar).filter((entry) => isCombinator(entry[1]));
|
|
12687
|
+
return collectGrammarReflection(entries);
|
|
12688
|
+
}
|
|
12689
|
+
function createVisitor(grammar, spec) {
|
|
12690
|
+
const reflection = reflectionFor(grammar);
|
|
12691
|
+
const typeHandlers = spec.type;
|
|
12692
|
+
const tagSpec = spec.tag;
|
|
12693
|
+
const tagHandlersByType = /* @__PURE__ */ new Map();
|
|
12694
|
+
if (tagSpec !== void 0) {
|
|
12695
|
+
for (const node2 of reflection.nodes) {
|
|
12696
|
+
const handlers = [];
|
|
12697
|
+
for (const tag of node2.tags) {
|
|
12698
|
+
const handler = tagSpec[tag];
|
|
12699
|
+
if (handler) handlers.push(handler);
|
|
12700
|
+
}
|
|
12701
|
+
if (handlers.length > 0) tagHandlersByType.set(node2.type, handlers);
|
|
12702
|
+
}
|
|
12703
|
+
}
|
|
12704
|
+
return (root, ctx = void 0) => {
|
|
12705
|
+
const go = (node2, parent) => {
|
|
12706
|
+
const descend = spec.enter ? spec.enter(node2, parent, ctx) : void 0;
|
|
12707
|
+
if (node2._tag === "node" && node2.type !== void 0) {
|
|
12708
|
+
typeHandlers?.[node2.type]?.(node2, parent, ctx);
|
|
12709
|
+
const tagHandlers = tagHandlersByType.get(node2.type);
|
|
12710
|
+
if (tagHandlers !== void 0) {
|
|
12711
|
+
for (const handler of tagHandlers) handler(node2, parent, ctx);
|
|
12272
12712
|
}
|
|
12273
12713
|
}
|
|
12274
|
-
|
|
12275
|
-
|
|
12714
|
+
const children2 = node2.children;
|
|
12715
|
+
if (descend !== false && Array.isArray(children2)) {
|
|
12716
|
+
for (const child of children2) go(child, node2);
|
|
12717
|
+
}
|
|
12718
|
+
spec.leave?.(node2, parent, ctx);
|
|
12719
|
+
};
|
|
12720
|
+
go(root, null);
|
|
12276
12721
|
};
|
|
12277
|
-
return (node2) => api.visit(node2);
|
|
12278
12722
|
}
|
|
12279
12723
|
|
|
12280
12724
|
// src/cst/offset-model.ts
|
|
@@ -12494,6 +12938,7 @@ export {
|
|
|
12494
12938
|
buildTriviaIndex,
|
|
12495
12939
|
charClassMembers,
|
|
12496
12940
|
choice,
|
|
12941
|
+
classifiedTrivia,
|
|
12497
12942
|
collectLeafSlots,
|
|
12498
12943
|
commentsIn,
|
|
12499
12944
|
compile,
|
|
@@ -12571,7 +13016,6 @@ export {
|
|
|
12571
13016
|
trivia,
|
|
12572
13017
|
triviaEntries,
|
|
12573
13018
|
triviaKindMask,
|
|
12574
|
-
walk,
|
|
12575
13019
|
when,
|
|
12576
13020
|
withCtx,
|
|
12577
13021
|
word
|