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.js
CHANGED
|
@@ -1071,843 +1071,433 @@ function keywords(words, opts = {}) {
|
|
|
1071
1071
|
};
|
|
1072
1072
|
}
|
|
1073
1073
|
|
|
1074
|
-
// src/
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
_cstChildren: ctx._cstChildren,
|
|
1081
|
-
_cstRawChildren: ctx._cstRawChildren,
|
|
1082
|
-
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1083
|
-
_triviaLog: ctx._triviaLog,
|
|
1084
|
-
_fields: ctx._fields,
|
|
1085
|
-
_cstBuf: ctx._cstBuf,
|
|
1086
|
-
_tolerant: ctx._tolerant,
|
|
1087
|
-
_sync: ctx._sync
|
|
1088
|
-
};
|
|
1089
|
-
ctx._probe = void 0;
|
|
1090
|
-
ctx._errors = void 0;
|
|
1091
|
-
ctx._cstLeaves = void 0;
|
|
1092
|
-
ctx._cstChildren = void 0;
|
|
1093
|
-
ctx._cstRawChildren = void 0;
|
|
1094
|
-
ctx._cstTriviaLog = void 0;
|
|
1095
|
-
ctx._triviaLog = void 0;
|
|
1096
|
-
ctx._fields = void 0;
|
|
1097
|
-
ctx._cstBuf = void 0;
|
|
1098
|
-
ctx._tolerant = void 0;
|
|
1099
|
-
ctx._sync = void 0;
|
|
1100
|
-
try {
|
|
1101
|
-
return sentinel.parse(input, pos, ctx).ok;
|
|
1102
|
-
} finally {
|
|
1103
|
-
ctx._probe = s._probe;
|
|
1104
|
-
ctx._errors = s._errors;
|
|
1105
|
-
ctx._cstLeaves = s._cstLeaves;
|
|
1106
|
-
ctx._cstChildren = s._cstChildren;
|
|
1107
|
-
ctx._cstRawChildren = s._cstRawChildren;
|
|
1108
|
-
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1109
|
-
ctx._triviaLog = s._triviaLog;
|
|
1110
|
-
ctx._fields = s._fields;
|
|
1111
|
-
ctx._cstBuf = s._cstBuf;
|
|
1112
|
-
ctx._tolerant = s._tolerant;
|
|
1113
|
-
ctx._sync = s._sync;
|
|
1114
|
-
}
|
|
1074
|
+
// src/cst/trivia-kinds.ts
|
|
1075
|
+
var labeledTriviaSpecs = /* @__PURE__ */ new WeakMap();
|
|
1076
|
+
function unwrapTrivia(p) {
|
|
1077
|
+
let cur = p;
|
|
1078
|
+
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1079
|
+
return cur;
|
|
1115
1080
|
}
|
|
1116
|
-
function
|
|
1117
|
-
if (
|
|
1118
|
-
return
|
|
1119
|
-
_tag: "orSentinel",
|
|
1120
|
-
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1121
|
-
_def: { tag: "unknown" },
|
|
1122
|
-
parse(input, pos, ctx) {
|
|
1123
|
-
const ra = a.parse(input, pos, ctx);
|
|
1124
|
-
if (ra.ok) return ra;
|
|
1125
|
-
return b.parse(input, pos, ctx);
|
|
1126
|
-
}
|
|
1127
|
-
};
|
|
1081
|
+
function peelLabel(p) {
|
|
1082
|
+
if (p._def.tag === "label") return { label: p._def.label, parser: p._def.parser };
|
|
1083
|
+
return null;
|
|
1128
1084
|
}
|
|
1129
|
-
function
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1085
|
+
function analyzeLabeledTrivia(trivia2) {
|
|
1086
|
+
const cached = labeledTriviaSpecs.get(trivia2);
|
|
1087
|
+
if (cached !== void 0) return cached;
|
|
1088
|
+
let core = unwrapTrivia(trivia2);
|
|
1089
|
+
let minRepeats = 1;
|
|
1090
|
+
if (core._def.tag === "oneOrMore") {
|
|
1091
|
+
core = core._def.parser;
|
|
1092
|
+
minRepeats = 1;
|
|
1093
|
+
} else if (core._def.tag === "many") {
|
|
1094
|
+
core = core._def.parser;
|
|
1095
|
+
minRepeats = 0;
|
|
1096
|
+
}
|
|
1097
|
+
const arms = [];
|
|
1098
|
+
if (core._def.tag === "choice") {
|
|
1099
|
+
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1100
|
+
const peeled = peelLabel(core._def.parsers[i]);
|
|
1101
|
+
if (!peeled) {
|
|
1102
|
+
labeledTriviaSpecs.set(trivia2, null);
|
|
1103
|
+
return null;
|
|
1142
1104
|
}
|
|
1143
|
-
|
|
1105
|
+
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1106
|
+
}
|
|
1107
|
+
} else {
|
|
1108
|
+
const peeled = peelLabel(core);
|
|
1109
|
+
if (!peeled) {
|
|
1110
|
+
labeledTriviaSpecs.set(trivia2, null);
|
|
1111
|
+
return null;
|
|
1144
1112
|
}
|
|
1113
|
+
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1114
|
+
}
|
|
1115
|
+
const spec = {
|
|
1116
|
+
labels: arms.map((a) => a.label),
|
|
1117
|
+
arms,
|
|
1118
|
+
minRepeats
|
|
1145
1119
|
};
|
|
1120
|
+
labeledTriviaSpecs.set(trivia2, spec);
|
|
1121
|
+
return spec;
|
|
1146
1122
|
}
|
|
1147
|
-
function
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1153
|
-
ctx._errors?.push(error);
|
|
1154
|
-
return { error, end: scanPos };
|
|
1155
|
-
}
|
|
1156
|
-
function matchesAt(sentinel, input, pos, ctx) {
|
|
1157
|
-
return probeAt(sentinel, input, pos, ctx);
|
|
1123
|
+
function matchArmAt(input, pos, arm, state) {
|
|
1124
|
+
if (!startsFirstSet(arm, input, pos)) return null;
|
|
1125
|
+
const r = arm.parse(input, pos, { trackLines: false, state });
|
|
1126
|
+
if (!r.ok || r.span.end <= pos) return null;
|
|
1127
|
+
return { end: r.span.end };
|
|
1158
1128
|
}
|
|
1159
|
-
function
|
|
1160
|
-
|
|
1129
|
+
function scanLabeledTriviaChunks(input, cur, spec, state) {
|
|
1130
|
+
const chunks = [];
|
|
1131
|
+
let pos = cur;
|
|
1132
|
+
while (pos < input.length) {
|
|
1133
|
+
let matched = null;
|
|
1134
|
+
for (const arm of spec.arms) {
|
|
1135
|
+
const m = matchArmAt(input, pos, arm.parser, state);
|
|
1136
|
+
if (m) {
|
|
1137
|
+
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1138
|
+
break;
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
if (!matched) break;
|
|
1142
|
+
chunks.push({ start: pos, end: matched.end, kindIndex: matched.kindIndex });
|
|
1143
|
+
pos = matched.end;
|
|
1144
|
+
}
|
|
1145
|
+
if (chunks.length < spec.minRepeats) {
|
|
1146
|
+
return { end: cur, chunks: [] };
|
|
1147
|
+
}
|
|
1148
|
+
return { end: pos, chunks };
|
|
1161
1149
|
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1150
|
+
function scanLabeledTriviaEnd(input, cur, spec, state) {
|
|
1151
|
+
let pos = cur;
|
|
1152
|
+
let count = 0;
|
|
1153
|
+
while (pos < input.length) {
|
|
1154
|
+
let matched = null;
|
|
1155
|
+
for (const arm of spec.arms) {
|
|
1156
|
+
matched = matchArmAt(input, pos, arm.parser, state);
|
|
1157
|
+
if (matched) break;
|
|
1158
|
+
}
|
|
1159
|
+
if (!matched) break;
|
|
1160
|
+
pos = matched.end;
|
|
1161
|
+
count++;
|
|
1162
|
+
}
|
|
1163
|
+
return count < spec.minRepeats ? cur : pos;
|
|
1166
1164
|
}
|
|
1167
|
-
function
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
return [def.label];
|
|
1179
|
-
case "choice":
|
|
1180
|
-
return def.parsers.flatMap(deriveExpected2);
|
|
1181
|
-
case "dispatch":
|
|
1182
|
-
return deriveExpected2(def.selector);
|
|
1183
|
-
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
1184
|
-
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
1185
|
-
// able to fail first — deriving from term 0 alone named a token the parse
|
|
1186
|
-
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
1187
|
-
// nothing (its own expectation is about what must NOT be here), but it is
|
|
1188
|
-
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
1189
|
-
case "sequence": {
|
|
1190
|
-
const out = [];
|
|
1191
|
-
for (const term of def.parsers) {
|
|
1192
|
-
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
1193
|
-
if (!matchesEmpty(term)) break;
|
|
1165
|
+
function visitLabeledTrivia(input, cur, spec, state, visit) {
|
|
1166
|
+
if (spec.minRepeats > 1) return void 0;
|
|
1167
|
+
let pos = cur;
|
|
1168
|
+
let count = 0;
|
|
1169
|
+
while (pos < input.length) {
|
|
1170
|
+
let matched = null;
|
|
1171
|
+
for (const arm of spec.arms) {
|
|
1172
|
+
const match = matchArmAt(input, pos, arm.parser, state);
|
|
1173
|
+
if (match) {
|
|
1174
|
+
matched = { end: match.end, kindIndex: arm.kindIndex };
|
|
1175
|
+
break;
|
|
1194
1176
|
}
|
|
1195
|
-
return out;
|
|
1196
1177
|
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
case "not":
|
|
1220
|
-
case "peek":
|
|
1221
|
-
return deriveExpected2(def.parser);
|
|
1222
|
-
case "routed":
|
|
1223
|
-
return ["routed()"];
|
|
1224
|
-
case "lazy": {
|
|
1225
|
-
const name = c._ruleName;
|
|
1226
|
-
if (seen.has(c)) return name ? [name] : [];
|
|
1227
|
-
seen.add(c);
|
|
1228
|
-
try {
|
|
1229
|
-
return deriveExpected2(def.thunk());
|
|
1230
|
-
} catch {
|
|
1231
|
-
return name ? [name] : [];
|
|
1232
|
-
} finally {
|
|
1233
|
-
seen.delete(c);
|
|
1178
|
+
if (!matched) break;
|
|
1179
|
+
visit(pos, matched.end, matched.kindIndex);
|
|
1180
|
+
pos = matched.end;
|
|
1181
|
+
count++;
|
|
1182
|
+
}
|
|
1183
|
+
return count < spec.minRepeats ? cur : pos;
|
|
1184
|
+
}
|
|
1185
|
+
function recordTriviaChunks(ctx, chunks) {
|
|
1186
|
+
const kinds = ctx.triviaKindLabels;
|
|
1187
|
+
const mask = ctx._triviaCaptureMask;
|
|
1188
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1189
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
1190
|
+
const rootMark = rootLog?.length ?? 0;
|
|
1191
|
+
for (const ch2 of chunks) {
|
|
1192
|
+
pushTriviaLogEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1193
|
+
const rootKindIndex = ctx._rootTriviaCapture === false || rootLog === void 0 || rootKinds === void 0 || kinds === void 0 ? -1 : rootKinds[kinds[ch2.kindIndex] ?? ""] ?? -1;
|
|
1194
|
+
if (rootKindIndex >= 0) {
|
|
1195
|
+
rootLog.push(0, 0, ch2.start, ch2.end, rootKindIndex);
|
|
1196
|
+
}
|
|
1197
|
+
if (ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)) {
|
|
1198
|
+
if (mask === void 0 || kinds === void 0 || (mask & 1 << ch2.kindIndex) !== 0) {
|
|
1199
|
+
pushCstTriviaEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1234
1200
|
}
|
|
1235
1201
|
}
|
|
1236
|
-
default:
|
|
1237
|
-
return [];
|
|
1238
1202
|
}
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
isTrivia: false
|
|
1246
|
-
};
|
|
1247
|
-
return {
|
|
1248
|
-
_tag: "expect",
|
|
1249
|
-
_meta: meta,
|
|
1250
|
-
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1251
|
-
parse(input, pos, ctx) {
|
|
1252
|
-
const result = combinator.parse(input, pos, ctx);
|
|
1253
|
-
if (result.ok) return result;
|
|
1254
|
-
const span = { start: pos, end: pos };
|
|
1255
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1256
|
-
ctx._errors?.push(error);
|
|
1257
|
-
if (ctx._tolerant) captureError(ctx, error);
|
|
1258
|
-
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1203
|
+
if (rootLog !== void 0 && rootLog.length !== rootMark && chunks.length > 0) {
|
|
1204
|
+
const start = chunks[0].start;
|
|
1205
|
+
const end = chunks[chunks.length - 1].end;
|
|
1206
|
+
for (let offset = rootMark; offset < rootLog.length; offset += 5) {
|
|
1207
|
+
rootLog[offset] = start;
|
|
1208
|
+
rootLog[offset + 1] = end;
|
|
1259
1209
|
}
|
|
1260
|
-
}
|
|
1210
|
+
}
|
|
1261
1211
|
}
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
const
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
1269
|
-
let combined = { kind: "empty" };
|
|
1270
|
-
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
1271
|
-
const meta = {
|
|
1272
|
-
firstSet: combined,
|
|
1273
|
-
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1274
|
-
isTrivia: false,
|
|
1275
|
-
disjoint
|
|
1276
|
-
};
|
|
1277
|
-
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
1278
|
-
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1279
|
-
let greedyLitMap = null;
|
|
1280
|
-
let sortedParsers = null;
|
|
1281
|
-
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
1282
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1283
|
-
greedyLitMap = /* @__PURE__ */ new Map();
|
|
1284
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1285
|
-
if (i === strategy.superIndex) continue;
|
|
1286
|
-
const litVal = getCoreLiteralValue(parsers[i]);
|
|
1287
|
-
if (litVal !== null) greedyLitMap.set(litVal, i);
|
|
1288
|
-
}
|
|
1289
|
-
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
1290
|
-
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
1212
|
+
function triviaKindMask(labels, keep) {
|
|
1213
|
+
if (!labels) return void 0;
|
|
1214
|
+
let mask = 0;
|
|
1215
|
+
for (const name of keep) {
|
|
1216
|
+
const idx = labels.indexOf(name);
|
|
1217
|
+
if (idx >= 0) mask |= 1 << idx;
|
|
1291
1218
|
}
|
|
1219
|
+
return mask;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
// src/combinators/trivia-skip.ts
|
|
1223
|
+
var NOOP_COMMIT = () => {
|
|
1224
|
+
};
|
|
1225
|
+
var fastTriviaCache = /* @__PURE__ */ new WeakMap();
|
|
1226
|
+
function needsDeferredTriviaCommit(ctx) {
|
|
1227
|
+
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
1228
|
+
}
|
|
1229
|
+
function saveTriviaMark(ctx) {
|
|
1230
|
+
const m = saveCstMark(ctx);
|
|
1292
1231
|
return {
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1232
|
+
raw: m.raw,
|
|
1233
|
+
tlog: m.tlog,
|
|
1234
|
+
leaves: m.leaves,
|
|
1235
|
+
fields: m.fields,
|
|
1236
|
+
errors: m.errors,
|
|
1237
|
+
log: ctx._triviaLog ? ctx._triviaLog.length : 0,
|
|
1238
|
+
rootLog: ctx._rootTriviaLog ? ctx._rootTriviaLog.length : 0
|
|
1239
|
+
};
|
|
1240
|
+
}
|
|
1241
|
+
function rollbackTrivia(ctx, mark) {
|
|
1242
|
+
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields, errors: mark.errors });
|
|
1243
|
+
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1244
|
+
if (ctx._rootTriviaLog && ctx._rootTriviaLog.length !== mark.rootLog) ctx._rootTriviaLog.length = mark.rootLog;
|
|
1245
|
+
}
|
|
1246
|
+
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1247
|
+
const probeCtx = {
|
|
1248
|
+
trackLines: ctx.trackLines,
|
|
1249
|
+
state: ctx.state,
|
|
1250
|
+
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1251
|
+
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1252
|
+
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1253
|
+
};
|
|
1254
|
+
const result = triviaP.parse(input, cur, probeCtx);
|
|
1255
|
+
ctx._lineScannedTo = probeCtx._lineScannedTo;
|
|
1256
|
+
return result;
|
|
1257
|
+
}
|
|
1258
|
+
function saveLookaheadMark(ctx) {
|
|
1259
|
+
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1260
|
+
}
|
|
1261
|
+
function rollbackLookahead(ctx, mark) {
|
|
1262
|
+
rollbackTrivia(ctx, mark);
|
|
1263
|
+
if (ctx._probe) ctx._probe.best = mark.probeBest;
|
|
1264
|
+
}
|
|
1265
|
+
function scanWithLabels(input, cur, ctx) {
|
|
1266
|
+
const triviaP = ctx.trivia;
|
|
1267
|
+
const spec = analyzeLabeledTrivia(triviaP);
|
|
1268
|
+
if (!spec) return { end: cur, commit: NOOP_COMMIT };
|
|
1269
|
+
const log = ctx._triviaLog;
|
|
1270
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1271
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
1272
|
+
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1273
|
+
const mask = ctx._triviaCaptureMask;
|
|
1274
|
+
let fullRows;
|
|
1275
|
+
let rootRows;
|
|
1276
|
+
let cstRows;
|
|
1277
|
+
const visitedEnd = visitLabeledTrivia(input, cur, spec, ctx.state, (start, matchEnd, kindIndex) => {
|
|
1278
|
+
if (log !== void 0) (fullRows ??= []).push(start, matchEnd, kindIndex);
|
|
1279
|
+
const selectedKind = rootLog === void 0 || rootKinds === void 0 || ctx._rootTriviaCapture === false ? void 0 : rootKinds[spec.labels[kindIndex] ?? ""];
|
|
1280
|
+
if (selectedKind !== void 0) (rootRows ??= []).push(start, matchEnd, selectedKind);
|
|
1281
|
+
if (captureTl && (mask === void 0 || (mask & 1 << kindIndex) !== 0)) {
|
|
1282
|
+
(cstRows ??= []).push(start, matchEnd, kindIndex);
|
|
1283
|
+
}
|
|
1284
|
+
});
|
|
1285
|
+
if (visitedEnd !== void 0) {
|
|
1286
|
+
if (visitedEnd === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1287
|
+
return {
|
|
1288
|
+
end: visitedEnd,
|
|
1289
|
+
commit: () => {
|
|
1290
|
+
if (fullRows !== void 0 && log !== void 0) log.push(...fullRows);
|
|
1291
|
+
if (rootRows !== void 0 && rootLog !== void 0) {
|
|
1292
|
+
for (let i = 0; i < rootRows.length; i += 3) {
|
|
1293
|
+
rootLog.push(cur, visitedEnd, rootRows[i], rootRows[i + 1], rootRows[i + 2]);
|
|
1314
1294
|
}
|
|
1315
1295
|
}
|
|
1316
|
-
if (
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1296
|
+
if (cstRows !== void 0) {
|
|
1297
|
+
for (let i = 0; i < cstRows.length; i += 3) {
|
|
1298
|
+
pushCstTriviaEntry(ctx, cstRows[i], cstRows[i + 1], cstRows[i + 2]);
|
|
1320
1299
|
}
|
|
1321
|
-
const result = parsers[idx].parse(input, pos, ctx);
|
|
1322
|
-
if (result.ok) return result;
|
|
1323
|
-
expected.push(...result.expected);
|
|
1324
|
-
if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
|
|
1325
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1326
|
-
}
|
|
1327
|
-
return {
|
|
1328
|
-
ok: false,
|
|
1329
|
-
expected: parsers.flatMap((p) => {
|
|
1330
|
-
const r = p.parse(input, pos, ctx);
|
|
1331
|
-
return r.ok ? [] : r.expected;
|
|
1332
|
-
}),
|
|
1333
|
-
span: { start: pos, end: pos }
|
|
1334
|
-
};
|
|
1335
|
-
}
|
|
1336
|
-
if (strategy?.tag === "greedyClassify") {
|
|
1337
|
-
const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
|
|
1338
|
-
if (!superResult.ok) return superResult;
|
|
1339
|
-
const end = superResult.span.end;
|
|
1340
|
-
const litIdx = greedyLitMap.get(input.slice(pos, end));
|
|
1341
|
-
if (litIdx !== void 0) {
|
|
1342
|
-
const litVal = getCoreLiteralValue(parsers[litIdx]);
|
|
1343
|
-
const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
|
|
1344
|
-
return { ok: true, value, span: { start: pos, end } };
|
|
1345
|
-
}
|
|
1346
|
-
return superResult;
|
|
1347
|
-
}
|
|
1348
|
-
if (strategy?.tag === "literalsLongestFirst") {
|
|
1349
|
-
for (const p of sortedParsers) {
|
|
1350
|
-
const r = p.parse(input, pos, ctx);
|
|
1351
|
-
if (r.ok) return r;
|
|
1352
|
-
expected.push(...r.expected);
|
|
1353
|
-
}
|
|
1354
|
-
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1355
|
-
}
|
|
1356
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1357
|
-
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
1358
|
-
const mark = saveCstMark(ctx);
|
|
1359
|
-
const logLen = ctx._triviaLog?.length;
|
|
1360
|
-
const result = parsers[i].parse(input, pos, ctx);
|
|
1361
|
-
if (!result.ok) {
|
|
1362
|
-
rollbackCstCapture(ctx, mark);
|
|
1363
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1364
|
-
expected.push(...result.expected);
|
|
1365
|
-
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
1366
|
-
continue;
|
|
1367
1300
|
}
|
|
1368
|
-
const checks = autoNot[i];
|
|
1369
|
-
if (checks && autoNotFires(input, result.span.end, checks)) {
|
|
1370
|
-
rollbackCstCapture(ctx, mark);
|
|
1371
|
-
if (logLen !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== logLen) ctx._triviaLog.length = logLen;
|
|
1372
|
-
continue;
|
|
1373
|
-
}
|
|
1374
|
-
return result;
|
|
1375
1301
|
}
|
|
1376
|
-
|
|
1377
|
-
|
|
1302
|
+
};
|
|
1303
|
+
}
|
|
1304
|
+
const { end, chunks } = scanLabeledTriviaChunks(input, cur, spec, ctx.state);
|
|
1305
|
+
if (end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1306
|
+
return {
|
|
1307
|
+
end,
|
|
1308
|
+
commit: () => recordTriviaChunks(ctx, chunks)
|
|
1378
1309
|
};
|
|
1379
1310
|
}
|
|
1380
|
-
function
|
|
1381
|
-
const
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
const
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
const m = re.exec(litVal);
|
|
1396
|
-
return m !== null && m[0] === litVal;
|
|
1397
|
-
});
|
|
1398
|
-
if (allSubsumed) return { tag: "greedyClassify", superIndex };
|
|
1311
|
+
function skipWithLabels(input, cur, ctx) {
|
|
1312
|
+
const spec = analyzeLabeledTrivia(ctx.trivia);
|
|
1313
|
+
if (spec) return scanLabeledTriviaEnd(input, cur, spec, ctx.state);
|
|
1314
|
+
const tr = parseTriviaNoCapture(ctx.trivia, input, cur, ctx);
|
|
1315
|
+
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1316
|
+
}
|
|
1317
|
+
function advanceTrivia(input, cur, ctx) {
|
|
1318
|
+
const triviaP = ctx.trivia;
|
|
1319
|
+
if (!triviaP) return cur;
|
|
1320
|
+
if (!ctx.trackLines) {
|
|
1321
|
+
const fast2 = fastTriviaScanner(triviaP);
|
|
1322
|
+
if (fast2) return fast2(input, cur);
|
|
1323
|
+
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
1324
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1325
|
+
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1399
1326
|
}
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
);
|
|
1404
|
-
|
|
1327
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1328
|
+
const fast = fastTriviaScanner(triviaP);
|
|
1329
|
+
if (fast) {
|
|
1330
|
+
const end = fast(input, cur);
|
|
1331
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1332
|
+
return end;
|
|
1405
1333
|
}
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
function bareLeadingTermKey(term) {
|
|
1411
|
-
const d = term._def;
|
|
1412
|
-
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
1413
|
-
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
1414
|
-
return null;
|
|
1415
|
-
}
|
|
1416
|
-
function detectSharedPrefix(parsers) {
|
|
1417
|
-
if (parsers.length < 2) return null;
|
|
1418
|
-
let key = null;
|
|
1419
|
-
let prefix = null;
|
|
1420
|
-
const members = [];
|
|
1421
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
1422
|
-
const term0 = leadingTermOfArm(parsers[i]);
|
|
1423
|
-
if (term0 === null) return null;
|
|
1424
|
-
const k = bareLeadingTermKey(term0);
|
|
1425
|
-
if (k === null) return null;
|
|
1426
|
-
if (key === null) {
|
|
1427
|
-
key = k;
|
|
1428
|
-
prefix = term0;
|
|
1429
|
-
} else if (k !== key) return null;
|
|
1430
|
-
members.push(i);
|
|
1334
|
+
if (ctx.triviaKindLabels) {
|
|
1335
|
+
const end = skipWithLabels(input, cur, ctx);
|
|
1336
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1337
|
+
return end;
|
|
1431
1338
|
}
|
|
1432
|
-
|
|
1433
|
-
return
|
|
1339
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1340
|
+
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1434
1341
|
}
|
|
1435
|
-
function
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1342
|
+
function scanTrivia(input, cur, ctx) {
|
|
1343
|
+
const triviaP = ctx.trivia;
|
|
1344
|
+
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1345
|
+
const log = ctx._triviaLog;
|
|
1346
|
+
const rootLog = ctx._rootTriviaLog;
|
|
1347
|
+
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1348
|
+
if (!ctx.trackLines) {
|
|
1349
|
+
const fast2 = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1350
|
+
if (fast2 && log === void 0 && !captureTl) {
|
|
1351
|
+
return { end: fast2(input, cur), commit: NOOP_COMMIT };
|
|
1441
1352
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
1445
|
-
return d.parsers[0];
|
|
1446
|
-
}
|
|
1447
|
-
function computeAutoNot(parsers) {
|
|
1448
|
-
return parsers.map((p, i) => {
|
|
1449
|
-
const litVal = getCoreLiteralValue(p);
|
|
1450
|
-
if (litVal === null) return null;
|
|
1451
|
-
const checks = [];
|
|
1452
|
-
for (let j = i + 1; j < parsers.length; j++) {
|
|
1453
|
-
const other = parsers[j];
|
|
1454
|
-
const otherLit = getCoreLiteralValue(other);
|
|
1455
|
-
if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
|
|
1456
|
-
checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
|
|
1457
|
-
continue;
|
|
1458
|
-
}
|
|
1459
|
-
const regexDef = getCoreRegexDef(other);
|
|
1460
|
-
if (regexDef !== null) {
|
|
1461
|
-
const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
|
|
1462
|
-
if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
|
|
1463
|
-
}
|
|
1353
|
+
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1354
|
+
return scanWithLabels(input, cur, ctx);
|
|
1464
1355
|
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1356
|
+
if (ctx.triviaKindLabels) return { end: skipWithLabels(input, cur, ctx), commit: NOOP_COMMIT };
|
|
1357
|
+
if (log !== void 0 || rootLog !== void 0 || captureTl) {
|
|
1358
|
+
const tr3 = triviaP.parse(input, cur, {
|
|
1359
|
+
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1360
|
+
state: ctx.state
|
|
1361
|
+
});
|
|
1362
|
+
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1363
|
+
const end = tr3.span.end;
|
|
1364
|
+
return {
|
|
1365
|
+
end,
|
|
1366
|
+
commit: () => {
|
|
1367
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1368
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1475
1371
|
}
|
|
1372
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1373
|
+
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1476
1374
|
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
return null;
|
|
1484
|
-
}
|
|
1485
|
-
function getCoreRegexDef(p) {
|
|
1486
|
-
const def = p._def;
|
|
1487
|
-
if (def.tag === "regex") return { source: def.source, flags: def.flags };
|
|
1488
|
-
if (def.tag === "transform") return getCoreRegexDef(def.parser);
|
|
1489
|
-
if (def.tag === "label") return getCoreRegexDef(def.parser);
|
|
1490
|
-
return null;
|
|
1491
|
-
}
|
|
1492
|
-
function applyTransforms(p, value, span) {
|
|
1493
|
-
const def = p._def;
|
|
1494
|
-
if (def.tag === "transform") {
|
|
1495
|
-
const inner = applyTransforms(def.parser, value, span);
|
|
1496
|
-
return def.fn(inner, span);
|
|
1375
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1376
|
+
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1377
|
+
if (fast && log === void 0 && !captureTl) {
|
|
1378
|
+
const end = fast(input, cur);
|
|
1379
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1380
|
+
return { end, commit: NOOP_COMMIT };
|
|
1497
1381
|
}
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
re.lastIndex = 0;
|
|
1503
|
-
const base = re.exec(lit);
|
|
1504
|
-
if (!base || base[0] !== lit) return null;
|
|
1505
|
-
const contCodes = [];
|
|
1506
|
-
for (let code = 1; code < 128; code++) {
|
|
1507
|
-
re.lastIndex = 0;
|
|
1508
|
-
const m = re.exec(lit + String.fromCharCode(code));
|
|
1509
|
-
if (m && m[0].length > lit.length) contCodes.push(code);
|
|
1382
|
+
if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
|
|
1383
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1384
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1385
|
+
return scan;
|
|
1510
1386
|
}
|
|
1511
|
-
if (
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
codes.sort((a, b) => a - b);
|
|
1516
|
-
const ranges = [];
|
|
1517
|
-
let lo = codes[0], hi = codes[0];
|
|
1518
|
-
for (let i = 1; i < codes.length; i++) {
|
|
1519
|
-
if (codes[i] === hi + 1) {
|
|
1520
|
-
hi = codes[i];
|
|
1521
|
-
} else {
|
|
1522
|
-
ranges.push({ lo, hi });
|
|
1523
|
-
lo = hi = codes[i];
|
|
1524
|
-
}
|
|
1387
|
+
if (ctx.triviaKindLabels) {
|
|
1388
|
+
const end = skipWithLabels(input, cur, ctx);
|
|
1389
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1390
|
+
return { end, commit: NOOP_COMMIT };
|
|
1525
1391
|
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1392
|
+
if (log !== void 0 || rootLog !== void 0 || captureTl) {
|
|
1393
|
+
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1394
|
+
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1395
|
+
const end = tr2.span.end;
|
|
1396
|
+
return {
|
|
1397
|
+
end,
|
|
1398
|
+
commit: () => {
|
|
1399
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1400
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1401
|
+
}
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1405
|
+
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1528
1406
|
}
|
|
1529
|
-
function
|
|
1530
|
-
if (
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
return
|
|
1407
|
+
function consumeTrivia(input, cur, ctx) {
|
|
1408
|
+
if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
|
|
1409
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1410
|
+
scan.commit();
|
|
1411
|
+
return scan.end;
|
|
1534
1412
|
}
|
|
1535
|
-
function
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
return
|
|
1413
|
+
function fastTriviaScanner(trivia2) {
|
|
1414
|
+
const cached = fastTriviaCache.get(trivia2);
|
|
1415
|
+
if (cached !== void 0) return cached;
|
|
1416
|
+
const scanner = buildFastTriviaScanner(trivia2);
|
|
1417
|
+
fastTriviaCache.set(trivia2, scanner);
|
|
1418
|
+
return scanner;
|
|
1541
1419
|
}
|
|
1542
|
-
function
|
|
1543
|
-
const
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1420
|
+
function buildFastTriviaScanner(trivia2) {
|
|
1421
|
+
const core = trivia2._def.tag === "trivia" ? trivia2._def.parser : trivia2;
|
|
1422
|
+
const direct = regexTriviaScanner(core);
|
|
1423
|
+
if (direct) return direct;
|
|
1424
|
+
const repeat = core._def.tag === "oneOrMore" || core._def.tag === "many" && core._def.min >= 1 ? core._def.parser : null;
|
|
1425
|
+
if (!repeat) return null;
|
|
1426
|
+
const one = regexTriviaScanner(repeat);
|
|
1427
|
+
if (one) return loopScanner([one]);
|
|
1428
|
+
if (repeat._def.tag !== "choice") return null;
|
|
1429
|
+
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1430
|
+
if (arms.some((s) => s === null)) return null;
|
|
1431
|
+
return loopScanner(arms);
|
|
1432
|
+
}
|
|
1433
|
+
function loopScanner(arms) {
|
|
1434
|
+
return (input, cur) => {
|
|
1435
|
+
let pos = cur;
|
|
1436
|
+
scan: while (pos < input.length) {
|
|
1437
|
+
for (const arm of arms) {
|
|
1438
|
+
const end = arm(input, pos);
|
|
1439
|
+
if (end > pos) {
|
|
1440
|
+
pos = end;
|
|
1441
|
+
continue scan;
|
|
1442
|
+
}
|
|
1550
1443
|
}
|
|
1444
|
+
break;
|
|
1551
1445
|
}
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
}
|
|
1555
|
-
|
|
1556
|
-
// src/cst/trivia-kinds.ts
|
|
1557
|
-
function unwrapTrivia(p) {
|
|
1558
|
-
let cur = p;
|
|
1559
|
-
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1560
|
-
return cur;
|
|
1446
|
+
return pos;
|
|
1447
|
+
};
|
|
1561
1448
|
}
|
|
1562
|
-
function
|
|
1563
|
-
if (
|
|
1564
|
-
|
|
1449
|
+
function regexTriviaScanner(parser2) {
|
|
1450
|
+
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1451
|
+
const source = parser2._def.source;
|
|
1452
|
+
return classRunSource(source) ?? altStarSource(source);
|
|
1565
1453
|
}
|
|
1566
|
-
function
|
|
1567
|
-
let
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
core = core._def.parser;
|
|
1571
|
-
minRepeats = 1;
|
|
1572
|
-
} else if (core._def.tag === "many") {
|
|
1573
|
-
core = core._def.parser;
|
|
1574
|
-
minRepeats = 0;
|
|
1575
|
-
}
|
|
1576
|
-
const arms = [];
|
|
1577
|
-
if (core._def.tag === "choice") {
|
|
1578
|
-
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1579
|
-
const peeled = peelLabel(core._def.parsers[i]);
|
|
1580
|
-
if (!peeled) return null;
|
|
1581
|
-
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1582
|
-
}
|
|
1583
|
-
} else {
|
|
1584
|
-
const peeled = peelLabel(core);
|
|
1585
|
-
if (!peeled) return null;
|
|
1586
|
-
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1454
|
+
function inRanges2(cp, ranges) {
|
|
1455
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
1456
|
+
const r = ranges[i];
|
|
1457
|
+
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1587
1458
|
}
|
|
1588
|
-
return
|
|
1459
|
+
return false;
|
|
1589
1460
|
}
|
|
1590
|
-
function
|
|
1591
|
-
const
|
|
1592
|
-
if (!
|
|
1593
|
-
return
|
|
1461
|
+
function classScanner(classBody) {
|
|
1462
|
+
const ranges = parseClassRanges(classBody);
|
|
1463
|
+
if (!ranges) return null;
|
|
1464
|
+
return (input, cur) => {
|
|
1465
|
+
let pos = cur;
|
|
1466
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1467
|
+
return pos;
|
|
1468
|
+
};
|
|
1594
1469
|
}
|
|
1595
|
-
function
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1604
|
-
break;
|
|
1605
|
-
}
|
|
1470
|
+
function untilLineBreakScanner(leaderCode) {
|
|
1471
|
+
return (input, cur) => {
|
|
1472
|
+
if (input.charCodeAt(cur) !== leaderCode) return cur;
|
|
1473
|
+
let pos = cur + 1;
|
|
1474
|
+
while (pos < input.length) {
|
|
1475
|
+
const cc = input.charCodeAt(pos);
|
|
1476
|
+
if (cc === 10 || cc === 13) break;
|
|
1477
|
+
pos++;
|
|
1606
1478
|
}
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1479
|
+
return pos;
|
|
1480
|
+
};
|
|
1481
|
+
}
|
|
1482
|
+
function classRunSource(source) {
|
|
1483
|
+
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1484
|
+
return m ? classScanner(m[1]) : null;
|
|
1485
|
+
}
|
|
1486
|
+
function classifyTriviaArm(arm) {
|
|
1487
|
+
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1488
|
+
if (cls) {
|
|
1489
|
+
const ranges = parseClassRanges(cls[1]);
|
|
1490
|
+
return ranges ? { kind: "class", ranges } : null;
|
|
1610
1491
|
}
|
|
1611
|
-
|
|
1612
|
-
|
|
1492
|
+
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1493
|
+
if (lc) {
|
|
1494
|
+
const marker = lc[1];
|
|
1495
|
+
return { kind: "untilLineBreak", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1613
1496
|
}
|
|
1614
|
-
return
|
|
1615
|
-
}
|
|
1616
|
-
function scanFastWsCommentsChunks(input, cur, wsKind, commentKind) {
|
|
1617
|
-
const chunks = [];
|
|
1618
|
-
let pos = cur;
|
|
1619
|
-
while (pos < input.length) {
|
|
1620
|
-
const c = input.charCodeAt(pos);
|
|
1621
|
-
if (c === 32 || c === 9 || c === 10 || c === 13 || c === 12) {
|
|
1622
|
-
const start = pos;
|
|
1623
|
-
pos++;
|
|
1624
|
-
while (pos < input.length) {
|
|
1625
|
-
const c2 = input.charCodeAt(pos);
|
|
1626
|
-
if (c2 === 32 || c2 === 9 || c2 === 10 || c2 === 13 || c2 === 12) pos++;
|
|
1627
|
-
else break;
|
|
1628
|
-
}
|
|
1629
|
-
chunks.push({ start, end: pos, kindIndex: wsKind });
|
|
1630
|
-
continue;
|
|
1631
|
-
}
|
|
1632
|
-
if (c === 47 && input.charCodeAt(pos + 1) === 42) {
|
|
1633
|
-
let j = pos + 2;
|
|
1634
|
-
while (j + 1 < input.length && !(input.charCodeAt(j) === 42 && input.charCodeAt(j + 1) === 47)) j++;
|
|
1635
|
-
if (j + 1 < input.length && input.charCodeAt(j) === 42 && input.charCodeAt(j + 1) === 47) {
|
|
1636
|
-
const start = pos;
|
|
1637
|
-
pos = j + 2;
|
|
1638
|
-
chunks.push({ start, end: pos, kindIndex: commentKind });
|
|
1639
|
-
continue;
|
|
1640
|
-
}
|
|
1641
|
-
break;
|
|
1642
|
-
}
|
|
1643
|
-
break;
|
|
1644
|
-
}
|
|
1645
|
-
return { end: pos, chunks };
|
|
1646
|
-
}
|
|
1647
|
-
function tryFastLabeledScan(input, cur, trivia2) {
|
|
1648
|
-
const spec = analyzeLabeledTrivia(trivia2);
|
|
1649
|
-
if (!spec || spec.arms.length !== 2) return null;
|
|
1650
|
-
const wsArm = spec.arms.find((a) => {
|
|
1651
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1652
|
-
return src != null && !src.includes("\\*");
|
|
1653
|
-
});
|
|
1654
|
-
const commentArm = spec.arms.find((a) => {
|
|
1655
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1656
|
-
return src != null && src.includes("\\*");
|
|
1657
|
-
});
|
|
1658
|
-
if (!wsArm || !commentArm) return null;
|
|
1659
|
-
const { chunks } = scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1660
|
-
if (chunks.length < spec.minRepeats) return { end: cur, chunks: [] };
|
|
1661
|
-
return scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1662
|
-
}
|
|
1663
|
-
function recordTriviaChunks(ctx, chunks) {
|
|
1664
|
-
const kinds = ctx.triviaKindLabels;
|
|
1665
|
-
const mask = ctx._triviaCaptureMask;
|
|
1666
|
-
for (const ch2 of chunks) {
|
|
1667
|
-
pushTriviaLogEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1668
|
-
if (ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)) {
|
|
1669
|
-
if (mask === void 0 || kinds === void 0 || (mask & 1 << ch2.kindIndex) !== 0) {
|
|
1670
|
-
pushCstTriviaEntry(ctx, ch2.start, ch2.end, kinds ? ch2.kindIndex : void 0);
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
function triviaKindMask(labels, keep) {
|
|
1676
|
-
if (!labels) return void 0;
|
|
1677
|
-
let mask = 0;
|
|
1678
|
-
for (const name of keep) {
|
|
1679
|
-
const idx = labels.indexOf(name);
|
|
1680
|
-
if (idx >= 0) mask |= 1 << idx;
|
|
1681
|
-
}
|
|
1682
|
-
return mask;
|
|
1683
|
-
}
|
|
1684
|
-
|
|
1685
|
-
// src/combinators/trivia-skip.ts
|
|
1686
|
-
var NOOP_COMMIT = () => {
|
|
1687
|
-
};
|
|
1688
|
-
var fastTriviaCache = /* @__PURE__ */ new WeakMap();
|
|
1689
|
-
function needsDeferredTriviaCommit(ctx) {
|
|
1690
|
-
return ctx._triviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
1691
|
-
}
|
|
1692
|
-
function saveTriviaMark(ctx) {
|
|
1693
|
-
const m = saveCstMark(ctx);
|
|
1694
|
-
return { raw: m.raw, tlog: m.tlog, leaves: m.leaves, fields: m.fields, errors: m.errors, log: ctx._triviaLog ? ctx._triviaLog.length : 0 };
|
|
1695
|
-
}
|
|
1696
|
-
function rollbackTrivia(ctx, mark) {
|
|
1697
|
-
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields, errors: mark.errors });
|
|
1698
|
-
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1699
|
-
}
|
|
1700
|
-
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1701
|
-
const probeCtx = {
|
|
1702
|
-
trackLines: ctx.trackLines,
|
|
1703
|
-
state: ctx.state,
|
|
1704
|
-
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1705
|
-
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1706
|
-
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1707
|
-
};
|
|
1708
|
-
const result = triviaP.parse(input, cur, probeCtx);
|
|
1709
|
-
ctx._lineScannedTo = probeCtx._lineScannedTo;
|
|
1710
|
-
return result;
|
|
1711
|
-
}
|
|
1712
|
-
function saveLookaheadMark(ctx) {
|
|
1713
|
-
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1714
|
-
}
|
|
1715
|
-
function rollbackLookahead(ctx, mark) {
|
|
1716
|
-
rollbackTrivia(ctx, mark);
|
|
1717
|
-
if (ctx._probe) ctx._probe.best = mark.probeBest;
|
|
1718
|
-
}
|
|
1719
|
-
function scanWithLabels(input, cur, ctx) {
|
|
1720
|
-
const triviaP = ctx.trivia;
|
|
1721
|
-
const spec = analyzeLabeledTrivia(triviaP);
|
|
1722
|
-
if (!spec) return { end: cur, commit: NOOP_COMMIT };
|
|
1723
|
-
const fast = tryFastLabeledScan(input, cur, triviaP);
|
|
1724
|
-
const { end, chunks } = fast ?? scanLabeledTriviaChunks(input, cur, spec);
|
|
1725
|
-
if (end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1726
|
-
return {
|
|
1727
|
-
end,
|
|
1728
|
-
commit: () => recordTriviaChunks(ctx, chunks)
|
|
1729
|
-
};
|
|
1730
|
-
}
|
|
1731
|
-
function advanceTrivia(input, cur, ctx) {
|
|
1732
|
-
const triviaP = ctx.trivia;
|
|
1733
|
-
if (!triviaP) return cur;
|
|
1734
|
-
if (!ctx.trackLines) {
|
|
1735
|
-
const fast2 = fastTriviaScanner(triviaP);
|
|
1736
|
-
if (fast2) return fast2(input, cur);
|
|
1737
|
-
if (ctx.triviaKindLabels) {
|
|
1738
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1739
|
-
return scan.end;
|
|
1740
|
-
}
|
|
1741
|
-
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1742
|
-
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1743
|
-
}
|
|
1744
|
-
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1745
|
-
const fast = fastTriviaScanner(triviaP);
|
|
1746
|
-
if (fast) {
|
|
1747
|
-
const end = fast(input, cur);
|
|
1748
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1749
|
-
return end;
|
|
1750
|
-
}
|
|
1751
|
-
if (ctx.triviaKindLabels) {
|
|
1752
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1753
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1754
|
-
return scan.end;
|
|
1755
|
-
}
|
|
1756
|
-
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1757
|
-
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1758
|
-
}
|
|
1759
|
-
function scanTrivia(input, cur, ctx) {
|
|
1760
|
-
const triviaP = ctx.trivia;
|
|
1761
|
-
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1762
|
-
const log = ctx._triviaLog;
|
|
1763
|
-
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1764
|
-
if (!ctx.trackLines) {
|
|
1765
|
-
const fast2 = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1766
|
-
if (fast2 && log === void 0 && !captureTl) {
|
|
1767
|
-
return { end: fast2(input, cur), commit: NOOP_COMMIT };
|
|
1768
|
-
}
|
|
1769
|
-
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1770
|
-
return scanWithLabels(input, cur, ctx);
|
|
1771
|
-
}
|
|
1772
|
-
if (log !== void 0 || captureTl) {
|
|
1773
|
-
const tr3 = triviaP.parse(input, cur, {
|
|
1774
|
-
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1775
|
-
state: ctx.state
|
|
1776
|
-
});
|
|
1777
|
-
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1778
|
-
const end = tr3.span.end;
|
|
1779
|
-
return {
|
|
1780
|
-
end,
|
|
1781
|
-
commit: () => {
|
|
1782
|
-
pushTriviaLogEntry(ctx, cur, end);
|
|
1783
|
-
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1784
|
-
}
|
|
1785
|
-
};
|
|
1786
|
-
}
|
|
1787
|
-
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1788
|
-
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1789
|
-
}
|
|
1790
|
-
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1791
|
-
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1792
|
-
if (fast && log === void 0 && !captureTl) {
|
|
1793
|
-
const end = fast(input, cur);
|
|
1794
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1795
|
-
return { end, commit: NOOP_COMMIT };
|
|
1796
|
-
}
|
|
1797
|
-
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1798
|
-
const scan = scanWithLabels(input, cur, ctx);
|
|
1799
|
-
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1800
|
-
return scan;
|
|
1801
|
-
}
|
|
1802
|
-
if (log !== void 0 || captureTl) {
|
|
1803
|
-
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1804
|
-
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1805
|
-
const end = tr2.span.end;
|
|
1806
|
-
return {
|
|
1807
|
-
end,
|
|
1808
|
-
commit: () => {
|
|
1809
|
-
pushTriviaLogEntry(ctx, cur, end);
|
|
1810
|
-
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1811
|
-
}
|
|
1812
|
-
};
|
|
1813
|
-
}
|
|
1814
|
-
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1815
|
-
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1816
|
-
}
|
|
1817
|
-
function consumeTrivia(input, cur, ctx) {
|
|
1818
|
-
if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
|
|
1819
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
1820
|
-
scan.commit();
|
|
1821
|
-
return scan.end;
|
|
1822
|
-
}
|
|
1823
|
-
function fastTriviaScanner(trivia2) {
|
|
1824
|
-
const cached = fastTriviaCache.get(trivia2);
|
|
1825
|
-
if (cached !== void 0) return cached;
|
|
1826
|
-
const scanner = buildFastTriviaScanner(trivia2);
|
|
1827
|
-
fastTriviaCache.set(trivia2, scanner);
|
|
1828
|
-
return scanner;
|
|
1829
|
-
}
|
|
1830
|
-
function buildFastTriviaScanner(trivia2) {
|
|
1831
|
-
const core = trivia2._def.tag === "trivia" ? trivia2._def.parser : trivia2;
|
|
1832
|
-
const direct = regexTriviaScanner(core);
|
|
1833
|
-
if (direct) return direct;
|
|
1834
|
-
const repeat = core._def.tag === "oneOrMore" || core._def.tag === "many" && core._def.min >= 1 ? core._def.parser : null;
|
|
1835
|
-
if (!repeat) return null;
|
|
1836
|
-
const one = regexTriviaScanner(repeat);
|
|
1837
|
-
if (one) return loopScanner([one]);
|
|
1838
|
-
if (repeat._def.tag !== "choice") return null;
|
|
1839
|
-
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1840
|
-
if (arms.some((s) => s === null)) return null;
|
|
1841
|
-
return loopScanner(arms);
|
|
1842
|
-
}
|
|
1843
|
-
function loopScanner(arms) {
|
|
1844
|
-
return (input, cur) => {
|
|
1845
|
-
let pos = cur;
|
|
1846
|
-
scan: while (pos < input.length) {
|
|
1847
|
-
for (const arm of arms) {
|
|
1848
|
-
const end = arm(input, pos);
|
|
1849
|
-
if (end > pos) {
|
|
1850
|
-
pos = end;
|
|
1851
|
-
continue scan;
|
|
1852
|
-
}
|
|
1853
|
-
}
|
|
1854
|
-
break;
|
|
1855
|
-
}
|
|
1856
|
-
return pos;
|
|
1857
|
-
};
|
|
1858
|
-
}
|
|
1859
|
-
function regexTriviaScanner(parser2) {
|
|
1860
|
-
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1861
|
-
const source = parser2._def.source;
|
|
1862
|
-
return classRunSource(source) ?? altStarSource(source) ?? (blockCommentSource(source) ? scanBlockComment : null);
|
|
1863
|
-
}
|
|
1864
|
-
function inRanges2(cp, ranges) {
|
|
1865
|
-
for (let i = 0; i < ranges.length; i++) {
|
|
1866
|
-
const r = ranges[i];
|
|
1867
|
-
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1868
|
-
}
|
|
1869
|
-
return false;
|
|
1870
|
-
}
|
|
1871
|
-
function classScanner(classBody) {
|
|
1872
|
-
const ranges = parseClassRanges(classBody);
|
|
1873
|
-
if (!ranges) return null;
|
|
1874
|
-
return (input, cur) => {
|
|
1875
|
-
let pos = cur;
|
|
1876
|
-
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1877
|
-
return pos;
|
|
1878
|
-
};
|
|
1879
|
-
}
|
|
1880
|
-
function lineCommentScanner(commentCode) {
|
|
1881
|
-
return (input, cur) => {
|
|
1882
|
-
if (input.charCodeAt(cur) !== commentCode) return cur;
|
|
1883
|
-
let pos = cur + 1;
|
|
1884
|
-
while (pos < input.length) {
|
|
1885
|
-
const cc = input.charCodeAt(pos);
|
|
1886
|
-
if (cc === 10 || cc === 13) break;
|
|
1887
|
-
pos++;
|
|
1888
|
-
}
|
|
1889
|
-
return pos;
|
|
1890
|
-
};
|
|
1891
|
-
}
|
|
1892
|
-
function classRunSource(source) {
|
|
1893
|
-
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1894
|
-
return m ? classScanner(m[1]) : null;
|
|
1895
|
-
}
|
|
1896
|
-
function classifyTriviaArm(arm) {
|
|
1897
|
-
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1898
|
-
if (cls) {
|
|
1899
|
-
const ranges = parseClassRanges(cls[1]);
|
|
1900
|
-
return ranges ? { kind: "class", ranges } : null;
|
|
1901
|
-
}
|
|
1902
|
-
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1903
|
-
if (lc) {
|
|
1904
|
-
const marker = lc[1];
|
|
1905
|
-
return { kind: "comment", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1906
|
-
}
|
|
1907
|
-
return null;
|
|
1497
|
+
return null;
|
|
1908
1498
|
}
|
|
1909
1499
|
function armScanner(arm) {
|
|
1910
|
-
if (arm.kind === "
|
|
1500
|
+
if (arm.kind === "untilLineBreak") return untilLineBreakScanner(arm.code);
|
|
1911
1501
|
const ranges = arm.ranges;
|
|
1912
1502
|
return (input, cur) => {
|
|
1913
1503
|
let pos = cur;
|
|
@@ -1915,9 +1505,9 @@ function armScanner(arm) {
|
|
|
1915
1505
|
return pos;
|
|
1916
1506
|
};
|
|
1917
1507
|
}
|
|
1918
|
-
function fusedTriviaScanner(ranges,
|
|
1919
|
-
const c0 =
|
|
1920
|
-
const single =
|
|
1508
|
+
function fusedTriviaScanner(ranges, leaders) {
|
|
1509
|
+
const c0 = leaders[0];
|
|
1510
|
+
const single = leaders.length === 1;
|
|
1921
1511
|
return (input, cur) => {
|
|
1922
1512
|
let pos = cur;
|
|
1923
1513
|
const len = input.length;
|
|
@@ -1927,7 +1517,7 @@ function fusedTriviaScanner(ranges, commentCodes) {
|
|
|
1927
1517
|
pos++;
|
|
1928
1518
|
continue;
|
|
1929
1519
|
}
|
|
1930
|
-
if (single ? c === c0 :
|
|
1520
|
+
if (single ? c === c0 : leaders.includes(c)) {
|
|
1931
1521
|
pos++;
|
|
1932
1522
|
while (pos < len) {
|
|
1933
1523
|
const cc = input.charCodeAt(pos);
|
|
@@ -1936,166 +1526,640 @@ function fusedTriviaScanner(ranges, commentCodes) {
|
|
|
1936
1526
|
}
|
|
1937
1527
|
continue;
|
|
1938
1528
|
}
|
|
1939
|
-
break;
|
|
1529
|
+
break;
|
|
1530
|
+
}
|
|
1531
|
+
return pos;
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
function splitTopLevelAlts(body) {
|
|
1535
|
+
const arms = [];
|
|
1536
|
+
let inClass = false;
|
|
1537
|
+
let start = 0;
|
|
1538
|
+
for (let i = 0; i < body.length; i++) {
|
|
1539
|
+
const c = body[i];
|
|
1540
|
+
if (c === "\\") {
|
|
1541
|
+
i++;
|
|
1542
|
+
continue;
|
|
1543
|
+
}
|
|
1544
|
+
if (inClass) {
|
|
1545
|
+
if (c === "]") inClass = false;
|
|
1546
|
+
continue;
|
|
1547
|
+
}
|
|
1548
|
+
if (c === "[") inClass = true;
|
|
1549
|
+
else if (c === "(") return null;
|
|
1550
|
+
else if (c === "|") {
|
|
1551
|
+
arms.push(body.slice(start, i));
|
|
1552
|
+
start = i + 1;
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
arms.push(body.slice(start));
|
|
1556
|
+
return arms;
|
|
1557
|
+
}
|
|
1558
|
+
function altStarSource(source) {
|
|
1559
|
+
const m = /^\(\?:(.*)\)[*+]$/.exec(source);
|
|
1560
|
+
if (!m) return null;
|
|
1561
|
+
const armSrcs = splitTopLevelAlts(m[1]);
|
|
1562
|
+
if (!armSrcs || armSrcs.length < 2) return null;
|
|
1563
|
+
const arms = [];
|
|
1564
|
+
for (const src of armSrcs) {
|
|
1565
|
+
const arm = classifyTriviaArm(src);
|
|
1566
|
+
if (!arm) return null;
|
|
1567
|
+
arms.push(arm);
|
|
1568
|
+
}
|
|
1569
|
+
const ranges = [];
|
|
1570
|
+
const leaders = [];
|
|
1571
|
+
for (const arm of arms) {
|
|
1572
|
+
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1573
|
+
else leaders.push(arm.code);
|
|
1574
|
+
}
|
|
1575
|
+
if (leaders.some((code) => inRanges2(code, ranges))) {
|
|
1576
|
+
return loopScanner(arms.map(armScanner));
|
|
1577
|
+
}
|
|
1578
|
+
if (leaders.length === 0) return armScanner({ kind: "class", ranges });
|
|
1579
|
+
return fusedTriviaScanner(ranges, leaders);
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
// src/recovery/scan.ts
|
|
1583
|
+
function probeAt(sentinel, input, pos, ctx) {
|
|
1584
|
+
const s = {
|
|
1585
|
+
_probe: ctx._probe,
|
|
1586
|
+
_errors: ctx._errors,
|
|
1587
|
+
_cstLeaves: ctx._cstLeaves,
|
|
1588
|
+
_cstChildren: ctx._cstChildren,
|
|
1589
|
+
_cstRawChildren: ctx._cstRawChildren,
|
|
1590
|
+
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1591
|
+
_triviaLog: ctx._triviaLog,
|
|
1592
|
+
_rootTriviaLog: ctx._rootTriviaLog,
|
|
1593
|
+
_fields: ctx._fields,
|
|
1594
|
+
_cstBuf: ctx._cstBuf,
|
|
1595
|
+
_tolerant: ctx._tolerant,
|
|
1596
|
+
_sync: ctx._sync
|
|
1597
|
+
};
|
|
1598
|
+
ctx._probe = void 0;
|
|
1599
|
+
ctx._errors = void 0;
|
|
1600
|
+
ctx._cstLeaves = void 0;
|
|
1601
|
+
ctx._cstChildren = void 0;
|
|
1602
|
+
ctx._cstRawChildren = void 0;
|
|
1603
|
+
ctx._cstTriviaLog = void 0;
|
|
1604
|
+
ctx._triviaLog = void 0;
|
|
1605
|
+
ctx._rootTriviaLog = void 0;
|
|
1606
|
+
ctx._fields = void 0;
|
|
1607
|
+
ctx._cstBuf = void 0;
|
|
1608
|
+
ctx._tolerant = void 0;
|
|
1609
|
+
ctx._sync = void 0;
|
|
1610
|
+
try {
|
|
1611
|
+
return sentinel.parse(input, pos, ctx).ok;
|
|
1612
|
+
} finally {
|
|
1613
|
+
ctx._probe = s._probe;
|
|
1614
|
+
ctx._errors = s._errors;
|
|
1615
|
+
ctx._cstLeaves = s._cstLeaves;
|
|
1616
|
+
ctx._cstChildren = s._cstChildren;
|
|
1617
|
+
ctx._cstRawChildren = s._cstRawChildren;
|
|
1618
|
+
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1619
|
+
ctx._triviaLog = s._triviaLog;
|
|
1620
|
+
ctx._rootTriviaLog = s._rootTriviaLog;
|
|
1621
|
+
ctx._fields = s._fields;
|
|
1622
|
+
ctx._cstBuf = s._cstBuf;
|
|
1623
|
+
ctx._tolerant = s._tolerant;
|
|
1624
|
+
ctx._sync = s._sync;
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
function orSentinel(a, b) {
|
|
1628
|
+
if (b === void 0) return a;
|
|
1629
|
+
return {
|
|
1630
|
+
_tag: "orSentinel",
|
|
1631
|
+
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1632
|
+
_def: { tag: "unknown" },
|
|
1633
|
+
parse(input, pos, ctx) {
|
|
1634
|
+
const ra = a.parse(input, pos, ctx);
|
|
1635
|
+
if (ra.ok) return ra;
|
|
1636
|
+
return b.parse(input, pos, ctx);
|
|
1637
|
+
}
|
|
1638
|
+
};
|
|
1639
|
+
}
|
|
1640
|
+
function firstSetSentinel(fs2) {
|
|
1641
|
+
if (fs2.kind !== "ranges" || fs2.ranges.length === 0) return null;
|
|
1642
|
+
const ranges = fs2.ranges;
|
|
1643
|
+
return {
|
|
1644
|
+
_tag: "firstSetSentinel",
|
|
1645
|
+
_meta: { firstSet: fs2, canMatchNewline: false, isTrivia: false },
|
|
1646
|
+
_def: { tag: "unknown" },
|
|
1647
|
+
parse(input, pos) {
|
|
1648
|
+
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
1649
|
+
if (code !== void 0) {
|
|
1650
|
+
for (const r of ranges) {
|
|
1651
|
+
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
1655
|
+
}
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
function recoverScan(input, from, ctx, sync, expected) {
|
|
1659
|
+
let scanPos = from;
|
|
1660
|
+
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1661
|
+
const span = { start: from, end: scanPos };
|
|
1662
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
1663
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1664
|
+
ctx._errors?.push(error);
|
|
1665
|
+
return { error, end: scanPos };
|
|
1666
|
+
}
|
|
1667
|
+
function matchesAt(sentinel, input, pos, ctx) {
|
|
1668
|
+
return probeAt(sentinel, input, pos, ctx);
|
|
1669
|
+
}
|
|
1670
|
+
function captureError(ctx, error) {
|
|
1671
|
+
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
// src/combinators/sequence.ts
|
|
1675
|
+
function sequence(...parsers) {
|
|
1676
|
+
const meta = {
|
|
1677
|
+
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
1678
|
+
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
1679
|
+
firstSet: sequenceFirstSet(parsers),
|
|
1680
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1681
|
+
isTrivia: false
|
|
1682
|
+
};
|
|
1683
|
+
const def = { tag: "sequence", parsers };
|
|
1684
|
+
let followSentinels;
|
|
1685
|
+
function parseTolerant(input, pos, ctx) {
|
|
1686
|
+
followSentinels ??= parsers.map((_, i) => {
|
|
1687
|
+
const fs2 = parsers.slice(i + 1).reduce(
|
|
1688
|
+
(acc, p) => union(acc, firstSetOf(p)),
|
|
1689
|
+
{ kind: "empty" }
|
|
1690
|
+
);
|
|
1691
|
+
return firstSetSentinel(fs2);
|
|
1692
|
+
});
|
|
1693
|
+
const values = def.valueUnused ? void 0 : [];
|
|
1694
|
+
let cur = pos;
|
|
1695
|
+
const inheritedSync = ctx._sync;
|
|
1696
|
+
try {
|
|
1697
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1698
|
+
ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
1699
|
+
if (ctx.trivia && i > 0) {
|
|
1700
|
+
const mark = saveTriviaMark(ctx);
|
|
1701
|
+
let scanEnd;
|
|
1702
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
1703
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1704
|
+
scan.commit();
|
|
1705
|
+
scanEnd = scan.end;
|
|
1706
|
+
} else {
|
|
1707
|
+
scanEnd = advanceTrivia(input, cur, ctx);
|
|
1708
|
+
}
|
|
1709
|
+
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
1710
|
+
if (!result2.ok) return result2;
|
|
1711
|
+
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
1712
|
+
else rollbackTrivia(ctx, mark);
|
|
1713
|
+
if (values !== void 0) values.push(result2.value);
|
|
1714
|
+
continue;
|
|
1715
|
+
}
|
|
1716
|
+
const result = parsers[i].parse(input, cur, ctx);
|
|
1717
|
+
if (!result.ok) return result;
|
|
1718
|
+
if (values !== void 0) values.push(result.value);
|
|
1719
|
+
cur = result.span.end;
|
|
1720
|
+
}
|
|
1721
|
+
} finally {
|
|
1722
|
+
ctx._sync = inheritedSync;
|
|
1723
|
+
}
|
|
1724
|
+
return {
|
|
1725
|
+
ok: true,
|
|
1726
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1727
|
+
value: values ?? void 0,
|
|
1728
|
+
span: { start: pos, end: cur }
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1731
|
+
return {
|
|
1732
|
+
_tag: "sequence",
|
|
1733
|
+
_meta: meta,
|
|
1734
|
+
_def: def,
|
|
1735
|
+
parse(input, pos, ctx) {
|
|
1736
|
+
if (ctx._tolerant) return parseTolerant(input, pos, ctx);
|
|
1737
|
+
const values = def.valueUnused ? void 0 : [];
|
|
1738
|
+
let cur = pos;
|
|
1739
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1740
|
+
if (ctx.trivia && i > 0) {
|
|
1741
|
+
let scanEnd;
|
|
1742
|
+
let mark = saveTriviaMark(ctx);
|
|
1743
|
+
if (needsDeferredTriviaCommit(ctx)) {
|
|
1744
|
+
const scan = scanTrivia(input, cur, ctx);
|
|
1745
|
+
scan.commit();
|
|
1746
|
+
scanEnd = scan.end;
|
|
1747
|
+
} else {
|
|
1748
|
+
scanEnd = advanceTrivia(input, cur, ctx);
|
|
1749
|
+
}
|
|
1750
|
+
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
1751
|
+
if (!result2.ok) return result2;
|
|
1752
|
+
if (result2.span.end > scanEnd) {
|
|
1753
|
+
cur = result2.span.end;
|
|
1754
|
+
} else {
|
|
1755
|
+
rollbackTrivia(ctx, mark);
|
|
1756
|
+
}
|
|
1757
|
+
if (values !== void 0) values.push(result2.value);
|
|
1758
|
+
continue;
|
|
1759
|
+
}
|
|
1760
|
+
const result = parsers[i].parse(input, cur, ctx);
|
|
1761
|
+
if (!result.ok) return result;
|
|
1762
|
+
if (values !== void 0) values.push(result.value);
|
|
1763
|
+
cur = result.span.end;
|
|
1764
|
+
}
|
|
1765
|
+
return {
|
|
1766
|
+
ok: true,
|
|
1767
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1768
|
+
value: values ?? void 0,
|
|
1769
|
+
span: { start: pos, end: cur }
|
|
1770
|
+
};
|
|
1771
|
+
}
|
|
1772
|
+
};
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
// src/combinators/expect.ts
|
|
1776
|
+
function deriveExpected(c) {
|
|
1777
|
+
return [...new Set(derive(c, /* @__PURE__ */ new Set()))];
|
|
1778
|
+
}
|
|
1779
|
+
function derive(c, seen) {
|
|
1780
|
+
const deriveExpected2 = (p) => derive(p, seen);
|
|
1781
|
+
const def = c._def;
|
|
1782
|
+
switch (def.tag) {
|
|
1783
|
+
case "literal":
|
|
1784
|
+
return [JSON.stringify(def.value)];
|
|
1785
|
+
case "regex":
|
|
1786
|
+
return [`/${def.source}/`];
|
|
1787
|
+
case "keywords":
|
|
1788
|
+
return def.words.map((w) => JSON.stringify(w));
|
|
1789
|
+
case "label":
|
|
1790
|
+
return [def.label];
|
|
1791
|
+
case "choice":
|
|
1792
|
+
return def.parsers.flatMap(deriveExpected2);
|
|
1793
|
+
case "dispatch":
|
|
1794
|
+
return deriveExpected2(def.selector);
|
|
1795
|
+
// Union through the NULLABLE prefix, mirroring `sequenceFirstSet`. A leading
|
|
1796
|
+
// `optional(…)`/`many(…)` can match nothing, so the term after it is equally
|
|
1797
|
+
// able to fail first — deriving from term 0 alone named a token the parse
|
|
1798
|
+
// never actually required. A leading `not(…)` is zero-width and contributes
|
|
1799
|
+
// nothing (its own expectation is about what must NOT be here), but it is
|
|
1800
|
+
// nullable, so keep scanning past it. Stop at the first term that must match.
|
|
1801
|
+
case "sequence": {
|
|
1802
|
+
const out = [];
|
|
1803
|
+
for (const term of def.parsers) {
|
|
1804
|
+
if (!isZeroWidthAssertion(term)) out.push(...deriveExpected2(term));
|
|
1805
|
+
if (!matchesEmpty(term)) break;
|
|
1806
|
+
}
|
|
1807
|
+
return out;
|
|
1808
|
+
}
|
|
1809
|
+
case "attempt":
|
|
1810
|
+
return deriveExpected2(def.parser);
|
|
1811
|
+
// Delegating wrappers whose first-token failure is their inner parser's — must
|
|
1812
|
+
// pass through so a start-failure (and the first-set-miss fast-path in attempt/
|
|
1813
|
+
// node, which reads this) names the real expected token, not the wrapper tag.
|
|
1814
|
+
case "field":
|
|
1815
|
+
case "withCtx":
|
|
1816
|
+
case "recover":
|
|
1817
|
+
return deriveExpected2(def.parser);
|
|
1818
|
+
case "skip":
|
|
1819
|
+
return deriveExpected2(def.main);
|
|
1820
|
+
case "expect":
|
|
1821
|
+
return def.expected;
|
|
1822
|
+
case "node":
|
|
1823
|
+
case "grammar":
|
|
1824
|
+
case "trivia":
|
|
1825
|
+
case "token":
|
|
1826
|
+
case "leaf":
|
|
1827
|
+
case "optional":
|
|
1828
|
+
case "many":
|
|
1829
|
+
case "oneOrMore":
|
|
1830
|
+
case "transform":
|
|
1831
|
+
case "not":
|
|
1832
|
+
case "peek":
|
|
1833
|
+
return deriveExpected2(def.parser);
|
|
1834
|
+
case "routed":
|
|
1835
|
+
return ["routed()"];
|
|
1836
|
+
case "lazy": {
|
|
1837
|
+
const name = c._ruleName;
|
|
1838
|
+
if (seen.has(c)) return name ? [name] : [];
|
|
1839
|
+
seen.add(c);
|
|
1840
|
+
try {
|
|
1841
|
+
return deriveExpected2(def.thunk());
|
|
1842
|
+
} catch {
|
|
1843
|
+
return name ? [name] : [];
|
|
1844
|
+
} finally {
|
|
1845
|
+
seen.delete(c);
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
default:
|
|
1849
|
+
return [];
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
function expect(combinator, label2) {
|
|
1853
|
+
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
1854
|
+
const meta = {
|
|
1855
|
+
firstSet: combinator._meta.firstSet,
|
|
1856
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1857
|
+
isTrivia: false
|
|
1858
|
+
};
|
|
1859
|
+
return {
|
|
1860
|
+
_tag: "expect",
|
|
1861
|
+
_meta: meta,
|
|
1862
|
+
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1863
|
+
parse(input, pos, ctx) {
|
|
1864
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1865
|
+
if (result.ok) return result;
|
|
1866
|
+
const span = { start: pos, end: pos };
|
|
1867
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1868
|
+
ctx._errors?.push(error);
|
|
1869
|
+
if (ctx._tolerant) captureError(ctx, error);
|
|
1870
|
+
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
// src/combinators/choice.ts
|
|
1876
|
+
function choice(...args) {
|
|
1877
|
+
const parsers = args.map((a) => "gate" in a ? a.combinator : a);
|
|
1878
|
+
const gates = args.map((a) => "gate" in a ? a.gate : null);
|
|
1879
|
+
const hasGates = gates.some((g) => g !== null);
|
|
1880
|
+
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
1881
|
+
let combined = { kind: "empty" };
|
|
1882
|
+
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
1883
|
+
const meta = {
|
|
1884
|
+
firstSet: combined,
|
|
1885
|
+
canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
|
|
1886
|
+
isTrivia: false,
|
|
1887
|
+
disjoint
|
|
1888
|
+
};
|
|
1889
|
+
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
1890
|
+
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1891
|
+
let greedyLitMap = null;
|
|
1892
|
+
let sortedParsers = null;
|
|
1893
|
+
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
1894
|
+
if (strategy?.tag === "greedyClassify") {
|
|
1895
|
+
greedyLitMap = /* @__PURE__ */ new Map();
|
|
1896
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1897
|
+
if (i === strategy.superIndex) continue;
|
|
1898
|
+
const litVal = getCoreLiteralValue(parsers[i]);
|
|
1899
|
+
if (litVal !== null) greedyLitMap.set(litVal, i);
|
|
1900
|
+
}
|
|
1901
|
+
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
1902
|
+
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
1903
|
+
}
|
|
1904
|
+
return {
|
|
1905
|
+
_tag: "choice",
|
|
1906
|
+
_meta: meta,
|
|
1907
|
+
_def: {
|
|
1908
|
+
tag: "choice",
|
|
1909
|
+
parsers,
|
|
1910
|
+
gates,
|
|
1911
|
+
disjoint,
|
|
1912
|
+
strategy: strategy ?? { tag: "firstMatch" },
|
|
1913
|
+
autoNot
|
|
1914
|
+
},
|
|
1915
|
+
parse(input, pos, ctx) {
|
|
1916
|
+
const expected = [];
|
|
1917
|
+
if (disjoint && pos < input.length) {
|
|
1918
|
+
const code = input.codePointAt(pos);
|
|
1919
|
+
let idx = code < 128 ? asciiDispatch[code] : -1;
|
|
1920
|
+
if (idx < 0) {
|
|
1921
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1922
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
1923
|
+
idx = i;
|
|
1924
|
+
break;
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
if (idx >= 0) {
|
|
1929
|
+
const gate2 = gates[idx];
|
|
1930
|
+
if (gate2 && !gate2(ctx.state)) {
|
|
1931
|
+
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1932
|
+
}
|
|
1933
|
+
const result = parsers[idx].parse(input, pos, ctx);
|
|
1934
|
+
if (result.ok) return result;
|
|
1935
|
+
expected.push(...result.expected);
|
|
1936
|
+
if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
|
|
1937
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1938
|
+
}
|
|
1939
|
+
return {
|
|
1940
|
+
ok: false,
|
|
1941
|
+
expected: parsers.flatMap((p) => {
|
|
1942
|
+
const r = p.parse(input, pos, ctx);
|
|
1943
|
+
return r.ok ? [] : r.expected;
|
|
1944
|
+
}),
|
|
1945
|
+
span: { start: pos, end: pos }
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
if (strategy?.tag === "greedyClassify") {
|
|
1949
|
+
const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
|
|
1950
|
+
if (!superResult.ok) return superResult;
|
|
1951
|
+
const end = superResult.span.end;
|
|
1952
|
+
const litIdx = greedyLitMap.get(input.slice(pos, end));
|
|
1953
|
+
if (litIdx !== void 0) {
|
|
1954
|
+
const litVal = getCoreLiteralValue(parsers[litIdx]);
|
|
1955
|
+
const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
|
|
1956
|
+
return { ok: true, value, span: { start: pos, end } };
|
|
1957
|
+
}
|
|
1958
|
+
return superResult;
|
|
1959
|
+
}
|
|
1960
|
+
if (strategy?.tag === "literalsLongestFirst") {
|
|
1961
|
+
for (const p of sortedParsers) {
|
|
1962
|
+
const r = p.parse(input, pos, ctx);
|
|
1963
|
+
if (r.ok) return r;
|
|
1964
|
+
expected.push(...r.expected);
|
|
1965
|
+
}
|
|
1966
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1967
|
+
}
|
|
1968
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1969
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
1970
|
+
const mark = saveTriviaMark(ctx);
|
|
1971
|
+
const result = parsers[i].parse(input, pos, ctx);
|
|
1972
|
+
if (!result.ok) {
|
|
1973
|
+
rollbackTrivia(ctx, mark);
|
|
1974
|
+
expected.push(...result.expected);
|
|
1975
|
+
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
1976
|
+
continue;
|
|
1977
|
+
}
|
|
1978
|
+
const checks = autoNot[i];
|
|
1979
|
+
if (checks && autoNotFires(input, result.span.end, checks)) {
|
|
1980
|
+
rollbackTrivia(ctx, mark);
|
|
1981
|
+
continue;
|
|
1982
|
+
}
|
|
1983
|
+
return result;
|
|
1984
|
+
}
|
|
1985
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1986
|
+
}
|
|
1987
|
+
};
|
|
1988
|
+
}
|
|
1989
|
+
function detectStrategy(parsers) {
|
|
1990
|
+
const regexIndices = [];
|
|
1991
|
+
const literalIndices = [];
|
|
1992
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1993
|
+
if (getCoreRegexDef(parsers[i]) !== null) regexIndices.push(i);
|
|
1994
|
+
else if (getCoreLiteralValue(parsers[i]) !== null) literalIndices.push(i);
|
|
1995
|
+
}
|
|
1996
|
+
if (regexIndices.length === 1 && literalIndices.length === parsers.length - 1 && literalIndices.length > 0) {
|
|
1997
|
+
const superIndex = regexIndices[0];
|
|
1998
|
+
const regexDef = getCoreRegexDef(parsers[superIndex]);
|
|
1999
|
+
const flags = "y" + regexDef.flags.replace(/[gy]/g, "");
|
|
2000
|
+
const re = new RegExp(regexDef.source, flags);
|
|
2001
|
+
const allSubsumed = literalIndices.every((i) => {
|
|
2002
|
+
const litVal = getCoreLiteralValue(parsers[i]);
|
|
2003
|
+
re.lastIndex = 0;
|
|
2004
|
+
const m = re.exec(litVal);
|
|
2005
|
+
return m !== null && m[0] === litVal;
|
|
2006
|
+
});
|
|
2007
|
+
if (allSubsumed) return { tag: "greedyClassify", superIndex };
|
|
2008
|
+
}
|
|
2009
|
+
if (parsers.length === literalIndices.length) {
|
|
2010
|
+
const sortedIndices = [...literalIndices].sort(
|
|
2011
|
+
(a, b) => getCoreLiteralValue(parsers[b]).length - getCoreLiteralValue(parsers[a]).length
|
|
2012
|
+
);
|
|
2013
|
+
return { tag: "literalsLongestFirst", sortedIndices };
|
|
2014
|
+
}
|
|
2015
|
+
const shared = detectSharedPrefix(parsers);
|
|
2016
|
+
if (shared !== null) return shared;
|
|
2017
|
+
return { tag: "firstMatch" };
|
|
2018
|
+
}
|
|
2019
|
+
function bareLeadingTermKey(term) {
|
|
2020
|
+
const d = term._def;
|
|
2021
|
+
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
2022
|
+
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
2023
|
+
return null;
|
|
2024
|
+
}
|
|
2025
|
+
function detectSharedPrefix(parsers) {
|
|
2026
|
+
if (parsers.length < 2) return null;
|
|
2027
|
+
let key = null;
|
|
2028
|
+
let prefix = null;
|
|
2029
|
+
const members = [];
|
|
2030
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2031
|
+
const term0 = leadingTermOfArm(parsers[i]);
|
|
2032
|
+
if (term0 === null) return null;
|
|
2033
|
+
const k = bareLeadingTermKey(term0);
|
|
2034
|
+
if (k === null) return null;
|
|
2035
|
+
if (key === null) {
|
|
2036
|
+
key = k;
|
|
2037
|
+
prefix = term0;
|
|
2038
|
+
} else if (k !== key) return null;
|
|
2039
|
+
members.push(i);
|
|
2040
|
+
}
|
|
2041
|
+
if (prefix === null || members.length < 2) return null;
|
|
2042
|
+
return { tag: "sharedPrefix", prefix, members };
|
|
2043
|
+
}
|
|
2044
|
+
function leadingTermOfArm(arm) {
|
|
2045
|
+
let d = arm._def;
|
|
2046
|
+
for (; ; ) {
|
|
2047
|
+
if (d.tag === "node" || d.tag === "grammar" || d.tag === "transform" || d.tag === "label") {
|
|
2048
|
+
d = d.parser._def;
|
|
2049
|
+
continue;
|
|
2050
|
+
}
|
|
2051
|
+
break;
|
|
2052
|
+
}
|
|
2053
|
+
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
2054
|
+
return d.parsers[0];
|
|
2055
|
+
}
|
|
2056
|
+
function computeAutoNot(parsers) {
|
|
2057
|
+
return parsers.map((p, i) => {
|
|
2058
|
+
const litVal = getCoreLiteralValue(p);
|
|
2059
|
+
if (litVal === null) return null;
|
|
2060
|
+
const checks = [];
|
|
2061
|
+
for (let j = i + 1; j < parsers.length; j++) {
|
|
2062
|
+
const other = parsers[j];
|
|
2063
|
+
const otherLit = getCoreLiteralValue(other);
|
|
2064
|
+
if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
|
|
2065
|
+
checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
|
|
2066
|
+
continue;
|
|
2067
|
+
}
|
|
2068
|
+
const regexDef = getCoreRegexDef(other);
|
|
2069
|
+
if (regexDef !== null) {
|
|
2070
|
+
const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
|
|
2071
|
+
if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
|
|
2072
|
+
}
|
|
1940
2073
|
}
|
|
1941
|
-
return
|
|
1942
|
-
};
|
|
2074
|
+
return checks.length > 0 ? checks : null;
|
|
2075
|
+
});
|
|
1943
2076
|
}
|
|
1944
|
-
function
|
|
1945
|
-
const
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
i++;
|
|
1952
|
-
continue;
|
|
1953
|
-
}
|
|
1954
|
-
if (inClass) {
|
|
1955
|
-
if (c === "]") inClass = false;
|
|
1956
|
-
continue;
|
|
1957
|
-
}
|
|
1958
|
-
if (c === "[") inClass = true;
|
|
1959
|
-
else if (c === "(") return null;
|
|
1960
|
-
else if (c === "|") {
|
|
1961
|
-
arms.push(body.slice(start, i));
|
|
1962
|
-
start = i + 1;
|
|
2077
|
+
function autoNotFires(input, end, checks) {
|
|
2078
|
+
for (const check of checks) {
|
|
2079
|
+
if (check.kind === "firstSet") {
|
|
2080
|
+
const code = end < input.length ? input.codePointAt(end) ?? -1 : -1;
|
|
2081
|
+
if (inFirstSet(code, check.set)) return true;
|
|
2082
|
+
} else {
|
|
2083
|
+
if (input.startsWith(check.value, end)) return true;
|
|
1963
2084
|
}
|
|
1964
2085
|
}
|
|
1965
|
-
|
|
1966
|
-
return arms;
|
|
2086
|
+
return false;
|
|
1967
2087
|
}
|
|
1968
|
-
function
|
|
1969
|
-
const
|
|
1970
|
-
if (!
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
2088
|
+
function getCoreLiteralValue(p) {
|
|
2089
|
+
const def = p._def;
|
|
2090
|
+
if (def.tag === "literal" && !def.caseInsensitive) return def.value;
|
|
2091
|
+
if (def.tag === "transform") return getCoreLiteralValue(def.parser);
|
|
2092
|
+
return null;
|
|
2093
|
+
}
|
|
2094
|
+
function getCoreRegexDef(p) {
|
|
2095
|
+
const def = p._def;
|
|
2096
|
+
if (def.tag === "regex") return { source: def.source, flags: def.flags };
|
|
2097
|
+
if (def.tag === "transform") return getCoreRegexDef(def.parser);
|
|
2098
|
+
if (def.tag === "label") return getCoreRegexDef(def.parser);
|
|
2099
|
+
return null;
|
|
2100
|
+
}
|
|
2101
|
+
function applyTransforms(p, value, span) {
|
|
2102
|
+
const def = p._def;
|
|
2103
|
+
if (def.tag === "transform") {
|
|
2104
|
+
const inner = applyTransforms(def.parser, value, span);
|
|
2105
|
+
return def.fn(inner, span);
|
|
1978
2106
|
}
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
2107
|
+
return value;
|
|
2108
|
+
}
|
|
2109
|
+
function continuationFirstSet(lit, source, flags) {
|
|
2110
|
+
const re = new RegExp(source, "y" + flags.replace(/[gy]/g, ""));
|
|
2111
|
+
re.lastIndex = 0;
|
|
2112
|
+
const base = re.exec(lit);
|
|
2113
|
+
if (!base || base[0] !== lit) return null;
|
|
2114
|
+
const contCodes = [];
|
|
2115
|
+
for (let code = 1; code < 128; code++) {
|
|
2116
|
+
re.lastIndex = 0;
|
|
2117
|
+
const m = re.exec(lit + String.fromCharCode(code));
|
|
2118
|
+
if (m && m[0].length > lit.length) contCodes.push(code);
|
|
1984
2119
|
}
|
|
1985
|
-
if (
|
|
1986
|
-
|
|
2120
|
+
if (contCodes.length === 0) return null;
|
|
2121
|
+
return codesToFirstSet(contCodes);
|
|
2122
|
+
}
|
|
2123
|
+
function codesToFirstSet(codes) {
|
|
2124
|
+
codes.sort((a, b) => a - b);
|
|
2125
|
+
const ranges = [];
|
|
2126
|
+
let lo = codes[0], hi = codes[0];
|
|
2127
|
+
for (let i = 1; i < codes.length; i++) {
|
|
2128
|
+
if (codes[i] === hi + 1) {
|
|
2129
|
+
hi = codes[i];
|
|
2130
|
+
} else {
|
|
2131
|
+
ranges.push({ lo, hi });
|
|
2132
|
+
lo = hi = codes[i];
|
|
2133
|
+
}
|
|
1987
2134
|
}
|
|
1988
|
-
|
|
1989
|
-
return
|
|
2135
|
+
ranges.push({ lo, hi });
|
|
2136
|
+
return { kind: "ranges", ranges };
|
|
1990
2137
|
}
|
|
1991
|
-
function
|
|
1992
|
-
|
|
2138
|
+
function inFirstSet(code, fs2) {
|
|
2139
|
+
if (fs2.kind === "any") return true;
|
|
2140
|
+
if (fs2.kind === "empty") return false;
|
|
2141
|
+
for (const r of fs2.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
2142
|
+
return false;
|
|
1993
2143
|
}
|
|
1994
|
-
function
|
|
1995
|
-
if (
|
|
1996
|
-
|
|
1997
|
-
|
|
2144
|
+
function areDisjoint(sets) {
|
|
2145
|
+
if (sets.some((s) => s.kind === "any")) return false;
|
|
2146
|
+
for (let i = 0; i < sets.length; i++)
|
|
2147
|
+
for (let j = i + 1; j < sets.length; j++)
|
|
2148
|
+
if (intersects(sets[i], sets[j])) return false;
|
|
2149
|
+
return true;
|
|
1998
2150
|
}
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
isTrivia: false
|
|
2008
|
-
};
|
|
2009
|
-
const def = { tag: "sequence", parsers };
|
|
2010
|
-
let followSentinels;
|
|
2011
|
-
function parseTolerant(input, pos, ctx) {
|
|
2012
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
2013
|
-
const fs2 = parsers.slice(i + 1).reduce(
|
|
2014
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
2015
|
-
{ kind: "empty" }
|
|
2016
|
-
);
|
|
2017
|
-
return firstSetSentinel(fs2);
|
|
2018
|
-
});
|
|
2019
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2020
|
-
let cur = pos;
|
|
2021
|
-
const inheritedSync = ctx._sync;
|
|
2022
|
-
try {
|
|
2023
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
2024
|
-
ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
2025
|
-
if (ctx.trivia && i > 0) {
|
|
2026
|
-
const mark = saveTriviaMark(ctx);
|
|
2027
|
-
let scanEnd;
|
|
2028
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2029
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
2030
|
-
scan.commit();
|
|
2031
|
-
scanEnd = scan.end;
|
|
2032
|
-
} else {
|
|
2033
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2034
|
-
}
|
|
2035
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2036
|
-
if (!result2.ok) return result2;
|
|
2037
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2038
|
-
else rollbackTrivia(ctx, mark);
|
|
2039
|
-
if (values !== void 0) values.push(result2.value);
|
|
2040
|
-
continue;
|
|
2041
|
-
}
|
|
2042
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2043
|
-
if (!result.ok) return result;
|
|
2044
|
-
if (values !== void 0) values.push(result.value);
|
|
2045
|
-
cur = result.span.end;
|
|
2151
|
+
function buildAsciiDispatch(parsers) {
|
|
2152
|
+
const table = Array(128).fill(-1);
|
|
2153
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2154
|
+
const fs2 = parsers[i]._meta.firstSet;
|
|
2155
|
+
if (fs2.kind !== "ranges") continue;
|
|
2156
|
+
for (const { lo, hi } of fs2.ranges) {
|
|
2157
|
+
for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
|
|
2158
|
+
table[code] = i;
|
|
2046
2159
|
}
|
|
2047
|
-
} finally {
|
|
2048
|
-
ctx._sync = inheritedSync;
|
|
2049
2160
|
}
|
|
2050
|
-
return {
|
|
2051
|
-
ok: true,
|
|
2052
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2053
|
-
value: values ?? void 0,
|
|
2054
|
-
span: { start: pos, end: cur }
|
|
2055
|
-
};
|
|
2056
2161
|
}
|
|
2057
|
-
return
|
|
2058
|
-
_tag: "sequence",
|
|
2059
|
-
_meta: meta,
|
|
2060
|
-
_def: def,
|
|
2061
|
-
parse(input, pos, ctx) {
|
|
2062
|
-
if (ctx._tolerant) return parseTolerant(input, pos, ctx);
|
|
2063
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2064
|
-
let cur = pos;
|
|
2065
|
-
for (let i = 0; i < parsers.length; i++) {
|
|
2066
|
-
if (ctx.trivia && i > 0) {
|
|
2067
|
-
let scanEnd;
|
|
2068
|
-
let mark = saveTriviaMark(ctx);
|
|
2069
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2070
|
-
const scan = scanTrivia(input, cur, ctx);
|
|
2071
|
-
scan.commit();
|
|
2072
|
-
scanEnd = scan.end;
|
|
2073
|
-
} else {
|
|
2074
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2075
|
-
}
|
|
2076
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2077
|
-
if (!result2.ok) return result2;
|
|
2078
|
-
if (result2.span.end > scanEnd) {
|
|
2079
|
-
cur = result2.span.end;
|
|
2080
|
-
} else {
|
|
2081
|
-
rollbackTrivia(ctx, mark);
|
|
2082
|
-
}
|
|
2083
|
-
if (values !== void 0) values.push(result2.value);
|
|
2084
|
-
continue;
|
|
2085
|
-
}
|
|
2086
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2087
|
-
if (!result.ok) return result;
|
|
2088
|
-
if (values !== void 0) values.push(result.value);
|
|
2089
|
-
cur = result.span.end;
|
|
2090
|
-
}
|
|
2091
|
-
return {
|
|
2092
|
-
ok: true,
|
|
2093
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2094
|
-
value: values ?? void 0,
|
|
2095
|
-
span: { start: pos, end: cur }
|
|
2096
|
-
};
|
|
2097
|
-
}
|
|
2098
|
-
};
|
|
2162
|
+
return table;
|
|
2099
2163
|
}
|
|
2100
2164
|
|
|
2101
2165
|
// src/combinators/dispatch.ts
|
|
@@ -2355,10 +2419,12 @@ function attempt(parser2) {
|
|
|
2355
2419
|
}
|
|
2356
2420
|
const mark = saveCstMark(ctx);
|
|
2357
2421
|
const log = ctx._triviaLog?.length;
|
|
2422
|
+
const rootLog = ctx._rootTriviaLog?.length;
|
|
2358
2423
|
const result = parser2.parse(input, pos, ctx);
|
|
2359
2424
|
if (result.ok) return result;
|
|
2360
2425
|
rollbackCstCapture(ctx, mark);
|
|
2361
2426
|
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
2427
|
+
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
2362
2428
|
if (result.committed) return result;
|
|
2363
2429
|
return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
|
|
2364
2430
|
}
|
|
@@ -2762,18 +2828,37 @@ function createParseLineContext(input, pos) {
|
|
|
2762
2828
|
}
|
|
2763
2829
|
function parser(opts, root) {
|
|
2764
2830
|
const clearTrivia = opts.trivia === null;
|
|
2831
|
+
const opaqueRootCapture = opts.rootCapture === "opaque";
|
|
2832
|
+
if (opaqueRootCapture && opts.trivia === void 0) {
|
|
2833
|
+
throw new TypeError("parser({ rootCapture: 'opaque' }) requires an explicit trivia scope.");
|
|
2834
|
+
}
|
|
2765
2835
|
return {
|
|
2766
2836
|
_tag: "grammar",
|
|
2767
|
-
_meta:
|
|
2837
|
+
_meta: {
|
|
2838
|
+
...root._meta,
|
|
2839
|
+
// Trivia classification describes this grammar's own active trivia
|
|
2840
|
+
// scope. A directly nested grammar may have classified trivia of its
|
|
2841
|
+
// own, but that must not advertise classification for this wrapper.
|
|
2842
|
+
triviaKindLabels: void 0,
|
|
2843
|
+
rootTriviaClassified: void 0,
|
|
2844
|
+
...opts.trivia?._meta?.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {},
|
|
2845
|
+
...opts.trivia?._meta?.rootTriviaClassified ? { rootTriviaClassified: true } : {}
|
|
2846
|
+
},
|
|
2768
2847
|
_def: {
|
|
2769
2848
|
tag: "grammar",
|
|
2770
2849
|
parser: root,
|
|
2771
2850
|
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2772
2851
|
clearTrivia,
|
|
2852
|
+
...opaqueRootCapture ? { rootCapture: "opaque" } : {},
|
|
2773
2853
|
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2774
2854
|
trackLines: opts.trackLines ?? false
|
|
2775
2855
|
},
|
|
2776
2856
|
parse(input, pos, _ctx) {
|
|
2857
|
+
if (_ctx?._rootTriviaStrictScopes && opts.trivia !== void 0 && opts.trivia !== null && !opts.trivia._meta.rootTriviaClassified && !opaqueRootCapture) {
|
|
2858
|
+
throw new TypeError(
|
|
2859
|
+
"parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'."
|
|
2860
|
+
);
|
|
2861
|
+
}
|
|
2777
2862
|
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2778
2863
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2779
2864
|
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
@@ -2796,7 +2881,11 @@ function parser(opts, root) {
|
|
|
2796
2881
|
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2797
2882
|
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2798
2883
|
// (capture all).
|
|
2799
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
2884
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {},
|
|
2885
|
+
// This is a property of the local trivia scope, not a post-parse filter:
|
|
2886
|
+
// nested recognition can still skip its trivia, but selected root rows
|
|
2887
|
+
// must never be written for an explicitly opaque region.
|
|
2888
|
+
...opaqueRootCapture ? { _rootTriviaCapture: false } : {}
|
|
2800
2889
|
};
|
|
2801
2890
|
const result = root.parse(input, pos ?? 0, ctx);
|
|
2802
2891
|
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
@@ -3449,6 +3538,25 @@ function trivia(combinator) {
|
|
|
3449
3538
|
parse: combinator.parse.bind(combinator)
|
|
3450
3539
|
};
|
|
3451
3540
|
}
|
|
3541
|
+
function classifiedTrivia(arms) {
|
|
3542
|
+
const entries = Object.entries(arms);
|
|
3543
|
+
if (entries.length === 0) {
|
|
3544
|
+
throw new TypeError("classifiedTrivia() requires at least one named trivia arm.");
|
|
3545
|
+
}
|
|
3546
|
+
for (let i = 0; i < entries.length; i++) {
|
|
3547
|
+
const [name, arm] = entries[i];
|
|
3548
|
+
const first = arm._meta.firstSet;
|
|
3549
|
+
if (matchesEmpty(arm) || first.kind !== "ranges" || first.ranges.length === 0) {
|
|
3550
|
+
throw new TypeError(
|
|
3551
|
+
`classifiedTrivia(): ${JSON.stringify(name)} must be non-nullable with a concrete finite first set.`
|
|
3552
|
+
);
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3555
|
+
const labeledArms = entries.map(([name, arm]) => label(name, arm));
|
|
3556
|
+
const result = trivia(oneOrMore(choice(...labeledArms)));
|
|
3557
|
+
result._meta.rootTriviaClassified = true;
|
|
3558
|
+
return result;
|
|
3559
|
+
}
|
|
3452
3560
|
function label(name, combinator) {
|
|
3453
3561
|
return {
|
|
3454
3562
|
_tag: combinator._tag,
|
|
@@ -3495,6 +3603,7 @@ function token(root) {
|
|
|
3495
3603
|
const savedRaw = ctx._cstRawChildren;
|
|
3496
3604
|
const savedTriviaLog = ctx._cstTriviaLog;
|
|
3497
3605
|
const savedOuterTriviaLog = ctx._triviaLog;
|
|
3606
|
+
const savedRootTriviaLog = ctx._rootTriviaLog;
|
|
3498
3607
|
const wasCapturing = cstCaptureActive(ctx);
|
|
3499
3608
|
ctx.trivia = void 0;
|
|
3500
3609
|
ctx.triviaKindLabels = void 0;
|
|
@@ -3504,6 +3613,7 @@ function token(root) {
|
|
|
3504
3613
|
ctx._cstRawChildren = void 0;
|
|
3505
3614
|
ctx._cstTriviaLog = void 0;
|
|
3506
3615
|
delete ctx._triviaLog;
|
|
3616
|
+
delete ctx._rootTriviaLog;
|
|
3507
3617
|
let result;
|
|
3508
3618
|
try {
|
|
3509
3619
|
result = root.parse(input, pos, ctx);
|
|
@@ -3517,6 +3627,8 @@ function token(root) {
|
|
|
3517
3627
|
ctx._cstTriviaLog = savedTriviaLog;
|
|
3518
3628
|
if (savedOuterTriviaLog === void 0) delete ctx._triviaLog;
|
|
3519
3629
|
else ctx._triviaLog = savedOuterTriviaLog;
|
|
3630
|
+
if (savedRootTriviaLog === void 0) delete ctx._rootTriviaLog;
|
|
3631
|
+
else ctx._rootTriviaLog = savedRootTriviaLog;
|
|
3520
3632
|
}
|
|
3521
3633
|
if (!result.ok) return result;
|
|
3522
3634
|
const span = result.span;
|
|
@@ -3571,7 +3683,7 @@ function leaf(root, fn) {
|
|
|
3571
3683
|
}
|
|
3572
3684
|
|
|
3573
3685
|
// src/version.ts
|
|
3574
|
-
var PARSEMAN_VERSION = "0.
|
|
3686
|
+
var PARSEMAN_VERSION = "0.44.0";
|
|
3575
3687
|
|
|
3576
3688
|
// src/cst/host-mode.ts
|
|
3577
3689
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -5469,9 +5581,18 @@ function buildGrammarPlan(entry, winners) {
|
|
|
5469
5581
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
|
|
5470
5582
|
}
|
|
5471
5583
|
|
|
5584
|
+
// src/cst/trivia-entries.ts
|
|
5585
|
+
var EMPTY_INDICES = Object.freeze([]);
|
|
5586
|
+
var EMPTY_GAPS = Object.freeze([]);
|
|
5587
|
+
var SELECTED_ROOT_STRIDE = 5;
|
|
5588
|
+
|
|
5472
5589
|
// src/compiler/scannable-run.ts
|
|
5473
5590
|
var BACKSLASH = 92;
|
|
5474
5591
|
var META = new Set("()[]{}*+?|^$.".split(""));
|
|
5592
|
+
var SELECTED_ROOT_OWNED_RANGE_PLACEHOLDER = Array.from(
|
|
5593
|
+
{ length: SELECTED_ROOT_STRIDE - 3 },
|
|
5594
|
+
() => "0"
|
|
5595
|
+
).join(", ");
|
|
5475
5596
|
function classToRanges(cls) {
|
|
5476
5597
|
if (cls === "\\d") return shorthandRanges("d");
|
|
5477
5598
|
if (cls === "\\w") return shorthandRanges("w");
|
|
@@ -6510,13 +6631,15 @@ function scanBranch(shape, mint) {
|
|
|
6510
6631
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6511
6632
|
return [...m.setup, ` if (${m.end} > _e) { _e = ${m.end}; continue }`].join("\n");
|
|
6512
6633
|
}
|
|
6513
|
-
function scanBranchLabeled(shape, kindIndex, mint) {
|
|
6634
|
+
function scanBranchLabeled(shape, kindIndex, label2, mint) {
|
|
6514
6635
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6515
6636
|
return [
|
|
6516
6637
|
...m.setup,
|
|
6517
6638
|
` if (${m.end} > _e) {`,
|
|
6518
6639
|
` if (_cap) {`,
|
|
6519
6640
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, ${m.end}, ${kindIndex})`,
|
|
6641
|
+
` const _rk = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(label2)}] ?? -1)`,
|
|
6642
|
+
` if (_rk >= 0) _ctx._rootTriviaLog.push(${SELECTED_ROOT_OWNED_RANGE_PLACEHOLDER}, _e, ${m.end}, _rk)`,
|
|
6520
6643
|
` 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})`,
|
|
6521
6644
|
` }`,
|
|
6522
6645
|
` _e = ${m.end}`,
|
|
@@ -6576,6 +6699,11 @@ var CAP_RECORD = [
|
|
|
6576
6699
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
|
|
6577
6700
|
` }`
|
|
6578
6701
|
].join("\n");
|
|
6702
|
+
var SELECTED_ROOT_FINISH = [
|
|
6703
|
+
` if (_cap && _ctx._rootTriviaCapture !== false && _ctx._rootTriviaLog !== undefined && _ctx._rootTriviaLog.length !== _rootMark) {`,
|
|
6704
|
+
` for (let _ri = _rootMark; _ri < _ctx._rootTriviaLog.length; _ri += ${SELECTED_ROOT_STRIDE}) { _ctx._rootTriviaLog[_ri] = _pos; _ctx._rootTriviaLog[_ri + 1] = _e }`,
|
|
6705
|
+
` }`
|
|
6706
|
+
].join("\n");
|
|
6579
6707
|
function composeFastLoop(shapes) {
|
|
6580
6708
|
const mint = makeMint();
|
|
6581
6709
|
return [
|
|
@@ -6604,7 +6732,7 @@ function analyzeLabeledScannableRun(trivia2) {
|
|
|
6604
6732
|
const d = getCoreRegexDef(arm.parser);
|
|
6605
6733
|
const shape = d ? scanShapeFromRegex(d.source, d.flags) : null;
|
|
6606
6734
|
if (!shape) return null;
|
|
6607
|
-
out.push({ shape, kindIndex: arm.kindIndex });
|
|
6735
|
+
out.push({ shape, kindIndex: arm.kindIndex, label: arm.label });
|
|
6608
6736
|
}
|
|
6609
6737
|
return out;
|
|
6610
6738
|
}
|
|
@@ -6613,11 +6741,13 @@ function buildLabeledScannableTriviaFnDecl(fnName, arms) {
|
|
|
6613
6741
|
return [
|
|
6614
6742
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6615
6743
|
` let _e = _pos`,
|
|
6744
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6616
6745
|
` while (_e < input.length) {`,
|
|
6617
6746
|
` const c = input.charCodeAt(_e)`,
|
|
6618
|
-
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, mint)),
|
|
6747
|
+
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, a.label, mint)),
|
|
6619
6748
|
` break`,
|
|
6620
6749
|
` }`,
|
|
6750
|
+
SELECTED_ROOT_FINISH,
|
|
6621
6751
|
` return _e`,
|
|
6622
6752
|
`}`
|
|
6623
6753
|
].join("\n");
|
|
@@ -6633,6 +6763,8 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6633
6763
|
` const _ce = _e + _m${i}[0].length`,
|
|
6634
6764
|
` if (_cap) {`,
|
|
6635
6765
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
|
|
6766
|
+
` const _rk${i} = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(arm.label)}] ?? -1)`,
|
|
6767
|
+
` if (_rk${i} >= 0) _ctx._rootTriviaLog.push(0, 0, _e, _ce, _rk${i})`,
|
|
6636
6768
|
` 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})`,
|
|
6637
6769
|
` }`,
|
|
6638
6770
|
` _e = _ce`,
|
|
@@ -6644,11 +6776,13 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6644
6776
|
return [
|
|
6645
6777
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6646
6778
|
` let _e = _pos`,
|
|
6779
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6647
6780
|
` while (_e < input.length) {`,
|
|
6648
6781
|
` let _matched = false`,
|
|
6649
6782
|
tryArms,
|
|
6650
6783
|
` if (!_matched) break`,
|
|
6651
6784
|
` }`,
|
|
6785
|
+
SELECTED_ROOT_FINISH,
|
|
6652
6786
|
` return _e`,
|
|
6653
6787
|
`}`
|
|
6654
6788
|
].join("\n");
|
|
@@ -6671,6 +6805,8 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6671
6805
|
` const _ce = _r${i}.span.end`,
|
|
6672
6806
|
` if (_cap) {`,
|
|
6673
6807
|
` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
|
|
6808
|
+
` const _rk${i} = _ctx._rootTriviaCapture === false || _ctx._rootTriviaLog === undefined ? -1 : (_ctx._rootTriviaKindIndex?.[${JSON.stringify(arm.label)}] ?? -1)`,
|
|
6809
|
+
` if (_rk${i} >= 0) _ctx._rootTriviaLog.push(0, 0, _e, _ce, _rk${i})`,
|
|
6674
6810
|
` 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})`,
|
|
6675
6811
|
` }`,
|
|
6676
6812
|
` _e = _ce`,
|
|
@@ -6682,11 +6818,13 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6682
6818
|
return [
|
|
6683
6819
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6684
6820
|
` let _e = _pos`,
|
|
6821
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6685
6822
|
` while (_e < input.length) {`,
|
|
6686
6823
|
` let _matched = false`,
|
|
6687
6824
|
tryArms,
|
|
6688
6825
|
` if (!_matched) break`,
|
|
6689
6826
|
` }`,
|
|
6827
|
+
SELECTED_ROOT_FINISH,
|
|
6690
6828
|
` return _e`,
|
|
6691
6829
|
`}`
|
|
6692
6830
|
].join("\n");
|
|
@@ -6917,6 +7055,9 @@ function endLoweringCapture() {
|
|
|
6917
7055
|
_loweringSink = null;
|
|
6918
7056
|
return misses;
|
|
6919
7057
|
}
|
|
7058
|
+
function hasSelectedRootTrivia(ctx) {
|
|
7059
|
+
return ctx.rootTriviaClassified === true;
|
|
7060
|
+
}
|
|
6920
7061
|
function v(ctx, prefix = "_v") {
|
|
6921
7062
|
return `${prefix}${ctx.vars++}`;
|
|
6922
7063
|
}
|
|
@@ -7226,10 +7367,12 @@ function planDisjointDispatch(parsers) {
|
|
|
7226
7367
|
}
|
|
7227
7368
|
return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
7228
7369
|
}
|
|
7229
|
-
function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
|
|
7370
|
+
function captureRestoreBody(ctx, mL, mR, mTl, mLg, mF = null, mRootLg = null) {
|
|
7230
7371
|
const fieldRestore = mF ? `; if (_ctx._fields && _ctx._fields.length !== ${mF}) _ctx._fields.length = ${mF}` : "";
|
|
7231
7372
|
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}`;
|
|
7232
|
-
|
|
7373
|
+
const logRestore = mLg ? `; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${mLg}) _ctx._triviaLog.length = ${mLg}` : "";
|
|
7374
|
+
const rootLogRestore = hasSelectedRootTrivia(ctx) && mRootLg ? `; if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${mRootLg}) _ctx._rootTriviaLog.length = ${mRootLg}` : "";
|
|
7375
|
+
return `${base}${logRestore}${rootLogRestore}`;
|
|
7233
7376
|
}
|
|
7234
7377
|
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
7235
7378
|
if (seen.has(p)) return false;
|
|
@@ -7439,7 +7582,7 @@ function emitFallible(inner, ctx, pos, swallow = false) {
|
|
|
7439
7582
|
`${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
|
|
7440
7583
|
`${ind0}}`,
|
|
7441
7584
|
...mL ? [
|
|
7442
|
-
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
|
|
7585
|
+
`${ind0}if (!${okV}) { ${captureRestoreBody(ctx, mL, mR, mTl, null, mF)} }`
|
|
7443
7586
|
] : []
|
|
7444
7587
|
];
|
|
7445
7588
|
return { stmts, okVar: okV, valVar: valV, endVar: endV, mayCommit };
|
|
@@ -7636,11 +7779,13 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7636
7779
|
const markV = v(ctx, "_mk");
|
|
7637
7780
|
const markTl = v(ctx, "_mktl");
|
|
7638
7781
|
const markLog = v(ctx, "_mklg");
|
|
7782
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7639
7783
|
const scanEndV = v(ctx, "_sne");
|
|
7640
7784
|
stmts.push(
|
|
7641
7785
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7642
7786
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7643
7787
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7788
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7644
7789
|
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7645
7790
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7646
7791
|
);
|
|
@@ -7649,17 +7794,19 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7649
7794
|
const endAfterV = v(ctx, "_sea");
|
|
7650
7795
|
stmts.push(
|
|
7651
7796
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7652
|
-
`${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}
|
|
7797
|
+
`${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};` : ""} }`
|
|
7653
7798
|
);
|
|
7654
7799
|
valueVars.push(r2.valueVar);
|
|
7655
7800
|
continue;
|
|
7656
7801
|
} else {
|
|
7657
7802
|
const trivFn = ensureTriviaFn(ctx);
|
|
7658
7803
|
const markLog = v(ctx, "_mklg");
|
|
7804
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7659
7805
|
const scanEndV = v(ctx, "_sne");
|
|
7660
|
-
const capArg = ctx.noHoist ? "0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7806
|
+
const capArg = ctx.noHoist ? "0" : hasSelectedRootTrivia(ctx) ? "(_ctx._triviaLog !== undefined || _ctx._rootTriviaLog !== undefined) ? 2 : 0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7661
7807
|
stmts.push(
|
|
7662
7808
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7809
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7663
7810
|
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7664
7811
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7665
7812
|
);
|
|
@@ -7668,7 +7815,7 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7668
7815
|
const endAfterV = v(ctx, "_sea");
|
|
7669
7816
|
stmts.push(
|
|
7670
7817
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7671
|
-
`${ind(ctx)}if (${endAfterV} > ${scanEndV}) ${curV} = ${endAfterV}; else if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}`
|
|
7818
|
+
`${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};` : ""} }`
|
|
7672
7819
|
);
|
|
7673
7820
|
valueVars.push(r2.valueVar);
|
|
7674
7821
|
continue;
|
|
@@ -7910,6 +8057,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7910
8057
|
const selectorRawMark = selectorNeedsRollback ? v(ctx, "_dsr") : null;
|
|
7911
8058
|
const selectorTriviaMark = selectorNeedsRollback ? v(ctx, "_dst") : null;
|
|
7912
8059
|
const selectorLogMark = selectorNeedsRollback ? v(ctx, "_dsg") : null;
|
|
8060
|
+
const selectorRootLogMark = selectorNeedsRollback && hasSelectedRootTrivia(ctx) ? v(ctx, "_dsrg") : null;
|
|
7913
8061
|
const selectorFieldMark = selectorNeedsRollback ? v(ctx, "_dsf") : null;
|
|
7914
8062
|
const selectorErrorMark = selectorNeedsRollback ? v(ctx, "_dse") : null;
|
|
7915
8063
|
const selector = emit(def.selector, ctx, pos);
|
|
@@ -7922,6 +8070,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7922
8070
|
`${ind(ctx)}const ${selectorRawMark} = _ctx._cstRawChildren?.length ?? 0`,
|
|
7923
8071
|
`${ind(ctx)}const ${selectorTriviaMark} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
7924
8072
|
`${ind(ctx)}const ${selectorLogMark} = _ctx._triviaLog?.length ?? 0`,
|
|
8073
|
+
...selectorRootLogMark ? [`${ind(ctx)}const ${selectorRootLogMark} = _ctx._rootTriviaLog?.length ?? 0`] : [],
|
|
7925
8074
|
`${ind(ctx)}const ${selectorFieldMark} = _ctx._fields?.length ?? 0`,
|
|
7926
8075
|
`${ind(ctx)}const ${selectorErrorMark} = _ctx._errors?.length ?? 0`
|
|
7927
8076
|
] : [],
|
|
@@ -7941,16 +8090,18 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7941
8090
|
const mayError = mayRecordRecoveryError(parser3, !!ctx.recovery);
|
|
7942
8091
|
const errMark = mayError ? v(ctx, "_derr") : null;
|
|
7943
8092
|
const logMark = ctx.activeTrivia ? v(ctx, "_dlog") : null;
|
|
8093
|
+
const rootLogMark = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_drlog") : null;
|
|
7944
8094
|
if (usesRouted) {
|
|
7945
8095
|
stmts.push(
|
|
7946
8096
|
...routedV ? [`${ind(ctx)}const ${routedV} = _ctx._routed; _ctx._routed = { value: ${selector.valueVar}, span: { start: ${pos}, end: ${selector.endVar} } }`] : [],
|
|
7947
8097
|
...selectorLeafMark ? [
|
|
7948
|
-
`${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}
|
|
8098
|
+
`${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}`
|
|
7949
8099
|
] : []
|
|
7950
8100
|
);
|
|
7951
8101
|
}
|
|
7952
8102
|
if (errMark) stmts.push(`${ind(ctx)}const ${errMark} = _ctx._errors?.length ?? 0`);
|
|
7953
8103
|
if (logMark) stmts.push(`${ind(ctx)}const ${logMark} = _ctx._triviaLog?.length ?? 0`);
|
|
8104
|
+
if (rootLogMark) stmts.push(`${ind(ctx)}const ${rootLogMark} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
7954
8105
|
const savedRoutedLocal = ctx.routedLocal;
|
|
7955
8106
|
const savedNoHoist = ctx.noHoist;
|
|
7956
8107
|
if (usesRouted && !needsRoutedContext) {
|
|
@@ -7965,11 +8116,12 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7965
8116
|
stmts.push(...coverageAttempt(ctx, coverageId, pos));
|
|
7966
8117
|
const errorRollback = errMark ? `if (_ctx._errors && _ctx._errors.length !== ${errMark}) _ctx._errors.length = ${errMark}; ` : "";
|
|
7967
8118
|
const logRollback = logMark ? `if (_ctx._triviaLog && _ctx._triviaLog.length !== ${logMark}) _ctx._triviaLog.length = ${logMark}; ` : "";
|
|
8119
|
+
const rootLogRollback = rootLogMark ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${rootLogMark}) _ctx._rootTriviaLog.length = ${rootLogMark}; ` : "";
|
|
7968
8120
|
const routedRollback = routedV ? `_ctx._routed = ${routedV}; ` : "";
|
|
7969
8121
|
const coverageFailure = coverageId === void 0 ? "" : `_ctx._grammarTrace?.write({ id: ${JSON.stringify(coverageId)}, phase: 'failure', offset: _ctx._fe }); `;
|
|
7970
8122
|
stmts.push(
|
|
7971
8123
|
...tail.stmts,
|
|
7972
|
-
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8124
|
+
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${rootLogRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
7973
8125
|
...routedV ? [`${ind(ctx)}_ctx._routed = ${routedV}`] : [],
|
|
7974
8126
|
`${ind(ctx)}${outV} = ${valueMode === "tail" ? tail.valVar : `[${selector.valueVar}, ${tail.valVar}]`}`,
|
|
7975
8127
|
`${ind(ctx)}${outE} = ${tail.endVar}`,
|
|
@@ -8150,11 +8302,13 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8150
8302
|
const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
|
|
8151
8303
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
8152
8304
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
8305
|
+
const markRootLog = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_cmlrg") : null;
|
|
8153
8306
|
const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
|
|
8154
8307
|
const markErrors = armMayRecordError ? v(ctx, "_cme") : null;
|
|
8155
|
-
const captureRollback = markLeaves ? captureRestoreBody(markLeaves, markRaw, markTl, markLog, markFields) : "";
|
|
8308
|
+
const captureRollback = markLeaves ? captureRestoreBody(ctx, markLeaves, markRaw, markTl, markLog, markFields, markRootLog) : "";
|
|
8309
|
+
const rootRollback = markRootLog && !markLeaves ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}` : "";
|
|
8156
8310
|
const errorRollback = markErrors ? `if (_ctx._errors && _ctx._errors.length !== ${markErrors}) _ctx._errors.length = ${markErrors}` : "";
|
|
8157
|
-
const rollback = [captureRollback, errorRollback].filter(Boolean).join("; ");
|
|
8311
|
+
const rollback = [captureRollback, rootRollback, errorRollback].filter(Boolean).join("; ");
|
|
8158
8312
|
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
8159
8313
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
8160
8314
|
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
@@ -8169,6 +8323,7 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8169
8323
|
...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
|
|
8170
8324
|
);
|
|
8171
8325
|
}
|
|
8326
|
+
if (markRootLog) stmts.push(`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
8172
8327
|
if (markErrors) stmts.push(`${ind(ctx)}const ${markErrors} = _ctx._errors?.length ?? 0`);
|
|
8173
8328
|
const arm = emitFallible(p, ctx, pos, atStart);
|
|
8174
8329
|
const { stmts: armStmts, okVar, valVar, endVar } = arm;
|
|
@@ -8356,21 +8511,29 @@ function emitMany(def, ctx, pos) {
|
|
|
8356
8511
|
const markV = v(ctx, "_mk");
|
|
8357
8512
|
const markTl = v(ctx, "_mktl");
|
|
8358
8513
|
const markLog = v(ctx, "_mklg");
|
|
8514
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8359
8515
|
const npV = v(ctx, "_np");
|
|
8360
8516
|
stmts.push(
|
|
8361
8517
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8362
8518
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8363
8519
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8520
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8364
8521
|
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8365
8522
|
...emitLineTrack(ctx, curV, npV)
|
|
8366
8523
|
);
|
|
8367
8524
|
itemPos = npV;
|
|
8368
|
-
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}
|
|
8525
|
+
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};` : ""} `;
|
|
8369
8526
|
} else {
|
|
8370
8527
|
const trivFn = ensureTriviaFn(ctx);
|
|
8528
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8371
8529
|
const npV = v(ctx, "_np");
|
|
8372
|
-
stmts.push(
|
|
8530
|
+
stmts.push(
|
|
8531
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8532
|
+
`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8533
|
+
...emitLineTrack(ctx, curV, npV)
|
|
8534
|
+
);
|
|
8373
8535
|
itemPos = npV;
|
|
8536
|
+
rollback = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8374
8537
|
}
|
|
8375
8538
|
}
|
|
8376
8539
|
if (!ctx.recovery && !ctx.coverage && !failsAtStart(def.parser) && needsFirstSetGuard(def.parser)) {
|
|
@@ -8430,9 +8593,10 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8430
8593
|
const raw = v(ctx, "_atr");
|
|
8431
8594
|
const trivia2 = v(ctx, "_att");
|
|
8432
8595
|
const log = v(ctx, "_atg");
|
|
8596
|
+
const rootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_atrg") : null;
|
|
8433
8597
|
const fields = v(ctx, "_atf");
|
|
8434
8598
|
const errors = v(ctx, "_ate");
|
|
8435
|
-
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}
|
|
8599
|
+
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}`;
|
|
8436
8600
|
const traceId = ctx.coverage?.plan.attempts.get(p);
|
|
8437
8601
|
const traceRollback = traceId === void 0 ? "" : ` _ctx._grammarTrace?.write({ id: ${JSON.stringify(traceId)}, phase: 'rollback', offset: ${pos} });`;
|
|
8438
8602
|
const preGuard = [];
|
|
@@ -8448,7 +8612,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8448
8612
|
return {
|
|
8449
8613
|
stmts: [
|
|
8450
8614
|
...preGuard,
|
|
8451
|
-
`${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`,
|
|
8615
|
+
`${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`,
|
|
8452
8616
|
...inner.stmts,
|
|
8453
8617
|
...emitIfFail(ctx, `!${inner.okVar}`, `{ ${rollback};${traceRollback}${inner.mayCommit ? ` if (_ctx._fc) ${committedFailBody(ctx)};` : ""} _ctx._fe = ${pos}; ${propagateFailBody(ctx)} }`)
|
|
8454
8618
|
],
|
|
@@ -8490,16 +8654,17 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8490
8654
|
const itemFailBreak = (sepEndVar, sepRb, postSepRb) => def.trailing === void 0 ? `${sepRb}break` : `${postSepRb}${curV} = ${sepEndVar}; break`;
|
|
8491
8655
|
const postSepMarks = () => {
|
|
8492
8656
|
if (def.trailing === void 0 || !ctx.capturing) return { decl: [], rb: "" };
|
|
8493
|
-
const lv = v(ctx, "_tlv"), rw = v(ctx, "_trw"), tl = v(ctx, "_ttl"), lg = v(ctx, "_tlg"), fl = v(ctx, "_tlf");
|
|
8657
|
+
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");
|
|
8494
8658
|
return {
|
|
8495
8659
|
decl: [
|
|
8496
8660
|
`${ind(ctx)}const ${lv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8497
8661
|
`${ind(ctx)}const ${rw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8498
8662
|
`${ind(ctx)}const ${tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8499
8663
|
`${ind(ctx)}const ${lg} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8664
|
+
...rlg ? [`${ind(ctx)}const ${rlg} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8500
8665
|
`${ind(ctx)}const ${fl} = _ctx._fields ? _ctx._fields.length : 0`
|
|
8501
8666
|
],
|
|
8502
|
-
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}
|
|
8667
|
+
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}; `
|
|
8503
8668
|
};
|
|
8504
8669
|
};
|
|
8505
8670
|
if (rec) {
|
|
@@ -8537,6 +8702,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8537
8702
|
const markV = v(ctx, "_mk");
|
|
8538
8703
|
const markTl = v(ctx, "_mktl");
|
|
8539
8704
|
const markLog = v(ctx, "_mklg");
|
|
8705
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8540
8706
|
const markLv = v(ctx, "_mklv");
|
|
8541
8707
|
const markFld = v(ctx, "_mkf");
|
|
8542
8708
|
const spV = v(ctx, "_sp");
|
|
@@ -8544,13 +8710,14 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8544
8710
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8545
8711
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8546
8712
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8713
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8547
8714
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8548
8715
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8549
8716
|
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8550
8717
|
...emitLineTrack(ctx, curV, spV)
|
|
8551
8718
|
);
|
|
8552
8719
|
sepAtPos = spV;
|
|
8553
|
-
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}
|
|
8720
|
+
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}; `;
|
|
8554
8721
|
const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8555
8722
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
|
|
8556
8723
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep2.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
@@ -8568,19 +8735,30 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8568
8735
|
);
|
|
8569
8736
|
} else {
|
|
8570
8737
|
const trivFn = ensureTriviaFn(ctx);
|
|
8738
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8571
8739
|
const spV = v(ctx, "_sp");
|
|
8572
|
-
stmts.push(
|
|
8740
|
+
stmts.push(
|
|
8741
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8742
|
+
`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8743
|
+
...emitLineTrack(ctx, curV, spV)
|
|
8744
|
+
);
|
|
8573
8745
|
sepAtPos = spV;
|
|
8574
8746
|
const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8575
8747
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
|
|
8576
|
-
|
|
8748
|
+
const rollbackToSep = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8749
|
+
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep2.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
8750
|
+
const postRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_psrlg") : null;
|
|
8577
8751
|
const npV = v(ctx, "_np");
|
|
8578
|
-
stmts.push(
|
|
8752
|
+
stmts.push(
|
|
8753
|
+
...postRootLog ? [`${ind(ctx)}const ${postRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8754
|
+
`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx, ${hasSelectedRootTrivia(ctx) ? "_ctx._rootTriviaLog !== undefined ? 2 : 0" : "0"})`,
|
|
8755
|
+
...emitLineTrack(ctx, sepEnd, npV)
|
|
8756
|
+
);
|
|
8579
8757
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8580
8758
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8581
8759
|
stmts.push(
|
|
8582
8760
|
...nextStmts,
|
|
8583
|
-
...failItem(nextOk, next.mayCommit, npV, itemFailBreak(sepEnd,
|
|
8761
|
+
...failItem(nextOk, next.mayCommit, npV, itemFailBreak(sepEnd, rollbackToSep, postRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${postRootLog}) _ctx._rootTriviaLog.length = ${postRootLog}; ` : "")),
|
|
8584
8762
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
8585
8763
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
8586
8764
|
);
|
|
@@ -8675,6 +8853,7 @@ function emitNot(def, ctx, pos) {
|
|
|
8675
8853
|
const raw = sinksLive ? v(ctx, "_ntr") : null;
|
|
8676
8854
|
const tl = sinksLive ? v(ctx, "_ntt") : null;
|
|
8677
8855
|
const log = sinksLive ? v(ctx, "_ntg") : null;
|
|
8856
|
+
const rootLog = sinksLive && hasSelectedRootTrivia(ctx) ? v(ctx, "_ntrg") : null;
|
|
8678
8857
|
const fields = sinksLive ? v(ctx, "_ntf") : null;
|
|
8679
8858
|
const errors = sinksLive ? v(ctx, "_nte") : null;
|
|
8680
8859
|
const { stmts, okVar } = emitFallible(def.parser, ctx, pos, true);
|
|
@@ -8682,11 +8861,11 @@ function emitNot(def, ctx, pos) {
|
|
|
8682
8861
|
return {
|
|
8683
8862
|
stmts: [
|
|
8684
8863
|
...sinksLive ? [
|
|
8685
|
-
`${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`
|
|
8864
|
+
`${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`
|
|
8686
8865
|
] : [],
|
|
8687
8866
|
...stmts,
|
|
8688
8867
|
...sinksLive ? [
|
|
8689
|
-
`${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}
|
|
8868
|
+
`${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}`
|
|
8690
8869
|
] : [],
|
|
8691
8870
|
...emitIfFail(ctx, okVar, failBody(ctx, label2, pos))
|
|
8692
8871
|
],
|
|
@@ -8822,16 +9001,17 @@ function emitToken(def, ctx, pos) {
|
|
|
8822
9001
|
const sk = v(ctx, "_tokKinds");
|
|
8823
9002
|
const stl = v(ctx, "_tokTl");
|
|
8824
9003
|
const sol = v(ctx, "_tokLog");
|
|
9004
|
+
const srl = hasSelectedRootTrivia(ctx) ? v(ctx, "_tokRootLog") : null;
|
|
8825
9005
|
const sb = v(ctx, "_tokBuf");
|
|
8826
9006
|
const valV = v(ctx, "_tok");
|
|
8827
9007
|
return {
|
|
8828
9008
|
stmts: [
|
|
8829
|
-
`${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`,
|
|
8830
|
-
`${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`,
|
|
9009
|
+
`${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`,
|
|
9010
|
+
`${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`,
|
|
8831
9011
|
`${i}try {`,
|
|
8832
9012
|
...reindentStmts(inner.stmts, ctx.indent + 1).map((stmt) => stmt.replace(/^(\s*)(?:const|let)\s+/, "$1var ")),
|
|
8833
9013
|
`${i}} finally {`,
|
|
8834
|
-
`${i} _ctx.trivia = ${sv}; _ctx.triviaKindLabels = ${sk}; _ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx._cstTriviaLog = ${stl}; _ctx._triviaLog = ${sol}
|
|
9014
|
+
`${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}`,
|
|
8835
9015
|
`${i}}`,
|
|
8836
9016
|
...emitIfFail(ctx, `!${inner.okVar}`, propagateFailBody(ctx)),
|
|
8837
9017
|
`${i}const ${valV} = input.slice(${pos}, ${inner.endVar})`,
|
|
@@ -9310,6 +9490,8 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9310
9490
|
case "grammar": {
|
|
9311
9491
|
const savedTrivia = ctx.activeTrivia;
|
|
9312
9492
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
9493
|
+
const opaqueRootCapture = hasSelectedRootTrivia(ctx) && def.rootCapture === "opaque";
|
|
9494
|
+
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;
|
|
9313
9495
|
if (def.clearTrivia) {
|
|
9314
9496
|
ctx.activeTrivia = void 0;
|
|
9315
9497
|
ctx.triviaKindLabels = void 0;
|
|
@@ -9320,13 +9502,38 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9320
9502
|
}
|
|
9321
9503
|
}
|
|
9322
9504
|
const savedCapture = def.captureTrivia ? v(ctx, "_gcap") : null;
|
|
9505
|
+
const savedRootCapture = opaqueRootCapture ? v(ctx, "_grtc") : null;
|
|
9506
|
+
const opaqueValue = opaqueRootCapture ? v(ctx, "_grtv") : null;
|
|
9507
|
+
const opaqueEnd = opaqueRootCapture ? v(ctx, "_grte") : null;
|
|
9508
|
+
if (opaqueRootCapture) ctx.indent++;
|
|
9323
9509
|
const r = emit(def.parser, ctx, pos);
|
|
9510
|
+
if (opaqueRootCapture) ctx.indent--;
|
|
9324
9511
|
ctx.activeTrivia = savedTrivia;
|
|
9325
9512
|
ctx.triviaKindLabels = savedKindLabels;
|
|
9326
|
-
if (!savedCapture) return r
|
|
9513
|
+
if (!savedCapture && !opaqueRootCapture) return strictScopeCheck === void 0 ? r : {
|
|
9514
|
+
...r,
|
|
9515
|
+
stmts: [strictScopeCheck, ...r.stmts]
|
|
9516
|
+
};
|
|
9517
|
+
if (opaqueRootCapture) {
|
|
9518
|
+
return {
|
|
9519
|
+
stmts: [
|
|
9520
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9521
|
+
`${ind(ctx)}let ${opaqueValue}, ${opaqueEnd}`,
|
|
9522
|
+
`${ind(ctx)}${savedCapture ? `const ${savedCapture} = _ctx.captureTrivia; ` : ""}const ${savedRootCapture} = _ctx._rootTriviaCapture; _ctx._rootTriviaCapture = false`,
|
|
9523
|
+
`${ind(ctx)}try {`,
|
|
9524
|
+
...savedCapture ? [`${ind(ctx)} _ctx.captureTrivia = true`] : [],
|
|
9525
|
+
...r.stmts,
|
|
9526
|
+
`${ind(ctx)} ${opaqueValue} = ${r.valueVar}; ${opaqueEnd} = ${r.endVar}`,
|
|
9527
|
+
`${ind(ctx)}} finally { ${savedCapture ? `_ctx.captureTrivia = ${savedCapture}; ` : ""}_ctx._rootTriviaCapture = ${savedRootCapture} }`
|
|
9528
|
+
],
|
|
9529
|
+
valueVar: opaqueValue,
|
|
9530
|
+
endVar: opaqueEnd
|
|
9531
|
+
};
|
|
9532
|
+
}
|
|
9327
9533
|
return {
|
|
9328
9534
|
...r,
|
|
9329
9535
|
stmts: [
|
|
9536
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9330
9537
|
`${ind(ctx)}const ${savedCapture} = _ctx.captureTrivia; _ctx.captureTrivia = true`,
|
|
9331
9538
|
...r.stmts,
|
|
9332
9539
|
`${ind(ctx)}_ctx.captureTrivia = ${savedCapture}`
|
|
@@ -9811,6 +10018,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9811
10018
|
runDuplicationDiagnostic(combinator, opts?.duplication);
|
|
9812
10019
|
markUnusedValues(combinator);
|
|
9813
10020
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
10021
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || combinator._meta.rootTriviaClassified === true;
|
|
9814
10022
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9815
10023
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9816
10024
|
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
@@ -9837,7 +10045,11 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9837
10045
|
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9838
10046
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9839
10047
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9840
|
-
...
|
|
10048
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10049
|
+
...grammarTrivia ? {
|
|
10050
|
+
activeTrivia: grammarTrivia,
|
|
10051
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10052
|
+
} : {},
|
|
9841
10053
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
9842
10054
|
};
|
|
9843
10055
|
const r = emit(combinator, ctx, "_pos");
|
|
@@ -9985,10 +10197,11 @@ function assertRuleName(name) {
|
|
|
9985
10197
|
);
|
|
9986
10198
|
}
|
|
9987
10199
|
}
|
|
9988
|
-
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels) {
|
|
9989
|
-
const labels = rule._meta.triviaKindLabels
|
|
9990
|
-
|
|
9991
|
-
|
|
10200
|
+
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels, ambientRootTriviaClassified) {
|
|
10201
|
+
const labels = ambientTriviaKindLabels ?? rule._meta.triviaKindLabels;
|
|
10202
|
+
const classified = ambientRootTriviaClassified ?? rule._meta.rootTriviaClassified;
|
|
10203
|
+
if (labels === void 0 && classified === void 0) return fnSource;
|
|
10204
|
+
return `Object.assign(${fnSource}, { _meta: {${labels === void 0 ? "" : ` triviaKindLabels: ${JSON.stringify(labels)},`}${classified === void 0 ? "" : " rootTriviaClassified: true,"} } })`;
|
|
9992
10205
|
}
|
|
9993
10206
|
function compileRuleMap(ruleMap, opts) {
|
|
9994
10207
|
runGatingDiagnosticRules(ruleMap, opts?.gating);
|
|
@@ -9996,6 +10209,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9996
10209
|
for (const [, rule] of ruleMap) markUnusedValues(rule);
|
|
9997
10210
|
const coverageWinners = opts?.coverage ? Object.fromEntries(ruleMap.filter(([, rule]) => rule._def.tag !== "lazy")) : void 0;
|
|
9998
10211
|
const grammarTrivia = opts?.trivia;
|
|
10212
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || ruleMap.some(([, rule]) => rule._meta.rootTriviaClassified === true);
|
|
9999
10213
|
const grammarScanSkip = opts?.scanSkip ?? ruleMap.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
10000
10214
|
const grammarHostMode = opts?.hostMode ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10001
10215
|
const grammarTrackLines = opts?.trackLines === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -10022,7 +10236,11 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
10022
10236
|
lineTracking: grammarTrackLines,
|
|
10023
10237
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(ruleMap.map(([, rule]) => rule), coverageWinners) } } : {},
|
|
10024
10238
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10025
|
-
...
|
|
10239
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10240
|
+
...grammarTrivia ? {
|
|
10241
|
+
activeTrivia: grammarTrivia,
|
|
10242
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10243
|
+
} : {},
|
|
10026
10244
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
10027
10245
|
};
|
|
10028
10246
|
const seenNames = /* @__PURE__ */ new Map();
|
|
@@ -10110,7 +10328,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
10110
10328
|
return [`function(input, _pos, _ctx) {`, ...body, `}`].join("\n");
|
|
10111
10329
|
};
|
|
10112
10330
|
const objBody = perEntry.map(({ key, rule, r }) => {
|
|
10113
|
-
const src = publicRuleWrapperSource(rule, entryFnText(r, rule), ctx.triviaKindLabels);
|
|
10331
|
+
const src = publicRuleWrapperSource(rule, entryFnText(r, rule), ctx.triviaKindLabels, ctx.rootTriviaClassified);
|
|
10114
10332
|
return ` ${JSON.stringify(key)}: ${src.split("\n").join("\n ")}`;
|
|
10115
10333
|
}).join(",\n");
|
|
10116
10334
|
const replacement = [
|
|
@@ -10139,6 +10357,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10139
10357
|
if (opts?.duplication !== void 0) runDuplicationDiagnosticRules(ruleMapArg, opts.duplication);
|
|
10140
10358
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
10141
10359
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
10360
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || ruleMapArg.some(([, rule]) => rule._meta.rootTriviaClassified === true);
|
|
10142
10361
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
10143
10362
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10144
10363
|
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -10182,7 +10401,11 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10182
10401
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10183
10402
|
ns,
|
|
10184
10403
|
deferFirstSetRefs: true,
|
|
10185
|
-
...
|
|
10404
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10405
|
+
...grammarTrivia ? {
|
|
10406
|
+
activeTrivia: grammarTrivia,
|
|
10407
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10408
|
+
} : {},
|
|
10186
10409
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
10187
10410
|
};
|
|
10188
10411
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -10314,7 +10537,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10314
10537
|
...r.stmts,
|
|
10315
10538
|
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
10316
10539
|
`}`
|
|
10317
|
-
].join("\n"), ctx.triviaKindLabels));
|
|
10540
|
+
].join("\n"), ctx.triviaKindLabels, ctx.rootTriviaClassified));
|
|
10318
10541
|
}
|
|
10319
10542
|
const firstSets = /* @__PURE__ */ new Map();
|
|
10320
10543
|
const firstSetRecipes = /* @__PURE__ */ new Map();
|
|
@@ -10663,6 +10886,7 @@ function evalRuleMapIR(ir) {
|
|
|
10663
10886
|
"transform",
|
|
10664
10887
|
"skip",
|
|
10665
10888
|
"trivia",
|
|
10889
|
+
"classifiedTrivia",
|
|
10666
10890
|
"label",
|
|
10667
10891
|
"field",
|
|
10668
10892
|
"expect",
|
|
@@ -10703,6 +10927,7 @@ function evalRuleMapIR(ir) {
|
|
|
10703
10927
|
transform,
|
|
10704
10928
|
skip,
|
|
10705
10929
|
trivia,
|
|
10930
|
+
classifiedTrivia,
|
|
10706
10931
|
label,
|
|
10707
10932
|
field,
|
|
10708
10933
|
expect,
|
|
@@ -10949,8 +11174,11 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10949
11174
|
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
10950
11175
|
}
|
|
10951
11176
|
case "grammar": {
|
|
10952
|
-
const
|
|
10953
|
-
|
|
11177
|
+
const classified = def.triviaParser?._meta.rootTriviaClassified === true;
|
|
11178
|
+
const spec = classified && def.triviaParser ? analyzeLabeledTrivia(def.triviaParser) : null;
|
|
11179
|
+
if (classified && !spec) throw new Unserializable("classified trivia without labeled arms");
|
|
11180
|
+
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";
|
|
11181
|
+
return `parser({ trivia: ${trivia2}${def.captureTrivia ? ", captureTrivia: true" : ""}${def.rootCapture ? `, rootCapture: ${JSON.stringify(def.rootCapture)}` : ""}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(def.parser)})`;
|
|
10954
11182
|
}
|
|
10955
11183
|
case "withCtx": {
|
|
10956
11184
|
if (def.extraSrc === void 0) throw new Unserializable("withCtx without extraSrc");
|
|
@@ -11182,10 +11410,6 @@ function gate(predicate) {
|
|
|
11182
11410
|
};
|
|
11183
11411
|
}
|
|
11184
11412
|
|
|
11185
|
-
// src/cst/trivia-entries.ts
|
|
11186
|
-
var EMPTY_INDICES = Object.freeze([]);
|
|
11187
|
-
var EMPTY_GAPS = Object.freeze([]);
|
|
11188
|
-
|
|
11189
11413
|
// src/cst/offset-model.ts
|
|
11190
11414
|
var { isFinite } = Number;
|
|
11191
11415
|
|
|
@@ -11437,6 +11661,9 @@ var SUPPORTED = {
|
|
|
11437
11661
|
optional: (...a) => optional(a[0]),
|
|
11438
11662
|
skip: (...a) => skip(a[0], a[1]),
|
|
11439
11663
|
trivia: (...a) => trivia(a[0]),
|
|
11664
|
+
classifiedTrivia: (...a) => classifiedTrivia(
|
|
11665
|
+
a[0]
|
|
11666
|
+
),
|
|
11440
11667
|
label: (...a) => label(a[0], a[1]),
|
|
11441
11668
|
field: (...a) => field(a[0], a[1]),
|
|
11442
11669
|
noTrivia: (...a) => noTrivia(a[0]),
|
|
@@ -13243,7 +13470,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
13243
13470
|
if (isComposeLeafCall(init)) {
|
|
13244
13471
|
const fused = compileComposeLeafCall(init);
|
|
13245
13472
|
if (!fused) {
|
|
13246
|
-
|
|
13473
|
+
const reasons = warnings.slice(-4);
|
|
13474
|
+
throw new Error(
|
|
13475
|
+
`${id}:${lineOf(init.start)} \u2014 composeLeaf() must macro-fuse; runtime composition is forbidden` + (reasons.length ? `
|
|
13476
|
+
causes:
|
|
13477
|
+
- ${reasons.join("\n - ")}` : "")
|
|
13478
|
+
);
|
|
13247
13479
|
}
|
|
13248
13480
|
replacements.push({ start: init.start, end: init.end, replacement: fused.replacement });
|
|
13249
13481
|
markUsedImportedFactories(fused.importedFactories);
|