parseman 0.43.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/combinators/attempt.d.ts.map +1 -1
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts +7 -0
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/map.d.ts +11 -0
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/token.d.ts +3 -2
- package/dist/combinators/token.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +1 -0
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/scannable-run.d.ts +1 -1
- package/dist/compiler/scannable-run.d.ts.map +1 -1
- package/dist/compiler/trivia-fast-path.d.ts +4 -3
- package/dist/compiler/trivia-fast-path.d.ts.map +1 -1
- package/dist/cst/trivia-entries.d.ts +15 -9
- package/dist/cst/trivia-entries.d.ts.map +1 -1
- package/dist/cst/trivia-kinds.d.ts +15 -11
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/functional/run.d.ts +22 -16
- package/dist/functional/run.d.ts.map +1 -1
- package/dist/index.cjs +1416 -1115
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1416 -1115
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs +161 -102
- package/dist/language-service/index.cjs.map +3 -3
- package/dist/language-service/index.js +161 -102
- package/dist/language-service/index.js.map +3 -3
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +1217 -985
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1217 -985
- package/dist/plugin/index.js.map +4 -4
- package/dist/run/index.cjs +152 -102
- package/dist/run/index.cjs.map +3 -3
- package/dist/run/index.d.ts +1 -1
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +152 -102
- package/dist/run/index.js.map +3 -3
- package/dist/spec/index.cjs +1414 -1286
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +1414 -1286
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +25 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/plugin/index.cjs
CHANGED
|
@@ -1106,843 +1106,433 @@ function keywords(words, opts = {}) {
|
|
|
1106
1106
|
};
|
|
1107
1107
|
}
|
|
1108
1108
|
|
|
1109
|
-
// src/
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
_cstChildren: ctx._cstChildren,
|
|
1116
|
-
_cstRawChildren: ctx._cstRawChildren,
|
|
1117
|
-
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1118
|
-
_triviaLog: ctx._triviaLog,
|
|
1119
|
-
_fields: ctx._fields,
|
|
1120
|
-
_cstBuf: ctx._cstBuf,
|
|
1121
|
-
_tolerant: ctx._tolerant,
|
|
1122
|
-
_sync: ctx._sync
|
|
1123
|
-
};
|
|
1124
|
-
ctx._probe = void 0;
|
|
1125
|
-
ctx._errors = void 0;
|
|
1126
|
-
ctx._cstLeaves = void 0;
|
|
1127
|
-
ctx._cstChildren = void 0;
|
|
1128
|
-
ctx._cstRawChildren = void 0;
|
|
1129
|
-
ctx._cstTriviaLog = void 0;
|
|
1130
|
-
ctx._triviaLog = void 0;
|
|
1131
|
-
ctx._fields = void 0;
|
|
1132
|
-
ctx._cstBuf = void 0;
|
|
1133
|
-
ctx._tolerant = void 0;
|
|
1134
|
-
ctx._sync = void 0;
|
|
1135
|
-
try {
|
|
1136
|
-
return sentinel.parse(input, pos, ctx).ok;
|
|
1137
|
-
} finally {
|
|
1138
|
-
ctx._probe = s._probe;
|
|
1139
|
-
ctx._errors = s._errors;
|
|
1140
|
-
ctx._cstLeaves = s._cstLeaves;
|
|
1141
|
-
ctx._cstChildren = s._cstChildren;
|
|
1142
|
-
ctx._cstRawChildren = s._cstRawChildren;
|
|
1143
|
-
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1144
|
-
ctx._triviaLog = s._triviaLog;
|
|
1145
|
-
ctx._fields = s._fields;
|
|
1146
|
-
ctx._cstBuf = s._cstBuf;
|
|
1147
|
-
ctx._tolerant = s._tolerant;
|
|
1148
|
-
ctx._sync = s._sync;
|
|
1149
|
-
}
|
|
1109
|
+
// src/cst/trivia-kinds.ts
|
|
1110
|
+
var labeledTriviaSpecs = /* @__PURE__ */ new WeakMap();
|
|
1111
|
+
function unwrapTrivia(p) {
|
|
1112
|
+
let cur = p;
|
|
1113
|
+
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1114
|
+
return cur;
|
|
1150
1115
|
}
|
|
1151
|
-
function
|
|
1152
|
-
if (
|
|
1153
|
-
return
|
|
1154
|
-
_tag: "orSentinel",
|
|
1155
|
-
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1156
|
-
_def: { tag: "unknown" },
|
|
1157
|
-
parse(input, pos, ctx) {
|
|
1158
|
-
const ra = a.parse(input, pos, ctx);
|
|
1159
|
-
if (ra.ok) return ra;
|
|
1160
|
-
return b.parse(input, pos, ctx);
|
|
1161
|
-
}
|
|
1162
|
-
};
|
|
1116
|
+
function peelLabel(p) {
|
|
1117
|
+
if (p._def.tag === "label") return { label: p._def.label, parser: p._def.parser };
|
|
1118
|
+
return null;
|
|
1163
1119
|
}
|
|
1164
|
-
function
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1120
|
+
function analyzeLabeledTrivia(trivia2) {
|
|
1121
|
+
const cached = labeledTriviaSpecs.get(trivia2);
|
|
1122
|
+
if (cached !== void 0) return cached;
|
|
1123
|
+
let core = unwrapTrivia(trivia2);
|
|
1124
|
+
let minRepeats = 1;
|
|
1125
|
+
if (core._def.tag === "oneOrMore") {
|
|
1126
|
+
core = core._def.parser;
|
|
1127
|
+
minRepeats = 1;
|
|
1128
|
+
} else if (core._def.tag === "many") {
|
|
1129
|
+
core = core._def.parser;
|
|
1130
|
+
minRepeats = 0;
|
|
1131
|
+
}
|
|
1132
|
+
const arms = [];
|
|
1133
|
+
if (core._def.tag === "choice") {
|
|
1134
|
+
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1135
|
+
const peeled = peelLabel(core._def.parsers[i]);
|
|
1136
|
+
if (!peeled) {
|
|
1137
|
+
labeledTriviaSpecs.set(trivia2, null);
|
|
1138
|
+
return null;
|
|
1177
1139
|
}
|
|
1178
|
-
|
|
1140
|
+
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1141
|
+
}
|
|
1142
|
+
} else {
|
|
1143
|
+
const peeled = peelLabel(core);
|
|
1144
|
+
if (!peeled) {
|
|
1145
|
+
labeledTriviaSpecs.set(trivia2, null);
|
|
1146
|
+
return null;
|
|
1179
1147
|
}
|
|
1148
|
+
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1149
|
+
}
|
|
1150
|
+
const spec = {
|
|
1151
|
+
labels: arms.map((a) => a.label),
|
|
1152
|
+
arms,
|
|
1153
|
+
minRepeats
|
|
1180
1154
|
};
|
|
1155
|
+
labeledTriviaSpecs.set(trivia2, spec);
|
|
1156
|
+
return spec;
|
|
1181
1157
|
}
|
|
1182
|
-
function
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1188
|
-
ctx._errors?.push(error);
|
|
1189
|
-
return { error, end: scanPos };
|
|
1190
|
-
}
|
|
1191
|
-
function matchesAt(sentinel, input, pos, ctx) {
|
|
1192
|
-
return probeAt(sentinel, input, pos, ctx);
|
|
1158
|
+
function matchArmAt(input, pos, arm, state) {
|
|
1159
|
+
if (!startsFirstSet(arm, input, pos)) return null;
|
|
1160
|
+
const r = arm.parse(input, pos, { trackLines: false, state });
|
|
1161
|
+
if (!r.ok || r.span.end <= pos) return null;
|
|
1162
|
+
return { end: r.span.end };
|
|
1193
1163
|
}
|
|
1194
|
-
function
|
|
1195
|
-
|
|
1164
|
+
function scanLabeledTriviaChunks(input, cur, spec, state) {
|
|
1165
|
+
const chunks = [];
|
|
1166
|
+
let pos = cur;
|
|
1167
|
+
while (pos < input.length) {
|
|
1168
|
+
let matched = null;
|
|
1169
|
+
for (const arm of spec.arms) {
|
|
1170
|
+
const m = matchArmAt(input, pos, arm.parser, state);
|
|
1171
|
+
if (m) {
|
|
1172
|
+
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1173
|
+
break;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
if (!matched) break;
|
|
1177
|
+
chunks.push({ start: pos, end: matched.end, kindIndex: matched.kindIndex });
|
|
1178
|
+
pos = matched.end;
|
|
1179
|
+
}
|
|
1180
|
+
if (chunks.length < spec.minRepeats) {
|
|
1181
|
+
return { end: cur, chunks: [] };
|
|
1182
|
+
}
|
|
1183
|
+
return { end: pos, chunks };
|
|
1196
1184
|
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1185
|
+
function scanLabeledTriviaEnd(input, cur, spec, state) {
|
|
1186
|
+
let pos = cur;
|
|
1187
|
+
let count = 0;
|
|
1188
|
+
while (pos < input.length) {
|
|
1189
|
+
let matched = null;
|
|
1190
|
+
for (const arm of spec.arms) {
|
|
1191
|
+
matched = matchArmAt(input, pos, arm.parser, state);
|
|
1192
|
+
if (matched) break;
|
|
1193
|
+
}
|
|
1194
|
+
if (!matched) break;
|
|
1195
|
+
pos = matched.end;
|
|
1196
|
+
count++;
|
|
1197
|
+
}
|
|
1198
|
+
return count < spec.minRepeats ? cur : pos;
|
|
1201
1199
|
}
|
|
1202
|
-
function
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
return [def.label];
|
|
1214
|
-
case "choice":
|
|
1215
|
-
return def.parsers.flatMap(deriveExpected2);
|
|
1216
|
-
case "dispatch":
|
|
1217
|
-
return deriveExpected2(def.selector);
|
|
1218
|
-
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
1219
|
-
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
1220
|
-
// able to fail first — deriving from term 0 alone named a token the parse
|
|
1221
|
-
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
1222
|
-
// nothing (its own expectation is about what must NOT be here), but it is
|
|
1223
|
-
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
1224
|
-
case "sequence": {
|
|
1225
|
-
const out = [];
|
|
1226
|
-
for (const term of def.parsers) {
|
|
1227
|
-
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
1228
|
-
if (!matchesEmpty(term)) break;
|
|
1200
|
+
function visitLabeledTrivia(input, cur, spec, state, visit) {
|
|
1201
|
+
if (spec.minRepeats > 1) return void 0;
|
|
1202
|
+
let pos = cur;
|
|
1203
|
+
let count = 0;
|
|
1204
|
+
while (pos < input.length) {
|
|
1205
|
+
let matched = null;
|
|
1206
|
+
for (const arm of spec.arms) {
|
|
1207
|
+
const match = matchArmAt(input, pos, arm.parser, state);
|
|
1208
|
+
if (match) {
|
|
1209
|
+
matched = { end: match.end, kindIndex: arm.kindIndex };
|
|
1210
|
+
break;
|
|
1229
1211
|
}
|
|
1230
|
-
return out;
|
|
1231
1212
|
}
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
case "not":
|
|
1255
|
-
case "peek":
|
|
1256
|
-
return deriveExpected2(def.parser);
|
|
1257
|
-
case "routed":
|
|
1258
|
-
return ["routed()"];
|
|
1259
|
-
case "lazy": {
|
|
1260
|
-
const name = c._ruleName;
|
|
1261
|
-
if (seen.has(c)) return name ? [name] : [];
|
|
1262
|
-
seen.add(c);
|
|
1263
|
-
try {
|
|
1264
|
-
return deriveExpected2(def.thunk());
|
|
1265
|
-
} catch {
|
|
1266
|
-
return name ? [name] : [];
|
|
1267
|
-
} finally {
|
|
1268
|
-
seen.delete(c);
|
|
1213
|
+
if (!matched) break;
|
|
1214
|
+
visit(pos, matched.end, matched.kindIndex);
|
|
1215
|
+
pos = matched.end;
|
|
1216
|
+
count++;
|
|
1217
|
+
}
|
|
1218
|
+
return count < spec.minRepeats ? cur : pos;
|
|
1219
|
+
}
|
|
1220
|
+
function recordTriviaChunks(ctx, chunks) {
|
|
1221
|
+
const kinds = ctx.triviaKindLabels;
|
|
1222
|
+
const mask = ctx._triviaCaptureMask;
|
|
1223
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1224
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
1225
|
+
const rootMark = rootLog?.length ?? 0;
|
|
1226
|
+
for (const ch2 of chunks) {
|
|
1227
|
+
pushTriviaLogEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1228
|
+
const rootKindIndex = ctx._rootTriviaCapture === false || rootLog === void 0 || rootKinds === void 0 || kinds === void 0 ? -1 : rootKinds[kinds[ch2.kindIndex] ?? ""] ?? -1;
|
|
1229
|
+
if (rootKindIndex >= 0) {
|
|
1230
|
+
rootLog.push(0, 0, ch2.start, ch2.end, rootKindIndex);
|
|
1231
|
+
}
|
|
1232
|
+
if (ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)) {
|
|
1233
|
+
if (mask === void 0 || kinds === void 0 || (mask & 1 << ch2.kindIndex) !== 0) {
|
|
1234
|
+
pushCstTriviaEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1269
1235
|
}
|
|
1270
1236
|
}
|
|
1271
|
-
default:
|
|
1272
|
-
return [];
|
|
1273
1237
|
}
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
isTrivia: false
|
|
1281
|
-
};
|
|
1282
|
-
return {
|
|
1283
|
-
_tag: "expect",
|
|
1284
|
-
_meta: meta,
|
|
1285
|
-
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1286
|
-
parse(input, pos, ctx) {
|
|
1287
|
-
const result = combinator.parse(input, pos, ctx);
|
|
1288
|
-
if (result.ok) return result;
|
|
1289
|
-
const span = { start: pos, end: pos };
|
|
1290
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1291
|
-
ctx._errors?.push(error);
|
|
1292
|
-
if (ctx._tolerant) captureError(ctx, error);
|
|
1293
|
-
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1238
|
+
if (rootLog !== void 0 && rootLog.length !== rootMark && chunks.length > 0) {
|
|
1239
|
+
const start = chunks[0].start;
|
|
1240
|
+
const end = chunks[chunks.length - 1].end;
|
|
1241
|
+
for (let offset = rootMark; offset < rootLog.length; offset += 5) {
|
|
1242
|
+
rootLog[offset] = start;
|
|
1243
|
+
rootLog[offset + 1] = end;
|
|
1294
1244
|
}
|
|
1295
|
-
}
|
|
1245
|
+
}
|
|
1296
1246
|
}
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
const
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
1304
|
-
let combined = { kind: "empty" };
|
|
1305
|
-
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
1306
|
-
const meta = {
|
|
1307
|
-
firstSet: combined,
|
|
1308
|
-
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1309
|
-
isTrivia: false,
|
|
1310
|
-
disjoint
|
|
1311
|
-
};
|
|
1312
|
-
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
1313
|
-
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1314
|
-
let greedyLitMap = null;
|
|
1315
|
-
let sortedParsers = null;
|
|
1316
|
-
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
1317
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1318
|
-
greedyLitMap = /* @__PURE__ */ new Map();
|
|
1319
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1320
|
-
if (i === strategy.superIndex) continue;
|
|
1321
|
-
const litVal = getCoreLiteralValue(parsers[i]);
|
|
1322
|
-
if (litVal !== null) greedyLitMap.set(litVal, i);
|
|
1323
|
-
}
|
|
1324
|
-
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
1325
|
-
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
1247
|
+
function triviaKindMask(labels, keep) {
|
|
1248
|
+
if (!labels) return void 0;
|
|
1249
|
+
let mask = 0;
|
|
1250
|
+
for (const name of keep) {
|
|
1251
|
+
const idx = labels.indexOf(name);
|
|
1252
|
+
if (idx >= 0) mask |= 1 << idx;
|
|
1326
1253
|
}
|
|
1254
|
+
return mask;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
// src/combinators/trivia-skip.ts
|
|
1258
|
+
var NOOP_COMMIT = () => {
|
|
1259
|
+
};
|
|
1260
|
+
var fastTriviaCache = /* @__PURE__ */ new WeakMap();
|
|
1261
|
+
function needsDeferredTriviaCommit(ctx) {
|
|
1262
|
+
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
1263
|
+
}
|
|
1264
|
+
function saveTriviaMark(ctx) {
|
|
1265
|
+
const m = saveCstMark(ctx);
|
|
1327
1266
|
return {
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1267
|
+
raw: m.raw,
|
|
1268
|
+
tlog: m.tlog,
|
|
1269
|
+
leaves: m.leaves,
|
|
1270
|
+
fields: m.fields,
|
|
1271
|
+
errors: m.errors,
|
|
1272
|
+
log: ctx._triviaLog ? ctx._triviaLog.length : 0,
|
|
1273
|
+
rootLog: ctx._rootTriviaLog ? ctx._rootTriviaLog.length : 0
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1276
|
+
function rollbackTrivia(ctx, mark) {
|
|
1277
|
+
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields, errors: mark.errors });
|
|
1278
|
+
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1279
|
+
if (ctx._rootTriviaLog && ctx._rootTriviaLog.length !== mark.rootLog) ctx._rootTriviaLog.length = mark.rootLog;
|
|
1280
|
+
}
|
|
1281
|
+
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1282
|
+
const probeCtx = {
|
|
1283
|
+
trackLines: ctx.trackLines,
|
|
1284
|
+
state: ctx.state,
|
|
1285
|
+
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1286
|
+
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1287
|
+
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1288
|
+
};
|
|
1289
|
+
const result = triviaP.parse(input, cur, probeCtx);
|
|
1290
|
+
ctx._lineScannedTo = probeCtx._lineScannedTo;
|
|
1291
|
+
return result;
|
|
1292
|
+
}
|
|
1293
|
+
function saveLookaheadMark(ctx) {
|
|
1294
|
+
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1295
|
+
}
|
|
1296
|
+
function rollbackLookahead(ctx, mark) {
|
|
1297
|
+
rollbackTrivia(ctx, mark);
|
|
1298
|
+
if (ctx._probe) ctx._probe.best = mark.probeBest;
|
|
1299
|
+
}
|
|
1300
|
+
function scanWithLabels(input, cur, ctx) {
|
|
1301
|
+
const triviaP = ctx.trivia;
|
|
1302
|
+
const spec = analyzeLabeledTrivia(triviaP);
|
|
1303
|
+
if (!spec) return { end: cur, commit: NOOP_COMMIT };
|
|
1304
|
+
const log = ctx._triviaLog;
|
|
1305
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1306
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
1307
|
+
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1308
|
+
const mask = ctx._triviaCaptureMask;
|
|
1309
|
+
let fullRows;
|
|
1310
|
+
let rootRows;
|
|
1311
|
+
let cstRows;
|
|
1312
|
+
const visitedEnd = visitLabeledTrivia(input, cur, spec, ctx.state, (start, matchEnd, kindIndex) => {
|
|
1313
|
+
if (log !== void 0) (fullRows ??= []).push(start, matchEnd, kindIndex);
|
|
1314
|
+
const selectedKind = rootLog === void 0 || rootKinds === void 0 || ctx._rootTriviaCapture === false ? void 0 : rootKinds[spec.labels[kindIndex] ?? ""];
|
|
1315
|
+
if (selectedKind !== void 0) (rootRows ??= []).push(start, matchEnd, selectedKind);
|
|
1316
|
+
if (captureTl && (mask === void 0 || (mask & 1 << kindIndex) !== 0)) {
|
|
1317
|
+
(cstRows ??= []).push(start, matchEnd, kindIndex);
|
|
1318
|
+
}
|
|
1319
|
+
});
|
|
1320
|
+
if (visitedEnd !== void 0) {
|
|
1321
|
+
if (visitedEnd === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1322
|
+
return {
|
|
1323
|
+
end: visitedEnd,
|
|
1324
|
+
commit: () => {
|
|
1325
|
+
if (fullRows !== void 0 && log !== void 0) log.push(...fullRows);
|
|
1326
|
+
if (rootRows !== void 0 && rootLog !== void 0) {
|
|
1327
|
+
for (let i = 0; i < rootRows.length; i += 3) {
|
|
1328
|
+
rootLog.push(cur, visitedEnd, rootRows[i], rootRows[i + 1], rootRows[i + 2]);
|
|
1349
1329
|
}
|
|
1350
1330
|
}
|
|
1351
|
-
if (
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1331
|
+
if (cstRows !== void 0) {
|
|
1332
|
+
for (let i = 0; i < cstRows.length; i += 3) {
|
|
1333
|
+
pushCstTriviaEntry(ctx, cstRows[i], cstRows[i + 1], cstRows[i + 2]);
|
|
1355
1334
|
}
|
|
1356
|
-
const result = parsers[idx].parse(input, pos, ctx);
|
|
1357
|
-
if (result.ok) return result;
|
|
1358
|
-
expected.push(...result.expected);
|
|
1359
|
-
if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
|
|
1360
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1361
|
-
}
|
|
1362
|
-
return {
|
|
1363
|
-
ok: false,
|
|
1364
|
-
expected: parsers.flatMap((p) => {
|
|
1365
|
-
const r = p.parse(input, pos, ctx);
|
|
1366
|
-
return r.ok ? [] : r.expected;
|
|
1367
|
-
}),
|
|
1368
|
-
span: { start: pos, end: pos }
|
|
1369
|
-
};
|
|
1370
|
-
}
|
|
1371
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1372
|
-
const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
|
|
1373
|
-
if (!superResult.ok) return superResult;
|
|
1374
|
-
const end = superResult.span.end;
|
|
1375
|
-
const litIdx = greedyLitMap.get(input.slice(pos, end));
|
|
1376
|
-
if (litIdx !== void 0) {
|
|
1377
|
-
const litVal = getCoreLiteralValue(parsers[litIdx]);
|
|
1378
|
-
const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
|
|
1379
|
-
return { ok: true, value, span: { start: pos, end } };
|
|
1380
|
-
}
|
|
1381
|
-
return superResult;
|
|
1382
|
-
}
|
|
1383
|
-
if (strategy?.tag === "literalsLongestFirst") {
|
|
1384
|
-
for (const p of sortedParsers) {
|
|
1385
|
-
const r = p.parse(input, pos, ctx);
|
|
1386
|
-
if (r.ok) return r;
|
|
1387
|
-
expected.push(...r.expected);
|
|
1388
|
-
}
|
|
1389
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1390
|
-
}
|
|
1391
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1392
|
-
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
1393
|
-
const mark = saveCstMark(ctx);
|
|
1394
|
-
const logLen = ctx._triviaLog?.length;
|
|
1395
|
-
const result = parsers[i].parse(input, pos, ctx);
|
|
1396
|
-
if (!result.ok) {
|
|
1397
|
-
rollbackCstCapture(ctx, mark);
|
|
1398
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1399
|
-
expected.push(...result.expected);
|
|
1400
|
-
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
1401
|
-
continue;
|
|
1402
1335
|
}
|
|
1403
|
-
const checks = autoNot[i];
|
|
1404
|
-
if (checks && autoNotFires(input, result.span.end, checks)) {
|
|
1405
|
-
rollbackCstCapture(ctx, mark);
|
|
1406
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1407
|
-
continue;
|
|
1408
|
-
}
|
|
1409
|
-
return result;
|
|
1410
1336
|
}
|
|
1411
|
-
|
|
1412
|
-
|
|
1337
|
+
};
|
|
1338
|
+
}
|
|
1339
|
+
const { end, chunks } = scanLabeledTriviaChunks(input, cur, spec, ctx.state);
|
|
1340
|
+
if (end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1341
|
+
return {
|
|
1342
|
+
end,
|
|
1343
|
+
commit: () => recordTriviaChunks(ctx, chunks)
|
|
1413
1344
|
};
|
|
1414
1345
|
}
|
|
1415
|
-
function
|
|
1416
|
-
const
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
const
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
const m = re.exec(litVal);
|
|
1431
|
-
return m !== null && m[0] === litVal;
|
|
1432
|
-
});
|
|
1433
|
-
if (allSubsumed) return { tag: "greedyClassify", superIndex };
|
|
1346
|
+
function skipWithLabels(input, cur, ctx) {
|
|
1347
|
+
const spec = analyzeLabeledTrivia(ctx.trivia);
|
|
1348
|
+
if (spec) return scanLabeledTriviaEnd(input, cur, spec, ctx.state);
|
|
1349
|
+
const tr = parseTriviaNoCapture(ctx.trivia, input, cur, ctx);
|
|
1350
|
+
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1351
|
+
}
|
|
1352
|
+
function advanceTrivia(input, cur, ctx) {
|
|
1353
|
+
const triviaP = ctx.trivia;
|
|
1354
|
+
if (!triviaP) return cur;
|
|
1355
|
+
if (!ctx.trackLines) {
|
|
1356
|
+
const fast2 = fastTriviaScanner(triviaP);
|
|
1357
|
+
if (fast2) return fast2(input, cur);
|
|
1358
|
+
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
1359
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1360
|
+
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1434
1361
|
}
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
);
|
|
1439
|
-
|
|
1362
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1363
|
+
const fast = fastTriviaScanner(triviaP);
|
|
1364
|
+
if (fast) {
|
|
1365
|
+
const end = fast(input, cur);
|
|
1366
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1367
|
+
return end;
|
|
1440
1368
|
}
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
function bareLeadingTermKey(term) {
|
|
1446
|
-
const d = term._def;
|
|
1447
|
-
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
1448
|
-
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
1449
|
-
return null;
|
|
1450
|
-
}
|
|
1451
|
-
function detectSharedPrefix(parsers) {
|
|
1452
|
-
if (parsers.length < 2) return null;
|
|
1453
|
-
let key = null;
|
|
1454
|
-
let prefix = null;
|
|
1455
|
-
const members = [];
|
|
1456
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1457
|
-
const term0 = leadingTermOfArm(parsers[i]);
|
|
1458
|
-
if (term0 === null) return null;
|
|
1459
|
-
const k = bareLeadingTermKey(term0);
|
|
1460
|
-
if (k === null) return null;
|
|
1461
|
-
if (key === null) {
|
|
1462
|
-
key = k;
|
|
1463
|
-
prefix = term0;
|
|
1464
|
-
} else if (k !== key) return null;
|
|
1465
|
-
members.push(i);
|
|
1369
|
+
if (ctx.triviaKindLabels) {
|
|
1370
|
+
const end = skipWithLabels(input, cur, ctx);
|
|
1371
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1372
|
+
return end;
|
|
1466
1373
|
}
|
|
1467
|
-
|
|
1468
|
-
return
|
|
1374
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1375
|
+
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1469
1376
|
}
|
|
1470
|
-
function
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1377
|
+
function scanTrivia(input, cur, ctx) {
|
|
1378
|
+
const triviaP = ctx.trivia;
|
|
1379
|
+
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1380
|
+
const log = ctx._triviaLog;
|
|
1381
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1382
|
+
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1383
|
+
if (!ctx.trackLines) {
|
|
1384
|
+
const fast2 = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1385
|
+
if (fast2 && log === void 0 && !captureTl) {
|
|
1386
|
+
return { end: fast2(input, cur), commit: NOOP_COMMIT };
|
|
1476
1387
|
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
1480
|
-
return d.parsers[0];
|
|
1481
|
-
}
|
|
1482
|
-
function computeAutoNot(parsers) {
|
|
1483
|
-
return parsers.map((p, i) => {
|
|
1484
|
-
const litVal = getCoreLiteralValue(p);
|
|
1485
|
-
if (litVal === null) return null;
|
|
1486
|
-
const checks = [];
|
|
1487
|
-
for (let j = i + 1; j < parsers.length; j++) {
|
|
1488
|
-
const other = parsers[j];
|
|
1489
|
-
const otherLit = getCoreLiteralValue(other);
|
|
1490
|
-
if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
|
|
1491
|
-
checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
|
|
1492
|
-
continue;
|
|
1493
|
-
}
|
|
1494
|
-
const regexDef = getCoreRegexDef(other);
|
|
1495
|
-
if (regexDef !== null) {
|
|
1496
|
-
const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
|
|
1497
|
-
if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
|
|
1498
|
-
}
|
|
1388
|
+
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1389
|
+
return scanWithLabels(input, cur, ctx);
|
|
1499
1390
|
}
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1391
|
+
if (ctx.triviaKindLabels) return { end: skipWithLabels(input, cur, ctx), commit: NOOP_COMMIT };
|
|
1392
|
+
if (log !== void 0 || rootLog !== void 0 || captureTl) {
|
|
1393
|
+
const tr3 = triviaP.parse(input, cur, {
|
|
1394
|
+
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1395
|
+
state: ctx.state
|
|
1396
|
+
});
|
|
1397
|
+
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1398
|
+
const end = tr3.span.end;
|
|
1399
|
+
return {
|
|
1400
|
+
end,
|
|
1401
|
+
commit: () => {
|
|
1402
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1403
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1404
|
+
}
|
|
1405
|
+
};
|
|
1510
1406
|
}
|
|
1407
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1408
|
+
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1511
1409
|
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
return null;
|
|
1519
|
-
}
|
|
1520
|
-
function getCoreRegexDef(p) {
|
|
1521
|
-
const def = p._def;
|
|
1522
|
-
if (def.tag === "regex") return { source: def.source, flags: def.flags };
|
|
1523
|
-
if (def.tag === "transform") return getCoreRegexDef(def.parser);
|
|
1524
|
-
if (def.tag === "label") return getCoreRegexDef(def.parser);
|
|
1525
|
-
return null;
|
|
1526
|
-
}
|
|
1527
|
-
function applyTransforms(p, value, span) {
|
|
1528
|
-
const def = p._def;
|
|
1529
|
-
if (def.tag === "transform") {
|
|
1530
|
-
const inner = applyTransforms(def.parser, value, span);
|
|
1531
|
-
return def.fn(inner, span);
|
|
1410
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1411
|
+
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1412
|
+
if (fast && log === void 0 && !captureTl) {
|
|
1413
|
+
const end = fast(input, cur);
|
|
1414
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1415
|
+
return { end, commit: NOOP_COMMIT };
|
|
1532
1416
|
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
re.lastIndex = 0;
|
|
1538
|
-
const base = re.exec(lit);
|
|
1539
|
-
if (!base || base[0] !== lit) return null;
|
|
1540
|
-
const contCodes = [];
|
|
1541
|
-
for (let code = 1; code < 128; code++) {
|
|
1542
|
-
re.lastIndex = 0;
|
|
1543
|
-
const m = re.exec(lit + String.fromCharCode(code));
|
|
1544
|
-
if (m && m[0].length > lit.length) contCodes.push(code);
|
|
1417
|
+
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1418
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1419
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1420
|
+
return scan;
|
|
1545
1421
|
}
|
|
1546
|
-
if (
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
codes.sort((a, b) => a - b);
|
|
1551
|
-
const ranges = [];
|
|
1552
|
-
let lo = codes[0], hi = codes[0];
|
|
1553
|
-
for (let i = 1; i < codes.length; i++) {
|
|
1554
|
-
if (codes[i] === hi + 1) {
|
|
1555
|
-
hi = codes[i];
|
|
1556
|
-
} else {
|
|
1557
|
-
ranges.push({ lo, hi });
|
|
1558
|
-
lo = hi = codes[i];
|
|
1559
|
-
}
|
|
1422
|
+
if (ctx.triviaKindLabels) {
|
|
1423
|
+
const end = skipWithLabels(input, cur, ctx);
|
|
1424
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1425
|
+
return { end, commit: NOOP_COMMIT };
|
|
1560
1426
|
}
|
|
1561
|
-
|
|
1562
|
-
|
|
1427
|
+
if (log !== void 0 || rootLog !== void 0 || captureTl) {
|
|
1428
|
+
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1429
|
+
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1430
|
+
const end = tr2.span.end;
|
|
1431
|
+
return {
|
|
1432
|
+
end,
|
|
1433
|
+
commit: () => {
|
|
1434
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1435
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1440
|
+
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1563
1441
|
}
|
|
1564
|
-
function
|
|
1565
|
-
if (
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
return
|
|
1442
|
+
function consumeTrivia(input, cur, ctx) {
|
|
1443
|
+
if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
|
|
1444
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1445
|
+
scan.commit();
|
|
1446
|
+
return scan.end;
|
|
1569
1447
|
}
|
|
1570
|
-
function
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
return
|
|
1448
|
+
function fastTriviaScanner(trivia2) {
|
|
1449
|
+
const cached = fastTriviaCache.get(trivia2);
|
|
1450
|
+
if (cached !== void 0) return cached;
|
|
1451
|
+
const scanner = buildFastTriviaScanner(trivia2);
|
|
1452
|
+
fastTriviaCache.set(trivia2, scanner);
|
|
1453
|
+
return scanner;
|
|
1576
1454
|
}
|
|
1577
|
-
function
|
|
1578
|
-
const
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1455
|
+
function buildFastTriviaScanner(trivia2) {
|
|
1456
|
+
const core = trivia2._def.tag === "trivia" ? trivia2._def.parser : trivia2;
|
|
1457
|
+
const direct = regexTriviaScanner(core);
|
|
1458
|
+
if (direct) return direct;
|
|
1459
|
+
const repeat = core._def.tag === "oneOrMore" || core._def.tag === "many" && core._def.min >= 1 ? core._def.parser : null;
|
|
1460
|
+
if (!repeat) return null;
|
|
1461
|
+
const one = regexTriviaScanner(repeat);
|
|
1462
|
+
if (one) return loopScanner([one]);
|
|
1463
|
+
if (repeat._def.tag !== "choice") return null;
|
|
1464
|
+
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1465
|
+
if (arms.some((s) => s === null)) return null;
|
|
1466
|
+
return loopScanner(arms);
|
|
1467
|
+
}
|
|
1468
|
+
function loopScanner(arms) {
|
|
1469
|
+
return (input, cur) => {
|
|
1470
|
+
let pos = cur;
|
|
1471
|
+
scan: while (pos < input.length) {
|
|
1472
|
+
for (const arm of arms) {
|
|
1473
|
+
const end = arm(input, pos);
|
|
1474
|
+
if (end > pos) {
|
|
1475
|
+
pos = end;
|
|
1476
|
+
continue scan;
|
|
1477
|
+
}
|
|
1585
1478
|
}
|
|
1479
|
+
break;
|
|
1586
1480
|
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
}
|
|
1590
|
-
|
|
1591
|
-
// src/cst/trivia-kinds.ts
|
|
1592
|
-
function unwrapTrivia(p) {
|
|
1593
|
-
let cur = p;
|
|
1594
|
-
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1595
|
-
return cur;
|
|
1481
|
+
return pos;
|
|
1482
|
+
};
|
|
1596
1483
|
}
|
|
1597
|
-
function
|
|
1598
|
-
if (
|
|
1599
|
-
|
|
1484
|
+
function regexTriviaScanner(parser2) {
|
|
1485
|
+
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1486
|
+
const source = parser2._def.source;
|
|
1487
|
+
return classRunSource(source) ?? altStarSource(source);
|
|
1600
1488
|
}
|
|
1601
|
-
function
|
|
1602
|
-
let
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
core = core._def.parser;
|
|
1606
|
-
minRepeats = 1;
|
|
1607
|
-
} else if (core._def.tag === "many") {
|
|
1608
|
-
core = core._def.parser;
|
|
1609
|
-
minRepeats = 0;
|
|
1610
|
-
}
|
|
1611
|
-
const arms = [];
|
|
1612
|
-
if (core._def.tag === "choice") {
|
|
1613
|
-
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1614
|
-
const peeled = peelLabel(core._def.parsers[i]);
|
|
1615
|
-
if (!peeled) return null;
|
|
1616
|
-
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1617
|
-
}
|
|
1618
|
-
} else {
|
|
1619
|
-
const peeled = peelLabel(core);
|
|
1620
|
-
if (!peeled) return null;
|
|
1621
|
-
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1489
|
+
function inRanges2(cp, ranges) {
|
|
1490
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
1491
|
+
const r = ranges[i];
|
|
1492
|
+
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1622
1493
|
}
|
|
1623
|
-
return
|
|
1494
|
+
return false;
|
|
1624
1495
|
}
|
|
1625
|
-
function
|
|
1626
|
-
const
|
|
1627
|
-
if (!
|
|
1628
|
-
return
|
|
1496
|
+
function classScanner(classBody) {
|
|
1497
|
+
const ranges = parseClassRanges(classBody);
|
|
1498
|
+
if (!ranges) return null;
|
|
1499
|
+
return (input, cur) => {
|
|
1500
|
+
let pos = cur;
|
|
1501
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1502
|
+
return pos;
|
|
1503
|
+
};
|
|
1629
1504
|
}
|
|
1630
|
-
function
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1639
|
-
break;
|
|
1640
|
-
}
|
|
1505
|
+
function untilLineBreakScanner(leaderCode) {
|
|
1506
|
+
return (input, cur) => {
|
|
1507
|
+
if (input.charCodeAt(cur) !== leaderCode) return cur;
|
|
1508
|
+
let pos = cur + 1;
|
|
1509
|
+
while (pos < input.length) {
|
|
1510
|
+
const cc = input.charCodeAt(pos);
|
|
1511
|
+
if (cc === 10 || cc === 13) break;
|
|
1512
|
+
pos++;
|
|
1641
1513
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1514
|
+
return pos;
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
function classRunSource(source) {
|
|
1518
|
+
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1519
|
+
return m ? classScanner(m[1]) : null;
|
|
1520
|
+
}
|
|
1521
|
+
function classifyTriviaArm(arm) {
|
|
1522
|
+
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1523
|
+
if (cls) {
|
|
1524
|
+
const ranges = parseClassRanges(cls[1]);
|
|
1525
|
+
return ranges ? { kind: "class", ranges } : null;
|
|
1645
1526
|
}
|
|
1646
|
-
|
|
1647
|
-
|
|
1527
|
+
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1528
|
+
if (lc) {
|
|
1529
|
+
const marker = lc[1];
|
|
1530
|
+
return { kind: "untilLineBreak", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1648
1531
|
}
|
|
1649
|
-
return
|
|
1650
|
-
}
|
|
1651
|
-
function scanFastWsCommentsChunks(input, cur, wsKind, commentKind) {
|
|
1652
|
-
const chunks = [];
|
|
1653
|
-
let pos = cur;
|
|
1654
|
-
while (pos < input.length) {
|
|
1655
|
-
const c = input.charCodeAt(pos);
|
|
1656
|
-
if (c === 32 || c === 9 || c === 10 || c === 13 || c === 12) {
|
|
1657
|
-
const start = pos;
|
|
1658
|
-
pos++;
|
|
1659
|
-
while (pos < input.length) {
|
|
1660
|
-
const c2 = input.charCodeAt(pos);
|
|
1661
|
-
if (c2 === 32 || c2 === 9 || c2 === 10 || c2 === 13 || c2 === 12) pos++;
|
|
1662
|
-
else break;
|
|
1663
|
-
}
|
|
1664
|
-
chunks.push({ start, end: pos, kindIndex: wsKind });
|
|
1665
|
-
continue;
|
|
1666
|
-
}
|
|
1667
|
-
if (c === 47 && input.charCodeAt(pos + 1) === 42) {
|
|
1668
|
-
let j = pos + 2;
|
|
1669
|
-
while (j + 1 < input.length && !(input.charCodeAt(j) === 42 && input.charCodeAt(j + 1) === 47)) j++;
|
|
1670
|
-
if (j + 1 < input.length && input.charCodeAt(j) === 42 && input.charCodeAt(j + 1) === 47) {
|
|
1671
|
-
const start = pos;
|
|
1672
|
-
pos = j + 2;
|
|
1673
|
-
chunks.push({ start, end: pos, kindIndex: commentKind });
|
|
1674
|
-
continue;
|
|
1675
|
-
}
|
|
1676
|
-
break;
|
|
1677
|
-
}
|
|
1678
|
-
break;
|
|
1679
|
-
}
|
|
1680
|
-
return { end: pos, chunks };
|
|
1681
|
-
}
|
|
1682
|
-
function tryFastLabeledScan(input, cur, trivia2) {
|
|
1683
|
-
const spec = analyzeLabeledTrivia(trivia2);
|
|
1684
|
-
if (!spec || spec.arms.length !== 2) return null;
|
|
1685
|
-
const wsArm = spec.arms.find((a) => {
|
|
1686
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1687
|
-
return src != null && !src.includes("\\*");
|
|
1688
|
-
});
|
|
1689
|
-
const commentArm = spec.arms.find((a) => {
|
|
1690
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1691
|
-
return src != null && src.includes("\\*");
|
|
1692
|
-
});
|
|
1693
|
-
if (!wsArm || !commentArm) return null;
|
|
1694
|
-
const { chunks } = scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1695
|
-
if (chunks.length < spec.minRepeats) return { end: cur, chunks: [] };
|
|
1696
|
-
return scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1697
|
-
}
|
|
1698
|
-
function recordTriviaChunks(ctx, chunks) {
|
|
1699
|
-
const kinds = ctx.triviaKindLabels;
|
|
1700
|
-
const mask = ctx._triviaCaptureMask;
|
|
1701
|
-
for (const ch2 of chunks) {
|
|
1702
|
-
pushTriviaLogEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1703
|
-
if (ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)) {
|
|
1704
|
-
if (mask === void 0 || kinds === void 0 || (mask & 1 << ch2.kindIndex) !== 0) {
|
|
1705
|
-
pushCstTriviaEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
function triviaKindMask(labels, keep) {
|
|
1711
|
-
if (!labels) return void 0;
|
|
1712
|
-
let mask = 0;
|
|
1713
|
-
for (const name of keep) {
|
|
1714
|
-
const idx = labels.indexOf(name);
|
|
1715
|
-
if (idx >= 0) mask |= 1 << idx;
|
|
1716
|
-
}
|
|
1717
|
-
return mask;
|
|
1718
|
-
}
|
|
1719
|
-
|
|
1720
|
-
// src/combinators/trivia-skip.ts
|
|
1721
|
-
var NOOP_COMMIT = () => {
|
|
1722
|
-
};
|
|
1723
|
-
var fastTriviaCache = /* @__PURE__ */ new WeakMap();
|
|
1724
|
-
function needsDeferredTriviaCommit(ctx) {
|
|
1725
|
-
return ctx._triviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
1726
|
-
}
|
|
1727
|
-
function saveTriviaMark(ctx) {
|
|
1728
|
-
const m = saveCstMark(ctx);
|
|
1729
|
-
return { raw: m.raw, tlog: m.tlog, leaves: m.leaves, fields: m.fields, errors: m.errors, log: ctx._triviaLog ? ctx._triviaLog.length : 0 };
|
|
1730
|
-
}
|
|
1731
|
-
function rollbackTrivia(ctx, mark) {
|
|
1732
|
-
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields, errors: mark.errors });
|
|
1733
|
-
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1734
|
-
}
|
|
1735
|
-
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1736
|
-
const probeCtx = {
|
|
1737
|
-
trackLines: ctx.trackLines,
|
|
1738
|
-
state: ctx.state,
|
|
1739
|
-
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1740
|
-
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1741
|
-
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1742
|
-
};
|
|
1743
|
-
const result = triviaP.parse(input, cur, probeCtx);
|
|
1744
|
-
ctx._lineScannedTo = probeCtx._lineScannedTo;
|
|
1745
|
-
return result;
|
|
1746
|
-
}
|
|
1747
|
-
function saveLookaheadMark(ctx) {
|
|
1748
|
-
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1749
|
-
}
|
|
1750
|
-
function rollbackLookahead(ctx, mark) {
|
|
1751
|
-
rollbackTrivia(ctx, mark);
|
|
1752
|
-
if (ctx._probe) ctx._probe.best = mark.probeBest;
|
|
1753
|
-
}
|
|
1754
|
-
function scanWithLabels(input, cur, ctx) {
|
|
1755
|
-
const triviaP = ctx.trivia;
|
|
1756
|
-
const spec = analyzeLabeledTrivia(triviaP);
|
|
1757
|
-
if (!spec) return { end: cur, commit: NOOP_COMMIT };
|
|
1758
|
-
const fast = tryFastLabeledScan(input, cur, triviaP);
|
|
1759
|
-
const { end, chunks } = fast ?? scanLabeledTriviaChunks(input, cur, spec);
|
|
1760
|
-
if (end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1761
|
-
return {
|
|
1762
|
-
end,
|
|
1763
|
-
commit: () => recordTriviaChunks(ctx, chunks)
|
|
1764
|
-
};
|
|
1765
|
-
}
|
|
1766
|
-
function advanceTrivia(input, cur, ctx) {
|
|
1767
|
-
const triviaP = ctx.trivia;
|
|
1768
|
-
if (!triviaP) return cur;
|
|
1769
|
-
if (!ctx.trackLines) {
|
|
1770
|
-
const fast2 = fastTriviaScanner(triviaP);
|
|
1771
|
-
if (fast2) return fast2(input, cur);
|
|
1772
|
-
if (ctx.triviaKindLabels) {
|
|
1773
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1774
|
-
return scan.end;
|
|
1775
|
-
}
|
|
1776
|
-
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1777
|
-
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1778
|
-
}
|
|
1779
|
-
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1780
|
-
const fast = fastTriviaScanner(triviaP);
|
|
1781
|
-
if (fast) {
|
|
1782
|
-
const end = fast(input, cur);
|
|
1783
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1784
|
-
return end;
|
|
1785
|
-
}
|
|
1786
|
-
if (ctx.triviaKindLabels) {
|
|
1787
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1788
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1789
|
-
return scan.end;
|
|
1790
|
-
}
|
|
1791
|
-
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1792
|
-
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1793
|
-
}
|
|
1794
|
-
function scanTrivia(input, cur, ctx) {
|
|
1795
|
-
const triviaP = ctx.trivia;
|
|
1796
|
-
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1797
|
-
const log = ctx._triviaLog;
|
|
1798
|
-
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1799
|
-
if (!ctx.trackLines) {
|
|
1800
|
-
const fast2 = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1801
|
-
if (fast2 && log === void 0 && !captureTl) {
|
|
1802
|
-
return { end: fast2(input, cur), commit: NOOP_COMMIT };
|
|
1803
|
-
}
|
|
1804
|
-
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1805
|
-
return scanWithLabels(input, cur, ctx);
|
|
1806
|
-
}
|
|
1807
|
-
if (log !== void 0 || captureTl) {
|
|
1808
|
-
const tr3 = triviaP.parse(input, cur, {
|
|
1809
|
-
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1810
|
-
state: ctx.state
|
|
1811
|
-
});
|
|
1812
|
-
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1813
|
-
const end = tr3.span.end;
|
|
1814
|
-
return {
|
|
1815
|
-
end,
|
|
1816
|
-
commit: () => {
|
|
1817
|
-
pushTriviaLogEntry(ctx, cur, end);
|
|
1818
|
-
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1819
|
-
}
|
|
1820
|
-
};
|
|
1821
|
-
}
|
|
1822
|
-
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1823
|
-
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1824
|
-
}
|
|
1825
|
-
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1826
|
-
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1827
|
-
if (fast && log === void 0 && !captureTl) {
|
|
1828
|
-
const end = fast(input, cur);
|
|
1829
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1830
|
-
return { end, commit: NOOP_COMMIT };
|
|
1831
|
-
}
|
|
1832
|
-
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1833
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1834
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1835
|
-
return scan;
|
|
1836
|
-
}
|
|
1837
|
-
if (log !== void 0 || captureTl) {
|
|
1838
|
-
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1839
|
-
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1840
|
-
const end = tr2.span.end;
|
|
1841
|
-
return {
|
|
1842
|
-
end,
|
|
1843
|
-
commit: () => {
|
|
1844
|
-
pushTriviaLogEntry(ctx, cur, end);
|
|
1845
|
-
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1846
|
-
}
|
|
1847
|
-
};
|
|
1848
|
-
}
|
|
1849
|
-
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1850
|
-
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1851
|
-
}
|
|
1852
|
-
function consumeTrivia(input, cur, ctx) {
|
|
1853
|
-
if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
|
|
1854
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
1855
|
-
scan.commit();
|
|
1856
|
-
return scan.end;
|
|
1857
|
-
}
|
|
1858
|
-
function fastTriviaScanner(trivia2) {
|
|
1859
|
-
const cached = fastTriviaCache.get(trivia2);
|
|
1860
|
-
if (cached !== void 0) return cached;
|
|
1861
|
-
const scanner = buildFastTriviaScanner(trivia2);
|
|
1862
|
-
fastTriviaCache.set(trivia2, scanner);
|
|
1863
|
-
return scanner;
|
|
1864
|
-
}
|
|
1865
|
-
function buildFastTriviaScanner(trivia2) {
|
|
1866
|
-
const core = trivia2._def.tag === "trivia" ? trivia2._def.parser : trivia2;
|
|
1867
|
-
const direct = regexTriviaScanner(core);
|
|
1868
|
-
if (direct) return direct;
|
|
1869
|
-
const repeat = core._def.tag === "oneOrMore" || core._def.tag === "many" && core._def.min >= 1 ? core._def.parser : null;
|
|
1870
|
-
if (!repeat) return null;
|
|
1871
|
-
const one = regexTriviaScanner(repeat);
|
|
1872
|
-
if (one) return loopScanner([one]);
|
|
1873
|
-
if (repeat._def.tag !== "choice") return null;
|
|
1874
|
-
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1875
|
-
if (arms.some((s) => s === null)) return null;
|
|
1876
|
-
return loopScanner(arms);
|
|
1877
|
-
}
|
|
1878
|
-
function loopScanner(arms) {
|
|
1879
|
-
return (input, cur) => {
|
|
1880
|
-
let pos = cur;
|
|
1881
|
-
scan: while (pos < input.length) {
|
|
1882
|
-
for (const arm of arms) {
|
|
1883
|
-
const end = arm(input, pos);
|
|
1884
|
-
if (end > pos) {
|
|
1885
|
-
pos = end;
|
|
1886
|
-
continue scan;
|
|
1887
|
-
}
|
|
1888
|
-
}
|
|
1889
|
-
break;
|
|
1890
|
-
}
|
|
1891
|
-
return pos;
|
|
1892
|
-
};
|
|
1893
|
-
}
|
|
1894
|
-
function regexTriviaScanner(parser2) {
|
|
1895
|
-
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1896
|
-
const source = parser2._def.source;
|
|
1897
|
-
return classRunSource(source) ?? altStarSource(source) ?? (blockCommentSource(source) ? scanBlockComment : null);
|
|
1898
|
-
}
|
|
1899
|
-
function inRanges2(cp, ranges) {
|
|
1900
|
-
for (let i = 0; i < ranges.length; i++) {
|
|
1901
|
-
const r = ranges[i];
|
|
1902
|
-
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1903
|
-
}
|
|
1904
|
-
return false;
|
|
1905
|
-
}
|
|
1906
|
-
function classScanner(classBody) {
|
|
1907
|
-
const ranges = parseClassRanges(classBody);
|
|
1908
|
-
if (!ranges) return null;
|
|
1909
|
-
return (input, cur) => {
|
|
1910
|
-
let pos = cur;
|
|
1911
|
-
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1912
|
-
return pos;
|
|
1913
|
-
};
|
|
1914
|
-
}
|
|
1915
|
-
function lineCommentScanner(commentCode) {
|
|
1916
|
-
return (input, cur) => {
|
|
1917
|
-
if (input.charCodeAt(cur) !== commentCode) return cur;
|
|
1918
|
-
let pos = cur + 1;
|
|
1919
|
-
while (pos < input.length) {
|
|
1920
|
-
const cc = input.charCodeAt(pos);
|
|
1921
|
-
if (cc === 10 || cc === 13) break;
|
|
1922
|
-
pos++;
|
|
1923
|
-
}
|
|
1924
|
-
return pos;
|
|
1925
|
-
};
|
|
1926
|
-
}
|
|
1927
|
-
function classRunSource(source) {
|
|
1928
|
-
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1929
|
-
return m ? classScanner(m[1]) : null;
|
|
1930
|
-
}
|
|
1931
|
-
function classifyTriviaArm(arm) {
|
|
1932
|
-
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1933
|
-
if (cls) {
|
|
1934
|
-
const ranges = parseClassRanges(cls[1]);
|
|
1935
|
-
return ranges ? { kind: "class", ranges } : null;
|
|
1936
|
-
}
|
|
1937
|
-
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1938
|
-
if (lc) {
|
|
1939
|
-
const marker = lc[1];
|
|
1940
|
-
return { kind: "comment", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1941
|
-
}
|
|
1942
|
-
return null;
|
|
1532
|
+
return null;
|
|
1943
1533
|
}
|
|
1944
1534
|
function armScanner(arm) {
|
|
1945
|
-
if (arm.kind === "
|
|
1535
|
+
if (arm.kind === "untilLineBreak") return untilLineBreakScanner(arm.code);
|
|
1946
1536
|
const ranges = arm.ranges;
|
|
1947
1537
|
return (input, cur) => {
|
|
1948
1538
|
let pos = cur;
|
|
@@ -1950,9 +1540,9 @@ function armScanner(arm) {
|
|
|
1950
1540
|
return pos;
|
|
1951
1541
|
};
|
|
1952
1542
|
}
|
|
1953
|
-
function fusedTriviaScanner(ranges,
|
|
1954
|
-
const c0 =
|
|
1955
|
-
const single =
|
|
1543
|
+
function fusedTriviaScanner(ranges, leaders) {
|
|
1544
|
+
const c0 = leaders[0];
|
|
1545
|
+
const single = leaders.length === 1;
|
|
1956
1546
|
return (input, cur) => {
|
|
1957
1547
|
let pos = cur;
|
|
1958
1548
|
const len = input.length;
|
|
@@ -1962,7 +1552,7 @@ function fusedTriviaScanner(ranges, commentCodes) {
|
|
|
1962
1552
|
pos++;
|
|
1963
1553
|
continue;
|
|
1964
1554
|
}
|
|
1965
|
-
if (single ? c === c0 :
|
|
1555
|
+
if (single ? c === c0 : leaders.includes(c)) {
|
|
1966
1556
|
pos++;
|
|
1967
1557
|
while (pos < len) {
|
|
1968
1558
|
const cc = input.charCodeAt(pos);
|
|
@@ -1971,166 +1561,640 @@ function fusedTriviaScanner(ranges, commentCodes) {
|
|
|
1971
1561
|
}
|
|
1972
1562
|
continue;
|
|
1973
1563
|
}
|
|
1974
|
-
break;
|
|
1564
|
+
break;
|
|
1565
|
+
}
|
|
1566
|
+
return pos;
|
|
1567
|
+
};
|
|
1568
|
+
}
|
|
1569
|
+
function splitTopLevelAlts(body) {
|
|
1570
|
+
const arms = [];
|
|
1571
|
+
let inClass = false;
|
|
1572
|
+
let start = 0;
|
|
1573
|
+
for (let i = 0; i < body.length; i++) {
|
|
1574
|
+
const c = body[i];
|
|
1575
|
+
if (c === "\\") {
|
|
1576
|
+
i++;
|
|
1577
|
+
continue;
|
|
1578
|
+
}
|
|
1579
|
+
if (inClass) {
|
|
1580
|
+
if (c === "]") inClass = false;
|
|
1581
|
+
continue;
|
|
1582
|
+
}
|
|
1583
|
+
if (c === "[") inClass = true;
|
|
1584
|
+
else if (c === "(") return null;
|
|
1585
|
+
else if (c === "|") {
|
|
1586
|
+
arms.push(body.slice(start, i));
|
|
1587
|
+
start = i + 1;
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
arms.push(body.slice(start));
|
|
1591
|
+
return arms;
|
|
1592
|
+
}
|
|
1593
|
+
function altStarSource(source) {
|
|
1594
|
+
const m = /^\(\?:(.*)\)[*+]$/.exec(source);
|
|
1595
|
+
if (!m) return null;
|
|
1596
|
+
const armSrcs = splitTopLevelAlts(m[1]);
|
|
1597
|
+
if (!armSrcs || armSrcs.length < 2) return null;
|
|
1598
|
+
const arms = [];
|
|
1599
|
+
for (const src of armSrcs) {
|
|
1600
|
+
const arm = classifyTriviaArm(src);
|
|
1601
|
+
if (!arm) return null;
|
|
1602
|
+
arms.push(arm);
|
|
1603
|
+
}
|
|
1604
|
+
const ranges = [];
|
|
1605
|
+
const leaders = [];
|
|
1606
|
+
for (const arm of arms) {
|
|
1607
|
+
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1608
|
+
else leaders.push(arm.code);
|
|
1609
|
+
}
|
|
1610
|
+
if (leaders.some((code) => inRanges2(code, ranges))) {
|
|
1611
|
+
return loopScanner(arms.map(armScanner));
|
|
1612
|
+
}
|
|
1613
|
+
if (leaders.length === 0) return armScanner({ kind: "class", ranges });
|
|
1614
|
+
return fusedTriviaScanner(ranges, leaders);
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
// src/recovery/scan.ts
|
|
1618
|
+
function probeAt(sentinel, input, pos, ctx) {
|
|
1619
|
+
const s = {
|
|
1620
|
+
_probe: ctx._probe,
|
|
1621
|
+
_errors: ctx._errors,
|
|
1622
|
+
_cstLeaves: ctx._cstLeaves,
|
|
1623
|
+
_cstChildren: ctx._cstChildren,
|
|
1624
|
+
_cstRawChildren: ctx._cstRawChildren,
|
|
1625
|
+
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1626
|
+
_triviaLog: ctx._triviaLog,
|
|
1627
|
+
_rootTriviaLog: ctx._rootTriviaLog,
|
|
1628
|
+
_fields: ctx._fields,
|
|
1629
|
+
_cstBuf: ctx._cstBuf,
|
|
1630
|
+
_tolerant: ctx._tolerant,
|
|
1631
|
+
_sync: ctx._sync
|
|
1632
|
+
};
|
|
1633
|
+
ctx._probe = void 0;
|
|
1634
|
+
ctx._errors = void 0;
|
|
1635
|
+
ctx._cstLeaves = void 0;
|
|
1636
|
+
ctx._cstChildren = void 0;
|
|
1637
|
+
ctx._cstRawChildren = void 0;
|
|
1638
|
+
ctx._cstTriviaLog = void 0;
|
|
1639
|
+
ctx._triviaLog = void 0;
|
|
1640
|
+
ctx._rootTriviaLog = void 0;
|
|
1641
|
+
ctx._fields = void 0;
|
|
1642
|
+
ctx._cstBuf = void 0;
|
|
1643
|
+
ctx._tolerant = void 0;
|
|
1644
|
+
ctx._sync = void 0;
|
|
1645
|
+
try {
|
|
1646
|
+
return sentinel.parse(input, pos, ctx).ok;
|
|
1647
|
+
} finally {
|
|
1648
|
+
ctx._probe = s._probe;
|
|
1649
|
+
ctx._errors = s._errors;
|
|
1650
|
+
ctx._cstLeaves = s._cstLeaves;
|
|
1651
|
+
ctx._cstChildren = s._cstChildren;
|
|
1652
|
+
ctx._cstRawChildren = s._cstRawChildren;
|
|
1653
|
+
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1654
|
+
ctx._triviaLog = s._triviaLog;
|
|
1655
|
+
ctx._rootTriviaLog = s._rootTriviaLog;
|
|
1656
|
+
ctx._fields = s._fields;
|
|
1657
|
+
ctx._cstBuf = s._cstBuf;
|
|
1658
|
+
ctx._tolerant = s._tolerant;
|
|
1659
|
+
ctx._sync = s._sync;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
function orSentinel(a, b) {
|
|
1663
|
+
if (b === void 0) return a;
|
|
1664
|
+
return {
|
|
1665
|
+
_tag: "orSentinel",
|
|
1666
|
+
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1667
|
+
_def: { tag: "unknown" },
|
|
1668
|
+
parse(input, pos, ctx) {
|
|
1669
|
+
const ra = a.parse(input, pos, ctx);
|
|
1670
|
+
if (ra.ok) return ra;
|
|
1671
|
+
return b.parse(input, pos, ctx);
|
|
1672
|
+
}
|
|
1673
|
+
};
|
|
1674
|
+
}
|
|
1675
|
+
function firstSetSentinel(fs2) {
|
|
1676
|
+
if (fs2.kind !== "ranges" || fs2.ranges.length === 0) return null;
|
|
1677
|
+
const ranges = fs2.ranges;
|
|
1678
|
+
return {
|
|
1679
|
+
_tag: "firstSetSentinel",
|
|
1680
|
+
_meta: { firstSet: fs2, canMatchNewline: false, isTrivia: false },
|
|
1681
|
+
_def: { tag: "unknown" },
|
|
1682
|
+
parse(input, pos) {
|
|
1683
|
+
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
1684
|
+
if (code !== void 0) {
|
|
1685
|
+
for (const r of ranges) {
|
|
1686
|
+
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
1690
|
+
}
|
|
1691
|
+
};
|
|
1692
|
+
}
|
|
1693
|
+
function recoverScan(input, from, ctx, sync, expected) {
|
|
1694
|
+
let scanPos = from;
|
|
1695
|
+
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1696
|
+
const span = { start: from, end: scanPos };
|
|
1697
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
1698
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1699
|
+
ctx._errors?.push(error);
|
|
1700
|
+
return { error, end: scanPos };
|
|
1701
|
+
}
|
|
1702
|
+
function matchesAt(sentinel, input, pos, ctx) {
|
|
1703
|
+
return probeAt(sentinel, input, pos, ctx);
|
|
1704
|
+
}
|
|
1705
|
+
function captureError(ctx, error) {
|
|
1706
|
+
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
// src/combinators/sequence.ts
|
|
1710
|
+
function sequence(...parsers) {
|
|
1711
|
+
const meta = {
|
|
1712
|
+
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
1713
|
+
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
1714
|
+
firstSet: sequenceFirstSet(parsers),
|
|
1715
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1716
|
+
isTrivia: false
|
|
1717
|
+
};
|
|
1718
|
+
const def = { tag: "sequence", parsers };
|
|
1719
|
+
let followSentinels;
|
|
1720
|
+
function parseTolerant(input, pos, ctx) {
|
|
1721
|
+
followSentinels ??= parsers.map((_, i) => {
|
|
1722
|
+
const fs2 = parsers.slice(i + 1).reduce(
|
|
1723
|
+
(acc, p) => union(acc, firstSetOf(p)),
|
|
1724
|
+
{ kind: "empty" }
|
|
1725
|
+
);
|
|
1726
|
+
return firstSetSentinel(fs2);
|
|
1727
|
+
});
|
|
1728
|
+
const values = def.valueUnused ? void 0 : [];
|
|
1729
|
+
let cur = pos;
|
|
1730
|
+
const inheritedSync = ctx._sync;
|
|
1731
|
+
try {
|
|
1732
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1733
|
+
ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
1734
|
+
if (ctx.trivia && i > 0) {
|
|
1735
|
+
const mark = saveTriviaMark(ctx);
|
|
1736
|
+
let scanEnd;
|
|
1737
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
1738
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1739
|
+
scan.commit();
|
|
1740
|
+
scanEnd = scan.end;
|
|
1741
|
+
} else {
|
|
1742
|
+
scanEnd = advanceTrivia(input, cur, ctx);
|
|
1743
|
+
}
|
|
1744
|
+
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
1745
|
+
if (!result2.ok) return result2;
|
|
1746
|
+
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
1747
|
+
else rollbackTrivia(ctx, mark);
|
|
1748
|
+
if (values !== void 0) values.push(result2.value);
|
|
1749
|
+
continue;
|
|
1750
|
+
}
|
|
1751
|
+
const result = parsers[i].parse(input, cur, ctx);
|
|
1752
|
+
if (!result.ok) return result;
|
|
1753
|
+
if (values !== void 0) values.push(result.value);
|
|
1754
|
+
cur = result.span.end;
|
|
1755
|
+
}
|
|
1756
|
+
} finally {
|
|
1757
|
+
ctx._sync = inheritedSync;
|
|
1758
|
+
}
|
|
1759
|
+
return {
|
|
1760
|
+
ok: true,
|
|
1761
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1762
|
+
value: values ?? void 0,
|
|
1763
|
+
span: { start: pos, end: cur }
|
|
1764
|
+
};
|
|
1765
|
+
}
|
|
1766
|
+
return {
|
|
1767
|
+
_tag: "sequence",
|
|
1768
|
+
_meta: meta,
|
|
1769
|
+
_def: def,
|
|
1770
|
+
parse(input, pos, ctx) {
|
|
1771
|
+
if (ctx._tolerant) return parseTolerant(input, pos, ctx);
|
|
1772
|
+
const values = def.valueUnused ? void 0 : [];
|
|
1773
|
+
let cur = pos;
|
|
1774
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1775
|
+
if (ctx.trivia && i > 0) {
|
|
1776
|
+
let scanEnd;
|
|
1777
|
+
let mark = saveTriviaMark(ctx);
|
|
1778
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
1779
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1780
|
+
scan.commit();
|
|
1781
|
+
scanEnd = scan.end;
|
|
1782
|
+
} else {
|
|
1783
|
+
scanEnd = advanceTrivia(input, cur, ctx);
|
|
1784
|
+
}
|
|
1785
|
+
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
1786
|
+
if (!result2.ok) return result2;
|
|
1787
|
+
if (result2.span.end > scanEnd) {
|
|
1788
|
+
cur = result2.span.end;
|
|
1789
|
+
} else {
|
|
1790
|
+
rollbackTrivia(ctx, mark);
|
|
1791
|
+
}
|
|
1792
|
+
if (values !== void 0) values.push(result2.value);
|
|
1793
|
+
continue;
|
|
1794
|
+
}
|
|
1795
|
+
const result = parsers[i].parse(input, cur, ctx);
|
|
1796
|
+
if (!result.ok) return result;
|
|
1797
|
+
if (values !== void 0) values.push(result.value);
|
|
1798
|
+
cur = result.span.end;
|
|
1799
|
+
}
|
|
1800
|
+
return {
|
|
1801
|
+
ok: true,
|
|
1802
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1803
|
+
value: values ?? void 0,
|
|
1804
|
+
span: { start: pos, end: cur }
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
};
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
// src/combinators/expect.ts
|
|
1811
|
+
function deriveExpected(c) {
|
|
1812
|
+
return [...new Set(derive(c, /* @__PURE__ */ new Set()))];
|
|
1813
|
+
}
|
|
1814
|
+
function derive(c, seen) {
|
|
1815
|
+
const deriveExpected2 = (p) => derive(p, seen);
|
|
1816
|
+
const def = c._def;
|
|
1817
|
+
switch (def.tag) {
|
|
1818
|
+
case "literal":
|
|
1819
|
+
return [JSON.stringify(def.value)];
|
|
1820
|
+
case "regex":
|
|
1821
|
+
return [`/${def.source}/`];
|
|
1822
|
+
case "keywords":
|
|
1823
|
+
return def.words.map((w) => JSON.stringify(w));
|
|
1824
|
+
case "label":
|
|
1825
|
+
return [def.label];
|
|
1826
|
+
case "choice":
|
|
1827
|
+
return def.parsers.flatMap(deriveExpected2);
|
|
1828
|
+
case "dispatch":
|
|
1829
|
+
return deriveExpected2(def.selector);
|
|
1830
|
+
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
1831
|
+
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
1832
|
+
// able to fail first — deriving from term 0 alone named a token the parse
|
|
1833
|
+
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
1834
|
+
// nothing (its own expectation is about what must NOT be here), but it is
|
|
1835
|
+
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
1836
|
+
case "sequence": {
|
|
1837
|
+
const out = [];
|
|
1838
|
+
for (const term of def.parsers) {
|
|
1839
|
+
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
1840
|
+
if (!matchesEmpty(term)) break;
|
|
1841
|
+
}
|
|
1842
|
+
return out;
|
|
1843
|
+
}
|
|
1844
|
+
case "attempt":
|
|
1845
|
+
return deriveExpected2(def.parser);
|
|
1846
|
+
// Delegating wrappers whose first-token failure is their inner parser's — must
|
|
1847
|
+
// pass through so a start-failure (and the first-set-miss fast-path in attempt/
|
|
1848
|
+
// node, which reads this) names the real expected token, not the wrapper tag.
|
|
1849
|
+
case "field":
|
|
1850
|
+
case "withCtx":
|
|
1851
|
+
case "recover":
|
|
1852
|
+
return deriveExpected2(def.parser);
|
|
1853
|
+
case "skip":
|
|
1854
|
+
return deriveExpected2(def.main);
|
|
1855
|
+
case "expect":
|
|
1856
|
+
return def.expected;
|
|
1857
|
+
case "node":
|
|
1858
|
+
case "grammar":
|
|
1859
|
+
case "trivia":
|
|
1860
|
+
case "token":
|
|
1861
|
+
case "leaf":
|
|
1862
|
+
case "optional":
|
|
1863
|
+
case "many":
|
|
1864
|
+
case "oneOrMore":
|
|
1865
|
+
case "transform":
|
|
1866
|
+
case "not":
|
|
1867
|
+
case "peek":
|
|
1868
|
+
return deriveExpected2(def.parser);
|
|
1869
|
+
case "routed":
|
|
1870
|
+
return ["routed()"];
|
|
1871
|
+
case "lazy": {
|
|
1872
|
+
const name = c._ruleName;
|
|
1873
|
+
if (seen.has(c)) return name ? [name] : [];
|
|
1874
|
+
seen.add(c);
|
|
1875
|
+
try {
|
|
1876
|
+
return deriveExpected2(def.thunk());
|
|
1877
|
+
} catch {
|
|
1878
|
+
return name ? [name] : [];
|
|
1879
|
+
} finally {
|
|
1880
|
+
seen.delete(c);
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
default:
|
|
1884
|
+
return [];
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
function expect(combinator, label2) {
|
|
1888
|
+
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
1889
|
+
const meta = {
|
|
1890
|
+
firstSet: combinator._meta.firstSet,
|
|
1891
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1892
|
+
isTrivia: false
|
|
1893
|
+
};
|
|
1894
|
+
return {
|
|
1895
|
+
_tag: "expect",
|
|
1896
|
+
_meta: meta,
|
|
1897
|
+
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1898
|
+
parse(input, pos, ctx) {
|
|
1899
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1900
|
+
if (result.ok) return result;
|
|
1901
|
+
const span = { start: pos, end: pos };
|
|
1902
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1903
|
+
ctx._errors?.push(error);
|
|
1904
|
+
if (ctx._tolerant) captureError(ctx, error);
|
|
1905
|
+
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1906
|
+
}
|
|
1907
|
+
};
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
// src/combinators/choice.ts
|
|
1911
|
+
function choice(...args) {
|
|
1912
|
+
const parsers = args.map((a) => "gate" in a ? a.combinator : a);
|
|
1913
|
+
const gates = args.map((a) => "gate" in a ? a.gate : null);
|
|
1914
|
+
const hasGates = gates.some((g) => g !== null);
|
|
1915
|
+
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
1916
|
+
let combined = { kind: "empty" };
|
|
1917
|
+
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
1918
|
+
const meta = {
|
|
1919
|
+
firstSet: combined,
|
|
1920
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1921
|
+
isTrivia: false,
|
|
1922
|
+
disjoint
|
|
1923
|
+
};
|
|
1924
|
+
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
1925
|
+
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1926
|
+
let greedyLitMap = null;
|
|
1927
|
+
let sortedParsers = null;
|
|
1928
|
+
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
1929
|
+
if (strategy?.tag === "greedyClassify") {
|
|
1930
|
+
greedyLitMap = /* @__PURE__ */ new Map();
|
|
1931
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1932
|
+
if (i === strategy.superIndex) continue;
|
|
1933
|
+
const litVal = getCoreLiteralValue(parsers[i]);
|
|
1934
|
+
if (litVal !== null) greedyLitMap.set(litVal, i);
|
|
1935
|
+
}
|
|
1936
|
+
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
1937
|
+
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
1938
|
+
}
|
|
1939
|
+
return {
|
|
1940
|
+
_tag: "choice",
|
|
1941
|
+
_meta: meta,
|
|
1942
|
+
_def: {
|
|
1943
|
+
tag: "choice",
|
|
1944
|
+
parsers,
|
|
1945
|
+
gates,
|
|
1946
|
+
disjoint,
|
|
1947
|
+
strategy: strategy ?? { tag: "firstMatch" },
|
|
1948
|
+
autoNot
|
|
1949
|
+
},
|
|
1950
|
+
parse(input, pos, ctx) {
|
|
1951
|
+
const expected = [];
|
|
1952
|
+
if (disjoint && pos < input.length) {
|
|
1953
|
+
const code = input.codePointAt(pos);
|
|
1954
|
+
let idx = code < 128 ? asciiDispatch[code] : -1;
|
|
1955
|
+
if (idx < 0) {
|
|
1956
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1957
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
1958
|
+
idx = i;
|
|
1959
|
+
break;
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
if (idx >= 0) {
|
|
1964
|
+
const gate2 = gates[idx];
|
|
1965
|
+
if (gate2 && !gate2(ctx.state)) {
|
|
1966
|
+
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1967
|
+
}
|
|
1968
|
+
const result = parsers[idx].parse(input, pos, ctx);
|
|
1969
|
+
if (result.ok) return result;
|
|
1970
|
+
expected.push(...result.expected);
|
|
1971
|
+
if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
|
|
1972
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1973
|
+
}
|
|
1974
|
+
return {
|
|
1975
|
+
ok: false,
|
|
1976
|
+
expected: parsers.flatMap((p) => {
|
|
1977
|
+
const r = p.parse(input, pos, ctx);
|
|
1978
|
+
return r.ok ? [] : r.expected;
|
|
1979
|
+
}),
|
|
1980
|
+
span: { start: pos, end: pos }
|
|
1981
|
+
};
|
|
1982
|
+
}
|
|
1983
|
+
if (strategy?.tag === "greedyClassify") {
|
|
1984
|
+
const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
|
|
1985
|
+
if (!superResult.ok) return superResult;
|
|
1986
|
+
const end = superResult.span.end;
|
|
1987
|
+
const litIdx = greedyLitMap.get(input.slice(pos, end));
|
|
1988
|
+
if (litIdx !== void 0) {
|
|
1989
|
+
const litVal = getCoreLiteralValue(parsers[litIdx]);
|
|
1990
|
+
const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
|
|
1991
|
+
return { ok: true, value, span: { start: pos, end } };
|
|
1992
|
+
}
|
|
1993
|
+
return superResult;
|
|
1994
|
+
}
|
|
1995
|
+
if (strategy?.tag === "literalsLongestFirst") {
|
|
1996
|
+
for (const p of sortedParsers) {
|
|
1997
|
+
const r = p.parse(input, pos, ctx);
|
|
1998
|
+
if (r.ok) return r;
|
|
1999
|
+
expected.push(...r.expected);
|
|
2000
|
+
}
|
|
2001
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
2002
|
+
}
|
|
2003
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2004
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
2005
|
+
const mark = saveTriviaMark(ctx);
|
|
2006
|
+
const result = parsers[i].parse(input, pos, ctx);
|
|
2007
|
+
if (!result.ok) {
|
|
2008
|
+
rollbackTrivia(ctx, mark);
|
|
2009
|
+
expected.push(...result.expected);
|
|
2010
|
+
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
2011
|
+
continue;
|
|
2012
|
+
}
|
|
2013
|
+
const checks = autoNot[i];
|
|
2014
|
+
if (checks && autoNotFires(input, result.span.end, checks)) {
|
|
2015
|
+
rollbackTrivia(ctx, mark);
|
|
2016
|
+
continue;
|
|
2017
|
+
}
|
|
2018
|
+
return result;
|
|
2019
|
+
}
|
|
2020
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
2021
|
+
}
|
|
2022
|
+
};
|
|
2023
|
+
}
|
|
2024
|
+
function detectStrategy(parsers) {
|
|
2025
|
+
const regexIndices = [];
|
|
2026
|
+
const literalIndices = [];
|
|
2027
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2028
|
+
if (getCoreRegexDef(parsers[i]) !== null) regexIndices.push(i);
|
|
2029
|
+
else if (getCoreLiteralValue(parsers[i]) !== null) literalIndices.push(i);
|
|
2030
|
+
}
|
|
2031
|
+
if (regexIndices.length === 1 && literalIndices.length === parsers.length - 1 && literalIndices.length > 0) {
|
|
2032
|
+
const superIndex = regexIndices[0];
|
|
2033
|
+
const regexDef = getCoreRegexDef(parsers[superIndex]);
|
|
2034
|
+
const flags = "y" + regexDef.flags.replace(/[gy]/g, "");
|
|
2035
|
+
const re = new RegExp(regexDef.source, flags);
|
|
2036
|
+
const allSubsumed = literalIndices.every((i) => {
|
|
2037
|
+
const litVal = getCoreLiteralValue(parsers[i]);
|
|
2038
|
+
re.lastIndex = 0;
|
|
2039
|
+
const m = re.exec(litVal);
|
|
2040
|
+
return m !== null && m[0] === litVal;
|
|
2041
|
+
});
|
|
2042
|
+
if (allSubsumed) return { tag: "greedyClassify", superIndex };
|
|
2043
|
+
}
|
|
2044
|
+
if (parsers.length === literalIndices.length) {
|
|
2045
|
+
const sortedIndices = [...literalIndices].sort(
|
|
2046
|
+
(a, b) => getCoreLiteralValue(parsers[b]).length - getCoreLiteralValue(parsers[a]).length
|
|
2047
|
+
);
|
|
2048
|
+
return { tag: "literalsLongestFirst", sortedIndices };
|
|
2049
|
+
}
|
|
2050
|
+
const shared = detectSharedPrefix(parsers);
|
|
2051
|
+
if (shared !== null) return shared;
|
|
2052
|
+
return { tag: "firstMatch" };
|
|
2053
|
+
}
|
|
2054
|
+
function bareLeadingTermKey(term) {
|
|
2055
|
+
const d = term._def;
|
|
2056
|
+
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
2057
|
+
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
2058
|
+
return null;
|
|
2059
|
+
}
|
|
2060
|
+
function detectSharedPrefix(parsers) {
|
|
2061
|
+
if (parsers.length < 2) return null;
|
|
2062
|
+
let key = null;
|
|
2063
|
+
let prefix = null;
|
|
2064
|
+
const members = [];
|
|
2065
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2066
|
+
const term0 = leadingTermOfArm(parsers[i]);
|
|
2067
|
+
if (term0 === null) return null;
|
|
2068
|
+
const k = bareLeadingTermKey(term0);
|
|
2069
|
+
if (k === null) return null;
|
|
2070
|
+
if (key === null) {
|
|
2071
|
+
key = k;
|
|
2072
|
+
prefix = term0;
|
|
2073
|
+
} else if (k !== key) return null;
|
|
2074
|
+
members.push(i);
|
|
2075
|
+
}
|
|
2076
|
+
if (prefix === null || members.length < 2) return null;
|
|
2077
|
+
return { tag: "sharedPrefix", prefix, members };
|
|
2078
|
+
}
|
|
2079
|
+
function leadingTermOfArm(arm) {
|
|
2080
|
+
let d = arm._def;
|
|
2081
|
+
for (; ; ) {
|
|
2082
|
+
if (d.tag === "node" || d.tag === "grammar" || d.tag === "transform" || d.tag === "label") {
|
|
2083
|
+
d = d.parser._def;
|
|
2084
|
+
continue;
|
|
2085
|
+
}
|
|
2086
|
+
break;
|
|
2087
|
+
}
|
|
2088
|
+
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
2089
|
+
return d.parsers[0];
|
|
2090
|
+
}
|
|
2091
|
+
function computeAutoNot(parsers) {
|
|
2092
|
+
return parsers.map((p, i) => {
|
|
2093
|
+
const litVal = getCoreLiteralValue(p);
|
|
2094
|
+
if (litVal === null) return null;
|
|
2095
|
+
const checks = [];
|
|
2096
|
+
for (let j = i + 1; j < parsers.length; j++) {
|
|
2097
|
+
const other = parsers[j];
|
|
2098
|
+
const otherLit = getCoreLiteralValue(other);
|
|
2099
|
+
if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
|
|
2100
|
+
checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
|
|
2101
|
+
continue;
|
|
2102
|
+
}
|
|
2103
|
+
const regexDef = getCoreRegexDef(other);
|
|
2104
|
+
if (regexDef !== null) {
|
|
2105
|
+
const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
|
|
2106
|
+
if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
|
|
2107
|
+
}
|
|
1975
2108
|
}
|
|
1976
|
-
return
|
|
1977
|
-
};
|
|
2109
|
+
return checks.length > 0 ? checks : null;
|
|
2110
|
+
});
|
|
1978
2111
|
}
|
|
1979
|
-
function
|
|
1980
|
-
const
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
i++;
|
|
1987
|
-
continue;
|
|
1988
|
-
}
|
|
1989
|
-
if (inClass) {
|
|
1990
|
-
if (c === "]") inClass = false;
|
|
1991
|
-
continue;
|
|
1992
|
-
}
|
|
1993
|
-
if (c === "[") inClass = true;
|
|
1994
|
-
else if (c === "(") return null;
|
|
1995
|
-
else if (c === "|") {
|
|
1996
|
-
arms.push(body.slice(start, i));
|
|
1997
|
-
start = i + 1;
|
|
2112
|
+
function autoNotFires(input, end, checks) {
|
|
2113
|
+
for (const check of checks) {
|
|
2114
|
+
if (check.kind === "firstSet") {
|
|
2115
|
+
const code = end < input.length ? input.codePointAt(end) ?? -1 : -1;
|
|
2116
|
+
if (inFirstSet(code, check.set)) return true;
|
|
2117
|
+
} else {
|
|
2118
|
+
if (input.startsWith(check.value, end)) return true;
|
|
1998
2119
|
}
|
|
1999
2120
|
}
|
|
2000
|
-
|
|
2001
|
-
return arms;
|
|
2121
|
+
return false;
|
|
2002
2122
|
}
|
|
2003
|
-
function
|
|
2004
|
-
const
|
|
2005
|
-
if (!
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2123
|
+
function getCoreLiteralValue(p) {
|
|
2124
|
+
const def = p._def;
|
|
2125
|
+
if (def.tag === "literal" && !def.caseInsensitive) return def.value;
|
|
2126
|
+
if (def.tag === "transform") return getCoreLiteralValue(def.parser);
|
|
2127
|
+
return null;
|
|
2128
|
+
}
|
|
2129
|
+
function getCoreRegexDef(p) {
|
|
2130
|
+
const def = p._def;
|
|
2131
|
+
if (def.tag === "regex") return { source: def.source, flags: def.flags };
|
|
2132
|
+
if (def.tag === "transform") return getCoreRegexDef(def.parser);
|
|
2133
|
+
if (def.tag === "label") return getCoreRegexDef(def.parser);
|
|
2134
|
+
return null;
|
|
2135
|
+
}
|
|
2136
|
+
function applyTransforms(p, value, span) {
|
|
2137
|
+
const def = p._def;
|
|
2138
|
+
if (def.tag === "transform") {
|
|
2139
|
+
const inner = applyTransforms(def.parser, value, span);
|
|
2140
|
+
return def.fn(inner, span);
|
|
2013
2141
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2142
|
+
return value;
|
|
2143
|
+
}
|
|
2144
|
+
function continuationFirstSet(lit, source, flags) {
|
|
2145
|
+
const re = new RegExp(source, "y" + flags.replace(/[gy]/g, ""));
|
|
2146
|
+
re.lastIndex = 0;
|
|
2147
|
+
const base = re.exec(lit);
|
|
2148
|
+
if (!base || base[0] !== lit) return null;
|
|
2149
|
+
const contCodes = [];
|
|
2150
|
+
for (let code = 1; code < 128; code++) {
|
|
2151
|
+
re.lastIndex = 0;
|
|
2152
|
+
const m = re.exec(lit + String.fromCharCode(code));
|
|
2153
|
+
if (m && m[0].length > lit.length) contCodes.push(code);
|
|
2019
2154
|
}
|
|
2020
|
-
if (
|
|
2021
|
-
|
|
2155
|
+
if (contCodes.length === 0) return null;
|
|
2156
|
+
return codesToFirstSet(contCodes);
|
|
2157
|
+
}
|
|
2158
|
+
function codesToFirstSet(codes) {
|
|
2159
|
+
codes.sort((a, b) => a - b);
|
|
2160
|
+
const ranges = [];
|
|
2161
|
+
let lo = codes[0], hi = codes[0];
|
|
2162
|
+
for (let i = 1; i < codes.length; i++) {
|
|
2163
|
+
if (codes[i] === hi + 1) {
|
|
2164
|
+
hi = codes[i];
|
|
2165
|
+
} else {
|
|
2166
|
+
ranges.push({ lo, hi });
|
|
2167
|
+
lo = hi = codes[i];
|
|
2168
|
+
}
|
|
2022
2169
|
}
|
|
2023
|
-
|
|
2024
|
-
return
|
|
2170
|
+
ranges.push({ lo, hi });
|
|
2171
|
+
return { kind: "ranges", ranges };
|
|
2025
2172
|
}
|
|
2026
|
-
function
|
|
2027
|
-
|
|
2173
|
+
function inFirstSet(code, fs2) {
|
|
2174
|
+
if (fs2.kind === "any") return true;
|
|
2175
|
+
if (fs2.kind === "empty") return false;
|
|
2176
|
+
for (const r of fs2.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
2177
|
+
return false;
|
|
2028
2178
|
}
|
|
2029
|
-
function
|
|
2030
|
-
if (
|
|
2031
|
-
|
|
2032
|
-
|
|
2179
|
+
function areDisjoint(sets) {
|
|
2180
|
+
if (sets.some((s) => s.kind === "any")) return false;
|
|
2181
|
+
for (let i = 0; i < sets.length; i++)
|
|
2182
|
+
for (let j = i + 1; j < sets.length; j++)
|
|
2183
|
+
if (intersects(sets[i], sets[j])) return false;
|
|
2184
|
+
return true;
|
|
2033
2185
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
isTrivia: false
|
|
2043
|
-
};
|
|
2044
|
-
const def = { tag: "sequence", parsers };
|
|
2045
|
-
let followSentinels;
|
|
2046
|
-
function parseTolerant(input, pos, ctx) {
|
|
2047
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
2048
|
-
const fs2 = parsers.slice(i + 1).reduce(
|
|
2049
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
2050
|
-
{ kind: "empty" }
|
|
2051
|
-
);
|
|
2052
|
-
return firstSetSentinel(fs2);
|
|
2053
|
-
});
|
|
2054
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2055
|
-
let cur = pos;
|
|
2056
|
-
const inheritedSync = ctx._sync;
|
|
2057
|
-
try {
|
|
2058
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
2059
|
-
ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
2060
|
-
if (ctx.trivia && i > 0) {
|
|
2061
|
-
const mark = saveTriviaMark(ctx);
|
|
2062
|
-
let scanEnd;
|
|
2063
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2064
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
2065
|
-
scan.commit();
|
|
2066
|
-
scanEnd = scan.end;
|
|
2067
|
-
} else {
|
|
2068
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2069
|
-
}
|
|
2070
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2071
|
-
if (!result2.ok) return result2;
|
|
2072
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2073
|
-
else rollbackTrivia(ctx, mark);
|
|
2074
|
-
if (values !== void 0) values.push(result2.value);
|
|
2075
|
-
continue;
|
|
2076
|
-
}
|
|
2077
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2078
|
-
if (!result.ok) return result;
|
|
2079
|
-
if (values !== void 0) values.push(result.value);
|
|
2080
|
-
cur = result.span.end;
|
|
2186
|
+
function buildAsciiDispatch(parsers) {
|
|
2187
|
+
const table = Array(128).fill(-1);
|
|
2188
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2189
|
+
const fs2 = parsers[i]._meta.firstSet;
|
|
2190
|
+
if (fs2.kind !== "ranges") continue;
|
|
2191
|
+
for (const { lo, hi } of fs2.ranges) {
|
|
2192
|
+
for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
|
|
2193
|
+
table[code] = i;
|
|
2081
2194
|
}
|
|
2082
|
-
} finally {
|
|
2083
|
-
ctx._sync = inheritedSync;
|
|
2084
2195
|
}
|
|
2085
|
-
return {
|
|
2086
|
-
ok: true,
|
|
2087
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2088
|
-
value: values ?? void 0,
|
|
2089
|
-
span: { start: pos, end: cur }
|
|
2090
|
-
};
|
|
2091
2196
|
}
|
|
2092
|
-
return
|
|
2093
|
-
_tag: "sequence",
|
|
2094
|
-
_meta: meta,
|
|
2095
|
-
_def: def,
|
|
2096
|
-
parse(input, pos, ctx) {
|
|
2097
|
-
if (ctx._tolerant) return parseTolerant(input, pos, ctx);
|
|
2098
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2099
|
-
let cur = pos;
|
|
2100
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
2101
|
-
if (ctx.trivia && i > 0) {
|
|
2102
|
-
let scanEnd;
|
|
2103
|
-
let mark = saveTriviaMark(ctx);
|
|
2104
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2105
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
2106
|
-
scan.commit();
|
|
2107
|
-
scanEnd = scan.end;
|
|
2108
|
-
} else {
|
|
2109
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2110
|
-
}
|
|
2111
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2112
|
-
if (!result2.ok) return result2;
|
|
2113
|
-
if (result2.span.end > scanEnd) {
|
|
2114
|
-
cur = result2.span.end;
|
|
2115
|
-
} else {
|
|
2116
|
-
rollbackTrivia(ctx, mark);
|
|
2117
|
-
}
|
|
2118
|
-
if (values !== void 0) values.push(result2.value);
|
|
2119
|
-
continue;
|
|
2120
|
-
}
|
|
2121
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2122
|
-
if (!result.ok) return result;
|
|
2123
|
-
if (values !== void 0) values.push(result.value);
|
|
2124
|
-
cur = result.span.end;
|
|
2125
|
-
}
|
|
2126
|
-
return {
|
|
2127
|
-
ok: true,
|
|
2128
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2129
|
-
value: values ?? void 0,
|
|
2130
|
-
span: { start: pos, end: cur }
|
|
2131
|
-
};
|
|
2132
|
-
}
|
|
2133
|
-
};
|
|
2197
|
+
return table;
|
|
2134
2198
|
}
|
|
2135
2199
|
|
|
2136
2200
|
// src/combinators/dispatch.ts
|
|
@@ -2390,10 +2454,12 @@ function attempt(parser2) {
|
|
|
2390
2454
|
}
|
|
2391
2455
|
const mark = saveCstMark(ctx);
|
|
2392
2456
|
const log = ctx._triviaLog?.length;
|
|
2457
|
+
const rootLog = ctx._rootTriviaLog?.length;
|
|
2393
2458
|
const result = parser2.parse(input, pos, ctx);
|
|
2394
2459
|
if (result.ok) return result;
|
|
2395
2460
|
rollbackCstCapture(ctx, mark);
|
|
2396
2461
|
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
2462
|
+
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
2397
2463
|
if (result.committed) return result;
|
|
2398
2464
|
return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
|
|
2399
2465
|
}
|
|
@@ -2797,18 +2863,37 @@ function createParseLineContext(input, pos) {
|
|
|
2797
2863
|
}
|
|
2798
2864
|
function parser(opts, root) {
|
|
2799
2865
|
const clearTrivia = opts.trivia === null;
|
|
2866
|
+
const opaqueRootCapture = opts.rootCapture === "opaque";
|
|
2867
|
+
if (opaqueRootCapture && opts.trivia === void 0) {
|
|
2868
|
+
throw new TypeError("parser({ rootCapture: 'opaque' }) requires an explicit trivia scope.");
|
|
2869
|
+
}
|
|
2800
2870
|
return {
|
|
2801
2871
|
_tag: "grammar",
|
|
2802
|
-
_meta:
|
|
2872
|
+
_meta: {
|
|
2873
|
+
...root._meta,
|
|
2874
|
+
// Trivia classification describes this grammar's own active trivia
|
|
2875
|
+
// scope. A directly nested grammar may have classified trivia of its
|
|
2876
|
+
// own, but that must not advertise classification for this wrapper.
|
|
2877
|
+
triviaKindLabels: void 0,
|
|
2878
|
+
rootTriviaClassified: void 0,
|
|
2879
|
+
...opts.trivia?._meta?.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {},
|
|
2880
|
+
...opts.trivia?._meta?.rootTriviaClassified ? { rootTriviaClassified: true } : {}
|
|
2881
|
+
},
|
|
2803
2882
|
_def: {
|
|
2804
2883
|
tag: "grammar",
|
|
2805
2884
|
parser: root,
|
|
2806
2885
|
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2807
2886
|
clearTrivia,
|
|
2887
|
+
...opaqueRootCapture ? { rootCapture: "opaque" } : {},
|
|
2808
2888
|
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2809
2889
|
trackLines: opts.trackLines ?? false
|
|
2810
2890
|
},
|
|
2811
2891
|
parse(input, pos, _ctx) {
|
|
2892
|
+
if (_ctx?._rootTriviaStrictScopes && opts.trivia !== void 0 && opts.trivia !== null && !opts.trivia._meta.rootTriviaClassified && !opaqueRootCapture) {
|
|
2893
|
+
throw new TypeError(
|
|
2894
|
+
"parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'."
|
|
2895
|
+
);
|
|
2896
|
+
}
|
|
2812
2897
|
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2813
2898
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2814
2899
|
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
@@ -2831,7 +2916,11 @@ function parser(opts, root) {
|
|
|
2831
2916
|
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2832
2917
|
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2833
2918
|
// (capture all).
|
|
2834
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
2919
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {},
|
|
2920
|
+
// This is a property of the local trivia scope, not a post-parse filter:
|
|
2921
|
+
// nested recognition can still skip its trivia, but selected root rows
|
|
2922
|
+
// must never be written for an explicitly opaque region.
|
|
2923
|
+
...opaqueRootCapture ? { _rootTriviaCapture: false } : {}
|
|
2835
2924
|
};
|
|
2836
2925
|
const result = root.parse(input, pos ?? 0, ctx);
|
|
2837
2926
|
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
@@ -3484,6 +3573,25 @@ function trivia(combinator) {
|
|
|
3484
3573
|
parse: combinator.parse.bind(combinator)
|
|
3485
3574
|
};
|
|
3486
3575
|
}
|
|
3576
|
+
function classifiedTrivia(arms) {
|
|
3577
|
+
const entries = Object.entries(arms);
|
|
3578
|
+
if (entries.length === 0) {
|
|
3579
|
+
throw new TypeError("classifiedTrivia() requires at least one named trivia arm.");
|
|
3580
|
+
}
|
|
3581
|
+
for (let i = 0; i < entries.length; i++) {
|
|
3582
|
+
const [name, arm] = entries[i];
|
|
3583
|
+
const first = arm._meta.firstSet;
|
|
3584
|
+
if (matchesEmpty(arm) || first.kind !== "ranges" || first.ranges.length === 0) {
|
|
3585
|
+
throw new TypeError(
|
|
3586
|
+
`classifiedTrivia(): ${JSON.stringify(name)} must be non-nullable with a concrete finite first set.`
|
|
3587
|
+
);
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
const labeledArms = entries.map(([name, arm]) => label(name, arm));
|
|
3591
|
+
const result = trivia(oneOrMore(choice(...labeledArms)));
|
|
3592
|
+
result._meta.rootTriviaClassified = true;
|
|
3593
|
+
return result;
|
|
3594
|
+
}
|
|
3487
3595
|
function label(name, combinator) {
|
|
3488
3596
|
return {
|
|
3489
3597
|
_tag: combinator._tag,
|
|
@@ -3530,6 +3638,7 @@ function token(root) {
|
|
|
3530
3638
|
const savedRaw = ctx._cstRawChildren;
|
|
3531
3639
|
const savedTriviaLog = ctx._cstTriviaLog;
|
|
3532
3640
|
const savedOuterTriviaLog = ctx._triviaLog;
|
|
3641
|
+
const savedRootTriviaLog = ctx._rootTriviaLog;
|
|
3533
3642
|
const wasCapturing = cstCaptureActive(ctx);
|
|
3534
3643
|
ctx.trivia = void 0;
|
|
3535
3644
|
ctx.triviaKindLabels = void 0;
|
|
@@ -3539,6 +3648,7 @@ function token(root) {
|
|
|
3539
3648
|
ctx._cstRawChildren = void 0;
|
|
3540
3649
|
ctx._cstTriviaLog = void 0;
|
|
3541
3650
|
delete ctx._triviaLog;
|
|
3651
|
+
delete ctx._rootTriviaLog;
|
|
3542
3652
|
let result;
|
|
3543
3653
|
try {
|
|
3544
3654
|
result = root.parse(input, pos, ctx);
|
|
@@ -3552,6 +3662,8 @@ function token(root) {
|
|
|
3552
3662
|
ctx._cstTriviaLog = savedTriviaLog;
|
|
3553
3663
|
if (savedOuterTriviaLog === void 0) delete ctx._triviaLog;
|
|
3554
3664
|
else ctx._triviaLog = savedOuterTriviaLog;
|
|
3665
|
+
if (savedRootTriviaLog === void 0) delete ctx._rootTriviaLog;
|
|
3666
|
+
else ctx._rootTriviaLog = savedRootTriviaLog;
|
|
3555
3667
|
}
|
|
3556
3668
|
if (!result.ok) return result;
|
|
3557
3669
|
const span = result.span;
|
|
@@ -3606,7 +3718,7 @@ function leaf(root, fn) {
|
|
|
3606
3718
|
}
|
|
3607
3719
|
|
|
3608
3720
|
// src/version.ts
|
|
3609
|
-
var PARSEMAN_VERSION = "0.
|
|
3721
|
+
var PARSEMAN_VERSION = "0.44.0";
|
|
3610
3722
|
|
|
3611
3723
|
// src/cst/host-mode.ts
|
|
3612
3724
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -5504,9 +5616,18 @@ function buildGrammarPlan(entry, winners) {
|
|
|
5504
5616
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
|
|
5505
5617
|
}
|
|
5506
5618
|
|
|
5619
|
+
// src/cst/trivia-entries.ts
|
|
5620
|
+
var EMPTY_INDICES = Object.freeze([]);
|
|
5621
|
+
var EMPTY_GAPS = Object.freeze([]);
|
|
5622
|
+
var SELECTED_ROOT_STRIDE = 5;
|
|
5623
|
+
|
|
5507
5624
|
// src/compiler/scannable-run.ts
|
|
5508
5625
|
var BACKSLASH = 92;
|
|
5509
5626
|
var META = new Set("()[]{}*+?|^$.".split(""));
|
|
5627
|
+
var SELECTED_ROOT_OWNED_RANGE_PLACEHOLDER = Array.from(
|
|
5628
|
+
{ length: SELECTED_ROOT_STRIDE - 3 },
|
|
5629
|
+
() => "0"
|
|
5630
|
+
).join(", ");
|
|
5510
5631
|
function classToRanges(cls) {
|
|
5511
5632
|
if (cls === "\\d") return shorthandRanges("d");
|
|
5512
5633
|
if (cls === "\\w") return shorthandRanges("w");
|
|
@@ -6545,13 +6666,15 @@ function scanBranch(shape, mint) {
|
|
|
6545
6666
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6546
6667
|
return [...m.setup, ` if (${m.end} > _e) { _e = ${m.end}; continue }`].join("\n");
|
|
6547
6668
|
}
|
|
6548
|
-
function scanBranchLabeled(shape, kindIndex, mint) {
|
|
6669
|
+
function scanBranchLabeled(shape, kindIndex, label2, mint) {
|
|
6549
6670
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6550
6671
|
return [
|
|
6551
6672
|
...m.setup,
|
|
6552
6673
|
` if (${m.end} > _e) {`,
|
|
6553
6674
|
` if (_cap) {`,
|
|
6554
6675
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, ${m.end}, ${kindIndex})`,
|
|
6676
|
+
` const _rk = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(label2)}] ?? -1)`,
|
|
6677
|
+
` if (_rk >= 0) _ctx._rootTriviaLog.push(${SELECTED_ROOT_OWNED_RANGE_PLACEHOLDER}, _e, ${m.end}, _rk)`,
|
|
6555
6678
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << kindIndex}))) _ctx._cstTriviaLog.push(_e, ${m.end}, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${kindIndex})`,
|
|
6556
6679
|
` }`,
|
|
6557
6680
|
` _e = ${m.end}`,
|
|
@@ -6611,6 +6734,11 @@ var CAP_RECORD = [
|
|
|
6611
6734
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
|
|
6612
6735
|
` }`
|
|
6613
6736
|
].join("\n");
|
|
6737
|
+
var SELECTED_ROOT_FINISH = [
|
|
6738
|
+
` if (_cap && _ctx._rootTriviaCapture !== false && _ctx._rootTriviaLog !== undefined && _ctx._rootTriviaLog.length !== _rootMark) {`,
|
|
6739
|
+
` for (let _ri = _rootMark; _ri < _ctx._rootTriviaLog.length; _ri += ${SELECTED_ROOT_STRIDE}) { _ctx._rootTriviaLog[_ri] = _pos; _ctx._rootTriviaLog[_ri + 1] = _e }`,
|
|
6740
|
+
` }`
|
|
6741
|
+
].join("\n");
|
|
6614
6742
|
function composeFastLoop(shapes) {
|
|
6615
6743
|
const mint = makeMint();
|
|
6616
6744
|
return [
|
|
@@ -6639,7 +6767,7 @@ function analyzeLabeledScannableRun(trivia2) {
|
|
|
6639
6767
|
const d = getCoreRegexDef(arm.parser);
|
|
6640
6768
|
const shape = d ? scanShapeFromRegex(d.source, d.flags) : null;
|
|
6641
6769
|
if (!shape) return null;
|
|
6642
|
-
out.push({ shape, kindIndex: arm.kindIndex });
|
|
6770
|
+
out.push({ shape, kindIndex: arm.kindIndex, label: arm.label });
|
|
6643
6771
|
}
|
|
6644
6772
|
return out;
|
|
6645
6773
|
}
|
|
@@ -6648,11 +6776,13 @@ function buildLabeledScannableTriviaFnDecl(fnName, arms) {
|
|
|
6648
6776
|
return [
|
|
6649
6777
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6650
6778
|
` let _e = _pos`,
|
|
6779
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6651
6780
|
` while (_e < input.length) {`,
|
|
6652
6781
|
` const c = input.charCodeAt(_e)`,
|
|
6653
|
-
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, mint)),
|
|
6782
|
+
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, a.label, mint)),
|
|
6654
6783
|
` break`,
|
|
6655
6784
|
` }`,
|
|
6785
|
+
SELECTED_ROOT_FINISH,
|
|
6656
6786
|
` return _e`,
|
|
6657
6787
|
`}`
|
|
6658
6788
|
].join("\n");
|
|
@@ -6668,6 +6798,8 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6668
6798
|
` const _ce = _e + _m${i}[0].length`,
|
|
6669
6799
|
` if (_cap) {`,
|
|
6670
6800
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
|
|
6801
|
+
` const _rk${i} = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(arm.label)}] ?? -1)`,
|
|
6802
|
+
` if (_rk${i} >= 0) _ctx._rootTriviaLog.push(0, 0, _e, _ce, _rk${i})`,
|
|
6671
6803
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
|
|
6672
6804
|
` }`,
|
|
6673
6805
|
` _e = _ce`,
|
|
@@ -6679,11 +6811,13 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6679
6811
|
return [
|
|
6680
6812
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6681
6813
|
` let _e = _pos`,
|
|
6814
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6682
6815
|
` while (_e < input.length) {`,
|
|
6683
6816
|
` let _matched = false`,
|
|
6684
6817
|
tryArms,
|
|
6685
6818
|
` if (!_matched) break`,
|
|
6686
6819
|
` }`,
|
|
6820
|
+
SELECTED_ROOT_FINISH,
|
|
6687
6821
|
` return _e`,
|
|
6688
6822
|
`}`
|
|
6689
6823
|
].join("\n");
|
|
@@ -6706,6 +6840,8 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6706
6840
|
` const _ce = _r${i}.span.end`,
|
|
6707
6841
|
` if (_cap) {`,
|
|
6708
6842
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
|
|
6843
|
+
` const _rk${i} = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(arm.label)}] ?? -1)`,
|
|
6844
|
+
` if (_rk${i} >= 0) _ctx._rootTriviaLog.push(0, 0, _e, _ce, _rk${i})`,
|
|
6709
6845
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
|
|
6710
6846
|
` }`,
|
|
6711
6847
|
` _e = _ce`,
|
|
@@ -6717,11 +6853,13 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6717
6853
|
return [
|
|
6718
6854
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6719
6855
|
` let _e = _pos`,
|
|
6856
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6720
6857
|
` while (_e < input.length) {`,
|
|
6721
6858
|
` let _matched = false`,
|
|
6722
6859
|
tryArms,
|
|
6723
6860
|
` if (!_matched) break`,
|
|
6724
6861
|
` }`,
|
|
6862
|
+
SELECTED_ROOT_FINISH,
|
|
6725
6863
|
` return _e`,
|
|
6726
6864
|
`}`
|
|
6727
6865
|
].join("\n");
|
|
@@ -6952,6 +7090,9 @@ function endLoweringCapture() {
|
|
|
6952
7090
|
_loweringSink = null;
|
|
6953
7091
|
return misses;
|
|
6954
7092
|
}
|
|
7093
|
+
function hasSelectedRootTrivia(ctx) {
|
|
7094
|
+
return ctx.rootTriviaClassified === true;
|
|
7095
|
+
}
|
|
6955
7096
|
function v(ctx, prefix = "_v") {
|
|
6956
7097
|
return `${prefix}${ctx.vars++}`;
|
|
6957
7098
|
}
|
|
@@ -7261,10 +7402,12 @@ function planDisjointDispatch(parsers) {
|
|
|
7261
7402
|
}
|
|
7262
7403
|
return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
7263
7404
|
}
|
|
7264
|
-
function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
|
|
7405
|
+
function captureRestoreBody(ctx, mL, mR, mTl, mLg, mF = null, mRootLg = null) {
|
|
7265
7406
|
const fieldRestore = mF ? `; if (_ctx._fields && _ctx._fields.length !== ${mF}) _ctx._fields.length = ${mF}` : "";
|
|
7266
7407
|
const base = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${mL}) _ctx._cstLeaves.length = ${mL}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${mR}) _ctx._cstRawChildren.length = ${mR}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${mTl}) _ctx._cstTriviaLog.length = ${mTl}${fieldRestore}`;
|
|
7267
|
-
|
|
7408
|
+
const logRestore = mLg ? `; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${mLg}) _ctx._triviaLog.length = ${mLg}` : "";
|
|
7409
|
+
const rootLogRestore = hasSelectedRootTrivia(ctx) && mRootLg ? `; if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${mRootLg}) _ctx._rootTriviaLog.length = ${mRootLg}` : "";
|
|
7410
|
+
return `${base}${logRestore}${rootLogRestore}`;
|
|
7268
7411
|
}
|
|
7269
7412
|
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
7270
7413
|
if (seen.has(p)) return false;
|
|
@@ -7474,7 +7617,7 @@ function emitFallible(inner, ctx, pos, swallow = false) {
|
|
|
7474
7617
|
`${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
|
|
7475
7618
|
`${ind0}}`,
|
|
7476
7619
|
...mL ? [
|
|
7477
|
-
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
|
|
7620
|
+
`${ind0}if (!${okV}) { ${captureRestoreBody(ctx, mL, mR, mTl, null, mF)} }`
|
|
7478
7621
|
] : []
|
|
7479
7622
|
];
|
|
7480
7623
|
return { stmts, okVar: okV, valVar: valV, endVar: endV, mayCommit };
|
|
@@ -7671,11 +7814,13 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7671
7814
|
const markV = v(ctx, "_mk");
|
|
7672
7815
|
const markTl = v(ctx, "_mktl");
|
|
7673
7816
|
const markLog = v(ctx, "_mklg");
|
|
7817
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7674
7818
|
const scanEndV = v(ctx, "_sne");
|
|
7675
7819
|
stmts.push(
|
|
7676
7820
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7677
7821
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7678
7822
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7823
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7679
7824
|
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7680
7825
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7681
7826
|
);
|
|
@@ -7684,17 +7829,19 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7684
7829
|
const endAfterV = v(ctx, "_sea");
|
|
7685
7830
|
stmts.push(
|
|
7686
7831
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7687
|
-
`${ind(ctx)}if (${endAfterV} > ${scanEndV}) { ${curV} = ${endAfterV} } else { if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}
|
|
7832
|
+
`${ind(ctx)}if (${endAfterV} > ${scanEndV}) { ${curV} = ${endAfterV} } else { if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog};${markRootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog};` : ""} }`
|
|
7688
7833
|
);
|
|
7689
7834
|
valueVars.push(r2.valueVar);
|
|
7690
7835
|
continue;
|
|
7691
7836
|
} else {
|
|
7692
7837
|
const trivFn = ensureTriviaFn(ctx);
|
|
7693
7838
|
const markLog = v(ctx, "_mklg");
|
|
7839
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7694
7840
|
const scanEndV = v(ctx, "_sne");
|
|
7695
|
-
const capArg = ctx.noHoist ? "0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7841
|
+
const capArg = ctx.noHoist ? "0" : hasSelectedRootTrivia(ctx) ? "(_ctx._triviaLog !== undefined || _ctx._rootTriviaLog !== undefined) ? 2 : 0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7696
7842
|
stmts.push(
|
|
7697
7843
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7844
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7698
7845
|
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7699
7846
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7700
7847
|
);
|
|
@@ -7703,7 +7850,7 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7703
7850
|
const endAfterV = v(ctx, "_sea");
|
|
7704
7851
|
stmts.push(
|
|
7705
7852
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7706
|
-
`${ind(ctx)}if (${endAfterV} > ${scanEndV}) ${curV} = ${endAfterV}; else if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}`
|
|
7853
|
+
`${ind(ctx)}if (${endAfterV} > ${scanEndV}) ${curV} = ${endAfterV}; else { if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog};${markRootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog};` : ""} }`
|
|
7707
7854
|
);
|
|
7708
7855
|
valueVars.push(r2.valueVar);
|
|
7709
7856
|
continue;
|
|
@@ -7945,6 +8092,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7945
8092
|
const selectorRawMark = selectorNeedsRollback ? v(ctx, "_dsr") : null;
|
|
7946
8093
|
const selectorTriviaMark = selectorNeedsRollback ? v(ctx, "_dst") : null;
|
|
7947
8094
|
const selectorLogMark = selectorNeedsRollback ? v(ctx, "_dsg") : null;
|
|
8095
|
+
const selectorRootLogMark = selectorNeedsRollback && hasSelectedRootTrivia(ctx) ? v(ctx, "_dsrg") : null;
|
|
7948
8096
|
const selectorFieldMark = selectorNeedsRollback ? v(ctx, "_dsf") : null;
|
|
7949
8097
|
const selectorErrorMark = selectorNeedsRollback ? v(ctx, "_dse") : null;
|
|
7950
8098
|
const selector = emit(def.selector, ctx, pos);
|
|
@@ -7957,6 +8105,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7957
8105
|
`${ind(ctx)}const ${selectorRawMark} = _ctx._cstRawChildren?.length ?? 0`,
|
|
7958
8106
|
`${ind(ctx)}const ${selectorTriviaMark} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
7959
8107
|
`${ind(ctx)}const ${selectorLogMark} = _ctx._triviaLog?.length ?? 0`,
|
|
8108
|
+
...selectorRootLogMark ? [`${ind(ctx)}const ${selectorRootLogMark} = _ctx._rootTriviaLog?.length ?? 0`] : [],
|
|
7960
8109
|
`${ind(ctx)}const ${selectorFieldMark} = _ctx._fields?.length ?? 0`,
|
|
7961
8110
|
`${ind(ctx)}const ${selectorErrorMark} = _ctx._errors?.length ?? 0`
|
|
7962
8111
|
] : [],
|
|
@@ -7976,16 +8125,18 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7976
8125
|
const mayError = mayRecordRecoveryError(parser3, !!ctx.recovery);
|
|
7977
8126
|
const errMark = mayError ? v(ctx, "_derr") : null;
|
|
7978
8127
|
const logMark = ctx.activeTrivia ? v(ctx, "_dlog") : null;
|
|
8128
|
+
const rootLogMark = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_drlog") : null;
|
|
7979
8129
|
if (usesRouted) {
|
|
7980
8130
|
stmts.push(
|
|
7981
8131
|
...routedV ? [`${ind(ctx)}const ${routedV} = _ctx._routed; _ctx._routed = { value: ${selector.valueVar}, span: { start: ${pos}, end: ${selector.endVar} } }`] : [],
|
|
7982
8132
|
...selectorLeafMark ? [
|
|
7983
|
-
`${ind(ctx)}if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${selectorLeafMark}) _ctx._cstLeaves.length = ${selectorLeafMark}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${selectorRawMark}) _ctx._cstRawChildren.length = ${selectorRawMark}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${selectorTriviaMark}) _ctx._cstTriviaLog.length = ${selectorTriviaMark}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${selectorLogMark}) _ctx._triviaLog.length = ${selectorLogMark}
|
|
8133
|
+
`${ind(ctx)}if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${selectorLeafMark}) _ctx._cstLeaves.length = ${selectorLeafMark}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${selectorRawMark}) _ctx._cstRawChildren.length = ${selectorRawMark}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${selectorTriviaMark}) _ctx._cstTriviaLog.length = ${selectorTriviaMark}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${selectorLogMark}) _ctx._triviaLog.length = ${selectorLogMark};${selectorRootLogMark ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${selectorRootLogMark}) _ctx._rootTriviaLog.length = ${selectorRootLogMark};` : ""} if (_ctx._fields && _ctx._fields.length !== ${selectorFieldMark}) _ctx._fields.length = ${selectorFieldMark}; if (_ctx._errors && _ctx._errors.length !== ${selectorErrorMark}) _ctx._errors.length = ${selectorErrorMark}`
|
|
7984
8134
|
] : []
|
|
7985
8135
|
);
|
|
7986
8136
|
}
|
|
7987
8137
|
if (errMark) stmts.push(`${ind(ctx)}const ${errMark} = _ctx._errors?.length ?? 0`);
|
|
7988
8138
|
if (logMark) stmts.push(`${ind(ctx)}const ${logMark} = _ctx._triviaLog?.length ?? 0`);
|
|
8139
|
+
if (rootLogMark) stmts.push(`${ind(ctx)}const ${rootLogMark} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
7989
8140
|
const savedRoutedLocal = ctx.routedLocal;
|
|
7990
8141
|
const savedNoHoist = ctx.noHoist;
|
|
7991
8142
|
if (usesRouted && !needsRoutedContext) {
|
|
@@ -8000,11 +8151,12 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
8000
8151
|
stmts.push(...coverageAttempt(ctx, coverageId, pos));
|
|
8001
8152
|
const errorRollback = errMark ? `if (_ctx._errors && _ctx._errors.length !== ${errMark}) _ctx._errors.length = ${errMark}; ` : "";
|
|
8002
8153
|
const logRollback = logMark ? `if (_ctx._triviaLog && _ctx._triviaLog.length !== ${logMark}) _ctx._triviaLog.length = ${logMark}; ` : "";
|
|
8154
|
+
const rootLogRollback = rootLogMark ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${rootLogMark}) _ctx._rootTriviaLog.length = ${rootLogMark}; ` : "";
|
|
8003
8155
|
const routedRollback = routedV ? `_ctx._routed = ${routedV}; ` : "";
|
|
8004
8156
|
const coverageFailure = coverageId === void 0 ? "" : `_ctx._grammarTrace?.write({ id: ${JSON.stringify(coverageId)}, phase: 'failure', offset: _ctx._fe }); `;
|
|
8005
8157
|
stmts.push(
|
|
8006
8158
|
...tail.stmts,
|
|
8007
|
-
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8159
|
+
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${rootLogRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8008
8160
|
...routedV ? [`${ind(ctx)}_ctx._routed = ${routedV}`] : [],
|
|
8009
8161
|
`${ind(ctx)}${outV} = ${valueMode === "tail" ? tail.valVar : `[${selector.valueVar}, ${tail.valVar}]`}`,
|
|
8010
8162
|
`${ind(ctx)}${outE} = ${tail.endVar}`,
|
|
@@ -8185,11 +8337,13 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8185
8337
|
const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
|
|
8186
8338
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
8187
8339
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
8340
|
+
const markRootLog = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_cmlrg") : null;
|
|
8188
8341
|
const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
|
|
8189
8342
|
const markErrors = armMayRecordError ? v(ctx, "_cme") : null;
|
|
8190
|
-
const captureRollback = markLeaves ? captureRestoreBody(markLeaves, markRaw, markTl, markLog, markFields) : "";
|
|
8343
|
+
const captureRollback = markLeaves ? captureRestoreBody(ctx, markLeaves, markRaw, markTl, markLog, markFields, markRootLog) : "";
|
|
8344
|
+
const rootRollback = markRootLog && !markLeaves ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}` : "";
|
|
8191
8345
|
const errorRollback = markErrors ? `if (_ctx._errors && _ctx._errors.length !== ${markErrors}) _ctx._errors.length = ${markErrors}` : "";
|
|
8192
|
-
const rollback = [captureRollback, errorRollback].filter(Boolean).join("; ");
|
|
8346
|
+
const rollback = [captureRollback, rootRollback, errorRollback].filter(Boolean).join("; ");
|
|
8193
8347
|
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
8194
8348
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
8195
8349
|
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
@@ -8204,6 +8358,7 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8204
8358
|
...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
|
|
8205
8359
|
);
|
|
8206
8360
|
}
|
|
8361
|
+
if (markRootLog) stmts.push(`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
8207
8362
|
if (markErrors) stmts.push(`${ind(ctx)}const ${markErrors} = _ctx._errors?.length ?? 0`);
|
|
8208
8363
|
const arm = emitFallible(p, ctx, pos, atStart);
|
|
8209
8364
|
const { stmts: armStmts, okVar, valVar, endVar } = arm;
|
|
@@ -8391,21 +8546,29 @@ function emitMany(def, ctx, pos) {
|
|
|
8391
8546
|
const markV = v(ctx, "_mk");
|
|
8392
8547
|
const markTl = v(ctx, "_mktl");
|
|
8393
8548
|
const markLog = v(ctx, "_mklg");
|
|
8549
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8394
8550
|
const npV = v(ctx, "_np");
|
|
8395
8551
|
stmts.push(
|
|
8396
8552
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8397
8553
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8398
8554
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8555
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8399
8556
|
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8400
8557
|
...emitLineTrack(ctx, curV, npV)
|
|
8401
8558
|
);
|
|
8402
8559
|
itemPos = npV;
|
|
8403
|
-
rollback = `if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}
|
|
8560
|
+
rollback = `if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog};${markRootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog};` : ""} `;
|
|
8404
8561
|
} else {
|
|
8405
8562
|
const trivFn = ensureTriviaFn(ctx);
|
|
8563
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8406
8564
|
const npV = v(ctx, "_np");
|
|
8407
|
-
stmts.push(
|
|
8565
|
+
stmts.push(
|
|
8566
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8567
|
+
`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8568
|
+
...emitLineTrack(ctx, curV, npV)
|
|
8569
|
+
);
|
|
8408
8570
|
itemPos = npV;
|
|
8571
|
+
rollback = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8409
8572
|
}
|
|
8410
8573
|
}
|
|
8411
8574
|
if (!ctx.recovery && !ctx.coverage && !failsAtStart(def.parser) && needsFirstSetGuard(def.parser)) {
|
|
@@ -8465,9 +8628,10 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8465
8628
|
const raw = v(ctx, "_atr");
|
|
8466
8629
|
const trivia2 = v(ctx, "_att");
|
|
8467
8630
|
const log = v(ctx, "_atg");
|
|
8631
|
+
const rootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_atrg") : null;
|
|
8468
8632
|
const fields = v(ctx, "_atf");
|
|
8469
8633
|
const errors = v(ctx, "_ate");
|
|
8470
|
-
const rollback = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${leaves}) _ctx._cstLeaves.length = ${leaves}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${raw}) _ctx._cstRawChildren.length = ${raw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${trivia2}) _ctx._cstTriviaLog.length = ${trivia2}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${log}) _ctx._triviaLog.length = ${log}
|
|
8634
|
+
const rollback = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${leaves}) _ctx._cstLeaves.length = ${leaves}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${raw}) _ctx._cstRawChildren.length = ${raw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${trivia2}) _ctx._cstTriviaLog.length = ${trivia2}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${log}) _ctx._triviaLog.length = ${log};${rootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${rootLog}) _ctx._rootTriviaLog.length = ${rootLog};` : ""} if (_ctx._fields && _ctx._fields.length !== ${fields}) _ctx._fields.length = ${fields}; if (_ctx._errors && _ctx._errors.length !== ${errors}) _ctx._errors.length = ${errors}`;
|
|
8471
8635
|
const traceId = ctx.coverage?.plan.attempts.get(p);
|
|
8472
8636
|
const traceRollback = traceId === void 0 ? "" : ` _ctx._grammarTrace?.write({ id: ${JSON.stringify(traceId)}, phase: 'rollback', offset: ${pos} });`;
|
|
8473
8637
|
const preGuard = [];
|
|
@@ -8483,7 +8647,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8483
8647
|
return {
|
|
8484
8648
|
stmts: [
|
|
8485
8649
|
...preGuard,
|
|
8486
|
-
`${ind(ctx)}const ${leaves} = _ctx._cstLeaves?.length ?? 0, ${raw} = _ctx._cstRawChildren?.length ?? 0, ${trivia2} = _ctx._cstTriviaLog?.length ?? 0, ${log} = _ctx._triviaLog?.length ?? 0, ${fields} = _ctx._fields?.length ?? 0, ${errors} = _ctx._errors?.length ?? 0`,
|
|
8650
|
+
`${ind(ctx)}const ${leaves} = _ctx._cstLeaves?.length ?? 0, ${raw} = _ctx._cstRawChildren?.length ?? 0, ${trivia2} = _ctx._cstTriviaLog?.length ?? 0, ${log} = _ctx._triviaLog?.length ?? 0${rootLog ? `, ${rootLog} = _ctx._rootTriviaLog?.length ?? 0` : ""}, ${fields} = _ctx._fields?.length ?? 0, ${errors} = _ctx._errors?.length ?? 0`,
|
|
8487
8651
|
...inner.stmts,
|
|
8488
8652
|
...emitIfFail(ctx, `!${inner.okVar}`, `{ ${rollback};${traceRollback}${inner.mayCommit ? ` if (_ctx._fc) ${committedFailBody(ctx)};` : ""} _ctx._fe = ${pos}; ${propagateFailBody(ctx)} }`)
|
|
8489
8653
|
],
|
|
@@ -8525,16 +8689,17 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8525
8689
|
const itemFailBreak = (sepEndVar, sepRb, postSepRb) => def.trailing === void 0 ? `${sepRb}break` : `${postSepRb}${curV} = ${sepEndVar}; break`;
|
|
8526
8690
|
const postSepMarks = () => {
|
|
8527
8691
|
if (def.trailing === void 0 || !ctx.capturing) return { decl: [], rb: "" };
|
|
8528
|
-
const lv = v(ctx, "_tlv"), rw = v(ctx, "_trw"), tl = v(ctx, "_ttl"), lg = v(ctx, "_tlg"), fl = v(ctx, "_tlf");
|
|
8692
|
+
const lv = v(ctx, "_tlv"), rw = v(ctx, "_trw"), tl = v(ctx, "_ttl"), lg = v(ctx, "_tlg"), rlg = hasSelectedRootTrivia(ctx) ? v(ctx, "_trlg") : null, fl = v(ctx, "_tlf");
|
|
8529
8693
|
return {
|
|
8530
8694
|
decl: [
|
|
8531
8695
|
`${ind(ctx)}const ${lv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8532
8696
|
`${ind(ctx)}const ${rw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8533
8697
|
`${ind(ctx)}const ${tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8534
8698
|
`${ind(ctx)}const ${lg} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8699
|
+
...rlg ? [`${ind(ctx)}const ${rlg} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8535
8700
|
`${ind(ctx)}const ${fl} = _ctx._fields ? _ctx._fields.length : 0`
|
|
8536
8701
|
],
|
|
8537
|
-
rb: `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${lv}) _ctx._cstLeaves.length = ${lv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${rw}) _ctx._cstRawChildren.length = ${rw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${tl}) _ctx._cstTriviaLog.length = ${tl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${lg}) _ctx._triviaLog.length = ${lg}
|
|
8702
|
+
rb: `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${lv}) _ctx._cstLeaves.length = ${lv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${rw}) _ctx._cstRawChildren.length = ${rw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${tl}) _ctx._cstTriviaLog.length = ${tl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${lg}) _ctx._triviaLog.length = ${lg};${rlg ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${rlg}) _ctx._rootTriviaLog.length = ${rlg};` : ""} if (_ctx._fields && _ctx._fields.length !== ${fl}) _ctx._fields.length = ${fl}; `
|
|
8538
8703
|
};
|
|
8539
8704
|
};
|
|
8540
8705
|
if (rec) {
|
|
@@ -8572,6 +8737,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8572
8737
|
const markV = v(ctx, "_mk");
|
|
8573
8738
|
const markTl = v(ctx, "_mktl");
|
|
8574
8739
|
const markLog = v(ctx, "_mklg");
|
|
8740
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8575
8741
|
const markLv = v(ctx, "_mklv");
|
|
8576
8742
|
const markFld = v(ctx, "_mkf");
|
|
8577
8743
|
const spV = v(ctx, "_sp");
|
|
@@ -8579,13 +8745,14 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8579
8745
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8580
8746
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8581
8747
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8748
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8582
8749
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8583
8750
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8584
8751
|
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8585
8752
|
...emitLineTrack(ctx, curV, spV)
|
|
8586
8753
|
);
|
|
8587
8754
|
sepAtPos = spV;
|
|
8588
|
-
const rollbackToSep = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${markLv}) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}
|
|
8755
|
+
const rollbackToSep = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${markLv}) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog};${markRootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog};` : ""} if (_ctx._fields && _ctx._fields.length !== ${markFld}) _ctx._fields.length = ${markFld}; `;
|
|
8589
8756
|
const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8590
8757
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
|
|
8591
8758
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep2.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
@@ -8603,19 +8770,30 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8603
8770
|
);
|
|
8604
8771
|
} else {
|
|
8605
8772
|
const trivFn = ensureTriviaFn(ctx);
|
|
8773
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8606
8774
|
const spV = v(ctx, "_sp");
|
|
8607
|
-
stmts.push(
|
|
8775
|
+
stmts.push(
|
|
8776
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8777
|
+
`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8778
|
+
...emitLineTrack(ctx, curV, spV)
|
|
8779
|
+
);
|
|
8608
8780
|
sepAtPos = spV;
|
|
8609
8781
|
const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8610
8782
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
|
|
8611
|
-
|
|
8783
|
+
const rollbackToSep = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8784
|
+
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep2.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
8785
|
+
const postRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_psrlg") : null;
|
|
8612
8786
|
const npV = v(ctx, "_np");
|
|
8613
|
-
stmts.push(
|
|
8787
|
+
stmts.push(
|
|
8788
|
+
...postRootLog ? [`${ind(ctx)}const ${postRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8789
|
+
`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8790
|
+
...emitLineTrack(ctx, sepEnd, npV)
|
|
8791
|
+
);
|
|
8614
8792
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8615
8793
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8616
8794
|
stmts.push(
|
|
8617
8795
|
...nextStmts,
|
|
8618
|
-
...failItem(nextOk, next.mayCommit, npV, itemFailBreak(sepEnd,
|
|
8796
|
+
...failItem(nextOk, next.mayCommit, npV, itemFailBreak(sepEnd, rollbackToSep, postRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${postRootLog}) _ctx._rootTriviaLog.length = ${postRootLog}; ` : "")),
|
|
8619
8797
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
8620
8798
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
8621
8799
|
);
|
|
@@ -8710,6 +8888,7 @@ function emitNot(def, ctx, pos) {
|
|
|
8710
8888
|
const raw = sinksLive ? v(ctx, "_ntr") : null;
|
|
8711
8889
|
const tl = sinksLive ? v(ctx, "_ntt") : null;
|
|
8712
8890
|
const log = sinksLive ? v(ctx, "_ntg") : null;
|
|
8891
|
+
const rootLog = sinksLive && hasSelectedRootTrivia(ctx) ? v(ctx, "_ntrg") : null;
|
|
8713
8892
|
const fields = sinksLive ? v(ctx, "_ntf") : null;
|
|
8714
8893
|
const errors = sinksLive ? v(ctx, "_nte") : null;
|
|
8715
8894
|
const { stmts, okVar } = emitFallible(def.parser, ctx, pos, true);
|
|
@@ -8717,11 +8896,11 @@ function emitNot(def, ctx, pos) {
|
|
|
8717
8896
|
return {
|
|
8718
8897
|
stmts: [
|
|
8719
8898
|
...sinksLive ? [
|
|
8720
|
-
`${ind(ctx)}const ${leaves} = _ctx._cstLeaves?.length ?? 0, ${raw} = _ctx._cstRawChildren?.length ?? 0, ${tl} = _ctx._cstTriviaLog?.length ?? 0, ${log} = _ctx._triviaLog?.length ?? 0, ${fields} = _ctx._fields?.length ?? 0, ${errors} = _ctx._errors?.length ?? 0`
|
|
8899
|
+
`${ind(ctx)}const ${leaves} = _ctx._cstLeaves?.length ?? 0, ${raw} = _ctx._cstRawChildren?.length ?? 0, ${tl} = _ctx._cstTriviaLog?.length ?? 0, ${log} = _ctx._triviaLog?.length ?? 0${rootLog ? `, ${rootLog} = _ctx._rootTriviaLog?.length ?? 0` : ""}, ${fields} = _ctx._fields?.length ?? 0, ${errors} = _ctx._errors?.length ?? 0`
|
|
8721
8900
|
] : [],
|
|
8722
8901
|
...stmts,
|
|
8723
8902
|
...sinksLive ? [
|
|
8724
|
-
`${ind(ctx)}if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${leaves}) _ctx._cstLeaves.length = ${leaves}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${raw}) _ctx._cstRawChildren.length = ${raw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${tl}) _ctx._cstTriviaLog.length = ${tl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${log}) _ctx._triviaLog.length = ${log}
|
|
8903
|
+
`${ind(ctx)}if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${leaves}) _ctx._cstLeaves.length = ${leaves}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${raw}) _ctx._cstRawChildren.length = ${raw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${tl}) _ctx._cstTriviaLog.length = ${tl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${log}) _ctx._triviaLog.length = ${log};${rootLog ? ` if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${rootLog}) _ctx._rootTriviaLog.length = ${rootLog};` : ""} if (_ctx._fields && _ctx._fields.length !== ${fields}) _ctx._fields.length = ${fields}; if (_ctx._errors && _ctx._errors.length !== ${errors}) _ctx._errors.length = ${errors}`
|
|
8725
8904
|
] : [],
|
|
8726
8905
|
...emitIfFail(ctx, okVar, failBody(ctx, label2, pos))
|
|
8727
8906
|
],
|
|
@@ -8857,16 +9036,17 @@ function emitToken(def, ctx, pos) {
|
|
|
8857
9036
|
const sk = v(ctx, "_tokKinds");
|
|
8858
9037
|
const stl = v(ctx, "_tokTl");
|
|
8859
9038
|
const sol = v(ctx, "_tokLog");
|
|
9039
|
+
const srl = hasSelectedRootTrivia(ctx) ? v(ctx, "_tokRootLog") : null;
|
|
8860
9040
|
const sb = v(ctx, "_tokBuf");
|
|
8861
9041
|
const valV = v(ctx, "_tok");
|
|
8862
9042
|
return {
|
|
8863
9043
|
stmts: [
|
|
8864
|
-
`${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`,
|
|
8865
|
-
`${i}_ctx.trivia = undefined; _ctx.triviaKindLabels = undefined; _ctx._cstChildren = undefined; _ctx._cstLeaves = undefined; _ctx._cstRawChildren = undefined; _ctx._cstTriviaLog = undefined; _ctx._triviaLog = undefined; _ctx._cstBuf = undefined`,
|
|
9044
|
+
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${sv} = _ctx.trivia, ${sk} = _ctx.triviaKindLabels, ${stl} = _ctx._cstTriviaLog, ${sol} = _ctx._triviaLog${srl ? `, ${srl} = _ctx._rootTriviaLog` : ""}, ${sb} = _ctx._cstBuf`,
|
|
9045
|
+
`${i}_ctx.trivia = undefined; _ctx.triviaKindLabels = undefined; _ctx._cstChildren = undefined; _ctx._cstLeaves = undefined; _ctx._cstRawChildren = undefined; _ctx._cstTriviaLog = undefined; _ctx._triviaLog = undefined;${srl ? " _ctx._rootTriviaLog = undefined;" : ""} _ctx._cstBuf = undefined`,
|
|
8866
9046
|
`${i}try {`,
|
|
8867
9047
|
...reindentStmts(inner.stmts, ctx.indent + 1).map((stmt) => stmt.replace(/^(\s*)(?:const|let)\s+/, "$1var ")),
|
|
8868
9048
|
`${i}} finally {`,
|
|
8869
|
-
`${i} _ctx.trivia = ${sv}; _ctx.triviaKindLabels = ${sk}; _ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx._cstTriviaLog = ${stl}; _ctx._triviaLog = ${sol}
|
|
9049
|
+
`${i} _ctx.trivia = ${sv}; _ctx.triviaKindLabels = ${sk}; _ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx._cstTriviaLog = ${stl}; _ctx._triviaLog = ${sol};${srl ? ` _ctx._rootTriviaLog = ${srl};` : ""} _ctx._cstBuf = ${sb}`,
|
|
8870
9050
|
`${i}}`,
|
|
8871
9051
|
...emitIfFail(ctx, `!${inner.okVar}`, propagateFailBody(ctx)),
|
|
8872
9052
|
`${i}const ${valV} = input.slice(${pos}, ${inner.endVar})`,
|
|
@@ -9345,6 +9525,8 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9345
9525
|
case "grammar": {
|
|
9346
9526
|
const savedTrivia = ctx.activeTrivia;
|
|
9347
9527
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
9528
|
+
const opaqueRootCapture = hasSelectedRootTrivia(ctx) && def.rootCapture === "opaque";
|
|
9529
|
+
const strictScopeCheck = hasSelectedRootTrivia(ctx) && def.triviaParser !== void 0 && !def.triviaParser._meta.rootTriviaClassified && !opaqueRootCapture ? `${ind(ctx)}if (_ctx._rootTriviaStrictScopes) throw new TypeError(${JSON.stringify("parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'.")})` : void 0;
|
|
9348
9530
|
if (def.clearTrivia) {
|
|
9349
9531
|
ctx.activeTrivia = void 0;
|
|
9350
9532
|
ctx.triviaKindLabels = void 0;
|
|
@@ -9355,13 +9537,38 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9355
9537
|
}
|
|
9356
9538
|
}
|
|
9357
9539
|
const savedCapture = def.captureTrivia ? v(ctx, "_gcap") : null;
|
|
9540
|
+
const savedRootCapture = opaqueRootCapture ? v(ctx, "_grtc") : null;
|
|
9541
|
+
const opaqueValue = opaqueRootCapture ? v(ctx, "_grtv") : null;
|
|
9542
|
+
const opaqueEnd = opaqueRootCapture ? v(ctx, "_grte") : null;
|
|
9543
|
+
if (opaqueRootCapture) ctx.indent++;
|
|
9358
9544
|
const r = emit(def.parser, ctx, pos);
|
|
9545
|
+
if (opaqueRootCapture) ctx.indent--;
|
|
9359
9546
|
ctx.activeTrivia = savedTrivia;
|
|
9360
9547
|
ctx.triviaKindLabels = savedKindLabels;
|
|
9361
|
-
if (!savedCapture) return r
|
|
9548
|
+
if (!savedCapture && !opaqueRootCapture) return strictScopeCheck === void 0 ? r : {
|
|
9549
|
+
...r,
|
|
9550
|
+
stmts: [strictScopeCheck, ...r.stmts]
|
|
9551
|
+
};
|
|
9552
|
+
if (opaqueRootCapture) {
|
|
9553
|
+
return {
|
|
9554
|
+
stmts: [
|
|
9555
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9556
|
+
`${ind(ctx)}let ${opaqueValue}, ${opaqueEnd}`,
|
|
9557
|
+
`${ind(ctx)}${savedCapture ? `const ${savedCapture} = _ctx.captureTrivia; ` : ""}const ${savedRootCapture} = _ctx._rootTriviaCapture; _ctx._rootTriviaCapture = false`,
|
|
9558
|
+
`${ind(ctx)}try {`,
|
|
9559
|
+
...savedCapture ? [`${ind(ctx)} _ctx.captureTrivia = true`] : [],
|
|
9560
|
+
...r.stmts,
|
|
9561
|
+
`${ind(ctx)} ${opaqueValue} = ${r.valueVar}; ${opaqueEnd} = ${r.endVar}`,
|
|
9562
|
+
`${ind(ctx)}} finally { ${savedCapture ? `_ctx.captureTrivia = ${savedCapture}; ` : ""}_ctx._rootTriviaCapture = ${savedRootCapture} }`
|
|
9563
|
+
],
|
|
9564
|
+
valueVar: opaqueValue,
|
|
9565
|
+
endVar: opaqueEnd
|
|
9566
|
+
};
|
|
9567
|
+
}
|
|
9362
9568
|
return {
|
|
9363
9569
|
...r,
|
|
9364
9570
|
stmts: [
|
|
9571
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9365
9572
|
`${ind(ctx)}const ${savedCapture} = _ctx.captureTrivia; _ctx.captureTrivia = true`,
|
|
9366
9573
|
...r.stmts,
|
|
9367
9574
|
`${ind(ctx)}_ctx.captureTrivia = ${savedCapture}`
|
|
@@ -9846,6 +10053,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9846
10053
|
runDuplicationDiagnostic(combinator, opts?.duplication);
|
|
9847
10054
|
markUnusedValues(combinator);
|
|
9848
10055
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
10056
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || combinator._meta.rootTriviaClassified === true;
|
|
9849
10057
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9850
10058
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9851
10059
|
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
@@ -9872,7 +10080,11 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9872
10080
|
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9873
10081
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9874
10082
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9875
|
-
...
|
|
10083
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10084
|
+
...grammarTrivia ? {
|
|
10085
|
+
activeTrivia: grammarTrivia,
|
|
10086
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10087
|
+
} : {},
|
|
9876
10088
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
9877
10089
|
};
|
|
9878
10090
|
const r = emit(combinator, ctx, "_pos");
|
|
@@ -10020,10 +10232,11 @@ function assertRuleName(name) {
|
|
|
10020
10232
|
);
|
|
10021
10233
|
}
|
|
10022
10234
|
}
|
|
10023
|
-
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels) {
|
|
10024
|
-
const labels = rule._meta.triviaKindLabels
|
|
10025
|
-
|
|
10026
|
-
|
|
10235
|
+
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels, ambientRootTriviaClassified) {
|
|
10236
|
+
const labels = ambientTriviaKindLabels ?? rule._meta.triviaKindLabels;
|
|
10237
|
+
const classified = ambientRootTriviaClassified ?? rule._meta.rootTriviaClassified;
|
|
10238
|
+
if (labels === void 0 && classified === void 0) return fnSource;
|
|
10239
|
+
return `Object.assign(${fnSource}, { _meta: {${labels === void 0 ? "" : ` triviaKindLabels: ${JSON.stringify(labels)},`}${classified === void 0 ? "" : " rootTriviaClassified: true,"} } })`;
|
|
10027
10240
|
}
|
|
10028
10241
|
function compileRuleMap(ruleMap, opts) {
|
|
10029
10242
|
runGatingDiagnosticRules(ruleMap, opts?.gating);
|
|
@@ -10031,6 +10244,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
10031
10244
|
for (const [, rule] of ruleMap) markUnusedValues(rule);
|
|
10032
10245
|
const coverageWinners = opts?.coverage ? Object.fromEntries(ruleMap.filter(([, rule]) => rule._def.tag !== "lazy")) : void 0;
|
|
10033
10246
|
const grammarTrivia = opts?.trivia;
|
|
10247
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || ruleMap.some(([, rule]) => rule._meta.rootTriviaClassified === true);
|
|
10034
10248
|
const grammarScanSkip = opts?.scanSkip ?? ruleMap.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
10035
10249
|
const grammarHostMode = opts?.hostMode ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10036
10250
|
const grammarTrackLines = opts?.trackLines === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -10057,7 +10271,11 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
10057
10271
|
lineTracking: grammarTrackLines,
|
|
10058
10272
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(ruleMap.map(([, rule]) => rule), coverageWinners) } } : {},
|
|
10059
10273
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10060
|
-
...
|
|
10274
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10275
|
+
...grammarTrivia ? {
|
|
10276
|
+
activeTrivia: grammarTrivia,
|
|
10277
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10278
|
+
} : {},
|
|
10061
10279
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
10062
10280
|
};
|
|
10063
10281
|
const seenNames = /* @__PURE__ */ new Map();
|
|
@@ -10145,7 +10363,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
10145
10363
|
return [`function(input, _pos, _ctx) {`, ...body, `}`].join("\n");
|
|
10146
10364
|
};
|
|
10147
10365
|
const objBody = perEntry.map(({ key, rule, r }) => {
|
|
10148
|
-
const src = publicRuleWrapperSource(rule, entryFnText(r, rule), ctx.triviaKindLabels);
|
|
10366
|
+
const src = publicRuleWrapperSource(rule, entryFnText(r, rule), ctx.triviaKindLabels, ctx.rootTriviaClassified);
|
|
10149
10367
|
return ` ${JSON.stringify(key)}: ${src.split("\n").join("\n ")}`;
|
|
10150
10368
|
}).join(",\n");
|
|
10151
10369
|
const replacement = [
|
|
@@ -10174,6 +10392,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10174
10392
|
if (opts?.duplication !== void 0) runDuplicationDiagnosticRules(ruleMapArg, opts.duplication);
|
|
10175
10393
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
10176
10394
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
10395
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || ruleMapArg.some(([, rule]) => rule._meta.rootTriviaClassified === true);
|
|
10177
10396
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
10178
10397
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10179
10398
|
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -10217,7 +10436,11 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10217
10436
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10218
10437
|
ns,
|
|
10219
10438
|
deferFirstSetRefs: true,
|
|
10220
|
-
...
|
|
10439
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10440
|
+
...grammarTrivia ? {
|
|
10441
|
+
activeTrivia: grammarTrivia,
|
|
10442
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10443
|
+
} : {},
|
|
10221
10444
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
10222
10445
|
};
|
|
10223
10446
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -10349,7 +10572,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10349
10572
|
...r.stmts,
|
|
10350
10573
|
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
10351
10574
|
`}`
|
|
10352
|
-
].join("\n"), ctx.triviaKindLabels));
|
|
10575
|
+
].join("\n"), ctx.triviaKindLabels, ctx.rootTriviaClassified));
|
|
10353
10576
|
}
|
|
10354
10577
|
const firstSets = /* @__PURE__ */ new Map();
|
|
10355
10578
|
const firstSetRecipes = /* @__PURE__ */ new Map();
|
|
@@ -10698,6 +10921,7 @@ function evalRuleMapIR(ir) {
|
|
|
10698
10921
|
"transform",
|
|
10699
10922
|
"skip",
|
|
10700
10923
|
"trivia",
|
|
10924
|
+
"classifiedTrivia",
|
|
10701
10925
|
"label",
|
|
10702
10926
|
"field",
|
|
10703
10927
|
"expect",
|
|
@@ -10738,6 +10962,7 @@ function evalRuleMapIR(ir) {
|
|
|
10738
10962
|
transform,
|
|
10739
10963
|
skip,
|
|
10740
10964
|
trivia,
|
|
10965
|
+
classifiedTrivia,
|
|
10741
10966
|
label,
|
|
10742
10967
|
field,
|
|
10743
10968
|
expect,
|
|
@@ -10984,8 +11209,11 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10984
11209
|
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
10985
11210
|
}
|
|
10986
11211
|
case "grammar": {
|
|
10987
|
-
const
|
|
10988
|
-
|
|
11212
|
+
const classified = def.triviaParser?._meta.rootTriviaClassified === true;
|
|
11213
|
+
const spec = classified && def.triviaParser ? analyzeLabeledTrivia(def.triviaParser) : null;
|
|
11214
|
+
if (classified && !spec) throw new Unserializable("classified trivia without labeled arms");
|
|
11215
|
+
const trivia2 = def.clearTrivia ? "null" : spec ? `classifiedTrivia({ ${spec.arms.map((arm) => `${JSON.stringify(arm.label)}: ${kid(arm.parser)}`).join(", ")} })` : def.triviaParser ? kid(def.triviaParser) : "undefined";
|
|
11216
|
+
return `parser({ trivia: ${trivia2}${def.captureTrivia ? ", captureTrivia: true" : ""}${def.rootCapture ? `, rootCapture: ${JSON.stringify(def.rootCapture)}` : ""}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(def.parser)})`;
|
|
10989
11217
|
}
|
|
10990
11218
|
case "withCtx": {
|
|
10991
11219
|
if (def.extraSrc === void 0) throw new Unserializable("withCtx without extraSrc");
|
|
@@ -11217,10 +11445,6 @@ function gate(predicate) {
|
|
|
11217
11445
|
};
|
|
11218
11446
|
}
|
|
11219
11447
|
|
|
11220
|
-
// src/cst/trivia-entries.ts
|
|
11221
|
-
var EMPTY_INDICES = Object.freeze([]);
|
|
11222
|
-
var EMPTY_GAPS = Object.freeze([]);
|
|
11223
|
-
|
|
11224
11448
|
// src/cst/offset-model.ts
|
|
11225
11449
|
var { isFinite } = Number;
|
|
11226
11450
|
|
|
@@ -11472,6 +11696,9 @@ var SUPPORTED = {
|
|
|
11472
11696
|
optional: (...a) => optional(a[0]),
|
|
11473
11697
|
skip: (...a) => skip(a[0], a[1]),
|
|
11474
11698
|
trivia: (...a) => trivia(a[0]),
|
|
11699
|
+
classifiedTrivia: (...a) => classifiedTrivia(
|
|
11700
|
+
a[0]
|
|
11701
|
+
),
|
|
11475
11702
|
label: (...a) => label(a[0], a[1]),
|
|
11476
11703
|
field: (...a) => field(a[0], a[1]),
|
|
11477
11704
|
noTrivia: (...a) => noTrivia(a[0]),
|
|
@@ -13278,7 +13505,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
13278
13505
|
if (isComposeLeafCall(init)) {
|
|
13279
13506
|
const fused = compileComposeLeafCall(init);
|
|
13280
13507
|
if (!fused) {
|
|
13281
|
-
|
|
13508
|
+
const reasons = warnings.slice(-4);
|
|
13509
|
+
throw new Error(
|
|
13510
|
+
`${id}:${lineOf(init.start)} \u2014 composeLeaf() must macro-fuse; runtime composition is forbidden` + (reasons.length ? `
|
|
13511
|
+
causes:
|
|
13512
|
+
- ${reasons.join("\n - ")}` : "")
|
|
13513
|
+
);
|
|
13282
13514
|
}
|
|
13283
13515
|
replacements.push({ start: init.start, end: init.end, replacement: fused.replacement });
|
|
13284
13516
|
markUsedImportedFactories(fused.importedFactories);
|