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/plugin/index.cjs
CHANGED
|
@@ -1106,1031 +1106,1095 @@ function keywords(words, opts = {}) {
|
|
|
1106
1106
|
};
|
|
1107
1107
|
}
|
|
1108
1108
|
|
|
1109
|
-
// src/
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
_cstChildren: ctx._cstChildren,
|
|
1116
|
-
_cstRawChildren: ctx._cstRawChildren,
|
|
1117
|
-
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1118
|
-
_triviaLog: ctx._triviaLog,
|
|
1119
|
-
_fields: ctx._fields,
|
|
1120
|
-
_cstBuf: ctx._cstBuf,
|
|
1121
|
-
_tolerant: ctx._tolerant,
|
|
1122
|
-
_sync: ctx._sync
|
|
1123
|
-
};
|
|
1124
|
-
ctx._probe = void 0;
|
|
1125
|
-
ctx._errors = void 0;
|
|
1126
|
-
ctx._cstLeaves = void 0;
|
|
1127
|
-
ctx._cstChildren = void 0;
|
|
1128
|
-
ctx._cstRawChildren = void 0;
|
|
1129
|
-
ctx._cstTriviaLog = void 0;
|
|
1130
|
-
ctx._triviaLog = void 0;
|
|
1131
|
-
ctx._fields = void 0;
|
|
1132
|
-
ctx._cstBuf = void 0;
|
|
1133
|
-
ctx._tolerant = void 0;
|
|
1134
|
-
ctx._sync = void 0;
|
|
1135
|
-
try {
|
|
1136
|
-
return sentinel.parse(input, pos, ctx).ok;
|
|
1137
|
-
} finally {
|
|
1138
|
-
ctx._probe = s._probe;
|
|
1139
|
-
ctx._errors = s._errors;
|
|
1140
|
-
ctx._cstLeaves = s._cstLeaves;
|
|
1141
|
-
ctx._cstChildren = s._cstChildren;
|
|
1142
|
-
ctx._cstRawChildren = s._cstRawChildren;
|
|
1143
|
-
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1144
|
-
ctx._triviaLog = s._triviaLog;
|
|
1145
|
-
ctx._fields = s._fields;
|
|
1146
|
-
ctx._cstBuf = s._cstBuf;
|
|
1147
|
-
ctx._tolerant = s._tolerant;
|
|
1148
|
-
ctx._sync = s._sync;
|
|
1149
|
-
}
|
|
1109
|
+
// src/cst/trivia-kinds.ts
|
|
1110
|
+
var labeledTriviaSpecs = /* @__PURE__ */ new WeakMap();
|
|
1111
|
+
function unwrapTrivia(p) {
|
|
1112
|
+
let cur = p;
|
|
1113
|
+
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1114
|
+
return cur;
|
|
1150
1115
|
}
|
|
1151
|
-
function
|
|
1152
|
-
if (
|
|
1153
|
-
return
|
|
1154
|
-
_tag: "orSentinel",
|
|
1155
|
-
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1156
|
-
_def: { tag: "unknown" },
|
|
1157
|
-
parse(input, pos, ctx) {
|
|
1158
|
-
const ra = a.parse(input, pos, ctx);
|
|
1159
|
-
if (ra.ok) return ra;
|
|
1160
|
-
return b.parse(input, pos, ctx);
|
|
1161
|
-
}
|
|
1162
|
-
};
|
|
1116
|
+
function peelLabel(p) {
|
|
1117
|
+
if (p._def.tag === "label") return { label: p._def.label, parser: p._def.parser };
|
|
1118
|
+
return null;
|
|
1163
1119
|
}
|
|
1164
|
-
function
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1120
|
+
function analyzeLabeledTrivia(trivia2) {
|
|
1121
|
+
const cached = labeledTriviaSpecs.get(trivia2);
|
|
1122
|
+
if (cached !== void 0) return cached;
|
|
1123
|
+
let core = unwrapTrivia(trivia2);
|
|
1124
|
+
let minRepeats = 1;
|
|
1125
|
+
if (core._def.tag === "oneOrMore") {
|
|
1126
|
+
core = core._def.parser;
|
|
1127
|
+
minRepeats = 1;
|
|
1128
|
+
} else if (core._def.tag === "many") {
|
|
1129
|
+
core = core._def.parser;
|
|
1130
|
+
minRepeats = 0;
|
|
1131
|
+
}
|
|
1132
|
+
const arms = [];
|
|
1133
|
+
if (core._def.tag === "choice") {
|
|
1134
|
+
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1135
|
+
const peeled = peelLabel(core._def.parsers[i]);
|
|
1136
|
+
if (!peeled) {
|
|
1137
|
+
labeledTriviaSpecs.set(trivia2, null);
|
|
1138
|
+
return null;
|
|
1177
1139
|
}
|
|
1178
|
-
|
|
1140
|
+
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1141
|
+
}
|
|
1142
|
+
} else {
|
|
1143
|
+
const peeled = peelLabel(core);
|
|
1144
|
+
if (!peeled) {
|
|
1145
|
+
labeledTriviaSpecs.set(trivia2, null);
|
|
1146
|
+
return null;
|
|
1179
1147
|
}
|
|
1148
|
+
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1149
|
+
}
|
|
1150
|
+
const spec = {
|
|
1151
|
+
labels: arms.map((a) => a.label),
|
|
1152
|
+
arms,
|
|
1153
|
+
minRepeats
|
|
1180
1154
|
};
|
|
1155
|
+
labeledTriviaSpecs.set(trivia2, spec);
|
|
1156
|
+
return spec;
|
|
1181
1157
|
}
|
|
1182
|
-
function
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1188
|
-
ctx._errors?.push(error);
|
|
1189
|
-
return { error, end: scanPos };
|
|
1190
|
-
}
|
|
1191
|
-
function matchesAt(sentinel, input, pos, ctx) {
|
|
1192
|
-
return probeAt(sentinel, input, pos, ctx);
|
|
1158
|
+
function matchArmAt(input, pos, arm, state) {
|
|
1159
|
+
if (!startsFirstSet(arm, input, pos)) return null;
|
|
1160
|
+
const r = arm.parse(input, pos, { trackLines: false, state });
|
|
1161
|
+
if (!r.ok || r.span.end <= pos) return null;
|
|
1162
|
+
return { end: r.span.end };
|
|
1193
1163
|
}
|
|
1194
|
-
function
|
|
1195
|
-
|
|
1164
|
+
function scanLabeledTriviaChunks(input, cur, spec, state) {
|
|
1165
|
+
const chunks = [];
|
|
1166
|
+
let pos = cur;
|
|
1167
|
+
while (pos < input.length) {
|
|
1168
|
+
let matched = null;
|
|
1169
|
+
for (const arm of spec.arms) {
|
|
1170
|
+
const m = matchArmAt(input, pos, arm.parser, state);
|
|
1171
|
+
if (m) {
|
|
1172
|
+
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1173
|
+
break;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
if (!matched) break;
|
|
1177
|
+
chunks.push({ start: pos, end: matched.end, kindIndex: matched.kindIndex });
|
|
1178
|
+
pos = matched.end;
|
|
1179
|
+
}
|
|
1180
|
+
if (chunks.length < spec.minRepeats) {
|
|
1181
|
+
return { end: cur, chunks: [] };
|
|
1182
|
+
}
|
|
1183
|
+
return { end: pos, chunks };
|
|
1196
1184
|
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1185
|
+
function scanLabeledTriviaEnd(input, cur, spec, state) {
|
|
1186
|
+
let pos = cur;
|
|
1187
|
+
let count = 0;
|
|
1188
|
+
while (pos < input.length) {
|
|
1189
|
+
let matched = null;
|
|
1190
|
+
for (const arm of spec.arms) {
|
|
1191
|
+
matched = matchArmAt(input, pos, arm.parser, state);
|
|
1192
|
+
if (matched) break;
|
|
1193
|
+
}
|
|
1194
|
+
if (!matched) break;
|
|
1195
|
+
pos = matched.end;
|
|
1196
|
+
count++;
|
|
1197
|
+
}
|
|
1198
|
+
return count < spec.minRepeats ? cur : pos;
|
|
1201
1199
|
}
|
|
1202
|
-
function
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
return [def.label];
|
|
1214
|
-
case "choice":
|
|
1215
|
-
return def.parsers.flatMap(deriveExpected2);
|
|
1216
|
-
case "dispatch":
|
|
1217
|
-
return deriveExpected2(def.selector);
|
|
1218
|
-
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
1219
|
-
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
1220
|
-
// able to fail first — deriving from term 0 alone named a token the parse
|
|
1221
|
-
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
1222
|
-
// nothing (its own expectation is about what must NOT be here), but it is
|
|
1223
|
-
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
1224
|
-
case "sequence": {
|
|
1225
|
-
const out = [];
|
|
1226
|
-
for (const term of def.parsers) {
|
|
1227
|
-
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
1228
|
-
if (!matchesEmpty(term)) break;
|
|
1200
|
+
function visitLabeledTrivia(input, cur, spec, state, visit) {
|
|
1201
|
+
if (spec.minRepeats > 1) return void 0;
|
|
1202
|
+
let pos = cur;
|
|
1203
|
+
let count = 0;
|
|
1204
|
+
while (pos < input.length) {
|
|
1205
|
+
let matched = null;
|
|
1206
|
+
for (const arm of spec.arms) {
|
|
1207
|
+
const match = matchArmAt(input, pos, arm.parser, state);
|
|
1208
|
+
if (match) {
|
|
1209
|
+
matched = { end: match.end, kindIndex: arm.kindIndex };
|
|
1210
|
+
break;
|
|
1229
1211
|
}
|
|
1230
|
-
return out;
|
|
1231
1212
|
}
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
case "not":
|
|
1255
|
-
case "peek":
|
|
1256
|
-
return deriveExpected2(def.parser);
|
|
1257
|
-
case "routed":
|
|
1258
|
-
return ["routed()"];
|
|
1259
|
-
case "lazy": {
|
|
1260
|
-
const name = c._ruleName;
|
|
1261
|
-
if (seen.has(c)) return name ? [name] : [];
|
|
1262
|
-
seen.add(c);
|
|
1263
|
-
try {
|
|
1264
|
-
return deriveExpected2(def.thunk());
|
|
1265
|
-
} catch {
|
|
1266
|
-
return name ? [name] : [];
|
|
1267
|
-
} finally {
|
|
1268
|
-
seen.delete(c);
|
|
1213
|
+
if (!matched) break;
|
|
1214
|
+
visit(pos, matched.end, matched.kindIndex);
|
|
1215
|
+
pos = matched.end;
|
|
1216
|
+
count++;
|
|
1217
|
+
}
|
|
1218
|
+
return count < spec.minRepeats ? cur : pos;
|
|
1219
|
+
}
|
|
1220
|
+
function recordTriviaChunks(ctx, chunks) {
|
|
1221
|
+
const kinds = ctx.triviaKindLabels;
|
|
1222
|
+
const mask = ctx._triviaCaptureMask;
|
|
1223
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1224
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
1225
|
+
const rootMark = rootLog?.length ?? 0;
|
|
1226
|
+
for (const ch2 of chunks) {
|
|
1227
|
+
pushTriviaLogEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1228
|
+
const rootKindIndex = ctx._rootTriviaCapture === false || rootLog === void 0 || rootKinds === void 0 || kinds === void 0 ? -1 : rootKinds[kinds[ch2.kindIndex] ?? ""] ?? -1;
|
|
1229
|
+
if (rootKindIndex >= 0) {
|
|
1230
|
+
rootLog.push(0, 0, ch2.start, ch2.end, rootKindIndex);
|
|
1231
|
+
}
|
|
1232
|
+
if (ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)) {
|
|
1233
|
+
if (mask === void 0 || kinds === void 0 || (mask & 1 << ch2.kindIndex) !== 0) {
|
|
1234
|
+
pushCstTriviaEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1269
1235
|
}
|
|
1270
1236
|
}
|
|
1271
|
-
default:
|
|
1272
|
-
return [];
|
|
1273
1237
|
}
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
isTrivia: false
|
|
1281
|
-
};
|
|
1282
|
-
return {
|
|
1283
|
-
_tag: "expect",
|
|
1284
|
-
_meta: meta,
|
|
1285
|
-
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1286
|
-
parse(input, pos, ctx) {
|
|
1287
|
-
const result = combinator.parse(input, pos, ctx);
|
|
1288
|
-
if (result.ok) return result;
|
|
1289
|
-
const span = { start: pos, end: pos };
|
|
1290
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1291
|
-
ctx._errors?.push(error);
|
|
1292
|
-
if (ctx._tolerant) captureError(ctx, error);
|
|
1293
|
-
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1238
|
+
if (rootLog !== void 0 && rootLog.length !== rootMark && chunks.length > 0) {
|
|
1239
|
+
const start = chunks[0].start;
|
|
1240
|
+
const end = chunks[chunks.length - 1].end;
|
|
1241
|
+
for (let offset = rootMark; offset < rootLog.length; offset += 5) {
|
|
1242
|
+
rootLog[offset] = start;
|
|
1243
|
+
rootLog[offset + 1] = end;
|
|
1294
1244
|
}
|
|
1295
|
-
}
|
|
1245
|
+
}
|
|
1296
1246
|
}
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
const
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
1304
|
-
let combined = { kind: "empty" };
|
|
1305
|
-
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
1306
|
-
const meta = {
|
|
1307
|
-
firstSet: combined,
|
|
1308
|
-
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1309
|
-
isTrivia: false,
|
|
1310
|
-
disjoint
|
|
1311
|
-
};
|
|
1312
|
-
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
1313
|
-
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1314
|
-
let greedyLitMap = null;
|
|
1315
|
-
let sortedParsers = null;
|
|
1316
|
-
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
1317
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1318
|
-
greedyLitMap = /* @__PURE__ */ new Map();
|
|
1319
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1320
|
-
if (i === strategy.superIndex) continue;
|
|
1321
|
-
const litVal = getCoreLiteralValue(parsers[i]);
|
|
1322
|
-
if (litVal !== null) greedyLitMap.set(litVal, i);
|
|
1323
|
-
}
|
|
1324
|
-
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
1325
|
-
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
1247
|
+
function triviaKindMask(labels, keep) {
|
|
1248
|
+
if (!labels) return void 0;
|
|
1249
|
+
let mask = 0;
|
|
1250
|
+
for (const name of keep) {
|
|
1251
|
+
const idx = labels.indexOf(name);
|
|
1252
|
+
if (idx >= 0) mask |= 1 << idx;
|
|
1326
1253
|
}
|
|
1254
|
+
return mask;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
// src/combinators/trivia-skip.ts
|
|
1258
|
+
var NOOP_COMMIT = () => {
|
|
1259
|
+
};
|
|
1260
|
+
var fastTriviaCache = /* @__PURE__ */ new WeakMap();
|
|
1261
|
+
function needsDeferredTriviaCommit(ctx) {
|
|
1262
|
+
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
1263
|
+
}
|
|
1264
|
+
function saveTriviaMark(ctx) {
|
|
1265
|
+
const m = saveCstMark(ctx);
|
|
1327
1266
|
return {
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1267
|
+
raw: m.raw,
|
|
1268
|
+
tlog: m.tlog,
|
|
1269
|
+
leaves: m.leaves,
|
|
1270
|
+
fields: m.fields,
|
|
1271
|
+
errors: m.errors,
|
|
1272
|
+
log: ctx._triviaLog ? ctx._triviaLog.length : 0,
|
|
1273
|
+
rootLog: ctx._rootTriviaLog ? ctx._rootTriviaLog.length : 0
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1276
|
+
function rollbackTrivia(ctx, mark) {
|
|
1277
|
+
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields, errors: mark.errors });
|
|
1278
|
+
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1279
|
+
if (ctx._rootTriviaLog && ctx._rootTriviaLog.length !== mark.rootLog) ctx._rootTriviaLog.length = mark.rootLog;
|
|
1280
|
+
}
|
|
1281
|
+
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1282
|
+
const probeCtx = {
|
|
1283
|
+
trackLines: ctx.trackLines,
|
|
1284
|
+
state: ctx.state,
|
|
1285
|
+
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1286
|
+
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1287
|
+
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1288
|
+
};
|
|
1289
|
+
const result = triviaP.parse(input, cur, probeCtx);
|
|
1290
|
+
ctx._lineScannedTo = probeCtx._lineScannedTo;
|
|
1291
|
+
return result;
|
|
1292
|
+
}
|
|
1293
|
+
function saveLookaheadMark(ctx) {
|
|
1294
|
+
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1295
|
+
}
|
|
1296
|
+
function rollbackLookahead(ctx, mark) {
|
|
1297
|
+
rollbackTrivia(ctx, mark);
|
|
1298
|
+
if (ctx._probe) ctx._probe.best = mark.probeBest;
|
|
1299
|
+
}
|
|
1300
|
+
function scanWithLabels(input, cur, ctx) {
|
|
1301
|
+
const triviaP = ctx.trivia;
|
|
1302
|
+
const spec = analyzeLabeledTrivia(triviaP);
|
|
1303
|
+
if (!spec) return { end: cur, commit: NOOP_COMMIT };
|
|
1304
|
+
const log = ctx._triviaLog;
|
|
1305
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1306
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
1307
|
+
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1308
|
+
const mask = ctx._triviaCaptureMask;
|
|
1309
|
+
let fullRows;
|
|
1310
|
+
let rootRows;
|
|
1311
|
+
let cstRows;
|
|
1312
|
+
const visitedEnd = visitLabeledTrivia(input, cur, spec, ctx.state, (start, matchEnd, kindIndex) => {
|
|
1313
|
+
if (log !== void 0) (fullRows ??= []).push(start, matchEnd, kindIndex);
|
|
1314
|
+
const selectedKind = rootLog === void 0 || rootKinds === void 0 || ctx._rootTriviaCapture === false ? void 0 : rootKinds[spec.labels[kindIndex] ?? ""];
|
|
1315
|
+
if (selectedKind !== void 0) (rootRows ??= []).push(start, matchEnd, selectedKind);
|
|
1316
|
+
if (captureTl && (mask === void 0 || (mask & 1 << kindIndex) !== 0)) {
|
|
1317
|
+
(cstRows ??= []).push(start, matchEnd, kindIndex);
|
|
1318
|
+
}
|
|
1319
|
+
});
|
|
1320
|
+
if (visitedEnd !== void 0) {
|
|
1321
|
+
if (visitedEnd === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1322
|
+
return {
|
|
1323
|
+
end: visitedEnd,
|
|
1324
|
+
commit: () => {
|
|
1325
|
+
if (fullRows !== void 0 && log !== void 0) log.push(...fullRows);
|
|
1326
|
+
if (rootRows !== void 0 && rootLog !== void 0) {
|
|
1327
|
+
for (let i = 0; i < rootRows.length; i += 3) {
|
|
1328
|
+
rootLog.push(cur, visitedEnd, rootRows[i], rootRows[i + 1], rootRows[i + 2]);
|
|
1349
1329
|
}
|
|
1350
1330
|
}
|
|
1351
|
-
if (
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1331
|
+
if (cstRows !== void 0) {
|
|
1332
|
+
for (let i = 0; i < cstRows.length; i += 3) {
|
|
1333
|
+
pushCstTriviaEntry(ctx, cstRows[i], cstRows[i + 1], cstRows[i + 2]);
|
|
1355
1334
|
}
|
|
1356
|
-
const result = parsers[idx].parse(input, pos, ctx);
|
|
1357
|
-
if (result.ok) return result;
|
|
1358
|
-
expected.push(...result.expected);
|
|
1359
|
-
if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
|
|
1360
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1361
|
-
}
|
|
1362
|
-
return {
|
|
1363
|
-
ok: false,
|
|
1364
|
-
expected: parsers.flatMap((p) => {
|
|
1365
|
-
const r = p.parse(input, pos, ctx);
|
|
1366
|
-
return r.ok ? [] : r.expected;
|
|
1367
|
-
}),
|
|
1368
|
-
span: { start: pos, end: pos }
|
|
1369
|
-
};
|
|
1370
|
-
}
|
|
1371
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1372
|
-
const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
|
|
1373
|
-
if (!superResult.ok) return superResult;
|
|
1374
|
-
const end = superResult.span.end;
|
|
1375
|
-
const litIdx = greedyLitMap.get(input.slice(pos, end));
|
|
1376
|
-
if (litIdx !== void 0) {
|
|
1377
|
-
const litVal = getCoreLiteralValue(parsers[litIdx]);
|
|
1378
|
-
const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
|
|
1379
|
-
return { ok: true, value, span: { start: pos, end } };
|
|
1380
|
-
}
|
|
1381
|
-
return superResult;
|
|
1382
|
-
}
|
|
1383
|
-
if (strategy?.tag === "literalsLongestFirst") {
|
|
1384
|
-
for (const p of sortedParsers) {
|
|
1385
|
-
const r = p.parse(input, pos, ctx);
|
|
1386
|
-
if (r.ok) return r;
|
|
1387
|
-
expected.push(...r.expected);
|
|
1388
|
-
}
|
|
1389
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1390
|
-
}
|
|
1391
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1392
|
-
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
1393
|
-
const mark = saveCstMark(ctx);
|
|
1394
|
-
const logLen = ctx._triviaLog?.length;
|
|
1395
|
-
const result = parsers[i].parse(input, pos, ctx);
|
|
1396
|
-
if (!result.ok) {
|
|
1397
|
-
rollbackCstCapture(ctx, mark);
|
|
1398
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1399
|
-
expected.push(...result.expected);
|
|
1400
|
-
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
1401
|
-
continue;
|
|
1402
1335
|
}
|
|
1403
|
-
const checks = autoNot[i];
|
|
1404
|
-
if (checks && autoNotFires(input, result.span.end, checks)) {
|
|
1405
|
-
rollbackCstCapture(ctx, mark);
|
|
1406
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1407
|
-
continue;
|
|
1408
|
-
}
|
|
1409
|
-
return result;
|
|
1410
1336
|
}
|
|
1411
|
-
|
|
1412
|
-
|
|
1337
|
+
};
|
|
1338
|
+
}
|
|
1339
|
+
const { end, chunks } = scanLabeledTriviaChunks(input, cur, spec, ctx.state);
|
|
1340
|
+
if (end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1341
|
+
return {
|
|
1342
|
+
end,
|
|
1343
|
+
commit: () => recordTriviaChunks(ctx, chunks)
|
|
1413
1344
|
};
|
|
1414
1345
|
}
|
|
1415
|
-
function
|
|
1416
|
-
const
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
const
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
const m = re.exec(litVal);
|
|
1431
|
-
return m !== null && m[0] === litVal;
|
|
1432
|
-
});
|
|
1433
|
-
if (allSubsumed) return { tag: "greedyClassify", superIndex };
|
|
1346
|
+
function skipWithLabels(input, cur, ctx) {
|
|
1347
|
+
const spec = analyzeLabeledTrivia(ctx.trivia);
|
|
1348
|
+
if (spec) return scanLabeledTriviaEnd(input, cur, spec, ctx.state);
|
|
1349
|
+
const tr = parseTriviaNoCapture(ctx.trivia, input, cur, ctx);
|
|
1350
|
+
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1351
|
+
}
|
|
1352
|
+
function advanceTrivia(input, cur, ctx) {
|
|
1353
|
+
const triviaP = ctx.trivia;
|
|
1354
|
+
if (!triviaP) return cur;
|
|
1355
|
+
if (!ctx.trackLines) {
|
|
1356
|
+
const fast2 = fastTriviaScanner(triviaP);
|
|
1357
|
+
if (fast2) return fast2(input, cur);
|
|
1358
|
+
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
1359
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1360
|
+
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1434
1361
|
}
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
);
|
|
1439
|
-
|
|
1362
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1363
|
+
const fast = fastTriviaScanner(triviaP);
|
|
1364
|
+
if (fast) {
|
|
1365
|
+
const end = fast(input, cur);
|
|
1366
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1367
|
+
return end;
|
|
1440
1368
|
}
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
function bareLeadingTermKey(term) {
|
|
1446
|
-
const d = term._def;
|
|
1447
|
-
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
1448
|
-
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
1449
|
-
return null;
|
|
1450
|
-
}
|
|
1451
|
-
function detectSharedPrefix(parsers) {
|
|
1452
|
-
if (parsers.length < 2) return null;
|
|
1453
|
-
let key = null;
|
|
1454
|
-
let prefix = null;
|
|
1455
|
-
const members = [];
|
|
1456
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1457
|
-
const term0 = leadingTermOfArm(parsers[i]);
|
|
1458
|
-
if (term0 === null) return null;
|
|
1459
|
-
const k = bareLeadingTermKey(term0);
|
|
1460
|
-
if (k === null) return null;
|
|
1461
|
-
if (key === null) {
|
|
1462
|
-
key = k;
|
|
1463
|
-
prefix = term0;
|
|
1464
|
-
} else if (k !== key) return null;
|
|
1465
|
-
members.push(i);
|
|
1369
|
+
if (ctx.triviaKindLabels) {
|
|
1370
|
+
const end = skipWithLabels(input, cur, ctx);
|
|
1371
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1372
|
+
return end;
|
|
1466
1373
|
}
|
|
1467
|
-
|
|
1468
|
-
return
|
|
1374
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1375
|
+
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1469
1376
|
}
|
|
1470
|
-
function
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1377
|
+
function scanTrivia(input, cur, ctx) {
|
|
1378
|
+
const triviaP = ctx.trivia;
|
|
1379
|
+
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1380
|
+
const log = ctx._triviaLog;
|
|
1381
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1382
|
+
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1383
|
+
if (!ctx.trackLines) {
|
|
1384
|
+
const fast2 = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1385
|
+
if (fast2 && log === void 0 && !captureTl) {
|
|
1386
|
+
return { end: fast2(input, cur), commit: NOOP_COMMIT };
|
|
1476
1387
|
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
1480
|
-
return d.parsers[0];
|
|
1481
|
-
}
|
|
1482
|
-
function computeAutoNot(parsers) {
|
|
1483
|
-
return parsers.map((p, i) => {
|
|
1484
|
-
const litVal = getCoreLiteralValue(p);
|
|
1485
|
-
if (litVal === null) return null;
|
|
1486
|
-
const checks = [];
|
|
1487
|
-
for (let j = i + 1; j < parsers.length; j++) {
|
|
1488
|
-
const other = parsers[j];
|
|
1489
|
-
const otherLit = getCoreLiteralValue(other);
|
|
1490
|
-
if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
|
|
1491
|
-
checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
|
|
1492
|
-
continue;
|
|
1493
|
-
}
|
|
1494
|
-
const regexDef = getCoreRegexDef(other);
|
|
1495
|
-
if (regexDef !== null) {
|
|
1496
|
-
const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
|
|
1497
|
-
if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
|
|
1498
|
-
}
|
|
1388
|
+
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1389
|
+
return scanWithLabels(input, cur, ctx);
|
|
1499
1390
|
}
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1391
|
+
if (ctx.triviaKindLabels) return { end: skipWithLabels(input, cur, ctx), commit: NOOP_COMMIT };
|
|
1392
|
+
if (log !== void 0 || rootLog !== void 0 || captureTl) {
|
|
1393
|
+
const tr3 = triviaP.parse(input, cur, {
|
|
1394
|
+
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1395
|
+
state: ctx.state
|
|
1396
|
+
});
|
|
1397
|
+
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1398
|
+
const end = tr3.span.end;
|
|
1399
|
+
return {
|
|
1400
|
+
end,
|
|
1401
|
+
commit: () => {
|
|
1402
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1403
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1404
|
+
}
|
|
1405
|
+
};
|
|
1510
1406
|
}
|
|
1407
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1408
|
+
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1511
1409
|
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
return null;
|
|
1519
|
-
}
|
|
1520
|
-
function getCoreRegexDef(p) {
|
|
1521
|
-
const def = p._def;
|
|
1522
|
-
if (def.tag === "regex") return { source: def.source, flags: def.flags };
|
|
1523
|
-
if (def.tag === "transform") return getCoreRegexDef(def.parser);
|
|
1524
|
-
if (def.tag === "label") return getCoreRegexDef(def.parser);
|
|
1525
|
-
return null;
|
|
1526
|
-
}
|
|
1527
|
-
function applyTransforms(p, value, span) {
|
|
1528
|
-
const def = p._def;
|
|
1529
|
-
if (def.tag === "transform") {
|
|
1530
|
-
const inner = applyTransforms(def.parser, value, span);
|
|
1531
|
-
return def.fn(inner, span);
|
|
1410
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1411
|
+
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1412
|
+
if (fast && log === void 0 && !captureTl) {
|
|
1413
|
+
const end = fast(input, cur);
|
|
1414
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1415
|
+
return { end, commit: NOOP_COMMIT };
|
|
1532
1416
|
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
re.lastIndex = 0;
|
|
1538
|
-
const base = re.exec(lit);
|
|
1539
|
-
if (!base || base[0] !== lit) return null;
|
|
1540
|
-
const contCodes = [];
|
|
1541
|
-
for (let code = 1; code < 128; code++) {
|
|
1542
|
-
re.lastIndex = 0;
|
|
1543
|
-
const m = re.exec(lit + String.fromCharCode(code));
|
|
1544
|
-
if (m && m[0].length > lit.length) contCodes.push(code);
|
|
1417
|
+
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1418
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1419
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1420
|
+
return scan;
|
|
1545
1421
|
}
|
|
1546
|
-
if (
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
codes.sort((a, b) => a - b);
|
|
1551
|
-
const ranges = [];
|
|
1552
|
-
let lo = codes[0], hi = codes[0];
|
|
1553
|
-
for (let i = 1; i < codes.length; i++) {
|
|
1554
|
-
if (codes[i] === hi + 1) {
|
|
1555
|
-
hi = codes[i];
|
|
1556
|
-
} else {
|
|
1557
|
-
ranges.push({ lo, hi });
|
|
1558
|
-
lo = hi = codes[i];
|
|
1559
|
-
}
|
|
1422
|
+
if (ctx.triviaKindLabels) {
|
|
1423
|
+
const end = skipWithLabels(input, cur, ctx);
|
|
1424
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1425
|
+
return { end, commit: NOOP_COMMIT };
|
|
1560
1426
|
}
|
|
1561
|
-
|
|
1562
|
-
|
|
1427
|
+
if (log !== void 0 || rootLog !== void 0 || captureTl) {
|
|
1428
|
+
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1429
|
+
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1430
|
+
const end = tr2.span.end;
|
|
1431
|
+
return {
|
|
1432
|
+
end,
|
|
1433
|
+
commit: () => {
|
|
1434
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1435
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1440
|
+
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1563
1441
|
}
|
|
1564
|
-
function
|
|
1565
|
-
if (
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
return
|
|
1442
|
+
function consumeTrivia(input, cur, ctx) {
|
|
1443
|
+
if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
|
|
1444
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1445
|
+
scan.commit();
|
|
1446
|
+
return scan.end;
|
|
1569
1447
|
}
|
|
1570
|
-
function
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
return
|
|
1448
|
+
function fastTriviaScanner(trivia2) {
|
|
1449
|
+
const cached = fastTriviaCache.get(trivia2);
|
|
1450
|
+
if (cached !== void 0) return cached;
|
|
1451
|
+
const scanner = buildFastTriviaScanner(trivia2);
|
|
1452
|
+
fastTriviaCache.set(trivia2, scanner);
|
|
1453
|
+
return scanner;
|
|
1576
1454
|
}
|
|
1577
|
-
function
|
|
1578
|
-
const
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1455
|
+
function buildFastTriviaScanner(trivia2) {
|
|
1456
|
+
const core = trivia2._def.tag === "trivia" ? trivia2._def.parser : trivia2;
|
|
1457
|
+
const direct = regexTriviaScanner(core);
|
|
1458
|
+
if (direct) return direct;
|
|
1459
|
+
const repeat = core._def.tag === "oneOrMore" || core._def.tag === "many" && core._def.min >= 1 ? core._def.parser : null;
|
|
1460
|
+
if (!repeat) return null;
|
|
1461
|
+
const one = regexTriviaScanner(repeat);
|
|
1462
|
+
if (one) return loopScanner([one]);
|
|
1463
|
+
if (repeat._def.tag !== "choice") return null;
|
|
1464
|
+
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1465
|
+
if (arms.some((s) => s === null)) return null;
|
|
1466
|
+
return loopScanner(arms);
|
|
1467
|
+
}
|
|
1468
|
+
function loopScanner(arms) {
|
|
1469
|
+
return (input, cur) => {
|
|
1470
|
+
let pos = cur;
|
|
1471
|
+
scan: while (pos < input.length) {
|
|
1472
|
+
for (const arm of arms) {
|
|
1473
|
+
const end = arm(input, pos);
|
|
1474
|
+
if (end > pos) {
|
|
1475
|
+
pos = end;
|
|
1476
|
+
continue scan;
|
|
1477
|
+
}
|
|
1585
1478
|
}
|
|
1479
|
+
break;
|
|
1586
1480
|
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
}
|
|
1590
|
-
|
|
1591
|
-
// src/cst/trivia-kinds.ts
|
|
1592
|
-
function unwrapTrivia(p) {
|
|
1593
|
-
let cur = p;
|
|
1594
|
-
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1595
|
-
return cur;
|
|
1481
|
+
return pos;
|
|
1482
|
+
};
|
|
1596
1483
|
}
|
|
1597
|
-
function
|
|
1598
|
-
if (
|
|
1599
|
-
|
|
1484
|
+
function regexTriviaScanner(parser2) {
|
|
1485
|
+
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1486
|
+
const source = parser2._def.source;
|
|
1487
|
+
return classRunSource(source) ?? altStarSource(source);
|
|
1600
1488
|
}
|
|
1601
|
-
function
|
|
1602
|
-
let
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
core = core._def.parser;
|
|
1606
|
-
minRepeats = 1;
|
|
1607
|
-
} else if (core._def.tag === "many") {
|
|
1608
|
-
core = core._def.parser;
|
|
1609
|
-
minRepeats = 0;
|
|
1610
|
-
}
|
|
1611
|
-
const arms = [];
|
|
1612
|
-
if (core._def.tag === "choice") {
|
|
1613
|
-
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1614
|
-
const peeled = peelLabel(core._def.parsers[i]);
|
|
1615
|
-
if (!peeled) return null;
|
|
1616
|
-
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1617
|
-
}
|
|
1618
|
-
} else {
|
|
1619
|
-
const peeled = peelLabel(core);
|
|
1620
|
-
if (!peeled) return null;
|
|
1621
|
-
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1489
|
+
function inRanges2(cp, ranges) {
|
|
1490
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
1491
|
+
const r = ranges[i];
|
|
1492
|
+
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1622
1493
|
}
|
|
1623
|
-
return
|
|
1494
|
+
return false;
|
|
1624
1495
|
}
|
|
1625
|
-
function
|
|
1626
|
-
const
|
|
1627
|
-
if (!
|
|
1628
|
-
return
|
|
1496
|
+
function classScanner(classBody) {
|
|
1497
|
+
const ranges = parseClassRanges(classBody);
|
|
1498
|
+
if (!ranges) return null;
|
|
1499
|
+
return (input, cur) => {
|
|
1500
|
+
let pos = cur;
|
|
1501
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1502
|
+
return pos;
|
|
1503
|
+
};
|
|
1629
1504
|
}
|
|
1630
|
-
function
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1639
|
-
break;
|
|
1640
|
-
}
|
|
1505
|
+
function untilLineBreakScanner(leaderCode) {
|
|
1506
|
+
return (input, cur) => {
|
|
1507
|
+
if (input.charCodeAt(cur) !== leaderCode) return cur;
|
|
1508
|
+
let pos = cur + 1;
|
|
1509
|
+
while (pos < input.length) {
|
|
1510
|
+
const cc = input.charCodeAt(pos);
|
|
1511
|
+
if (cc === 10 || cc === 13) break;
|
|
1512
|
+
pos++;
|
|
1641
1513
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1514
|
+
return pos;
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
function classRunSource(source) {
|
|
1518
|
+
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1519
|
+
return m ? classScanner(m[1]) : null;
|
|
1520
|
+
}
|
|
1521
|
+
function classifyTriviaArm(arm) {
|
|
1522
|
+
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1523
|
+
if (cls) {
|
|
1524
|
+
const ranges = parseClassRanges(cls[1]);
|
|
1525
|
+
return ranges ? { kind: "class", ranges } : null;
|
|
1645
1526
|
}
|
|
1646
|
-
|
|
1647
|
-
|
|
1527
|
+
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1528
|
+
if (lc) {
|
|
1529
|
+
const marker = lc[1];
|
|
1530
|
+
return { kind: "untilLineBreak", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1648
1531
|
}
|
|
1649
|
-
return
|
|
1532
|
+
return null;
|
|
1650
1533
|
}
|
|
1651
|
-
function
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1534
|
+
function armScanner(arm) {
|
|
1535
|
+
if (arm.kind === "untilLineBreak") return untilLineBreakScanner(arm.code);
|
|
1536
|
+
const ranges = arm.ranges;
|
|
1537
|
+
return (input, cur) => {
|
|
1538
|
+
let pos = cur;
|
|
1539
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1540
|
+
return pos;
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1543
|
+
function fusedTriviaScanner(ranges, leaders) {
|
|
1544
|
+
const c0 = leaders[0];
|
|
1545
|
+
const single = leaders.length === 1;
|
|
1546
|
+
return (input, cur) => {
|
|
1547
|
+
let pos = cur;
|
|
1548
|
+
const len = input.length;
|
|
1549
|
+
for (; ; ) {
|
|
1550
|
+
const c = input.charCodeAt(pos);
|
|
1551
|
+
if (pos < len && inRanges2(c, ranges)) {
|
|
1552
|
+
pos++;
|
|
1553
|
+
continue;
|
|
1554
|
+
}
|
|
1555
|
+
if (single ? c === c0 : leaders.includes(c)) {
|
|
1556
|
+
pos++;
|
|
1557
|
+
while (pos < len) {
|
|
1558
|
+
const cc = input.charCodeAt(pos);
|
|
1559
|
+
if (cc === 10 || cc === 13) break;
|
|
1560
|
+
pos++;
|
|
1561
|
+
}
|
|
1674
1562
|
continue;
|
|
1675
1563
|
}
|
|
1676
1564
|
break;
|
|
1677
1565
|
}
|
|
1678
|
-
|
|
1679
|
-
}
|
|
1680
|
-
return { end: pos, chunks };
|
|
1681
|
-
}
|
|
1682
|
-
function tryFastLabeledScan(input, cur, trivia2) {
|
|
1683
|
-
const spec = analyzeLabeledTrivia(trivia2);
|
|
1684
|
-
if (!spec || spec.arms.length !== 2) return null;
|
|
1685
|
-
const wsArm = spec.arms.find((a) => {
|
|
1686
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1687
|
-
return src != null && !src.includes("\\*");
|
|
1688
|
-
});
|
|
1689
|
-
const commentArm = spec.arms.find((a) => {
|
|
1690
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1691
|
-
return src != null && src.includes("\\*");
|
|
1692
|
-
});
|
|
1693
|
-
if (!wsArm || !commentArm) return null;
|
|
1694
|
-
const { chunks } = scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1695
|
-
if (chunks.length < spec.minRepeats) return { end: cur, chunks: [] };
|
|
1696
|
-
return scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1566
|
+
return pos;
|
|
1567
|
+
};
|
|
1697
1568
|
}
|
|
1698
|
-
function
|
|
1699
|
-
const
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1569
|
+
function splitTopLevelAlts(body) {
|
|
1570
|
+
const arms = [];
|
|
1571
|
+
let inClass = false;
|
|
1572
|
+
let start = 0;
|
|
1573
|
+
for (let i = 0; i < body.length; i++) {
|
|
1574
|
+
const c = body[i];
|
|
1575
|
+
if (c === "\\") {
|
|
1576
|
+
i++;
|
|
1577
|
+
continue;
|
|
1578
|
+
}
|
|
1579
|
+
if (inClass) {
|
|
1580
|
+
if (c === "]") inClass = false;
|
|
1581
|
+
continue;
|
|
1582
|
+
}
|
|
1583
|
+
if (c === "[") inClass = true;
|
|
1584
|
+
else if (c === "(") return null;
|
|
1585
|
+
else if (c === "|") {
|
|
1586
|
+
arms.push(body.slice(start, i));
|
|
1587
|
+
start = i + 1;
|
|
1707
1588
|
}
|
|
1708
1589
|
}
|
|
1590
|
+
arms.push(body.slice(start));
|
|
1591
|
+
return arms;
|
|
1709
1592
|
}
|
|
1710
|
-
function
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1593
|
+
function altStarSource(source) {
|
|
1594
|
+
const m = /^\(\?:(.*)\)[*+]$/.exec(source);
|
|
1595
|
+
if (!m) return null;
|
|
1596
|
+
const armSrcs = splitTopLevelAlts(m[1]);
|
|
1597
|
+
if (!armSrcs || armSrcs.length < 2) return null;
|
|
1598
|
+
const arms = [];
|
|
1599
|
+
for (const src of armSrcs) {
|
|
1600
|
+
const arm = classifyTriviaArm(src);
|
|
1601
|
+
if (!arm) return null;
|
|
1602
|
+
arms.push(arm);
|
|
1716
1603
|
}
|
|
1717
|
-
|
|
1604
|
+
const ranges = [];
|
|
1605
|
+
const leaders = [];
|
|
1606
|
+
for (const arm of arms) {
|
|
1607
|
+
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1608
|
+
else leaders.push(arm.code);
|
|
1609
|
+
}
|
|
1610
|
+
if (leaders.some((code) => inRanges2(code, ranges))) {
|
|
1611
|
+
return loopScanner(arms.map(armScanner));
|
|
1612
|
+
}
|
|
1613
|
+
if (leaders.length === 0) return armScanner({ kind: "class", ranges });
|
|
1614
|
+
return fusedTriviaScanner(ranges, leaders);
|
|
1718
1615
|
}
|
|
1719
1616
|
|
|
1720
|
-
// src/
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1736
|
-
const probeCtx = {
|
|
1737
|
-
trackLines: ctx.trackLines,
|
|
1738
|
-
state: ctx.state,
|
|
1739
|
-
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1740
|
-
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1741
|
-
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1617
|
+
// src/recovery/scan.ts
|
|
1618
|
+
function probeAt(sentinel, input, pos, ctx) {
|
|
1619
|
+
const s = {
|
|
1620
|
+
_probe: ctx._probe,
|
|
1621
|
+
_errors: ctx._errors,
|
|
1622
|
+
_cstLeaves: ctx._cstLeaves,
|
|
1623
|
+
_cstChildren: ctx._cstChildren,
|
|
1624
|
+
_cstRawChildren: ctx._cstRawChildren,
|
|
1625
|
+
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1626
|
+
_triviaLog: ctx._triviaLog,
|
|
1627
|
+
_rootTriviaLog: ctx._rootTriviaLog,
|
|
1628
|
+
_fields: ctx._fields,
|
|
1629
|
+
_cstBuf: ctx._cstBuf,
|
|
1630
|
+
_tolerant: ctx._tolerant,
|
|
1631
|
+
_sync: ctx._sync
|
|
1742
1632
|
};
|
|
1743
|
-
|
|
1744
|
-
ctx.
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1633
|
+
ctx._probe = void 0;
|
|
1634
|
+
ctx._errors = void 0;
|
|
1635
|
+
ctx._cstLeaves = void 0;
|
|
1636
|
+
ctx._cstChildren = void 0;
|
|
1637
|
+
ctx._cstRawChildren = void 0;
|
|
1638
|
+
ctx._cstTriviaLog = void 0;
|
|
1639
|
+
ctx._triviaLog = void 0;
|
|
1640
|
+
ctx._rootTriviaLog = void 0;
|
|
1641
|
+
ctx._fields = void 0;
|
|
1642
|
+
ctx._cstBuf = void 0;
|
|
1643
|
+
ctx._tolerant = void 0;
|
|
1644
|
+
ctx._sync = void 0;
|
|
1645
|
+
try {
|
|
1646
|
+
return sentinel.parse(input, pos, ctx).ok;
|
|
1647
|
+
} finally {
|
|
1648
|
+
ctx._probe = s._probe;
|
|
1649
|
+
ctx._errors = s._errors;
|
|
1650
|
+
ctx._cstLeaves = s._cstLeaves;
|
|
1651
|
+
ctx._cstChildren = s._cstChildren;
|
|
1652
|
+
ctx._cstRawChildren = s._cstRawChildren;
|
|
1653
|
+
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1654
|
+
ctx._triviaLog = s._triviaLog;
|
|
1655
|
+
ctx._rootTriviaLog = s._rootTriviaLog;
|
|
1656
|
+
ctx._fields = s._fields;
|
|
1657
|
+
ctx._cstBuf = s._cstBuf;
|
|
1658
|
+
ctx._tolerant = s._tolerant;
|
|
1659
|
+
ctx._sync = s._sync;
|
|
1660
|
+
}
|
|
1753
1661
|
}
|
|
1754
|
-
function
|
|
1755
|
-
|
|
1756
|
-
const spec = analyzeLabeledTrivia(triviaP);
|
|
1757
|
-
if (!spec) return { end: cur, commit: NOOP_COMMIT };
|
|
1758
|
-
const fast = tryFastLabeledScan(input, cur, triviaP);
|
|
1759
|
-
const { end, chunks } = fast ?? scanLabeledTriviaChunks(input, cur, spec);
|
|
1760
|
-
if (end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1662
|
+
function orSentinel(a, b) {
|
|
1663
|
+
if (b === void 0) return a;
|
|
1761
1664
|
return {
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
if (!ctx.trackLines) {
|
|
1770
|
-
const fast2 = fastTriviaScanner(triviaP);
|
|
1771
|
-
if (fast2) return fast2(input, cur);
|
|
1772
|
-
if (ctx.triviaKindLabels) {
|
|
1773
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1774
|
-
return scan.end;
|
|
1665
|
+
_tag: "orSentinel",
|
|
1666
|
+
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1667
|
+
_def: { tag: "unknown" },
|
|
1668
|
+
parse(input, pos, ctx) {
|
|
1669
|
+
const ra = a.parse(input, pos, ctx);
|
|
1670
|
+
if (ra.ok) return ra;
|
|
1671
|
+
return b.parse(input, pos, ctx);
|
|
1775
1672
|
}
|
|
1776
|
-
|
|
1777
|
-
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1778
|
-
}
|
|
1779
|
-
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1780
|
-
const fast = fastTriviaScanner(triviaP);
|
|
1781
|
-
if (fast) {
|
|
1782
|
-
const end = fast(input, cur);
|
|
1783
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1784
|
-
return end;
|
|
1785
|
-
}
|
|
1786
|
-
if (ctx.triviaKindLabels) {
|
|
1787
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1788
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1789
|
-
return scan.end;
|
|
1790
|
-
}
|
|
1791
|
-
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1792
|
-
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1673
|
+
};
|
|
1793
1674
|
}
|
|
1794
|
-
function
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
}
|
|
1807
|
-
if (log !== void 0 || captureTl) {
|
|
1808
|
-
const tr3 = triviaP.parse(input, cur, {
|
|
1809
|
-
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1810
|
-
state: ctx.state
|
|
1811
|
-
});
|
|
1812
|
-
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1813
|
-
const end = tr3.span.end;
|
|
1814
|
-
return {
|
|
1815
|
-
end,
|
|
1816
|
-
commit: () => {
|
|
1817
|
-
pushTriviaLogEntry(ctx, cur, end);
|
|
1818
|
-
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1675
|
+
function firstSetSentinel(fs2) {
|
|
1676
|
+
if (fs2.kind !== "ranges" || fs2.ranges.length === 0) return null;
|
|
1677
|
+
const ranges = fs2.ranges;
|
|
1678
|
+
return {
|
|
1679
|
+
_tag: "firstSetSentinel",
|
|
1680
|
+
_meta: { firstSet: fs2, canMatchNewline: false, isTrivia: false },
|
|
1681
|
+
_def: { tag: "unknown" },
|
|
1682
|
+
parse(input, pos) {
|
|
1683
|
+
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
1684
|
+
if (code !== void 0) {
|
|
1685
|
+
for (const r of ranges) {
|
|
1686
|
+
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1819
1687
|
}
|
|
1820
|
-
}
|
|
1688
|
+
}
|
|
1689
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
1821
1690
|
}
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
}
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
if (
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1691
|
+
};
|
|
1692
|
+
}
|
|
1693
|
+
function recoverScan(input, from, ctx, sync, expected) {
|
|
1694
|
+
let scanPos = from;
|
|
1695
|
+
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1696
|
+
const span = { start: from, end: scanPos };
|
|
1697
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
1698
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1699
|
+
ctx._errors?.push(error);
|
|
1700
|
+
return { error, end: scanPos };
|
|
1701
|
+
}
|
|
1702
|
+
function matchesAt(sentinel, input, pos, ctx) {
|
|
1703
|
+
return probeAt(sentinel, input, pos, ctx);
|
|
1704
|
+
}
|
|
1705
|
+
function captureError(ctx, error) {
|
|
1706
|
+
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
// src/combinators/sequence.ts
|
|
1710
|
+
function sequence(...parsers) {
|
|
1711
|
+
const meta = {
|
|
1712
|
+
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
1713
|
+
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
1714
|
+
firstSet: sequenceFirstSet(parsers),
|
|
1715
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1716
|
+
isTrivia: false
|
|
1717
|
+
};
|
|
1718
|
+
const def = { tag: "sequence", parsers };
|
|
1719
|
+
let followSentinels;
|
|
1720
|
+
function parseTolerant(input, pos, ctx) {
|
|
1721
|
+
followSentinels ??= parsers.map((_, i) => {
|
|
1722
|
+
const fs2 = parsers.slice(i + 1).reduce(
|
|
1723
|
+
(acc, p) => union(acc, firstSetOf(p)),
|
|
1724
|
+
{ kind: "empty" }
|
|
1725
|
+
);
|
|
1726
|
+
return firstSetSentinel(fs2);
|
|
1727
|
+
});
|
|
1728
|
+
const values = def.valueUnused ? void 0 : [];
|
|
1729
|
+
let cur = pos;
|
|
1730
|
+
const inheritedSync = ctx._sync;
|
|
1731
|
+
try {
|
|
1732
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1733
|
+
ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
1734
|
+
if (ctx.trivia && i > 0) {
|
|
1735
|
+
const mark = saveTriviaMark(ctx);
|
|
1736
|
+
let scanEnd;
|
|
1737
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
1738
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1739
|
+
scan.commit();
|
|
1740
|
+
scanEnd = scan.end;
|
|
1741
|
+
} else {
|
|
1742
|
+
scanEnd = advanceTrivia(input, cur, ctx);
|
|
1743
|
+
}
|
|
1744
|
+
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
1745
|
+
if (!result2.ok) return result2;
|
|
1746
|
+
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
1747
|
+
else rollbackTrivia(ctx, mark);
|
|
1748
|
+
if (values !== void 0) values.push(result2.value);
|
|
1749
|
+
continue;
|
|
1750
|
+
}
|
|
1751
|
+
const result = parsers[i].parse(input, cur, ctx);
|
|
1752
|
+
if (!result.ok) return result;
|
|
1753
|
+
if (values !== void 0) values.push(result.value);
|
|
1754
|
+
cur = result.span.end;
|
|
1846
1755
|
}
|
|
1756
|
+
} finally {
|
|
1757
|
+
ctx._sync = inheritedSync;
|
|
1758
|
+
}
|
|
1759
|
+
return {
|
|
1760
|
+
ok: true,
|
|
1761
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1762
|
+
value: values ?? void 0,
|
|
1763
|
+
span: { start: pos, end: cur }
|
|
1847
1764
|
};
|
|
1848
1765
|
}
|
|
1849
|
-
|
|
1850
|
-
|
|
1766
|
+
return {
|
|
1767
|
+
_tag: "sequence",
|
|
1768
|
+
_meta: meta,
|
|
1769
|
+
_def: def,
|
|
1770
|
+
parse(input, pos, ctx) {
|
|
1771
|
+
if (ctx._tolerant) return parseTolerant(input, pos, ctx);
|
|
1772
|
+
const values = def.valueUnused ? void 0 : [];
|
|
1773
|
+
let cur = pos;
|
|
1774
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1775
|
+
if (ctx.trivia && i > 0) {
|
|
1776
|
+
let scanEnd;
|
|
1777
|
+
let mark = saveTriviaMark(ctx);
|
|
1778
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
1779
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1780
|
+
scan.commit();
|
|
1781
|
+
scanEnd = scan.end;
|
|
1782
|
+
} else {
|
|
1783
|
+
scanEnd = advanceTrivia(input, cur, ctx);
|
|
1784
|
+
}
|
|
1785
|
+
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
1786
|
+
if (!result2.ok) return result2;
|
|
1787
|
+
if (result2.span.end > scanEnd) {
|
|
1788
|
+
cur = result2.span.end;
|
|
1789
|
+
} else {
|
|
1790
|
+
rollbackTrivia(ctx, mark);
|
|
1791
|
+
}
|
|
1792
|
+
if (values !== void 0) values.push(result2.value);
|
|
1793
|
+
continue;
|
|
1794
|
+
}
|
|
1795
|
+
const result = parsers[i].parse(input, cur, ctx);
|
|
1796
|
+
if (!result.ok) return result;
|
|
1797
|
+
if (values !== void 0) values.push(result.value);
|
|
1798
|
+
cur = result.span.end;
|
|
1799
|
+
}
|
|
1800
|
+
return {
|
|
1801
|
+
ok: true,
|
|
1802
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1803
|
+
value: values ?? void 0,
|
|
1804
|
+
span: { start: pos, end: cur }
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
};
|
|
1851
1808
|
}
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
return scan.end;
|
|
1809
|
+
|
|
1810
|
+
// src/combinators/expect.ts
|
|
1811
|
+
function deriveExpected(c) {
|
|
1812
|
+
return [...new Set(derive(c, /* @__PURE__ */ new Set()))];
|
|
1857
1813
|
}
|
|
1858
|
-
function
|
|
1859
|
-
const
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1814
|
+
function derive(c, seen) {
|
|
1815
|
+
const deriveExpected2 = (p) => derive(p, seen);
|
|
1816
|
+
const def = c._def;
|
|
1817
|
+
switch (def.tag) {
|
|
1818
|
+
case "literal":
|
|
1819
|
+
return [JSON.stringify(def.value)];
|
|
1820
|
+
case "regex":
|
|
1821
|
+
return [`/${def.source}/`];
|
|
1822
|
+
case "keywords":
|
|
1823
|
+
return def.words.map((w) => JSON.stringify(w));
|
|
1824
|
+
case "label":
|
|
1825
|
+
return [def.label];
|
|
1826
|
+
case "choice":
|
|
1827
|
+
return def.parsers.flatMap(deriveExpected2);
|
|
1828
|
+
case "dispatch":
|
|
1829
|
+
return deriveExpected2(def.selector);
|
|
1830
|
+
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
1831
|
+
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
1832
|
+
// able to fail first — deriving from term 0 alone named a token the parse
|
|
1833
|
+
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
1834
|
+
// nothing (its own expectation is about what must NOT be here), but it is
|
|
1835
|
+
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
1836
|
+
case "sequence": {
|
|
1837
|
+
const out = [];
|
|
1838
|
+
for (const term of def.parsers) {
|
|
1839
|
+
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
1840
|
+
if (!matchesEmpty(term)) break;
|
|
1841
|
+
}
|
|
1842
|
+
return out;
|
|
1843
|
+
}
|
|
1844
|
+
case "attempt":
|
|
1845
|
+
return deriveExpected2(def.parser);
|
|
1846
|
+
// Delegating wrappers whose first-token failure is their inner parser's — must
|
|
1847
|
+
// pass through so a start-failure (and the first-set-miss fast-path in attempt/
|
|
1848
|
+
// node, which reads this) names the real expected token, not the wrapper tag.
|
|
1849
|
+
case "field":
|
|
1850
|
+
case "withCtx":
|
|
1851
|
+
case "recover":
|
|
1852
|
+
return deriveExpected2(def.parser);
|
|
1853
|
+
case "skip":
|
|
1854
|
+
return deriveExpected2(def.main);
|
|
1855
|
+
case "expect":
|
|
1856
|
+
return def.expected;
|
|
1857
|
+
case "node":
|
|
1858
|
+
case "grammar":
|
|
1859
|
+
case "trivia":
|
|
1860
|
+
case "token":
|
|
1861
|
+
case "leaf":
|
|
1862
|
+
case "optional":
|
|
1863
|
+
case "many":
|
|
1864
|
+
case "oneOrMore":
|
|
1865
|
+
case "transform":
|
|
1866
|
+
case "not":
|
|
1867
|
+
case "peek":
|
|
1868
|
+
return deriveExpected2(def.parser);
|
|
1869
|
+
case "routed":
|
|
1870
|
+
return ["routed()"];
|
|
1871
|
+
case "lazy": {
|
|
1872
|
+
const name = c._ruleName;
|
|
1873
|
+
if (seen.has(c)) return name ? [name] : [];
|
|
1874
|
+
seen.add(c);
|
|
1875
|
+
try {
|
|
1876
|
+
return deriveExpected2(def.thunk());
|
|
1877
|
+
} catch {
|
|
1878
|
+
return name ? [name] : [];
|
|
1879
|
+
} finally {
|
|
1880
|
+
seen.delete(c);
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
default:
|
|
1884
|
+
return [];
|
|
1885
|
+
}
|
|
1864
1886
|
}
|
|
1865
|
-
function
|
|
1866
|
-
const
|
|
1867
|
-
const
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1887
|
+
function expect(combinator, label2) {
|
|
1888
|
+
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
1889
|
+
const meta = {
|
|
1890
|
+
firstSet: combinator._meta.firstSet,
|
|
1891
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1892
|
+
isTrivia: false
|
|
1893
|
+
};
|
|
1894
|
+
return {
|
|
1895
|
+
_tag: "expect",
|
|
1896
|
+
_meta: meta,
|
|
1897
|
+
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1898
|
+
parse(input, pos, ctx) {
|
|
1899
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1900
|
+
if (result.ok) return result;
|
|
1901
|
+
const span = { start: pos, end: pos };
|
|
1902
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1903
|
+
ctx._errors?.push(error);
|
|
1904
|
+
if (ctx._tolerant) captureError(ctx, error);
|
|
1905
|
+
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1906
|
+
}
|
|
1907
|
+
};
|
|
1877
1908
|
}
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1909
|
+
|
|
1910
|
+
// src/combinators/choice.ts
|
|
1911
|
+
function choice(...args) {
|
|
1912
|
+
const parsers = args.map((a) => "gate" in a ? a.combinator : a);
|
|
1913
|
+
const gates = args.map((a) => "gate" in a ? a.gate : null);
|
|
1914
|
+
const hasGates = gates.some((g) => g !== null);
|
|
1915
|
+
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
1916
|
+
let combined = { kind: "empty" };
|
|
1917
|
+
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
1918
|
+
const meta = {
|
|
1919
|
+
firstSet: combined,
|
|
1920
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1921
|
+
isTrivia: false,
|
|
1922
|
+
disjoint
|
|
1923
|
+
};
|
|
1924
|
+
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
1925
|
+
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1926
|
+
let greedyLitMap = null;
|
|
1927
|
+
let sortedParsers = null;
|
|
1928
|
+
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
1929
|
+
if (strategy?.tag === "greedyClassify") {
|
|
1930
|
+
greedyLitMap = /* @__PURE__ */ new Map();
|
|
1931
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1932
|
+
if (i === strategy.superIndex) continue;
|
|
1933
|
+
const litVal = getCoreLiteralValue(parsers[i]);
|
|
1934
|
+
if (litVal !== null) greedyLitMap.set(litVal, i);
|
|
1935
|
+
}
|
|
1936
|
+
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
1937
|
+
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
1938
|
+
}
|
|
1939
|
+
return {
|
|
1940
|
+
_tag: "choice",
|
|
1941
|
+
_meta: meta,
|
|
1942
|
+
_def: {
|
|
1943
|
+
tag: "choice",
|
|
1944
|
+
parsers,
|
|
1945
|
+
gates,
|
|
1946
|
+
disjoint,
|
|
1947
|
+
strategy: strategy ?? { tag: "firstMatch" },
|
|
1948
|
+
autoNot
|
|
1949
|
+
},
|
|
1950
|
+
parse(input, pos, ctx) {
|
|
1951
|
+
const expected = [];
|
|
1952
|
+
if (disjoint && pos < input.length) {
|
|
1953
|
+
const code = input.codePointAt(pos);
|
|
1954
|
+
let idx = code < 128 ? asciiDispatch[code] : -1;
|
|
1955
|
+
if (idx < 0) {
|
|
1956
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1957
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
1958
|
+
idx = i;
|
|
1959
|
+
break;
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
if (idx >= 0) {
|
|
1964
|
+
const gate2 = gates[idx];
|
|
1965
|
+
if (gate2 && !gate2(ctx.state)) {
|
|
1966
|
+
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1967
|
+
}
|
|
1968
|
+
const result = parsers[idx].parse(input, pos, ctx);
|
|
1969
|
+
if (result.ok) return result;
|
|
1970
|
+
expected.push(...result.expected);
|
|
1971
|
+
if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
|
|
1972
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1973
|
+
}
|
|
1974
|
+
return {
|
|
1975
|
+
ok: false,
|
|
1976
|
+
expected: parsers.flatMap((p) => {
|
|
1977
|
+
const r = p.parse(input, pos, ctx);
|
|
1978
|
+
return r.ok ? [] : r.expected;
|
|
1979
|
+
}),
|
|
1980
|
+
span: { start: pos, end: pos }
|
|
1981
|
+
};
|
|
1982
|
+
}
|
|
1983
|
+
if (strategy?.tag === "greedyClassify") {
|
|
1984
|
+
const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
|
|
1985
|
+
if (!superResult.ok) return superResult;
|
|
1986
|
+
const end = superResult.span.end;
|
|
1987
|
+
const litIdx = greedyLitMap.get(input.slice(pos, end));
|
|
1988
|
+
if (litIdx !== void 0) {
|
|
1989
|
+
const litVal = getCoreLiteralValue(parsers[litIdx]);
|
|
1990
|
+
const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
|
|
1991
|
+
return { ok: true, value, span: { start: pos, end } };
|
|
1992
|
+
}
|
|
1993
|
+
return superResult;
|
|
1994
|
+
}
|
|
1995
|
+
if (strategy?.tag === "literalsLongestFirst") {
|
|
1996
|
+
for (const p of sortedParsers) {
|
|
1997
|
+
const r = p.parse(input, pos, ctx);
|
|
1998
|
+
if (r.ok) return r;
|
|
1999
|
+
expected.push(...r.expected);
|
|
1887
2000
|
}
|
|
2001
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1888
2002
|
}
|
|
1889
|
-
|
|
2003
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2004
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
2005
|
+
const mark = saveTriviaMark(ctx);
|
|
2006
|
+
const result = parsers[i].parse(input, pos, ctx);
|
|
2007
|
+
if (!result.ok) {
|
|
2008
|
+
rollbackTrivia(ctx, mark);
|
|
2009
|
+
expected.push(...result.expected);
|
|
2010
|
+
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
2011
|
+
continue;
|
|
2012
|
+
}
|
|
2013
|
+
const checks = autoNot[i];
|
|
2014
|
+
if (checks && autoNotFires(input, result.span.end, checks)) {
|
|
2015
|
+
rollbackTrivia(ctx, mark);
|
|
2016
|
+
continue;
|
|
2017
|
+
}
|
|
2018
|
+
return result;
|
|
2019
|
+
}
|
|
2020
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1890
2021
|
}
|
|
1891
|
-
return pos;
|
|
1892
2022
|
};
|
|
1893
2023
|
}
|
|
1894
|
-
function
|
|
1895
|
-
|
|
1896
|
-
const
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
for (let i = 0; i < ranges.length; i++) {
|
|
1901
|
-
const r = ranges[i];
|
|
1902
|
-
if (cp >= r[0] && cp <= r[1]) return true;
|
|
2024
|
+
function detectStrategy(parsers) {
|
|
2025
|
+
const regexIndices = [];
|
|
2026
|
+
const literalIndices = [];
|
|
2027
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2028
|
+
if (getCoreRegexDef(parsers[i]) !== null) regexIndices.push(i);
|
|
2029
|
+
else if (getCoreLiteralValue(parsers[i]) !== null) literalIndices.push(i);
|
|
1903
2030
|
}
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
}
|
|
1915
|
-
|
|
1916
|
-
return (input, cur) => {
|
|
1917
|
-
if (input.charCodeAt(cur) !== commentCode) return cur;
|
|
1918
|
-
let pos = cur + 1;
|
|
1919
|
-
while (pos < input.length) {
|
|
1920
|
-
const cc = input.charCodeAt(pos);
|
|
1921
|
-
if (cc === 10 || cc === 13) break;
|
|
1922
|
-
pos++;
|
|
1923
|
-
}
|
|
1924
|
-
return pos;
|
|
1925
|
-
};
|
|
1926
|
-
}
|
|
1927
|
-
function classRunSource(source) {
|
|
1928
|
-
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1929
|
-
return m ? classScanner(m[1]) : null;
|
|
1930
|
-
}
|
|
1931
|
-
function classifyTriviaArm(arm) {
|
|
1932
|
-
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1933
|
-
if (cls) {
|
|
1934
|
-
const ranges = parseClassRanges(cls[1]);
|
|
1935
|
-
return ranges ? { kind: "class", ranges } : null;
|
|
2031
|
+
if (regexIndices.length === 1 && literalIndices.length === parsers.length - 1 && literalIndices.length > 0) {
|
|
2032
|
+
const superIndex = regexIndices[0];
|
|
2033
|
+
const regexDef = getCoreRegexDef(parsers[superIndex]);
|
|
2034
|
+
const flags = "y" + regexDef.flags.replace(/[gy]/g, "");
|
|
2035
|
+
const re = new RegExp(regexDef.source, flags);
|
|
2036
|
+
const allSubsumed = literalIndices.every((i) => {
|
|
2037
|
+
const litVal = getCoreLiteralValue(parsers[i]);
|
|
2038
|
+
re.lastIndex = 0;
|
|
2039
|
+
const m = re.exec(litVal);
|
|
2040
|
+
return m !== null && m[0] === litVal;
|
|
2041
|
+
});
|
|
2042
|
+
if (allSubsumed) return { tag: "greedyClassify", superIndex };
|
|
1936
2043
|
}
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
2044
|
+
if (parsers.length === literalIndices.length) {
|
|
2045
|
+
const sortedIndices = [...literalIndices].sort(
|
|
2046
|
+
(a, b) => getCoreLiteralValue(parsers[b]).length - getCoreLiteralValue(parsers[a]).length
|
|
2047
|
+
);
|
|
2048
|
+
return { tag: "literalsLongestFirst", sortedIndices };
|
|
1941
2049
|
}
|
|
2050
|
+
const shared = detectSharedPrefix(parsers);
|
|
2051
|
+
if (shared !== null) return shared;
|
|
2052
|
+
return { tag: "firstMatch" };
|
|
2053
|
+
}
|
|
2054
|
+
function bareLeadingTermKey(term) {
|
|
2055
|
+
const d = term._def;
|
|
2056
|
+
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
2057
|
+
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
1942
2058
|
return null;
|
|
1943
2059
|
}
|
|
1944
|
-
function
|
|
1945
|
-
if (
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
2060
|
+
function detectSharedPrefix(parsers) {
|
|
2061
|
+
if (parsers.length < 2) return null;
|
|
2062
|
+
let key = null;
|
|
2063
|
+
let prefix = null;
|
|
2064
|
+
const members = [];
|
|
2065
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2066
|
+
const term0 = leadingTermOfArm(parsers[i]);
|
|
2067
|
+
if (term0 === null) return null;
|
|
2068
|
+
const k = bareLeadingTermKey(term0);
|
|
2069
|
+
if (k === null) return null;
|
|
2070
|
+
if (key === null) {
|
|
2071
|
+
key = k;
|
|
2072
|
+
prefix = term0;
|
|
2073
|
+
} else if (k !== key) return null;
|
|
2074
|
+
members.push(i);
|
|
2075
|
+
}
|
|
2076
|
+
if (prefix === null || members.length < 2) return null;
|
|
2077
|
+
return { tag: "sharedPrefix", prefix, members };
|
|
1952
2078
|
}
|
|
1953
|
-
function
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
2079
|
+
function leadingTermOfArm(arm) {
|
|
2080
|
+
let d = arm._def;
|
|
2081
|
+
for (; ; ) {
|
|
2082
|
+
if (d.tag === "node" || d.tag === "grammar" || d.tag === "transform" || d.tag === "label") {
|
|
2083
|
+
d = d.parser._def;
|
|
2084
|
+
continue;
|
|
2085
|
+
}
|
|
2086
|
+
break;
|
|
2087
|
+
}
|
|
2088
|
+
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
2089
|
+
return d.parsers[0];
|
|
2090
|
+
}
|
|
2091
|
+
function computeAutoNot(parsers) {
|
|
2092
|
+
return parsers.map((p, i) => {
|
|
2093
|
+
const litVal = getCoreLiteralValue(p);
|
|
2094
|
+
if (litVal === null) return null;
|
|
2095
|
+
const checks = [];
|
|
2096
|
+
for (let j = i + 1; j < parsers.length; j++) {
|
|
2097
|
+
const other = parsers[j];
|
|
2098
|
+
const otherLit = getCoreLiteralValue(other);
|
|
2099
|
+
if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
|
|
2100
|
+
checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
|
|
1963
2101
|
continue;
|
|
1964
2102
|
}
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
if (cc === 10 || cc === 13) break;
|
|
1970
|
-
pos++;
|
|
1971
|
-
}
|
|
1972
|
-
continue;
|
|
2103
|
+
const regexDef = getCoreRegexDef(other);
|
|
2104
|
+
if (regexDef !== null) {
|
|
2105
|
+
const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
|
|
2106
|
+
if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
|
|
1973
2107
|
}
|
|
1974
|
-
break;
|
|
1975
2108
|
}
|
|
1976
|
-
return
|
|
1977
|
-
};
|
|
2109
|
+
return checks.length > 0 ? checks : null;
|
|
2110
|
+
});
|
|
1978
2111
|
}
|
|
1979
|
-
function
|
|
1980
|
-
const
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
i++;
|
|
1987
|
-
continue;
|
|
1988
|
-
}
|
|
1989
|
-
if (inClass) {
|
|
1990
|
-
if (c === "]") inClass = false;
|
|
1991
|
-
continue;
|
|
1992
|
-
}
|
|
1993
|
-
if (c === "[") inClass = true;
|
|
1994
|
-
else if (c === "(") return null;
|
|
1995
|
-
else if (c === "|") {
|
|
1996
|
-
arms.push(body.slice(start, i));
|
|
1997
|
-
start = i + 1;
|
|
2112
|
+
function autoNotFires(input, end, checks) {
|
|
2113
|
+
for (const check of checks) {
|
|
2114
|
+
if (check.kind === "firstSet") {
|
|
2115
|
+
const code = end < input.length ? input.codePointAt(end) ?? -1 : -1;
|
|
2116
|
+
if (inFirstSet(code, check.set)) return true;
|
|
2117
|
+
} else {
|
|
2118
|
+
if (input.startsWith(check.value, end)) return true;
|
|
1998
2119
|
}
|
|
1999
2120
|
}
|
|
2000
|
-
|
|
2001
|
-
return arms;
|
|
2121
|
+
return false;
|
|
2002
2122
|
}
|
|
2003
|
-
function
|
|
2004
|
-
const
|
|
2005
|
-
if (!
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2123
|
+
function getCoreLiteralValue(p) {
|
|
2124
|
+
const def = p._def;
|
|
2125
|
+
if (def.tag === "literal" && !def.caseInsensitive) return def.value;
|
|
2126
|
+
if (def.tag === "transform") return getCoreLiteralValue(def.parser);
|
|
2127
|
+
return null;
|
|
2128
|
+
}
|
|
2129
|
+
function getCoreRegexDef(p) {
|
|
2130
|
+
const def = p._def;
|
|
2131
|
+
if (def.tag === "regex") return { source: def.source, flags: def.flags };
|
|
2132
|
+
if (def.tag === "transform") return getCoreRegexDef(def.parser);
|
|
2133
|
+
if (def.tag === "label") return getCoreRegexDef(def.parser);
|
|
2134
|
+
return null;
|
|
2135
|
+
}
|
|
2136
|
+
function applyTransforms(p, value, span) {
|
|
2137
|
+
const def = p._def;
|
|
2138
|
+
if (def.tag === "transform") {
|
|
2139
|
+
const inner = applyTransforms(def.parser, value, span);
|
|
2140
|
+
return def.fn(inner, span);
|
|
2013
2141
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2142
|
+
return value;
|
|
2143
|
+
}
|
|
2144
|
+
function continuationFirstSet(lit, source, flags) {
|
|
2145
|
+
const re = new RegExp(source, "y" + flags.replace(/[gy]/g, ""));
|
|
2146
|
+
re.lastIndex = 0;
|
|
2147
|
+
const base = re.exec(lit);
|
|
2148
|
+
if (!base || base[0] !== lit) return null;
|
|
2149
|
+
const contCodes = [];
|
|
2150
|
+
for (let code = 1; code < 128; code++) {
|
|
2151
|
+
re.lastIndex = 0;
|
|
2152
|
+
const m = re.exec(lit + String.fromCharCode(code));
|
|
2153
|
+
if (m && m[0].length > lit.length) contCodes.push(code);
|
|
2019
2154
|
}
|
|
2020
|
-
if (
|
|
2021
|
-
|
|
2155
|
+
if (contCodes.length === 0) return null;
|
|
2156
|
+
return codesToFirstSet(contCodes);
|
|
2157
|
+
}
|
|
2158
|
+
function codesToFirstSet(codes) {
|
|
2159
|
+
codes.sort((a, b) => a - b);
|
|
2160
|
+
const ranges = [];
|
|
2161
|
+
let lo = codes[0], hi = codes[0];
|
|
2162
|
+
for (let i = 1; i < codes.length; i++) {
|
|
2163
|
+
if (codes[i] === hi + 1) {
|
|
2164
|
+
hi = codes[i];
|
|
2165
|
+
} else {
|
|
2166
|
+
ranges.push({ lo, hi });
|
|
2167
|
+
lo = hi = codes[i];
|
|
2168
|
+
}
|
|
2022
2169
|
}
|
|
2023
|
-
|
|
2024
|
-
return
|
|
2170
|
+
ranges.push({ lo, hi });
|
|
2171
|
+
return { kind: "ranges", ranges };
|
|
2025
2172
|
}
|
|
2026
|
-
function
|
|
2027
|
-
|
|
2173
|
+
function inFirstSet(code, fs2) {
|
|
2174
|
+
if (fs2.kind === "any") return true;
|
|
2175
|
+
if (fs2.kind === "empty") return false;
|
|
2176
|
+
for (const r of fs2.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
2177
|
+
return false;
|
|
2028
2178
|
}
|
|
2029
|
-
function
|
|
2030
|
-
if (
|
|
2031
|
-
|
|
2032
|
-
|
|
2179
|
+
function areDisjoint(sets) {
|
|
2180
|
+
if (sets.some((s) => s.kind === "any")) return false;
|
|
2181
|
+
for (let i = 0; i < sets.length; i++)
|
|
2182
|
+
for (let j = i + 1; j < sets.length; j++)
|
|
2183
|
+
if (intersects(sets[i], sets[j])) return false;
|
|
2184
|
+
return true;
|
|
2033
2185
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
isTrivia: false
|
|
2043
|
-
};
|
|
2044
|
-
const def = { tag: "sequence", parsers };
|
|
2045
|
-
let followSentinels;
|
|
2046
|
-
function parseTolerant(input, pos, ctx) {
|
|
2047
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
2048
|
-
const fs2 = parsers.slice(i + 1).reduce(
|
|
2049
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
2050
|
-
{ kind: "empty" }
|
|
2051
|
-
);
|
|
2052
|
-
return firstSetSentinel(fs2);
|
|
2053
|
-
});
|
|
2054
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2055
|
-
let cur = pos;
|
|
2056
|
-
const inheritedSync = ctx._sync;
|
|
2057
|
-
try {
|
|
2058
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
2059
|
-
ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
2060
|
-
if (ctx.trivia && i > 0) {
|
|
2061
|
-
const mark = saveTriviaMark(ctx);
|
|
2062
|
-
let scanEnd;
|
|
2063
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2064
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
2065
|
-
scan.commit();
|
|
2066
|
-
scanEnd = scan.end;
|
|
2067
|
-
} else {
|
|
2068
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2069
|
-
}
|
|
2070
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2071
|
-
if (!result2.ok) return result2;
|
|
2072
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2073
|
-
else rollbackTrivia(ctx, mark);
|
|
2074
|
-
if (values !== void 0) values.push(result2.value);
|
|
2075
|
-
continue;
|
|
2076
|
-
}
|
|
2077
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2078
|
-
if (!result.ok) return result;
|
|
2079
|
-
if (values !== void 0) values.push(result.value);
|
|
2080
|
-
cur = result.span.end;
|
|
2186
|
+
function buildAsciiDispatch(parsers) {
|
|
2187
|
+
const table = Array(128).fill(-1);
|
|
2188
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2189
|
+
const fs2 = parsers[i]._meta.firstSet;
|
|
2190
|
+
if (fs2.kind !== "ranges") continue;
|
|
2191
|
+
for (const { lo, hi } of fs2.ranges) {
|
|
2192
|
+
for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
|
|
2193
|
+
table[code] = i;
|
|
2081
2194
|
}
|
|
2082
|
-
} finally {
|
|
2083
|
-
ctx._sync = inheritedSync;
|
|
2084
2195
|
}
|
|
2085
|
-
return {
|
|
2086
|
-
ok: true,
|
|
2087
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2088
|
-
value: values ?? void 0,
|
|
2089
|
-
span: { start: pos, end: cur }
|
|
2090
|
-
};
|
|
2091
2196
|
}
|
|
2092
|
-
return
|
|
2093
|
-
_tag: "sequence",
|
|
2094
|
-
_meta: meta,
|
|
2095
|
-
_def: def,
|
|
2096
|
-
parse(input, pos, ctx) {
|
|
2097
|
-
if (ctx._tolerant) return parseTolerant(input, pos, ctx);
|
|
2098
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2099
|
-
let cur = pos;
|
|
2100
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
2101
|
-
if (ctx.trivia && i > 0) {
|
|
2102
|
-
let scanEnd;
|
|
2103
|
-
let mark = saveTriviaMark(ctx);
|
|
2104
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2105
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
2106
|
-
scan.commit();
|
|
2107
|
-
scanEnd = scan.end;
|
|
2108
|
-
} else {
|
|
2109
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2110
|
-
}
|
|
2111
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2112
|
-
if (!result2.ok) return result2;
|
|
2113
|
-
if (result2.span.end > scanEnd) {
|
|
2114
|
-
cur = result2.span.end;
|
|
2115
|
-
} else {
|
|
2116
|
-
rollbackTrivia(ctx, mark);
|
|
2117
|
-
}
|
|
2118
|
-
if (values !== void 0) values.push(result2.value);
|
|
2119
|
-
continue;
|
|
2120
|
-
}
|
|
2121
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2122
|
-
if (!result.ok) return result;
|
|
2123
|
-
if (values !== void 0) values.push(result.value);
|
|
2124
|
-
cur = result.span.end;
|
|
2125
|
-
}
|
|
2126
|
-
return {
|
|
2127
|
-
ok: true,
|
|
2128
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2129
|
-
value: values ?? void 0,
|
|
2130
|
-
span: { start: pos, end: cur }
|
|
2131
|
-
};
|
|
2132
|
-
}
|
|
2133
|
-
};
|
|
2197
|
+
return table;
|
|
2134
2198
|
}
|
|
2135
2199
|
|
|
2136
2200
|
// src/combinators/dispatch.ts
|
|
@@ -2390,10 +2454,12 @@ function attempt(parser2) {
|
|
|
2390
2454
|
}
|
|
2391
2455
|
const mark = saveCstMark(ctx);
|
|
2392
2456
|
const log = ctx._triviaLog?.length;
|
|
2457
|
+
const rootLog = ctx._rootTriviaLog?.length;
|
|
2393
2458
|
const result = parser2.parse(input, pos, ctx);
|
|
2394
2459
|
if (result.ok) return result;
|
|
2395
2460
|
rollbackCstCapture(ctx, mark);
|
|
2396
2461
|
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
2462
|
+
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
2397
2463
|
if (result.committed) return result;
|
|
2398
2464
|
return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
|
|
2399
2465
|
}
|
|
@@ -2797,18 +2863,37 @@ function createParseLineContext(input, pos) {
|
|
|
2797
2863
|
}
|
|
2798
2864
|
function parser(opts, root) {
|
|
2799
2865
|
const clearTrivia = opts.trivia === null;
|
|
2866
|
+
const opaqueRootCapture = opts.rootCapture === "opaque";
|
|
2867
|
+
if (opaqueRootCapture && opts.trivia === void 0) {
|
|
2868
|
+
throw new TypeError("parser({ rootCapture: 'opaque' }) requires an explicit trivia scope.");
|
|
2869
|
+
}
|
|
2800
2870
|
return {
|
|
2801
2871
|
_tag: "grammar",
|
|
2802
|
-
_meta:
|
|
2872
|
+
_meta: {
|
|
2873
|
+
...root._meta,
|
|
2874
|
+
// Trivia classification describes this grammar's own active trivia
|
|
2875
|
+
// scope. A directly nested grammar may have classified trivia of its
|
|
2876
|
+
// own, but that must not advertise classification for this wrapper.
|
|
2877
|
+
triviaKindLabels: void 0,
|
|
2878
|
+
rootTriviaClassified: void 0,
|
|
2879
|
+
...opts.trivia?._meta?.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {},
|
|
2880
|
+
...opts.trivia?._meta?.rootTriviaClassified ? { rootTriviaClassified: true } : {}
|
|
2881
|
+
},
|
|
2803
2882
|
_def: {
|
|
2804
2883
|
tag: "grammar",
|
|
2805
2884
|
parser: root,
|
|
2806
2885
|
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2807
2886
|
clearTrivia,
|
|
2887
|
+
...opaqueRootCapture ? { rootCapture: "opaque" } : {},
|
|
2808
2888
|
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2809
2889
|
trackLines: opts.trackLines ?? false
|
|
2810
2890
|
},
|
|
2811
2891
|
parse(input, pos, _ctx) {
|
|
2892
|
+
if (_ctx?._rootTriviaStrictScopes && opts.trivia !== void 0 && opts.trivia !== null && !opts.trivia._meta.rootTriviaClassified && !opaqueRootCapture) {
|
|
2893
|
+
throw new TypeError(
|
|
2894
|
+
"parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'."
|
|
2895
|
+
);
|
|
2896
|
+
}
|
|
2812
2897
|
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2813
2898
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2814
2899
|
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
@@ -2831,7 +2916,11 @@ function parser(opts, root) {
|
|
|
2831
2916
|
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2832
2917
|
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2833
2918
|
// (capture all).
|
|
2834
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
2919
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {},
|
|
2920
|
+
// This is a property of the local trivia scope, not a post-parse filter:
|
|
2921
|
+
// nested recognition can still skip its trivia, but selected root rows
|
|
2922
|
+
// must never be written for an explicitly opaque region.
|
|
2923
|
+
...opaqueRootCapture ? { _rootTriviaCapture: false } : {}
|
|
2835
2924
|
};
|
|
2836
2925
|
const result = root.parse(input, pos ?? 0, ctx);
|
|
2837
2926
|
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
@@ -2845,6 +2934,123 @@ function noTrivia(root) {
|
|
|
2845
2934
|
return parser({ trivia: null }, root);
|
|
2846
2935
|
}
|
|
2847
2936
|
|
|
2937
|
+
// src/cst/reflection.ts
|
|
2938
|
+
var GRAMMAR_REFLECTION = /* @__PURE__ */ Symbol.for("parseman.grammarReflection");
|
|
2939
|
+
function childrenOf(def) {
|
|
2940
|
+
switch (def.tag) {
|
|
2941
|
+
case "sequence":
|
|
2942
|
+
case "choice":
|
|
2943
|
+
return def.parsers;
|
|
2944
|
+
case "dispatch":
|
|
2945
|
+
return [
|
|
2946
|
+
def.selector,
|
|
2947
|
+
...def.cases.map((c) => c.parser),
|
|
2948
|
+
...def.matchers ? def.matchers.map((c) => c.parser) : [],
|
|
2949
|
+
...def.otherwise ? [def.otherwise] : []
|
|
2950
|
+
];
|
|
2951
|
+
case "many":
|
|
2952
|
+
case "oneOrMore":
|
|
2953
|
+
case "optional":
|
|
2954
|
+
case "attempt":
|
|
2955
|
+
case "transform":
|
|
2956
|
+
case "trivia":
|
|
2957
|
+
case "token":
|
|
2958
|
+
case "leaf":
|
|
2959
|
+
case "label":
|
|
2960
|
+
case "field":
|
|
2961
|
+
case "not":
|
|
2962
|
+
case "peek":
|
|
2963
|
+
case "node":
|
|
2964
|
+
case "withCtx":
|
|
2965
|
+
case "recover":
|
|
2966
|
+
case "expect":
|
|
2967
|
+
return [def.parser];
|
|
2968
|
+
case "grammar":
|
|
2969
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
2970
|
+
case "sepBy":
|
|
2971
|
+
return [def.parser, def.separator];
|
|
2972
|
+
case "skip":
|
|
2973
|
+
return [def.main, def.skipped];
|
|
2974
|
+
case "scanTo":
|
|
2975
|
+
return [def.sentinel, ...def.skip];
|
|
2976
|
+
case "literal":
|
|
2977
|
+
case "regex":
|
|
2978
|
+
case "keywords":
|
|
2979
|
+
case "routed":
|
|
2980
|
+
case "guard":
|
|
2981
|
+
case "lazy":
|
|
2982
|
+
case "unknown":
|
|
2983
|
+
return [];
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
function addNode(out, def) {
|
|
2987
|
+
if (def.type === void 0) return;
|
|
2988
|
+
const existing = out.get(def.type);
|
|
2989
|
+
if (existing === void 0) {
|
|
2990
|
+
out.set(def.type, def.tags === void 0 ? [] : [...def.tags]);
|
|
2991
|
+
return;
|
|
2992
|
+
}
|
|
2993
|
+
if (def.tags === void 0) return;
|
|
2994
|
+
for (const tag of def.tags) {
|
|
2995
|
+
if (!existing.includes(tag)) existing.push(tag);
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
2998
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
2999
|
+
if (seen.has(parser2)) return;
|
|
3000
|
+
seen.add(parser2);
|
|
3001
|
+
const def = parser2._def;
|
|
3002
|
+
if (def.tag === "lazy") {
|
|
3003
|
+
if (followLazy) {
|
|
3004
|
+
try {
|
|
3005
|
+
collectFromCombinator(def.thunk(), out, seen, followLazy);
|
|
3006
|
+
} catch {
|
|
3007
|
+
}
|
|
3008
|
+
}
|
|
3009
|
+
return;
|
|
3010
|
+
}
|
|
3011
|
+
if (def.tag === "node") addNode(out, def);
|
|
3012
|
+
for (const child of childrenOf(def)) collectFromCombinator(child, out, seen, followLazy);
|
|
3013
|
+
}
|
|
3014
|
+
function collectGrammarReflection(ruleMap, opts) {
|
|
3015
|
+
const byType = /* @__PURE__ */ new Map();
|
|
3016
|
+
const followLazy = opts?.followLazy !== false;
|
|
3017
|
+
for (const [, rule] of ruleMap) {
|
|
3018
|
+
if (!followLazy && rule._def.tag === "lazy") {
|
|
3019
|
+
try {
|
|
3020
|
+
const resolved = rule._def.thunk();
|
|
3021
|
+
if (resolved._def.tag !== "lazy") collectFromCombinator(resolved, byType, /* @__PURE__ */ new Set(), false);
|
|
3022
|
+
} catch {
|
|
3023
|
+
}
|
|
3024
|
+
continue;
|
|
3025
|
+
}
|
|
3026
|
+
collectFromCombinator(rule, byType, /* @__PURE__ */ new Set(), followLazy);
|
|
3027
|
+
}
|
|
3028
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
3029
|
+
}
|
|
3030
|
+
function mergeGrammarReflections(reflections) {
|
|
3031
|
+
const byType = /* @__PURE__ */ new Map();
|
|
3032
|
+
for (const reflection of reflections) {
|
|
3033
|
+
for (const node2 of reflection.nodes) {
|
|
3034
|
+
const tags = byType.get(node2.type);
|
|
3035
|
+
if (tags === void 0) {
|
|
3036
|
+
byType.set(node2.type, [...node2.tags]);
|
|
3037
|
+
continue;
|
|
3038
|
+
}
|
|
3039
|
+
for (const tag of node2.tags) {
|
|
3040
|
+
if (!tags.includes(tag)) tags.push(tag);
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
}
|
|
3044
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
3045
|
+
}
|
|
3046
|
+
function attachGrammarReflection(grammar, reflection) {
|
|
3047
|
+
Object.defineProperty(grammar, GRAMMAR_REFLECTION, { value: reflection, enumerable: false, configurable: true });
|
|
3048
|
+
return grammar;
|
|
3049
|
+
}
|
|
3050
|
+
function grammarReflectionSource(reflection) {
|
|
3051
|
+
return `{ nodes: ${JSON.stringify(reflection.nodes)} }`;
|
|
3052
|
+
}
|
|
3053
|
+
|
|
2848
3054
|
// src/combinators/parser.ts
|
|
2849
3055
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2850
3056
|
function tagRule(r, key) {
|
|
@@ -2943,6 +3149,7 @@ function rules(a, b) {
|
|
|
2943
3149
|
enumerable: false,
|
|
2944
3150
|
configurable: true
|
|
2945
3151
|
});
|
|
3152
|
+
attachGrammarReflection(cache, collectGrammarReflection(Object.keys(definitions).map((key) => [key, cache[key]])));
|
|
2946
3153
|
return cache;
|
|
2947
3154
|
}
|
|
2948
3155
|
|
|
@@ -3263,13 +3470,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3263
3470
|
const collapse = opts?.collapse === true;
|
|
3264
3471
|
const captureTrivia = opts?.captureTrivia === true;
|
|
3265
3472
|
const trailingTrivia = opts?.trailingTrivia === true;
|
|
3473
|
+
const tags = opts?.tags;
|
|
3266
3474
|
if (unwrap && collapse) {
|
|
3267
3475
|
throw new Error("node() options cannot set both unwrap and collapse");
|
|
3268
3476
|
}
|
|
3269
3477
|
if (project !== void 0 && (unwrap || collapse)) {
|
|
3270
3478
|
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
3271
3479
|
}
|
|
3272
|
-
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;
|
|
3480
|
+
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;
|
|
3273
3481
|
const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
3274
3482
|
const clonesState = build ? buildReadsState(def) : project === void 0;
|
|
3275
3483
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
@@ -3315,7 +3523,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3315
3523
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3316
3524
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3317
3525
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3318
|
-
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 };
|
|
3526
|
+
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 };
|
|
3319
3527
|
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 };
|
|
3320
3528
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3321
3529
|
pushCstChild(ctx, built, rawEntry);
|
|
@@ -3365,6 +3573,25 @@ function trivia(combinator) {
|
|
|
3365
3573
|
parse: combinator.parse.bind(combinator)
|
|
3366
3574
|
};
|
|
3367
3575
|
}
|
|
3576
|
+
function classifiedTrivia(arms) {
|
|
3577
|
+
const entries = Object.entries(arms);
|
|
3578
|
+
if (entries.length === 0) {
|
|
3579
|
+
throw new TypeError("classifiedTrivia() requires at least one named trivia arm.");
|
|
3580
|
+
}
|
|
3581
|
+
for (let i = 0; i < entries.length; i++) {
|
|
3582
|
+
const [name, arm] = entries[i];
|
|
3583
|
+
const first = arm._meta.firstSet;
|
|
3584
|
+
if (matchesEmpty(arm) || first.kind !== "ranges" || first.ranges.length === 0) {
|
|
3585
|
+
throw new TypeError(
|
|
3586
|
+
`classifiedTrivia(): ${JSON.stringify(name)} must be non-nullable with a concrete finite first set.`
|
|
3587
|
+
);
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
const labeledArms = entries.map(([name, arm]) => label(name, arm));
|
|
3591
|
+
const result = trivia(oneOrMore(choice(...labeledArms)));
|
|
3592
|
+
result._meta.rootTriviaClassified = true;
|
|
3593
|
+
return result;
|
|
3594
|
+
}
|
|
3368
3595
|
function label(name, combinator) {
|
|
3369
3596
|
return {
|
|
3370
3597
|
_tag: combinator._tag,
|
|
@@ -3411,6 +3638,7 @@ function token(root) {
|
|
|
3411
3638
|
const savedRaw = ctx._cstRawChildren;
|
|
3412
3639
|
const savedTriviaLog = ctx._cstTriviaLog;
|
|
3413
3640
|
const savedOuterTriviaLog = ctx._triviaLog;
|
|
3641
|
+
const savedRootTriviaLog = ctx._rootTriviaLog;
|
|
3414
3642
|
const wasCapturing = cstCaptureActive(ctx);
|
|
3415
3643
|
ctx.trivia = void 0;
|
|
3416
3644
|
ctx.triviaKindLabels = void 0;
|
|
@@ -3420,6 +3648,7 @@ function token(root) {
|
|
|
3420
3648
|
ctx._cstRawChildren = void 0;
|
|
3421
3649
|
ctx._cstTriviaLog = void 0;
|
|
3422
3650
|
delete ctx._triviaLog;
|
|
3651
|
+
delete ctx._rootTriviaLog;
|
|
3423
3652
|
let result;
|
|
3424
3653
|
try {
|
|
3425
3654
|
result = root.parse(input, pos, ctx);
|
|
@@ -3433,6 +3662,8 @@ function token(root) {
|
|
|
3433
3662
|
ctx._cstTriviaLog = savedTriviaLog;
|
|
3434
3663
|
if (savedOuterTriviaLog === void 0) delete ctx._triviaLog;
|
|
3435
3664
|
else ctx._triviaLog = savedOuterTriviaLog;
|
|
3665
|
+
if (savedRootTriviaLog === void 0) delete ctx._rootTriviaLog;
|
|
3666
|
+
else ctx._rootTriviaLog = savedRootTriviaLog;
|
|
3436
3667
|
}
|
|
3437
3668
|
if (!result.ok) return result;
|
|
3438
3669
|
const span = result.span;
|
|
@@ -3487,7 +3718,7 @@ function leaf(root, fn) {
|
|
|
3487
3718
|
}
|
|
3488
3719
|
|
|
3489
3720
|
// src/version.ts
|
|
3490
|
-
var PARSEMAN_VERSION = "0.
|
|
3721
|
+
var PARSEMAN_VERSION = "0.44.0";
|
|
3491
3722
|
|
|
3492
3723
|
// src/cst/host-mode.ts
|
|
3493
3724
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -3553,7 +3784,7 @@ var SUGGESTIONS = {
|
|
|
3553
3784
|
function classifyBroadArm(arm, resolve2) {
|
|
3554
3785
|
const seen = /* @__PURE__ */ new Set();
|
|
3555
3786
|
const relabel = (inner, cause, detail) => ({ cause, detail, ...inner?.unresolvedExternal ? { unresolvedExternal: true } : {} });
|
|
3556
|
-
const
|
|
3787
|
+
const walk = (p) => {
|
|
3557
3788
|
if (seen.has(p)) return { cause: "ref-cycle", detail: "ref cycle" };
|
|
3558
3789
|
seen.add(p);
|
|
3559
3790
|
const d = p._def;
|
|
@@ -3567,7 +3798,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3567
3798
|
// peek() CARRIES its body's first-set, so it is only broad when the body is
|
|
3568
3799
|
// (or the body is nullable) — walk in for the real cause.
|
|
3569
3800
|
case "peek":
|
|
3570
|
-
return
|
|
3801
|
+
return walk(d.parser);
|
|
3571
3802
|
case "scanTo":
|
|
3572
3803
|
return { cause: "broad-recognizer", detail: "scanTo (any first char)" };
|
|
3573
3804
|
// `guard` (the `gate()` state predicate) has a genuinely-`any` first-set of
|
|
@@ -3581,7 +3812,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3581
3812
|
case "attempt":
|
|
3582
3813
|
case "withCtx":
|
|
3583
3814
|
case "recover":
|
|
3584
|
-
return
|
|
3815
|
+
return walk(d.parser);
|
|
3585
3816
|
case "lazy": {
|
|
3586
3817
|
const name = p._ruleName;
|
|
3587
3818
|
let target;
|
|
@@ -3593,13 +3824,13 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3593
3824
|
return { cause: "cross-artifact-ref", detail: `unresolved ref${name ? ` g.${name}` : ""}`, unresolvedExternal: name !== void 0 };
|
|
3594
3825
|
target = bound;
|
|
3595
3826
|
}
|
|
3596
|
-
const inner =
|
|
3827
|
+
const inner = walk(target);
|
|
3597
3828
|
if (name !== void 0) return inner ? relabel(inner, "cross-artifact-ref", `via ref g.${name} \u2192 ${inner.detail}`) : null;
|
|
3598
3829
|
return inner;
|
|
3599
3830
|
}
|
|
3600
3831
|
case "optional":
|
|
3601
3832
|
case "many": {
|
|
3602
|
-
const inner =
|
|
3833
|
+
const inner = walk(d.parser);
|
|
3603
3834
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3604
3835
|
}
|
|
3605
3836
|
case "oneOrMore":
|
|
@@ -3612,9 +3843,9 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3612
3843
|
case "node":
|
|
3613
3844
|
case "grammar":
|
|
3614
3845
|
case "expect":
|
|
3615
|
-
return
|
|
3846
|
+
return walk(d.parser);
|
|
3616
3847
|
case "skip":
|
|
3617
|
-
return
|
|
3848
|
+
return walk(d.main);
|
|
3618
3849
|
case "sequence": {
|
|
3619
3850
|
let sawNullablePrefix = false;
|
|
3620
3851
|
for (const t of d.parsers) {
|
|
@@ -3623,7 +3854,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3623
3854
|
continue;
|
|
3624
3855
|
}
|
|
3625
3856
|
if (isAny(firstSetOf(t, /* @__PURE__ */ new Set(), resolve2))) {
|
|
3626
|
-
const inner =
|
|
3857
|
+
const inner = walk(t);
|
|
3627
3858
|
if (sawNullablePrefix)
|
|
3628
3859
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3629
3860
|
return inner ?? { cause: "broad-recognizer", detail: "sequence leading term is broad" };
|
|
@@ -3638,18 +3869,18 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3638
3869
|
}
|
|
3639
3870
|
case "choice": {
|
|
3640
3871
|
for (const a of d.parsers) {
|
|
3641
|
-
const r =
|
|
3872
|
+
const r = walk(a);
|
|
3642
3873
|
if (r) return relabel(r, r.cause, `choice arm \u2192 ${r.detail}`);
|
|
3643
3874
|
}
|
|
3644
3875
|
return null;
|
|
3645
3876
|
}
|
|
3646
3877
|
case "dispatch":
|
|
3647
|
-
return
|
|
3878
|
+
return walk(d.selector);
|
|
3648
3879
|
default:
|
|
3649
3880
|
return { cause: "broad-recognizer", detail: `unmodeled construct (${d.tag})` };
|
|
3650
3881
|
}
|
|
3651
3882
|
};
|
|
3652
|
-
return
|
|
3883
|
+
return walk(arm) ?? { cause: "broad-recognizer", detail: "broad (cause not localized)" };
|
|
3653
3884
|
}
|
|
3654
3885
|
function peelToLeading(arm) {
|
|
3655
3886
|
let d = arm._def;
|
|
@@ -3851,7 +4082,7 @@ function formatGatingWarnings(report) {
|
|
|
3851
4082
|
|
|
3852
4083
|
// src/analysis/duplication.ts
|
|
3853
4084
|
var siteToString = (s) => s.path === "" ? s.rule : `${s.rule} \u203A ${s.path}`;
|
|
3854
|
-
function
|
|
4085
|
+
function childrenOf2(d) {
|
|
3855
4086
|
switch (d.tag) {
|
|
3856
4087
|
case "sequence":
|
|
3857
4088
|
case "choice":
|
|
@@ -3985,7 +4216,7 @@ function render(p, depth = 3) {
|
|
|
3985
4216
|
break;
|
|
3986
4217
|
}
|
|
3987
4218
|
if (depth <= 0) return `${d.tag}(\u2026)`;
|
|
3988
|
-
const kids =
|
|
4219
|
+
const kids = childrenOf2(d).map((k) => render(k, depth - 1));
|
|
3989
4220
|
switch (d.tag) {
|
|
3990
4221
|
case "sequence":
|
|
3991
4222
|
return `sequence(${kids.join(", ")})`;
|
|
@@ -4180,7 +4411,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4180
4411
|
if (hit !== void 0) return hit;
|
|
4181
4412
|
const d = p._def;
|
|
4182
4413
|
shapeCache.set(p, interner.hole);
|
|
4183
|
-
const kids =
|
|
4414
|
+
const kids = childrenOf2(d);
|
|
4184
4415
|
const id = interner.of(`${payloadKey(p, d)}|${kids.map(shapeOf).join(",")}`);
|
|
4185
4416
|
shapeCache.set(p, id);
|
|
4186
4417
|
return id;
|
|
@@ -4190,7 +4421,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4190
4421
|
if (hit !== void 0) return hit;
|
|
4191
4422
|
sizeCache.set(p, 1);
|
|
4192
4423
|
let n = 1;
|
|
4193
|
-
for (const k of
|
|
4424
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4194
4425
|
sizeCache.set(p, n);
|
|
4195
4426
|
return n;
|
|
4196
4427
|
};
|
|
@@ -4203,7 +4434,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4203
4434
|
visited.set(p, { p, d, site: here, shape: shapeOf(p), size: sizeOf(p), enclosingNode, enclosingReducer });
|
|
4204
4435
|
const inner = d.tag === "node" ? d.type ?? "(anonymous)" : enclosingNode;
|
|
4205
4436
|
const innerReducer = enclosingReducer || d.tag === "node" && (d.build !== void 0 || d.buildSrc !== void 0) || d.tag === "transform" || d.tag === "leaf";
|
|
4206
|
-
const kids =
|
|
4437
|
+
const kids = childrenOf2(d);
|
|
4207
4438
|
kids.forEach((k, i) => {
|
|
4208
4439
|
const seg = segment(d, i);
|
|
4209
4440
|
visit(k, here.rule, here.path === "" ? seg : `${here.path} \u203A ${seg}`, inner, innerReducer);
|
|
@@ -4263,7 +4494,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4263
4494
|
function markSubtree(p, into) {
|
|
4264
4495
|
if (into.has(p)) return;
|
|
4265
4496
|
into.add(p);
|
|
4266
|
-
for (const k of
|
|
4497
|
+
for (const k of childrenOf2(p._def)) markSubtree(k, into);
|
|
4267
4498
|
}
|
|
4268
4499
|
var stripMembers = (f) => {
|
|
4269
4500
|
const { _members, ...rest } = f;
|
|
@@ -4303,7 +4534,7 @@ function findNearDuplicates(visited, interner, shapeOf, minSize) {
|
|
|
4303
4534
|
if (hit !== void 0) return hit;
|
|
4304
4535
|
holeCache.set(p, []);
|
|
4305
4536
|
const d = p._def;
|
|
4306
|
-
const kids =
|
|
4537
|
+
const kids = childrenOf2(d);
|
|
4307
4538
|
const kidShapes = kids.map(shapeOf);
|
|
4308
4539
|
const payload = payloadKey(p, d);
|
|
4309
4540
|
const out2 = [];
|
|
@@ -4364,7 +4595,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4364
4595
|
let cur = [...members];
|
|
4365
4596
|
for (let guard2 = 0; guard2 < 64; guard2++) {
|
|
4366
4597
|
const d0 = cur[0]._def;
|
|
4367
|
-
const kidLists = cur.map((c) =>
|
|
4598
|
+
const kidLists = cur.map((c) => childrenOf2(c._def));
|
|
4368
4599
|
const arity = kidLists[0].length;
|
|
4369
4600
|
if (kidLists.some((k) => k.length !== arity) || arity === 0) break;
|
|
4370
4601
|
const diff = [];
|
|
@@ -4377,7 +4608,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4377
4608
|
path2.push(i);
|
|
4378
4609
|
defs.push(d0);
|
|
4379
4610
|
cur = kidLists.map((k) => k[i]);
|
|
4380
|
-
const nextArity =
|
|
4611
|
+
const nextArity = childrenOf2(cur[0]._def).length;
|
|
4381
4612
|
const samePayload = cur.every((c) => payloadKey(c, c._def) === payloadKey(cur[0], cur[0]._def));
|
|
4382
4613
|
if (!samePayload || nextArity === 0) break;
|
|
4383
4614
|
}
|
|
@@ -4385,7 +4616,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4385
4616
|
let slotSize = 0;
|
|
4386
4617
|
const sizeOf = (p) => {
|
|
4387
4618
|
let n = 1;
|
|
4388
|
-
for (const k of
|
|
4619
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4389
4620
|
return n;
|
|
4390
4621
|
};
|
|
4391
4622
|
for (const c of cur) slotSize = Math.max(slotSize, sizeOf(c));
|
|
@@ -4394,7 +4625,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4394
4625
|
function renderWithHole(p, path2, depth = 0) {
|
|
4395
4626
|
if (depth === path2.length) return "\u2039slot\u203A";
|
|
4396
4627
|
const d = p._def;
|
|
4397
|
-
const kids =
|
|
4628
|
+
const kids = childrenOf2(d);
|
|
4398
4629
|
const idx = path2[depth];
|
|
4399
4630
|
const parts = kids.map((k, i) => i === idx ? renderWithHole(k, path2, depth + 1) : render(k, 2));
|
|
4400
4631
|
switch (d.tag) {
|
|
@@ -4852,7 +5083,7 @@ function capturesPositionally(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4852
5083
|
seen.add(p);
|
|
4853
5084
|
const d = p._def;
|
|
4854
5085
|
if (d.tag === "field" || d.tag === "label") return true;
|
|
4855
|
-
for (const k of
|
|
5086
|
+
for (const k of childrenOf2(d)) if (capturesPositionally(k, seen)) return true;
|
|
4856
5087
|
return false;
|
|
4857
5088
|
}
|
|
4858
5089
|
function detectHandRolledSepBy(terms, shapeOf) {
|
|
@@ -4958,7 +5189,7 @@ function nestedNodeTypes(root, out, seen, isRoot) {
|
|
|
4958
5189
|
}
|
|
4959
5190
|
return;
|
|
4960
5191
|
}
|
|
4961
|
-
for (const k of
|
|
5192
|
+
for (const k of childrenOf2(d)) nestedNodeTypes(k, out, seen, false);
|
|
4962
5193
|
}
|
|
4963
5194
|
var MAX_LOST_TYPES = 8;
|
|
4964
5195
|
function findStructureLoss(visited, resolve2) {
|
|
@@ -5385,9 +5616,18 @@ function buildGrammarPlan(entry, winners) {
|
|
|
5385
5616
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
|
|
5386
5617
|
}
|
|
5387
5618
|
|
|
5619
|
+
// src/cst/trivia-entries.ts
|
|
5620
|
+
var EMPTY_INDICES = Object.freeze([]);
|
|
5621
|
+
var EMPTY_GAPS = Object.freeze([]);
|
|
5622
|
+
var SELECTED_ROOT_STRIDE = 5;
|
|
5623
|
+
|
|
5388
5624
|
// src/compiler/scannable-run.ts
|
|
5389
5625
|
var BACKSLASH = 92;
|
|
5390
5626
|
var META = new Set("()[]{}*+?|^$.".split(""));
|
|
5627
|
+
var SELECTED_ROOT_OWNED_RANGE_PLACEHOLDER = Array.from(
|
|
5628
|
+
{ length: SELECTED_ROOT_STRIDE - 3 },
|
|
5629
|
+
() => "0"
|
|
5630
|
+
).join(", ");
|
|
5391
5631
|
function classToRanges(cls) {
|
|
5392
5632
|
if (cls === "\\d") return shorthandRanges("d");
|
|
5393
5633
|
if (cls === "\\w") return shorthandRanges("w");
|
|
@@ -6426,13 +6666,15 @@ function scanBranch(shape, mint) {
|
|
|
6426
6666
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6427
6667
|
return [...m.setup, ` if (${m.end} > _e) { _e = ${m.end}; continue }`].join("\n");
|
|
6428
6668
|
}
|
|
6429
|
-
function scanBranchLabeled(shape, kindIndex, mint) {
|
|
6669
|
+
function scanBranchLabeled(shape, kindIndex, label2, mint) {
|
|
6430
6670
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6431
6671
|
return [
|
|
6432
6672
|
...m.setup,
|
|
6433
6673
|
` if (${m.end} > _e) {`,
|
|
6434
6674
|
` if (_cap) {`,
|
|
6435
6675
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, ${m.end}, ${kindIndex})`,
|
|
6676
|
+
` const _rk = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(label2)}] ?? -1)`,
|
|
6677
|
+
` if (_rk >= 0) _ctx._rootTriviaLog.push(${SELECTED_ROOT_OWNED_RANGE_PLACEHOLDER}, _e, ${m.end}, _rk)`,
|
|
6436
6678
|
` 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})`,
|
|
6437
6679
|
` }`,
|
|
6438
6680
|
` _e = ${m.end}`,
|
|
@@ -6492,6 +6734,11 @@ var CAP_RECORD = [
|
|
|
6492
6734
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
|
|
6493
6735
|
` }`
|
|
6494
6736
|
].join("\n");
|
|
6737
|
+
var SELECTED_ROOT_FINISH = [
|
|
6738
|
+
` if (_cap && _ctx._rootTriviaCapture !== false && _ctx._rootTriviaLog !== undefined && _ctx._rootTriviaLog.length !== _rootMark) {`,
|
|
6739
|
+
` for (let _ri = _rootMark; _ri < _ctx._rootTriviaLog.length; _ri += ${SELECTED_ROOT_STRIDE}) { _ctx._rootTriviaLog[_ri] = _pos; _ctx._rootTriviaLog[_ri + 1] = _e }`,
|
|
6740
|
+
` }`
|
|
6741
|
+
].join("\n");
|
|
6495
6742
|
function composeFastLoop(shapes) {
|
|
6496
6743
|
const mint = makeMint();
|
|
6497
6744
|
return [
|
|
@@ -6520,7 +6767,7 @@ function analyzeLabeledScannableRun(trivia2) {
|
|
|
6520
6767
|
const d = getCoreRegexDef(arm.parser);
|
|
6521
6768
|
const shape = d ? scanShapeFromRegex(d.source, d.flags) : null;
|
|
6522
6769
|
if (!shape) return null;
|
|
6523
|
-
out.push({ shape, kindIndex: arm.kindIndex });
|
|
6770
|
+
out.push({ shape, kindIndex: arm.kindIndex, label: arm.label });
|
|
6524
6771
|
}
|
|
6525
6772
|
return out;
|
|
6526
6773
|
}
|
|
@@ -6529,11 +6776,13 @@ function buildLabeledScannableTriviaFnDecl(fnName, arms) {
|
|
|
6529
6776
|
return [
|
|
6530
6777
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6531
6778
|
` let _e = _pos`,
|
|
6779
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6532
6780
|
` while (_e < input.length) {`,
|
|
6533
6781
|
` const c = input.charCodeAt(_e)`,
|
|
6534
|
-
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, mint)),
|
|
6782
|
+
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, a.label, mint)),
|
|
6535
6783
|
` break`,
|
|
6536
6784
|
` }`,
|
|
6785
|
+
SELECTED_ROOT_FINISH,
|
|
6537
6786
|
` return _e`,
|
|
6538
6787
|
`}`
|
|
6539
6788
|
].join("\n");
|
|
@@ -6549,6 +6798,8 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6549
6798
|
` const _ce = _e + _m${i}[0].length`,
|
|
6550
6799
|
` if (_cap) {`,
|
|
6551
6800
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
|
|
6801
|
+
` const _rk${i} = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(arm.label)}] ?? -1)`,
|
|
6802
|
+
` if (_rk${i} >= 0) _ctx._rootTriviaLog.push(0, 0, _e, _ce, _rk${i})`,
|
|
6552
6803
|
` 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})`,
|
|
6553
6804
|
` }`,
|
|
6554
6805
|
` _e = _ce`,
|
|
@@ -6560,11 +6811,13 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6560
6811
|
return [
|
|
6561
6812
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6562
6813
|
` let _e = _pos`,
|
|
6814
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6563
6815
|
` while (_e < input.length) {`,
|
|
6564
6816
|
` let _matched = false`,
|
|
6565
6817
|
tryArms,
|
|
6566
6818
|
` if (!_matched) break`,
|
|
6567
6819
|
` }`,
|
|
6820
|
+
SELECTED_ROOT_FINISH,
|
|
6568
6821
|
` return _e`,
|
|
6569
6822
|
`}`
|
|
6570
6823
|
].join("\n");
|
|
@@ -6587,6 +6840,8 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6587
6840
|
` const _ce = _r${i}.span.end`,
|
|
6588
6841
|
` if (_cap) {`,
|
|
6589
6842
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
|
|
6843
|
+
` const _rk${i} = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(arm.label)}] ?? -1)`,
|
|
6844
|
+
` if (_rk${i} >= 0) _ctx._rootTriviaLog.push(0, 0, _e, _ce, _rk${i})`,
|
|
6590
6845
|
` 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})`,
|
|
6591
6846
|
` }`,
|
|
6592
6847
|
` _e = _ce`,
|
|
@@ -6598,11 +6853,13 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6598
6853
|
return [
|
|
6599
6854
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6600
6855
|
` let _e = _pos`,
|
|
6856
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6601
6857
|
` while (_e < input.length) {`,
|
|
6602
6858
|
` let _matched = false`,
|
|
6603
6859
|
tryArms,
|
|
6604
6860
|
` if (!_matched) break`,
|
|
6605
6861
|
` }`,
|
|
6862
|
+
SELECTED_ROOT_FINISH,
|
|
6606
6863
|
` return _e`,
|
|
6607
6864
|
`}`
|
|
6608
6865
|
].join("\n");
|
|
@@ -6833,6 +7090,9 @@ function endLoweringCapture() {
|
|
|
6833
7090
|
_loweringSink = null;
|
|
6834
7091
|
return misses;
|
|
6835
7092
|
}
|
|
7093
|
+
function hasSelectedRootTrivia(ctx) {
|
|
7094
|
+
return ctx.rootTriviaClassified === true;
|
|
7095
|
+
}
|
|
6836
7096
|
function v(ctx, prefix = "_v") {
|
|
6837
7097
|
return `${prefix}${ctx.vars++}`;
|
|
6838
7098
|
}
|
|
@@ -7142,10 +7402,12 @@ function planDisjointDispatch(parsers) {
|
|
|
7142
7402
|
}
|
|
7143
7403
|
return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
7144
7404
|
}
|
|
7145
|
-
function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
|
|
7405
|
+
function captureRestoreBody(ctx, mL, mR, mTl, mLg, mF = null, mRootLg = null) {
|
|
7146
7406
|
const fieldRestore = mF ? `; if (_ctx._fields && _ctx._fields.length !== ${mF}) _ctx._fields.length = ${mF}` : "";
|
|
7147
7407
|
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}`;
|
|
7148
|
-
|
|
7408
|
+
const logRestore = mLg ? `; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${mLg}) _ctx._triviaLog.length = ${mLg}` : "";
|
|
7409
|
+
const rootLogRestore = hasSelectedRootTrivia(ctx) && mRootLg ? `; if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${mRootLg}) _ctx._rootTriviaLog.length = ${mRootLg}` : "";
|
|
7410
|
+
return `${base}${logRestore}${rootLogRestore}`;
|
|
7149
7411
|
}
|
|
7150
7412
|
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
7151
7413
|
if (seen.has(p)) return false;
|
|
@@ -7355,7 +7617,7 @@ function emitFallible(inner, ctx, pos, swallow = false) {
|
|
|
7355
7617
|
`${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
|
|
7356
7618
|
`${ind0}}`,
|
|
7357
7619
|
...mL ? [
|
|
7358
|
-
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
|
|
7620
|
+
`${ind0}if (!${okV}) { ${captureRestoreBody(ctx, mL, mR, mTl, null, mF)} }`
|
|
7359
7621
|
] : []
|
|
7360
7622
|
];
|
|
7361
7623
|
return { stmts, okVar: okV, valVar: valV, endVar: endV, mayCommit };
|
|
@@ -7552,11 +7814,13 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7552
7814
|
const markV = v(ctx, "_mk");
|
|
7553
7815
|
const markTl = v(ctx, "_mktl");
|
|
7554
7816
|
const markLog = v(ctx, "_mklg");
|
|
7817
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7555
7818
|
const scanEndV = v(ctx, "_sne");
|
|
7556
7819
|
stmts.push(
|
|
7557
7820
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7558
7821
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7559
7822
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7823
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7560
7824
|
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7561
7825
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7562
7826
|
);
|
|
@@ -7565,17 +7829,19 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7565
7829
|
const endAfterV = v(ctx, "_sea");
|
|
7566
7830
|
stmts.push(
|
|
7567
7831
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7568
|
-
`${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}
|
|
7832
|
+
`${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};` : ""} }`
|
|
7569
7833
|
);
|
|
7570
7834
|
valueVars.push(r2.valueVar);
|
|
7571
7835
|
continue;
|
|
7572
7836
|
} else {
|
|
7573
7837
|
const trivFn = ensureTriviaFn(ctx);
|
|
7574
7838
|
const markLog = v(ctx, "_mklg");
|
|
7839
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7575
7840
|
const scanEndV = v(ctx, "_sne");
|
|
7576
|
-
const capArg = ctx.noHoist ? "0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7841
|
+
const capArg = ctx.noHoist ? "0" : hasSelectedRootTrivia(ctx) ? "(_ctx._triviaLog !== undefined || _ctx._rootTriviaLog !== undefined) ? 2 : 0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7577
7842
|
stmts.push(
|
|
7578
7843
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7844
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7579
7845
|
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7580
7846
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7581
7847
|
);
|
|
@@ -7584,7 +7850,7 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7584
7850
|
const endAfterV = v(ctx, "_sea");
|
|
7585
7851
|
stmts.push(
|
|
7586
7852
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7587
|
-
`${ind(ctx)}if (${endAfterV} > ${scanEndV}) ${curV} = ${endAfterV}; else if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}`
|
|
7853
|
+
`${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};` : ""} }`
|
|
7588
7854
|
);
|
|
7589
7855
|
valueVars.push(r2.valueVar);
|
|
7590
7856
|
continue;
|
|
@@ -7826,6 +8092,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7826
8092
|
const selectorRawMark = selectorNeedsRollback ? v(ctx, "_dsr") : null;
|
|
7827
8093
|
const selectorTriviaMark = selectorNeedsRollback ? v(ctx, "_dst") : null;
|
|
7828
8094
|
const selectorLogMark = selectorNeedsRollback ? v(ctx, "_dsg") : null;
|
|
8095
|
+
const selectorRootLogMark = selectorNeedsRollback && hasSelectedRootTrivia(ctx) ? v(ctx, "_dsrg") : null;
|
|
7829
8096
|
const selectorFieldMark = selectorNeedsRollback ? v(ctx, "_dsf") : null;
|
|
7830
8097
|
const selectorErrorMark = selectorNeedsRollback ? v(ctx, "_dse") : null;
|
|
7831
8098
|
const selector = emit(def.selector, ctx, pos);
|
|
@@ -7838,6 +8105,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7838
8105
|
`${ind(ctx)}const ${selectorRawMark} = _ctx._cstRawChildren?.length ?? 0`,
|
|
7839
8106
|
`${ind(ctx)}const ${selectorTriviaMark} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
7840
8107
|
`${ind(ctx)}const ${selectorLogMark} = _ctx._triviaLog?.length ?? 0`,
|
|
8108
|
+
...selectorRootLogMark ? [`${ind(ctx)}const ${selectorRootLogMark} = _ctx._rootTriviaLog?.length ?? 0`] : [],
|
|
7841
8109
|
`${ind(ctx)}const ${selectorFieldMark} = _ctx._fields?.length ?? 0`,
|
|
7842
8110
|
`${ind(ctx)}const ${selectorErrorMark} = _ctx._errors?.length ?? 0`
|
|
7843
8111
|
] : [],
|
|
@@ -7857,16 +8125,18 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7857
8125
|
const mayError = mayRecordRecoveryError(parser3, !!ctx.recovery);
|
|
7858
8126
|
const errMark = mayError ? v(ctx, "_derr") : null;
|
|
7859
8127
|
const logMark = ctx.activeTrivia ? v(ctx, "_dlog") : null;
|
|
8128
|
+
const rootLogMark = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_drlog") : null;
|
|
7860
8129
|
if (usesRouted) {
|
|
7861
8130
|
stmts.push(
|
|
7862
8131
|
...routedV ? [`${ind(ctx)}const ${routedV} = _ctx._routed; _ctx._routed = { value: ${selector.valueVar}, span: { start: ${pos}, end: ${selector.endVar} } }`] : [],
|
|
7863
8132
|
...selectorLeafMark ? [
|
|
7864
|
-
`${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}
|
|
8133
|
+
`${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}`
|
|
7865
8134
|
] : []
|
|
7866
8135
|
);
|
|
7867
8136
|
}
|
|
7868
8137
|
if (errMark) stmts.push(`${ind(ctx)}const ${errMark} = _ctx._errors?.length ?? 0`);
|
|
7869
8138
|
if (logMark) stmts.push(`${ind(ctx)}const ${logMark} = _ctx._triviaLog?.length ?? 0`);
|
|
8139
|
+
if (rootLogMark) stmts.push(`${ind(ctx)}const ${rootLogMark} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
7870
8140
|
const savedRoutedLocal = ctx.routedLocal;
|
|
7871
8141
|
const savedNoHoist = ctx.noHoist;
|
|
7872
8142
|
if (usesRouted && !needsRoutedContext) {
|
|
@@ -7881,11 +8151,12 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7881
8151
|
stmts.push(...coverageAttempt(ctx, coverageId, pos));
|
|
7882
8152
|
const errorRollback = errMark ? `if (_ctx._errors && _ctx._errors.length !== ${errMark}) _ctx._errors.length = ${errMark}; ` : "";
|
|
7883
8153
|
const logRollback = logMark ? `if (_ctx._triviaLog && _ctx._triviaLog.length !== ${logMark}) _ctx._triviaLog.length = ${logMark}; ` : "";
|
|
8154
|
+
const rootLogRollback = rootLogMark ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${rootLogMark}) _ctx._rootTriviaLog.length = ${rootLogMark}; ` : "";
|
|
7884
8155
|
const routedRollback = routedV ? `_ctx._routed = ${routedV}; ` : "";
|
|
7885
8156
|
const coverageFailure = coverageId === void 0 ? "" : `_ctx._grammarTrace?.write({ id: ${JSON.stringify(coverageId)}, phase: 'failure', offset: _ctx._fe }); `;
|
|
7886
8157
|
stmts.push(
|
|
7887
8158
|
...tail.stmts,
|
|
7888
|
-
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8159
|
+
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${rootLogRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
7889
8160
|
...routedV ? [`${ind(ctx)}_ctx._routed = ${routedV}`] : [],
|
|
7890
8161
|
`${ind(ctx)}${outV} = ${valueMode === "tail" ? tail.valVar : `[${selector.valueVar}, ${tail.valVar}]`}`,
|
|
7891
8162
|
`${ind(ctx)}${outE} = ${tail.endVar}`,
|
|
@@ -8066,11 +8337,13 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8066
8337
|
const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
|
|
8067
8338
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
8068
8339
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
8340
|
+
const markRootLog = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_cmlrg") : null;
|
|
8069
8341
|
const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
|
|
8070
8342
|
const markErrors = armMayRecordError ? v(ctx, "_cme") : null;
|
|
8071
|
-
const captureRollback = markLeaves ? captureRestoreBody(markLeaves, markRaw, markTl, markLog, markFields) : "";
|
|
8343
|
+
const captureRollback = markLeaves ? captureRestoreBody(ctx, markLeaves, markRaw, markTl, markLog, markFields, markRootLog) : "";
|
|
8344
|
+
const rootRollback = markRootLog && !markLeaves ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}` : "";
|
|
8072
8345
|
const errorRollback = markErrors ? `if (_ctx._errors && _ctx._errors.length !== ${markErrors}) _ctx._errors.length = ${markErrors}` : "";
|
|
8073
|
-
const rollback = [captureRollback, errorRollback].filter(Boolean).join("; ");
|
|
8346
|
+
const rollback = [captureRollback, rootRollback, errorRollback].filter(Boolean).join("; ");
|
|
8074
8347
|
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
8075
8348
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
8076
8349
|
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
@@ -8085,6 +8358,7 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8085
8358
|
...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
|
|
8086
8359
|
);
|
|
8087
8360
|
}
|
|
8361
|
+
if (markRootLog) stmts.push(`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
8088
8362
|
if (markErrors) stmts.push(`${ind(ctx)}const ${markErrors} = _ctx._errors?.length ?? 0`);
|
|
8089
8363
|
const arm = emitFallible(p, ctx, pos, atStart);
|
|
8090
8364
|
const { stmts: armStmts, okVar, valVar, endVar } = arm;
|
|
@@ -8153,7 +8427,7 @@ function routedNeedsContextBridge(p, ctx, seen = /* @__PURE__ */ new Set()) {
|
|
|
8153
8427
|
const d = p._def;
|
|
8154
8428
|
if (d.tag === "dispatch") return false;
|
|
8155
8429
|
if (d.tag === "withCtx") return parserUsesRouted2(d.parser);
|
|
8156
|
-
return
|
|
8430
|
+
return childrenOf3(d).some((child) => routedNeedsContextBridge(child, ctx, seen));
|
|
8157
8431
|
}
|
|
8158
8432
|
function armReplayInScope(arm, ctx) {
|
|
8159
8433
|
let p = arm;
|
|
@@ -8272,21 +8546,29 @@ function emitMany(def, ctx, pos) {
|
|
|
8272
8546
|
const markV = v(ctx, "_mk");
|
|
8273
8547
|
const markTl = v(ctx, "_mktl");
|
|
8274
8548
|
const markLog = v(ctx, "_mklg");
|
|
8549
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8275
8550
|
const npV = v(ctx, "_np");
|
|
8276
8551
|
stmts.push(
|
|
8277
8552
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8278
8553
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8279
8554
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8555
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8280
8556
|
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8281
8557
|
...emitLineTrack(ctx, curV, npV)
|
|
8282
8558
|
);
|
|
8283
8559
|
itemPos = npV;
|
|
8284
|
-
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}
|
|
8560
|
+
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};` : ""} `;
|
|
8285
8561
|
} else {
|
|
8286
8562
|
const trivFn = ensureTriviaFn(ctx);
|
|
8563
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8287
8564
|
const npV = v(ctx, "_np");
|
|
8288
|
-
stmts.push(
|
|
8565
|
+
stmts.push(
|
|
8566
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8567
|
+
`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8568
|
+
...emitLineTrack(ctx, curV, npV)
|
|
8569
|
+
);
|
|
8289
8570
|
itemPos = npV;
|
|
8571
|
+
rollback = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8290
8572
|
}
|
|
8291
8573
|
}
|
|
8292
8574
|
if (!ctx.recovery && !ctx.coverage && !failsAtStart(def.parser) && needsFirstSetGuard(def.parser)) {
|
|
@@ -8346,9 +8628,10 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8346
8628
|
const raw = v(ctx, "_atr");
|
|
8347
8629
|
const trivia2 = v(ctx, "_att");
|
|
8348
8630
|
const log = v(ctx, "_atg");
|
|
8631
|
+
const rootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_atrg") : null;
|
|
8349
8632
|
const fields = v(ctx, "_atf");
|
|
8350
8633
|
const errors = v(ctx, "_ate");
|
|
8351
|
-
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}
|
|
8634
|
+
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}`;
|
|
8352
8635
|
const traceId = ctx.coverage?.plan.attempts.get(p);
|
|
8353
8636
|
const traceRollback = traceId === void 0 ? "" : ` _ctx._grammarTrace?.write({ id: ${JSON.stringify(traceId)}, phase: 'rollback', offset: ${pos} });`;
|
|
8354
8637
|
const preGuard = [];
|
|
@@ -8364,7 +8647,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8364
8647
|
return {
|
|
8365
8648
|
stmts: [
|
|
8366
8649
|
...preGuard,
|
|
8367
|
-
`${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`,
|
|
8650
|
+
`${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`,
|
|
8368
8651
|
...inner.stmts,
|
|
8369
8652
|
...emitIfFail(ctx, `!${inner.okVar}`, `{ ${rollback};${traceRollback}${inner.mayCommit ? ` if (_ctx._fc) ${committedFailBody(ctx)};` : ""} _ctx._fe = ${pos}; ${propagateFailBody(ctx)} }`)
|
|
8370
8653
|
],
|
|
@@ -8406,16 +8689,17 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8406
8689
|
const itemFailBreak = (sepEndVar, sepRb, postSepRb) => def.trailing === void 0 ? `${sepRb}break` : `${postSepRb}${curV} = ${sepEndVar}; break`;
|
|
8407
8690
|
const postSepMarks = () => {
|
|
8408
8691
|
if (def.trailing === void 0 || !ctx.capturing) return { decl: [], rb: "" };
|
|
8409
|
-
const lv = v(ctx, "_tlv"), rw = v(ctx, "_trw"), tl = v(ctx, "_ttl"), lg = v(ctx, "_tlg"), fl = v(ctx, "_tlf");
|
|
8692
|
+
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");
|
|
8410
8693
|
return {
|
|
8411
8694
|
decl: [
|
|
8412
8695
|
`${ind(ctx)}const ${lv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8413
8696
|
`${ind(ctx)}const ${rw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8414
8697
|
`${ind(ctx)}const ${tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8415
8698
|
`${ind(ctx)}const ${lg} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8699
|
+
...rlg ? [`${ind(ctx)}const ${rlg} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8416
8700
|
`${ind(ctx)}const ${fl} = _ctx._fields ? _ctx._fields.length : 0`
|
|
8417
8701
|
],
|
|
8418
|
-
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}
|
|
8702
|
+
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}; `
|
|
8419
8703
|
};
|
|
8420
8704
|
};
|
|
8421
8705
|
if (rec) {
|
|
@@ -8453,6 +8737,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8453
8737
|
const markV = v(ctx, "_mk");
|
|
8454
8738
|
const markTl = v(ctx, "_mktl");
|
|
8455
8739
|
const markLog = v(ctx, "_mklg");
|
|
8740
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8456
8741
|
const markLv = v(ctx, "_mklv");
|
|
8457
8742
|
const markFld = v(ctx, "_mkf");
|
|
8458
8743
|
const spV = v(ctx, "_sp");
|
|
@@ -8460,13 +8745,14 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8460
8745
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8461
8746
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8462
8747
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8748
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8463
8749
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8464
8750
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8465
8751
|
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8466
8752
|
...emitLineTrack(ctx, curV, spV)
|
|
8467
8753
|
);
|
|
8468
8754
|
sepAtPos = spV;
|
|
8469
|
-
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}
|
|
8755
|
+
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}; `;
|
|
8470
8756
|
const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8471
8757
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
|
|
8472
8758
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep2.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
@@ -8484,19 +8770,30 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8484
8770
|
);
|
|
8485
8771
|
} else {
|
|
8486
8772
|
const trivFn = ensureTriviaFn(ctx);
|
|
8773
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8487
8774
|
const spV = v(ctx, "_sp");
|
|
8488
|
-
stmts.push(
|
|
8775
|
+
stmts.push(
|
|
8776
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8777
|
+
`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8778
|
+
...emitLineTrack(ctx, curV, spV)
|
|
8779
|
+
);
|
|
8489
8780
|
sepAtPos = spV;
|
|
8490
8781
|
const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8491
8782
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
|
|
8492
|
-
|
|
8783
|
+
const rollbackToSep = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8784
|
+
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep2.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
8785
|
+
const postRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_psrlg") : null;
|
|
8493
8786
|
const npV = v(ctx, "_np");
|
|
8494
|
-
stmts.push(
|
|
8787
|
+
stmts.push(
|
|
8788
|
+
...postRootLog ? [`${ind(ctx)}const ${postRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8789
|
+
`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8790
|
+
...emitLineTrack(ctx, sepEnd, npV)
|
|
8791
|
+
);
|
|
8495
8792
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8496
8793
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8497
8794
|
stmts.push(
|
|
8498
8795
|
...nextStmts,
|
|
8499
|
-
...failItem(nextOk, next.mayCommit, npV, itemFailBreak(sepEnd,
|
|
8796
|
+
...failItem(nextOk, next.mayCommit, npV, itemFailBreak(sepEnd, rollbackToSep, postRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${postRootLog}) _ctx._rootTriviaLog.length = ${postRootLog}; ` : "")),
|
|
8500
8797
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
8501
8798
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
8502
8799
|
);
|
|
@@ -8591,6 +8888,7 @@ function emitNot(def, ctx, pos) {
|
|
|
8591
8888
|
const raw = sinksLive ? v(ctx, "_ntr") : null;
|
|
8592
8889
|
const tl = sinksLive ? v(ctx, "_ntt") : null;
|
|
8593
8890
|
const log = sinksLive ? v(ctx, "_ntg") : null;
|
|
8891
|
+
const rootLog = sinksLive && hasSelectedRootTrivia(ctx) ? v(ctx, "_ntrg") : null;
|
|
8594
8892
|
const fields = sinksLive ? v(ctx, "_ntf") : null;
|
|
8595
8893
|
const errors = sinksLive ? v(ctx, "_nte") : null;
|
|
8596
8894
|
const { stmts, okVar } = emitFallible(def.parser, ctx, pos, true);
|
|
@@ -8598,11 +8896,11 @@ function emitNot(def, ctx, pos) {
|
|
|
8598
8896
|
return {
|
|
8599
8897
|
stmts: [
|
|
8600
8898
|
...sinksLive ? [
|
|
8601
|
-
`${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`
|
|
8899
|
+
`${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`
|
|
8602
8900
|
] : [],
|
|
8603
8901
|
...stmts,
|
|
8604
8902
|
...sinksLive ? [
|
|
8605
|
-
`${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}
|
|
8903
|
+
`${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}`
|
|
8606
8904
|
] : [],
|
|
8607
8905
|
...emitIfFail(ctx, okVar, failBody(ctx, label2, pos))
|
|
8608
8906
|
],
|
|
@@ -8738,16 +9036,17 @@ function emitToken(def, ctx, pos) {
|
|
|
8738
9036
|
const sk = v(ctx, "_tokKinds");
|
|
8739
9037
|
const stl = v(ctx, "_tokTl");
|
|
8740
9038
|
const sol = v(ctx, "_tokLog");
|
|
9039
|
+
const srl = hasSelectedRootTrivia(ctx) ? v(ctx, "_tokRootLog") : null;
|
|
8741
9040
|
const sb = v(ctx, "_tokBuf");
|
|
8742
9041
|
const valV = v(ctx, "_tok");
|
|
8743
9042
|
return {
|
|
8744
9043
|
stmts: [
|
|
8745
|
-
`${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`,
|
|
8746
|
-
`${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`,
|
|
9044
|
+
`${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`,
|
|
9045
|
+
`${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`,
|
|
8747
9046
|
`${i}try {`,
|
|
8748
9047
|
...reindentStmts(inner.stmts, ctx.indent + 1).map((stmt) => stmt.replace(/^(\s*)(?:const|let)\s+/, "$1var ")),
|
|
8749
9048
|
`${i}} finally {`,
|
|
8750
|
-
`${i} _ctx.trivia = ${sv}; _ctx.triviaKindLabels = ${sk}; _ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx._cstTriviaLog = ${stl}; _ctx._triviaLog = ${sol}
|
|
9049
|
+
`${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}`,
|
|
8751
9050
|
`${i}}`,
|
|
8752
9051
|
...emitIfFail(ctx, `!${inner.okVar}`, propagateFailBody(ctx)),
|
|
8753
9052
|
`${i}const ${valV} = input.slice(${pos}, ${inner.endVar})`,
|
|
@@ -8916,7 +9215,8 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8916
9215
|
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
8917
9216
|
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
8918
9217
|
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})`;
|
|
8919
|
-
const
|
|
9218
|
+
const hostBuildArgs = `${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV}${def.tags !== void 0 && def.tags.length > 0 ? `, ${JSON.stringify(def.tags)}` : ""}`;
|
|
9219
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${hostBuildArgs})`;
|
|
8920
9220
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
8921
9221
|
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;
|
|
8922
9222
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -9225,6 +9525,8 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9225
9525
|
case "grammar": {
|
|
9226
9526
|
const savedTrivia = ctx.activeTrivia;
|
|
9227
9527
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
9528
|
+
const opaqueRootCapture = hasSelectedRootTrivia(ctx) && def.rootCapture === "opaque";
|
|
9529
|
+
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;
|
|
9228
9530
|
if (def.clearTrivia) {
|
|
9229
9531
|
ctx.activeTrivia = void 0;
|
|
9230
9532
|
ctx.triviaKindLabels = void 0;
|
|
@@ -9235,13 +9537,38 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9235
9537
|
}
|
|
9236
9538
|
}
|
|
9237
9539
|
const savedCapture = def.captureTrivia ? v(ctx, "_gcap") : null;
|
|
9540
|
+
const savedRootCapture = opaqueRootCapture ? v(ctx, "_grtc") : null;
|
|
9541
|
+
const opaqueValue = opaqueRootCapture ? v(ctx, "_grtv") : null;
|
|
9542
|
+
const opaqueEnd = opaqueRootCapture ? v(ctx, "_grte") : null;
|
|
9543
|
+
if (opaqueRootCapture) ctx.indent++;
|
|
9238
9544
|
const r = emit(def.parser, ctx, pos);
|
|
9545
|
+
if (opaqueRootCapture) ctx.indent--;
|
|
9239
9546
|
ctx.activeTrivia = savedTrivia;
|
|
9240
9547
|
ctx.triviaKindLabels = savedKindLabels;
|
|
9241
|
-
if (!savedCapture) return r
|
|
9548
|
+
if (!savedCapture && !opaqueRootCapture) return strictScopeCheck === void 0 ? r : {
|
|
9549
|
+
...r,
|
|
9550
|
+
stmts: [strictScopeCheck, ...r.stmts]
|
|
9551
|
+
};
|
|
9552
|
+
if (opaqueRootCapture) {
|
|
9553
|
+
return {
|
|
9554
|
+
stmts: [
|
|
9555
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9556
|
+
`${ind(ctx)}let ${opaqueValue}, ${opaqueEnd}`,
|
|
9557
|
+
`${ind(ctx)}${savedCapture ? `const ${savedCapture} = _ctx.captureTrivia; ` : ""}const ${savedRootCapture} = _ctx._rootTriviaCapture; _ctx._rootTriviaCapture = false`,
|
|
9558
|
+
`${ind(ctx)}try {`,
|
|
9559
|
+
...savedCapture ? [`${ind(ctx)} _ctx.captureTrivia = true`] : [],
|
|
9560
|
+
...r.stmts,
|
|
9561
|
+
`${ind(ctx)} ${opaqueValue} = ${r.valueVar}; ${opaqueEnd} = ${r.endVar}`,
|
|
9562
|
+
`${ind(ctx)}} finally { ${savedCapture ? `_ctx.captureTrivia = ${savedCapture}; ` : ""}_ctx._rootTriviaCapture = ${savedRootCapture} }`
|
|
9563
|
+
],
|
|
9564
|
+
valueVar: opaqueValue,
|
|
9565
|
+
endVar: opaqueEnd
|
|
9566
|
+
};
|
|
9567
|
+
}
|
|
9242
9568
|
return {
|
|
9243
9569
|
...r,
|
|
9244
9570
|
stmts: [
|
|
9571
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9245
9572
|
`${ind(ctx)}const ${savedCapture} = _ctx.captureTrivia; _ctx.captureTrivia = true`,
|
|
9246
9573
|
...r.stmts,
|
|
9247
9574
|
`${ind(ctx)}_ctx.captureTrivia = ${savedCapture}`
|
|
@@ -9379,7 +9706,7 @@ function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9379
9706
|
return false;
|
|
9380
9707
|
}
|
|
9381
9708
|
}
|
|
9382
|
-
return
|
|
9709
|
+
return childrenOf3(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9383
9710
|
}
|
|
9384
9711
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9385
9712
|
if (seen.has(p)) return false;
|
|
@@ -9398,7 +9725,7 @@ function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9398
9725
|
case "dispatch":
|
|
9399
9726
|
return false;
|
|
9400
9727
|
default:
|
|
9401
|
-
return
|
|
9728
|
+
return childrenOf3(d).some((child) => parserUsesRouted2(child, seen));
|
|
9402
9729
|
}
|
|
9403
9730
|
}
|
|
9404
9731
|
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -9413,9 +9740,9 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9413
9740
|
return false;
|
|
9414
9741
|
}
|
|
9415
9742
|
}
|
|
9416
|
-
return
|
|
9743
|
+
return childrenOf3(d).some((child) => hasDirectBuildDef(child, seen));
|
|
9417
9744
|
}
|
|
9418
|
-
function
|
|
9745
|
+
function childrenOf3(def) {
|
|
9419
9746
|
switch (def.tag) {
|
|
9420
9747
|
case "sequence":
|
|
9421
9748
|
case "choice":
|
|
@@ -9490,7 +9817,7 @@ function subtreeSizes(roots) {
|
|
|
9490
9817
|
const def = p._def;
|
|
9491
9818
|
let s = 1;
|
|
9492
9819
|
if (def.tag !== "lazy") {
|
|
9493
|
-
for (const child of
|
|
9820
|
+
for (const child of childrenOf3(def)) s += child._def.tag === "lazy" ? 1 : sz(child);
|
|
9494
9821
|
}
|
|
9495
9822
|
sizes.set(p, s);
|
|
9496
9823
|
return s;
|
|
@@ -9511,7 +9838,7 @@ function subtreeSizes(roots) {
|
|
|
9511
9838
|
return;
|
|
9512
9839
|
}
|
|
9513
9840
|
sz(p);
|
|
9514
|
-
for (const child of
|
|
9841
|
+
for (const child of childrenOf3(def)) visit(child);
|
|
9515
9842
|
};
|
|
9516
9843
|
for (const root of roots) visit(root);
|
|
9517
9844
|
return sizes;
|
|
@@ -9521,7 +9848,7 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9521
9848
|
const recursive = /* @__PURE__ */ new Set();
|
|
9522
9849
|
const descended = /* @__PURE__ */ new Set();
|
|
9523
9850
|
const active = /* @__PURE__ */ new Set();
|
|
9524
|
-
function
|
|
9851
|
+
function walk(p) {
|
|
9525
9852
|
const def = p._def;
|
|
9526
9853
|
if (def.tag === "lazy") {
|
|
9527
9854
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
@@ -9538,17 +9865,17 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9538
9865
|
return;
|
|
9539
9866
|
}
|
|
9540
9867
|
active.add(p);
|
|
9541
|
-
|
|
9868
|
+
walk(resolved);
|
|
9542
9869
|
active.delete(p);
|
|
9543
9870
|
return;
|
|
9544
9871
|
}
|
|
9545
9872
|
if (isHoistableTag(def.tag)) {
|
|
9546
9873
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
9547
9874
|
}
|
|
9548
|
-
for (const child of
|
|
9875
|
+
for (const child of childrenOf3(def)) walk(child);
|
|
9549
9876
|
}
|
|
9550
9877
|
const rootsArr = [...roots];
|
|
9551
|
-
for (const root of rootsArr)
|
|
9878
|
+
for (const root of rootsArr) walk(root);
|
|
9552
9879
|
return { counts, recursive, sizes: subtreeSizes(rootsArr) };
|
|
9553
9880
|
}
|
|
9554
9881
|
function ruleDependencies(ruleMap) {
|
|
@@ -9558,7 +9885,7 @@ function ruleDependencies(ruleMap) {
|
|
|
9558
9885
|
for (const [name, comb] of ruleMap) {
|
|
9559
9886
|
const found = /* @__PURE__ */ new Set();
|
|
9560
9887
|
const seen = /* @__PURE__ */ new Set();
|
|
9561
|
-
const
|
|
9888
|
+
const walk = (p, isRoot) => {
|
|
9562
9889
|
const def = p._def;
|
|
9563
9890
|
const boundary = def.tag === "lazy" ? nameOf.get(p) ?? p._ruleName : nameOf.get(p);
|
|
9564
9891
|
if (!isRoot && boundary !== void 0) {
|
|
@@ -9574,12 +9901,12 @@ function ruleDependencies(ruleMap) {
|
|
|
9574
9901
|
} catch {
|
|
9575
9902
|
return;
|
|
9576
9903
|
}
|
|
9577
|
-
|
|
9904
|
+
walk(resolved, false);
|
|
9578
9905
|
return;
|
|
9579
9906
|
}
|
|
9580
|
-
for (const child of
|
|
9907
|
+
for (const child of childrenOf3(def)) walk(child, false);
|
|
9581
9908
|
};
|
|
9582
|
-
|
|
9909
|
+
walk(comb, true);
|
|
9583
9910
|
deps.set(name, [...found]);
|
|
9584
9911
|
}
|
|
9585
9912
|
return deps;
|
|
@@ -9726,6 +10053,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9726
10053
|
runDuplicationDiagnostic(combinator, opts?.duplication);
|
|
9727
10054
|
markUnusedValues(combinator);
|
|
9728
10055
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
10056
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || combinator._meta.rootTriviaClassified === true;
|
|
9729
10057
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9730
10058
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9731
10059
|
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
@@ -9752,7 +10080,11 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9752
10080
|
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9753
10081
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9754
10082
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9755
|
-
...
|
|
10083
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10084
|
+
...grammarTrivia ? {
|
|
10085
|
+
activeTrivia: grammarTrivia,
|
|
10086
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10087
|
+
} : {},
|
|
9756
10088
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
9757
10089
|
};
|
|
9758
10090
|
const r = emit(combinator, ctx, "_pos");
|
|
@@ -9900,10 +10232,11 @@ function assertRuleName(name) {
|
|
|
9900
10232
|
);
|
|
9901
10233
|
}
|
|
9902
10234
|
}
|
|
9903
|
-
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels) {
|
|
9904
|
-
const labels = rule._meta.triviaKindLabels
|
|
9905
|
-
|
|
9906
|
-
|
|
10235
|
+
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels, ambientRootTriviaClassified) {
|
|
10236
|
+
const labels = ambientTriviaKindLabels ?? rule._meta.triviaKindLabels;
|
|
10237
|
+
const classified = ambientRootTriviaClassified ?? rule._meta.rootTriviaClassified;
|
|
10238
|
+
if (labels === void 0 && classified === void 0) return fnSource;
|
|
10239
|
+
return `Object.assign(${fnSource}, { _meta: {${labels === void 0 ? "" : ` triviaKindLabels: ${JSON.stringify(labels)},`}${classified === void 0 ? "" : " rootTriviaClassified: true,"} } })`;
|
|
9907
10240
|
}
|
|
9908
10241
|
function compileRuleMap(ruleMap, opts) {
|
|
9909
10242
|
runGatingDiagnosticRules(ruleMap, opts?.gating);
|
|
@@ -9911,6 +10244,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9911
10244
|
for (const [, rule] of ruleMap) markUnusedValues(rule);
|
|
9912
10245
|
const coverageWinners = opts?.coverage ? Object.fromEntries(ruleMap.filter(([, rule]) => rule._def.tag !== "lazy")) : void 0;
|
|
9913
10246
|
const grammarTrivia = opts?.trivia;
|
|
10247
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || ruleMap.some(([, rule]) => rule._meta.rootTriviaClassified === true);
|
|
9914
10248
|
const grammarScanSkip = opts?.scanSkip ?? ruleMap.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9915
10249
|
const grammarHostMode = opts?.hostMode ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
9916
10250
|
const grammarTrackLines = opts?.trackLines === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -9937,7 +10271,11 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9937
10271
|
lineTracking: grammarTrackLines,
|
|
9938
10272
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(ruleMap.map(([, rule]) => rule), coverageWinners) } } : {},
|
|
9939
10273
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
9940
|
-
...
|
|
10274
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10275
|
+
...grammarTrivia ? {
|
|
10276
|
+
activeTrivia: grammarTrivia,
|
|
10277
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10278
|
+
} : {},
|
|
9941
10279
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
9942
10280
|
};
|
|
9943
10281
|
const seenNames = /* @__PURE__ */ new Map();
|
|
@@ -10025,7 +10363,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
10025
10363
|
return [`function(input, _pos, _ctx) {`, ...body, `}`].join("\n");
|
|
10026
10364
|
};
|
|
10027
10365
|
const objBody = perEntry.map(({ key, rule, r }) => {
|
|
10028
|
-
const src = publicRuleWrapperSource(rule, entryFnText(r, rule), ctx.triviaKindLabels);
|
|
10366
|
+
const src = publicRuleWrapperSource(rule, entryFnText(r, rule), ctx.triviaKindLabels, ctx.rootTriviaClassified);
|
|
10029
10367
|
return ` ${JSON.stringify(key)}: ${src.split("\n").join("\n ")}`;
|
|
10030
10368
|
}).join(",\n");
|
|
10031
10369
|
const replacement = [
|
|
@@ -10044,6 +10382,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
10044
10382
|
// host check passes vacuously — see `withHostMode` in the plugin.
|
|
10045
10383
|
hostMode: ctx.hostMode ?? "ast",
|
|
10046
10384
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10385
|
+
reflection: collectGrammarReflection(ruleMap),
|
|
10047
10386
|
...ctx.coverage === void 0 ? {} : { coverageDefinitions: ctx.coverage.plan.definitions }
|
|
10048
10387
|
};
|
|
10049
10388
|
}
|
|
@@ -10053,6 +10392,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10053
10392
|
if (opts?.duplication !== void 0) runDuplicationDiagnosticRules(ruleMapArg, opts.duplication);
|
|
10054
10393
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
10055
10394
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
10395
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || ruleMapArg.some(([, rule]) => rule._meta.rootTriviaClassified === true);
|
|
10056
10396
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
10057
10397
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10058
10398
|
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -10066,6 +10406,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10066
10406
|
return false;
|
|
10067
10407
|
}
|
|
10068
10408
|
});
|
|
10409
|
+
const nodeMeta = new Map(ruleMap.map(([name, rule]) => [name, collectGrammarReflection([[name, rule]], { followLazy: false })]));
|
|
10069
10410
|
const ctx = {
|
|
10070
10411
|
vars: 0,
|
|
10071
10412
|
indent: 1,
|
|
@@ -10095,7 +10436,11 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10095
10436
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10096
10437
|
ns,
|
|
10097
10438
|
deferFirstSetRefs: true,
|
|
10098
|
-
...
|
|
10439
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10440
|
+
...grammarTrivia ? {
|
|
10441
|
+
activeTrivia: grammarTrivia,
|
|
10442
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10443
|
+
} : {},
|
|
10099
10444
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
10100
10445
|
};
|
|
10101
10446
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -10141,7 +10486,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10141
10486
|
scanExternal(resolved);
|
|
10142
10487
|
return;
|
|
10143
10488
|
}
|
|
10144
|
-
for (const child of
|
|
10489
|
+
for (const child of childrenOf3(def)) scanExternal(child);
|
|
10145
10490
|
};
|
|
10146
10491
|
for (const [, rule] of ruleMap) scanExternal(rule);
|
|
10147
10492
|
}
|
|
@@ -10227,7 +10572,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10227
10572
|
...r.stmts,
|
|
10228
10573
|
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
10229
10574
|
`}`
|
|
10230
|
-
].join("\n"), ctx.triviaKindLabels));
|
|
10575
|
+
].join("\n"), ctx.triviaKindLabels, ctx.rootTriviaClassified));
|
|
10231
10576
|
}
|
|
10232
10577
|
const firstSets = /* @__PURE__ */ new Map();
|
|
10233
10578
|
const firstSetRecipes = /* @__PURE__ */ new Map();
|
|
@@ -10263,6 +10608,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10263
10608
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10264
10609
|
hasDirectBuilders: ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
10265
10610
|
isRecognitionOnly: !hasSemanticReduction(ruleMap.map(([, rule]) => rule), externalRefs),
|
|
10611
|
+
nodeMeta,
|
|
10266
10612
|
mfFns: mfSrcs ? [] : ctx.mapFns,
|
|
10267
10613
|
buildFns: buildSrcs ? [] : ctx.buildFns
|
|
10268
10614
|
};
|
|
@@ -10283,7 +10629,7 @@ function hasExternalRuleRef(ruleMap) {
|
|
|
10283
10629
|
if (resolved === void 0) return p._ruleName !== void 0;
|
|
10284
10630
|
return visit(resolved);
|
|
10285
10631
|
}
|
|
10286
|
-
return
|
|
10632
|
+
return childrenOf3(def).some(visit);
|
|
10287
10633
|
};
|
|
10288
10634
|
return ruleMap.some(([, rule]) => visit(rule));
|
|
10289
10635
|
}
|
|
@@ -10305,7 +10651,7 @@ function hasSemanticReduction(roots, externalRefs) {
|
|
|
10305
10651
|
return true;
|
|
10306
10652
|
}
|
|
10307
10653
|
}
|
|
10308
|
-
return
|
|
10654
|
+
return childrenOf3(def).some(visit);
|
|
10309
10655
|
};
|
|
10310
10656
|
return roots.some(visit);
|
|
10311
10657
|
}
|
|
@@ -10378,7 +10724,7 @@ function withCtx(extra, combinator) {
|
|
|
10378
10724
|
}
|
|
10379
10725
|
|
|
10380
10726
|
// src/compiler/ir-serialize.ts
|
|
10381
|
-
function
|
|
10727
|
+
function childrenOf4(def) {
|
|
10382
10728
|
switch (def.tag) {
|
|
10383
10729
|
case "sequence":
|
|
10384
10730
|
case "choice":
|
|
@@ -10442,6 +10788,10 @@ function projectOpt(project) {
|
|
|
10442
10788
|
if (project === void 0) return void 0;
|
|
10443
10789
|
return `project: ${project}`;
|
|
10444
10790
|
}
|
|
10791
|
+
function tagsOpt(tags) {
|
|
10792
|
+
if (tags === void 0 || tags.length === 0) return void 0;
|
|
10793
|
+
return `tags: ${JSON.stringify(tags)}`;
|
|
10794
|
+
}
|
|
10445
10795
|
function matcherExpr(entry) {
|
|
10446
10796
|
switch (entry.kind) {
|
|
10447
10797
|
case "startsWith":
|
|
@@ -10571,6 +10921,7 @@ function evalRuleMapIR(ir) {
|
|
|
10571
10921
|
"transform",
|
|
10572
10922
|
"skip",
|
|
10573
10923
|
"trivia",
|
|
10924
|
+
"classifiedTrivia",
|
|
10574
10925
|
"label",
|
|
10575
10926
|
"field",
|
|
10576
10927
|
"expect",
|
|
@@ -10611,6 +10962,7 @@ function evalRuleMapIR(ir) {
|
|
|
10611
10962
|
transform,
|
|
10612
10963
|
skip,
|
|
10613
10964
|
trivia,
|
|
10965
|
+
classifiedTrivia,
|
|
10614
10966
|
label,
|
|
10615
10967
|
field,
|
|
10616
10968
|
expect,
|
|
@@ -10655,7 +11007,7 @@ var Serializer = class {
|
|
|
10655
11007
|
if (target) this.assertNoRuleRef(target, seen);
|
|
10656
11008
|
return;
|
|
10657
11009
|
}
|
|
10658
|
-
for (const child of
|
|
11010
|
+
for (const child of childrenOf4(c._def)) this.assertNoRuleRef(child, seen);
|
|
10659
11011
|
}
|
|
10660
11012
|
/** A `rules()` map wraps each rule value in a named `lazy` proxy; the real body is
|
|
10661
11013
|
* its target (compileLinkable unwraps the same way). A ref INSIDE a body stays a
|
|
@@ -10719,7 +11071,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10719
11071
|
this.counts.set(c, (this.counts.get(c) ?? 0) + 1);
|
|
10720
11072
|
if ((this.counts.get(c) ?? 0) > 1) return;
|
|
10721
11073
|
active.add(c);
|
|
10722
|
-
for (const child of
|
|
11074
|
+
for (const child of childrenOf4(def)) this.analyze(child, active);
|
|
10723
11075
|
active.delete(c);
|
|
10724
11076
|
}
|
|
10725
11077
|
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
@@ -10836,12 +11188,14 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10836
11188
|
case "node": {
|
|
10837
11189
|
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
10838
11190
|
const projectEntry = projectOpt(def.project);
|
|
11191
|
+
const tagEntry = tagsOpt(def.tags);
|
|
10839
11192
|
const optEntries = [
|
|
10840
11193
|
...def.unwrap ? ["unwrap: true"] : [],
|
|
10841
11194
|
...def.collapse ? ["collapse: true"] : [],
|
|
10842
11195
|
...projectEntry === void 0 ? [] : [projectEntry],
|
|
10843
11196
|
...def.captureTrivia ? ["captureTrivia: true"] : [],
|
|
10844
|
-
...def.trailingTrivia ? ["trailingTrivia: true"] : []
|
|
11197
|
+
...def.trailingTrivia ? ["trailingTrivia: true"] : [],
|
|
11198
|
+
...tagEntry === void 0 ? [] : [tagEntry]
|
|
10845
11199
|
];
|
|
10846
11200
|
const opts = optEntries.length > 0 ? `, { ${optEntries.join(", ")} }` : "";
|
|
10847
11201
|
if (def.type === void 0) {
|
|
@@ -10855,8 +11209,11 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10855
11209
|
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
10856
11210
|
}
|
|
10857
11211
|
case "grammar": {
|
|
10858
|
-
const
|
|
10859
|
-
|
|
11212
|
+
const classified = def.triviaParser?._meta.rootTriviaClassified === true;
|
|
11213
|
+
const spec = classified && def.triviaParser ? analyzeLabeledTrivia(def.triviaParser) : null;
|
|
11214
|
+
if (classified && !spec) throw new Unserializable("classified trivia without labeled arms");
|
|
11215
|
+
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";
|
|
11216
|
+
return `parser({ trivia: ${trivia2}${def.captureTrivia ? ", captureTrivia: true" : ""}${def.rootCapture ? `, rootCapture: ${JSON.stringify(def.rootCapture)}` : ""}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(def.parser)})`;
|
|
10860
11217
|
}
|
|
10861
11218
|
case "withCtx": {
|
|
10862
11219
|
if (def.extraSrc === void 0) throw new Unserializable("withCtx without extraSrc");
|
|
@@ -10879,15 +11236,16 @@ function normalizeCstCollapse(collapse) {
|
|
|
10879
11236
|
}
|
|
10880
11237
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10881
11238
|
}
|
|
10882
|
-
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10883
|
-
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
11239
|
+
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
11240
|
+
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] };
|
|
10884
11241
|
}
|
|
10885
|
-
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
11242
|
+
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
10886
11243
|
if (typeof typeOrOptions === "string") {
|
|
10887
11244
|
return buildCstNode(typeOrOptions, children2 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
10888
11245
|
}
|
|
10889
11246
|
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
10890
|
-
const
|
|
11247
|
+
const materializeTags = typeOrOptions?.tags === true;
|
|
11248
|
+
const host = (type, children3, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children3 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
10891
11249
|
host._parsemanCstOutput = true;
|
|
10892
11250
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
10893
11251
|
return host;
|
|
@@ -10908,7 +11266,7 @@ function pickPieces(pieces, names) {
|
|
|
10908
11266
|
};
|
|
10909
11267
|
for (const n of names) visit(n);
|
|
10910
11268
|
const filt = (m, pc) => new Map([...m].filter(([k]) => keep.has(k) && winner.get(k) === pc));
|
|
10911
|
-
return pieces.map((pc) => ({ ...pc, keys: pc.keys.filter((k) => keep.has(k) && winner.get(k) === pc), ruleFns: filt(pc.ruleFns, pc), wrappers: filt(pc.wrappers, pc), deps: filt(pc.deps, pc) })).filter((pc) => pc.keys.length > 0);
|
|
11269
|
+
return pieces.map((pc) => ({ ...pc, keys: pc.keys.filter((k) => keep.has(k) && winner.get(k) === pc), ruleFns: filt(pc.ruleFns, pc), wrappers: filt(pc.wrappers, pc), deps: filt(pc.deps, pc), nodeMeta: filt(pc.nodeMeta, pc) })).filter((pc) => pc.keys.length > 0);
|
|
10912
11270
|
}
|
|
10913
11271
|
function fusedBody(pieces) {
|
|
10914
11272
|
for (const p of pieces) {
|
|
@@ -10946,6 +11304,7 @@ function fusedBody(pieces) {
|
|
|
10946
11304
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
10947
11305
|
];
|
|
10948
11306
|
const wrapperEntries = [...winner].map(([k, p]) => `${JSON.stringify(k)}: ${p.wrappers.get(k)}`);
|
|
11307
|
+
const reflection = mergeGrammarReflections([...winner].map(([k, p]) => p.nodeMeta.get(k) ?? { nodes: [] }));
|
|
10949
11308
|
const { mode, elided } = hostModeOfPieces(pieces);
|
|
10950
11309
|
const rawBody = [
|
|
10951
11310
|
...lines,
|
|
@@ -10954,6 +11313,7 @@ function fusedBody(pieces) {
|
|
|
10954
11313
|
"}",
|
|
10955
11314
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_MODE.description)}), { value: ${JSON.stringify(mode)}, enumerable: false })`,
|
|
10956
11315
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_ELIDED.description)}), { value: ${JSON.stringify(elided)}, enumerable: false })`,
|
|
11316
|
+
`Object.defineProperty(_map, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`,
|
|
10957
11317
|
// …and on each rule FUNCTION, because `run(map.Rule, …)` is handed the rule, not the
|
|
10958
11318
|
// map, and would otherwise have nothing to check against. Done once at fuse time,
|
|
10959
11319
|
// before any rule has been called, so it costs nothing per parse.
|
|
@@ -11085,10 +11445,6 @@ function gate(predicate) {
|
|
|
11085
11445
|
};
|
|
11086
11446
|
}
|
|
11087
11447
|
|
|
11088
|
-
// src/cst/trivia-entries.ts
|
|
11089
|
-
var EMPTY_INDICES = Object.freeze([]);
|
|
11090
|
-
var EMPTY_GAPS = Object.freeze([]);
|
|
11091
|
-
|
|
11092
11448
|
// src/cst/offset-model.ts
|
|
11093
11449
|
var { isFinite } = Number;
|
|
11094
11450
|
|
|
@@ -11244,19 +11600,19 @@ function directBuilderUnsupportedBindings(src) {
|
|
|
11244
11600
|
// src/plugin/evaluator.ts
|
|
11245
11601
|
function stripTsFromSource(node2, code) {
|
|
11246
11602
|
const cuts = [];
|
|
11247
|
-
const
|
|
11603
|
+
const walk = (n) => {
|
|
11248
11604
|
if (!n || typeof n !== "object") return;
|
|
11249
11605
|
const rec = n;
|
|
11250
11606
|
if (typeof rec.type === "string" && rec.type.startsWith("TS") && typeof rec.start === "number" && typeof rec.end === "number") {
|
|
11251
11607
|
const ex = rec.expression;
|
|
11252
11608
|
if ((rec.type === "TSAsExpression" || rec.type === "TSSatisfiesExpression" || rec.type === "TSNonNullExpression" || rec.type === "TSInstantiationExpression") && ex && typeof ex.end === "number") {
|
|
11253
11609
|
cuts.push([ex.end, rec.end]);
|
|
11254
|
-
|
|
11610
|
+
walk(rec.expression);
|
|
11255
11611
|
return;
|
|
11256
11612
|
}
|
|
11257
11613
|
if (rec.type === "TSTypeAssertion" && ex && typeof ex.start === "number") {
|
|
11258
11614
|
cuts.push([rec.start, ex.start]);
|
|
11259
|
-
|
|
11615
|
+
walk(rec.expression);
|
|
11260
11616
|
return;
|
|
11261
11617
|
}
|
|
11262
11618
|
cuts.push([rec.start, rec.end]);
|
|
@@ -11266,11 +11622,11 @@ function stripTsFromSource(node2, code) {
|
|
|
11266
11622
|
if (key === "type" || key === "start" || key === "end") continue;
|
|
11267
11623
|
const v2 = rec[key];
|
|
11268
11624
|
if (Array.isArray(v2)) {
|
|
11269
|
-
for (const item of v2)
|
|
11270
|
-
} else if (v2 && typeof v2 === "object")
|
|
11625
|
+
for (const item of v2) walk(item);
|
|
11626
|
+
} else if (v2 && typeof v2 === "object") walk(v2);
|
|
11271
11627
|
}
|
|
11272
11628
|
};
|
|
11273
|
-
|
|
11629
|
+
walk(node2);
|
|
11274
11630
|
const start = node2.start;
|
|
11275
11631
|
const end = node2.end;
|
|
11276
11632
|
if (cuts.length === 0) return code.slice(start, end);
|
|
@@ -11340,6 +11696,9 @@ var SUPPORTED = {
|
|
|
11340
11696
|
optional: (...a) => optional(a[0]),
|
|
11341
11697
|
skip: (...a) => skip(a[0], a[1]),
|
|
11342
11698
|
trivia: (...a) => trivia(a[0]),
|
|
11699
|
+
classifiedTrivia: (...a) => classifiedTrivia(
|
|
11700
|
+
a[0]
|
|
11701
|
+
),
|
|
11343
11702
|
label: (...a) => label(a[0], a[1]),
|
|
11344
11703
|
field: (...a) => field(a[0], a[1]),
|
|
11345
11704
|
noTrivia: (...a) => noTrivia(a[0]),
|
|
@@ -11449,10 +11808,38 @@ function scopeGet(scope, name, mfs) {
|
|
|
11449
11808
|
if (isCombinator(entry)) return entry;
|
|
11450
11809
|
return null;
|
|
11451
11810
|
}
|
|
11811
|
+
function unwrapStaticExpr(expr) {
|
|
11812
|
+
let cur = expr;
|
|
11813
|
+
while (cur.type === "TSAsExpression" || cur.type === "TSSatisfiesExpression" || cur.type === "TSNonNullExpression" || cur.type === "TSTypeAssertion" || cur.type === "TSInstantiationExpression" || cur.type === "ParenthesizedExpression") {
|
|
11814
|
+
if (!cur.expression) break;
|
|
11815
|
+
cur = cur.expression;
|
|
11816
|
+
}
|
|
11817
|
+
return cur;
|
|
11818
|
+
}
|
|
11452
11819
|
function staticLiteralValue(expr) {
|
|
11453
|
-
const val = expr;
|
|
11820
|
+
const val = unwrapStaticExpr(expr);
|
|
11454
11821
|
return val.type === "Literal" || val.type === "BooleanLiteral" || val.type === "NumericLiteral" ? val.value : void 0;
|
|
11455
11822
|
}
|
|
11823
|
+
function staticStringArray(expr, scope) {
|
|
11824
|
+
const id = unwrapStaticExpr(expr);
|
|
11825
|
+
if (id.type === "Identifier" && scope !== void 0 && id.name !== void 0) {
|
|
11826
|
+
const scoped = scope.get(id.name);
|
|
11827
|
+
const value = isStaticValueEntry(scoped) ? scoped.value : scoped;
|
|
11828
|
+
return Array.isArray(value) && value.every((v2) => typeof v2 === "string") ? value : void 0;
|
|
11829
|
+
}
|
|
11830
|
+
const arr = id;
|
|
11831
|
+
if (arr.type !== "ArrayExpression" || !Array.isArray(arr.elements)) return void 0;
|
|
11832
|
+
const out = [];
|
|
11833
|
+
for (const el of arr.elements) {
|
|
11834
|
+
if (!el || el.type === "SpreadElement") return void 0;
|
|
11835
|
+
const value = staticLiteralValue(el);
|
|
11836
|
+
if (typeof value !== "string") return void 0;
|
|
11837
|
+
out.push(value);
|
|
11838
|
+
}
|
|
11839
|
+
return out;
|
|
11840
|
+
}
|
|
11841
|
+
var STATIC_NODE_OPTIONS_FAILED = /* @__PURE__ */ Symbol("parseman.staticNodeOptions.failed");
|
|
11842
|
+
var STATIC_NODE_OPTIONS_NOT_OPTIONS = /* @__PURE__ */ Symbol("parseman.staticNodeOptions.notOptions");
|
|
11456
11843
|
function staticNodeProject(expr) {
|
|
11457
11844
|
const literalValue = staticLiteralValue(expr);
|
|
11458
11845
|
if (typeof literalValue === "number" && Number.isInteger(literalValue) && literalValue >= 0) {
|
|
@@ -11461,23 +11848,60 @@ function staticNodeProject(expr) {
|
|
|
11461
11848
|
if (typeof literalValue === "number" || literalValue !== void 0) return { ok: false };
|
|
11462
11849
|
return { ok: false };
|
|
11463
11850
|
}
|
|
11464
|
-
function
|
|
11465
|
-
|
|
11851
|
+
function scopedStaticValue(expr, scope) {
|
|
11852
|
+
const unwrapped = unwrapStaticExpr(expr);
|
|
11853
|
+
if (unwrapped.type !== "Identifier" || unwrapped.name === "undefined") return { found: false };
|
|
11854
|
+
if (!scope.has(unwrapped.name)) return { found: false };
|
|
11855
|
+
const scoped = scope.get(unwrapped.name);
|
|
11856
|
+
const value = isStaticValueEntry(scoped) ? scoped.value : scoped;
|
|
11857
|
+
return { found: true, value };
|
|
11858
|
+
}
|
|
11859
|
+
function staticNodeOptionsFromValue(value) {
|
|
11860
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || isCombinator(value)) return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11861
|
+
const opts = {};
|
|
11862
|
+
const rec = value;
|
|
11863
|
+
for (const name of Object.keys(rec)) {
|
|
11864
|
+
const v2 = rec[name];
|
|
11865
|
+
if (name === "unwrap" || name === "collapse" || name === "captureTrivia" || name === "trailingTrivia") {
|
|
11866
|
+
if (v2 === true) opts[name] = true;
|
|
11867
|
+
else if (v2 !== false && v2 !== void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11868
|
+
} else if (name === "project") {
|
|
11869
|
+
if (typeof v2 !== "number" || !Number.isInteger(v2) || v2 < 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11870
|
+
opts.project = v2;
|
|
11871
|
+
} else if (name === "tags") {
|
|
11872
|
+
if (!Array.isArray(v2) || !v2.every((item) => typeof item === "string")) return STATIC_NODE_OPTIONS_FAILED;
|
|
11873
|
+
opts.tags = v2;
|
|
11874
|
+
}
|
|
11875
|
+
}
|
|
11876
|
+
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia || opts.tags !== void 0 ? opts : void 0;
|
|
11877
|
+
}
|
|
11878
|
+
function staticNodeOptions(expr, scope) {
|
|
11879
|
+
const unwrapped = unwrapStaticExpr(expr);
|
|
11880
|
+
const scoped = scopedStaticValue(unwrapped, scope);
|
|
11881
|
+
if (scoped.found) return staticNodeOptionsFromValue(scoped.value);
|
|
11882
|
+
if (unwrapped.type !== "ObjectExpression") return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11466
11883
|
const opts = {};
|
|
11467
|
-
for (const prop of
|
|
11884
|
+
for (const prop of unwrapped.properties) {
|
|
11885
|
+
if (prop.type !== "Property") return STATIC_NODE_OPTIONS_FAILED;
|
|
11468
11886
|
const p = prop;
|
|
11469
|
-
if (p.computed)
|
|
11887
|
+
if (p.computed) return STATIC_NODE_OPTIONS_FAILED;
|
|
11470
11888
|
const key = p.key;
|
|
11471
11889
|
const name = key.type === "Identifier" ? key.name : key.type === "Literal" ? String(key.value) : void 0;
|
|
11472
11890
|
if (name === "unwrap" || name === "collapse" || name === "captureTrivia" || name === "trailingTrivia") {
|
|
11473
|
-
|
|
11891
|
+
const value = staticLiteralValue(p.value);
|
|
11892
|
+
if (value === true) opts[name] = true;
|
|
11893
|
+
else if (value !== false && value !== void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11474
11894
|
} else if (name === "project") {
|
|
11475
11895
|
const project = staticNodeProject(p.value);
|
|
11476
|
-
if (project?.ok === false) return
|
|
11896
|
+
if (project?.ok === false) return STATIC_NODE_OPTIONS_FAILED;
|
|
11477
11897
|
if (project !== void 0) opts.project = project.value;
|
|
11898
|
+
} else if (name === "tags") {
|
|
11899
|
+
const tags = staticStringArray(p.value, scope);
|
|
11900
|
+
if (tags === void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11901
|
+
opts.tags = tags;
|
|
11478
11902
|
}
|
|
11479
11903
|
}
|
|
11480
|
-
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia ? opts : void 0;
|
|
11904
|
+
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia || opts.tags !== void 0 ? opts : void 0;
|
|
11481
11905
|
}
|
|
11482
11906
|
function exprToCombi(node2, scope, code, mfs) {
|
|
11483
11907
|
if (node2.type === "Identifier") return scopeGet(scope, node2.name, mfs);
|
|
@@ -11552,10 +11976,23 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
11552
11976
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
11553
11977
|
if (!isCombinator(inner)) return null;
|
|
11554
11978
|
const be = buildArg;
|
|
11555
|
-
const
|
|
11979
|
+
const buildExpr = be === void 0 || be.type === "SpreadElement" ? void 0 : unwrapStaticExpr(be);
|
|
11980
|
+
const buildArgOptions = be !== void 0 && be.type !== "SpreadElement" ? staticNodeOptions(buildArg, scope) : STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11981
|
+
if (buildArgOptions === STATIC_NODE_OPTIONS_FAILED) return null;
|
|
11982
|
+
const buildArgIsOptions = buildArgOptions !== STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11983
|
+
const scopedBuild = buildExpr === void 0 ? { found: false } : scopedStaticValue(buildExpr, scope);
|
|
11984
|
+
const absentBuild = buildExpr?.type === "Identifier" && buildExpr.name === "undefined" || buildExpr !== void 0 && staticLiteralValue(buildExpr) === null || scopedBuild.found && (scopedBuild.value === void 0 || scopedBuild.value === null);
|
|
11985
|
+
const hasBuild = be !== void 0 && be.type !== "SpreadElement" && !buildArgIsOptions && !absentBuild;
|
|
11556
11986
|
const buildSrc = hasBuild ? stripTsFromSource(be, code) : void 0;
|
|
11557
|
-
|
|
11558
|
-
|
|
11987
|
+
let opts;
|
|
11988
|
+
if (buildArgIsOptions) {
|
|
11989
|
+
opts = buildArgOptions;
|
|
11990
|
+
} else if (optsArg !== void 0) {
|
|
11991
|
+
if (optsArg.type === "SpreadElement") return null;
|
|
11992
|
+
const optsResult = staticNodeOptions(optsArg, scope);
|
|
11993
|
+
if (optsResult === STATIC_NODE_OPTIONS_FAILED || optsResult === STATIC_NODE_OPTIONS_NOT_OPTIONS) return null;
|
|
11994
|
+
opts = optsResult;
|
|
11995
|
+
}
|
|
11559
11996
|
try {
|
|
11560
11997
|
const combi = explicitType !== void 0 ? node(explicitType, inner, hasBuild ? () => null : void 0, opts) : node(inner, hasBuild ? () => null : void 0, opts);
|
|
11561
11998
|
if (combi._def.tag === "node" && buildSrc !== void 0) {
|
|
@@ -11778,6 +12215,10 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
11778
12215
|
}
|
|
11779
12216
|
}
|
|
11780
12217
|
function anyValue(node2, scope, code, mfs) {
|
|
12218
|
+
if (node2.type === "TSAsExpression" || node2.type === "TSSatisfiesExpression" || node2.type === "TSNonNullExpression" || node2.type === "TSTypeAssertion" || node2.type === "TSInstantiationExpression" || node2.type === "ParenthesizedExpression") {
|
|
12219
|
+
const inner = node2.expression;
|
|
12220
|
+
return inner ? anyValue(inner, scope, code, mfs) : null;
|
|
12221
|
+
}
|
|
11781
12222
|
if (node2.type === "Literal") {
|
|
11782
12223
|
if ("regex" in node2 && node2.regex !== null && node2.regex !== void 0) {
|
|
11783
12224
|
return new RegExp(node2.regex.pattern, node2.regex.flags);
|
|
@@ -11901,6 +12342,9 @@ function collectRuleKeys(retObj) {
|
|
|
11901
12342
|
}
|
|
11902
12343
|
return out;
|
|
11903
12344
|
}
|
|
12345
|
+
function evaluateStaticValue(node2, scope, code) {
|
|
12346
|
+
return anyValue(node2, scope, code, []);
|
|
12347
|
+
}
|
|
11904
12348
|
function flattenRuleEntries(retObj, scope, code) {
|
|
11905
12349
|
const out = [];
|
|
11906
12350
|
for (const prop of retObj.properties) {
|
|
@@ -12066,6 +12510,18 @@ function referencesAny(node2, names, scope) {
|
|
|
12066
12510
|
// src/plugin/index.ts
|
|
12067
12511
|
var import_node_crypto = require("node:crypto");
|
|
12068
12512
|
var PARSEMAN_MODULE = "parseman";
|
|
12513
|
+
function unwrapStaticExpression(expr) {
|
|
12514
|
+
let cur = expr;
|
|
12515
|
+
while (cur.type === "TSAsExpression" || cur.type === "TSSatisfiesExpression" || cur.type === "TSNonNullExpression" || cur.type === "TSTypeAssertion" || cur.type === "TSInstantiationExpression" || cur.type === "ParenthesizedExpression") {
|
|
12516
|
+
if (!cur.expression) break;
|
|
12517
|
+
cur = cur.expression;
|
|
12518
|
+
}
|
|
12519
|
+
return cur;
|
|
12520
|
+
}
|
|
12521
|
+
function isStaticNullishExpression(expr) {
|
|
12522
|
+
const unwrapped = unwrapStaticExpression(expr);
|
|
12523
|
+
return unwrapped.type === "Identifier" && unwrapped.name === "undefined" || unwrapped.type === "Literal" && unwrapped.value === null;
|
|
12524
|
+
}
|
|
12069
12525
|
var _compiledResolver = null;
|
|
12070
12526
|
function getCompiledResolver() {
|
|
12071
12527
|
return _compiledResolver ??= new import_oxc_resolver.ResolverFactory({
|
|
@@ -12548,6 +13004,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12548
13004
|
ruleMap: evaluated.ruleMap,
|
|
12549
13005
|
hostMode: compiled?.hostMode ?? "ast",
|
|
12550
13006
|
hostBranchElided: compiled?.hostBranchElided ?? false,
|
|
13007
|
+
reflection: compiled?.reflection ?? { nodes: [] },
|
|
12551
13008
|
...compiled?.coverageDefinitions ? { coverageDefinitions: compiled.coverageDefinitions } : {},
|
|
12552
13009
|
...evaluated.trivia ? { trivia: evaluated.trivia } : {},
|
|
12553
13010
|
...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {},
|
|
@@ -12568,7 +13025,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12568
13025
|
const mapLit = (m, stripVals = false) => `new Map([${[...m].map(
|
|
12569
13026
|
([k, v2]) => `[${JSON.stringify(k)}, ${JSON.stringify(stripVals && typeof v2 === "string" ? stripIndent(v2) : v2)}]`
|
|
12570
13027
|
).join(", ")}])`;
|
|
12571
|
-
return `{ v: ${JSON.stringify(p.v)}, ns: ${JSON.stringify(p.ns)}, keys: ${JSON.stringify(p.keys)}, prelude: ${JSON.stringify(p.prelude.map(stripIndent))}, ruleFns: ${mapLit(p.ruleFns, true)}, wrappers: ${mapLit(p.wrappers, true)}, firstSets: ${mapLit(p.firstSets)}, nullable: ${p.nullable ? mapLit(p.nullable) : "new Map()"}, firstSetRecipes: ${p.firstSetRecipes ? mapLit(p.firstSetRecipes) : "new Map()"}, deps: ${mapLit(p.deps)}, hostMode: ${JSON.stringify(p.hostMode ?? "ast")}, hostBranchElided: ${p.hostBranchElided === true}, needsEmptyTl: ${p.needsEmptyTl}, needsHostReads: ${p.needsHostReads}, hasDirectBuilders: ${p.hasDirectBuilders === true}, isRecognitionOnly: ${p.isRecognitionOnly === true}, mfFns: [], buildFns: [] }`;
|
|
13028
|
+
return `{ v: ${JSON.stringify(p.v)}, ns: ${JSON.stringify(p.ns)}, keys: ${JSON.stringify(p.keys)}, prelude: ${JSON.stringify(p.prelude.map(stripIndent))}, ruleFns: ${mapLit(p.ruleFns, true)}, wrappers: ${mapLit(p.wrappers, true)}, firstSets: ${mapLit(p.firstSets)}, nullable: ${p.nullable ? mapLit(p.nullable) : "new Map()"}, firstSetRecipes: ${p.firstSetRecipes ? mapLit(p.firstSetRecipes) : "new Map()"}, deps: ${mapLit(p.deps)}, nodeMeta: ${mapLit(p.nodeMeta)}, hostMode: ${JSON.stringify(p.hostMode ?? "ast")}, hostBranchElided: ${p.hostBranchElided === true}, needsEmptyTl: ${p.needsEmptyTl}, needsHostReads: ${p.needsHostReads}, hasDirectBuilders: ${p.hasDirectBuilders === true}, isRecognitionOnly: ${p.isRecognitionOnly === true}, mfFns: [], buildFns: [] }`;
|
|
12572
13029
|
};
|
|
12573
13030
|
const isSpread = (it) => "__spreadLocal" in it;
|
|
12574
13031
|
const isIR = (it) => "ir" in it && !("ruleFns" in it);
|
|
@@ -12577,6 +13034,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12577
13034
|
const withCarriedPieces = (grammarExpr, list) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.composedPieces'), { value: ${serializeList(list)}, enumerable: false })`;
|
|
12578
13035
|
const withLeafMarker = (grammarExpr) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.leafComposed'), { value: true, enumerable: false })`;
|
|
12579
13036
|
const withHostMode = (grammarExpr, mode, elided) => `/* @__PURE__ */ (m => { for (const k of Object.keys(m)) { Object.defineProperty(m[k], Symbol.for('parseman.fusedHostMode'), { value: ${JSON.stringify(mode)}, enumerable: false }); Object.defineProperty(m[k], Symbol.for('parseman.fusedHostElided'), { value: ${JSON.stringify(elided)}, enumerable: false }) } Object.defineProperty(m, Symbol.for('parseman.fusedHostMode'), { value: ${JSON.stringify(mode)}, enumerable: false }); Object.defineProperty(m, Symbol.for('parseman.fusedHostElided'), { value: ${JSON.stringify(elided)}, enumerable: false }); return m })(${grammarExpr})`;
|
|
13037
|
+
const withGrammarReflection = (grammarExpr, reflection) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`;
|
|
12580
13038
|
const withCoverageDefinitions = (grammarExpr, definitions) => !grammarCoverage ? grammarExpr : `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.grammarCoverageDefinitions'), { value: Object.freeze(${JSON.stringify(definitions)}.map(Object.freeze)), enumerable: false })`;
|
|
12581
13039
|
const emittedCoverageDefinitions = (source) => {
|
|
12582
13040
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -12972,7 +13430,14 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12972
13430
|
const kind = vd.kind ?? "const";
|
|
12973
13431
|
if (d.id.type === "Identifier") {
|
|
12974
13432
|
const varName = d.id.name;
|
|
12975
|
-
if (!referencesAny(init, allNames, scope))
|
|
13433
|
+
if (!referencesAny(init, allNames, scope)) {
|
|
13434
|
+
const staticValue = evaluateStaticValue(init, scope, code);
|
|
13435
|
+
if (staticValue !== null && staticValue !== void 0 || isStaticNullishExpression(init)) {
|
|
13436
|
+
;
|
|
13437
|
+
scope.set(varName, staticValue);
|
|
13438
|
+
}
|
|
13439
|
+
continue;
|
|
13440
|
+
}
|
|
12976
13441
|
if (refNames.has(varName)) {
|
|
12977
13442
|
const refEntry = scope.get(varName);
|
|
12978
13443
|
const refCombi = refEntry?.combi ?? null;
|
|
@@ -13012,6 +13477,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
13012
13477
|
);
|
|
13013
13478
|
if (compiledRules.replacement !== null) {
|
|
13014
13479
|
replacement = withHostMode(replacement, compiledRules.hostMode, compiledRules.hostBranchElided);
|
|
13480
|
+
replacement = withGrammarReflection(replacement, compiledRules.reflection);
|
|
13015
13481
|
}
|
|
13016
13482
|
if (exportPrefix && pieces && !pieces.mfFns.length && !pieces.buildFns.length) {
|
|
13017
13483
|
const ir = serializeRuleMap([...compiledRules.ruleMap], compiledRules.scanSkip);
|
|
@@ -13039,7 +13505,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
13039
13505
|
if (isComposeLeafCall(init)) {
|
|
13040
13506
|
const fused = compileComposeLeafCall(init);
|
|
13041
13507
|
if (!fused) {
|
|
13042
|
-
|
|
13508
|
+
const reasons = warnings.slice(-4);
|
|
13509
|
+
throw new Error(
|
|
13510
|
+
`${id}:${lineOf(init.start)} \u2014 composeLeaf() must macro-fuse; runtime composition is forbidden` + (reasons.length ? `
|
|
13511
|
+
causes:
|
|
13512
|
+
- ${reasons.join("\n - ")}` : "")
|
|
13513
|
+
);
|
|
13043
13514
|
}
|
|
13044
13515
|
replacements.push({ start: init.start, end: init.end, replacement: fused.replacement });
|
|
13045
13516
|
markUsedImportedFactories(fused.importedFactories);
|
|
@@ -13068,6 +13539,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
13068
13539
|
scope.set(varName, combiArray);
|
|
13069
13540
|
continue;
|
|
13070
13541
|
}
|
|
13542
|
+
const staticValue = evaluateStaticValue(init, scope, code);
|
|
13543
|
+
if (staticValue !== null && staticValue !== void 0 || isStaticNullishExpression(init)) {
|
|
13544
|
+
;
|
|
13545
|
+
scope.set(varName, staticValue);
|
|
13546
|
+
continue;
|
|
13547
|
+
}
|
|
13071
13548
|
if (factoryDecls.has(varName)) continue;
|
|
13072
13549
|
warn(init.start, `"${varName}" references a parseman macro import but isn't a statically-evaluable combinator`);
|
|
13073
13550
|
continue;
|
|
@@ -13143,7 +13620,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
13143
13620
|
const replacementRanges = runtimeComposeFallback ? [] : replacements.map(({ start, end }) => ({ start, end }));
|
|
13144
13621
|
const isInsideReplacement = (start, end) => replacementRanges.some((r) => start >= r.start && end <= r.end);
|
|
13145
13622
|
const importedBindingStillReferenced = (local) => {
|
|
13146
|
-
const
|
|
13623
|
+
const walk = (node2, parent, parentKey) => {
|
|
13147
13624
|
if (!node2 || typeof node2 !== "object") return false;
|
|
13148
13625
|
const rec = node2;
|
|
13149
13626
|
if (rec.type === "ImportDeclaration") return false;
|
|
@@ -13158,14 +13635,14 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
13158
13635
|
if (key === "type" || key === "start" || key === "end") continue;
|
|
13159
13636
|
const value = rec[key];
|
|
13160
13637
|
if (Array.isArray(value)) {
|
|
13161
|
-
if (value.some((child) =>
|
|
13162
|
-
} else if (
|
|
13638
|
+
if (value.some((child) => walk(child, rec, key))) return true;
|
|
13639
|
+
} else if (walk(value, rec, key)) {
|
|
13163
13640
|
return true;
|
|
13164
13641
|
}
|
|
13165
13642
|
}
|
|
13166
13643
|
return false;
|
|
13167
13644
|
};
|
|
13168
|
-
return body.some((stmt) =>
|
|
13645
|
+
return body.some((stmt) => walk(stmt));
|
|
13169
13646
|
};
|
|
13170
13647
|
for (const imp of ordinaryImports) {
|
|
13171
13648
|
if (!runtimeComposeFallback && imp.specifiers.length > 0 && imp.specifiers.every(
|