parseman 0.42.1 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/combinators/attempt.d.ts.map +1 -1
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts +7 -0
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/map.d.ts +11 -0
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/node.d.ts +21 -7
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +17 -2
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/token.d.ts +3 -2
- package/dist/combinators/token.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +1 -0
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +4 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +6 -1
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/compiler/scannable-run.d.ts +1 -1
- package/dist/compiler/scannable-run.d.ts.map +1 -1
- package/dist/compiler/trivia-fast-path.d.ts +4 -3
- package/dist/compiler/trivia-fast-path.d.ts.map +1 -1
- package/dist/cst/reflection.d.ts +24 -0
- package/dist/cst/reflection.d.ts.map +1 -0
- package/dist/cst/trivia-entries.d.ts +15 -9
- package/dist/cst/trivia-entries.d.ts.map +1 -1
- package/dist/cst/trivia-kinds.d.ts +15 -11
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/cst/types.d.ts +2 -0
- package/dist/cst/types.d.ts.map +1 -1
- package/dist/cst/walk.d.ts +27 -62
- package/dist/cst/walk.d.ts.map +1 -1
- package/dist/functional/run.d.ts +22 -16
- package/dist/functional/run.d.ts.map +1 -1
- package/dist/index.cjs +1651 -1207
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1651 -1207
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs +186 -135
- package/dist/language-service/index.cjs.map +4 -4
- package/dist/language-service/index.d.ts +1 -1
- package/dist/language-service/index.d.ts.map +1 -1
- package/dist/language-service/index.js +186 -135
- package/dist/language-service/index.js.map +4 -4
- package/dist/plugin/evaluator.d.ts +1 -0
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +1525 -1048
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1525 -1048
- package/dist/plugin/index.js.map +4 -4
- package/dist/run/index.cjs +152 -102
- package/dist/run/index.cjs.map +3 -3
- package/dist/run/index.d.ts +1 -1
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +152 -102
- package/dist/run/index.js.map +3 -3
- package/dist/spec/index.cjs +1381 -1152
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +1381 -1152
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +27 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.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,
|
|
@@ -121,7 +122,6 @@ __export(index_exports, {
|
|
|
121
122
|
trivia: () => trivia,
|
|
122
123
|
triviaEntries: () => triviaEntries,
|
|
123
124
|
triviaKindMask: () => triviaKindMask,
|
|
124
|
-
walk: () => walk,
|
|
125
125
|
when: () => when,
|
|
126
126
|
withCtx: () => withCtx,
|
|
127
127
|
word: () => word
|
|
@@ -1183,1035 +1183,1099 @@ function keywords(words, opts = {}) {
|
|
|
1183
1183
|
};
|
|
1184
1184
|
}
|
|
1185
1185
|
|
|
1186
|
-
// src/
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
_cstChildren: ctx._cstChildren,
|
|
1193
|
-
_cstRawChildren: ctx._cstRawChildren,
|
|
1194
|
-
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1195
|
-
_triviaLog: ctx._triviaLog,
|
|
1196
|
-
_fields: ctx._fields,
|
|
1197
|
-
_cstBuf: ctx._cstBuf,
|
|
1198
|
-
_tolerant: ctx._tolerant,
|
|
1199
|
-
_sync: ctx._sync
|
|
1200
|
-
};
|
|
1201
|
-
ctx._probe = void 0;
|
|
1202
|
-
ctx._errors = void 0;
|
|
1203
|
-
ctx._cstLeaves = void 0;
|
|
1204
|
-
ctx._cstChildren = void 0;
|
|
1205
|
-
ctx._cstRawChildren = void 0;
|
|
1206
|
-
ctx._cstTriviaLog = void 0;
|
|
1207
|
-
ctx._triviaLog = void 0;
|
|
1208
|
-
ctx._fields = void 0;
|
|
1209
|
-
ctx._cstBuf = void 0;
|
|
1210
|
-
ctx._tolerant = void 0;
|
|
1211
|
-
ctx._sync = void 0;
|
|
1212
|
-
try {
|
|
1213
|
-
return sentinel.parse(input, pos, ctx).ok;
|
|
1214
|
-
} finally {
|
|
1215
|
-
ctx._probe = s._probe;
|
|
1216
|
-
ctx._errors = s._errors;
|
|
1217
|
-
ctx._cstLeaves = s._cstLeaves;
|
|
1218
|
-
ctx._cstChildren = s._cstChildren;
|
|
1219
|
-
ctx._cstRawChildren = s._cstRawChildren;
|
|
1220
|
-
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1221
|
-
ctx._triviaLog = s._triviaLog;
|
|
1222
|
-
ctx._fields = s._fields;
|
|
1223
|
-
ctx._cstBuf = s._cstBuf;
|
|
1224
|
-
ctx._tolerant = s._tolerant;
|
|
1225
|
-
ctx._sync = s._sync;
|
|
1226
|
-
}
|
|
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;
|
|
1227
1192
|
}
|
|
1228
|
-
function
|
|
1229
|
-
if (
|
|
1230
|
-
return
|
|
1231
|
-
_tag: "orSentinel",
|
|
1232
|
-
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1233
|
-
_def: { tag: "unknown" },
|
|
1234
|
-
parse(input, pos, ctx) {
|
|
1235
|
-
const ra = a.parse(input, pos, ctx);
|
|
1236
|
-
if (ra.ok) return ra;
|
|
1237
|
-
return b.parse(input, pos, ctx);
|
|
1238
|
-
}
|
|
1239
|
-
};
|
|
1193
|
+
function peelLabel(p) {
|
|
1194
|
+
if (p._def.tag === "label") return { label: p._def.label, parser: p._def.parser };
|
|
1195
|
+
return null;
|
|
1240
1196
|
}
|
|
1241
|
-
function
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
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;
|
|
1254
1216
|
}
|
|
1255
|
-
|
|
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;
|
|
1256
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
|
|
1257
1231
|
};
|
|
1232
|
+
labeledTriviaSpecs.set(trivia2, spec);
|
|
1233
|
+
return spec;
|
|
1258
1234
|
}
|
|
1259
|
-
function
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1265
|
-
ctx._errors?.push(error);
|
|
1266
|
-
return { error, end: scanPos };
|
|
1267
|
-
}
|
|
1268
|
-
function matchesAt(sentinel, input, pos, ctx) {
|
|
1269
|
-
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 };
|
|
1270
1240
|
}
|
|
1271
|
-
function
|
|
1272
|
-
|
|
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 };
|
|
1273
1261
|
}
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
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;
|
|
1279
1276
|
}
|
|
1280
|
-
function
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
return [def.label];
|
|
1292
|
-
case "choice":
|
|
1293
|
-
return def.parsers.flatMap(deriveExpected2);
|
|
1294
|
-
case "dispatch":
|
|
1295
|
-
return deriveExpected2(def.selector);
|
|
1296
|
-
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
1297
|
-
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
1298
|
-
// able to fail first — deriving from term 0 alone named a token the parse
|
|
1299
|
-
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
1300
|
-
// nothing (its own expectation is about what must NOT be here), but it is
|
|
1301
|
-
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
1302
|
-
case "sequence": {
|
|
1303
|
-
const out = [];
|
|
1304
|
-
for (const term of def.parsers) {
|
|
1305
|
-
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
1306
|
-
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;
|
|
1307
1288
|
}
|
|
1308
|
-
return out;
|
|
1309
1289
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
case "not":
|
|
1333
|
-
case "peek":
|
|
1334
|
-
return deriveExpected2(def.parser);
|
|
1335
|
-
case "routed":
|
|
1336
|
-
return ["routed()"];
|
|
1337
|
-
case "lazy": {
|
|
1338
|
-
const name = c._ruleName;
|
|
1339
|
-
if (seen.has(c)) return name ? [name] : [];
|
|
1340
|
-
seen.add(c);
|
|
1341
|
-
try {
|
|
1342
|
-
return deriveExpected2(def.thunk());
|
|
1343
|
-
} catch {
|
|
1344
|
-
return name ? [name] : [];
|
|
1345
|
-
} finally {
|
|
1346
|
-
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);
|
|
1347
1312
|
}
|
|
1348
1313
|
}
|
|
1349
|
-
default:
|
|
1350
|
-
return [];
|
|
1351
1314
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
isTrivia: false
|
|
1359
|
-
};
|
|
1360
|
-
return {
|
|
1361
|
-
_tag: "expect",
|
|
1362
|
-
_meta: meta,
|
|
1363
|
-
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1364
|
-
parse(input, pos, ctx) {
|
|
1365
|
-
const result = combinator.parse(input, pos, ctx);
|
|
1366
|
-
if (result.ok) return result;
|
|
1367
|
-
const span = { start: pos, end: pos };
|
|
1368
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1369
|
-
ctx._errors?.push(error);
|
|
1370
|
-
if (ctx._tolerant) captureError(ctx, error);
|
|
1371
|
-
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;
|
|
1372
1321
|
}
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
function isParseError(value) {
|
|
1376
|
-
return typeof value === "object" && value !== null && value._tag === "parseError";
|
|
1322
|
+
}
|
|
1377
1323
|
}
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
const
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
1385
|
-
let combined = { kind: "empty" };
|
|
1386
|
-
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
1387
|
-
const meta = {
|
|
1388
|
-
firstSet: combined,
|
|
1389
|
-
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1390
|
-
isTrivia: false,
|
|
1391
|
-
disjoint
|
|
1392
|
-
};
|
|
1393
|
-
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
1394
|
-
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1395
|
-
let greedyLitMap = null;
|
|
1396
|
-
let sortedParsers = null;
|
|
1397
|
-
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
1398
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1399
|
-
greedyLitMap = /* @__PURE__ */ new Map();
|
|
1400
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1401
|
-
if (i === strategy.superIndex) continue;
|
|
1402
|
-
const litVal = getCoreLiteralValue(parsers[i]);
|
|
1403
|
-
if (litVal !== null) greedyLitMap.set(litVal, i);
|
|
1404
|
-
}
|
|
1405
|
-
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
1406
|
-
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;
|
|
1407
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);
|
|
1408
1343
|
return {
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
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]);
|
|
1430
1406
|
}
|
|
1431
1407
|
}
|
|
1432
|
-
if (
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
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]);
|
|
1436
1411
|
}
|
|
1437
|
-
const result = parsers[idx].parse(input, pos, ctx);
|
|
1438
|
-
if (result.ok) return result;
|
|
1439
|
-
expected.push(...result.expected);
|
|
1440
|
-
if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
|
|
1441
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1442
|
-
}
|
|
1443
|
-
return {
|
|
1444
|
-
ok: false,
|
|
1445
|
-
expected: parsers.flatMap((p) => {
|
|
1446
|
-
const r = p.parse(input, pos, ctx);
|
|
1447
|
-
return r.ok ? [] : r.expected;
|
|
1448
|
-
}),
|
|
1449
|
-
span: { start: pos, end: pos }
|
|
1450
|
-
};
|
|
1451
|
-
}
|
|
1452
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1453
|
-
const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
|
|
1454
|
-
if (!superResult.ok) return superResult;
|
|
1455
|
-
const end = superResult.span.end;
|
|
1456
|
-
const litIdx = greedyLitMap.get(input.slice(pos, end));
|
|
1457
|
-
if (litIdx !== void 0) {
|
|
1458
|
-
const litVal = getCoreLiteralValue(parsers[litIdx]);
|
|
1459
|
-
const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
|
|
1460
|
-
return { ok: true, value, span: { start: pos, end } };
|
|
1461
|
-
}
|
|
1462
|
-
return superResult;
|
|
1463
|
-
}
|
|
1464
|
-
if (strategy?.tag === "literalsLongestFirst") {
|
|
1465
|
-
for (const p of sortedParsers) {
|
|
1466
|
-
const r = p.parse(input, pos, ctx);
|
|
1467
|
-
if (r.ok) return r;
|
|
1468
|
-
expected.push(...r.expected);
|
|
1469
|
-
}
|
|
1470
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1471
|
-
}
|
|
1472
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1473
|
-
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
1474
|
-
const mark = saveCstMark(ctx);
|
|
1475
|
-
const logLen = ctx._triviaLog?.length;
|
|
1476
|
-
const result = parsers[i].parse(input, pos, ctx);
|
|
1477
|
-
if (!result.ok) {
|
|
1478
|
-
rollbackCstCapture(ctx, mark);
|
|
1479
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1480
|
-
expected.push(...result.expected);
|
|
1481
|
-
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
1482
|
-
continue;
|
|
1483
|
-
}
|
|
1484
|
-
const checks = autoNot[i];
|
|
1485
|
-
if (checks && autoNotFires(input, result.span.end, checks)) {
|
|
1486
|
-
rollbackCstCapture(ctx, mark);
|
|
1487
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1488
|
-
continue;
|
|
1489
1412
|
}
|
|
1490
|
-
return result;
|
|
1491
1413
|
}
|
|
1492
|
-
|
|
1493
|
-
|
|
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)
|
|
1494
1421
|
};
|
|
1495
1422
|
}
|
|
1496
|
-
function
|
|
1497
|
-
const
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
const
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
const m = re.exec(litVal);
|
|
1512
|
-
return m !== null && m[0] === litVal;
|
|
1513
|
-
});
|
|
1514
|
-
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;
|
|
1515
1438
|
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
);
|
|
1520
|
-
|
|
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;
|
|
1521
1445
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
function bareLeadingTermKey(term) {
|
|
1527
|
-
const d = term._def;
|
|
1528
|
-
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
1529
|
-
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
1530
|
-
return null;
|
|
1531
|
-
}
|
|
1532
|
-
function detectSharedPrefix(parsers) {
|
|
1533
|
-
if (parsers.length < 2) return null;
|
|
1534
|
-
let key = null;
|
|
1535
|
-
let prefix = null;
|
|
1536
|
-
const members = [];
|
|
1537
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1538
|
-
const term0 = leadingTermOfArm(parsers[i]);
|
|
1539
|
-
if (term0 === null) return null;
|
|
1540
|
-
const k = bareLeadingTermKey(term0);
|
|
1541
|
-
if (k === null) return null;
|
|
1542
|
-
if (key === null) {
|
|
1543
|
-
key = k;
|
|
1544
|
-
prefix = term0;
|
|
1545
|
-
} else if (k !== key) return null;
|
|
1546
|
-
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;
|
|
1547
1450
|
}
|
|
1548
|
-
|
|
1549
|
-
return
|
|
1451
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1452
|
+
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1550
1453
|
}
|
|
1551
|
-
function
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
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 };
|
|
1557
1464
|
}
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
1561
|
-
return d.parsers[0];
|
|
1562
|
-
}
|
|
1563
|
-
function computeAutoNot(parsers) {
|
|
1564
|
-
return parsers.map((p, i) => {
|
|
1565
|
-
const litVal = getCoreLiteralValue(p);
|
|
1566
|
-
if (litVal === null) return null;
|
|
1567
|
-
const checks = [];
|
|
1568
|
-
for (let j = i + 1; j < parsers.length; j++) {
|
|
1569
|
-
const other = parsers[j];
|
|
1570
|
-
const otherLit = getCoreLiteralValue(other);
|
|
1571
|
-
if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
|
|
1572
|
-
checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
|
|
1573
|
-
continue;
|
|
1574
|
-
}
|
|
1575
|
-
const regexDef = getCoreRegexDef(other);
|
|
1576
|
-
if (regexDef !== null) {
|
|
1577
|
-
const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
|
|
1578
|
-
if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
|
|
1579
|
-
}
|
|
1465
|
+
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1466
|
+
return scanWithLabels(input, cur, ctx);
|
|
1580
1467
|
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
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
|
+
};
|
|
1591
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 };
|
|
1592
1486
|
}
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
return null;
|
|
1600
|
-
}
|
|
1601
|
-
function getCoreRegexDef(p) {
|
|
1602
|
-
const def = p._def;
|
|
1603
|
-
if (def.tag === "regex") return { source: def.source, flags: def.flags };
|
|
1604
|
-
if (def.tag === "transform") return getCoreRegexDef(def.parser);
|
|
1605
|
-
if (def.tag === "label") return getCoreRegexDef(def.parser);
|
|
1606
|
-
return null;
|
|
1607
|
-
}
|
|
1608
|
-
function applyTransforms(p, value, span) {
|
|
1609
|
-
const def = p._def;
|
|
1610
|
-
if (def.tag === "transform") {
|
|
1611
|
-
const inner = applyTransforms(def.parser, value, span);
|
|
1612
|
-
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 };
|
|
1613
1493
|
}
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
re.lastIndex = 0;
|
|
1619
|
-
const base = re.exec(lit);
|
|
1620
|
-
if (!base || base[0] !== lit) return null;
|
|
1621
|
-
const contCodes = [];
|
|
1622
|
-
for (let code = 1; code < 128; code++) {
|
|
1623
|
-
re.lastIndex = 0;
|
|
1624
|
-
const m = re.exec(lit + String.fromCharCode(code));
|
|
1625
|
-
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;
|
|
1626
1498
|
}
|
|
1627
|
-
if (
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
codes.sort((a, b) => a - b);
|
|
1632
|
-
const ranges = [];
|
|
1633
|
-
let lo = codes[0], hi = codes[0];
|
|
1634
|
-
for (let i = 1; i < codes.length; i++) {
|
|
1635
|
-
if (codes[i] === hi + 1) {
|
|
1636
|
-
hi = codes[i];
|
|
1637
|
-
} else {
|
|
1638
|
-
ranges.push({ lo, hi });
|
|
1639
|
-
lo = hi = codes[i];
|
|
1640
|
-
}
|
|
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 };
|
|
1641
1503
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
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 };
|
|
1644
1518
|
}
|
|
1645
|
-
function
|
|
1646
|
-
if (
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
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;
|
|
1650
1524
|
}
|
|
1651
|
-
function
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
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;
|
|
1657
1531
|
}
|
|
1658
|
-
function
|
|
1659
|
-
const
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
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
|
+
}
|
|
1666
1555
|
}
|
|
1556
|
+
break;
|
|
1667
1557
|
}
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
}
|
|
1671
|
-
|
|
1672
|
-
// src/cst/trivia-kinds.ts
|
|
1673
|
-
function unwrapTrivia(p) {
|
|
1674
|
-
let cur = p;
|
|
1675
|
-
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1676
|
-
return cur;
|
|
1558
|
+
return pos;
|
|
1559
|
+
};
|
|
1677
1560
|
}
|
|
1678
|
-
function
|
|
1679
|
-
if (
|
|
1680
|
-
|
|
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);
|
|
1681
1565
|
}
|
|
1682
|
-
function
|
|
1683
|
-
let
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
core = core._def.parser;
|
|
1687
|
-
minRepeats = 1;
|
|
1688
|
-
} else if (core._def.tag === "many") {
|
|
1689
|
-
core = core._def.parser;
|
|
1690
|
-
minRepeats = 0;
|
|
1691
|
-
}
|
|
1692
|
-
const arms = [];
|
|
1693
|
-
if (core._def.tag === "choice") {
|
|
1694
|
-
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1695
|
-
const peeled = peelLabel(core._def.parsers[i]);
|
|
1696
|
-
if (!peeled) return null;
|
|
1697
|
-
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1698
|
-
}
|
|
1699
|
-
} else {
|
|
1700
|
-
const peeled = peelLabel(core);
|
|
1701
|
-
if (!peeled) return null;
|
|
1702
|
-
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;
|
|
1703
1570
|
}
|
|
1704
|
-
return
|
|
1571
|
+
return false;
|
|
1705
1572
|
}
|
|
1706
|
-
function
|
|
1707
|
-
const
|
|
1708
|
-
if (!
|
|
1709
|
-
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
|
+
};
|
|
1710
1581
|
}
|
|
1711
|
-
function
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1720
|
-
break;
|
|
1721
|
-
}
|
|
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++;
|
|
1722
1590
|
}
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
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;
|
|
1726
1603
|
}
|
|
1727
|
-
|
|
1728
|
-
|
|
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) };
|
|
1729
1608
|
}
|
|
1730
|
-
return
|
|
1609
|
+
return null;
|
|
1731
1610
|
}
|
|
1732
|
-
function
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
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;
|
|
1744
1631
|
}
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
const start = pos;
|
|
1753
|
-
pos = j + 2;
|
|
1754
|
-
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
|
+
}
|
|
1755
1639
|
continue;
|
|
1756
1640
|
}
|
|
1757
1641
|
break;
|
|
1758
1642
|
}
|
|
1759
|
-
|
|
1760
|
-
}
|
|
1761
|
-
return { end: pos, chunks };
|
|
1762
|
-
}
|
|
1763
|
-
function tryFastLabeledScan(input, cur, trivia2) {
|
|
1764
|
-
const spec = analyzeLabeledTrivia(trivia2);
|
|
1765
|
-
if (!spec || spec.arms.length !== 2) return null;
|
|
1766
|
-
const wsArm = spec.arms.find((a) => {
|
|
1767
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1768
|
-
return src != null && !src.includes("\\*");
|
|
1769
|
-
});
|
|
1770
|
-
const commentArm = spec.arms.find((a) => {
|
|
1771
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1772
|
-
return src != null && src.includes("\\*");
|
|
1773
|
-
});
|
|
1774
|
-
if (!wsArm || !commentArm) return null;
|
|
1775
|
-
const { chunks } = scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1776
|
-
if (chunks.length < spec.minRepeats) return { end: cur, chunks: [] };
|
|
1777
|
-
return scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1643
|
+
return pos;
|
|
1644
|
+
};
|
|
1778
1645
|
}
|
|
1779
|
-
function
|
|
1780
|
-
const
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
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;
|
|
1788
1665
|
}
|
|
1789
1666
|
}
|
|
1667
|
+
arms.push(body.slice(start));
|
|
1668
|
+
return arms;
|
|
1790
1669
|
}
|
|
1791
|
-
function
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
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);
|
|
1797
1680
|
}
|
|
1798
|
-
|
|
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);
|
|
1799
1692
|
}
|
|
1800
1693
|
|
|
1801
|
-
// src/
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1817
|
-
const probeCtx = {
|
|
1818
|
-
trackLines: ctx.trackLines,
|
|
1819
|
-
state: ctx.state,
|
|
1820
|
-
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1821
|
-
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1822
|
-
...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
|
|
1823
1709
|
};
|
|
1824
|
-
|
|
1825
|
-
ctx.
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
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
|
+
}
|
|
1834
1738
|
}
|
|
1835
|
-
function
|
|
1836
|
-
|
|
1837
|
-
const spec = analyzeLabeledTrivia(triviaP);
|
|
1838
|
-
if (!spec) return { end: cur, commit: NOOP_COMMIT };
|
|
1839
|
-
const fast = tryFastLabeledScan(input, cur, triviaP);
|
|
1840
|
-
const { end, chunks } = fast ?? scanLabeledTriviaChunks(input, cur, spec);
|
|
1841
|
-
if (end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1739
|
+
function orSentinel(a, b) {
|
|
1740
|
+
if (b === void 0) return a;
|
|
1842
1741
|
return {
|
|
1843
|
-
|
|
1844
|
-
|
|
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);
|
|
1749
|
+
}
|
|
1845
1750
|
};
|
|
1846
1751
|
}
|
|
1847
|
-
function
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
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 } };
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
1856
1767
|
}
|
|
1857
|
-
|
|
1858
|
-
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1859
|
-
}
|
|
1860
|
-
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1861
|
-
const fast = fastTriviaScanner(triviaP);
|
|
1862
|
-
if (fast) {
|
|
1863
|
-
const end = fast(input, cur);
|
|
1864
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1865
|
-
return end;
|
|
1866
|
-
}
|
|
1867
|
-
if (ctx.triviaKindLabels) {
|
|
1868
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1869
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1870
|
-
return scan.end;
|
|
1871
|
-
}
|
|
1872
|
-
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1873
|
-
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1768
|
+
};
|
|
1874
1769
|
}
|
|
1875
|
-
function
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
const
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
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 };
|
|
1778
|
+
}
|
|
1779
|
+
function matchesAt(sentinel, input, pos, ctx) {
|
|
1780
|
+
return probeAt(sentinel, input, pos, ctx);
|
|
1781
|
+
}
|
|
1782
|
+
function captureError(ctx, error) {
|
|
1783
|
+
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1784
|
+
}
|
|
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;
|
|
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;
|
|
1833
|
+
}
|
|
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
|
+
};
|
|
1884
|
+
}
|
|
1885
|
+
};
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
// src/combinators/expect.ts
|
|
1889
|
+
function deriveExpected(c) {
|
|
1890
|
+
return [...new Set(derive(c, /* @__PURE__ */ new Set()))];
|
|
1891
|
+
}
|
|
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 [];
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
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
|
|
1971
|
+
};
|
|
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 } };
|
|
1984
|
+
}
|
|
1985
|
+
};
|
|
1986
|
+
}
|
|
1987
|
+
function isParseError(value) {
|
|
1988
|
+
return typeof value === "object" && value !== null && value._tag === "parseError";
|
|
1989
|
+
}
|
|
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]);
|
|
2019
|
+
}
|
|
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 } };
|
|
1900
2073
|
}
|
|
1901
|
-
|
|
1902
|
-
}
|
|
1903
|
-
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1904
|
-
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1905
|
-
}
|
|
1906
|
-
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1907
|
-
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1908
|
-
if (fast && log === void 0 && !captureTl) {
|
|
1909
|
-
const end = fast(input, cur);
|
|
1910
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1911
|
-
return { end, commit: NOOP_COMMIT };
|
|
1912
|
-
}
|
|
1913
|
-
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1914
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1915
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1916
|
-
return scan;
|
|
1917
|
-
}
|
|
1918
|
-
if (log !== void 0 || captureTl) {
|
|
1919
|
-
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1920
|
-
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1921
|
-
const end = tr2.span.end;
|
|
1922
|
-
return {
|
|
1923
|
-
end,
|
|
1924
|
-
commit: () => {
|
|
1925
|
-
pushTriviaLogEntry(ctx, cur, end);
|
|
1926
|
-
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
2074
|
+
return superResult;
|
|
1927
2075
|
}
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
function consumeTrivia(input, cur, ctx) {
|
|
1934
|
-
if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
|
|
1935
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
1936
|
-
scan.commit();
|
|
1937
|
-
return scan.end;
|
|
1938
|
-
}
|
|
1939
|
-
function fastTriviaScanner(trivia2) {
|
|
1940
|
-
const cached = fastTriviaCache.get(trivia2);
|
|
1941
|
-
if (cached !== void 0) return cached;
|
|
1942
|
-
const scanner = buildFastTriviaScanner(trivia2);
|
|
1943
|
-
fastTriviaCache.set(trivia2, scanner);
|
|
1944
|
-
return scanner;
|
|
1945
|
-
}
|
|
1946
|
-
function buildFastTriviaScanner(trivia2) {
|
|
1947
|
-
const core = trivia2._def.tag === "trivia" ? trivia2._def.parser : trivia2;
|
|
1948
|
-
const direct = regexTriviaScanner(core);
|
|
1949
|
-
if (direct) return direct;
|
|
1950
|
-
const repeat = core._def.tag === "oneOrMore" || core._def.tag === "many" && core._def.min >= 1 ? core._def.parser : null;
|
|
1951
|
-
if (!repeat) return null;
|
|
1952
|
-
const one = regexTriviaScanner(repeat);
|
|
1953
|
-
if (one) return loopScanner([one]);
|
|
1954
|
-
if (repeat._def.tag !== "choice") return null;
|
|
1955
|
-
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1956
|
-
if (arms.some((s) => s === null)) return null;
|
|
1957
|
-
return loopScanner(arms);
|
|
1958
|
-
}
|
|
1959
|
-
function loopScanner(arms) {
|
|
1960
|
-
return (input, cur) => {
|
|
1961
|
-
let pos = cur;
|
|
1962
|
-
scan: while (pos < input.length) {
|
|
1963
|
-
for (const arm of arms) {
|
|
1964
|
-
const end = arm(input, pos);
|
|
1965
|
-
if (end > pos) {
|
|
1966
|
-
pos = end;
|
|
1967
|
-
continue scan;
|
|
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);
|
|
1968
2081
|
}
|
|
2082
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1969
2083
|
}
|
|
1970
|
-
|
|
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 } };
|
|
1971
2102
|
}
|
|
1972
|
-
return pos;
|
|
1973
2103
|
};
|
|
1974
2104
|
}
|
|
1975
|
-
function
|
|
1976
|
-
|
|
1977
|
-
const
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
for (let i = 0; i < ranges.length; i++) {
|
|
1982
|
-
const r = ranges[i];
|
|
1983
|
-
if (cp >= r[0] && cp <= r[1]) return true;
|
|
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);
|
|
1984
2111
|
}
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
}
|
|
1996
|
-
|
|
1997
|
-
return (input, cur) => {
|
|
1998
|
-
if (input.charCodeAt(cur) !== commentCode) return cur;
|
|
1999
|
-
let pos = cur + 1;
|
|
2000
|
-
while (pos < input.length) {
|
|
2001
|
-
const cc = input.charCodeAt(pos);
|
|
2002
|
-
if (cc === 10 || cc === 13) break;
|
|
2003
|
-
pos++;
|
|
2004
|
-
}
|
|
2005
|
-
return pos;
|
|
2006
|
-
};
|
|
2007
|
-
}
|
|
2008
|
-
function classRunSource(source) {
|
|
2009
|
-
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
2010
|
-
return m ? classScanner(m[1]) : null;
|
|
2011
|
-
}
|
|
2012
|
-
function classifyTriviaArm(arm) {
|
|
2013
|
-
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
2014
|
-
if (cls) {
|
|
2015
|
-
const ranges = parseClassRanges(cls[1]);
|
|
2016
|
-
return ranges ? { kind: "class", ranges } : null;
|
|
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 };
|
|
2017
2124
|
}
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
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 };
|
|
2022
2130
|
}
|
|
2023
|
-
|
|
2131
|
+
const shared = detectSharedPrefix(parsers);
|
|
2132
|
+
if (shared !== null) return shared;
|
|
2133
|
+
return { tag: "firstMatch" };
|
|
2024
2134
|
}
|
|
2025
|
-
function
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
2031
|
-
return pos;
|
|
2032
|
-
};
|
|
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}`;
|
|
2139
|
+
return null;
|
|
2033
2140
|
}
|
|
2034
|
-
function
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
}
|
|
2053
|
-
continue;
|
|
2054
|
-
}
|
|
2055
|
-
break;
|
|
2056
|
-
}
|
|
2057
|
-
return pos;
|
|
2058
|
-
};
|
|
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 };
|
|
2059
2159
|
}
|
|
2060
|
-
function
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
const c = body[i];
|
|
2066
|
-
if (c === "\\") {
|
|
2067
|
-
i++;
|
|
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;
|
|
2068
2165
|
continue;
|
|
2069
2166
|
}
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
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) });
|
|
2182
|
+
continue;
|
|
2183
|
+
}
|
|
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 });
|
|
2188
|
+
}
|
|
2073
2189
|
}
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2190
|
+
return checks.length > 0 ? checks : null;
|
|
2191
|
+
});
|
|
2192
|
+
}
|
|
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;
|
|
2079
2200
|
}
|
|
2080
2201
|
}
|
|
2081
|
-
|
|
2082
|
-
return arms;
|
|
2202
|
+
return false;
|
|
2083
2203
|
}
|
|
2084
|
-
function
|
|
2085
|
-
const
|
|
2086
|
-
if (!
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
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;
|
|
2216
|
+
}
|
|
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);
|
|
2094
2222
|
}
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2223
|
+
return value;
|
|
2224
|
+
}
|
|
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);
|
|
2100
2235
|
}
|
|
2101
|
-
if (
|
|
2102
|
-
|
|
2236
|
+
if (contCodes.length === 0) return null;
|
|
2237
|
+
return codesToFirstSet(contCodes);
|
|
2238
|
+
}
|
|
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];
|
|
2249
|
+
}
|
|
2103
2250
|
}
|
|
2104
|
-
|
|
2105
|
-
return
|
|
2251
|
+
ranges.push({ lo, hi });
|
|
2252
|
+
return { kind: "ranges", ranges };
|
|
2106
2253
|
}
|
|
2107
|
-
function
|
|
2108
|
-
|
|
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;
|
|
2109
2259
|
}
|
|
2110
|
-
function
|
|
2111
|
-
if (
|
|
2112
|
-
|
|
2113
|
-
|
|
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;
|
|
2114
2266
|
}
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
isTrivia: false
|
|
2124
|
-
};
|
|
2125
|
-
const def = { tag: "sequence", parsers };
|
|
2126
|
-
let followSentinels;
|
|
2127
|
-
function parseTolerant(input, pos, ctx) {
|
|
2128
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
2129
|
-
const fs = parsers.slice(i + 1).reduce(
|
|
2130
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
2131
|
-
{ kind: "empty" }
|
|
2132
|
-
);
|
|
2133
|
-
return firstSetSentinel(fs);
|
|
2134
|
-
});
|
|
2135
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2136
|
-
let cur = pos;
|
|
2137
|
-
const inheritedSync = ctx._sync;
|
|
2138
|
-
try {
|
|
2139
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
2140
|
-
ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
2141
|
-
if (ctx.trivia && i > 0) {
|
|
2142
|
-
const mark = saveTriviaMark(ctx);
|
|
2143
|
-
let scanEnd;
|
|
2144
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2145
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
2146
|
-
scan.commit();
|
|
2147
|
-
scanEnd = scan.end;
|
|
2148
|
-
} else {
|
|
2149
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2150
|
-
}
|
|
2151
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2152
|
-
if (!result2.ok) return result2;
|
|
2153
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2154
|
-
else rollbackTrivia(ctx, mark);
|
|
2155
|
-
if (values !== void 0) values.push(result2.value);
|
|
2156
|
-
continue;
|
|
2157
|
-
}
|
|
2158
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2159
|
-
if (!result.ok) return result;
|
|
2160
|
-
if (values !== void 0) values.push(result.value);
|
|
2161
|
-
cur = result.span.end;
|
|
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;
|
|
2162
2275
|
}
|
|
2163
|
-
} finally {
|
|
2164
|
-
ctx._sync = inheritedSync;
|
|
2165
2276
|
}
|
|
2166
|
-
return {
|
|
2167
|
-
ok: true,
|
|
2168
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2169
|
-
value: values ?? void 0,
|
|
2170
|
-
span: { start: pos, end: cur }
|
|
2171
|
-
};
|
|
2172
2277
|
}
|
|
2173
|
-
return
|
|
2174
|
-
_tag: "sequence",
|
|
2175
|
-
_meta: meta,
|
|
2176
|
-
_def: def,
|
|
2177
|
-
parse(input, pos, ctx) {
|
|
2178
|
-
if (ctx._tolerant) return parseTolerant(input, pos, ctx);
|
|
2179
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2180
|
-
let cur = pos;
|
|
2181
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
2182
|
-
if (ctx.trivia && i > 0) {
|
|
2183
|
-
let scanEnd;
|
|
2184
|
-
let mark = saveTriviaMark(ctx);
|
|
2185
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2186
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
2187
|
-
scan.commit();
|
|
2188
|
-
scanEnd = scan.end;
|
|
2189
|
-
} else {
|
|
2190
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2191
|
-
}
|
|
2192
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2193
|
-
if (!result2.ok) return result2;
|
|
2194
|
-
if (result2.span.end > scanEnd) {
|
|
2195
|
-
cur = result2.span.end;
|
|
2196
|
-
} else {
|
|
2197
|
-
rollbackTrivia(ctx, mark);
|
|
2198
|
-
}
|
|
2199
|
-
if (values !== void 0) values.push(result2.value);
|
|
2200
|
-
continue;
|
|
2201
|
-
}
|
|
2202
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2203
|
-
if (!result.ok) return result;
|
|
2204
|
-
if (values !== void 0) values.push(result.value);
|
|
2205
|
-
cur = result.span.end;
|
|
2206
|
-
}
|
|
2207
|
-
return {
|
|
2208
|
-
ok: true,
|
|
2209
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2210
|
-
value: values ?? void 0,
|
|
2211
|
-
span: { start: pos, end: cur }
|
|
2212
|
-
};
|
|
2213
|
-
}
|
|
2214
|
-
};
|
|
2278
|
+
return table;
|
|
2215
2279
|
}
|
|
2216
2280
|
|
|
2217
2281
|
// src/combinators/dispatch.ts
|
|
@@ -2474,10 +2538,12 @@ function attempt(parser2) {
|
|
|
2474
2538
|
}
|
|
2475
2539
|
const mark = saveCstMark(ctx);
|
|
2476
2540
|
const log = ctx._triviaLog?.length;
|
|
2541
|
+
const rootLog = ctx._rootTriviaLog?.length;
|
|
2477
2542
|
const result = parser2.parse(input, pos, ctx);
|
|
2478
2543
|
if (result.ok) return result;
|
|
2479
2544
|
rollbackCstCapture(ctx, mark);
|
|
2480
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;
|
|
2481
2547
|
if (result.committed) return result;
|
|
2482
2548
|
return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
|
|
2483
2549
|
}
|
|
@@ -2918,18 +2984,37 @@ function createParseLineContext(input, pos) {
|
|
|
2918
2984
|
}
|
|
2919
2985
|
function parser(opts, root) {
|
|
2920
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
|
+
}
|
|
2921
2991
|
return {
|
|
2922
2992
|
_tag: "grammar",
|
|
2923
|
-
_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
|
+
},
|
|
2924
3003
|
_def: {
|
|
2925
3004
|
tag: "grammar",
|
|
2926
3005
|
parser: root,
|
|
2927
3006
|
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2928
3007
|
clearTrivia,
|
|
3008
|
+
...opaqueRootCapture ? { rootCapture: "opaque" } : {},
|
|
2929
3009
|
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2930
3010
|
trackLines: opts.trackLines ?? false
|
|
2931
3011
|
},
|
|
2932
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
|
+
}
|
|
2933
3018
|
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2934
3019
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2935
3020
|
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
@@ -2952,7 +3037,11 @@ function parser(opts, root) {
|
|
|
2952
3037
|
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2953
3038
|
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2954
3039
|
// (capture all).
|
|
2955
|
-
...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 } : {}
|
|
2956
3045
|
};
|
|
2957
3046
|
const result = root.parse(input, pos ?? 0, ctx);
|
|
2958
3047
|
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
@@ -2993,6 +3082,126 @@ function parse(combinator, input, opts = {}) {
|
|
|
2993
3082
|
return lineIndex ? annotateResultLines(withErrors, normalizeLineIndex(lineIndex)) : withErrors;
|
|
2994
3083
|
}
|
|
2995
3084
|
|
|
3085
|
+
// src/cst/reflection.ts
|
|
3086
|
+
var GRAMMAR_REFLECTION = /* @__PURE__ */ Symbol.for("parseman.grammarReflection");
|
|
3087
|
+
function childrenOf(def) {
|
|
3088
|
+
switch (def.tag) {
|
|
3089
|
+
case "sequence":
|
|
3090
|
+
case "choice":
|
|
3091
|
+
return def.parsers;
|
|
3092
|
+
case "dispatch":
|
|
3093
|
+
return [
|
|
3094
|
+
def.selector,
|
|
3095
|
+
...def.cases.map((c) => c.parser),
|
|
3096
|
+
...def.matchers ? def.matchers.map((c) => c.parser) : [],
|
|
3097
|
+
...def.otherwise ? [def.otherwise] : []
|
|
3098
|
+
];
|
|
3099
|
+
case "many":
|
|
3100
|
+
case "oneOrMore":
|
|
3101
|
+
case "optional":
|
|
3102
|
+
case "attempt":
|
|
3103
|
+
case "transform":
|
|
3104
|
+
case "trivia":
|
|
3105
|
+
case "token":
|
|
3106
|
+
case "leaf":
|
|
3107
|
+
case "label":
|
|
3108
|
+
case "field":
|
|
3109
|
+
case "not":
|
|
3110
|
+
case "peek":
|
|
3111
|
+
case "node":
|
|
3112
|
+
case "withCtx":
|
|
3113
|
+
case "recover":
|
|
3114
|
+
case "expect":
|
|
3115
|
+
return [def.parser];
|
|
3116
|
+
case "grammar":
|
|
3117
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
3118
|
+
case "sepBy":
|
|
3119
|
+
return [def.parser, def.separator];
|
|
3120
|
+
case "skip":
|
|
3121
|
+
return [def.main, def.skipped];
|
|
3122
|
+
case "scanTo":
|
|
3123
|
+
return [def.sentinel, ...def.skip];
|
|
3124
|
+
case "literal":
|
|
3125
|
+
case "regex":
|
|
3126
|
+
case "keywords":
|
|
3127
|
+
case "routed":
|
|
3128
|
+
case "guard":
|
|
3129
|
+
case "lazy":
|
|
3130
|
+
case "unknown":
|
|
3131
|
+
return [];
|
|
3132
|
+
}
|
|
3133
|
+
}
|
|
3134
|
+
function addNode(out, def) {
|
|
3135
|
+
if (def.type === void 0) return;
|
|
3136
|
+
const existing = out.get(def.type);
|
|
3137
|
+
if (existing === void 0) {
|
|
3138
|
+
out.set(def.type, def.tags === void 0 ? [] : [...def.tags]);
|
|
3139
|
+
return;
|
|
3140
|
+
}
|
|
3141
|
+
if (def.tags === void 0) return;
|
|
3142
|
+
for (const tag of def.tags) {
|
|
3143
|
+
if (!existing.includes(tag)) existing.push(tag);
|
|
3144
|
+
}
|
|
3145
|
+
}
|
|
3146
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
3147
|
+
if (seen.has(parser2)) return;
|
|
3148
|
+
seen.add(parser2);
|
|
3149
|
+
const def = parser2._def;
|
|
3150
|
+
if (def.tag === "lazy") {
|
|
3151
|
+
if (followLazy) {
|
|
3152
|
+
try {
|
|
3153
|
+
collectFromCombinator(def.thunk(), out, seen, followLazy);
|
|
3154
|
+
} catch {
|
|
3155
|
+
}
|
|
3156
|
+
}
|
|
3157
|
+
return;
|
|
3158
|
+
}
|
|
3159
|
+
if (def.tag === "node") addNode(out, def);
|
|
3160
|
+
for (const child of childrenOf(def)) collectFromCombinator(child, out, seen, followLazy);
|
|
3161
|
+
}
|
|
3162
|
+
function collectGrammarReflection(ruleMap, opts) {
|
|
3163
|
+
const byType = /* @__PURE__ */ new Map();
|
|
3164
|
+
const followLazy = opts?.followLazy !== false;
|
|
3165
|
+
for (const [, rule] of ruleMap) {
|
|
3166
|
+
if (!followLazy && rule._def.tag === "lazy") {
|
|
3167
|
+
try {
|
|
3168
|
+
const resolved = rule._def.thunk();
|
|
3169
|
+
if (resolved._def.tag !== "lazy") collectFromCombinator(resolved, byType, /* @__PURE__ */ new Set(), false);
|
|
3170
|
+
} catch {
|
|
3171
|
+
}
|
|
3172
|
+
continue;
|
|
3173
|
+
}
|
|
3174
|
+
collectFromCombinator(rule, byType, /* @__PURE__ */ new Set(), followLazy);
|
|
3175
|
+
}
|
|
3176
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
3177
|
+
}
|
|
3178
|
+
function mergeGrammarReflections(reflections) {
|
|
3179
|
+
const byType = /* @__PURE__ */ new Map();
|
|
3180
|
+
for (const reflection of reflections) {
|
|
3181
|
+
for (const node2 of reflection.nodes) {
|
|
3182
|
+
const tags = byType.get(node2.type);
|
|
3183
|
+
if (tags === void 0) {
|
|
3184
|
+
byType.set(node2.type, [...node2.tags]);
|
|
3185
|
+
continue;
|
|
3186
|
+
}
|
|
3187
|
+
for (const tag of node2.tags) {
|
|
3188
|
+
if (!tags.includes(tag)) tags.push(tag);
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
3193
|
+
}
|
|
3194
|
+
function attachGrammarReflection(grammar, reflection) {
|
|
3195
|
+
Object.defineProperty(grammar, GRAMMAR_REFLECTION, { value: reflection, enumerable: false, configurable: true });
|
|
3196
|
+
return grammar;
|
|
3197
|
+
}
|
|
3198
|
+
function grammarReflectionOf(grammar) {
|
|
3199
|
+
return grammar[GRAMMAR_REFLECTION];
|
|
3200
|
+
}
|
|
3201
|
+
function grammarReflectionSource(reflection) {
|
|
3202
|
+
return `{ nodes: ${JSON.stringify(reflection.nodes)} }`;
|
|
3203
|
+
}
|
|
3204
|
+
|
|
2996
3205
|
// src/combinators/parser.ts
|
|
2997
3206
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2998
3207
|
function tagRule(r, key) {
|
|
@@ -3091,6 +3300,7 @@ function rules(a, b) {
|
|
|
3091
3300
|
enumerable: false,
|
|
3092
3301
|
configurable: true
|
|
3093
3302
|
});
|
|
3303
|
+
attachGrammarReflection(cache, collectGrammarReflection(Object.keys(definitions).map((key) => [key, cache[key]])));
|
|
3094
3304
|
return cache;
|
|
3095
3305
|
}
|
|
3096
3306
|
|
|
@@ -3411,13 +3621,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3411
3621
|
const collapse = opts?.collapse === true;
|
|
3412
3622
|
const captureTrivia = opts?.captureTrivia === true;
|
|
3413
3623
|
const trailingTrivia = opts?.trailingTrivia === true;
|
|
3624
|
+
const tags = opts?.tags;
|
|
3414
3625
|
if (unwrap && collapse) {
|
|
3415
3626
|
throw new Error("node() options cannot set both unwrap and collapse");
|
|
3416
3627
|
}
|
|
3417
3628
|
if (project !== void 0 && (unwrap || collapse)) {
|
|
3418
3629
|
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
3419
3630
|
}
|
|
3420
|
-
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {} } : baseDef;
|
|
3631
|
+
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
|
|
3421
3632
|
const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
3422
3633
|
const clonesState = build ? buildReadsState(def) : project === void 0;
|
|
3423
3634
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
@@ -3463,7 +3674,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3463
3674
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3464
3675
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3465
3676
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3466
|
-
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
3677
|
+
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
3467
3678
|
const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
|
|
3468
3679
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3469
3680
|
pushCstChild(ctx, built, rawEntry);
|
|
@@ -3513,6 +3724,25 @@ function trivia(combinator) {
|
|
|
3513
3724
|
parse: combinator.parse.bind(combinator)
|
|
3514
3725
|
};
|
|
3515
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
|
+
}
|
|
3516
3746
|
function label(name, combinator) {
|
|
3517
3747
|
return {
|
|
3518
3748
|
_tag: combinator._tag,
|
|
@@ -3559,6 +3789,7 @@ function token(root) {
|
|
|
3559
3789
|
const savedRaw = ctx._cstRawChildren;
|
|
3560
3790
|
const savedTriviaLog = ctx._cstTriviaLog;
|
|
3561
3791
|
const savedOuterTriviaLog = ctx._triviaLog;
|
|
3792
|
+
const savedRootTriviaLog = ctx._rootTriviaLog;
|
|
3562
3793
|
const wasCapturing = cstCaptureActive(ctx);
|
|
3563
3794
|
ctx.trivia = void 0;
|
|
3564
3795
|
ctx.triviaKindLabels = void 0;
|
|
@@ -3568,6 +3799,7 @@ function token(root) {
|
|
|
3568
3799
|
ctx._cstRawChildren = void 0;
|
|
3569
3800
|
ctx._cstTriviaLog = void 0;
|
|
3570
3801
|
delete ctx._triviaLog;
|
|
3802
|
+
delete ctx._rootTriviaLog;
|
|
3571
3803
|
let result;
|
|
3572
3804
|
try {
|
|
3573
3805
|
result = root.parse(input, pos, ctx);
|
|
@@ -3581,6 +3813,8 @@ function token(root) {
|
|
|
3581
3813
|
ctx._cstTriviaLog = savedTriviaLog;
|
|
3582
3814
|
if (savedOuterTriviaLog === void 0) delete ctx._triviaLog;
|
|
3583
3815
|
else ctx._triviaLog = savedOuterTriviaLog;
|
|
3816
|
+
if (savedRootTriviaLog === void 0) delete ctx._rootTriviaLog;
|
|
3817
|
+
else ctx._rootTriviaLog = savedRootTriviaLog;
|
|
3584
3818
|
}
|
|
3585
3819
|
if (!result.ok) return result;
|
|
3586
3820
|
const span = result.span;
|
|
@@ -3635,7 +3869,7 @@ function leaf(root, fn) {
|
|
|
3635
3869
|
}
|
|
3636
3870
|
|
|
3637
3871
|
// src/version.ts
|
|
3638
|
-
var PARSEMAN_VERSION = "0.
|
|
3872
|
+
var PARSEMAN_VERSION = "0.44.0";
|
|
3639
3873
|
|
|
3640
3874
|
// src/cst/host-mode.ts
|
|
3641
3875
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -3701,7 +3935,7 @@ var SUGGESTIONS = {
|
|
|
3701
3935
|
function classifyBroadArm(arm, resolve) {
|
|
3702
3936
|
const seen = /* @__PURE__ */ new Set();
|
|
3703
3937
|
const relabel = (inner, cause, detail) => ({ cause, detail, ...inner?.unresolvedExternal ? { unresolvedExternal: true } : {} });
|
|
3704
|
-
const
|
|
3938
|
+
const walk = (p) => {
|
|
3705
3939
|
if (seen.has(p)) return { cause: "ref-cycle", detail: "ref cycle" };
|
|
3706
3940
|
seen.add(p);
|
|
3707
3941
|
const d = p._def;
|
|
@@ -3715,7 +3949,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3715
3949
|
// peek() CARRIES its body's first-set, so it is only broad when the body is
|
|
3716
3950
|
// (or the body is nullable) — walk in for the real cause.
|
|
3717
3951
|
case "peek":
|
|
3718
|
-
return
|
|
3952
|
+
return walk(d.parser);
|
|
3719
3953
|
case "scanTo":
|
|
3720
3954
|
return { cause: "broad-recognizer", detail: "scanTo (any first char)" };
|
|
3721
3955
|
// `guard` (the `gate()` state predicate) has a genuinely-`any` first-set of
|
|
@@ -3729,7 +3963,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3729
3963
|
case "attempt":
|
|
3730
3964
|
case "withCtx":
|
|
3731
3965
|
case "recover":
|
|
3732
|
-
return
|
|
3966
|
+
return walk(d.parser);
|
|
3733
3967
|
case "lazy": {
|
|
3734
3968
|
const name = p._ruleName;
|
|
3735
3969
|
let target;
|
|
@@ -3741,13 +3975,13 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3741
3975
|
return { cause: "cross-artifact-ref", detail: `unresolved ref${name ? ` g.${name}` : ""}`, unresolvedExternal: name !== void 0 };
|
|
3742
3976
|
target = bound;
|
|
3743
3977
|
}
|
|
3744
|
-
const inner =
|
|
3978
|
+
const inner = walk(target);
|
|
3745
3979
|
if (name !== void 0) return inner ? relabel(inner, "cross-artifact-ref", `via ref g.${name} \u2192 ${inner.detail}`) : null;
|
|
3746
3980
|
return inner;
|
|
3747
3981
|
}
|
|
3748
3982
|
case "optional":
|
|
3749
3983
|
case "many": {
|
|
3750
|
-
const inner =
|
|
3984
|
+
const inner = walk(d.parser);
|
|
3751
3985
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3752
3986
|
}
|
|
3753
3987
|
case "oneOrMore":
|
|
@@ -3760,9 +3994,9 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3760
3994
|
case "node":
|
|
3761
3995
|
case "grammar":
|
|
3762
3996
|
case "expect":
|
|
3763
|
-
return
|
|
3997
|
+
return walk(d.parser);
|
|
3764
3998
|
case "skip":
|
|
3765
|
-
return
|
|
3999
|
+
return walk(d.main);
|
|
3766
4000
|
case "sequence": {
|
|
3767
4001
|
let sawNullablePrefix = false;
|
|
3768
4002
|
for (const t of d.parsers) {
|
|
@@ -3771,7 +4005,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3771
4005
|
continue;
|
|
3772
4006
|
}
|
|
3773
4007
|
if (isAny(firstSetOf(t, /* @__PURE__ */ new Set(), resolve))) {
|
|
3774
|
-
const inner =
|
|
4008
|
+
const inner = walk(t);
|
|
3775
4009
|
if (sawNullablePrefix)
|
|
3776
4010
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3777
4011
|
return inner ?? { cause: "broad-recognizer", detail: "sequence leading term is broad" };
|
|
@@ -3786,18 +4020,18 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3786
4020
|
}
|
|
3787
4021
|
case "choice": {
|
|
3788
4022
|
for (const a of d.parsers) {
|
|
3789
|
-
const r =
|
|
4023
|
+
const r = walk(a);
|
|
3790
4024
|
if (r) return relabel(r, r.cause, `choice arm \u2192 ${r.detail}`);
|
|
3791
4025
|
}
|
|
3792
4026
|
return null;
|
|
3793
4027
|
}
|
|
3794
4028
|
case "dispatch":
|
|
3795
|
-
return
|
|
4029
|
+
return walk(d.selector);
|
|
3796
4030
|
default:
|
|
3797
4031
|
return { cause: "broad-recognizer", detail: `unmodeled construct (${d.tag})` };
|
|
3798
4032
|
}
|
|
3799
4033
|
};
|
|
3800
|
-
return
|
|
4034
|
+
return walk(arm) ?? { cause: "broad-recognizer", detail: "broad (cause not localized)" };
|
|
3801
4035
|
}
|
|
3802
4036
|
function peelToLeading(arm) {
|
|
3803
4037
|
let d = arm._def;
|
|
@@ -3999,7 +4233,7 @@ function formatGatingWarnings(report) {
|
|
|
3999
4233
|
|
|
4000
4234
|
// src/analysis/duplication.ts
|
|
4001
4235
|
var siteToString = (s) => s.path === "" ? s.rule : `${s.rule} \u203A ${s.path}`;
|
|
4002
|
-
function
|
|
4236
|
+
function childrenOf2(d) {
|
|
4003
4237
|
switch (d.tag) {
|
|
4004
4238
|
case "sequence":
|
|
4005
4239
|
case "choice":
|
|
@@ -4133,7 +4367,7 @@ function render(p, depth = 3) {
|
|
|
4133
4367
|
break;
|
|
4134
4368
|
}
|
|
4135
4369
|
if (depth <= 0) return `${d.tag}(\u2026)`;
|
|
4136
|
-
const kids =
|
|
4370
|
+
const kids = childrenOf2(d).map((k) => render(k, depth - 1));
|
|
4137
4371
|
switch (d.tag) {
|
|
4138
4372
|
case "sequence":
|
|
4139
4373
|
return `sequence(${kids.join(", ")})`;
|
|
@@ -4328,7 +4562,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4328
4562
|
if (hit !== void 0) return hit;
|
|
4329
4563
|
const d = p._def;
|
|
4330
4564
|
shapeCache.set(p, interner.hole);
|
|
4331
|
-
const kids =
|
|
4565
|
+
const kids = childrenOf2(d);
|
|
4332
4566
|
const id = interner.of(`${payloadKey(p, d)}|${kids.map(shapeOf).join(",")}`);
|
|
4333
4567
|
shapeCache.set(p, id);
|
|
4334
4568
|
return id;
|
|
@@ -4338,7 +4572,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4338
4572
|
if (hit !== void 0) return hit;
|
|
4339
4573
|
sizeCache.set(p, 1);
|
|
4340
4574
|
let n = 1;
|
|
4341
|
-
for (const k of
|
|
4575
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4342
4576
|
sizeCache.set(p, n);
|
|
4343
4577
|
return n;
|
|
4344
4578
|
};
|
|
@@ -4351,7 +4585,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4351
4585
|
visited.set(p, { p, d, site: here, shape: shapeOf(p), size: sizeOf(p), enclosingNode, enclosingReducer });
|
|
4352
4586
|
const inner = d.tag === "node" ? d.type ?? "(anonymous)" : enclosingNode;
|
|
4353
4587
|
const innerReducer = enclosingReducer || d.tag === "node" && (d.build !== void 0 || d.buildSrc !== void 0) || d.tag === "transform" || d.tag === "leaf";
|
|
4354
|
-
const kids =
|
|
4588
|
+
const kids = childrenOf2(d);
|
|
4355
4589
|
kids.forEach((k, i) => {
|
|
4356
4590
|
const seg = segment(d, i);
|
|
4357
4591
|
visit(k, here.rule, here.path === "" ? seg : `${here.path} \u203A ${seg}`, inner, innerReducer);
|
|
@@ -4411,7 +4645,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4411
4645
|
function markSubtree(p, into) {
|
|
4412
4646
|
if (into.has(p)) return;
|
|
4413
4647
|
into.add(p);
|
|
4414
|
-
for (const k of
|
|
4648
|
+
for (const k of childrenOf2(p._def)) markSubtree(k, into);
|
|
4415
4649
|
}
|
|
4416
4650
|
var stripMembers = (f) => {
|
|
4417
4651
|
const { _members, ...rest } = f;
|
|
@@ -4451,7 +4685,7 @@ function findNearDuplicates(visited, interner, shapeOf, minSize) {
|
|
|
4451
4685
|
if (hit !== void 0) return hit;
|
|
4452
4686
|
holeCache.set(p, []);
|
|
4453
4687
|
const d = p._def;
|
|
4454
|
-
const kids =
|
|
4688
|
+
const kids = childrenOf2(d);
|
|
4455
4689
|
const kidShapes = kids.map(shapeOf);
|
|
4456
4690
|
const payload = payloadKey(p, d);
|
|
4457
4691
|
const out2 = [];
|
|
@@ -4512,7 +4746,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4512
4746
|
let cur = [...members];
|
|
4513
4747
|
for (let guard2 = 0; guard2 < 64; guard2++) {
|
|
4514
4748
|
const d0 = cur[0]._def;
|
|
4515
|
-
const kidLists = cur.map((c) =>
|
|
4749
|
+
const kidLists = cur.map((c) => childrenOf2(c._def));
|
|
4516
4750
|
const arity = kidLists[0].length;
|
|
4517
4751
|
if (kidLists.some((k) => k.length !== arity) || arity === 0) break;
|
|
4518
4752
|
const diff = [];
|
|
@@ -4525,7 +4759,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4525
4759
|
path.push(i);
|
|
4526
4760
|
defs.push(d0);
|
|
4527
4761
|
cur = kidLists.map((k) => k[i]);
|
|
4528
|
-
const nextArity =
|
|
4762
|
+
const nextArity = childrenOf2(cur[0]._def).length;
|
|
4529
4763
|
const samePayload = cur.every((c) => payloadKey(c, c._def) === payloadKey(cur[0], cur[0]._def));
|
|
4530
4764
|
if (!samePayload || nextArity === 0) break;
|
|
4531
4765
|
}
|
|
@@ -4533,7 +4767,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4533
4767
|
let slotSize = 0;
|
|
4534
4768
|
const sizeOf = (p) => {
|
|
4535
4769
|
let n = 1;
|
|
4536
|
-
for (const k of
|
|
4770
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4537
4771
|
return n;
|
|
4538
4772
|
};
|
|
4539
4773
|
for (const c of cur) slotSize = Math.max(slotSize, sizeOf(c));
|
|
@@ -4542,7 +4776,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4542
4776
|
function renderWithHole(p, path, depth = 0) {
|
|
4543
4777
|
if (depth === path.length) return "\u2039slot\u203A";
|
|
4544
4778
|
const d = p._def;
|
|
4545
|
-
const kids =
|
|
4779
|
+
const kids = childrenOf2(d);
|
|
4546
4780
|
const idx = path[depth];
|
|
4547
4781
|
const parts = kids.map((k, i) => i === idx ? renderWithHole(k, path, depth + 1) : render(k, 2));
|
|
4548
4782
|
switch (d.tag) {
|
|
@@ -5000,7 +5234,7 @@ function capturesPositionally(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
5000
5234
|
seen.add(p);
|
|
5001
5235
|
const d = p._def;
|
|
5002
5236
|
if (d.tag === "field" || d.tag === "label") return true;
|
|
5003
|
-
for (const k of
|
|
5237
|
+
for (const k of childrenOf2(d)) if (capturesPositionally(k, seen)) return true;
|
|
5004
5238
|
return false;
|
|
5005
5239
|
}
|
|
5006
5240
|
function detectHandRolledSepBy(terms, shapeOf) {
|
|
@@ -5106,7 +5340,7 @@ function nestedNodeTypes(root, out, seen, isRoot) {
|
|
|
5106
5340
|
}
|
|
5107
5341
|
return;
|
|
5108
5342
|
}
|
|
5109
|
-
for (const k of
|
|
5343
|
+
for (const k of childrenOf2(d)) nestedNodeTypes(k, out, seen, false);
|
|
5110
5344
|
}
|
|
5111
5345
|
var MAX_LOST_TYPES = 8;
|
|
5112
5346
|
function findStructureLoss(visited, resolve) {
|
|
@@ -5533,9 +5767,196 @@ function buildGrammarPlan(entry, winners) {
|
|
|
5533
5767
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
|
|
5534
5768
|
}
|
|
5535
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
|
+
|
|
5536
5953
|
// src/compiler/scannable-run.ts
|
|
5537
5954
|
var BACKSLASH = 92;
|
|
5538
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(", ");
|
|
5539
5960
|
function classToRanges(cls) {
|
|
5540
5961
|
if (cls === "\\d") return shorthandRanges("d");
|
|
5541
5962
|
if (cls === "\\w") return shorthandRanges("w");
|
|
@@ -6574,13 +6995,15 @@ function scanBranch(shape, mint) {
|
|
|
6574
6995
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6575
6996
|
return [...m.setup, ` if (${m.end} > _e) { _e = ${m.end}; continue }`].join("\n");
|
|
6576
6997
|
}
|
|
6577
|
-
function scanBranchLabeled(shape, kindIndex, mint) {
|
|
6998
|
+
function scanBranchLabeled(shape, kindIndex, label2, mint) {
|
|
6578
6999
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6579
7000
|
return [
|
|
6580
7001
|
...m.setup,
|
|
6581
7002
|
` if (${m.end} > _e) {`,
|
|
6582
7003
|
` if (_cap) {`,
|
|
6583
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)`,
|
|
6584
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})`,
|
|
6585
7008
|
` }`,
|
|
6586
7009
|
` _e = ${m.end}`,
|
|
@@ -6640,6 +7063,11 @@ var CAP_RECORD = [
|
|
|
6640
7063
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
|
|
6641
7064
|
` }`
|
|
6642
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");
|
|
6643
7071
|
function composeFastLoop(shapes) {
|
|
6644
7072
|
const mint = makeMint();
|
|
6645
7073
|
return [
|
|
@@ -6668,7 +7096,7 @@ function analyzeLabeledScannableRun(trivia2) {
|
|
|
6668
7096
|
const d = getCoreRegexDef(arm.parser);
|
|
6669
7097
|
const shape = d ? scanShapeFromRegex(d.source, d.flags) : null;
|
|
6670
7098
|
if (!shape) return null;
|
|
6671
|
-
out.push({ shape, kindIndex: arm.kindIndex });
|
|
7099
|
+
out.push({ shape, kindIndex: arm.kindIndex, label: arm.label });
|
|
6672
7100
|
}
|
|
6673
7101
|
return out;
|
|
6674
7102
|
}
|
|
@@ -6677,11 +7105,13 @@ function buildLabeledScannableTriviaFnDecl(fnName, arms) {
|
|
|
6677
7105
|
return [
|
|
6678
7106
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6679
7107
|
` let _e = _pos`,
|
|
7108
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6680
7109
|
` while (_e < input.length) {`,
|
|
6681
7110
|
` const c = input.charCodeAt(_e)`,
|
|
6682
|
-
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, mint)),
|
|
7111
|
+
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, a.label, mint)),
|
|
6683
7112
|
` break`,
|
|
6684
7113
|
` }`,
|
|
7114
|
+
SELECTED_ROOT_FINISH,
|
|
6685
7115
|
` return _e`,
|
|
6686
7116
|
`}`
|
|
6687
7117
|
].join("\n");
|
|
@@ -6697,6 +7127,8 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6697
7127
|
` const _ce = _e + _m${i}[0].length`,
|
|
6698
7128
|
` if (_cap) {`,
|
|
6699
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})`,
|
|
6700
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})`,
|
|
6701
7133
|
` }`,
|
|
6702
7134
|
` _e = _ce`,
|
|
@@ -6708,11 +7140,13 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6708
7140
|
return [
|
|
6709
7141
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6710
7142
|
` let _e = _pos`,
|
|
7143
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6711
7144
|
` while (_e < input.length) {`,
|
|
6712
7145
|
` let _matched = false`,
|
|
6713
7146
|
tryArms,
|
|
6714
7147
|
` if (!_matched) break`,
|
|
6715
7148
|
` }`,
|
|
7149
|
+
SELECTED_ROOT_FINISH,
|
|
6716
7150
|
` return _e`,
|
|
6717
7151
|
`}`
|
|
6718
7152
|
].join("\n");
|
|
@@ -6735,6 +7169,8 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6735
7169
|
` const _ce = _r${i}.span.end`,
|
|
6736
7170
|
` if (_cap) {`,
|
|
6737
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})`,
|
|
6738
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})`,
|
|
6739
7175
|
` }`,
|
|
6740
7176
|
` _e = _ce`,
|
|
@@ -6746,11 +7182,13 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6746
7182
|
return [
|
|
6747
7183
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6748
7184
|
` let _e = _pos`,
|
|
7185
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6749
7186
|
` while (_e < input.length) {`,
|
|
6750
7187
|
` let _matched = false`,
|
|
6751
7188
|
tryArms,
|
|
6752
7189
|
` if (!_matched) break`,
|
|
6753
7190
|
` }`,
|
|
7191
|
+
SELECTED_ROOT_FINISH,
|
|
6754
7192
|
` return _e`,
|
|
6755
7193
|
`}`
|
|
6756
7194
|
].join("\n");
|
|
@@ -6973,6 +7411,9 @@ var HOST_READS_DECL = "const _hostReads = (b, n) => { if (b === undefined) retur
|
|
|
6973
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 }";
|
|
6974
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] } }";
|
|
6975
7413
|
var _loweringSink = null;
|
|
7414
|
+
function hasSelectedRootTrivia(ctx) {
|
|
7415
|
+
return ctx.rootTriviaClassified === true;
|
|
7416
|
+
}
|
|
6976
7417
|
function v(ctx, prefix = "_v") {
|
|
6977
7418
|
return `${prefix}${ctx.vars++}`;
|
|
6978
7419
|
}
|
|
@@ -7282,10 +7723,12 @@ function planDisjointDispatch(parsers) {
|
|
|
7282
7723
|
}
|
|
7283
7724
|
return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
7284
7725
|
}
|
|
7285
|
-
function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
|
|
7726
|
+
function captureRestoreBody(ctx, mL, mR, mTl, mLg, mF = null, mRootLg = null) {
|
|
7286
7727
|
const fieldRestore = mF ? `; if (_ctx._fields && _ctx._fields.length !== ${mF}) _ctx._fields.length = ${mF}` : "";
|
|
7287
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}`;
|
|
7288
|
-
|
|
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}`;
|
|
7289
7732
|
}
|
|
7290
7733
|
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
7291
7734
|
if (seen.has(p)) return false;
|
|
@@ -7495,7 +7938,7 @@ function emitFallible(inner, ctx, pos, swallow = false) {
|
|
|
7495
7938
|
`${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
|
|
7496
7939
|
`${ind0}}`,
|
|
7497
7940
|
...mL ? [
|
|
7498
|
-
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
|
|
7941
|
+
`${ind0}if (!${okV}) { ${captureRestoreBody(ctx, mL, mR, mTl, null, mF)} }`
|
|
7499
7942
|
] : []
|
|
7500
7943
|
];
|
|
7501
7944
|
return { stmts, okVar: okV, valVar: valV, endVar: endV, mayCommit };
|
|
@@ -7692,11 +8135,13 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7692
8135
|
const markV = v(ctx, "_mk");
|
|
7693
8136
|
const markTl = v(ctx, "_mktl");
|
|
7694
8137
|
const markLog = v(ctx, "_mklg");
|
|
8138
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7695
8139
|
const scanEndV = v(ctx, "_sne");
|
|
7696
8140
|
stmts.push(
|
|
7697
8141
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7698
8142
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7699
8143
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8144
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7700
8145
|
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7701
8146
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7702
8147
|
);
|
|
@@ -7705,17 +8150,19 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7705
8150
|
const endAfterV = v(ctx, "_sea");
|
|
7706
8151
|
stmts.push(
|
|
7707
8152
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7708
|
-
`${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};` : ""} }`
|
|
7709
8154
|
);
|
|
7710
8155
|
valueVars.push(r2.valueVar);
|
|
7711
8156
|
continue;
|
|
7712
8157
|
} else {
|
|
7713
8158
|
const trivFn = ensureTriviaFn(ctx);
|
|
7714
8159
|
const markLog = v(ctx, "_mklg");
|
|
8160
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7715
8161
|
const scanEndV = v(ctx, "_sne");
|
|
7716
|
-
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";
|
|
7717
8163
|
stmts.push(
|
|
7718
8164
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8165
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7719
8166
|
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7720
8167
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7721
8168
|
);
|
|
@@ -7724,7 +8171,7 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7724
8171
|
const endAfterV = v(ctx, "_sea");
|
|
7725
8172
|
stmts.push(
|
|
7726
8173
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7727
|
-
`${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};` : ""} }`
|
|
7728
8175
|
);
|
|
7729
8176
|
valueVars.push(r2.valueVar);
|
|
7730
8177
|
continue;
|
|
@@ -7966,6 +8413,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7966
8413
|
const selectorRawMark = selectorNeedsRollback ? v(ctx, "_dsr") : null;
|
|
7967
8414
|
const selectorTriviaMark = selectorNeedsRollback ? v(ctx, "_dst") : null;
|
|
7968
8415
|
const selectorLogMark = selectorNeedsRollback ? v(ctx, "_dsg") : null;
|
|
8416
|
+
const selectorRootLogMark = selectorNeedsRollback && hasSelectedRootTrivia(ctx) ? v(ctx, "_dsrg") : null;
|
|
7969
8417
|
const selectorFieldMark = selectorNeedsRollback ? v(ctx, "_dsf") : null;
|
|
7970
8418
|
const selectorErrorMark = selectorNeedsRollback ? v(ctx, "_dse") : null;
|
|
7971
8419
|
const selector = emit(def.selector, ctx, pos);
|
|
@@ -7978,6 +8426,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7978
8426
|
`${ind(ctx)}const ${selectorRawMark} = _ctx._cstRawChildren?.length ?? 0`,
|
|
7979
8427
|
`${ind(ctx)}const ${selectorTriviaMark} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
7980
8428
|
`${ind(ctx)}const ${selectorLogMark} = _ctx._triviaLog?.length ?? 0`,
|
|
8429
|
+
...selectorRootLogMark ? [`${ind(ctx)}const ${selectorRootLogMark} = _ctx._rootTriviaLog?.length ?? 0`] : [],
|
|
7981
8430
|
`${ind(ctx)}const ${selectorFieldMark} = _ctx._fields?.length ?? 0`,
|
|
7982
8431
|
`${ind(ctx)}const ${selectorErrorMark} = _ctx._errors?.length ?? 0`
|
|
7983
8432
|
] : [],
|
|
@@ -7997,16 +8446,18 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7997
8446
|
const mayError = mayRecordRecoveryError(parser3, !!ctx.recovery);
|
|
7998
8447
|
const errMark = mayError ? v(ctx, "_derr") : null;
|
|
7999
8448
|
const logMark = ctx.activeTrivia ? v(ctx, "_dlog") : null;
|
|
8449
|
+
const rootLogMark = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_drlog") : null;
|
|
8000
8450
|
if (usesRouted) {
|
|
8001
8451
|
stmts.push(
|
|
8002
8452
|
...routedV ? [`${ind(ctx)}const ${routedV} = _ctx._routed; _ctx._routed = { value: ${selector.valueVar}, span: { start: ${pos}, end: ${selector.endVar} } }`] : [],
|
|
8003
8453
|
...selectorLeafMark ? [
|
|
8004
|
-
`${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}`
|
|
8005
8455
|
] : []
|
|
8006
8456
|
);
|
|
8007
8457
|
}
|
|
8008
8458
|
if (errMark) stmts.push(`${ind(ctx)}const ${errMark} = _ctx._errors?.length ?? 0`);
|
|
8009
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`);
|
|
8010
8461
|
const savedRoutedLocal = ctx.routedLocal;
|
|
8011
8462
|
const savedNoHoist = ctx.noHoist;
|
|
8012
8463
|
if (usesRouted && !needsRoutedContext) {
|
|
@@ -8021,11 +8472,12 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
8021
8472
|
stmts.push(...coverageAttempt(ctx, coverageId, pos));
|
|
8022
8473
|
const errorRollback = errMark ? `if (_ctx._errors && _ctx._errors.length !== ${errMark}) _ctx._errors.length = ${errMark}; ` : "";
|
|
8023
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}; ` : "";
|
|
8024
8476
|
const routedRollback = routedV ? `_ctx._routed = ${routedV}; ` : "";
|
|
8025
8477
|
const coverageFailure = coverageId === void 0 ? "" : `_ctx._grammarTrace?.write({ id: ${JSON.stringify(coverageId)}, phase: 'failure', offset: _ctx._fe }); `;
|
|
8026
8478
|
stmts.push(
|
|
8027
8479
|
...tail.stmts,
|
|
8028
|
-
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8480
|
+
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${rootLogRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8029
8481
|
...routedV ? [`${ind(ctx)}_ctx._routed = ${routedV}`] : [],
|
|
8030
8482
|
`${ind(ctx)}${outV} = ${valueMode === "tail" ? tail.valVar : `[${selector.valueVar}, ${tail.valVar}]`}`,
|
|
8031
8483
|
`${ind(ctx)}${outE} = ${tail.endVar}`,
|
|
@@ -8206,11 +8658,13 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8206
8658
|
const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
|
|
8207
8659
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
8208
8660
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
8661
|
+
const markRootLog = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_cmlrg") : null;
|
|
8209
8662
|
const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
|
|
8210
8663
|
const markErrors = armMayRecordError ? v(ctx, "_cme") : null;
|
|
8211
|
-
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}` : "";
|
|
8212
8666
|
const errorRollback = markErrors ? `if (_ctx._errors && _ctx._errors.length !== ${markErrors}) _ctx._errors.length = ${markErrors}` : "";
|
|
8213
|
-
const rollback = [captureRollback, errorRollback].filter(Boolean).join("; ");
|
|
8667
|
+
const rollback = [captureRollback, rootRollback, errorRollback].filter(Boolean).join("; ");
|
|
8214
8668
|
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
8215
8669
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
8216
8670
|
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
@@ -8225,6 +8679,7 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8225
8679
|
...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
|
|
8226
8680
|
);
|
|
8227
8681
|
}
|
|
8682
|
+
if (markRootLog) stmts.push(`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
8228
8683
|
if (markErrors) stmts.push(`${ind(ctx)}const ${markErrors} = _ctx._errors?.length ?? 0`);
|
|
8229
8684
|
const arm = emitFallible(p, ctx, pos, atStart);
|
|
8230
8685
|
const { stmts: armStmts, okVar, valVar, endVar } = arm;
|
|
@@ -8293,7 +8748,7 @@ function routedNeedsContextBridge(p, ctx, seen = /* @__PURE__ */ new Set()) {
|
|
|
8293
8748
|
const d = p._def;
|
|
8294
8749
|
if (d.tag === "dispatch") return false;
|
|
8295
8750
|
if (d.tag === "withCtx") return parserUsesRouted2(d.parser);
|
|
8296
|
-
return
|
|
8751
|
+
return childrenOf3(d).some((child) => routedNeedsContextBridge(child, ctx, seen));
|
|
8297
8752
|
}
|
|
8298
8753
|
function armReplayInScope(arm, ctx) {
|
|
8299
8754
|
let p = arm;
|
|
@@ -8412,21 +8867,29 @@ function emitMany(def, ctx, pos) {
|
|
|
8412
8867
|
const markV = v(ctx, "_mk");
|
|
8413
8868
|
const markTl = v(ctx, "_mktl");
|
|
8414
8869
|
const markLog = v(ctx, "_mklg");
|
|
8870
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8415
8871
|
const npV = v(ctx, "_np");
|
|
8416
8872
|
stmts.push(
|
|
8417
8873
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8418
8874
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8419
8875
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8876
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8420
8877
|
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8421
8878
|
...emitLineTrack(ctx, curV, npV)
|
|
8422
8879
|
);
|
|
8423
8880
|
itemPos = npV;
|
|
8424
|
-
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};` : ""} `;
|
|
8425
8882
|
} else {
|
|
8426
8883
|
const trivFn = ensureTriviaFn(ctx);
|
|
8884
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8427
8885
|
const npV = v(ctx, "_np");
|
|
8428
|
-
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
|
+
);
|
|
8429
8891
|
itemPos = npV;
|
|
8892
|
+
rollback = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8430
8893
|
}
|
|
8431
8894
|
}
|
|
8432
8895
|
if (!ctx.recovery && !ctx.coverage && !failsAtStart(def.parser) && needsFirstSetGuard(def.parser)) {
|
|
@@ -8486,9 +8949,10 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8486
8949
|
const raw = v(ctx, "_atr");
|
|
8487
8950
|
const trivia2 = v(ctx, "_att");
|
|
8488
8951
|
const log = v(ctx, "_atg");
|
|
8952
|
+
const rootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_atrg") : null;
|
|
8489
8953
|
const fields = v(ctx, "_atf");
|
|
8490
8954
|
const errors = v(ctx, "_ate");
|
|
8491
|
-
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}`;
|
|
8492
8956
|
const traceId = ctx.coverage?.plan.attempts.get(p);
|
|
8493
8957
|
const traceRollback = traceId === void 0 ? "" : ` _ctx._grammarTrace?.write({ id: ${JSON.stringify(traceId)}, phase: 'rollback', offset: ${pos} });`;
|
|
8494
8958
|
const preGuard = [];
|
|
@@ -8504,7 +8968,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8504
8968
|
return {
|
|
8505
8969
|
stmts: [
|
|
8506
8970
|
...preGuard,
|
|
8507
|
-
`${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`,
|
|
8508
8972
|
...inner.stmts,
|
|
8509
8973
|
...emitIfFail(ctx, `!${inner.okVar}`, `{ ${rollback};${traceRollback}${inner.mayCommit ? ` if (_ctx._fc) ${committedFailBody(ctx)};` : ""} _ctx._fe = ${pos}; ${propagateFailBody(ctx)} }`)
|
|
8510
8974
|
],
|
|
@@ -8546,16 +9010,17 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8546
9010
|
const itemFailBreak = (sepEndVar, sepRb, postSepRb) => def.trailing === void 0 ? `${sepRb}break` : `${postSepRb}${curV} = ${sepEndVar}; break`;
|
|
8547
9011
|
const postSepMarks = () => {
|
|
8548
9012
|
if (def.trailing === void 0 || !ctx.capturing) return { decl: [], rb: "" };
|
|
8549
|
-
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");
|
|
8550
9014
|
return {
|
|
8551
9015
|
decl: [
|
|
8552
9016
|
`${ind(ctx)}const ${lv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8553
9017
|
`${ind(ctx)}const ${rw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8554
9018
|
`${ind(ctx)}const ${tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8555
9019
|
`${ind(ctx)}const ${lg} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
9020
|
+
...rlg ? [`${ind(ctx)}const ${rlg} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8556
9021
|
`${ind(ctx)}const ${fl} = _ctx._fields ? _ctx._fields.length : 0`
|
|
8557
9022
|
],
|
|
8558
|
-
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}; `
|
|
8559
9024
|
};
|
|
8560
9025
|
};
|
|
8561
9026
|
if (rec) {
|
|
@@ -8593,6 +9058,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8593
9058
|
const markV = v(ctx, "_mk");
|
|
8594
9059
|
const markTl = v(ctx, "_mktl");
|
|
8595
9060
|
const markLog = v(ctx, "_mklg");
|
|
9061
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8596
9062
|
const markLv = v(ctx, "_mklv");
|
|
8597
9063
|
const markFld = v(ctx, "_mkf");
|
|
8598
9064
|
const spV = v(ctx, "_sp");
|
|
@@ -8600,13 +9066,14 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8600
9066
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8601
9067
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8602
9068
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
9069
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8603
9070
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8604
9071
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8605
9072
|
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8606
9073
|
...emitLineTrack(ctx, curV, spV)
|
|
8607
9074
|
);
|
|
8608
9075
|
sepAtPos = spV;
|
|
8609
|
-
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}; `;
|
|
8610
9077
|
const sep = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8611
9078
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep;
|
|
8612
9079
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
@@ -8624,19 +9091,30 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8624
9091
|
);
|
|
8625
9092
|
} else {
|
|
8626
9093
|
const trivFn = ensureTriviaFn(ctx);
|
|
9094
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8627
9095
|
const spV = v(ctx, "_sp");
|
|
8628
|
-
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
|
+
);
|
|
8629
9101
|
sepAtPos = spV;
|
|
8630
9102
|
const sep = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8631
9103
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep;
|
|
8632
|
-
|
|
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;
|
|
8633
9107
|
const npV = v(ctx, "_np");
|
|
8634
|
-
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
|
+
);
|
|
8635
9113
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8636
9114
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8637
9115
|
stmts.push(
|
|
8638
9116
|
...nextStmts,
|
|
8639
|
-
...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}; ` : "")),
|
|
8640
9118
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
8641
9119
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
8642
9120
|
);
|
|
@@ -8731,6 +9209,7 @@ function emitNot(def, ctx, pos) {
|
|
|
8731
9209
|
const raw = sinksLive ? v(ctx, "_ntr") : null;
|
|
8732
9210
|
const tl = sinksLive ? v(ctx, "_ntt") : null;
|
|
8733
9211
|
const log = sinksLive ? v(ctx, "_ntg") : null;
|
|
9212
|
+
const rootLog = sinksLive && hasSelectedRootTrivia(ctx) ? v(ctx, "_ntrg") : null;
|
|
8734
9213
|
const fields = sinksLive ? v(ctx, "_ntf") : null;
|
|
8735
9214
|
const errors = sinksLive ? v(ctx, "_nte") : null;
|
|
8736
9215
|
const { stmts, okVar } = emitFallible(def.parser, ctx, pos, true);
|
|
@@ -8738,11 +9217,11 @@ function emitNot(def, ctx, pos) {
|
|
|
8738
9217
|
return {
|
|
8739
9218
|
stmts: [
|
|
8740
9219
|
...sinksLive ? [
|
|
8741
|
-
`${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`
|
|
8742
9221
|
] : [],
|
|
8743
9222
|
...stmts,
|
|
8744
9223
|
...sinksLive ? [
|
|
8745
|
-
`${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}`
|
|
8746
9225
|
] : [],
|
|
8747
9226
|
...emitIfFail(ctx, okVar, failBody(ctx, label2, pos))
|
|
8748
9227
|
],
|
|
@@ -8878,16 +9357,17 @@ function emitToken(def, ctx, pos) {
|
|
|
8878
9357
|
const sk = v(ctx, "_tokKinds");
|
|
8879
9358
|
const stl = v(ctx, "_tokTl");
|
|
8880
9359
|
const sol = v(ctx, "_tokLog");
|
|
9360
|
+
const srl = hasSelectedRootTrivia(ctx) ? v(ctx, "_tokRootLog") : null;
|
|
8881
9361
|
const sb = v(ctx, "_tokBuf");
|
|
8882
9362
|
const valV = v(ctx, "_tok");
|
|
8883
9363
|
return {
|
|
8884
9364
|
stmts: [
|
|
8885
|
-
`${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`,
|
|
8886
|
-
`${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`,
|
|
8887
9367
|
`${i}try {`,
|
|
8888
9368
|
...reindentStmts(inner.stmts, ctx.indent + 1).map((stmt) => stmt.replace(/^(\s*)(?:const|let)\s+/, "$1var ")),
|
|
8889
9369
|
`${i}} finally {`,
|
|
8890
|
-
`${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}`,
|
|
8891
9371
|
`${i}}`,
|
|
8892
9372
|
...emitIfFail(ctx, `!${inner.okVar}`, propagateFailBody(ctx)),
|
|
8893
9373
|
`${i}const ${valV} = input.slice(${pos}, ${inner.endVar})`,
|
|
@@ -9056,7 +9536,8 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
9056
9536
|
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
9057
9537
|
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
9058
9538
|
const buildExpr = structural ? `{ _tag: 'node', type: ${JSON.stringify(def.type)}, span: ${nodeSpanV}, state: ${stV} ?? null, children: ${chV} }` : mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, nodeSpanV, tlV) : def.project !== void 0 ? emitNodeProjectExpr(def.type, def.project, chV) : `${buildRef(ctx)}[${buildIdx}](${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV})`;
|
|
9059
|
-
const
|
|
9539
|
+
const hostBuildArgs = `${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV}${def.tags !== void 0 && def.tags.length > 0 ? `, ${JSON.stringify(def.tags)}` : ""}`;
|
|
9540
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${hostBuildArgs})`;
|
|
9060
9541
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
9061
9542
|
const hostCollapseExpr = structural ? `_ctx.build !== undefined && _ctx.build._parsemanCstCollapse !== undefined && ${chV}.length === 1 && ${rawV}.length === 1 && _ctx.build._parsemanCstCollapse(${JSON.stringify(def.type)}, ${chV}[0], ${chV}, ${rawV}) ? ${chV}[0] : (${ndExpr})` : ndExpr;
|
|
9062
9543
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -9365,6 +9846,8 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9365
9846
|
case "grammar": {
|
|
9366
9847
|
const savedTrivia = ctx.activeTrivia;
|
|
9367
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;
|
|
9368
9851
|
if (def.clearTrivia) {
|
|
9369
9852
|
ctx.activeTrivia = void 0;
|
|
9370
9853
|
ctx.triviaKindLabels = void 0;
|
|
@@ -9375,13 +9858,38 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9375
9858
|
}
|
|
9376
9859
|
}
|
|
9377
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++;
|
|
9378
9865
|
const r = emit(def.parser, ctx, pos);
|
|
9866
|
+
if (opaqueRootCapture) ctx.indent--;
|
|
9379
9867
|
ctx.activeTrivia = savedTrivia;
|
|
9380
9868
|
ctx.triviaKindLabels = savedKindLabels;
|
|
9381
|
-
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
|
+
}
|
|
9382
9889
|
return {
|
|
9383
9890
|
...r,
|
|
9384
9891
|
stmts: [
|
|
9892
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9385
9893
|
`${ind(ctx)}const ${savedCapture} = _ctx.captureTrivia; _ctx.captureTrivia = true`,
|
|
9386
9894
|
...r.stmts,
|
|
9387
9895
|
`${ind(ctx)}_ctx.captureTrivia = ${savedCapture}`
|
|
@@ -9519,7 +10027,7 @@ function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9519
10027
|
return false;
|
|
9520
10028
|
}
|
|
9521
10029
|
}
|
|
9522
|
-
return
|
|
10030
|
+
return childrenOf3(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9523
10031
|
}
|
|
9524
10032
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9525
10033
|
if (seen.has(p)) return false;
|
|
@@ -9538,7 +10046,7 @@ function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9538
10046
|
case "dispatch":
|
|
9539
10047
|
return false;
|
|
9540
10048
|
default:
|
|
9541
|
-
return
|
|
10049
|
+
return childrenOf3(d).some((child) => parserUsesRouted2(child, seen));
|
|
9542
10050
|
}
|
|
9543
10051
|
}
|
|
9544
10052
|
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -9553,9 +10061,9 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9553
10061
|
return false;
|
|
9554
10062
|
}
|
|
9555
10063
|
}
|
|
9556
|
-
return
|
|
10064
|
+
return childrenOf3(d).some((child) => hasDirectBuildDef(child, seen));
|
|
9557
10065
|
}
|
|
9558
|
-
function
|
|
10066
|
+
function childrenOf3(def) {
|
|
9559
10067
|
switch (def.tag) {
|
|
9560
10068
|
case "sequence":
|
|
9561
10069
|
case "choice":
|
|
@@ -9630,7 +10138,7 @@ function subtreeSizes(roots) {
|
|
|
9630
10138
|
const def = p._def;
|
|
9631
10139
|
let s = 1;
|
|
9632
10140
|
if (def.tag !== "lazy") {
|
|
9633
|
-
for (const child of
|
|
10141
|
+
for (const child of childrenOf3(def)) s += child._def.tag === "lazy" ? 1 : sz(child);
|
|
9634
10142
|
}
|
|
9635
10143
|
sizes.set(p, s);
|
|
9636
10144
|
return s;
|
|
@@ -9651,7 +10159,7 @@ function subtreeSizes(roots) {
|
|
|
9651
10159
|
return;
|
|
9652
10160
|
}
|
|
9653
10161
|
sz(p);
|
|
9654
|
-
for (const child of
|
|
10162
|
+
for (const child of childrenOf3(def)) visit(child);
|
|
9655
10163
|
};
|
|
9656
10164
|
for (const root of roots) visit(root);
|
|
9657
10165
|
return sizes;
|
|
@@ -9661,7 +10169,7 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9661
10169
|
const recursive = /* @__PURE__ */ new Set();
|
|
9662
10170
|
const descended = /* @__PURE__ */ new Set();
|
|
9663
10171
|
const active = /* @__PURE__ */ new Set();
|
|
9664
|
-
function
|
|
10172
|
+
function walk(p) {
|
|
9665
10173
|
const def = p._def;
|
|
9666
10174
|
if (def.tag === "lazy") {
|
|
9667
10175
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
@@ -9678,17 +10186,17 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9678
10186
|
return;
|
|
9679
10187
|
}
|
|
9680
10188
|
active.add(p);
|
|
9681
|
-
|
|
10189
|
+
walk(resolved);
|
|
9682
10190
|
active.delete(p);
|
|
9683
10191
|
return;
|
|
9684
10192
|
}
|
|
9685
10193
|
if (isHoistableTag(def.tag)) {
|
|
9686
10194
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
9687
10195
|
}
|
|
9688
|
-
for (const child of
|
|
10196
|
+
for (const child of childrenOf3(def)) walk(child);
|
|
9689
10197
|
}
|
|
9690
10198
|
const rootsArr = [...roots];
|
|
9691
|
-
for (const root of rootsArr)
|
|
10199
|
+
for (const root of rootsArr) walk(root);
|
|
9692
10200
|
return { counts, recursive, sizes: subtreeSizes(rootsArr) };
|
|
9693
10201
|
}
|
|
9694
10202
|
function ruleDependencies(ruleMap) {
|
|
@@ -9698,7 +10206,7 @@ function ruleDependencies(ruleMap) {
|
|
|
9698
10206
|
for (const [name, comb] of ruleMap) {
|
|
9699
10207
|
const found = /* @__PURE__ */ new Set();
|
|
9700
10208
|
const seen = /* @__PURE__ */ new Set();
|
|
9701
|
-
const
|
|
10209
|
+
const walk = (p, isRoot) => {
|
|
9702
10210
|
const def = p._def;
|
|
9703
10211
|
const boundary = def.tag === "lazy" ? nameOf.get(p) ?? p._ruleName : nameOf.get(p);
|
|
9704
10212
|
if (!isRoot && boundary !== void 0) {
|
|
@@ -9714,12 +10222,12 @@ function ruleDependencies(ruleMap) {
|
|
|
9714
10222
|
} catch {
|
|
9715
10223
|
return;
|
|
9716
10224
|
}
|
|
9717
|
-
|
|
10225
|
+
walk(resolved, false);
|
|
9718
10226
|
return;
|
|
9719
10227
|
}
|
|
9720
|
-
for (const child of
|
|
10228
|
+
for (const child of childrenOf3(def)) walk(child, false);
|
|
9721
10229
|
};
|
|
9722
|
-
|
|
10230
|
+
walk(comb, true);
|
|
9723
10231
|
deps.set(name, [...found]);
|
|
9724
10232
|
}
|
|
9725
10233
|
return deps;
|
|
@@ -9866,6 +10374,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9866
10374
|
runDuplicationDiagnostic(combinator, opts?.duplication);
|
|
9867
10375
|
markUnusedValues(combinator);
|
|
9868
10376
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
10377
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || combinator._meta.rootTriviaClassified === true;
|
|
9869
10378
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9870
10379
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9871
10380
|
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
@@ -9892,7 +10401,11 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9892
10401
|
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9893
10402
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9894
10403
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9895
|
-
...
|
|
10404
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10405
|
+
...grammarTrivia ? {
|
|
10406
|
+
activeTrivia: grammarTrivia,
|
|
10407
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10408
|
+
} : {},
|
|
9896
10409
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
9897
10410
|
};
|
|
9898
10411
|
const r = emit(combinator, ctx, "_pos");
|
|
@@ -10040,10 +10553,11 @@ function assertRuleName(name) {
|
|
|
10040
10553
|
);
|
|
10041
10554
|
}
|
|
10042
10555
|
}
|
|
10043
|
-
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels) {
|
|
10044
|
-
const labels = rule._meta.triviaKindLabels
|
|
10045
|
-
|
|
10046
|
-
|
|
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,"} } })`;
|
|
10047
10561
|
}
|
|
10048
10562
|
function compileLinkable(ruleMapArg, ns, opts) {
|
|
10049
10563
|
if (!ns) throw new Error("compileLinkable: ns must be a non-empty namespace");
|
|
@@ -10051,6 +10565,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10051
10565
|
if (opts?.duplication !== void 0) runDuplicationDiagnosticRules(ruleMapArg, opts.duplication);
|
|
10052
10566
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
10053
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);
|
|
10054
10569
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
10055
10570
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10056
10571
|
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -10064,6 +10579,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10064
10579
|
return false;
|
|
10065
10580
|
}
|
|
10066
10581
|
});
|
|
10582
|
+
const nodeMeta = new Map(ruleMap.map(([name, rule]) => [name, collectGrammarReflection([[name, rule]], { followLazy: false })]));
|
|
10067
10583
|
const ctx = {
|
|
10068
10584
|
vars: 0,
|
|
10069
10585
|
indent: 1,
|
|
@@ -10093,7 +10609,11 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10093
10609
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10094
10610
|
ns,
|
|
10095
10611
|
deferFirstSetRefs: true,
|
|
10096
|
-
...
|
|
10612
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10613
|
+
...grammarTrivia ? {
|
|
10614
|
+
activeTrivia: grammarTrivia,
|
|
10615
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10616
|
+
} : {},
|
|
10097
10617
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
10098
10618
|
};
|
|
10099
10619
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -10139,7 +10659,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10139
10659
|
scanExternal(resolved);
|
|
10140
10660
|
return;
|
|
10141
10661
|
}
|
|
10142
|
-
for (const child of
|
|
10662
|
+
for (const child of childrenOf3(def)) scanExternal(child);
|
|
10143
10663
|
};
|
|
10144
10664
|
for (const [, rule] of ruleMap) scanExternal(rule);
|
|
10145
10665
|
}
|
|
@@ -10225,7 +10745,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10225
10745
|
...r.stmts,
|
|
10226
10746
|
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
10227
10747
|
`}`
|
|
10228
|
-
].join("\n"), ctx.triviaKindLabels));
|
|
10748
|
+
].join("\n"), ctx.triviaKindLabels, ctx.rootTriviaClassified));
|
|
10229
10749
|
}
|
|
10230
10750
|
const firstSets = /* @__PURE__ */ new Map();
|
|
10231
10751
|
const firstSetRecipes = /* @__PURE__ */ new Map();
|
|
@@ -10261,6 +10781,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10261
10781
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10262
10782
|
hasDirectBuilders: ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
10263
10783
|
isRecognitionOnly: !hasSemanticReduction(ruleMap.map(([, rule]) => rule), externalRefs),
|
|
10784
|
+
nodeMeta,
|
|
10264
10785
|
mfFns: mfSrcs ? [] : ctx.mapFns,
|
|
10265
10786
|
buildFns: buildSrcs ? [] : ctx.buildFns
|
|
10266
10787
|
};
|
|
@@ -10281,7 +10802,7 @@ function hasExternalRuleRef(ruleMap) {
|
|
|
10281
10802
|
if (resolved === void 0) return p._ruleName !== void 0;
|
|
10282
10803
|
return visit(resolved);
|
|
10283
10804
|
}
|
|
10284
|
-
return
|
|
10805
|
+
return childrenOf3(def).some(visit);
|
|
10285
10806
|
};
|
|
10286
10807
|
return ruleMap.some(([, rule]) => visit(rule));
|
|
10287
10808
|
}
|
|
@@ -10303,7 +10824,7 @@ function hasSemanticReduction(roots, externalRefs) {
|
|
|
10303
10824
|
return true;
|
|
10304
10825
|
}
|
|
10305
10826
|
}
|
|
10306
|
-
return
|
|
10827
|
+
return childrenOf3(def).some(visit);
|
|
10307
10828
|
};
|
|
10308
10829
|
return roots.some(visit);
|
|
10309
10830
|
}
|
|
@@ -10376,7 +10897,7 @@ function withCtx(extra, combinator) {
|
|
|
10376
10897
|
}
|
|
10377
10898
|
|
|
10378
10899
|
// src/compiler/ir-serialize.ts
|
|
10379
|
-
function
|
|
10900
|
+
function childrenOf4(def) {
|
|
10380
10901
|
switch (def.tag) {
|
|
10381
10902
|
case "sequence":
|
|
10382
10903
|
case "choice":
|
|
@@ -10440,6 +10961,10 @@ function projectOpt(project) {
|
|
|
10440
10961
|
if (project === void 0) return void 0;
|
|
10441
10962
|
return `project: ${project}`;
|
|
10442
10963
|
}
|
|
10964
|
+
function tagsOpt(tags) {
|
|
10965
|
+
if (tags === void 0 || tags.length === 0) return void 0;
|
|
10966
|
+
return `tags: ${JSON.stringify(tags)}`;
|
|
10967
|
+
}
|
|
10443
10968
|
function matcherExpr(entry) {
|
|
10444
10969
|
switch (entry.kind) {
|
|
10445
10970
|
case "startsWith":
|
|
@@ -10569,6 +11094,7 @@ function evalRuleMapIR(ir) {
|
|
|
10569
11094
|
"transform",
|
|
10570
11095
|
"skip",
|
|
10571
11096
|
"trivia",
|
|
11097
|
+
"classifiedTrivia",
|
|
10572
11098
|
"label",
|
|
10573
11099
|
"field",
|
|
10574
11100
|
"expect",
|
|
@@ -10609,6 +11135,7 @@ function evalRuleMapIR(ir) {
|
|
|
10609
11135
|
transform,
|
|
10610
11136
|
skip,
|
|
10611
11137
|
trivia,
|
|
11138
|
+
classifiedTrivia,
|
|
10612
11139
|
label,
|
|
10613
11140
|
field,
|
|
10614
11141
|
expect,
|
|
@@ -10653,7 +11180,7 @@ var Serializer = class {
|
|
|
10653
11180
|
if (target) this.assertNoRuleRef(target, seen);
|
|
10654
11181
|
return;
|
|
10655
11182
|
}
|
|
10656
|
-
for (const child of
|
|
11183
|
+
for (const child of childrenOf4(c._def)) this.assertNoRuleRef(child, seen);
|
|
10657
11184
|
}
|
|
10658
11185
|
/** A `rules()` map wraps each rule value in a named `lazy` proxy; the real body is
|
|
10659
11186
|
* its target (compileLinkable unwraps the same way). A ref INSIDE a body stays a
|
|
@@ -10717,7 +11244,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10717
11244
|
this.counts.set(c, (this.counts.get(c) ?? 0) + 1);
|
|
10718
11245
|
if ((this.counts.get(c) ?? 0) > 1) return;
|
|
10719
11246
|
active.add(c);
|
|
10720
|
-
for (const child of
|
|
11247
|
+
for (const child of childrenOf4(def)) this.analyze(child, active);
|
|
10721
11248
|
active.delete(c);
|
|
10722
11249
|
}
|
|
10723
11250
|
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
@@ -10834,12 +11361,14 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10834
11361
|
case "node": {
|
|
10835
11362
|
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
10836
11363
|
const projectEntry = projectOpt(def.project);
|
|
11364
|
+
const tagEntry = tagsOpt(def.tags);
|
|
10837
11365
|
const optEntries = [
|
|
10838
11366
|
...def.unwrap ? ["unwrap: true"] : [],
|
|
10839
11367
|
...def.collapse ? ["collapse: true"] : [],
|
|
10840
11368
|
...projectEntry === void 0 ? [] : [projectEntry],
|
|
10841
11369
|
...def.captureTrivia ? ["captureTrivia: true"] : [],
|
|
10842
|
-
...def.trailingTrivia ? ["trailingTrivia: true"] : []
|
|
11370
|
+
...def.trailingTrivia ? ["trailingTrivia: true"] : [],
|
|
11371
|
+
...tagEntry === void 0 ? [] : [tagEntry]
|
|
10843
11372
|
];
|
|
10844
11373
|
const opts = optEntries.length > 0 ? `, { ${optEntries.join(", ")} }` : "";
|
|
10845
11374
|
if (def.type === void 0) {
|
|
@@ -10853,8 +11382,11 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10853
11382
|
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
10854
11383
|
}
|
|
10855
11384
|
case "grammar": {
|
|
10856
|
-
const
|
|
10857
|
-
|
|
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)})`;
|
|
10858
11390
|
}
|
|
10859
11391
|
case "withCtx": {
|
|
10860
11392
|
if (def.extraSrc === void 0) throw new Unserializable("withCtx without extraSrc");
|
|
@@ -10887,15 +11419,16 @@ function normalizeCstCollapse(collapse) {
|
|
|
10887
11419
|
}
|
|
10888
11420
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10889
11421
|
}
|
|
10890
|
-
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10891
|
-
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
11422
|
+
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
11423
|
+
return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children2] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
10892
11424
|
}
|
|
10893
|
-
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
11425
|
+
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
10894
11426
|
if (typeof typeOrOptions === "string") {
|
|
10895
11427
|
return buildCstNode(typeOrOptions, children2 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
10896
11428
|
}
|
|
10897
11429
|
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
10898
|
-
const
|
|
11430
|
+
const materializeTags = typeOrOptions?.tags === true;
|
|
11431
|
+
const host = (type, children3, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children3 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
10899
11432
|
host._parsemanCstOutput = true;
|
|
10900
11433
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
10901
11434
|
return host;
|
|
@@ -10937,6 +11470,7 @@ function fusedBody(pieces) {
|
|
|
10937
11470
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
10938
11471
|
];
|
|
10939
11472
|
const wrapperEntries = [...winner].map(([k, p]) => `${JSON.stringify(k)}: ${p.wrappers.get(k)}`);
|
|
11473
|
+
const reflection = mergeGrammarReflections([...winner].map(([k, p]) => p.nodeMeta.get(k) ?? { nodes: [] }));
|
|
10940
11474
|
const { mode, elided } = hostModeOfPieces(pieces);
|
|
10941
11475
|
const rawBody = [
|
|
10942
11476
|
...lines,
|
|
@@ -10945,6 +11479,7 @@ function fusedBody(pieces) {
|
|
|
10945
11479
|
"}",
|
|
10946
11480
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_MODE.description)}), { value: ${JSON.stringify(mode)}, enumerable: false })`,
|
|
10947
11481
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_ELIDED.description)}), { value: ${JSON.stringify(elided)}, enumerable: false })`,
|
|
11482
|
+
`Object.defineProperty(_map, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`,
|
|
10948
11483
|
// …and on each rule FUNCTION, because `run(map.Rule, …)` is handed the rule, not the
|
|
10949
11484
|
// map, and would otherwise have nothing to check against. Done once at fuse time,
|
|
10950
11485
|
// before any rule has been called, so it costs nothing per parse.
|
|
@@ -11748,157 +12283,26 @@ function parseDoc(registry, rootRule, input, opts = {}) {
|
|
|
11748
12283
|
return new ParseDocImpl(registry, rootRule, opts, { abs: null }, [fail], null, input);
|
|
11749
12284
|
}
|
|
11750
12285
|
|
|
11751
|
-
// src/cst/trivia-entries.ts
|
|
11752
|
-
var EMPTY_INDICES = Object.freeze([]);
|
|
11753
|
-
var EMPTY_GAPS = Object.freeze([]);
|
|
11754
|
-
function entryOffset(i, stride) {
|
|
11755
|
-
return i * stride;
|
|
11756
|
-
}
|
|
11757
|
-
function triviaEntries(log, labels, opts) {
|
|
11758
|
-
const baseStride = opts?.nodeLog ? 3 : 2;
|
|
11759
|
-
const stride = labels ? baseStride + 1 : baseStride;
|
|
11760
|
-
const length = Math.floor(log.length / stride);
|
|
11761
|
-
return {
|
|
11762
|
-
length,
|
|
11763
|
-
labels,
|
|
11764
|
-
stride,
|
|
11765
|
-
start(i) {
|
|
11766
|
-
return log[entryOffset(i, stride)];
|
|
11767
|
-
},
|
|
11768
|
-
end(i) {
|
|
11769
|
-
return log[entryOffset(i, stride) + 1];
|
|
11770
|
-
},
|
|
11771
|
-
insertIndex(i) {
|
|
11772
|
-
return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
|
|
11773
|
-
},
|
|
11774
|
-
kindIndex(i) {
|
|
11775
|
-
if (!labels) return void 0;
|
|
11776
|
-
return log[entryOffset(i, stride) + baseStride];
|
|
11777
|
-
},
|
|
11778
|
-
kind(i) {
|
|
11779
|
-
const ki = labels ? log[entryOffset(i, stride) + baseStride] : void 0;
|
|
11780
|
-
return ki !== void 0 ? labels[ki] : void 0;
|
|
11781
|
-
},
|
|
11782
|
-
text(i, input) {
|
|
11783
|
-
const s = log[entryOffset(i, stride)];
|
|
11784
|
-
const e = log[entryOffset(i, stride) + 1];
|
|
11785
|
-
return input.slice(s, e);
|
|
11786
|
-
}
|
|
11787
|
-
};
|
|
11788
|
-
}
|
|
11789
|
-
function appendEntryRange(map, key, first, last) {
|
|
11790
|
-
let indices = map.get(key);
|
|
11791
|
-
if (!indices) {
|
|
11792
|
-
indices = [];
|
|
11793
|
-
map.set(key, indices);
|
|
11794
|
-
}
|
|
11795
|
-
for (let i = first; i <= last; i++) indices.push(i);
|
|
11796
|
-
}
|
|
11797
|
-
function buildGap(entries, start, end, first, last) {
|
|
11798
|
-
const entryIndices = [];
|
|
11799
|
-
for (let i = first; i <= last; i++) entryIndices.push(i);
|
|
11800
|
-
return {
|
|
11801
|
-
start,
|
|
11802
|
-
end,
|
|
11803
|
-
entryIndices,
|
|
11804
|
-
hasKind(kind) {
|
|
11805
|
-
for (const i of entryIndices) {
|
|
11806
|
-
if (entries.kind(i) === kind) return true;
|
|
11807
|
-
}
|
|
11808
|
-
return false;
|
|
11809
|
-
},
|
|
11810
|
-
text(input) {
|
|
11811
|
-
return input.slice(start, end);
|
|
11812
|
-
}
|
|
11813
|
-
};
|
|
11814
|
-
}
|
|
11815
|
-
function buildRootMaps(entries) {
|
|
11816
|
-
const before = /* @__PURE__ */ new Map();
|
|
11817
|
-
const after = /* @__PURE__ */ new Map();
|
|
11818
|
-
const beforeGaps = /* @__PURE__ */ new Map();
|
|
11819
|
-
const afterGaps = /* @__PURE__ */ new Map();
|
|
11820
|
-
const gaps = [];
|
|
11821
|
-
if (entries.length === 0) return { before, after, beforeGaps, afterGaps, gaps };
|
|
11822
|
-
const appendGap = (first2, last, start2, end2) => {
|
|
11823
|
-
const gap = buildGap(entries, start2, end2, first2, last);
|
|
11824
|
-
gaps.push(gap);
|
|
11825
|
-
afterGaps.set(start2, gap);
|
|
11826
|
-
beforeGaps.set(end2, gap);
|
|
11827
|
-
appendEntryRange(after, start2, first2, last);
|
|
11828
|
-
appendEntryRange(before, end2, first2, last);
|
|
11829
|
-
};
|
|
11830
|
-
let first = 0;
|
|
11831
|
-
let start = entries.start(0);
|
|
11832
|
-
let end = entries.end(0);
|
|
11833
|
-
for (let i = 1; i < entries.length; i++) {
|
|
11834
|
-
const nextStart = entries.start(i);
|
|
11835
|
-
const nextEnd = entries.end(i);
|
|
11836
|
-
if (nextStart === end) {
|
|
11837
|
-
end = nextEnd;
|
|
11838
|
-
continue;
|
|
11839
|
-
}
|
|
11840
|
-
appendGap(first, i - 1, start, end);
|
|
11841
|
-
first = i;
|
|
11842
|
-
start = nextStart;
|
|
11843
|
-
end = nextEnd;
|
|
11844
|
-
}
|
|
11845
|
-
appendGap(first, entries.length - 1, start, end);
|
|
11846
|
-
return { before, after, beforeGaps, afterGaps, gaps };
|
|
11847
|
-
}
|
|
11848
|
-
function buildRootTriviaIndex(log, labels) {
|
|
11849
|
-
const entries = triviaEntries(log, labels);
|
|
11850
|
-
let maps;
|
|
11851
|
-
const getMaps = () => {
|
|
11852
|
-
maps ??= buildRootMaps(entries);
|
|
11853
|
-
return maps;
|
|
11854
|
-
};
|
|
11855
|
-
return {
|
|
11856
|
-
entries,
|
|
11857
|
-
labels,
|
|
11858
|
-
get before() {
|
|
11859
|
-
return getMaps().before;
|
|
11860
|
-
},
|
|
11861
|
-
get after() {
|
|
11862
|
-
return getMaps().after;
|
|
11863
|
-
},
|
|
11864
|
-
entryIndicesBefore(offset) {
|
|
11865
|
-
return getMaps().before.get(offset) ?? EMPTY_INDICES;
|
|
11866
|
-
},
|
|
11867
|
-
entryIndicesAfter(offset) {
|
|
11868
|
-
return getMaps().after.get(offset) ?? EMPTY_INDICES;
|
|
11869
|
-
},
|
|
11870
|
-
gapBefore(offset) {
|
|
11871
|
-
return getMaps().beforeGaps.get(offset);
|
|
11872
|
-
},
|
|
11873
|
-
gapAfter(offset) {
|
|
11874
|
-
return getMaps().afterGaps.get(offset);
|
|
11875
|
-
},
|
|
11876
|
-
gaps() {
|
|
11877
|
-
return getMaps().gaps;
|
|
11878
|
-
},
|
|
11879
|
-
gapsWithKind(kind) {
|
|
11880
|
-
const kinds = typeof kind === "string" ? [kind] : kind;
|
|
11881
|
-
const matches2 = [];
|
|
11882
|
-
for (const gap of getMaps().gaps) {
|
|
11883
|
-
for (const k of kinds) {
|
|
11884
|
-
if (gap.hasKind(k)) {
|
|
11885
|
-
matches2.push(gap);
|
|
11886
|
-
break;
|
|
11887
|
-
}
|
|
11888
|
-
}
|
|
11889
|
-
}
|
|
11890
|
-
return matches2.length === 0 ? EMPTY_GAPS : matches2;
|
|
11891
|
-
}
|
|
11892
|
-
};
|
|
11893
|
-
}
|
|
11894
|
-
|
|
11895
12286
|
// src/functional/run.ts
|
|
11896
12287
|
var invoke = (r, input, pos, ctx) => typeof r === "function" ? r(input, pos, ctx) : r.parse(input, pos, ctx);
|
|
11897
12288
|
function triviaKindLabelsFromRunnable(r) {
|
|
11898
12289
|
if (!r) return void 0;
|
|
11899
12290
|
if (typeof r === "function") return r._meta?.triviaKindLabels;
|
|
11900
12291
|
const grammarTrivia = r._meta.grammarTrivia;
|
|
11901
|
-
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;
|
|
11902
12306
|
}
|
|
11903
12307
|
function runOnce(entry, input, options, phase, profileState) {
|
|
11904
12308
|
if (typeof entry !== "function" && typeof entry?.parse !== "function") {
|
|
@@ -11906,13 +12310,31 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
11906
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).`
|
|
11907
12311
|
);
|
|
11908
12312
|
}
|
|
11909
|
-
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;
|
|
11910
12317
|
const errors = [];
|
|
11911
12318
|
const profile = profileState ?? (phase === void 0 ? void 0 : { phase, nodes: 0, childSlots: 0, rawSlots: 0, triviaSlots: 0, fieldSlots: 0, hostCalls: 0 });
|
|
11912
12319
|
const skipGlobalSinks = phase === "recognizer" || phase === "capture";
|
|
11913
12320
|
const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
|
|
11914
12321
|
const grammarScanSkip = typeof entry !== "function" ? entry._meta.grammarScanSkip : void 0;
|
|
11915
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
|
+
}
|
|
11916
12338
|
const stamped = entry;
|
|
11917
12339
|
assertHostModeCompatible(
|
|
11918
12340
|
typeof entry === "function" ? stamped[FUSED_HOST_MODE] ?? "ast" : entry._meta.grammarHostMode ?? "ast",
|
|
@@ -11921,7 +12343,15 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
11921
12343
|
);
|
|
11922
12344
|
const ctx = {
|
|
11923
12345
|
trackLines: false,
|
|
11924
|
-
...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
|
+
},
|
|
11925
12355
|
build: options.build,
|
|
11926
12356
|
state: options.state,
|
|
11927
12357
|
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...triviaKindLabels ? { triviaKindLabels } : {} } : triviaKindLabels ? { triviaKindLabels } : {},
|
|
@@ -11946,9 +12376,13 @@ function runOnce(entry, input, options, phase, profileState) {
|
|
|
11946
12376
|
span: r.span ?? { start: 0, end: 0 },
|
|
11947
12377
|
expected: r.ok ? [] : r.expected ?? [],
|
|
11948
12378
|
errors,
|
|
11949
|
-
|
|
11950
|
-
|
|
11951
|
-
|
|
12379
|
+
...selectedRootLog !== void 0 && selectedRootLog.length > 0 ? {
|
|
12380
|
+
rootTrivia: {
|
|
12381
|
+
rows: selectedRootLog,
|
|
12382
|
+
select: rootTriviaSelection,
|
|
12383
|
+
index: buildRootTriviaIndex(selectedRootLog, rootTriviaSelection)
|
|
12384
|
+
}
|
|
12385
|
+
} : {},
|
|
11952
12386
|
unconsumedFrom
|
|
11953
12387
|
};
|
|
11954
12388
|
}
|
|
@@ -12373,38 +12807,48 @@ function buildTriviaIndex(root, input = "", opts) {
|
|
|
12373
12807
|
}
|
|
12374
12808
|
|
|
12375
12809
|
// src/cst/walk.ts
|
|
12376
|
-
function
|
|
12377
|
-
|
|
12378
|
-
|
|
12379
|
-
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12388
|
-
const
|
|
12389
|
-
|
|
12390
|
-
|
|
12391
|
-
|
|
12392
|
-
|
|
12393
|
-
|
|
12394
|
-
|
|
12395
|
-
|
|
12396
|
-
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12810
|
+
function isCombinator(value) {
|
|
12811
|
+
return !!value && typeof value === "object" && "_def" in value && "_meta" in value && typeof value.parse === "function";
|
|
12812
|
+
}
|
|
12813
|
+
function reflectionFor(grammar) {
|
|
12814
|
+
const stamped = grammarReflectionOf(grammar);
|
|
12815
|
+
if (stamped) return stamped;
|
|
12816
|
+
const entries = Object.entries(grammar).filter((entry) => isCombinator(entry[1]));
|
|
12817
|
+
return collectGrammarReflection(entries);
|
|
12818
|
+
}
|
|
12819
|
+
function createVisitor(grammar, spec) {
|
|
12820
|
+
const reflection = reflectionFor(grammar);
|
|
12821
|
+
const typeHandlers = spec.type;
|
|
12822
|
+
const tagSpec = spec.tag;
|
|
12823
|
+
const tagHandlersByType = /* @__PURE__ */ new Map();
|
|
12824
|
+
if (tagSpec !== void 0) {
|
|
12825
|
+
for (const node2 of reflection.nodes) {
|
|
12826
|
+
const handlers = [];
|
|
12827
|
+
for (const tag of node2.tags) {
|
|
12828
|
+
const handler = tagSpec[tag];
|
|
12829
|
+
if (handler) handlers.push(handler);
|
|
12830
|
+
}
|
|
12831
|
+
if (handlers.length > 0) tagHandlersByType.set(node2.type, handlers);
|
|
12832
|
+
}
|
|
12833
|
+
}
|
|
12834
|
+
return (root, ctx = void 0) => {
|
|
12835
|
+
const go = (node2, parent) => {
|
|
12836
|
+
const descend = spec.enter ? spec.enter(node2, parent, ctx) : void 0;
|
|
12837
|
+
if (node2._tag === "node" && node2.type !== void 0) {
|
|
12838
|
+
typeHandlers?.[node2.type]?.(node2, parent, ctx);
|
|
12839
|
+
const tagHandlers = tagHandlersByType.get(node2.type);
|
|
12840
|
+
if (tagHandlers !== void 0) {
|
|
12841
|
+
for (const handler of tagHandlers) handler(node2, parent, ctx);
|
|
12402
12842
|
}
|
|
12403
12843
|
}
|
|
12404
|
-
|
|
12405
|
-
|
|
12844
|
+
const children2 = node2.children;
|
|
12845
|
+
if (descend !== false && Array.isArray(children2)) {
|
|
12846
|
+
for (const child of children2) go(child, node2);
|
|
12847
|
+
}
|
|
12848
|
+
spec.leave?.(node2, parent, ctx);
|
|
12849
|
+
};
|
|
12850
|
+
go(root, null);
|
|
12406
12851
|
};
|
|
12407
|
-
return (node2) => api.visit(node2);
|
|
12408
12852
|
}
|
|
12409
12853
|
|
|
12410
12854
|
// src/cst/offset-model.ts
|