parseman 0.43.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/combinators/attempt.d.ts.map +1 -1
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts +7 -0
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/map.d.ts +11 -0
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/token.d.ts +3 -2
- package/dist/combinators/token.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +1 -0
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/scannable-run.d.ts +1 -1
- package/dist/compiler/scannable-run.d.ts.map +1 -1
- package/dist/compiler/trivia-fast-path.d.ts +4 -3
- package/dist/compiler/trivia-fast-path.d.ts.map +1 -1
- package/dist/cst/trivia-entries.d.ts +15 -9
- package/dist/cst/trivia-entries.d.ts.map +1 -1
- package/dist/cst/trivia-kinds.d.ts +15 -11
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/functional/run.d.ts +22 -16
- package/dist/functional/run.d.ts.map +1 -1
- package/dist/index.cjs +1416 -1115
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1416 -1115
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs +161 -102
- package/dist/language-service/index.cjs.map +3 -3
- package/dist/language-service/index.js +161 -102
- package/dist/language-service/index.js.map +3 -3
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +1217 -985
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1217 -985
- package/dist/plugin/index.js.map +4 -4
- package/dist/run/index.cjs +152 -102
- package/dist/run/index.cjs.map +3 -3
- package/dist/run/index.d.ts +1 -1
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +152 -102
- package/dist/run/index.js.map +3 -3
- package/dist/spec/index.cjs +1414 -1286
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +1414 -1286
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +25 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -44,6 +44,7 @@ __export(index_exports, {
|
|
|
44
44
|
buildTriviaIndex: () => buildTriviaIndex,
|
|
45
45
|
charClassMembers: () => charClassMembers,
|
|
46
46
|
choice: () => choice,
|
|
47
|
+
classifiedTrivia: () => classifiedTrivia,
|
|
47
48
|
collectLeafSlots: () => collectLeafSlots,
|
|
48
49
|
commentsIn: () => commentsIn,
|
|
49
50
|
compile: () => compile,
|
|
@@ -1182,1035 +1183,1099 @@ function keywords(words, opts = {}) {
|
|
|
1182
1183
|
};
|
|
1183
1184
|
}
|
|
1184
1185
|
|
|
1185
|
-
// src/
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
_cstChildren: ctx._cstChildren,
|
|
1192
|
-
_cstRawChildren: ctx._cstRawChildren,
|
|
1193
|
-
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1194
|
-
_triviaLog: ctx._triviaLog,
|
|
1195
|
-
_fields: ctx._fields,
|
|
1196
|
-
_cstBuf: ctx._cstBuf,
|
|
1197
|
-
_tolerant: ctx._tolerant,
|
|
1198
|
-
_sync: ctx._sync
|
|
1199
|
-
};
|
|
1200
|
-
ctx._probe = void 0;
|
|
1201
|
-
ctx._errors = void 0;
|
|
1202
|
-
ctx._cstLeaves = void 0;
|
|
1203
|
-
ctx._cstChildren = void 0;
|
|
1204
|
-
ctx._cstRawChildren = void 0;
|
|
1205
|
-
ctx._cstTriviaLog = void 0;
|
|
1206
|
-
ctx._triviaLog = void 0;
|
|
1207
|
-
ctx._fields = void 0;
|
|
1208
|
-
ctx._cstBuf = void 0;
|
|
1209
|
-
ctx._tolerant = void 0;
|
|
1210
|
-
ctx._sync = void 0;
|
|
1211
|
-
try {
|
|
1212
|
-
return sentinel.parse(input, pos, ctx).ok;
|
|
1213
|
-
} finally {
|
|
1214
|
-
ctx._probe = s._probe;
|
|
1215
|
-
ctx._errors = s._errors;
|
|
1216
|
-
ctx._cstLeaves = s._cstLeaves;
|
|
1217
|
-
ctx._cstChildren = s._cstChildren;
|
|
1218
|
-
ctx._cstRawChildren = s._cstRawChildren;
|
|
1219
|
-
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1220
|
-
ctx._triviaLog = s._triviaLog;
|
|
1221
|
-
ctx._fields = s._fields;
|
|
1222
|
-
ctx._cstBuf = s._cstBuf;
|
|
1223
|
-
ctx._tolerant = s._tolerant;
|
|
1224
|
-
ctx._sync = s._sync;
|
|
1225
|
-
}
|
|
1186
|
+
// src/cst/trivia-kinds.ts
|
|
1187
|
+
var labeledTriviaSpecs = /* @__PURE__ */ new WeakMap();
|
|
1188
|
+
function unwrapTrivia(p) {
|
|
1189
|
+
let cur = p;
|
|
1190
|
+
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1191
|
+
return cur;
|
|
1226
1192
|
}
|
|
1227
|
-
function
|
|
1228
|
-
if (
|
|
1229
|
-
return
|
|
1230
|
-
_tag: "orSentinel",
|
|
1231
|
-
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1232
|
-
_def: { tag: "unknown" },
|
|
1233
|
-
parse(input, pos, ctx) {
|
|
1234
|
-
const ra = a.parse(input, pos, ctx);
|
|
1235
|
-
if (ra.ok) return ra;
|
|
1236
|
-
return b.parse(input, pos, ctx);
|
|
1237
|
-
}
|
|
1238
|
-
};
|
|
1193
|
+
function peelLabel(p) {
|
|
1194
|
+
if (p._def.tag === "label") return { label: p._def.label, parser: p._def.parser };
|
|
1195
|
+
return null;
|
|
1239
1196
|
}
|
|
1240
|
-
function
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1197
|
+
function analyzeLabeledTrivia(trivia2) {
|
|
1198
|
+
const cached = labeledTriviaSpecs.get(trivia2);
|
|
1199
|
+
if (cached !== void 0) return cached;
|
|
1200
|
+
let core = unwrapTrivia(trivia2);
|
|
1201
|
+
let minRepeats = 1;
|
|
1202
|
+
if (core._def.tag === "oneOrMore") {
|
|
1203
|
+
core = core._def.parser;
|
|
1204
|
+
minRepeats = 1;
|
|
1205
|
+
} else if (core._def.tag === "many") {
|
|
1206
|
+
core = core._def.parser;
|
|
1207
|
+
minRepeats = 0;
|
|
1208
|
+
}
|
|
1209
|
+
const arms = [];
|
|
1210
|
+
if (core._def.tag === "choice") {
|
|
1211
|
+
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1212
|
+
const peeled = peelLabel(core._def.parsers[i]);
|
|
1213
|
+
if (!peeled) {
|
|
1214
|
+
labeledTriviaSpecs.set(trivia2, null);
|
|
1215
|
+
return null;
|
|
1253
1216
|
}
|
|
1254
|
-
|
|
1217
|
+
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1218
|
+
}
|
|
1219
|
+
} else {
|
|
1220
|
+
const peeled = peelLabel(core);
|
|
1221
|
+
if (!peeled) {
|
|
1222
|
+
labeledTriviaSpecs.set(trivia2, null);
|
|
1223
|
+
return null;
|
|
1255
1224
|
}
|
|
1225
|
+
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1226
|
+
}
|
|
1227
|
+
const spec = {
|
|
1228
|
+
labels: arms.map((a) => a.label),
|
|
1229
|
+
arms,
|
|
1230
|
+
minRepeats
|
|
1256
1231
|
};
|
|
1232
|
+
labeledTriviaSpecs.set(trivia2, spec);
|
|
1233
|
+
return spec;
|
|
1257
1234
|
}
|
|
1258
|
-
function
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1264
|
-
ctx._errors?.push(error);
|
|
1265
|
-
return { error, end: scanPos };
|
|
1266
|
-
}
|
|
1267
|
-
function matchesAt(sentinel, input, pos, ctx) {
|
|
1268
|
-
return probeAt(sentinel, input, pos, ctx);
|
|
1235
|
+
function matchArmAt(input, pos, arm, state) {
|
|
1236
|
+
if (!startsFirstSet(arm, input, pos)) return null;
|
|
1237
|
+
const r = arm.parse(input, pos, { trackLines: false, state });
|
|
1238
|
+
if (!r.ok || r.span.end <= pos) return null;
|
|
1239
|
+
return { end: r.span.end };
|
|
1269
1240
|
}
|
|
1270
|
-
function
|
|
1271
|
-
|
|
1241
|
+
function scanLabeledTriviaChunks(input, cur, spec, state) {
|
|
1242
|
+
const chunks = [];
|
|
1243
|
+
let pos = cur;
|
|
1244
|
+
while (pos < input.length) {
|
|
1245
|
+
let matched = null;
|
|
1246
|
+
for (const arm of spec.arms) {
|
|
1247
|
+
const m = matchArmAt(input, pos, arm.parser, state);
|
|
1248
|
+
if (m) {
|
|
1249
|
+
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1250
|
+
break;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
if (!matched) break;
|
|
1254
|
+
chunks.push({ start: pos, end: matched.end, kindIndex: matched.kindIndex });
|
|
1255
|
+
pos = matched.end;
|
|
1256
|
+
}
|
|
1257
|
+
if (chunks.length < spec.minRepeats) {
|
|
1258
|
+
return { end: cur, chunks: [] };
|
|
1259
|
+
}
|
|
1260
|
+
return { end: pos, chunks };
|
|
1272
1261
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1262
|
+
function scanLabeledTriviaEnd(input, cur, spec, state) {
|
|
1263
|
+
let pos = cur;
|
|
1264
|
+
let count = 0;
|
|
1265
|
+
while (pos < input.length) {
|
|
1266
|
+
let matched = null;
|
|
1267
|
+
for (const arm of spec.arms) {
|
|
1268
|
+
matched = matchArmAt(input, pos, arm.parser, state);
|
|
1269
|
+
if (matched) break;
|
|
1270
|
+
}
|
|
1271
|
+
if (!matched) break;
|
|
1272
|
+
pos = matched.end;
|
|
1273
|
+
count++;
|
|
1274
|
+
}
|
|
1275
|
+
return count < spec.minRepeats ? cur : pos;
|
|
1278
1276
|
}
|
|
1279
|
-
function
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
return [def.label];
|
|
1291
|
-
case "choice":
|
|
1292
|
-
return def.parsers.flatMap(deriveExpected2);
|
|
1293
|
-
case "dispatch":
|
|
1294
|
-
return deriveExpected2(def.selector);
|
|
1295
|
-
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
1296
|
-
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
1297
|
-
// able to fail first — deriving from term 0 alone named a token the parse
|
|
1298
|
-
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
1299
|
-
// nothing (its own expectation is about what must NOT be here), but it is
|
|
1300
|
-
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
1301
|
-
case "sequence": {
|
|
1302
|
-
const out = [];
|
|
1303
|
-
for (const term of def.parsers) {
|
|
1304
|
-
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
1305
|
-
if (!matchesEmpty(term)) break;
|
|
1277
|
+
function visitLabeledTrivia(input, cur, spec, state, visit) {
|
|
1278
|
+
if (spec.minRepeats > 1) return void 0;
|
|
1279
|
+
let pos = cur;
|
|
1280
|
+
let count = 0;
|
|
1281
|
+
while (pos < input.length) {
|
|
1282
|
+
let matched = null;
|
|
1283
|
+
for (const arm of spec.arms) {
|
|
1284
|
+
const match = matchArmAt(input, pos, arm.parser, state);
|
|
1285
|
+
if (match) {
|
|
1286
|
+
matched = { end: match.end, kindIndex: arm.kindIndex };
|
|
1287
|
+
break;
|
|
1306
1288
|
}
|
|
1307
|
-
return out;
|
|
1308
1289
|
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
case "not":
|
|
1332
|
-
case "peek":
|
|
1333
|
-
return deriveExpected2(def.parser);
|
|
1334
|
-
case "routed":
|
|
1335
|
-
return ["routed()"];
|
|
1336
|
-
case "lazy": {
|
|
1337
|
-
const name = c._ruleName;
|
|
1338
|
-
if (seen.has(c)) return name ? [name] : [];
|
|
1339
|
-
seen.add(c);
|
|
1340
|
-
try {
|
|
1341
|
-
return deriveExpected2(def.thunk());
|
|
1342
|
-
} catch {
|
|
1343
|
-
return name ? [name] : [];
|
|
1344
|
-
} finally {
|
|
1345
|
-
seen.delete(c);
|
|
1290
|
+
if (!matched) break;
|
|
1291
|
+
visit(pos, matched.end, matched.kindIndex);
|
|
1292
|
+
pos = matched.end;
|
|
1293
|
+
count++;
|
|
1294
|
+
}
|
|
1295
|
+
return count < spec.minRepeats ? cur : pos;
|
|
1296
|
+
}
|
|
1297
|
+
function recordTriviaChunks(ctx, chunks) {
|
|
1298
|
+
const kinds = ctx.triviaKindLabels;
|
|
1299
|
+
const mask = ctx._triviaCaptureMask;
|
|
1300
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1301
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
1302
|
+
const rootMark = rootLog?.length ?? 0;
|
|
1303
|
+
for (const ch2 of chunks) {
|
|
1304
|
+
pushTriviaLogEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1305
|
+
const rootKindIndex = ctx._rootTriviaCapture === false || rootLog === void 0 || rootKinds === void 0 || kinds === void 0 ? -1 : rootKinds[kinds[ch2.kindIndex] ?? ""] ?? -1;
|
|
1306
|
+
if (rootKindIndex >= 0) {
|
|
1307
|
+
rootLog.push(0, 0, ch2.start, ch2.end, rootKindIndex);
|
|
1308
|
+
}
|
|
1309
|
+
if (ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)) {
|
|
1310
|
+
if (mask === void 0 || kinds === void 0 || (mask & 1 << ch2.kindIndex) !== 0) {
|
|
1311
|
+
pushCstTriviaEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1346
1312
|
}
|
|
1347
1313
|
}
|
|
1348
|
-
default:
|
|
1349
|
-
return [];
|
|
1350
1314
|
}
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
isTrivia: false
|
|
1358
|
-
};
|
|
1359
|
-
return {
|
|
1360
|
-
_tag: "expect",
|
|
1361
|
-
_meta: meta,
|
|
1362
|
-
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1363
|
-
parse(input, pos, ctx) {
|
|
1364
|
-
const result = combinator.parse(input, pos, ctx);
|
|
1365
|
-
if (result.ok) return result;
|
|
1366
|
-
const span = { start: pos, end: pos };
|
|
1367
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1368
|
-
ctx._errors?.push(error);
|
|
1369
|
-
if (ctx._tolerant) captureError(ctx, error);
|
|
1370
|
-
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1315
|
+
if (rootLog !== void 0 && rootLog.length !== rootMark && chunks.length > 0) {
|
|
1316
|
+
const start = chunks[0].start;
|
|
1317
|
+
const end = chunks[chunks.length - 1].end;
|
|
1318
|
+
for (let offset = rootMark; offset < rootLog.length; offset += 5) {
|
|
1319
|
+
rootLog[offset] = start;
|
|
1320
|
+
rootLog[offset + 1] = end;
|
|
1371
1321
|
}
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
function isParseError(value) {
|
|
1375
|
-
return typeof value === "object" && value !== null && value._tag === "parseError";
|
|
1322
|
+
}
|
|
1376
1323
|
}
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
const
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
1384
|
-
let combined = { kind: "empty" };
|
|
1385
|
-
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
1386
|
-
const meta = {
|
|
1387
|
-
firstSet: combined,
|
|
1388
|
-
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1389
|
-
isTrivia: false,
|
|
1390
|
-
disjoint
|
|
1391
|
-
};
|
|
1392
|
-
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
1393
|
-
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1394
|
-
let greedyLitMap = null;
|
|
1395
|
-
let sortedParsers = null;
|
|
1396
|
-
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
1397
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1398
|
-
greedyLitMap = /* @__PURE__ */ new Map();
|
|
1399
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1400
|
-
if (i === strategy.superIndex) continue;
|
|
1401
|
-
const litVal = getCoreLiteralValue(parsers[i]);
|
|
1402
|
-
if (litVal !== null) greedyLitMap.set(litVal, i);
|
|
1403
|
-
}
|
|
1404
|
-
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
1405
|
-
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
1324
|
+
function triviaKindMask(labels, keep) {
|
|
1325
|
+
if (!labels) return void 0;
|
|
1326
|
+
let mask = 0;
|
|
1327
|
+
for (const name of keep) {
|
|
1328
|
+
const idx = labels.indexOf(name);
|
|
1329
|
+
if (idx >= 0) mask |= 1 << idx;
|
|
1406
1330
|
}
|
|
1331
|
+
return mask;
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
// src/combinators/trivia-skip.ts
|
|
1335
|
+
var NOOP_COMMIT = () => {
|
|
1336
|
+
};
|
|
1337
|
+
var fastTriviaCache = /* @__PURE__ */ new WeakMap();
|
|
1338
|
+
function needsDeferredTriviaCommit(ctx) {
|
|
1339
|
+
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
1340
|
+
}
|
|
1341
|
+
function saveTriviaMark(ctx) {
|
|
1342
|
+
const m = saveCstMark(ctx);
|
|
1407
1343
|
return {
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1344
|
+
raw: m.raw,
|
|
1345
|
+
tlog: m.tlog,
|
|
1346
|
+
leaves: m.leaves,
|
|
1347
|
+
fields: m.fields,
|
|
1348
|
+
errors: m.errors,
|
|
1349
|
+
log: ctx._triviaLog ? ctx._triviaLog.length : 0,
|
|
1350
|
+
rootLog: ctx._rootTriviaLog ? ctx._rootTriviaLog.length : 0
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
function rollbackTrivia(ctx, mark) {
|
|
1354
|
+
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields, errors: mark.errors });
|
|
1355
|
+
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1356
|
+
if (ctx._rootTriviaLog && ctx._rootTriviaLog.length !== mark.rootLog) ctx._rootTriviaLog.length = mark.rootLog;
|
|
1357
|
+
}
|
|
1358
|
+
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1359
|
+
const probeCtx = {
|
|
1360
|
+
trackLines: ctx.trackLines,
|
|
1361
|
+
state: ctx.state,
|
|
1362
|
+
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1363
|
+
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1364
|
+
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1365
|
+
};
|
|
1366
|
+
const result = triviaP.parse(input, cur, probeCtx);
|
|
1367
|
+
ctx._lineScannedTo = probeCtx._lineScannedTo;
|
|
1368
|
+
return result;
|
|
1369
|
+
}
|
|
1370
|
+
function saveLookaheadMark(ctx) {
|
|
1371
|
+
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1372
|
+
}
|
|
1373
|
+
function rollbackLookahead(ctx, mark) {
|
|
1374
|
+
rollbackTrivia(ctx, mark);
|
|
1375
|
+
if (ctx._probe) ctx._probe.best = mark.probeBest;
|
|
1376
|
+
}
|
|
1377
|
+
function scanWithLabels(input, cur, ctx) {
|
|
1378
|
+
const triviaP = ctx.trivia;
|
|
1379
|
+
const spec = analyzeLabeledTrivia(triviaP);
|
|
1380
|
+
if (!spec) return { end: cur, commit: NOOP_COMMIT };
|
|
1381
|
+
const log = ctx._triviaLog;
|
|
1382
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1383
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
1384
|
+
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1385
|
+
const mask = ctx._triviaCaptureMask;
|
|
1386
|
+
let fullRows;
|
|
1387
|
+
let rootRows;
|
|
1388
|
+
let cstRows;
|
|
1389
|
+
const visitedEnd = visitLabeledTrivia(input, cur, spec, ctx.state, (start, matchEnd, kindIndex) => {
|
|
1390
|
+
if (log !== void 0) (fullRows ??= []).push(start, matchEnd, kindIndex);
|
|
1391
|
+
const selectedKind = rootLog === void 0 || rootKinds === void 0 || ctx._rootTriviaCapture === false ? void 0 : rootKinds[spec.labels[kindIndex] ?? ""];
|
|
1392
|
+
if (selectedKind !== void 0) (rootRows ??= []).push(start, matchEnd, selectedKind);
|
|
1393
|
+
if (captureTl && (mask === void 0 || (mask & 1 << kindIndex) !== 0)) {
|
|
1394
|
+
(cstRows ??= []).push(start, matchEnd, kindIndex);
|
|
1395
|
+
}
|
|
1396
|
+
});
|
|
1397
|
+
if (visitedEnd !== void 0) {
|
|
1398
|
+
if (visitedEnd === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1399
|
+
return {
|
|
1400
|
+
end: visitedEnd,
|
|
1401
|
+
commit: () => {
|
|
1402
|
+
if (fullRows !== void 0 && log !== void 0) log.push(...fullRows);
|
|
1403
|
+
if (rootRows !== void 0 && rootLog !== void 0) {
|
|
1404
|
+
for (let i = 0; i < rootRows.length; i += 3) {
|
|
1405
|
+
rootLog.push(cur, visitedEnd, rootRows[i], rootRows[i + 1], rootRows[i + 2]);
|
|
1429
1406
|
}
|
|
1430
1407
|
}
|
|
1431
|
-
if (
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1408
|
+
if (cstRows !== void 0) {
|
|
1409
|
+
for (let i = 0; i < cstRows.length; i += 3) {
|
|
1410
|
+
pushCstTriviaEntry(ctx, cstRows[i], cstRows[i + 1], cstRows[i + 2]);
|
|
1435
1411
|
}
|
|
1436
|
-
const result = parsers[idx].parse(input, pos, ctx);
|
|
1437
|
-
if (result.ok) return result;
|
|
1438
|
-
expected.push(...result.expected);
|
|
1439
|
-
if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
|
|
1440
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1441
|
-
}
|
|
1442
|
-
return {
|
|
1443
|
-
ok: false,
|
|
1444
|
-
expected: parsers.flatMap((p) => {
|
|
1445
|
-
const r = p.parse(input, pos, ctx);
|
|
1446
|
-
return r.ok ? [] : r.expected;
|
|
1447
|
-
}),
|
|
1448
|
-
span: { start: pos, end: pos }
|
|
1449
|
-
};
|
|
1450
|
-
}
|
|
1451
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1452
|
-
const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
|
|
1453
|
-
if (!superResult.ok) return superResult;
|
|
1454
|
-
const end = superResult.span.end;
|
|
1455
|
-
const litIdx = greedyLitMap.get(input.slice(pos, end));
|
|
1456
|
-
if (litIdx !== void 0) {
|
|
1457
|
-
const litVal = getCoreLiteralValue(parsers[litIdx]);
|
|
1458
|
-
const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
|
|
1459
|
-
return { ok: true, value, span: { start: pos, end } };
|
|
1460
|
-
}
|
|
1461
|
-
return superResult;
|
|
1462
|
-
}
|
|
1463
|
-
if (strategy?.tag === "literalsLongestFirst") {
|
|
1464
|
-
for (const p of sortedParsers) {
|
|
1465
|
-
const r = p.parse(input, pos, ctx);
|
|
1466
|
-
if (r.ok) return r;
|
|
1467
|
-
expected.push(...r.expected);
|
|
1468
|
-
}
|
|
1469
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1470
|
-
}
|
|
1471
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1472
|
-
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
1473
|
-
const mark = saveCstMark(ctx);
|
|
1474
|
-
const logLen = ctx._triviaLog?.length;
|
|
1475
|
-
const result = parsers[i].parse(input, pos, ctx);
|
|
1476
|
-
if (!result.ok) {
|
|
1477
|
-
rollbackCstCapture(ctx, mark);
|
|
1478
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1479
|
-
expected.push(...result.expected);
|
|
1480
|
-
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
1481
|
-
continue;
|
|
1482
|
-
}
|
|
1483
|
-
const checks = autoNot[i];
|
|
1484
|
-
if (checks && autoNotFires(input, result.span.end, checks)) {
|
|
1485
|
-
rollbackCstCapture(ctx, mark);
|
|
1486
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1487
|
-
continue;
|
|
1488
1412
|
}
|
|
1489
|
-
return result;
|
|
1490
1413
|
}
|
|
1491
|
-
|
|
1492
|
-
|
|
1414
|
+
};
|
|
1415
|
+
}
|
|
1416
|
+
const { end, chunks } = scanLabeledTriviaChunks(input, cur, spec, ctx.state);
|
|
1417
|
+
if (end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1418
|
+
return {
|
|
1419
|
+
end,
|
|
1420
|
+
commit: () => recordTriviaChunks(ctx, chunks)
|
|
1493
1421
|
};
|
|
1494
1422
|
}
|
|
1495
|
-
function
|
|
1496
|
-
const
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
const
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
const m = re.exec(litVal);
|
|
1511
|
-
return m !== null && m[0] === litVal;
|
|
1512
|
-
});
|
|
1513
|
-
if (allSubsumed) return { tag: "greedyClassify", superIndex };
|
|
1423
|
+
function skipWithLabels(input, cur, ctx) {
|
|
1424
|
+
const spec = analyzeLabeledTrivia(ctx.trivia);
|
|
1425
|
+
if (spec) return scanLabeledTriviaEnd(input, cur, spec, ctx.state);
|
|
1426
|
+
const tr = parseTriviaNoCapture(ctx.trivia, input, cur, ctx);
|
|
1427
|
+
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1428
|
+
}
|
|
1429
|
+
function advanceTrivia(input, cur, ctx) {
|
|
1430
|
+
const triviaP = ctx.trivia;
|
|
1431
|
+
if (!triviaP) return cur;
|
|
1432
|
+
if (!ctx.trackLines) {
|
|
1433
|
+
const fast2 = fastTriviaScanner(triviaP);
|
|
1434
|
+
if (fast2) return fast2(input, cur);
|
|
1435
|
+
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
1436
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1437
|
+
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1514
1438
|
}
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
);
|
|
1519
|
-
|
|
1439
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1440
|
+
const fast = fastTriviaScanner(triviaP);
|
|
1441
|
+
if (fast) {
|
|
1442
|
+
const end = fast(input, cur);
|
|
1443
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1444
|
+
return end;
|
|
1520
1445
|
}
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
function bareLeadingTermKey(term) {
|
|
1526
|
-
const d = term._def;
|
|
1527
|
-
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
1528
|
-
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
1529
|
-
return null;
|
|
1530
|
-
}
|
|
1531
|
-
function detectSharedPrefix(parsers) {
|
|
1532
|
-
if (parsers.length < 2) return null;
|
|
1533
|
-
let key = null;
|
|
1534
|
-
let prefix = null;
|
|
1535
|
-
const members = [];
|
|
1536
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1537
|
-
const term0 = leadingTermOfArm(parsers[i]);
|
|
1538
|
-
if (term0 === null) return null;
|
|
1539
|
-
const k = bareLeadingTermKey(term0);
|
|
1540
|
-
if (k === null) return null;
|
|
1541
|
-
if (key === null) {
|
|
1542
|
-
key = k;
|
|
1543
|
-
prefix = term0;
|
|
1544
|
-
} else if (k !== key) return null;
|
|
1545
|
-
members.push(i);
|
|
1446
|
+
if (ctx.triviaKindLabels) {
|
|
1447
|
+
const end = skipWithLabels(input, cur, ctx);
|
|
1448
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1449
|
+
return end;
|
|
1546
1450
|
}
|
|
1547
|
-
|
|
1548
|
-
return
|
|
1451
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1452
|
+
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1549
1453
|
}
|
|
1550
|
-
function
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1454
|
+
function scanTrivia(input, cur, ctx) {
|
|
1455
|
+
const triviaP = ctx.trivia;
|
|
1456
|
+
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1457
|
+
const log = ctx._triviaLog;
|
|
1458
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1459
|
+
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1460
|
+
if (!ctx.trackLines) {
|
|
1461
|
+
const fast2 = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1462
|
+
if (fast2 && log === void 0 && !captureTl) {
|
|
1463
|
+
return { end: fast2(input, cur), commit: NOOP_COMMIT };
|
|
1556
1464
|
}
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
1560
|
-
return d.parsers[0];
|
|
1561
|
-
}
|
|
1562
|
-
function computeAutoNot(parsers) {
|
|
1563
|
-
return parsers.map((p, i) => {
|
|
1564
|
-
const litVal = getCoreLiteralValue(p);
|
|
1565
|
-
if (litVal === null) return null;
|
|
1566
|
-
const checks = [];
|
|
1567
|
-
for (let j = i + 1; j < parsers.length; j++) {
|
|
1568
|
-
const other = parsers[j];
|
|
1569
|
-
const otherLit = getCoreLiteralValue(other);
|
|
1570
|
-
if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
|
|
1571
|
-
checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
|
|
1572
|
-
continue;
|
|
1573
|
-
}
|
|
1574
|
-
const regexDef = getCoreRegexDef(other);
|
|
1575
|
-
if (regexDef !== null) {
|
|
1576
|
-
const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
|
|
1577
|
-
if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
|
|
1578
|
-
}
|
|
1465
|
+
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1466
|
+
return scanWithLabels(input, cur, ctx);
|
|
1579
1467
|
}
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1468
|
+
if (ctx.triviaKindLabels) return { end: skipWithLabels(input, cur, ctx), commit: NOOP_COMMIT };
|
|
1469
|
+
if (log !== void 0 || rootLog !== void 0 || captureTl) {
|
|
1470
|
+
const tr3 = triviaP.parse(input, cur, {
|
|
1471
|
+
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1472
|
+
state: ctx.state
|
|
1473
|
+
});
|
|
1474
|
+
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1475
|
+
const end = tr3.span.end;
|
|
1476
|
+
return {
|
|
1477
|
+
end,
|
|
1478
|
+
commit: () => {
|
|
1479
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1480
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1481
|
+
}
|
|
1482
|
+
};
|
|
1590
1483
|
}
|
|
1484
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1485
|
+
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1591
1486
|
}
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
return null;
|
|
1599
|
-
}
|
|
1600
|
-
function getCoreRegexDef(p) {
|
|
1601
|
-
const def = p._def;
|
|
1602
|
-
if (def.tag === "regex") return { source: def.source, flags: def.flags };
|
|
1603
|
-
if (def.tag === "transform") return getCoreRegexDef(def.parser);
|
|
1604
|
-
if (def.tag === "label") return getCoreRegexDef(def.parser);
|
|
1605
|
-
return null;
|
|
1606
|
-
}
|
|
1607
|
-
function applyTransforms(p, value, span) {
|
|
1608
|
-
const def = p._def;
|
|
1609
|
-
if (def.tag === "transform") {
|
|
1610
|
-
const inner = applyTransforms(def.parser, value, span);
|
|
1611
|
-
return def.fn(inner, span);
|
|
1487
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1488
|
+
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1489
|
+
if (fast && log === void 0 && !captureTl) {
|
|
1490
|
+
const end = fast(input, cur);
|
|
1491
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1492
|
+
return { end, commit: NOOP_COMMIT };
|
|
1612
1493
|
}
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
re.lastIndex = 0;
|
|
1618
|
-
const base = re.exec(lit);
|
|
1619
|
-
if (!base || base[0] !== lit) return null;
|
|
1620
|
-
const contCodes = [];
|
|
1621
|
-
for (let code = 1; code < 128; code++) {
|
|
1622
|
-
re.lastIndex = 0;
|
|
1623
|
-
const m = re.exec(lit + String.fromCharCode(code));
|
|
1624
|
-
if (m && m[0].length > lit.length) contCodes.push(code);
|
|
1494
|
+
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1495
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1496
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1497
|
+
return scan;
|
|
1625
1498
|
}
|
|
1626
|
-
if (
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
codes.sort((a, b) => a - b);
|
|
1631
|
-
const ranges = [];
|
|
1632
|
-
let lo = codes[0], hi = codes[0];
|
|
1633
|
-
for (let i = 1; i < codes.length; i++) {
|
|
1634
|
-
if (codes[i] === hi + 1) {
|
|
1635
|
-
hi = codes[i];
|
|
1636
|
-
} else {
|
|
1637
|
-
ranges.push({ lo, hi });
|
|
1638
|
-
lo = hi = codes[i];
|
|
1639
|
-
}
|
|
1499
|
+
if (ctx.triviaKindLabels) {
|
|
1500
|
+
const end = skipWithLabels(input, cur, ctx);
|
|
1501
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1502
|
+
return { end, commit: NOOP_COMMIT };
|
|
1640
1503
|
}
|
|
1641
|
-
|
|
1642
|
-
|
|
1504
|
+
if (log !== void 0 || rootLog !== void 0 || captureTl) {
|
|
1505
|
+
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1506
|
+
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1507
|
+
const end = tr2.span.end;
|
|
1508
|
+
return {
|
|
1509
|
+
end,
|
|
1510
|
+
commit: () => {
|
|
1511
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1512
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1513
|
+
}
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1517
|
+
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1643
1518
|
}
|
|
1644
|
-
function
|
|
1645
|
-
if (
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
return
|
|
1519
|
+
function consumeTrivia(input, cur, ctx) {
|
|
1520
|
+
if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
|
|
1521
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1522
|
+
scan.commit();
|
|
1523
|
+
return scan.end;
|
|
1649
1524
|
}
|
|
1650
|
-
function
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
return
|
|
1525
|
+
function fastTriviaScanner(trivia2) {
|
|
1526
|
+
const cached = fastTriviaCache.get(trivia2);
|
|
1527
|
+
if (cached !== void 0) return cached;
|
|
1528
|
+
const scanner = buildFastTriviaScanner(trivia2);
|
|
1529
|
+
fastTriviaCache.set(trivia2, scanner);
|
|
1530
|
+
return scanner;
|
|
1656
1531
|
}
|
|
1657
|
-
function
|
|
1658
|
-
const
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1532
|
+
function buildFastTriviaScanner(trivia2) {
|
|
1533
|
+
const core = trivia2._def.tag === "trivia" ? trivia2._def.parser : trivia2;
|
|
1534
|
+
const direct = regexTriviaScanner(core);
|
|
1535
|
+
if (direct) return direct;
|
|
1536
|
+
const repeat = core._def.tag === "oneOrMore" || core._def.tag === "many" && core._def.min >= 1 ? core._def.parser : null;
|
|
1537
|
+
if (!repeat) return null;
|
|
1538
|
+
const one = regexTriviaScanner(repeat);
|
|
1539
|
+
if (one) return loopScanner([one]);
|
|
1540
|
+
if (repeat._def.tag !== "choice") return null;
|
|
1541
|
+
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1542
|
+
if (arms.some((s) => s === null)) return null;
|
|
1543
|
+
return loopScanner(arms);
|
|
1544
|
+
}
|
|
1545
|
+
function loopScanner(arms) {
|
|
1546
|
+
return (input, cur) => {
|
|
1547
|
+
let pos = cur;
|
|
1548
|
+
scan: while (pos < input.length) {
|
|
1549
|
+
for (const arm of arms) {
|
|
1550
|
+
const end = arm(input, pos);
|
|
1551
|
+
if (end > pos) {
|
|
1552
|
+
pos = end;
|
|
1553
|
+
continue scan;
|
|
1554
|
+
}
|
|
1665
1555
|
}
|
|
1556
|
+
break;
|
|
1666
1557
|
}
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
}
|
|
1670
|
-
|
|
1671
|
-
// src/cst/trivia-kinds.ts
|
|
1672
|
-
function unwrapTrivia(p) {
|
|
1673
|
-
let cur = p;
|
|
1674
|
-
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1675
|
-
return cur;
|
|
1558
|
+
return pos;
|
|
1559
|
+
};
|
|
1676
1560
|
}
|
|
1677
|
-
function
|
|
1678
|
-
if (
|
|
1679
|
-
|
|
1561
|
+
function regexTriviaScanner(parser2) {
|
|
1562
|
+
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1563
|
+
const source = parser2._def.source;
|
|
1564
|
+
return classRunSource(source) ?? altStarSource(source);
|
|
1680
1565
|
}
|
|
1681
|
-
function
|
|
1682
|
-
let
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
core = core._def.parser;
|
|
1686
|
-
minRepeats = 1;
|
|
1687
|
-
} else if (core._def.tag === "many") {
|
|
1688
|
-
core = core._def.parser;
|
|
1689
|
-
minRepeats = 0;
|
|
1690
|
-
}
|
|
1691
|
-
const arms = [];
|
|
1692
|
-
if (core._def.tag === "choice") {
|
|
1693
|
-
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1694
|
-
const peeled = peelLabel(core._def.parsers[i]);
|
|
1695
|
-
if (!peeled) return null;
|
|
1696
|
-
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1697
|
-
}
|
|
1698
|
-
} else {
|
|
1699
|
-
const peeled = peelLabel(core);
|
|
1700
|
-
if (!peeled) return null;
|
|
1701
|
-
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1566
|
+
function inRanges2(cp, ranges) {
|
|
1567
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
1568
|
+
const r = ranges[i];
|
|
1569
|
+
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1702
1570
|
}
|
|
1703
|
-
return
|
|
1571
|
+
return false;
|
|
1704
1572
|
}
|
|
1705
|
-
function
|
|
1706
|
-
const
|
|
1707
|
-
if (!
|
|
1708
|
-
return
|
|
1573
|
+
function classScanner(classBody) {
|
|
1574
|
+
const ranges = parseClassRanges(classBody);
|
|
1575
|
+
if (!ranges) return null;
|
|
1576
|
+
return (input, cur) => {
|
|
1577
|
+
let pos = cur;
|
|
1578
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1579
|
+
return pos;
|
|
1580
|
+
};
|
|
1709
1581
|
}
|
|
1710
|
-
function
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1719
|
-
break;
|
|
1720
|
-
}
|
|
1582
|
+
function untilLineBreakScanner(leaderCode) {
|
|
1583
|
+
return (input, cur) => {
|
|
1584
|
+
if (input.charCodeAt(cur) !== leaderCode) return cur;
|
|
1585
|
+
let pos = cur + 1;
|
|
1586
|
+
while (pos < input.length) {
|
|
1587
|
+
const cc = input.charCodeAt(pos);
|
|
1588
|
+
if (cc === 10 || cc === 13) break;
|
|
1589
|
+
pos++;
|
|
1721
1590
|
}
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1591
|
+
return pos;
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
function classRunSource(source) {
|
|
1595
|
+
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1596
|
+
return m ? classScanner(m[1]) : null;
|
|
1597
|
+
}
|
|
1598
|
+
function classifyTriviaArm(arm) {
|
|
1599
|
+
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1600
|
+
if (cls) {
|
|
1601
|
+
const ranges = parseClassRanges(cls[1]);
|
|
1602
|
+
return ranges ? { kind: "class", ranges } : null;
|
|
1725
1603
|
}
|
|
1726
|
-
|
|
1727
|
-
|
|
1604
|
+
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1605
|
+
if (lc) {
|
|
1606
|
+
const marker = lc[1];
|
|
1607
|
+
return { kind: "untilLineBreak", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1728
1608
|
}
|
|
1729
|
-
return
|
|
1609
|
+
return null;
|
|
1730
1610
|
}
|
|
1731
|
-
function
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1611
|
+
function armScanner(arm) {
|
|
1612
|
+
if (arm.kind === "untilLineBreak") return untilLineBreakScanner(arm.code);
|
|
1613
|
+
const ranges = arm.ranges;
|
|
1614
|
+
return (input, cur) => {
|
|
1615
|
+
let pos = cur;
|
|
1616
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1617
|
+
return pos;
|
|
1618
|
+
};
|
|
1619
|
+
}
|
|
1620
|
+
function fusedTriviaScanner(ranges, leaders) {
|
|
1621
|
+
const c0 = leaders[0];
|
|
1622
|
+
const single = leaders.length === 1;
|
|
1623
|
+
return (input, cur) => {
|
|
1624
|
+
let pos = cur;
|
|
1625
|
+
const len = input.length;
|
|
1626
|
+
for (; ; ) {
|
|
1627
|
+
const c = input.charCodeAt(pos);
|
|
1628
|
+
if (pos < len && inRanges2(c, ranges)) {
|
|
1629
|
+
pos++;
|
|
1630
|
+
continue;
|
|
1743
1631
|
}
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
const start = pos;
|
|
1752
|
-
pos = j + 2;
|
|
1753
|
-
chunks.push({ start, end: pos, kindIndex: commentKind });
|
|
1632
|
+
if (single ? c === c0 : leaders.includes(c)) {
|
|
1633
|
+
pos++;
|
|
1634
|
+
while (pos < len) {
|
|
1635
|
+
const cc = input.charCodeAt(pos);
|
|
1636
|
+
if (cc === 10 || cc === 13) break;
|
|
1637
|
+
pos++;
|
|
1638
|
+
}
|
|
1754
1639
|
continue;
|
|
1755
1640
|
}
|
|
1756
1641
|
break;
|
|
1757
1642
|
}
|
|
1758
|
-
|
|
1759
|
-
}
|
|
1760
|
-
return { end: pos, chunks };
|
|
1761
|
-
}
|
|
1762
|
-
function tryFastLabeledScan(input, cur, trivia2) {
|
|
1763
|
-
const spec = analyzeLabeledTrivia(trivia2);
|
|
1764
|
-
if (!spec || spec.arms.length !== 2) return null;
|
|
1765
|
-
const wsArm = spec.arms.find((a) => {
|
|
1766
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1767
|
-
return src != null && !src.includes("\\*");
|
|
1768
|
-
});
|
|
1769
|
-
const commentArm = spec.arms.find((a) => {
|
|
1770
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1771
|
-
return src != null && src.includes("\\*");
|
|
1772
|
-
});
|
|
1773
|
-
if (!wsArm || !commentArm) return null;
|
|
1774
|
-
const { chunks } = scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1775
|
-
if (chunks.length < spec.minRepeats) return { end: cur, chunks: [] };
|
|
1776
|
-
return scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1643
|
+
return pos;
|
|
1644
|
+
};
|
|
1777
1645
|
}
|
|
1778
|
-
function
|
|
1779
|
-
const
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1646
|
+
function splitTopLevelAlts(body) {
|
|
1647
|
+
const arms = [];
|
|
1648
|
+
let inClass = false;
|
|
1649
|
+
let start = 0;
|
|
1650
|
+
for (let i = 0; i < body.length; i++) {
|
|
1651
|
+
const c = body[i];
|
|
1652
|
+
if (c === "\\") {
|
|
1653
|
+
i++;
|
|
1654
|
+
continue;
|
|
1655
|
+
}
|
|
1656
|
+
if (inClass) {
|
|
1657
|
+
if (c === "]") inClass = false;
|
|
1658
|
+
continue;
|
|
1659
|
+
}
|
|
1660
|
+
if (c === "[") inClass = true;
|
|
1661
|
+
else if (c === "(") return null;
|
|
1662
|
+
else if (c === "|") {
|
|
1663
|
+
arms.push(body.slice(start, i));
|
|
1664
|
+
start = i + 1;
|
|
1787
1665
|
}
|
|
1788
1666
|
}
|
|
1667
|
+
arms.push(body.slice(start));
|
|
1668
|
+
return arms;
|
|
1789
1669
|
}
|
|
1790
|
-
function
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1670
|
+
function altStarSource(source) {
|
|
1671
|
+
const m = /^\(\?:(.*)\)[*+]$/.exec(source);
|
|
1672
|
+
if (!m) return null;
|
|
1673
|
+
const armSrcs = splitTopLevelAlts(m[1]);
|
|
1674
|
+
if (!armSrcs || armSrcs.length < 2) return null;
|
|
1675
|
+
const arms = [];
|
|
1676
|
+
for (const src of armSrcs) {
|
|
1677
|
+
const arm = classifyTriviaArm(src);
|
|
1678
|
+
if (!arm) return null;
|
|
1679
|
+
arms.push(arm);
|
|
1796
1680
|
}
|
|
1797
|
-
|
|
1681
|
+
const ranges = [];
|
|
1682
|
+
const leaders = [];
|
|
1683
|
+
for (const arm of arms) {
|
|
1684
|
+
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1685
|
+
else leaders.push(arm.code);
|
|
1686
|
+
}
|
|
1687
|
+
if (leaders.some((code) => inRanges2(code, ranges))) {
|
|
1688
|
+
return loopScanner(arms.map(armScanner));
|
|
1689
|
+
}
|
|
1690
|
+
if (leaders.length === 0) return armScanner({ kind: "class", ranges });
|
|
1691
|
+
return fusedTriviaScanner(ranges, leaders);
|
|
1798
1692
|
}
|
|
1799
1693
|
|
|
1800
|
-
// src/
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1816
|
-
const probeCtx = {
|
|
1817
|
-
trackLines: ctx.trackLines,
|
|
1818
|
-
state: ctx.state,
|
|
1819
|
-
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1820
|
-
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1821
|
-
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1694
|
+
// src/recovery/scan.ts
|
|
1695
|
+
function probeAt(sentinel, input, pos, ctx) {
|
|
1696
|
+
const s = {
|
|
1697
|
+
_probe: ctx._probe,
|
|
1698
|
+
_errors: ctx._errors,
|
|
1699
|
+
_cstLeaves: ctx._cstLeaves,
|
|
1700
|
+
_cstChildren: ctx._cstChildren,
|
|
1701
|
+
_cstRawChildren: ctx._cstRawChildren,
|
|
1702
|
+
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1703
|
+
_triviaLog: ctx._triviaLog,
|
|
1704
|
+
_rootTriviaLog: ctx._rootTriviaLog,
|
|
1705
|
+
_fields: ctx._fields,
|
|
1706
|
+
_cstBuf: ctx._cstBuf,
|
|
1707
|
+
_tolerant: ctx._tolerant,
|
|
1708
|
+
_sync: ctx._sync
|
|
1822
1709
|
};
|
|
1823
|
-
|
|
1824
|
-
ctx.
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1710
|
+
ctx._probe = void 0;
|
|
1711
|
+
ctx._errors = void 0;
|
|
1712
|
+
ctx._cstLeaves = void 0;
|
|
1713
|
+
ctx._cstChildren = void 0;
|
|
1714
|
+
ctx._cstRawChildren = void 0;
|
|
1715
|
+
ctx._cstTriviaLog = void 0;
|
|
1716
|
+
ctx._triviaLog = void 0;
|
|
1717
|
+
ctx._rootTriviaLog = void 0;
|
|
1718
|
+
ctx._fields = void 0;
|
|
1719
|
+
ctx._cstBuf = void 0;
|
|
1720
|
+
ctx._tolerant = void 0;
|
|
1721
|
+
ctx._sync = void 0;
|
|
1722
|
+
try {
|
|
1723
|
+
return sentinel.parse(input, pos, ctx).ok;
|
|
1724
|
+
} finally {
|
|
1725
|
+
ctx._probe = s._probe;
|
|
1726
|
+
ctx._errors = s._errors;
|
|
1727
|
+
ctx._cstLeaves = s._cstLeaves;
|
|
1728
|
+
ctx._cstChildren = s._cstChildren;
|
|
1729
|
+
ctx._cstRawChildren = s._cstRawChildren;
|
|
1730
|
+
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1731
|
+
ctx._triviaLog = s._triviaLog;
|
|
1732
|
+
ctx._rootTriviaLog = s._rootTriviaLog;
|
|
1733
|
+
ctx._fields = s._fields;
|
|
1734
|
+
ctx._cstBuf = s._cstBuf;
|
|
1735
|
+
ctx._tolerant = s._tolerant;
|
|
1736
|
+
ctx._sync = s._sync;
|
|
1737
|
+
}
|
|
1833
1738
|
}
|
|
1834
|
-
function
|
|
1835
|
-
|
|
1836
|
-
const spec = analyzeLabeledTrivia(triviaP);
|
|
1837
|
-
if (!spec) return { end: cur, commit: NOOP_COMMIT };
|
|
1838
|
-
const fast = tryFastLabeledScan(input, cur, triviaP);
|
|
1839
|
-
const { end, chunks } = fast ?? scanLabeledTriviaChunks(input, cur, spec);
|
|
1840
|
-
if (end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1739
|
+
function orSentinel(a, b) {
|
|
1740
|
+
if (b === void 0) return a;
|
|
1841
1741
|
return {
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
if (!ctx.trackLines) {
|
|
1850
|
-
const fast2 = fastTriviaScanner(triviaP);
|
|
1851
|
-
if (fast2) return fast2(input, cur);
|
|
1852
|
-
if (ctx.triviaKindLabels) {
|
|
1853
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1854
|
-
return scan.end;
|
|
1742
|
+
_tag: "orSentinel",
|
|
1743
|
+
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1744
|
+
_def: { tag: "unknown" },
|
|
1745
|
+
parse(input, pos, ctx) {
|
|
1746
|
+
const ra = a.parse(input, pos, ctx);
|
|
1747
|
+
if (ra.ok) return ra;
|
|
1748
|
+
return b.parse(input, pos, ctx);
|
|
1855
1749
|
}
|
|
1856
|
-
|
|
1857
|
-
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1858
|
-
}
|
|
1859
|
-
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1860
|
-
const fast = fastTriviaScanner(triviaP);
|
|
1861
|
-
if (fast) {
|
|
1862
|
-
const end = fast(input, cur);
|
|
1863
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1864
|
-
return end;
|
|
1865
|
-
}
|
|
1866
|
-
if (ctx.triviaKindLabels) {
|
|
1867
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1868
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1869
|
-
return scan.end;
|
|
1870
|
-
}
|
|
1871
|
-
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1872
|
-
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1750
|
+
};
|
|
1873
1751
|
}
|
|
1874
|
-
function
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
}
|
|
1887
|
-
if (log !== void 0 || captureTl) {
|
|
1888
|
-
const tr3 = triviaP.parse(input, cur, {
|
|
1889
|
-
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1890
|
-
state: ctx.state
|
|
1891
|
-
});
|
|
1892
|
-
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1893
|
-
const end = tr3.span.end;
|
|
1894
|
-
return {
|
|
1895
|
-
end,
|
|
1896
|
-
commit: () => {
|
|
1897
|
-
pushTriviaLogEntry(ctx, cur, end);
|
|
1898
|
-
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1752
|
+
function firstSetSentinel(fs) {
|
|
1753
|
+
if (fs.kind !== "ranges" || fs.ranges.length === 0) return null;
|
|
1754
|
+
const ranges = fs.ranges;
|
|
1755
|
+
return {
|
|
1756
|
+
_tag: "firstSetSentinel",
|
|
1757
|
+
_meta: { firstSet: fs, canMatchNewline: false, isTrivia: false },
|
|
1758
|
+
_def: { tag: "unknown" },
|
|
1759
|
+
parse(input, pos) {
|
|
1760
|
+
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
1761
|
+
if (code !== void 0) {
|
|
1762
|
+
for (const r of ranges) {
|
|
1763
|
+
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1899
1764
|
}
|
|
1900
|
-
}
|
|
1765
|
+
}
|
|
1766
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
1901
1767
|
}
|
|
1902
|
-
|
|
1903
|
-
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1904
|
-
}
|
|
1905
|
-
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1906
|
-
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1907
|
-
if (fast && log === void 0 && !captureTl) {
|
|
1908
|
-
const end = fast(input, cur);
|
|
1909
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1910
|
-
return { end, commit: NOOP_COMMIT };
|
|
1911
|
-
}
|
|
1912
|
-
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1913
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1914
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1915
|
-
return scan;
|
|
1916
|
-
}
|
|
1917
|
-
if (log !== void 0 || captureTl) {
|
|
1918
|
-
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1919
|
-
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1920
|
-
const end = tr2.span.end;
|
|
1921
|
-
return {
|
|
1922
|
-
end,
|
|
1923
|
-
commit: () => {
|
|
1924
|
-
pushTriviaLogEntry(ctx, cur, end);
|
|
1925
|
-
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1926
|
-
}
|
|
1927
|
-
};
|
|
1928
|
-
}
|
|
1929
|
-
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1930
|
-
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1768
|
+
};
|
|
1931
1769
|
}
|
|
1932
|
-
function
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1770
|
+
function recoverScan(input, from, ctx, sync, expected) {
|
|
1771
|
+
let scanPos = from;
|
|
1772
|
+
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1773
|
+
const span = { start: from, end: scanPos };
|
|
1774
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
1775
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1776
|
+
ctx._errors?.push(error);
|
|
1777
|
+
return { error, end: scanPos };
|
|
1937
1778
|
}
|
|
1938
|
-
function
|
|
1939
|
-
|
|
1940
|
-
if (cached !== void 0) return cached;
|
|
1941
|
-
const scanner = buildFastTriviaScanner(trivia2);
|
|
1942
|
-
fastTriviaCache.set(trivia2, scanner);
|
|
1943
|
-
return scanner;
|
|
1779
|
+
function matchesAt(sentinel, input, pos, ctx) {
|
|
1780
|
+
return probeAt(sentinel, input, pos, ctx);
|
|
1944
1781
|
}
|
|
1945
|
-
function
|
|
1946
|
-
|
|
1947
|
-
const direct = regexTriviaScanner(core);
|
|
1948
|
-
if (direct) return direct;
|
|
1949
|
-
const repeat = core._def.tag === "oneOrMore" || core._def.tag === "many" && core._def.min >= 1 ? core._def.parser : null;
|
|
1950
|
-
if (!repeat) return null;
|
|
1951
|
-
const one = regexTriviaScanner(repeat);
|
|
1952
|
-
if (one) return loopScanner([one]);
|
|
1953
|
-
if (repeat._def.tag !== "choice") return null;
|
|
1954
|
-
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1955
|
-
if (arms.some((s) => s === null)) return null;
|
|
1956
|
-
return loopScanner(arms);
|
|
1782
|
+
function captureError(ctx, error) {
|
|
1783
|
+
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1957
1784
|
}
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1785
|
+
var REC = { scan: recoverScan, at: matchesAt, or: orSentinel, sentinel: firstSetSentinel, capture: captureError };
|
|
1786
|
+
|
|
1787
|
+
// src/combinators/sequence.ts
|
|
1788
|
+
function sequence(...parsers) {
|
|
1789
|
+
const meta = {
|
|
1790
|
+
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
1791
|
+
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
1792
|
+
firstSet: sequenceFirstSet(parsers),
|
|
1793
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1794
|
+
isTrivia: false
|
|
1795
|
+
};
|
|
1796
|
+
const def = { tag: "sequence", parsers };
|
|
1797
|
+
let followSentinels;
|
|
1798
|
+
function parseTolerant(input, pos, ctx) {
|
|
1799
|
+
followSentinels ??= parsers.map((_, i) => {
|
|
1800
|
+
const fs = parsers.slice(i + 1).reduce(
|
|
1801
|
+
(acc, p) => union(acc, firstSetOf(p)),
|
|
1802
|
+
{ kind: "empty" }
|
|
1803
|
+
);
|
|
1804
|
+
return firstSetSentinel(fs);
|
|
1805
|
+
});
|
|
1806
|
+
const values = def.valueUnused ? void 0 : [];
|
|
1807
|
+
let cur = pos;
|
|
1808
|
+
const inheritedSync = ctx._sync;
|
|
1809
|
+
try {
|
|
1810
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1811
|
+
ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
1812
|
+
if (ctx.trivia && i > 0) {
|
|
1813
|
+
const mark = saveTriviaMark(ctx);
|
|
1814
|
+
let scanEnd;
|
|
1815
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
1816
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1817
|
+
scan.commit();
|
|
1818
|
+
scanEnd = scan.end;
|
|
1819
|
+
} else {
|
|
1820
|
+
scanEnd = advanceTrivia(input, cur, ctx);
|
|
1821
|
+
}
|
|
1822
|
+
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
1823
|
+
if (!result2.ok) return result2;
|
|
1824
|
+
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
1825
|
+
else rollbackTrivia(ctx, mark);
|
|
1826
|
+
if (values !== void 0) values.push(result2.value);
|
|
1827
|
+
continue;
|
|
1967
1828
|
}
|
|
1829
|
+
const result = parsers[i].parse(input, cur, ctx);
|
|
1830
|
+
if (!result.ok) return result;
|
|
1831
|
+
if (values !== void 0) values.push(result.value);
|
|
1832
|
+
cur = result.span.end;
|
|
1968
1833
|
}
|
|
1969
|
-
|
|
1834
|
+
} finally {
|
|
1835
|
+
ctx._sync = inheritedSync;
|
|
1836
|
+
}
|
|
1837
|
+
return {
|
|
1838
|
+
ok: true,
|
|
1839
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1840
|
+
value: values ?? void 0,
|
|
1841
|
+
span: { start: pos, end: cur }
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
return {
|
|
1845
|
+
_tag: "sequence",
|
|
1846
|
+
_meta: meta,
|
|
1847
|
+
_def: def,
|
|
1848
|
+
parse(input, pos, ctx) {
|
|
1849
|
+
if (ctx._tolerant) return parseTolerant(input, pos, ctx);
|
|
1850
|
+
const values = def.valueUnused ? void 0 : [];
|
|
1851
|
+
let cur = pos;
|
|
1852
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1853
|
+
if (ctx.trivia && i > 0) {
|
|
1854
|
+
let scanEnd;
|
|
1855
|
+
let mark = saveTriviaMark(ctx);
|
|
1856
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
1857
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1858
|
+
scan.commit();
|
|
1859
|
+
scanEnd = scan.end;
|
|
1860
|
+
} else {
|
|
1861
|
+
scanEnd = advanceTrivia(input, cur, ctx);
|
|
1862
|
+
}
|
|
1863
|
+
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
1864
|
+
if (!result2.ok) return result2;
|
|
1865
|
+
if (result2.span.end > scanEnd) {
|
|
1866
|
+
cur = result2.span.end;
|
|
1867
|
+
} else {
|
|
1868
|
+
rollbackTrivia(ctx, mark);
|
|
1869
|
+
}
|
|
1870
|
+
if (values !== void 0) values.push(result2.value);
|
|
1871
|
+
continue;
|
|
1872
|
+
}
|
|
1873
|
+
const result = parsers[i].parse(input, cur, ctx);
|
|
1874
|
+
if (!result.ok) return result;
|
|
1875
|
+
if (values !== void 0) values.push(result.value);
|
|
1876
|
+
cur = result.span.end;
|
|
1877
|
+
}
|
|
1878
|
+
return {
|
|
1879
|
+
ok: true,
|
|
1880
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1881
|
+
value: values ?? void 0,
|
|
1882
|
+
span: { start: pos, end: cur }
|
|
1883
|
+
};
|
|
1970
1884
|
}
|
|
1971
|
-
return pos;
|
|
1972
1885
|
};
|
|
1973
1886
|
}
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
return
|
|
1887
|
+
|
|
1888
|
+
// src/combinators/expect.ts
|
|
1889
|
+
function deriveExpected(c) {
|
|
1890
|
+
return [...new Set(derive(c, /* @__PURE__ */ new Set()))];
|
|
1978
1891
|
}
|
|
1979
|
-
function
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1892
|
+
function derive(c, seen) {
|
|
1893
|
+
const deriveExpected2 = (p) => derive(p, seen);
|
|
1894
|
+
const def = c._def;
|
|
1895
|
+
switch (def.tag) {
|
|
1896
|
+
case "literal":
|
|
1897
|
+
return [JSON.stringify(def.value)];
|
|
1898
|
+
case "regex":
|
|
1899
|
+
return [`/${def.source}/`];
|
|
1900
|
+
case "keywords":
|
|
1901
|
+
return def.words.map((w) => JSON.stringify(w));
|
|
1902
|
+
case "label":
|
|
1903
|
+
return [def.label];
|
|
1904
|
+
case "choice":
|
|
1905
|
+
return def.parsers.flatMap(deriveExpected2);
|
|
1906
|
+
case "dispatch":
|
|
1907
|
+
return deriveExpected2(def.selector);
|
|
1908
|
+
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
1909
|
+
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
1910
|
+
// able to fail first — deriving from term 0 alone named a token the parse
|
|
1911
|
+
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
1912
|
+
// nothing (its own expectation is about what must NOT be here), but it is
|
|
1913
|
+
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
1914
|
+
case "sequence": {
|
|
1915
|
+
const out = [];
|
|
1916
|
+
for (const term of def.parsers) {
|
|
1917
|
+
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
1918
|
+
if (!matchesEmpty(term)) break;
|
|
1919
|
+
}
|
|
1920
|
+
return out;
|
|
1921
|
+
}
|
|
1922
|
+
case "attempt":
|
|
1923
|
+
return deriveExpected2(def.parser);
|
|
1924
|
+
// Delegating wrappers whose first-token failure is their inner parser's — must
|
|
1925
|
+
// pass through so a start-failure (and the first-set-miss fast-path in attempt/
|
|
1926
|
+
// node, which reads this) names the real expected token, not the wrapper tag.
|
|
1927
|
+
case "field":
|
|
1928
|
+
case "withCtx":
|
|
1929
|
+
case "recover":
|
|
1930
|
+
return deriveExpected2(def.parser);
|
|
1931
|
+
case "skip":
|
|
1932
|
+
return deriveExpected2(def.main);
|
|
1933
|
+
case "expect":
|
|
1934
|
+
return def.expected;
|
|
1935
|
+
case "node":
|
|
1936
|
+
case "grammar":
|
|
1937
|
+
case "trivia":
|
|
1938
|
+
case "token":
|
|
1939
|
+
case "leaf":
|
|
1940
|
+
case "optional":
|
|
1941
|
+
case "many":
|
|
1942
|
+
case "oneOrMore":
|
|
1943
|
+
case "transform":
|
|
1944
|
+
case "not":
|
|
1945
|
+
case "peek":
|
|
1946
|
+
return deriveExpected2(def.parser);
|
|
1947
|
+
case "routed":
|
|
1948
|
+
return ["routed()"];
|
|
1949
|
+
case "lazy": {
|
|
1950
|
+
const name = c._ruleName;
|
|
1951
|
+
if (seen.has(c)) return name ? [name] : [];
|
|
1952
|
+
seen.add(c);
|
|
1953
|
+
try {
|
|
1954
|
+
return deriveExpected2(def.thunk());
|
|
1955
|
+
} catch {
|
|
1956
|
+
return name ? [name] : [];
|
|
1957
|
+
} finally {
|
|
1958
|
+
seen.delete(c);
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
default:
|
|
1962
|
+
return [];
|
|
1983
1963
|
}
|
|
1984
|
-
return false;
|
|
1985
1964
|
}
|
|
1986
|
-
function
|
|
1987
|
-
const
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
return pos;
|
|
1965
|
+
function expect(combinator, label2) {
|
|
1966
|
+
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
1967
|
+
const meta = {
|
|
1968
|
+
firstSet: combinator._meta.firstSet,
|
|
1969
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1970
|
+
isTrivia: false
|
|
1993
1971
|
};
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
1972
|
+
return {
|
|
1973
|
+
_tag: "expect",
|
|
1974
|
+
_meta: meta,
|
|
1975
|
+
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1976
|
+
parse(input, pos, ctx) {
|
|
1977
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1978
|
+
if (result.ok) return result;
|
|
1979
|
+
const span = { start: pos, end: pos };
|
|
1980
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1981
|
+
ctx._errors?.push(error);
|
|
1982
|
+
if (ctx._tolerant) captureError(ctx, error);
|
|
1983
|
+
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
2003
1984
|
}
|
|
2004
|
-
return pos;
|
|
2005
1985
|
};
|
|
2006
1986
|
}
|
|
2007
|
-
function
|
|
2008
|
-
|
|
2009
|
-
return m ? classScanner(m[1]) : null;
|
|
1987
|
+
function isParseError(value) {
|
|
1988
|
+
return typeof value === "object" && value !== null && value._tag === "parseError";
|
|
2010
1989
|
}
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
1990
|
+
|
|
1991
|
+
// src/combinators/choice.ts
|
|
1992
|
+
function choice(...args) {
|
|
1993
|
+
const parsers = args.map((a) => "gate" in a ? a.combinator : a);
|
|
1994
|
+
const gates = args.map((a) => "gate" in a ? a.gate : null);
|
|
1995
|
+
const hasGates = gates.some((g) => g !== null);
|
|
1996
|
+
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
1997
|
+
let combined = { kind: "empty" };
|
|
1998
|
+
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
1999
|
+
const meta = {
|
|
2000
|
+
firstSet: combined,
|
|
2001
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
2002
|
+
isTrivia: false,
|
|
2003
|
+
disjoint
|
|
2004
|
+
};
|
|
2005
|
+
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
2006
|
+
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
2007
|
+
let greedyLitMap = null;
|
|
2008
|
+
let sortedParsers = null;
|
|
2009
|
+
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
2010
|
+
if (strategy?.tag === "greedyClassify") {
|
|
2011
|
+
greedyLitMap = /* @__PURE__ */ new Map();
|
|
2012
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2013
|
+
if (i === strategy.superIndex) continue;
|
|
2014
|
+
const litVal = getCoreLiteralValue(parsers[i]);
|
|
2015
|
+
if (litVal !== null) greedyLitMap.set(litVal, i);
|
|
2016
|
+
}
|
|
2017
|
+
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
2018
|
+
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
2016
2019
|
}
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2020
|
+
return {
|
|
2021
|
+
_tag: "choice",
|
|
2022
|
+
_meta: meta,
|
|
2023
|
+
_def: {
|
|
2024
|
+
tag: "choice",
|
|
2025
|
+
parsers,
|
|
2026
|
+
gates,
|
|
2027
|
+
disjoint,
|
|
2028
|
+
strategy: strategy ?? { tag: "firstMatch" },
|
|
2029
|
+
autoNot
|
|
2030
|
+
},
|
|
2031
|
+
parse(input, pos, ctx) {
|
|
2032
|
+
const expected = [];
|
|
2033
|
+
if (disjoint && pos < input.length) {
|
|
2034
|
+
const code = input.codePointAt(pos);
|
|
2035
|
+
let idx = code < 128 ? asciiDispatch[code] : -1;
|
|
2036
|
+
if (idx < 0) {
|
|
2037
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2038
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
2039
|
+
idx = i;
|
|
2040
|
+
break;
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
if (idx >= 0) {
|
|
2045
|
+
const gate2 = gates[idx];
|
|
2046
|
+
if (gate2 && !gate2(ctx.state)) {
|
|
2047
|
+
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
2048
|
+
}
|
|
2049
|
+
const result = parsers[idx].parse(input, pos, ctx);
|
|
2050
|
+
if (result.ok) return result;
|
|
2051
|
+
expected.push(...result.expected);
|
|
2052
|
+
if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
|
|
2053
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
2054
|
+
}
|
|
2055
|
+
return {
|
|
2056
|
+
ok: false,
|
|
2057
|
+
expected: parsers.flatMap((p) => {
|
|
2058
|
+
const r = p.parse(input, pos, ctx);
|
|
2059
|
+
return r.ok ? [] : r.expected;
|
|
2060
|
+
}),
|
|
2061
|
+
span: { start: pos, end: pos }
|
|
2062
|
+
};
|
|
2063
|
+
}
|
|
2064
|
+
if (strategy?.tag === "greedyClassify") {
|
|
2065
|
+
const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
|
|
2066
|
+
if (!superResult.ok) return superResult;
|
|
2067
|
+
const end = superResult.span.end;
|
|
2068
|
+
const litIdx = greedyLitMap.get(input.slice(pos, end));
|
|
2069
|
+
if (litIdx !== void 0) {
|
|
2070
|
+
const litVal = getCoreLiteralValue(parsers[litIdx]);
|
|
2071
|
+
const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
|
|
2072
|
+
return { ok: true, value, span: { start: pos, end } };
|
|
2073
|
+
}
|
|
2074
|
+
return superResult;
|
|
2075
|
+
}
|
|
2076
|
+
if (strategy?.tag === "literalsLongestFirst") {
|
|
2077
|
+
for (const p of sortedParsers) {
|
|
2078
|
+
const r = p.parse(input, pos, ctx);
|
|
2079
|
+
if (r.ok) return r;
|
|
2080
|
+
expected.push(...r.expected);
|
|
2081
|
+
}
|
|
2082
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
2083
|
+
}
|
|
2084
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2085
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
2086
|
+
const mark = saveTriviaMark(ctx);
|
|
2087
|
+
const result = parsers[i].parse(input, pos, ctx);
|
|
2088
|
+
if (!result.ok) {
|
|
2089
|
+
rollbackTrivia(ctx, mark);
|
|
2090
|
+
expected.push(...result.expected);
|
|
2091
|
+
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
2092
|
+
continue;
|
|
2093
|
+
}
|
|
2094
|
+
const checks = autoNot[i];
|
|
2095
|
+
if (checks && autoNotFires(input, result.span.end, checks)) {
|
|
2096
|
+
rollbackTrivia(ctx, mark);
|
|
2097
|
+
continue;
|
|
2098
|
+
}
|
|
2099
|
+
return result;
|
|
2100
|
+
}
|
|
2101
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
2102
|
+
}
|
|
2103
|
+
};
|
|
2104
|
+
}
|
|
2105
|
+
function detectStrategy(parsers) {
|
|
2106
|
+
const regexIndices = [];
|
|
2107
|
+
const literalIndices = [];
|
|
2108
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2109
|
+
if (getCoreRegexDef(parsers[i]) !== null) regexIndices.push(i);
|
|
2110
|
+
else if (getCoreLiteralValue(parsers[i]) !== null) literalIndices.push(i);
|
|
2111
|
+
}
|
|
2112
|
+
if (regexIndices.length === 1 && literalIndices.length === parsers.length - 1 && literalIndices.length > 0) {
|
|
2113
|
+
const superIndex = regexIndices[0];
|
|
2114
|
+
const regexDef = getCoreRegexDef(parsers[superIndex]);
|
|
2115
|
+
const flags = "y" + regexDef.flags.replace(/[gy]/g, "");
|
|
2116
|
+
const re = new RegExp(regexDef.source, flags);
|
|
2117
|
+
const allSubsumed = literalIndices.every((i) => {
|
|
2118
|
+
const litVal = getCoreLiteralValue(parsers[i]);
|
|
2119
|
+
re.lastIndex = 0;
|
|
2120
|
+
const m = re.exec(litVal);
|
|
2121
|
+
return m !== null && m[0] === litVal;
|
|
2122
|
+
});
|
|
2123
|
+
if (allSubsumed) return { tag: "greedyClassify", superIndex };
|
|
2124
|
+
}
|
|
2125
|
+
if (parsers.length === literalIndices.length) {
|
|
2126
|
+
const sortedIndices = [...literalIndices].sort(
|
|
2127
|
+
(a, b) => getCoreLiteralValue(parsers[b]).length - getCoreLiteralValue(parsers[a]).length
|
|
2128
|
+
);
|
|
2129
|
+
return { tag: "literalsLongestFirst", sortedIndices };
|
|
2021
2130
|
}
|
|
2131
|
+
const shared = detectSharedPrefix(parsers);
|
|
2132
|
+
if (shared !== null) return shared;
|
|
2133
|
+
return { tag: "firstMatch" };
|
|
2134
|
+
}
|
|
2135
|
+
function bareLeadingTermKey(term) {
|
|
2136
|
+
const d = term._def;
|
|
2137
|
+
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
2138
|
+
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
2022
2139
|
return null;
|
|
2023
2140
|
}
|
|
2024
|
-
function
|
|
2025
|
-
if (
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2141
|
+
function detectSharedPrefix(parsers) {
|
|
2142
|
+
if (parsers.length < 2) return null;
|
|
2143
|
+
let key = null;
|
|
2144
|
+
let prefix = null;
|
|
2145
|
+
const members = [];
|
|
2146
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2147
|
+
const term0 = leadingTermOfArm(parsers[i]);
|
|
2148
|
+
if (term0 === null) return null;
|
|
2149
|
+
const k = bareLeadingTermKey(term0);
|
|
2150
|
+
if (k === null) return null;
|
|
2151
|
+
if (key === null) {
|
|
2152
|
+
key = k;
|
|
2153
|
+
prefix = term0;
|
|
2154
|
+
} else if (k !== key) return null;
|
|
2155
|
+
members.push(i);
|
|
2156
|
+
}
|
|
2157
|
+
if (prefix === null || members.length < 2) return null;
|
|
2158
|
+
return { tag: "sharedPrefix", prefix, members };
|
|
2032
2159
|
}
|
|
2033
|
-
function
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2160
|
+
function leadingTermOfArm(arm) {
|
|
2161
|
+
let d = arm._def;
|
|
2162
|
+
for (; ; ) {
|
|
2163
|
+
if (d.tag === "node" || d.tag === "grammar" || d.tag === "transform" || d.tag === "label") {
|
|
2164
|
+
d = d.parser._def;
|
|
2165
|
+
continue;
|
|
2166
|
+
}
|
|
2167
|
+
break;
|
|
2168
|
+
}
|
|
2169
|
+
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
2170
|
+
return d.parsers[0];
|
|
2171
|
+
}
|
|
2172
|
+
function computeAutoNot(parsers) {
|
|
2173
|
+
return parsers.map((p, i) => {
|
|
2174
|
+
const litVal = getCoreLiteralValue(p);
|
|
2175
|
+
if (litVal === null) return null;
|
|
2176
|
+
const checks = [];
|
|
2177
|
+
for (let j = i + 1; j < parsers.length; j++) {
|
|
2178
|
+
const other = parsers[j];
|
|
2179
|
+
const otherLit = getCoreLiteralValue(other);
|
|
2180
|
+
if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
|
|
2181
|
+
checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
|
|
2043
2182
|
continue;
|
|
2044
2183
|
}
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
if (cc === 10 || cc === 13) break;
|
|
2050
|
-
pos++;
|
|
2051
|
-
}
|
|
2052
|
-
continue;
|
|
2184
|
+
const regexDef = getCoreRegexDef(other);
|
|
2185
|
+
if (regexDef !== null) {
|
|
2186
|
+
const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
|
|
2187
|
+
if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
|
|
2053
2188
|
}
|
|
2054
|
-
break;
|
|
2055
2189
|
}
|
|
2056
|
-
return
|
|
2057
|
-
};
|
|
2190
|
+
return checks.length > 0 ? checks : null;
|
|
2191
|
+
});
|
|
2058
2192
|
}
|
|
2059
|
-
function
|
|
2060
|
-
const
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
i++;
|
|
2067
|
-
continue;
|
|
2068
|
-
}
|
|
2069
|
-
if (inClass) {
|
|
2070
|
-
if (c === "]") inClass = false;
|
|
2071
|
-
continue;
|
|
2072
|
-
}
|
|
2073
|
-
if (c === "[") inClass = true;
|
|
2074
|
-
else if (c === "(") return null;
|
|
2075
|
-
else if (c === "|") {
|
|
2076
|
-
arms.push(body.slice(start, i));
|
|
2077
|
-
start = i + 1;
|
|
2193
|
+
function autoNotFires(input, end, checks) {
|
|
2194
|
+
for (const check of checks) {
|
|
2195
|
+
if (check.kind === "firstSet") {
|
|
2196
|
+
const code = end < input.length ? input.codePointAt(end) ?? -1 : -1;
|
|
2197
|
+
if (inFirstSet(code, check.set)) return true;
|
|
2198
|
+
} else {
|
|
2199
|
+
if (input.startsWith(check.value, end)) return true;
|
|
2078
2200
|
}
|
|
2079
2201
|
}
|
|
2080
|
-
|
|
2081
|
-
return arms;
|
|
2202
|
+
return false;
|
|
2082
2203
|
}
|
|
2083
|
-
function
|
|
2084
|
-
const
|
|
2085
|
-
if (!
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
const commentCodes = [];
|
|
2096
|
-
for (const arm of arms) {
|
|
2097
|
-
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
2098
|
-
else commentCodes.push(arm.code);
|
|
2099
|
-
}
|
|
2100
|
-
if (commentCodes.some((code) => inRanges2(code, ranges))) {
|
|
2101
|
-
return loopScanner(arms.map(armScanner));
|
|
2102
|
-
}
|
|
2103
|
-
if (commentCodes.length === 0) return armScanner({ kind: "class", ranges });
|
|
2104
|
-
return fusedTriviaScanner(ranges, commentCodes);
|
|
2204
|
+
function getCoreLiteralValue(p) {
|
|
2205
|
+
const def = p._def;
|
|
2206
|
+
if (def.tag === "literal" && !def.caseInsensitive) return def.value;
|
|
2207
|
+
if (def.tag === "transform") return getCoreLiteralValue(def.parser);
|
|
2208
|
+
return null;
|
|
2209
|
+
}
|
|
2210
|
+
function getCoreRegexDef(p) {
|
|
2211
|
+
const def = p._def;
|
|
2212
|
+
if (def.tag === "regex") return { source: def.source, flags: def.flags };
|
|
2213
|
+
if (def.tag === "transform") return getCoreRegexDef(def.parser);
|
|
2214
|
+
if (def.tag === "label") return getCoreRegexDef(def.parser);
|
|
2215
|
+
return null;
|
|
2105
2216
|
}
|
|
2106
|
-
function
|
|
2107
|
-
|
|
2217
|
+
function applyTransforms(p, value, span) {
|
|
2218
|
+
const def = p._def;
|
|
2219
|
+
if (def.tag === "transform") {
|
|
2220
|
+
const inner = applyTransforms(def.parser, value, span);
|
|
2221
|
+
return def.fn(inner, span);
|
|
2222
|
+
}
|
|
2223
|
+
return value;
|
|
2108
2224
|
}
|
|
2109
|
-
function
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2225
|
+
function continuationFirstSet(lit, source, flags) {
|
|
2226
|
+
const re = new RegExp(source, "y" + flags.replace(/[gy]/g, ""));
|
|
2227
|
+
re.lastIndex = 0;
|
|
2228
|
+
const base = re.exec(lit);
|
|
2229
|
+
if (!base || base[0] !== lit) return null;
|
|
2230
|
+
const contCodes = [];
|
|
2231
|
+
for (let code = 1; code < 128; code++) {
|
|
2232
|
+
re.lastIndex = 0;
|
|
2233
|
+
const m = re.exec(lit + String.fromCharCode(code));
|
|
2234
|
+
if (m && m[0].length > lit.length) contCodes.push(code);
|
|
2235
|
+
}
|
|
2236
|
+
if (contCodes.length === 0) return null;
|
|
2237
|
+
return codesToFirstSet(contCodes);
|
|
2113
2238
|
}
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
const def = { tag: "sequence", parsers };
|
|
2125
|
-
let followSentinels;
|
|
2126
|
-
function parseTolerant(input, pos, ctx) {
|
|
2127
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
2128
|
-
const fs = parsers.slice(i + 1).reduce(
|
|
2129
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
2130
|
-
{ kind: "empty" }
|
|
2131
|
-
);
|
|
2132
|
-
return firstSetSentinel(fs);
|
|
2133
|
-
});
|
|
2134
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2135
|
-
let cur = pos;
|
|
2136
|
-
const inheritedSync = ctx._sync;
|
|
2137
|
-
try {
|
|
2138
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
2139
|
-
ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
2140
|
-
if (ctx.trivia && i > 0) {
|
|
2141
|
-
const mark = saveTriviaMark(ctx);
|
|
2142
|
-
let scanEnd;
|
|
2143
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2144
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
2145
|
-
scan.commit();
|
|
2146
|
-
scanEnd = scan.end;
|
|
2147
|
-
} else {
|
|
2148
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2149
|
-
}
|
|
2150
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2151
|
-
if (!result2.ok) return result2;
|
|
2152
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2153
|
-
else rollbackTrivia(ctx, mark);
|
|
2154
|
-
if (values !== void 0) values.push(result2.value);
|
|
2155
|
-
continue;
|
|
2156
|
-
}
|
|
2157
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2158
|
-
if (!result.ok) return result;
|
|
2159
|
-
if (values !== void 0) values.push(result.value);
|
|
2160
|
-
cur = result.span.end;
|
|
2161
|
-
}
|
|
2162
|
-
} finally {
|
|
2163
|
-
ctx._sync = inheritedSync;
|
|
2239
|
+
function codesToFirstSet(codes) {
|
|
2240
|
+
codes.sort((a, b) => a - b);
|
|
2241
|
+
const ranges = [];
|
|
2242
|
+
let lo = codes[0], hi = codes[0];
|
|
2243
|
+
for (let i = 1; i < codes.length; i++) {
|
|
2244
|
+
if (codes[i] === hi + 1) {
|
|
2245
|
+
hi = codes[i];
|
|
2246
|
+
} else {
|
|
2247
|
+
ranges.push({ lo, hi });
|
|
2248
|
+
lo = hi = codes[i];
|
|
2164
2249
|
}
|
|
2165
|
-
return {
|
|
2166
|
-
ok: true,
|
|
2167
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2168
|
-
value: values ?? void 0,
|
|
2169
|
-
span: { start: pos, end: cur }
|
|
2170
|
-
};
|
|
2171
2250
|
}
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
rollbackTrivia(ctx, mark);
|
|
2197
|
-
}
|
|
2198
|
-
if (values !== void 0) values.push(result2.value);
|
|
2199
|
-
continue;
|
|
2200
|
-
}
|
|
2201
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2202
|
-
if (!result.ok) return result;
|
|
2203
|
-
if (values !== void 0) values.push(result.value);
|
|
2204
|
-
cur = result.span.end;
|
|
2251
|
+
ranges.push({ lo, hi });
|
|
2252
|
+
return { kind: "ranges", ranges };
|
|
2253
|
+
}
|
|
2254
|
+
function inFirstSet(code, fs) {
|
|
2255
|
+
if (fs.kind === "any") return true;
|
|
2256
|
+
if (fs.kind === "empty") return false;
|
|
2257
|
+
for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
2258
|
+
return false;
|
|
2259
|
+
}
|
|
2260
|
+
function areDisjoint(sets) {
|
|
2261
|
+
if (sets.some((s) => s.kind === "any")) return false;
|
|
2262
|
+
for (let i = 0; i < sets.length; i++)
|
|
2263
|
+
for (let j = i + 1; j < sets.length; j++)
|
|
2264
|
+
if (intersects(sets[i], sets[j])) return false;
|
|
2265
|
+
return true;
|
|
2266
|
+
}
|
|
2267
|
+
function buildAsciiDispatch(parsers) {
|
|
2268
|
+
const table = Array(128).fill(-1);
|
|
2269
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2270
|
+
const fs = parsers[i]._meta.firstSet;
|
|
2271
|
+
if (fs.kind !== "ranges") continue;
|
|
2272
|
+
for (const { lo, hi } of fs.ranges) {
|
|
2273
|
+
for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
|
|
2274
|
+
table[code] = i;
|
|
2205
2275
|
}
|
|
2206
|
-
return {
|
|
2207
|
-
ok: true,
|
|
2208
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2209
|
-
value: values ?? void 0,
|
|
2210
|
-
span: { start: pos, end: cur }
|
|
2211
|
-
};
|
|
2212
2276
|
}
|
|
2213
|
-
}
|
|
2277
|
+
}
|
|
2278
|
+
return table;
|
|
2214
2279
|
}
|
|
2215
2280
|
|
|
2216
2281
|
// src/combinators/dispatch.ts
|
|
@@ -2473,10 +2538,12 @@ function attempt(parser2) {
|
|
|
2473
2538
|
}
|
|
2474
2539
|
const mark = saveCstMark(ctx);
|
|
2475
2540
|
const log = ctx._triviaLog?.length;
|
|
2541
|
+
const rootLog = ctx._rootTriviaLog?.length;
|
|
2476
2542
|
const result = parser2.parse(input, pos, ctx);
|
|
2477
2543
|
if (result.ok) return result;
|
|
2478
2544
|
rollbackCstCapture(ctx, mark);
|
|
2479
2545
|
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
2546
|
+
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
2480
2547
|
if (result.committed) return result;
|
|
2481
2548
|
return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
|
|
2482
2549
|
}
|
|
@@ -2917,18 +2984,37 @@ function createParseLineContext(input, pos) {
|
|
|
2917
2984
|
}
|
|
2918
2985
|
function parser(opts, root) {
|
|
2919
2986
|
const clearTrivia = opts.trivia === null;
|
|
2987
|
+
const opaqueRootCapture = opts.rootCapture === "opaque";
|
|
2988
|
+
if (opaqueRootCapture && opts.trivia === void 0) {
|
|
2989
|
+
throw new TypeError("parser({ rootCapture: 'opaque' }) requires an explicit trivia scope.");
|
|
2990
|
+
}
|
|
2920
2991
|
return {
|
|
2921
2992
|
_tag: "grammar",
|
|
2922
|
-
_meta:
|
|
2993
|
+
_meta: {
|
|
2994
|
+
...root._meta,
|
|
2995
|
+
// Trivia classification describes this grammar's own active trivia
|
|
2996
|
+
// scope. A directly nested grammar may have classified trivia of its
|
|
2997
|
+
// own, but that must not advertise classification for this wrapper.
|
|
2998
|
+
triviaKindLabels: void 0,
|
|
2999
|
+
rootTriviaClassified: void 0,
|
|
3000
|
+
...opts.trivia?._meta?.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {},
|
|
3001
|
+
...opts.trivia?._meta?.rootTriviaClassified ? { rootTriviaClassified: true } : {}
|
|
3002
|
+
},
|
|
2923
3003
|
_def: {
|
|
2924
3004
|
tag: "grammar",
|
|
2925
3005
|
parser: root,
|
|
2926
3006
|
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2927
3007
|
clearTrivia,
|
|
3008
|
+
...opaqueRootCapture ? { rootCapture: "opaque" } : {},
|
|
2928
3009
|
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2929
3010
|
trackLines: opts.trackLines ?? false
|
|
2930
3011
|
},
|
|
2931
3012
|
parse(input, pos, _ctx) {
|
|
3013
|
+
if (_ctx?._rootTriviaStrictScopes && opts.trivia !== void 0 && opts.trivia !== null && !opts.trivia._meta.rootTriviaClassified && !opaqueRootCapture) {
|
|
3014
|
+
throw new TypeError(
|
|
3015
|
+
"parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'."
|
|
3016
|
+
);
|
|
3017
|
+
}
|
|
2932
3018
|
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2933
3019
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2934
3020
|
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
@@ -2951,7 +3037,11 @@ function parser(opts, root) {
|
|
|
2951
3037
|
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2952
3038
|
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2953
3039
|
// (capture all).
|
|
2954
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
3040
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {},
|
|
3041
|
+
// This is a property of the local trivia scope, not a post-parse filter:
|
|
3042
|
+
// nested recognition can still skip its trivia, but selected root rows
|
|
3043
|
+
// must never be written for an explicitly opaque region.
|
|
3044
|
+
...opaqueRootCapture ? { _rootTriviaCapture: false } : {}
|
|
2955
3045
|
};
|
|
2956
3046
|
const result = root.parse(input, pos ?? 0, ctx);
|
|
2957
3047
|
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
@@ -3634,6 +3724,25 @@ function trivia(combinator) {
|
|
|
3634
3724
|
parse: combinator.parse.bind(combinator)
|
|
3635
3725
|
};
|
|
3636
3726
|
}
|
|
3727
|
+
function classifiedTrivia(arms) {
|
|
3728
|
+
const entries = Object.entries(arms);
|
|
3729
|
+
if (entries.length === 0) {
|
|
3730
|
+
throw new TypeError("classifiedTrivia() requires at least one named trivia arm.");
|
|
3731
|
+
}
|
|
3732
|
+
for (let i = 0; i < entries.length; i++) {
|
|
3733
|
+
const [name, arm] = entries[i];
|
|
3734
|
+
const first = arm._meta.firstSet;
|
|
3735
|
+
if (matchesEmpty(arm) || first.kind !== "ranges" || first.ranges.length === 0) {
|
|
3736
|
+
throw new TypeError(
|
|
3737
|
+
`classifiedTrivia(): ${JSON.stringify(name)} must be non-nullable with a concrete finite first set.`
|
|
3738
|
+
);
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3741
|
+
const labeledArms = entries.map(([name, arm]) => label(name, arm));
|
|
3742
|
+
const result = trivia(oneOrMore(choice(...labeledArms)));
|
|
3743
|
+
result._meta.rootTriviaClassified = true;
|
|
3744
|
+
return result;
|
|
3745
|
+
}
|
|
3637
3746
|
function label(name, combinator) {
|
|
3638
3747
|
return {
|
|
3639
3748
|
_tag: combinator._tag,
|
|
@@ -3680,6 +3789,7 @@ function token(root) {
|
|
|
3680
3789
|
const savedRaw = ctx._cstRawChildren;
|
|
3681
3790
|
const savedTriviaLog = ctx._cstTriviaLog;
|
|
3682
3791
|
const savedOuterTriviaLog = ctx._triviaLog;
|
|
3792
|
+
const savedRootTriviaLog = ctx._rootTriviaLog;
|
|
3683
3793
|
const wasCapturing = cstCaptureActive(ctx);
|
|
3684
3794
|
ctx.trivia = void 0;
|
|
3685
3795
|
ctx.triviaKindLabels = void 0;
|
|
@@ -3689,6 +3799,7 @@ function token(root) {
|
|
|
3689
3799
|
ctx._cstRawChildren = void 0;
|
|
3690
3800
|
ctx._cstTriviaLog = void 0;
|
|
3691
3801
|
delete ctx._triviaLog;
|
|
3802
|
+
delete ctx._rootTriviaLog;
|
|
3692
3803
|
let result;
|
|
3693
3804
|
try {
|
|
3694
3805
|
result = root.parse(input, pos, ctx);
|
|
@@ -3702,6 +3813,8 @@ function token(root) {
|
|
|
3702
3813
|
ctx._cstTriviaLog = savedTriviaLog;
|
|
3703
3814
|
if (savedOuterTriviaLog === void 0) delete ctx._triviaLog;
|
|
3704
3815
|
else ctx._triviaLog = savedOuterTriviaLog;
|
|
3816
|
+
if (savedRootTriviaLog === void 0) delete ctx._rootTriviaLog;
|
|
3817
|
+
else ctx._rootTriviaLog = savedRootTriviaLog;
|
|
3705
3818
|
}
|
|
3706
3819
|
if (!result.ok) return result;
|
|
3707
3820
|
const span = result.span;
|
|
@@ -3756,7 +3869,7 @@ function leaf(root, fn) {
|
|
|
3756
3869
|
}
|
|
3757
3870
|
|
|
3758
3871
|
// src/version.ts
|
|
3759
|
-
var PARSEMAN_VERSION = "0.
|
|
3872
|
+
var PARSEMAN_VERSION = "0.44.0";
|
|
3760
3873
|
|
|
3761
3874
|
// src/cst/host-mode.ts
|
|
3762
3875
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -5654,9 +5767,196 @@ function buildGrammarPlan(entry, winners) {
|
|
|
5654
5767
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
|
|
5655
5768
|
}
|
|
5656
5769
|
|
|
5770
|
+
// src/cst/trivia-entries.ts
|
|
5771
|
+
var EMPTY_INDICES = Object.freeze([]);
|
|
5772
|
+
var EMPTY_GAPS = Object.freeze([]);
|
|
5773
|
+
var SELECTED_ROOT_STRIDE = 5;
|
|
5774
|
+
function entryOffset(i, stride) {
|
|
5775
|
+
return i * stride;
|
|
5776
|
+
}
|
|
5777
|
+
function triviaEntries(log, labels, opts) {
|
|
5778
|
+
const baseStride = opts?.nodeLog ? 3 : 2;
|
|
5779
|
+
const stride = labels ? baseStride + 1 : baseStride;
|
|
5780
|
+
const length = Math.floor(log.length / stride);
|
|
5781
|
+
return {
|
|
5782
|
+
length,
|
|
5783
|
+
labels,
|
|
5784
|
+
stride,
|
|
5785
|
+
start(i) {
|
|
5786
|
+
return log[entryOffset(i, stride)];
|
|
5787
|
+
},
|
|
5788
|
+
end(i) {
|
|
5789
|
+
return log[entryOffset(i, stride) + 1];
|
|
5790
|
+
},
|
|
5791
|
+
insertIndex(i) {
|
|
5792
|
+
return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
|
|
5793
|
+
},
|
|
5794
|
+
kindIndex(i) {
|
|
5795
|
+
if (!labels) return void 0;
|
|
5796
|
+
return log[entryOffset(i, stride) + baseStride];
|
|
5797
|
+
},
|
|
5798
|
+
kind(i) {
|
|
5799
|
+
const ki = labels ? log[entryOffset(i, stride) + baseStride] : void 0;
|
|
5800
|
+
return ki !== void 0 ? labels[ki] : void 0;
|
|
5801
|
+
},
|
|
5802
|
+
text(i, input) {
|
|
5803
|
+
const s = log[entryOffset(i, stride)];
|
|
5804
|
+
const e = log[entryOffset(i, stride) + 1];
|
|
5805
|
+
return input.slice(s, e);
|
|
5806
|
+
}
|
|
5807
|
+
};
|
|
5808
|
+
}
|
|
5809
|
+
function buildRootTriviaIndex(log, labels) {
|
|
5810
|
+
const length = Math.floor(log.length / SELECTED_ROOT_STRIDE);
|
|
5811
|
+
const markerOffset = (i) => i * SELECTED_ROOT_STRIDE;
|
|
5812
|
+
const ownedRangeStart = (i) => log[markerOffset(i)];
|
|
5813
|
+
const ownedRangeEnd = (i) => log[markerOffset(i) + 1];
|
|
5814
|
+
const markerStart = (i) => log[markerOffset(i) + 2];
|
|
5815
|
+
const markerEnd = (i) => log[markerOffset(i) + 3];
|
|
5816
|
+
const markerKind = (i) => log[markerOffset(i) + 4];
|
|
5817
|
+
const entries = {
|
|
5818
|
+
length,
|
|
5819
|
+
labels,
|
|
5820
|
+
stride: SELECTED_ROOT_STRIDE,
|
|
5821
|
+
start: markerStart,
|
|
5822
|
+
end: markerEnd,
|
|
5823
|
+
insertIndex: () => void 0,
|
|
5824
|
+
kindIndex: markerKind,
|
|
5825
|
+
kind(i) {
|
|
5826
|
+
return labels[markerKind(i)];
|
|
5827
|
+
},
|
|
5828
|
+
text(i, input) {
|
|
5829
|
+
return input.slice(markerStart(i), markerEnd(i));
|
|
5830
|
+
}
|
|
5831
|
+
};
|
|
5832
|
+
const lowerBound = (offset, by) => {
|
|
5833
|
+
let lo = 0;
|
|
5834
|
+
let hi = length;
|
|
5835
|
+
while (lo < hi) {
|
|
5836
|
+
const mid = lo + hi >>> 1;
|
|
5837
|
+
if (by(mid) < offset) lo = mid + 1;
|
|
5838
|
+
else hi = mid;
|
|
5839
|
+
}
|
|
5840
|
+
return lo;
|
|
5841
|
+
};
|
|
5842
|
+
const gapRowsAt = (offset, direction) => {
|
|
5843
|
+
const edge = direction === "before" ? ownedRangeEnd : ownedRangeStart;
|
|
5844
|
+
let first = lowerBound(offset, edge);
|
|
5845
|
+
if (first === length || edge(first) !== offset) return void 0;
|
|
5846
|
+
const start = ownedRangeStart(first);
|
|
5847
|
+
const end = ownedRangeEnd(first);
|
|
5848
|
+
while (first > 0 && ownedRangeStart(first - 1) === start && ownedRangeEnd(first - 1) === end) first--;
|
|
5849
|
+
let last = first + 1;
|
|
5850
|
+
while (last < length && ownedRangeStart(last) === start && ownedRangeEnd(last) === end) last++;
|
|
5851
|
+
return [first, last];
|
|
5852
|
+
};
|
|
5853
|
+
const indices = (first, last) => {
|
|
5854
|
+
const out = [];
|
|
5855
|
+
for (let i = first; i < last; i++) out.push(i);
|
|
5856
|
+
return out;
|
|
5857
|
+
};
|
|
5858
|
+
const makeGap = (first, last) => {
|
|
5859
|
+
const start = ownedRangeStart(first);
|
|
5860
|
+
const end = ownedRangeEnd(first);
|
|
5861
|
+
let entryIndices;
|
|
5862
|
+
return {
|
|
5863
|
+
start,
|
|
5864
|
+
end,
|
|
5865
|
+
get entryIndices() {
|
|
5866
|
+
return entryIndices ??= indices(first, last);
|
|
5867
|
+
},
|
|
5868
|
+
hasKind(kind) {
|
|
5869
|
+
for (let i = first; i < last; i++) {
|
|
5870
|
+
if (labels[markerKind(i)] === kind) return true;
|
|
5871
|
+
}
|
|
5872
|
+
return false;
|
|
5873
|
+
},
|
|
5874
|
+
text(input) {
|
|
5875
|
+
return input.slice(start, end);
|
|
5876
|
+
}
|
|
5877
|
+
};
|
|
5878
|
+
};
|
|
5879
|
+
let maps;
|
|
5880
|
+
const getMaps = () => {
|
|
5881
|
+
if (maps !== void 0) return maps;
|
|
5882
|
+
const before = /* @__PURE__ */ new Map();
|
|
5883
|
+
const after = /* @__PURE__ */ new Map();
|
|
5884
|
+
const beforeGaps = /* @__PURE__ */ new Map();
|
|
5885
|
+
const afterGaps = /* @__PURE__ */ new Map();
|
|
5886
|
+
const gaps = [];
|
|
5887
|
+
for (let first = 0; first < length; ) {
|
|
5888
|
+
let last = first + 1;
|
|
5889
|
+
while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
|
|
5890
|
+
const gap = makeGap(first, last);
|
|
5891
|
+
gaps.push(gap);
|
|
5892
|
+
afterGaps.set(gap.start, gap);
|
|
5893
|
+
beforeGaps.set(gap.end, gap);
|
|
5894
|
+
after.set(gap.start, [...gap.entryIndices]);
|
|
5895
|
+
before.set(gap.end, [...gap.entryIndices]);
|
|
5896
|
+
first = last;
|
|
5897
|
+
}
|
|
5898
|
+
maps = { before, after, beforeGaps, afterGaps, gaps };
|
|
5899
|
+
return maps;
|
|
5900
|
+
};
|
|
5901
|
+
return {
|
|
5902
|
+
entries,
|
|
5903
|
+
labels,
|
|
5904
|
+
get before() {
|
|
5905
|
+
return getMaps().before;
|
|
5906
|
+
},
|
|
5907
|
+
get after() {
|
|
5908
|
+
return getMaps().after;
|
|
5909
|
+
},
|
|
5910
|
+
entryIndicesBefore(offset) {
|
|
5911
|
+
const rows = gapRowsAt(offset, "before");
|
|
5912
|
+
return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
|
|
5913
|
+
},
|
|
5914
|
+
entryIndicesAfter(offset) {
|
|
5915
|
+
const rows = gapRowsAt(offset, "after");
|
|
5916
|
+
return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
|
|
5917
|
+
},
|
|
5918
|
+
gapBefore(offset) {
|
|
5919
|
+
const rows = gapRowsAt(offset, "before");
|
|
5920
|
+
return rows ? makeGap(rows[0], rows[1]) : void 0;
|
|
5921
|
+
},
|
|
5922
|
+
gapAfter(offset) {
|
|
5923
|
+
const rows = gapRowsAt(offset, "after");
|
|
5924
|
+
return rows ? makeGap(rows[0], rows[1]) : void 0;
|
|
5925
|
+
},
|
|
5926
|
+
gaps() {
|
|
5927
|
+
return getMaps().gaps;
|
|
5928
|
+
},
|
|
5929
|
+
gapsWithKind(kind) {
|
|
5930
|
+
const kinds = typeof kind === "string" ? [kind] : kind;
|
|
5931
|
+
const matches2 = [];
|
|
5932
|
+
for (let first = 0; first < length; ) {
|
|
5933
|
+
let last = first + 1;
|
|
5934
|
+
while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
|
|
5935
|
+
let matched = false;
|
|
5936
|
+
for (let i = first; i < last && !matched; i++) {
|
|
5937
|
+
const label2 = labels[markerKind(i)];
|
|
5938
|
+
for (const kind2 of kinds) {
|
|
5939
|
+
if (label2 === kind2) {
|
|
5940
|
+
matched = true;
|
|
5941
|
+
break;
|
|
5942
|
+
}
|
|
5943
|
+
}
|
|
5944
|
+
}
|
|
5945
|
+
if (matched) matches2.push(makeGap(first, last));
|
|
5946
|
+
first = last;
|
|
5947
|
+
}
|
|
5948
|
+
return matches2.length === 0 ? EMPTY_GAPS : matches2;
|
|
5949
|
+
}
|
|
5950
|
+
};
|
|
5951
|
+
}
|
|
5952
|
+
|
|
5657
5953
|
// src/compiler/scannable-run.ts
|
|
5658
5954
|
var BACKSLASH = 92;
|
|
5659
5955
|
var META = new Set("()[]{}*+?|^$.".split(""));
|
|
5956
|
+
var SELECTED_ROOT_OWNED_RANGE_PLACEHOLDER = Array.from(
|
|
5957
|
+
{ length: SELECTED_ROOT_STRIDE - 3 },
|
|
5958
|
+
() => "0"
|
|
5959
|
+
).join(", ");
|
|
5660
5960
|
function classToRanges(cls) {
|
|
5661
5961
|
if (cls === "\\d") return shorthandRanges("d");
|
|
5662
5962
|
if (cls === "\\w") return shorthandRanges("w");
|
|
@@ -6695,13 +6995,15 @@ function scanBranch(shape, mint) {
|
|
|
6695
6995
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6696
6996
|
return [...m.setup, ` if (${m.end} > _e) { _e = ${m.end}; continue }`].join("\n");
|
|
6697
6997
|
}
|
|
6698
|
-
function scanBranchLabeled(shape, kindIndex, mint) {
|
|
6998
|
+
function scanBranchLabeled(shape, kindIndex, label2, mint) {
|
|
6699
6999
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6700
7000
|
return [
|
|
6701
7001
|
...m.setup,
|
|
6702
7002
|
` if (${m.end} > _e) {`,
|
|
6703
7003
|
` if (_cap) {`,
|
|
6704
7004
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, ${m.end}, ${kindIndex})`,
|
|
7005
|
+
` const _rk = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(label2)}] ?? -1)`,
|
|
7006
|
+
` if (_rk >= 0) _ctx._rootTriviaLog.push(${SELECTED_ROOT_OWNED_RANGE_PLACEHOLDER}, _e, ${m.end}, _rk)`,
|
|
6705
7007
|
` 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})`,
|
|
6706
7008
|
` }`,
|
|
6707
7009
|
` _e = ${m.end}`,
|
|
@@ -6761,6 +7063,11 @@ var CAP_RECORD = [
|
|
|
6761
7063
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
|
|
6762
7064
|
` }`
|
|
6763
7065
|
].join("\n");
|
|
7066
|
+
var SELECTED_ROOT_FINISH = [
|
|
7067
|
+
` if (_cap && _ctx._rootTriviaCapture !== false && _ctx._rootTriviaLog !== undefined && _ctx._rootTriviaLog.length !== _rootMark) {`,
|
|
7068
|
+
` for (let _ri = _rootMark; _ri < _ctx._rootTriviaLog.length; _ri += ${SELECTED_ROOT_STRIDE}) { _ctx._rootTriviaLog[_ri] = _pos; _ctx._rootTriviaLog[_ri + 1] = _e }`,
|
|
7069
|
+
` }`
|
|
7070
|
+
].join("\n");
|
|
6764
7071
|
function composeFastLoop(shapes) {
|
|
6765
7072
|
const mint = makeMint();
|
|
6766
7073
|
return [
|
|
@@ -6789,7 +7096,7 @@ function analyzeLabeledScannableRun(trivia2) {
|
|
|
6789
7096
|
const d = getCoreRegexDef(arm.parser);
|
|
6790
7097
|
const shape = d ? scanShapeFromRegex(d.source, d.flags) : null;
|
|
6791
7098
|
if (!shape) return null;
|
|
6792
|
-
out.push({ shape, kindIndex: arm.kindIndex });
|
|
7099
|
+
out.push({ shape, kindIndex: arm.kindIndex, label: arm.label });
|
|
6793
7100
|
}
|
|
6794
7101
|
return out;
|
|
6795
7102
|
}
|
|
@@ -6798,11 +7105,13 @@ function buildLabeledScannableTriviaFnDecl(fnName, arms) {
|
|
|
6798
7105
|
return [
|
|
6799
7106
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6800
7107
|
` let _e = _pos`,
|
|
7108
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6801
7109
|
` while (_e < input.length) {`,
|
|
6802
7110
|
` const c = input.charCodeAt(_e)`,
|
|
6803
|
-
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, mint)),
|
|
7111
|
+
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, a.label, mint)),
|
|
6804
7112
|
` break`,
|
|
6805
7113
|
` }`,
|
|
7114
|
+
SELECTED_ROOT_FINISH,
|
|
6806
7115
|
` return _e`,
|
|
6807
7116
|
`}`
|
|
6808
7117
|
].join("\n");
|
|
@@ -6818,6 +7127,8 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6818
7127
|
` const _ce = _e + _m${i}[0].length`,
|
|
6819
7128
|
` if (_cap) {`,
|
|
6820
7129
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
|
|
7130
|
+
` const _rk${i} = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(arm.label)}] ?? -1)`,
|
|
7131
|
+
` if (_rk${i} >= 0) _ctx._rootTriviaLog.push(0, 0, _e, _ce, _rk${i})`,
|
|
6821
7132
|
` 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})`,
|
|
6822
7133
|
` }`,
|
|
6823
7134
|
` _e = _ce`,
|
|
@@ -6829,11 +7140,13 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6829
7140
|
return [
|
|
6830
7141
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6831
7142
|
` let _e = _pos`,
|
|
7143
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6832
7144
|
` while (_e < input.length) {`,
|
|
6833
7145
|
` let _matched = false`,
|
|
6834
7146
|
tryArms,
|
|
6835
7147
|
` if (!_matched) break`,
|
|
6836
7148
|
` }`,
|
|
7149
|
+
SELECTED_ROOT_FINISH,
|
|
6837
7150
|
` return _e`,
|
|
6838
7151
|
`}`
|
|
6839
7152
|
].join("\n");
|
|
@@ -6856,6 +7169,8 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6856
7169
|
` const _ce = _r${i}.span.end`,
|
|
6857
7170
|
` if (_cap) {`,
|
|
6858
7171
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
|
|
7172
|
+
` const _rk${i} = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(arm.label)}] ?? -1)`,
|
|
7173
|
+
` if (_rk${i} >= 0) _ctx._rootTriviaLog.push(0, 0, _e, _ce, _rk${i})`,
|
|
6859
7174
|
` 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})`,
|
|
6860
7175
|
` }`,
|
|
6861
7176
|
` _e = _ce`,
|
|
@@ -6867,11 +7182,13 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6867
7182
|
return [
|
|
6868
7183
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6869
7184
|
` let _e = _pos`,
|
|
7185
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6870
7186
|
` while (_e < input.length) {`,
|
|
6871
7187
|
` let _matched = false`,
|
|
6872
7188
|
tryArms,
|
|
6873
7189
|
` if (!_matched) break`,
|
|
6874
7190
|
` }`,
|
|
7191
|
+
SELECTED_ROOT_FINISH,
|
|
6875
7192
|
` return _e`,
|
|
6876
7193
|
`}`
|
|
6877
7194
|
].join("\n");
|
|
@@ -7094,6 +7411,9 @@ var HOST_READS_DECL = "const _hostReads = (b, n) => { if (b === undefined) retur
|
|
|
7094
7411
|
var LINE_TRACK_DECL = "const _trackLines = (_ctx, input, start, end) => { const from = _ctx._lineScannedTo ?? 0; if (end <= from) return; for (let i = from; i < end; i++) if (input.charCodeAt(i) === 10) _ctx._lineStarts.push(i + 1); _ctx._lineScannedTo = end }";
|
|
7095
7412
|
var LINE_SPAN_DECL = "const _lineCol = (_ctx, offset) => { const starts = _ctx._lineStarts; let lo = 0, hi = starts.length - 1; while (lo < hi) { const mid = (lo + hi + 1) >> 1; if (starts[mid] <= offset) lo = mid; else hi = mid - 1 } return [lo + 1, offset - starts[lo] + 1] }\nconst _spanLines = (_ctx, start, end) => { const s = _lineCol(_ctx, start), e = _lineCol(_ctx, end); return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] } }";
|
|
7096
7413
|
var _loweringSink = null;
|
|
7414
|
+
function hasSelectedRootTrivia(ctx) {
|
|
7415
|
+
return ctx.rootTriviaClassified === true;
|
|
7416
|
+
}
|
|
7097
7417
|
function v(ctx, prefix = "_v") {
|
|
7098
7418
|
return `${prefix}${ctx.vars++}`;
|
|
7099
7419
|
}
|
|
@@ -7403,10 +7723,12 @@ function planDisjointDispatch(parsers) {
|
|
|
7403
7723
|
}
|
|
7404
7724
|
return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
7405
7725
|
}
|
|
7406
|
-
function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
|
|
7726
|
+
function captureRestoreBody(ctx, mL, mR, mTl, mLg, mF = null, mRootLg = null) {
|
|
7407
7727
|
const fieldRestore = mF ? `; if (_ctx._fields && _ctx._fields.length !== ${mF}) _ctx._fields.length = ${mF}` : "";
|
|
7408
7728
|
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}`;
|
|
7409
|
-
|
|
7729
|
+
const logRestore = mLg ? `; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${mLg}) _ctx._triviaLog.length = ${mLg}` : "";
|
|
7730
|
+
const rootLogRestore = hasSelectedRootTrivia(ctx) && mRootLg ? `; if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${mRootLg}) _ctx._rootTriviaLog.length = ${mRootLg}` : "";
|
|
7731
|
+
return `${base}${logRestore}${rootLogRestore}`;
|
|
7410
7732
|
}
|
|
7411
7733
|
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
7412
7734
|
if (seen.has(p)) return false;
|
|
@@ -7616,7 +7938,7 @@ function emitFallible(inner, ctx, pos, swallow = false) {
|
|
|
7616
7938
|
`${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
|
|
7617
7939
|
`${ind0}}`,
|
|
7618
7940
|
...mL ? [
|
|
7619
|
-
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
|
|
7941
|
+
`${ind0}if (!${okV}) { ${captureRestoreBody(ctx, mL, mR, mTl, null, mF)} }`
|
|
7620
7942
|
] : []
|
|
7621
7943
|
];
|
|
7622
7944
|
return { stmts, okVar: okV, valVar: valV, endVar: endV, mayCommit };
|
|
@@ -7813,11 +8135,13 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7813
8135
|
const markV = v(ctx, "_mk");
|
|
7814
8136
|
const markTl = v(ctx, "_mktl");
|
|
7815
8137
|
const markLog = v(ctx, "_mklg");
|
|
8138
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7816
8139
|
const scanEndV = v(ctx, "_sne");
|
|
7817
8140
|
stmts.push(
|
|
7818
8141
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7819
8142
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7820
8143
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8144
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7821
8145
|
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7822
8146
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7823
8147
|
);
|
|
@@ -7826,17 +8150,19 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7826
8150
|
const endAfterV = v(ctx, "_sea");
|
|
7827
8151
|
stmts.push(
|
|
7828
8152
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7829
|
-
`${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}
|
|
8153
|
+
`${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};` : ""} }`
|
|
7830
8154
|
);
|
|
7831
8155
|
valueVars.push(r2.valueVar);
|
|
7832
8156
|
continue;
|
|
7833
8157
|
} else {
|
|
7834
8158
|
const trivFn = ensureTriviaFn(ctx);
|
|
7835
8159
|
const markLog = v(ctx, "_mklg");
|
|
8160
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7836
8161
|
const scanEndV = v(ctx, "_sne");
|
|
7837
|
-
const capArg = ctx.noHoist ? "0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
8162
|
+
const capArg = ctx.noHoist ? "0" : hasSelectedRootTrivia(ctx) ? "(_ctx._triviaLog !== undefined || _ctx._rootTriviaLog !== undefined) ? 2 : 0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7838
8163
|
stmts.push(
|
|
7839
8164
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8165
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7840
8166
|
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7841
8167
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7842
8168
|
);
|
|
@@ -7845,7 +8171,7 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7845
8171
|
const endAfterV = v(ctx, "_sea");
|
|
7846
8172
|
stmts.push(
|
|
7847
8173
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7848
|
-
`${ind(ctx)}if (${endAfterV} > ${scanEndV}) ${curV} = ${endAfterV}; else if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}`
|
|
8174
|
+
`${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};` : ""} }`
|
|
7849
8175
|
);
|
|
7850
8176
|
valueVars.push(r2.valueVar);
|
|
7851
8177
|
continue;
|
|
@@ -8087,6 +8413,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
8087
8413
|
const selectorRawMark = selectorNeedsRollback ? v(ctx, "_dsr") : null;
|
|
8088
8414
|
const selectorTriviaMark = selectorNeedsRollback ? v(ctx, "_dst") : null;
|
|
8089
8415
|
const selectorLogMark = selectorNeedsRollback ? v(ctx, "_dsg") : null;
|
|
8416
|
+
const selectorRootLogMark = selectorNeedsRollback && hasSelectedRootTrivia(ctx) ? v(ctx, "_dsrg") : null;
|
|
8090
8417
|
const selectorFieldMark = selectorNeedsRollback ? v(ctx, "_dsf") : null;
|
|
8091
8418
|
const selectorErrorMark = selectorNeedsRollback ? v(ctx, "_dse") : null;
|
|
8092
8419
|
const selector = emit(def.selector, ctx, pos);
|
|
@@ -8099,6 +8426,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
8099
8426
|
`${ind(ctx)}const ${selectorRawMark} = _ctx._cstRawChildren?.length ?? 0`,
|
|
8100
8427
|
`${ind(ctx)}const ${selectorTriviaMark} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
8101
8428
|
`${ind(ctx)}const ${selectorLogMark} = _ctx._triviaLog?.length ?? 0`,
|
|
8429
|
+
...selectorRootLogMark ? [`${ind(ctx)}const ${selectorRootLogMark} = _ctx._rootTriviaLog?.length ?? 0`] : [],
|
|
8102
8430
|
`${ind(ctx)}const ${selectorFieldMark} = _ctx._fields?.length ?? 0`,
|
|
8103
8431
|
`${ind(ctx)}const ${selectorErrorMark} = _ctx._errors?.length ?? 0`
|
|
8104
8432
|
] : [],
|
|
@@ -8118,16 +8446,18 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
8118
8446
|
const mayError = mayRecordRecoveryError(parser3, !!ctx.recovery);
|
|
8119
8447
|
const errMark = mayError ? v(ctx, "_derr") : null;
|
|
8120
8448
|
const logMark = ctx.activeTrivia ? v(ctx, "_dlog") : null;
|
|
8449
|
+
const rootLogMark = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_drlog") : null;
|
|
8121
8450
|
if (usesRouted) {
|
|
8122
8451
|
stmts.push(
|
|
8123
8452
|
...routedV ? [`${ind(ctx)}const ${routedV} = _ctx._routed; _ctx._routed = { value: ${selector.valueVar}, span: { start: ${pos}, end: ${selector.endVar} } }`] : [],
|
|
8124
8453
|
...selectorLeafMark ? [
|
|
8125
|
-
`${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}
|
|
8454
|
+
`${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}`
|
|
8126
8455
|
] : []
|
|
8127
8456
|
);
|
|
8128
8457
|
}
|
|
8129
8458
|
if (errMark) stmts.push(`${ind(ctx)}const ${errMark} = _ctx._errors?.length ?? 0`);
|
|
8130
8459
|
if (logMark) stmts.push(`${ind(ctx)}const ${logMark} = _ctx._triviaLog?.length ?? 0`);
|
|
8460
|
+
if (rootLogMark) stmts.push(`${ind(ctx)}const ${rootLogMark} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
8131
8461
|
const savedRoutedLocal = ctx.routedLocal;
|
|
8132
8462
|
const savedNoHoist = ctx.noHoist;
|
|
8133
8463
|
if (usesRouted && !needsRoutedContext) {
|
|
@@ -8142,11 +8472,12 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
8142
8472
|
stmts.push(...coverageAttempt(ctx, coverageId, pos));
|
|
8143
8473
|
const errorRollback = errMark ? `if (_ctx._errors && _ctx._errors.length !== ${errMark}) _ctx._errors.length = ${errMark}; ` : "";
|
|
8144
8474
|
const logRollback = logMark ? `if (_ctx._triviaLog && _ctx._triviaLog.length !== ${logMark}) _ctx._triviaLog.length = ${logMark}; ` : "";
|
|
8475
|
+
const rootLogRollback = rootLogMark ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${rootLogMark}) _ctx._rootTriviaLog.length = ${rootLogMark}; ` : "";
|
|
8145
8476
|
const routedRollback = routedV ? `_ctx._routed = ${routedV}; ` : "";
|
|
8146
8477
|
const coverageFailure = coverageId === void 0 ? "" : `_ctx._grammarTrace?.write({ id: ${JSON.stringify(coverageId)}, phase: 'failure', offset: _ctx._fe }); `;
|
|
8147
8478
|
stmts.push(
|
|
8148
8479
|
...tail.stmts,
|
|
8149
|
-
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8480
|
+
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${rootLogRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8150
8481
|
...routedV ? [`${ind(ctx)}_ctx._routed = ${routedV}`] : [],
|
|
8151
8482
|
`${ind(ctx)}${outV} = ${valueMode === "tail" ? tail.valVar : `[${selector.valueVar}, ${tail.valVar}]`}`,
|
|
8152
8483
|
`${ind(ctx)}${outE} = ${tail.endVar}`,
|
|
@@ -8327,11 +8658,13 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8327
8658
|
const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
|
|
8328
8659
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
8329
8660
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
8661
|
+
const markRootLog = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_cmlrg") : null;
|
|
8330
8662
|
const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
|
|
8331
8663
|
const markErrors = armMayRecordError ? v(ctx, "_cme") : null;
|
|
8332
|
-
const captureRollback = markLeaves ? captureRestoreBody(markLeaves, markRaw, markTl, markLog, markFields) : "";
|
|
8664
|
+
const captureRollback = markLeaves ? captureRestoreBody(ctx, markLeaves, markRaw, markTl, markLog, markFields, markRootLog) : "";
|
|
8665
|
+
const rootRollback = markRootLog && !markLeaves ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}` : "";
|
|
8333
8666
|
const errorRollback = markErrors ? `if (_ctx._errors && _ctx._errors.length !== ${markErrors}) _ctx._errors.length = ${markErrors}` : "";
|
|
8334
|
-
const rollback = [captureRollback, errorRollback].filter(Boolean).join("; ");
|
|
8667
|
+
const rollback = [captureRollback, rootRollback, errorRollback].filter(Boolean).join("; ");
|
|
8335
8668
|
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
8336
8669
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
8337
8670
|
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
@@ -8346,6 +8679,7 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8346
8679
|
...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
|
|
8347
8680
|
);
|
|
8348
8681
|
}
|
|
8682
|
+
if (markRootLog) stmts.push(`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
8349
8683
|
if (markErrors) stmts.push(`${ind(ctx)}const ${markErrors} = _ctx._errors?.length ?? 0`);
|
|
8350
8684
|
const arm = emitFallible(p, ctx, pos, atStart);
|
|
8351
8685
|
const { stmts: armStmts, okVar, valVar, endVar } = arm;
|
|
@@ -8533,21 +8867,29 @@ function emitMany(def, ctx, pos) {
|
|
|
8533
8867
|
const markV = v(ctx, "_mk");
|
|
8534
8868
|
const markTl = v(ctx, "_mktl");
|
|
8535
8869
|
const markLog = v(ctx, "_mklg");
|
|
8870
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8536
8871
|
const npV = v(ctx, "_np");
|
|
8537
8872
|
stmts.push(
|
|
8538
8873
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8539
8874
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8540
8875
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8876
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8541
8877
|
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8542
8878
|
...emitLineTrack(ctx, curV, npV)
|
|
8543
8879
|
);
|
|
8544
8880
|
itemPos = npV;
|
|
8545
|
-
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}
|
|
8881
|
+
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};` : ""} `;
|
|
8546
8882
|
} else {
|
|
8547
8883
|
const trivFn = ensureTriviaFn(ctx);
|
|
8884
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8548
8885
|
const npV = v(ctx, "_np");
|
|
8549
|
-
stmts.push(
|
|
8886
|
+
stmts.push(
|
|
8887
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8888
|
+
`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8889
|
+
...emitLineTrack(ctx, curV, npV)
|
|
8890
|
+
);
|
|
8550
8891
|
itemPos = npV;
|
|
8892
|
+
rollback = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8551
8893
|
}
|
|
8552
8894
|
}
|
|
8553
8895
|
if (!ctx.recovery && !ctx.coverage && !failsAtStart(def.parser) && needsFirstSetGuard(def.parser)) {
|
|
@@ -8607,9 +8949,10 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8607
8949
|
const raw = v(ctx, "_atr");
|
|
8608
8950
|
const trivia2 = v(ctx, "_att");
|
|
8609
8951
|
const log = v(ctx, "_atg");
|
|
8952
|
+
const rootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_atrg") : null;
|
|
8610
8953
|
const fields = v(ctx, "_atf");
|
|
8611
8954
|
const errors = v(ctx, "_ate");
|
|
8612
|
-
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}
|
|
8955
|
+
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}`;
|
|
8613
8956
|
const traceId = ctx.coverage?.plan.attempts.get(p);
|
|
8614
8957
|
const traceRollback = traceId === void 0 ? "" : ` _ctx._grammarTrace?.write({ id: ${JSON.stringify(traceId)}, phase: 'rollback', offset: ${pos} });`;
|
|
8615
8958
|
const preGuard = [];
|
|
@@ -8625,7 +8968,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8625
8968
|
return {
|
|
8626
8969
|
stmts: [
|
|
8627
8970
|
...preGuard,
|
|
8628
|
-
`${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`,
|
|
8971
|
+
`${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`,
|
|
8629
8972
|
...inner.stmts,
|
|
8630
8973
|
...emitIfFail(ctx, `!${inner.okVar}`, `{ ${rollback};${traceRollback}${inner.mayCommit ? ` if (_ctx._fc) ${committedFailBody(ctx)};` : ""} _ctx._fe = ${pos}; ${propagateFailBody(ctx)} }`)
|
|
8631
8974
|
],
|
|
@@ -8667,16 +9010,17 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8667
9010
|
const itemFailBreak = (sepEndVar, sepRb, postSepRb) => def.trailing === void 0 ? `${sepRb}break` : `${postSepRb}${curV} = ${sepEndVar}; break`;
|
|
8668
9011
|
const postSepMarks = () => {
|
|
8669
9012
|
if (def.trailing === void 0 || !ctx.capturing) return { decl: [], rb: "" };
|
|
8670
|
-
const lv = v(ctx, "_tlv"), rw = v(ctx, "_trw"), tl = v(ctx, "_ttl"), lg = v(ctx, "_tlg"), fl = v(ctx, "_tlf");
|
|
9013
|
+
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");
|
|
8671
9014
|
return {
|
|
8672
9015
|
decl: [
|
|
8673
9016
|
`${ind(ctx)}const ${lv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8674
9017
|
`${ind(ctx)}const ${rw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8675
9018
|
`${ind(ctx)}const ${tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8676
9019
|
`${ind(ctx)}const ${lg} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
9020
|
+
...rlg ? [`${ind(ctx)}const ${rlg} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8677
9021
|
`${ind(ctx)}const ${fl} = _ctx._fields ? _ctx._fields.length : 0`
|
|
8678
9022
|
],
|
|
8679
|
-
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}
|
|
9023
|
+
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}; `
|
|
8680
9024
|
};
|
|
8681
9025
|
};
|
|
8682
9026
|
if (rec) {
|
|
@@ -8714,6 +9058,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8714
9058
|
const markV = v(ctx, "_mk");
|
|
8715
9059
|
const markTl = v(ctx, "_mktl");
|
|
8716
9060
|
const markLog = v(ctx, "_mklg");
|
|
9061
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8717
9062
|
const markLv = v(ctx, "_mklv");
|
|
8718
9063
|
const markFld = v(ctx, "_mkf");
|
|
8719
9064
|
const spV = v(ctx, "_sp");
|
|
@@ -8721,13 +9066,14 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8721
9066
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8722
9067
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8723
9068
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
9069
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8724
9070
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8725
9071
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8726
9072
|
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8727
9073
|
...emitLineTrack(ctx, curV, spV)
|
|
8728
9074
|
);
|
|
8729
9075
|
sepAtPos = spV;
|
|
8730
|
-
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}
|
|
9076
|
+
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}; `;
|
|
8731
9077
|
const sep = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8732
9078
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep;
|
|
8733
9079
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
@@ -8745,19 +9091,30 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8745
9091
|
);
|
|
8746
9092
|
} else {
|
|
8747
9093
|
const trivFn = ensureTriviaFn(ctx);
|
|
9094
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8748
9095
|
const spV = v(ctx, "_sp");
|
|
8749
|
-
stmts.push(
|
|
9096
|
+
stmts.push(
|
|
9097
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
9098
|
+
`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
9099
|
+
...emitLineTrack(ctx, curV, spV)
|
|
9100
|
+
);
|
|
8750
9101
|
sepAtPos = spV;
|
|
8751
9102
|
const sep = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8752
9103
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep;
|
|
8753
|
-
|
|
9104
|
+
const rollbackToSep = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
9105
|
+
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
9106
|
+
const postRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_psrlg") : null;
|
|
8754
9107
|
const npV = v(ctx, "_np");
|
|
8755
|
-
stmts.push(
|
|
9108
|
+
stmts.push(
|
|
9109
|
+
...postRootLog ? [`${ind(ctx)}const ${postRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
9110
|
+
`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
9111
|
+
...emitLineTrack(ctx, sepEnd, npV)
|
|
9112
|
+
);
|
|
8756
9113
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8757
9114
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8758
9115
|
stmts.push(
|
|
8759
9116
|
...nextStmts,
|
|
8760
|
-
...failItem(nextOk, next.mayCommit, npV, itemFailBreak(sepEnd,
|
|
9117
|
+
...failItem(nextOk, next.mayCommit, npV, itemFailBreak(sepEnd, rollbackToSep, postRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${postRootLog}) _ctx._rootTriviaLog.length = ${postRootLog}; ` : "")),
|
|
8761
9118
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
8762
9119
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
8763
9120
|
);
|
|
@@ -8852,6 +9209,7 @@ function emitNot(def, ctx, pos) {
|
|
|
8852
9209
|
const raw = sinksLive ? v(ctx, "_ntr") : null;
|
|
8853
9210
|
const tl = sinksLive ? v(ctx, "_ntt") : null;
|
|
8854
9211
|
const log = sinksLive ? v(ctx, "_ntg") : null;
|
|
9212
|
+
const rootLog = sinksLive && hasSelectedRootTrivia(ctx) ? v(ctx, "_ntrg") : null;
|
|
8855
9213
|
const fields = sinksLive ? v(ctx, "_ntf") : null;
|
|
8856
9214
|
const errors = sinksLive ? v(ctx, "_nte") : null;
|
|
8857
9215
|
const { stmts, okVar } = emitFallible(def.parser, ctx, pos, true);
|
|
@@ -8859,11 +9217,11 @@ function emitNot(def, ctx, pos) {
|
|
|
8859
9217
|
return {
|
|
8860
9218
|
stmts: [
|
|
8861
9219
|
...sinksLive ? [
|
|
8862
|
-
`${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`
|
|
9220
|
+
`${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`
|
|
8863
9221
|
] : [],
|
|
8864
9222
|
...stmts,
|
|
8865
9223
|
...sinksLive ? [
|
|
8866
|
-
`${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}
|
|
9224
|
+
`${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}`
|
|
8867
9225
|
] : [],
|
|
8868
9226
|
...emitIfFail(ctx, okVar, failBody(ctx, label2, pos))
|
|
8869
9227
|
],
|
|
@@ -8999,16 +9357,17 @@ function emitToken(def, ctx, pos) {
|
|
|
8999
9357
|
const sk = v(ctx, "_tokKinds");
|
|
9000
9358
|
const stl = v(ctx, "_tokTl");
|
|
9001
9359
|
const sol = v(ctx, "_tokLog");
|
|
9360
|
+
const srl = hasSelectedRootTrivia(ctx) ? v(ctx, "_tokRootLog") : null;
|
|
9002
9361
|
const sb = v(ctx, "_tokBuf");
|
|
9003
9362
|
const valV = v(ctx, "_tok");
|
|
9004
9363
|
return {
|
|
9005
9364
|
stmts: [
|
|
9006
|
-
`${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`,
|
|
9007
|
-
`${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`,
|
|
9365
|
+
`${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`,
|
|
9366
|
+
`${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`,
|
|
9008
9367
|
`${i}try {`,
|
|
9009
9368
|
...reindentStmts(inner.stmts, ctx.indent + 1).map((stmt) => stmt.replace(/^(\s*)(?:const|let)\s+/, "$1var ")),
|
|
9010
9369
|
`${i}} finally {`,
|
|
9011
|
-
`${i} _ctx.trivia = ${sv}; _ctx.triviaKindLabels = ${sk}; _ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx._cstTriviaLog = ${stl}; _ctx._triviaLog = ${sol}
|
|
9370
|
+
`${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}`,
|
|
9012
9371
|
`${i}}`,
|
|
9013
9372
|
...emitIfFail(ctx, `!${inner.okVar}`, propagateFailBody(ctx)),
|
|
9014
9373
|
`${i}const ${valV} = input.slice(${pos}, ${inner.endVar})`,
|
|
@@ -9487,6 +9846,8 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9487
9846
|
case "grammar": {
|
|
9488
9847
|
const savedTrivia = ctx.activeTrivia;
|
|
9489
9848
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
9849
|
+
const opaqueRootCapture = hasSelectedRootTrivia(ctx) && def.rootCapture === "opaque";
|
|
9850
|
+
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;
|
|
9490
9851
|
if (def.clearTrivia) {
|
|
9491
9852
|
ctx.activeTrivia = void 0;
|
|
9492
9853
|
ctx.triviaKindLabels = void 0;
|
|
@@ -9497,13 +9858,38 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9497
9858
|
}
|
|
9498
9859
|
}
|
|
9499
9860
|
const savedCapture = def.captureTrivia ? v(ctx, "_gcap") : null;
|
|
9861
|
+
const savedRootCapture = opaqueRootCapture ? v(ctx, "_grtc") : null;
|
|
9862
|
+
const opaqueValue = opaqueRootCapture ? v(ctx, "_grtv") : null;
|
|
9863
|
+
const opaqueEnd = opaqueRootCapture ? v(ctx, "_grte") : null;
|
|
9864
|
+
if (opaqueRootCapture) ctx.indent++;
|
|
9500
9865
|
const r = emit(def.parser, ctx, pos);
|
|
9866
|
+
if (opaqueRootCapture) ctx.indent--;
|
|
9501
9867
|
ctx.activeTrivia = savedTrivia;
|
|
9502
9868
|
ctx.triviaKindLabels = savedKindLabels;
|
|
9503
|
-
if (!savedCapture) return r
|
|
9869
|
+
if (!savedCapture && !opaqueRootCapture) return strictScopeCheck === void 0 ? r : {
|
|
9870
|
+
...r,
|
|
9871
|
+
stmts: [strictScopeCheck, ...r.stmts]
|
|
9872
|
+
};
|
|
9873
|
+
if (opaqueRootCapture) {
|
|
9874
|
+
return {
|
|
9875
|
+
stmts: [
|
|
9876
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9877
|
+
`${ind(ctx)}let ${opaqueValue}, ${opaqueEnd}`,
|
|
9878
|
+
`${ind(ctx)}${savedCapture ? `const ${savedCapture} = _ctx.captureTrivia; ` : ""}const ${savedRootCapture} = _ctx._rootTriviaCapture; _ctx._rootTriviaCapture = false`,
|
|
9879
|
+
`${ind(ctx)}try {`,
|
|
9880
|
+
...savedCapture ? [`${ind(ctx)} _ctx.captureTrivia = true`] : [],
|
|
9881
|
+
...r.stmts,
|
|
9882
|
+
`${ind(ctx)} ${opaqueValue} = ${r.valueVar}; ${opaqueEnd} = ${r.endVar}`,
|
|
9883
|
+
`${ind(ctx)}} finally { ${savedCapture ? `_ctx.captureTrivia = ${savedCapture}; ` : ""}_ctx._rootTriviaCapture = ${savedRootCapture} }`
|
|
9884
|
+
],
|
|
9885
|
+
valueVar: opaqueValue,
|
|
9886
|
+
endVar: opaqueEnd
|
|
9887
|
+
};
|
|
9888
|
+
}
|
|
9504
9889
|
return {
|
|
9505
9890
|
...r,
|
|
9506
9891
|
stmts: [
|
|
9892
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9507
9893
|
`${ind(ctx)}const ${savedCapture} = _ctx.captureTrivia; _ctx.captureTrivia = true`,
|
|
9508
9894
|
...r.stmts,
|
|
9509
9895
|
`${ind(ctx)}_ctx.captureTrivia = ${savedCapture}`
|
|
@@ -9988,6 +10374,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9988
10374
|
runDuplicationDiagnostic(combinator, opts?.duplication);
|
|
9989
10375
|
markUnusedValues(combinator);
|
|
9990
10376
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
10377
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || combinator._meta.rootTriviaClassified === true;
|
|
9991
10378
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9992
10379
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9993
10380
|
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
@@ -10014,7 +10401,11 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
10014
10401
|
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
10015
10402
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
10016
10403
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
10017
|
-
...
|
|
10404
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10405
|
+
...grammarTrivia ? {
|
|
10406
|
+
activeTrivia: grammarTrivia,
|
|
10407
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10408
|
+
} : {},
|
|
10018
10409
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
10019
10410
|
};
|
|
10020
10411
|
const r = emit(combinator, ctx, "_pos");
|
|
@@ -10162,10 +10553,11 @@ function assertRuleName(name) {
|
|
|
10162
10553
|
);
|
|
10163
10554
|
}
|
|
10164
10555
|
}
|
|
10165
|
-
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels) {
|
|
10166
|
-
const labels = rule._meta.triviaKindLabels
|
|
10167
|
-
|
|
10168
|
-
|
|
10556
|
+
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels, ambientRootTriviaClassified) {
|
|
10557
|
+
const labels = ambientTriviaKindLabels ?? rule._meta.triviaKindLabels;
|
|
10558
|
+
const classified = ambientRootTriviaClassified ?? rule._meta.rootTriviaClassified;
|
|
10559
|
+
if (labels === void 0 && classified === void 0) return fnSource;
|
|
10560
|
+
return `Object.assign(${fnSource}, { _meta: {${labels === void 0 ? "" : ` triviaKindLabels: ${JSON.stringify(labels)},`}${classified === void 0 ? "" : " rootTriviaClassified: true,"} } })`;
|
|
10169
10561
|
}
|
|
10170
10562
|
function compileLinkable(ruleMapArg, ns, opts) {
|
|
10171
10563
|
if (!ns) throw new Error("compileLinkable: ns must be a non-empty namespace");
|
|
@@ -10173,6 +10565,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10173
10565
|
if (opts?.duplication !== void 0) runDuplicationDiagnosticRules(ruleMapArg, opts.duplication);
|
|
10174
10566
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
10175
10567
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
10568
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || ruleMapArg.some(([, rule]) => rule._meta.rootTriviaClassified === true);
|
|
10176
10569
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
10177
10570
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10178
10571
|
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -10216,7 +10609,11 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10216
10609
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10217
10610
|
ns,
|
|
10218
10611
|
deferFirstSetRefs: true,
|
|
10219
|
-
...
|
|
10612
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10613
|
+
...grammarTrivia ? {
|
|
10614
|
+
activeTrivia: grammarTrivia,
|
|
10615
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10616
|
+
} : {},
|
|
10220
10617
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
10221
10618
|
};
|
|
10222
10619
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -10348,7 +10745,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10348
10745
|
...r.stmts,
|
|
10349
10746
|
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
10350
10747
|
`}`
|
|
10351
|
-
].join("\n"), ctx.triviaKindLabels));
|
|
10748
|
+
].join("\n"), ctx.triviaKindLabels, ctx.rootTriviaClassified));
|
|
10352
10749
|
}
|
|
10353
10750
|
const firstSets = /* @__PURE__ */ new Map();
|
|
10354
10751
|
const firstSetRecipes = /* @__PURE__ */ new Map();
|
|
@@ -10697,6 +11094,7 @@ function evalRuleMapIR(ir) {
|
|
|
10697
11094
|
"transform",
|
|
10698
11095
|
"skip",
|
|
10699
11096
|
"trivia",
|
|
11097
|
+
"classifiedTrivia",
|
|
10700
11098
|
"label",
|
|
10701
11099
|
"field",
|
|
10702
11100
|
"expect",
|
|
@@ -10737,6 +11135,7 @@ function evalRuleMapIR(ir) {
|
|
|
10737
11135
|
transform,
|
|
10738
11136
|
skip,
|
|
10739
11137
|
trivia,
|
|
11138
|
+
classifiedTrivia,
|
|
10740
11139
|
label,
|
|
10741
11140
|
field,
|
|
10742
11141
|
expect,
|
|
@@ -10983,8 +11382,11 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10983
11382
|
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
10984
11383
|
}
|
|
10985
11384
|
case "grammar": {
|
|
10986
|
-
const
|
|
10987
|
-
|
|
11385
|
+
const classified = def.triviaParser?._meta.rootTriviaClassified === true;
|
|
11386
|
+
const spec = classified && def.triviaParser ? analyzeLabeledTrivia(def.triviaParser) : null;
|
|
11387
|
+
if (classified && !spec) throw new Unserializable("classified trivia without labeled arms");
|
|
11388
|
+
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";
|
|
11389
|
+
return `parser({ trivia: ${trivia2}${def.captureTrivia ? ", captureTrivia: true" : ""}${def.rootCapture ? `, rootCapture: ${JSON.stringify(def.rootCapture)}` : ""}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(def.parser)})`;
|
|
10988
11390
|
}
|
|
10989
11391
|
case "withCtx": {
|
|
10990
11392
|
if (def.extraSrc === void 0) throw new Unserializable("withCtx without extraSrc");
|
|
@@ -11881,157 +12283,26 @@ function parseDoc(registry, rootRule, input, opts = {}) {
|
|
|
11881
12283
|
return new ParseDocImpl(registry, rootRule, opts, { abs: null }, [fail], null, input);
|
|
11882
12284
|
}
|
|
11883
12285
|
|
|
11884
|
-
// src/cst/trivia-entries.ts
|
|
11885
|
-
var EMPTY_INDICES = Object.freeze([]);
|
|
11886
|
-
var EMPTY_GAPS = Object.freeze([]);
|
|
11887
|
-
function entryOffset(i, stride) {
|
|
11888
|
-
return i * stride;
|
|
11889
|
-
}
|
|
11890
|
-
function triviaEntries(log, labels, opts) {
|
|
11891
|
-
const baseStride = opts?.nodeLog ? 3 : 2;
|
|
11892
|
-
const stride = labels ? baseStride + 1 : baseStride;
|
|
11893
|
-
const length = Math.floor(log.length / stride);
|
|
11894
|
-
return {
|
|
11895
|
-
length,
|
|
11896
|
-
labels,
|
|
11897
|
-
stride,
|
|
11898
|
-
start(i) {
|
|
11899
|
-
return log[entryOffset(i, stride)];
|
|
11900
|
-
},
|
|
11901
|
-
end(i) {
|
|
11902
|
-
return log[entryOffset(i, stride) + 1];
|
|
11903
|
-
},
|
|
11904
|
-
insertIndex(i) {
|
|
11905
|
-
return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
|
|
11906
|
-
},
|
|
11907
|
-
kindIndex(i) {
|
|
11908
|
-
if (!labels) return void 0;
|
|
11909
|
-
return log[entryOffset(i, stride) + baseStride];
|
|
11910
|
-
},
|
|
11911
|
-
kind(i) {
|
|
11912
|
-
const ki = labels ? log[entryOffset(i, stride) + baseStride] : void 0;
|
|
11913
|
-
return ki !== void 0 ? labels[ki] : void 0;
|
|
11914
|
-
},
|
|
11915
|
-
text(i, input) {
|
|
11916
|
-
const s = log[entryOffset(i, stride)];
|
|
11917
|
-
const e = log[entryOffset(i, stride) + 1];
|
|
11918
|
-
return input.slice(s, e);
|
|
11919
|
-
}
|
|
11920
|
-
};
|
|
11921
|
-
}
|
|
11922
|
-
function appendEntryRange(map, key, first, last) {
|
|
11923
|
-
let indices = map.get(key);
|
|
11924
|
-
if (!indices) {
|
|
11925
|
-
indices = [];
|
|
11926
|
-
map.set(key, indices);
|
|
11927
|
-
}
|
|
11928
|
-
for (let i = first; i <= last; i++) indices.push(i);
|
|
11929
|
-
}
|
|
11930
|
-
function buildGap(entries, start, end, first, last) {
|
|
11931
|
-
const entryIndices = [];
|
|
11932
|
-
for (let i = first; i <= last; i++) entryIndices.push(i);
|
|
11933
|
-
return {
|
|
11934
|
-
start,
|
|
11935
|
-
end,
|
|
11936
|
-
entryIndices,
|
|
11937
|
-
hasKind(kind) {
|
|
11938
|
-
for (const i of entryIndices) {
|
|
11939
|
-
if (entries.kind(i) === kind) return true;
|
|
11940
|
-
}
|
|
11941
|
-
return false;
|
|
11942
|
-
},
|
|
11943
|
-
text(input) {
|
|
11944
|
-
return input.slice(start, end);
|
|
11945
|
-
}
|
|
11946
|
-
};
|
|
11947
|
-
}
|
|
11948
|
-
function buildRootMaps(entries) {
|
|
11949
|
-
const before = /* @__PURE__ */ new Map();
|
|
11950
|
-
const after = /* @__PURE__ */ new Map();
|
|
11951
|
-
const beforeGaps = /* @__PURE__ */ new Map();
|
|
11952
|
-
const afterGaps = /* @__PURE__ */ new Map();
|
|
11953
|
-
const gaps = [];
|
|
11954
|
-
if (entries.length === 0) return { before, after, beforeGaps, afterGaps, gaps };
|
|
11955
|
-
const appendGap = (first2, last, start2, end2) => {
|
|
11956
|
-
const gap = buildGap(entries, start2, end2, first2, last);
|
|
11957
|
-
gaps.push(gap);
|
|
11958
|
-
afterGaps.set(start2, gap);
|
|
11959
|
-
beforeGaps.set(end2, gap);
|
|
11960
|
-
appendEntryRange(after, start2, first2, last);
|
|
11961
|
-
appendEntryRange(before, end2, first2, last);
|
|
11962
|
-
};
|
|
11963
|
-
let first = 0;
|
|
11964
|
-
let start = entries.start(0);
|
|
11965
|
-
let end = entries.end(0);
|
|
11966
|
-
for (let i = 1; i < entries.length; i++) {
|
|
11967
|
-
const nextStart = entries.start(i);
|
|
11968
|
-
const nextEnd = entries.end(i);
|
|
11969
|
-
if (nextStart === end) {
|
|
11970
|
-
end = nextEnd;
|
|
11971
|
-
continue;
|
|
11972
|
-
}
|
|
11973
|
-
appendGap(first, i - 1, start, end);
|
|
11974
|
-
first = i;
|
|
11975
|
-
start = nextStart;
|
|
11976
|
-
end = nextEnd;
|
|
11977
|
-
}
|
|
11978
|
-
appendGap(first, entries.length - 1, start, end);
|
|
11979
|
-
return { before, after, beforeGaps, afterGaps, gaps };
|
|
11980
|
-
}
|
|
11981
|
-
function buildRootTriviaIndex(log, labels) {
|
|
11982
|
-
const entries = triviaEntries(log, labels);
|
|
11983
|
-
let maps;
|
|
11984
|
-
const getMaps = () => {
|
|
11985
|
-
maps ??= buildRootMaps(entries);
|
|
11986
|
-
return maps;
|
|
11987
|
-
};
|
|
11988
|
-
return {
|
|
11989
|
-
entries,
|
|
11990
|
-
labels,
|
|
11991
|
-
get before() {
|
|
11992
|
-
return getMaps().before;
|
|
11993
|
-
},
|
|
11994
|
-
get after() {
|
|
11995
|
-
return getMaps().after;
|
|
11996
|
-
},
|
|
11997
|
-
entryIndicesBefore(offset) {
|
|
11998
|
-
return getMaps().before.get(offset) ?? EMPTY_INDICES;
|
|
11999
|
-
},
|
|
12000
|
-
entryIndicesAfter(offset) {
|
|
12001
|
-
return getMaps().after.get(offset) ?? EMPTY_INDICES;
|
|
12002
|
-
},
|
|
12003
|
-
gapBefore(offset) {
|
|
12004
|
-
return getMaps().beforeGaps.get(offset);
|
|
12005
|
-
},
|
|
12006
|
-
gapAfter(offset) {
|
|
12007
|
-
return getMaps().afterGaps.get(offset);
|
|
12008
|
-
},
|
|
12009
|
-
gaps() {
|
|
12010
|
-
return getMaps().gaps;
|
|
12011
|
-
},
|
|
12012
|
-
gapsWithKind(kind) {
|
|
12013
|
-
const kinds = typeof kind === "string" ? [kind] : kind;
|
|
12014
|
-
const matches2 = [];
|
|
12015
|
-
for (const gap of getMaps().gaps) {
|
|
12016
|
-
for (const k of kinds) {
|
|
12017
|
-
if (gap.hasKind(k)) {
|
|
12018
|
-
matches2.push(gap);
|
|
12019
|
-
break;
|
|
12020
|
-
}
|
|
12021
|
-
}
|
|
12022
|
-
}
|
|
12023
|
-
return matches2.length === 0 ? EMPTY_GAPS : matches2;
|
|
12024
|
-
}
|
|
12025
|
-
};
|
|
12026
|
-
}
|
|
12027
|
-
|
|
12028
12286
|
// src/functional/run.ts
|
|
12029
12287
|
var invoke = (r, input, pos, ctx) => typeof r === "function" ? r(input, pos, ctx) : r.parse(input, pos, ctx);
|
|
12030
12288
|
function triviaKindLabelsFromRunnable(r) {
|
|
12031
12289
|
if (!r) return void 0;
|
|
12032
12290
|
if (typeof r === "function") return r._meta?.triviaKindLabels;
|
|
12033
12291
|
const grammarTrivia = r._meta.grammarTrivia;
|
|
12034
|
-
return
|
|
12292
|
+
return grammarTrivia?._meta.triviaKindLabels ?? r._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
|
|
12293
|
+
}
|
|
12294
|
+
function rootTriviaClassifiedFromRunnable(r) {
|
|
12295
|
+
if (!r) return false;
|
|
12296
|
+
if (typeof r === "function") return r._meta?.rootTriviaClassified === true;
|
|
12297
|
+
const grammarTrivia = r._meta.grammarTrivia;
|
|
12298
|
+
return grammarTrivia?._meta.rootTriviaClassified === true || r._meta.rootTriviaClassified === true;
|
|
12299
|
+
}
|
|
12300
|
+
function makeSelectedRootLabelIndex(labels) {
|
|
12301
|
+
const index = /* @__PURE__ */ Object.create(null);
|
|
12302
|
+
for (let i = 0; i < labels.length; i++) {
|
|
12303
|
+
if (index[labels[i]] === void 0) index[labels[i]] = i;
|
|
12304
|
+
}
|
|
12305
|
+
return index;
|
|
12035
12306
|
}
|
|
12036
12307
|
function runOnce(entry, input, options, phase, profileState) {
|
|
12037
12308
|
if (typeof entry !== "function" && typeof entry?.parse !== "function") {
|
|
@@ -12039,13 +12310,31 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
12039
12310
|
`run(): start production is ${entry === null ? "null" : typeof entry}, not a rule \u2014 the requested grammar rule does not exist (check the rule name).`
|
|
12040
12311
|
);
|
|
12041
12312
|
}
|
|
12042
|
-
const
|
|
12313
|
+
const rootTriviaSelection = options.rootTrivia?.select;
|
|
12314
|
+
const captureRootTrivia = rootTriviaSelection !== void 0 && rootTriviaSelection.length > 0;
|
|
12315
|
+
const selectedRootLog = captureRootTrivia ? [] : void 0;
|
|
12316
|
+
const selectedRootLabelIndex = captureRootTrivia ? makeSelectedRootLabelIndex(rootTriviaSelection) : void 0;
|
|
12043
12317
|
const errors = [];
|
|
12044
12318
|
const profile = profileState ?? (phase === void 0 ? void 0 : { phase, nodes: 0, childSlots: 0, rawSlots: 0, triviaSlots: 0, fieldSlots: 0, hostCalls: 0 });
|
|
12045
12319
|
const skipGlobalSinks = phase === "recognizer" || phase === "capture";
|
|
12046
12320
|
const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
|
|
12047
12321
|
const grammarScanSkip = typeof entry !== "function" ? entry._meta.grammarScanSkip : void 0;
|
|
12048
12322
|
const triviaKindLabels = triviaKindLabelsFromRunnable(entry) ?? triviaKindLabelsFromRunnable(options.trivia);
|
|
12323
|
+
if (captureRootTrivia && triviaKindLabels === void 0) {
|
|
12324
|
+
throw new TypeError("run(): rootTrivia.select requires labeled grammar trivia.");
|
|
12325
|
+
}
|
|
12326
|
+
if (captureRootTrivia) {
|
|
12327
|
+
for (const label2 of rootTriviaSelection) {
|
|
12328
|
+
if (!triviaKindLabels.includes(label2)) {
|
|
12329
|
+
throw new TypeError(`run(): rootTrivia.select contains unknown trivia label ${JSON.stringify(label2)}.`);
|
|
12330
|
+
}
|
|
12331
|
+
}
|
|
12332
|
+
}
|
|
12333
|
+
if (captureRootTrivia && !rootTriviaClassifiedFromRunnable(entry) && !rootTriviaClassifiedFromRunnable(options.trivia)) {
|
|
12334
|
+
throw new TypeError(
|
|
12335
|
+
"run(): rootTrivia.select requires classifiedTrivia() at the root."
|
|
12336
|
+
);
|
|
12337
|
+
}
|
|
12049
12338
|
const stamped = entry;
|
|
12050
12339
|
assertHostModeCompatible(
|
|
12051
12340
|
typeof entry === "function" ? stamped[FUSED_HOST_MODE] ?? "ast" : entry._meta.grammarHostMode ?? "ast",
|
|
@@ -12054,7 +12343,15 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
12054
12343
|
);
|
|
12055
12344
|
const ctx = {
|
|
12056
12345
|
trackLines: false,
|
|
12057
|
-
...skipGlobalSinks ? { _pmProfile: profile } : {
|
|
12346
|
+
...skipGlobalSinks ? { _pmProfile: profile } : {
|
|
12347
|
+
...captureRootTrivia ? {
|
|
12348
|
+
_rootTriviaLog: selectedRootLog,
|
|
12349
|
+
_rootTriviaKindIndex: selectedRootLabelIndex,
|
|
12350
|
+
_rootTriviaStrictScopes: true
|
|
12351
|
+
} : {},
|
|
12352
|
+
_errors: errors,
|
|
12353
|
+
...profile === void 0 ? {} : { _pmProfile: profile }
|
|
12354
|
+
},
|
|
12058
12355
|
build: options.build,
|
|
12059
12356
|
state: options.state,
|
|
12060
12357
|
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...triviaKindLabels ? { triviaKindLabels } : {} } : triviaKindLabels ? { triviaKindLabels } : {},
|
|
@@ -12079,9 +12376,13 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
12079
12376
|
span: r.span ?? { start: 0, end: 0 },
|
|
12080
12377
|
expected: r.ok ? [] : r.expected ?? [],
|
|
12081
12378
|
errors,
|
|
12082
|
-
|
|
12083
|
-
|
|
12084
|
-
|
|
12379
|
+
...selectedRootLog !== void 0 && selectedRootLog.length > 0 ? {
|
|
12380
|
+
rootTrivia: {
|
|
12381
|
+
rows: selectedRootLog,
|
|
12382
|
+
select: rootTriviaSelection,
|
|
12383
|
+
index: buildRootTriviaIndex(selectedRootLog, rootTriviaSelection)
|
|
12384
|
+
}
|
|
12385
|
+
} : {},
|
|
12085
12386
|
unconsumedFrom
|
|
12086
12387
|
};
|
|
12087
12388
|
}
|