parseman 0.42.1 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/combinators/attempt.d.ts.map +1 -1
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts +7 -0
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/map.d.ts +11 -0
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/node.d.ts +21 -7
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +17 -2
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/token.d.ts +3 -2
- package/dist/combinators/token.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +1 -0
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +4 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +6 -1
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/compiler/scannable-run.d.ts +1 -1
- package/dist/compiler/scannable-run.d.ts.map +1 -1
- package/dist/compiler/trivia-fast-path.d.ts +4 -3
- package/dist/compiler/trivia-fast-path.d.ts.map +1 -1
- package/dist/cst/reflection.d.ts +24 -0
- package/dist/cst/reflection.d.ts.map +1 -0
- package/dist/cst/trivia-entries.d.ts +15 -9
- package/dist/cst/trivia-entries.d.ts.map +1 -1
- package/dist/cst/trivia-kinds.d.ts +15 -11
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/cst/types.d.ts +2 -0
- package/dist/cst/types.d.ts.map +1 -1
- package/dist/cst/walk.d.ts +27 -62
- package/dist/cst/walk.d.ts.map +1 -1
- package/dist/functional/run.d.ts +22 -16
- package/dist/functional/run.d.ts.map +1 -1
- package/dist/index.cjs +1651 -1207
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1651 -1207
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs +186 -135
- package/dist/language-service/index.cjs.map +4 -4
- package/dist/language-service/index.d.ts +1 -1
- package/dist/language-service/index.d.ts.map +1 -1
- package/dist/language-service/index.js +186 -135
- package/dist/language-service/index.js.map +4 -4
- package/dist/plugin/evaluator.d.ts +1 -0
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +1525 -1048
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1525 -1048
- package/dist/plugin/index.js.map +4 -4
- package/dist/run/index.cjs +152 -102
- package/dist/run/index.cjs.map +3 -3
- package/dist/run/index.d.ts +1 -1
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +152 -102
- package/dist/run/index.js.map +3 -3
- package/dist/spec/index.cjs +1381 -1152
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +1381 -1152
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +27 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/plugin/index.js
CHANGED
|
@@ -1071,1031 +1071,1095 @@ 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
|
|
1497
|
+
return null;
|
|
1615
1498
|
}
|
|
1616
|
-
function
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1499
|
+
function armScanner(arm) {
|
|
1500
|
+
if (arm.kind === "untilLineBreak") return untilLineBreakScanner(arm.code);
|
|
1501
|
+
const ranges = arm.ranges;
|
|
1502
|
+
return (input, cur) => {
|
|
1503
|
+
let pos = cur;
|
|
1504
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1505
|
+
return pos;
|
|
1506
|
+
};
|
|
1507
|
+
}
|
|
1508
|
+
function fusedTriviaScanner(ranges, leaders) {
|
|
1509
|
+
const c0 = leaders[0];
|
|
1510
|
+
const single = leaders.length === 1;
|
|
1511
|
+
return (input, cur) => {
|
|
1512
|
+
let pos = cur;
|
|
1513
|
+
const len = input.length;
|
|
1514
|
+
for (; ; ) {
|
|
1515
|
+
const c = input.charCodeAt(pos);
|
|
1516
|
+
if (pos < len && inRanges2(c, ranges)) {
|
|
1517
|
+
pos++;
|
|
1518
|
+
continue;
|
|
1519
|
+
}
|
|
1520
|
+
if (single ? c === c0 : leaders.includes(c)) {
|
|
1521
|
+
pos++;
|
|
1522
|
+
while (pos < len) {
|
|
1523
|
+
const cc = input.charCodeAt(pos);
|
|
1524
|
+
if (cc === 10 || cc === 13) break;
|
|
1525
|
+
pos++;
|
|
1526
|
+
}
|
|
1639
1527
|
continue;
|
|
1640
1528
|
}
|
|
1641
1529
|
break;
|
|
1642
1530
|
}
|
|
1643
|
-
|
|
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);
|
|
1531
|
+
return pos;
|
|
1532
|
+
};
|
|
1662
1533
|
}
|
|
1663
|
-
function
|
|
1664
|
-
const
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
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;
|
|
1672
1553
|
}
|
|
1673
1554
|
}
|
|
1555
|
+
arms.push(body.slice(start));
|
|
1556
|
+
return arms;
|
|
1674
1557
|
}
|
|
1675
|
-
function
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
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);
|
|
1681
1568
|
}
|
|
1682
|
-
|
|
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);
|
|
1683
1580
|
}
|
|
1684
1581
|
|
|
1685
|
-
// src/
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
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 } : {}
|
|
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
|
|
1707
1597
|
};
|
|
1708
|
-
|
|
1709
|
-
ctx.
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
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
|
+
}
|
|
1718
1626
|
}
|
|
1719
|
-
function
|
|
1720
|
-
|
|
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 };
|
|
1627
|
+
function orSentinel(a, b) {
|
|
1628
|
+
if (b === void 0) return a;
|
|
1726
1629
|
return {
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
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;
|
|
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);
|
|
1740
1637
|
}
|
|
1741
|
-
|
|
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;
|
|
1638
|
+
};
|
|
1758
1639
|
}
|
|
1759
|
-
function
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
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);
|
|
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 } };
|
|
1784
1652
|
}
|
|
1785
|
-
}
|
|
1653
|
+
}
|
|
1654
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
1786
1655
|
}
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
}
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
if (
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
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;
|
|
1811
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 }
|
|
1812
1729
|
};
|
|
1813
1730
|
}
|
|
1814
|
-
|
|
1815
|
-
|
|
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
|
+
};
|
|
1816
1773
|
}
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
return scan.end;
|
|
1774
|
+
|
|
1775
|
+
// src/combinators/expect.ts
|
|
1776
|
+
function deriveExpected(c) {
|
|
1777
|
+
return [...new Set(derive(c, /* @__PURE__ */ new Set()))];
|
|
1822
1778
|
}
|
|
1823
|
-
function
|
|
1824
|
-
const
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
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
|
+
}
|
|
1829
1851
|
}
|
|
1830
|
-
function
|
|
1831
|
-
const
|
|
1832
|
-
const
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
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
|
+
};
|
|
1842
1873
|
}
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
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);
|
|
1852
1965
|
}
|
|
1966
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
1853
1967
|
}
|
|
1854
|
-
|
|
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 } };
|
|
1855
1986
|
}
|
|
1856
|
-
return pos;
|
|
1857
1987
|
};
|
|
1858
1988
|
}
|
|
1859
|
-
function
|
|
1860
|
-
|
|
1861
|
-
const
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
for (let i = 0; i < ranges.length; i++) {
|
|
1866
|
-
const r = ranges[i];
|
|
1867
|
-
if (cp >= r[0] && cp <= r[1]) return true;
|
|
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);
|
|
1868
1995
|
}
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
}
|
|
1880
|
-
|
|
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;
|
|
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 };
|
|
1901
2008
|
}
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
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 };
|
|
1906
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}`;
|
|
1907
2023
|
return null;
|
|
1908
2024
|
}
|
|
1909
|
-
function
|
|
1910
|
-
if (
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
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 };
|
|
1917
2043
|
}
|
|
1918
|
-
function
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
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) });
|
|
1928
2066
|
continue;
|
|
1929
2067
|
}
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
if (cc === 10 || cc === 13) break;
|
|
1935
|
-
pos++;
|
|
1936
|
-
}
|
|
1937
|
-
continue;
|
|
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 });
|
|
1938
2072
|
}
|
|
1939
|
-
break;
|
|
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) {
|
|
@@ -2810,6 +2899,123 @@ function noTrivia(root) {
|
|
|
2810
2899
|
return parser({ trivia: null }, root);
|
|
2811
2900
|
}
|
|
2812
2901
|
|
|
2902
|
+
// src/cst/reflection.ts
|
|
2903
|
+
var GRAMMAR_REFLECTION = /* @__PURE__ */ Symbol.for("parseman.grammarReflection");
|
|
2904
|
+
function childrenOf(def) {
|
|
2905
|
+
switch (def.tag) {
|
|
2906
|
+
case "sequence":
|
|
2907
|
+
case "choice":
|
|
2908
|
+
return def.parsers;
|
|
2909
|
+
case "dispatch":
|
|
2910
|
+
return [
|
|
2911
|
+
def.selector,
|
|
2912
|
+
...def.cases.map((c) => c.parser),
|
|
2913
|
+
...def.matchers ? def.matchers.map((c) => c.parser) : [],
|
|
2914
|
+
...def.otherwise ? [def.otherwise] : []
|
|
2915
|
+
];
|
|
2916
|
+
case "many":
|
|
2917
|
+
case "oneOrMore":
|
|
2918
|
+
case "optional":
|
|
2919
|
+
case "attempt":
|
|
2920
|
+
case "transform":
|
|
2921
|
+
case "trivia":
|
|
2922
|
+
case "token":
|
|
2923
|
+
case "leaf":
|
|
2924
|
+
case "label":
|
|
2925
|
+
case "field":
|
|
2926
|
+
case "not":
|
|
2927
|
+
case "peek":
|
|
2928
|
+
case "node":
|
|
2929
|
+
case "withCtx":
|
|
2930
|
+
case "recover":
|
|
2931
|
+
case "expect":
|
|
2932
|
+
return [def.parser];
|
|
2933
|
+
case "grammar":
|
|
2934
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
2935
|
+
case "sepBy":
|
|
2936
|
+
return [def.parser, def.separator];
|
|
2937
|
+
case "skip":
|
|
2938
|
+
return [def.main, def.skipped];
|
|
2939
|
+
case "scanTo":
|
|
2940
|
+
return [def.sentinel, ...def.skip];
|
|
2941
|
+
case "literal":
|
|
2942
|
+
case "regex":
|
|
2943
|
+
case "keywords":
|
|
2944
|
+
case "routed":
|
|
2945
|
+
case "guard":
|
|
2946
|
+
case "lazy":
|
|
2947
|
+
case "unknown":
|
|
2948
|
+
return [];
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
function addNode(out, def) {
|
|
2952
|
+
if (def.type === void 0) return;
|
|
2953
|
+
const existing = out.get(def.type);
|
|
2954
|
+
if (existing === void 0) {
|
|
2955
|
+
out.set(def.type, def.tags === void 0 ? [] : [...def.tags]);
|
|
2956
|
+
return;
|
|
2957
|
+
}
|
|
2958
|
+
if (def.tags === void 0) return;
|
|
2959
|
+
for (const tag of def.tags) {
|
|
2960
|
+
if (!existing.includes(tag)) existing.push(tag);
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2963
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
2964
|
+
if (seen.has(parser2)) return;
|
|
2965
|
+
seen.add(parser2);
|
|
2966
|
+
const def = parser2._def;
|
|
2967
|
+
if (def.tag === "lazy") {
|
|
2968
|
+
if (followLazy) {
|
|
2969
|
+
try {
|
|
2970
|
+
collectFromCombinator(def.thunk(), out, seen, followLazy);
|
|
2971
|
+
} catch {
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
return;
|
|
2975
|
+
}
|
|
2976
|
+
if (def.tag === "node") addNode(out, def);
|
|
2977
|
+
for (const child of childrenOf(def)) collectFromCombinator(child, out, seen, followLazy);
|
|
2978
|
+
}
|
|
2979
|
+
function collectGrammarReflection(ruleMap, opts) {
|
|
2980
|
+
const byType = /* @__PURE__ */ new Map();
|
|
2981
|
+
const followLazy = opts?.followLazy !== false;
|
|
2982
|
+
for (const [, rule] of ruleMap) {
|
|
2983
|
+
if (!followLazy && rule._def.tag === "lazy") {
|
|
2984
|
+
try {
|
|
2985
|
+
const resolved = rule._def.thunk();
|
|
2986
|
+
if (resolved._def.tag !== "lazy") collectFromCombinator(resolved, byType, /* @__PURE__ */ new Set(), false);
|
|
2987
|
+
} catch {
|
|
2988
|
+
}
|
|
2989
|
+
continue;
|
|
2990
|
+
}
|
|
2991
|
+
collectFromCombinator(rule, byType, /* @__PURE__ */ new Set(), followLazy);
|
|
2992
|
+
}
|
|
2993
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
2994
|
+
}
|
|
2995
|
+
function mergeGrammarReflections(reflections) {
|
|
2996
|
+
const byType = /* @__PURE__ */ new Map();
|
|
2997
|
+
for (const reflection of reflections) {
|
|
2998
|
+
for (const node2 of reflection.nodes) {
|
|
2999
|
+
const tags = byType.get(node2.type);
|
|
3000
|
+
if (tags === void 0) {
|
|
3001
|
+
byType.set(node2.type, [...node2.tags]);
|
|
3002
|
+
continue;
|
|
3003
|
+
}
|
|
3004
|
+
for (const tag of node2.tags) {
|
|
3005
|
+
if (!tags.includes(tag)) tags.push(tag);
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
}
|
|
3009
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
3010
|
+
}
|
|
3011
|
+
function attachGrammarReflection(grammar, reflection) {
|
|
3012
|
+
Object.defineProperty(grammar, GRAMMAR_REFLECTION, { value: reflection, enumerable: false, configurable: true });
|
|
3013
|
+
return grammar;
|
|
3014
|
+
}
|
|
3015
|
+
function grammarReflectionSource(reflection) {
|
|
3016
|
+
return `{ nodes: ${JSON.stringify(reflection.nodes)} }`;
|
|
3017
|
+
}
|
|
3018
|
+
|
|
2813
3019
|
// src/combinators/parser.ts
|
|
2814
3020
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2815
3021
|
function tagRule(r, key) {
|
|
@@ -2908,6 +3114,7 @@ function rules(a, b) {
|
|
|
2908
3114
|
enumerable: false,
|
|
2909
3115
|
configurable: true
|
|
2910
3116
|
});
|
|
3117
|
+
attachGrammarReflection(cache, collectGrammarReflection(Object.keys(definitions).map((key) => [key, cache[key]])));
|
|
2911
3118
|
return cache;
|
|
2912
3119
|
}
|
|
2913
3120
|
|
|
@@ -3228,13 +3435,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3228
3435
|
const collapse = opts?.collapse === true;
|
|
3229
3436
|
const captureTrivia = opts?.captureTrivia === true;
|
|
3230
3437
|
const trailingTrivia = opts?.trailingTrivia === true;
|
|
3438
|
+
const tags = opts?.tags;
|
|
3231
3439
|
if (unwrap && collapse) {
|
|
3232
3440
|
throw new Error("node() options cannot set both unwrap and collapse");
|
|
3233
3441
|
}
|
|
3234
3442
|
if (project !== void 0 && (unwrap || collapse)) {
|
|
3235
3443
|
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
3236
3444
|
}
|
|
3237
|
-
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {} } : baseDef;
|
|
3445
|
+
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
|
|
3238
3446
|
const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
3239
3447
|
const clonesState = build ? buildReadsState(def) : project === void 0;
|
|
3240
3448
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
@@ -3280,7 +3488,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3280
3488
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3281
3489
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3282
3490
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3283
|
-
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
3491
|
+
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
3284
3492
|
const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
|
|
3285
3493
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3286
3494
|
pushCstChild(ctx, built, rawEntry);
|
|
@@ -3330,6 +3538,25 @@ function trivia(combinator) {
|
|
|
3330
3538
|
parse: combinator.parse.bind(combinator)
|
|
3331
3539
|
};
|
|
3332
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
|
+
}
|
|
3333
3560
|
function label(name, combinator) {
|
|
3334
3561
|
return {
|
|
3335
3562
|
_tag: combinator._tag,
|
|
@@ -3376,6 +3603,7 @@ function token(root) {
|
|
|
3376
3603
|
const savedRaw = ctx._cstRawChildren;
|
|
3377
3604
|
const savedTriviaLog = ctx._cstTriviaLog;
|
|
3378
3605
|
const savedOuterTriviaLog = ctx._triviaLog;
|
|
3606
|
+
const savedRootTriviaLog = ctx._rootTriviaLog;
|
|
3379
3607
|
const wasCapturing = cstCaptureActive(ctx);
|
|
3380
3608
|
ctx.trivia = void 0;
|
|
3381
3609
|
ctx.triviaKindLabels = void 0;
|
|
@@ -3385,6 +3613,7 @@ function token(root) {
|
|
|
3385
3613
|
ctx._cstRawChildren = void 0;
|
|
3386
3614
|
ctx._cstTriviaLog = void 0;
|
|
3387
3615
|
delete ctx._triviaLog;
|
|
3616
|
+
delete ctx._rootTriviaLog;
|
|
3388
3617
|
let result;
|
|
3389
3618
|
try {
|
|
3390
3619
|
result = root.parse(input, pos, ctx);
|
|
@@ -3398,6 +3627,8 @@ function token(root) {
|
|
|
3398
3627
|
ctx._cstTriviaLog = savedTriviaLog;
|
|
3399
3628
|
if (savedOuterTriviaLog === void 0) delete ctx._triviaLog;
|
|
3400
3629
|
else ctx._triviaLog = savedOuterTriviaLog;
|
|
3630
|
+
if (savedRootTriviaLog === void 0) delete ctx._rootTriviaLog;
|
|
3631
|
+
else ctx._rootTriviaLog = savedRootTriviaLog;
|
|
3401
3632
|
}
|
|
3402
3633
|
if (!result.ok) return result;
|
|
3403
3634
|
const span = result.span;
|
|
@@ -3452,7 +3683,7 @@ function leaf(root, fn) {
|
|
|
3452
3683
|
}
|
|
3453
3684
|
|
|
3454
3685
|
// src/version.ts
|
|
3455
|
-
var PARSEMAN_VERSION = "0.
|
|
3686
|
+
var PARSEMAN_VERSION = "0.44.0";
|
|
3456
3687
|
|
|
3457
3688
|
// src/cst/host-mode.ts
|
|
3458
3689
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -3518,7 +3749,7 @@ var SUGGESTIONS = {
|
|
|
3518
3749
|
function classifyBroadArm(arm, resolve2) {
|
|
3519
3750
|
const seen = /* @__PURE__ */ new Set();
|
|
3520
3751
|
const relabel = (inner, cause, detail) => ({ cause, detail, ...inner?.unresolvedExternal ? { unresolvedExternal: true } : {} });
|
|
3521
|
-
const
|
|
3752
|
+
const walk = (p) => {
|
|
3522
3753
|
if (seen.has(p)) return { cause: "ref-cycle", detail: "ref cycle" };
|
|
3523
3754
|
seen.add(p);
|
|
3524
3755
|
const d = p._def;
|
|
@@ -3532,7 +3763,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3532
3763
|
// peek() CARRIES its body's first-set, so it is only broad when the body is
|
|
3533
3764
|
// (or the body is nullable) — walk in for the real cause.
|
|
3534
3765
|
case "peek":
|
|
3535
|
-
return
|
|
3766
|
+
return walk(d.parser);
|
|
3536
3767
|
case "scanTo":
|
|
3537
3768
|
return { cause: "broad-recognizer", detail: "scanTo (any first char)" };
|
|
3538
3769
|
// `guard` (the `gate()` state predicate) has a genuinely-`any` first-set of
|
|
@@ -3546,7 +3777,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3546
3777
|
case "attempt":
|
|
3547
3778
|
case "withCtx":
|
|
3548
3779
|
case "recover":
|
|
3549
|
-
return
|
|
3780
|
+
return walk(d.parser);
|
|
3550
3781
|
case "lazy": {
|
|
3551
3782
|
const name = p._ruleName;
|
|
3552
3783
|
let target;
|
|
@@ -3558,13 +3789,13 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3558
3789
|
return { cause: "cross-artifact-ref", detail: `unresolved ref${name ? ` g.${name}` : ""}`, unresolvedExternal: name !== void 0 };
|
|
3559
3790
|
target = bound;
|
|
3560
3791
|
}
|
|
3561
|
-
const inner =
|
|
3792
|
+
const inner = walk(target);
|
|
3562
3793
|
if (name !== void 0) return inner ? relabel(inner, "cross-artifact-ref", `via ref g.${name} \u2192 ${inner.detail}`) : null;
|
|
3563
3794
|
return inner;
|
|
3564
3795
|
}
|
|
3565
3796
|
case "optional":
|
|
3566
3797
|
case "many": {
|
|
3567
|
-
const inner =
|
|
3798
|
+
const inner = walk(d.parser);
|
|
3568
3799
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3569
3800
|
}
|
|
3570
3801
|
case "oneOrMore":
|
|
@@ -3577,9 +3808,9 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3577
3808
|
case "node":
|
|
3578
3809
|
case "grammar":
|
|
3579
3810
|
case "expect":
|
|
3580
|
-
return
|
|
3811
|
+
return walk(d.parser);
|
|
3581
3812
|
case "skip":
|
|
3582
|
-
return
|
|
3813
|
+
return walk(d.main);
|
|
3583
3814
|
case "sequence": {
|
|
3584
3815
|
let sawNullablePrefix = false;
|
|
3585
3816
|
for (const t of d.parsers) {
|
|
@@ -3588,7 +3819,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3588
3819
|
continue;
|
|
3589
3820
|
}
|
|
3590
3821
|
if (isAny(firstSetOf(t, /* @__PURE__ */ new Set(), resolve2))) {
|
|
3591
|
-
const inner =
|
|
3822
|
+
const inner = walk(t);
|
|
3592
3823
|
if (sawNullablePrefix)
|
|
3593
3824
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3594
3825
|
return inner ?? { cause: "broad-recognizer", detail: "sequence leading term is broad" };
|
|
@@ -3603,18 +3834,18 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3603
3834
|
}
|
|
3604
3835
|
case "choice": {
|
|
3605
3836
|
for (const a of d.parsers) {
|
|
3606
|
-
const r =
|
|
3837
|
+
const r = walk(a);
|
|
3607
3838
|
if (r) return relabel(r, r.cause, `choice arm \u2192 ${r.detail}`);
|
|
3608
3839
|
}
|
|
3609
3840
|
return null;
|
|
3610
3841
|
}
|
|
3611
3842
|
case "dispatch":
|
|
3612
|
-
return
|
|
3843
|
+
return walk(d.selector);
|
|
3613
3844
|
default:
|
|
3614
3845
|
return { cause: "broad-recognizer", detail: `unmodeled construct (${d.tag})` };
|
|
3615
3846
|
}
|
|
3616
3847
|
};
|
|
3617
|
-
return
|
|
3848
|
+
return walk(arm) ?? { cause: "broad-recognizer", detail: "broad (cause not localized)" };
|
|
3618
3849
|
}
|
|
3619
3850
|
function peelToLeading(arm) {
|
|
3620
3851
|
let d = arm._def;
|
|
@@ -3816,7 +4047,7 @@ function formatGatingWarnings(report) {
|
|
|
3816
4047
|
|
|
3817
4048
|
// src/analysis/duplication.ts
|
|
3818
4049
|
var siteToString = (s) => s.path === "" ? s.rule : `${s.rule} \u203A ${s.path}`;
|
|
3819
|
-
function
|
|
4050
|
+
function childrenOf2(d) {
|
|
3820
4051
|
switch (d.tag) {
|
|
3821
4052
|
case "sequence":
|
|
3822
4053
|
case "choice":
|
|
@@ -3950,7 +4181,7 @@ function render(p, depth = 3) {
|
|
|
3950
4181
|
break;
|
|
3951
4182
|
}
|
|
3952
4183
|
if (depth <= 0) return `${d.tag}(\u2026)`;
|
|
3953
|
-
const kids =
|
|
4184
|
+
const kids = childrenOf2(d).map((k) => render(k, depth - 1));
|
|
3954
4185
|
switch (d.tag) {
|
|
3955
4186
|
case "sequence":
|
|
3956
4187
|
return `sequence(${kids.join(", ")})`;
|
|
@@ -4145,7 +4376,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4145
4376
|
if (hit !== void 0) return hit;
|
|
4146
4377
|
const d = p._def;
|
|
4147
4378
|
shapeCache.set(p, interner.hole);
|
|
4148
|
-
const kids =
|
|
4379
|
+
const kids = childrenOf2(d);
|
|
4149
4380
|
const id = interner.of(`${payloadKey(p, d)}|${kids.map(shapeOf).join(",")}`);
|
|
4150
4381
|
shapeCache.set(p, id);
|
|
4151
4382
|
return id;
|
|
@@ -4155,7 +4386,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4155
4386
|
if (hit !== void 0) return hit;
|
|
4156
4387
|
sizeCache.set(p, 1);
|
|
4157
4388
|
let n = 1;
|
|
4158
|
-
for (const k of
|
|
4389
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4159
4390
|
sizeCache.set(p, n);
|
|
4160
4391
|
return n;
|
|
4161
4392
|
};
|
|
@@ -4168,7 +4399,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4168
4399
|
visited.set(p, { p, d, site: here, shape: shapeOf(p), size: sizeOf(p), enclosingNode, enclosingReducer });
|
|
4169
4400
|
const inner = d.tag === "node" ? d.type ?? "(anonymous)" : enclosingNode;
|
|
4170
4401
|
const innerReducer = enclosingReducer || d.tag === "node" && (d.build !== void 0 || d.buildSrc !== void 0) || d.tag === "transform" || d.tag === "leaf";
|
|
4171
|
-
const kids =
|
|
4402
|
+
const kids = childrenOf2(d);
|
|
4172
4403
|
kids.forEach((k, i) => {
|
|
4173
4404
|
const seg = segment(d, i);
|
|
4174
4405
|
visit(k, here.rule, here.path === "" ? seg : `${here.path} \u203A ${seg}`, inner, innerReducer);
|
|
@@ -4228,7 +4459,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4228
4459
|
function markSubtree(p, into) {
|
|
4229
4460
|
if (into.has(p)) return;
|
|
4230
4461
|
into.add(p);
|
|
4231
|
-
for (const k of
|
|
4462
|
+
for (const k of childrenOf2(p._def)) markSubtree(k, into);
|
|
4232
4463
|
}
|
|
4233
4464
|
var stripMembers = (f) => {
|
|
4234
4465
|
const { _members, ...rest } = f;
|
|
@@ -4268,7 +4499,7 @@ function findNearDuplicates(visited, interner, shapeOf, minSize) {
|
|
|
4268
4499
|
if (hit !== void 0) return hit;
|
|
4269
4500
|
holeCache.set(p, []);
|
|
4270
4501
|
const d = p._def;
|
|
4271
|
-
const kids =
|
|
4502
|
+
const kids = childrenOf2(d);
|
|
4272
4503
|
const kidShapes = kids.map(shapeOf);
|
|
4273
4504
|
const payload = payloadKey(p, d);
|
|
4274
4505
|
const out2 = [];
|
|
@@ -4329,7 +4560,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4329
4560
|
let cur = [...members];
|
|
4330
4561
|
for (let guard2 = 0; guard2 < 64; guard2++) {
|
|
4331
4562
|
const d0 = cur[0]._def;
|
|
4332
|
-
const kidLists = cur.map((c) =>
|
|
4563
|
+
const kidLists = cur.map((c) => childrenOf2(c._def));
|
|
4333
4564
|
const arity = kidLists[0].length;
|
|
4334
4565
|
if (kidLists.some((k) => k.length !== arity) || arity === 0) break;
|
|
4335
4566
|
const diff = [];
|
|
@@ -4342,7 +4573,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4342
4573
|
path2.push(i);
|
|
4343
4574
|
defs.push(d0);
|
|
4344
4575
|
cur = kidLists.map((k) => k[i]);
|
|
4345
|
-
const nextArity =
|
|
4576
|
+
const nextArity = childrenOf2(cur[0]._def).length;
|
|
4346
4577
|
const samePayload = cur.every((c) => payloadKey(c, c._def) === payloadKey(cur[0], cur[0]._def));
|
|
4347
4578
|
if (!samePayload || nextArity === 0) break;
|
|
4348
4579
|
}
|
|
@@ -4350,7 +4581,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4350
4581
|
let slotSize = 0;
|
|
4351
4582
|
const sizeOf = (p) => {
|
|
4352
4583
|
let n = 1;
|
|
4353
|
-
for (const k of
|
|
4584
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4354
4585
|
return n;
|
|
4355
4586
|
};
|
|
4356
4587
|
for (const c of cur) slotSize = Math.max(slotSize, sizeOf(c));
|
|
@@ -4359,7 +4590,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4359
4590
|
function renderWithHole(p, path2, depth = 0) {
|
|
4360
4591
|
if (depth === path2.length) return "\u2039slot\u203A";
|
|
4361
4592
|
const d = p._def;
|
|
4362
|
-
const kids =
|
|
4593
|
+
const kids = childrenOf2(d);
|
|
4363
4594
|
const idx = path2[depth];
|
|
4364
4595
|
const parts = kids.map((k, i) => i === idx ? renderWithHole(k, path2, depth + 1) : render(k, 2));
|
|
4365
4596
|
switch (d.tag) {
|
|
@@ -4817,7 +5048,7 @@ function capturesPositionally(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4817
5048
|
seen.add(p);
|
|
4818
5049
|
const d = p._def;
|
|
4819
5050
|
if (d.tag === "field" || d.tag === "label") return true;
|
|
4820
|
-
for (const k of
|
|
5051
|
+
for (const k of childrenOf2(d)) if (capturesPositionally(k, seen)) return true;
|
|
4821
5052
|
return false;
|
|
4822
5053
|
}
|
|
4823
5054
|
function detectHandRolledSepBy(terms, shapeOf) {
|
|
@@ -4923,7 +5154,7 @@ function nestedNodeTypes(root, out, seen, isRoot) {
|
|
|
4923
5154
|
}
|
|
4924
5155
|
return;
|
|
4925
5156
|
}
|
|
4926
|
-
for (const k of
|
|
5157
|
+
for (const k of childrenOf2(d)) nestedNodeTypes(k, out, seen, false);
|
|
4927
5158
|
}
|
|
4928
5159
|
var MAX_LOST_TYPES = 8;
|
|
4929
5160
|
function findStructureLoss(visited, resolve2) {
|
|
@@ -5350,9 +5581,18 @@ function buildGrammarPlan(entry, winners) {
|
|
|
5350
5581
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
|
|
5351
5582
|
}
|
|
5352
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
|
+
|
|
5353
5589
|
// src/compiler/scannable-run.ts
|
|
5354
5590
|
var BACKSLASH = 92;
|
|
5355
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(", ");
|
|
5356
5596
|
function classToRanges(cls) {
|
|
5357
5597
|
if (cls === "\\d") return shorthandRanges("d");
|
|
5358
5598
|
if (cls === "\\w") return shorthandRanges("w");
|
|
@@ -6391,13 +6631,15 @@ function scanBranch(shape, mint) {
|
|
|
6391
6631
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6392
6632
|
return [...m.setup, ` if (${m.end} > _e) { _e = ${m.end}; continue }`].join("\n");
|
|
6393
6633
|
}
|
|
6394
|
-
function scanBranchLabeled(shape, kindIndex, mint) {
|
|
6634
|
+
function scanBranchLabeled(shape, kindIndex, label2, mint) {
|
|
6395
6635
|
const m = emitShapeMatch(shape, "_e", mint, " ", "c");
|
|
6396
6636
|
return [
|
|
6397
6637
|
...m.setup,
|
|
6398
6638
|
` if (${m.end} > _e) {`,
|
|
6399
6639
|
` if (_cap) {`,
|
|
6400
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)`,
|
|
6401
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})`,
|
|
6402
6644
|
` }`,
|
|
6403
6645
|
` _e = ${m.end}`,
|
|
@@ -6457,6 +6699,11 @@ var CAP_RECORD = [
|
|
|
6457
6699
|
` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
|
|
6458
6700
|
` }`
|
|
6459
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");
|
|
6460
6707
|
function composeFastLoop(shapes) {
|
|
6461
6708
|
const mint = makeMint();
|
|
6462
6709
|
return [
|
|
@@ -6485,7 +6732,7 @@ function analyzeLabeledScannableRun(trivia2) {
|
|
|
6485
6732
|
const d = getCoreRegexDef(arm.parser);
|
|
6486
6733
|
const shape = d ? scanShapeFromRegex(d.source, d.flags) : null;
|
|
6487
6734
|
if (!shape) return null;
|
|
6488
|
-
out.push({ shape, kindIndex: arm.kindIndex });
|
|
6735
|
+
out.push({ shape, kindIndex: arm.kindIndex, label: arm.label });
|
|
6489
6736
|
}
|
|
6490
6737
|
return out;
|
|
6491
6738
|
}
|
|
@@ -6494,11 +6741,13 @@ function buildLabeledScannableTriviaFnDecl(fnName, arms) {
|
|
|
6494
6741
|
return [
|
|
6495
6742
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6496
6743
|
` let _e = _pos`,
|
|
6744
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6497
6745
|
` while (_e < input.length) {`,
|
|
6498
6746
|
` const c = input.charCodeAt(_e)`,
|
|
6499
|
-
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, mint)),
|
|
6747
|
+
...arms.map((a) => scanBranchLabeled(a.shape, a.kindIndex, a.label, mint)),
|
|
6500
6748
|
` break`,
|
|
6501
6749
|
` }`,
|
|
6750
|
+
SELECTED_ROOT_FINISH,
|
|
6502
6751
|
` return _e`,
|
|
6503
6752
|
`}`
|
|
6504
6753
|
].join("\n");
|
|
@@ -6514,6 +6763,8 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6514
6763
|
` const _ce = _e + _m${i}[0].length`,
|
|
6515
6764
|
` if (_cap) {`,
|
|
6516
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})`,
|
|
6517
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})`,
|
|
6518
6769
|
` }`,
|
|
6519
6770
|
` _e = _ce`,
|
|
@@ -6525,11 +6776,13 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
|
|
|
6525
6776
|
return [
|
|
6526
6777
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6527
6778
|
` let _e = _pos`,
|
|
6779
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6528
6780
|
` while (_e < input.length) {`,
|
|
6529
6781
|
` let _matched = false`,
|
|
6530
6782
|
tryArms,
|
|
6531
6783
|
` if (!_matched) break`,
|
|
6532
6784
|
` }`,
|
|
6785
|
+
SELECTED_ROOT_FINISH,
|
|
6533
6786
|
` return _e`,
|
|
6534
6787
|
`}`
|
|
6535
6788
|
].join("\n");
|
|
@@ -6552,6 +6805,8 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6552
6805
|
` const _ce = _r${i}.span.end`,
|
|
6553
6806
|
` if (_cap) {`,
|
|
6554
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})`,
|
|
6555
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})`,
|
|
6556
6811
|
` }`,
|
|
6557
6812
|
` _e = _ce`,
|
|
@@ -6563,11 +6818,13 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
|
|
|
6563
6818
|
return [
|
|
6564
6819
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
6565
6820
|
` let _e = _pos`,
|
|
6821
|
+
` const _rootMark = _cap && _ctx._rootTriviaLog !== undefined ? _ctx._rootTriviaLog.length : 0`,
|
|
6566
6822
|
` while (_e < input.length) {`,
|
|
6567
6823
|
` let _matched = false`,
|
|
6568
6824
|
tryArms,
|
|
6569
6825
|
` if (!_matched) break`,
|
|
6570
6826
|
` }`,
|
|
6827
|
+
SELECTED_ROOT_FINISH,
|
|
6571
6828
|
` return _e`,
|
|
6572
6829
|
`}`
|
|
6573
6830
|
].join("\n");
|
|
@@ -6798,6 +7055,9 @@ function endLoweringCapture() {
|
|
|
6798
7055
|
_loweringSink = null;
|
|
6799
7056
|
return misses;
|
|
6800
7057
|
}
|
|
7058
|
+
function hasSelectedRootTrivia(ctx) {
|
|
7059
|
+
return ctx.rootTriviaClassified === true;
|
|
7060
|
+
}
|
|
6801
7061
|
function v(ctx, prefix = "_v") {
|
|
6802
7062
|
return `${prefix}${ctx.vars++}`;
|
|
6803
7063
|
}
|
|
@@ -7107,10 +7367,12 @@ function planDisjointDispatch(parsers) {
|
|
|
7107
7367
|
}
|
|
7108
7368
|
return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
7109
7369
|
}
|
|
7110
|
-
function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
|
|
7370
|
+
function captureRestoreBody(ctx, mL, mR, mTl, mLg, mF = null, mRootLg = null) {
|
|
7111
7371
|
const fieldRestore = mF ? `; if (_ctx._fields && _ctx._fields.length !== ${mF}) _ctx._fields.length = ${mF}` : "";
|
|
7112
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}`;
|
|
7113
|
-
|
|
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}`;
|
|
7114
7376
|
}
|
|
7115
7377
|
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
7116
7378
|
if (seen.has(p)) return false;
|
|
@@ -7320,7 +7582,7 @@ function emitFallible(inner, ctx, pos, swallow = false) {
|
|
|
7320
7582
|
`${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
|
|
7321
7583
|
`${ind0}}`,
|
|
7322
7584
|
...mL ? [
|
|
7323
|
-
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
|
|
7585
|
+
`${ind0}if (!${okV}) { ${captureRestoreBody(ctx, mL, mR, mTl, null, mF)} }`
|
|
7324
7586
|
] : []
|
|
7325
7587
|
];
|
|
7326
7588
|
return { stmts, okVar: okV, valVar: valV, endVar: endV, mayCommit };
|
|
@@ -7517,11 +7779,13 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7517
7779
|
const markV = v(ctx, "_mk");
|
|
7518
7780
|
const markTl = v(ctx, "_mktl");
|
|
7519
7781
|
const markLog = v(ctx, "_mklg");
|
|
7782
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7520
7783
|
const scanEndV = v(ctx, "_sne");
|
|
7521
7784
|
stmts.push(
|
|
7522
7785
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7523
7786
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7524
7787
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7788
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7525
7789
|
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7526
7790
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7527
7791
|
);
|
|
@@ -7530,17 +7794,19 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7530
7794
|
const endAfterV = v(ctx, "_sea");
|
|
7531
7795
|
stmts.push(
|
|
7532
7796
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7533
|
-
`${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};` : ""} }`
|
|
7534
7798
|
);
|
|
7535
7799
|
valueVars.push(r2.valueVar);
|
|
7536
7800
|
continue;
|
|
7537
7801
|
} else {
|
|
7538
7802
|
const trivFn = ensureTriviaFn(ctx);
|
|
7539
7803
|
const markLog = v(ctx, "_mklg");
|
|
7804
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
7540
7805
|
const scanEndV = v(ctx, "_sne");
|
|
7541
|
-
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";
|
|
7542
7807
|
stmts.push(
|
|
7543
7808
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7809
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
7544
7810
|
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7545
7811
|
...emitLineTrack(ctx, curV, scanEndV)
|
|
7546
7812
|
);
|
|
@@ -7549,7 +7815,7 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7549
7815
|
const endAfterV = v(ctx, "_sea");
|
|
7550
7816
|
stmts.push(
|
|
7551
7817
|
`${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
|
|
7552
|
-
`${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};` : ""} }`
|
|
7553
7819
|
);
|
|
7554
7820
|
valueVars.push(r2.valueVar);
|
|
7555
7821
|
continue;
|
|
@@ -7791,6 +8057,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7791
8057
|
const selectorRawMark = selectorNeedsRollback ? v(ctx, "_dsr") : null;
|
|
7792
8058
|
const selectorTriviaMark = selectorNeedsRollback ? v(ctx, "_dst") : null;
|
|
7793
8059
|
const selectorLogMark = selectorNeedsRollback ? v(ctx, "_dsg") : null;
|
|
8060
|
+
const selectorRootLogMark = selectorNeedsRollback && hasSelectedRootTrivia(ctx) ? v(ctx, "_dsrg") : null;
|
|
7794
8061
|
const selectorFieldMark = selectorNeedsRollback ? v(ctx, "_dsf") : null;
|
|
7795
8062
|
const selectorErrorMark = selectorNeedsRollback ? v(ctx, "_dse") : null;
|
|
7796
8063
|
const selector = emit(def.selector, ctx, pos);
|
|
@@ -7803,6 +8070,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7803
8070
|
`${ind(ctx)}const ${selectorRawMark} = _ctx._cstRawChildren?.length ?? 0`,
|
|
7804
8071
|
`${ind(ctx)}const ${selectorTriviaMark} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
7805
8072
|
`${ind(ctx)}const ${selectorLogMark} = _ctx._triviaLog?.length ?? 0`,
|
|
8073
|
+
...selectorRootLogMark ? [`${ind(ctx)}const ${selectorRootLogMark} = _ctx._rootTriviaLog?.length ?? 0`] : [],
|
|
7806
8074
|
`${ind(ctx)}const ${selectorFieldMark} = _ctx._fields?.length ?? 0`,
|
|
7807
8075
|
`${ind(ctx)}const ${selectorErrorMark} = _ctx._errors?.length ?? 0`
|
|
7808
8076
|
] : [],
|
|
@@ -7822,16 +8090,18 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7822
8090
|
const mayError = mayRecordRecoveryError(parser3, !!ctx.recovery);
|
|
7823
8091
|
const errMark = mayError ? v(ctx, "_derr") : null;
|
|
7824
8092
|
const logMark = ctx.activeTrivia ? v(ctx, "_dlog") : null;
|
|
8093
|
+
const rootLogMark = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_drlog") : null;
|
|
7825
8094
|
if (usesRouted) {
|
|
7826
8095
|
stmts.push(
|
|
7827
8096
|
...routedV ? [`${ind(ctx)}const ${routedV} = _ctx._routed; _ctx._routed = { value: ${selector.valueVar}, span: { start: ${pos}, end: ${selector.endVar} } }`] : [],
|
|
7828
8097
|
...selectorLeafMark ? [
|
|
7829
|
-
`${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}`
|
|
7830
8099
|
] : []
|
|
7831
8100
|
);
|
|
7832
8101
|
}
|
|
7833
8102
|
if (errMark) stmts.push(`${ind(ctx)}const ${errMark} = _ctx._errors?.length ?? 0`);
|
|
7834
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`);
|
|
7835
8105
|
const savedRoutedLocal = ctx.routedLocal;
|
|
7836
8106
|
const savedNoHoist = ctx.noHoist;
|
|
7837
8107
|
if (usesRouted && !needsRoutedContext) {
|
|
@@ -7846,11 +8116,12 @@ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
|
|
|
7846
8116
|
stmts.push(...coverageAttempt(ctx, coverageId, pos));
|
|
7847
8117
|
const errorRollback = errMark ? `if (_ctx._errors && _ctx._errors.length !== ${errMark}) _ctx._errors.length = ${errMark}; ` : "";
|
|
7848
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}; ` : "";
|
|
7849
8120
|
const routedRollback = routedV ? `_ctx._routed = ${routedV}; ` : "";
|
|
7850
8121
|
const coverageFailure = coverageId === void 0 ? "" : `_ctx._grammarTrace?.write({ id: ${JSON.stringify(coverageId)}, phase: 'failure', offset: _ctx._fe }); `;
|
|
7851
8122
|
stmts.push(
|
|
7852
8123
|
...tail.stmts,
|
|
7853
|
-
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
8124
|
+
`${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${rootLogRollback}${coverageFailure}${committedFailBody(ctx)} }`,
|
|
7854
8125
|
...routedV ? [`${ind(ctx)}_ctx._routed = ${routedV}`] : [],
|
|
7855
8126
|
`${ind(ctx)}${outV} = ${valueMode === "tail" ? tail.valVar : `[${selector.valueVar}, ${tail.valVar}]`}`,
|
|
7856
8127
|
`${ind(ctx)}${outE} = ${tail.endVar}`,
|
|
@@ -8031,11 +8302,13 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8031
8302
|
const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
|
|
8032
8303
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
8033
8304
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
8305
|
+
const markRootLog = ctx.activeTrivia && hasSelectedRootTrivia(ctx) ? v(ctx, "_cmlrg") : null;
|
|
8034
8306
|
const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
|
|
8035
8307
|
const markErrors = armMayRecordError ? v(ctx, "_cme") : null;
|
|
8036
|
-
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}` : "";
|
|
8037
8310
|
const errorRollback = markErrors ? `if (_ctx._errors && _ctx._errors.length !== ${markErrors}) _ctx._errors.length = ${markErrors}` : "";
|
|
8038
|
-
const rollback = [captureRollback, errorRollback].filter(Boolean).join("; ");
|
|
8311
|
+
const rollback = [captureRollback, rootRollback, errorRollback].filter(Boolean).join("; ");
|
|
8039
8312
|
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
8040
8313
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
8041
8314
|
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
@@ -8050,6 +8323,7 @@ function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
|
8050
8323
|
...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
|
|
8051
8324
|
);
|
|
8052
8325
|
}
|
|
8326
|
+
if (markRootLog) stmts.push(`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog?.length ?? 0`);
|
|
8053
8327
|
if (markErrors) stmts.push(`${ind(ctx)}const ${markErrors} = _ctx._errors?.length ?? 0`);
|
|
8054
8328
|
const arm = emitFallible(p, ctx, pos, atStart);
|
|
8055
8329
|
const { stmts: armStmts, okVar, valVar, endVar } = arm;
|
|
@@ -8118,7 +8392,7 @@ function routedNeedsContextBridge(p, ctx, seen = /* @__PURE__ */ new Set()) {
|
|
|
8118
8392
|
const d = p._def;
|
|
8119
8393
|
if (d.tag === "dispatch") return false;
|
|
8120
8394
|
if (d.tag === "withCtx") return parserUsesRouted2(d.parser);
|
|
8121
|
-
return
|
|
8395
|
+
return childrenOf3(d).some((child) => routedNeedsContextBridge(child, ctx, seen));
|
|
8122
8396
|
}
|
|
8123
8397
|
function armReplayInScope(arm, ctx) {
|
|
8124
8398
|
let p = arm;
|
|
@@ -8237,21 +8511,29 @@ function emitMany(def, ctx, pos) {
|
|
|
8237
8511
|
const markV = v(ctx, "_mk");
|
|
8238
8512
|
const markTl = v(ctx, "_mktl");
|
|
8239
8513
|
const markLog = v(ctx, "_mklg");
|
|
8514
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8240
8515
|
const npV = v(ctx, "_np");
|
|
8241
8516
|
stmts.push(
|
|
8242
8517
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8243
8518
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8244
8519
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8520
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8245
8521
|
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8246
8522
|
...emitLineTrack(ctx, curV, npV)
|
|
8247
8523
|
);
|
|
8248
8524
|
itemPos = npV;
|
|
8249
|
-
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};` : ""} `;
|
|
8250
8526
|
} else {
|
|
8251
8527
|
const trivFn = ensureTriviaFn(ctx);
|
|
8528
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8252
8529
|
const npV = v(ctx, "_np");
|
|
8253
|
-
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
|
+
);
|
|
8254
8535
|
itemPos = npV;
|
|
8536
|
+
rollback = markRootLog ? `if (_ctx._rootTriviaLog && _ctx._rootTriviaLog.length !== ${markRootLog}) _ctx._rootTriviaLog.length = ${markRootLog}; ` : "";
|
|
8255
8537
|
}
|
|
8256
8538
|
}
|
|
8257
8539
|
if (!ctx.recovery && !ctx.coverage && !failsAtStart(def.parser) && needsFirstSetGuard(def.parser)) {
|
|
@@ -8311,9 +8593,10 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8311
8593
|
const raw = v(ctx, "_atr");
|
|
8312
8594
|
const trivia2 = v(ctx, "_att");
|
|
8313
8595
|
const log = v(ctx, "_atg");
|
|
8596
|
+
const rootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_atrg") : null;
|
|
8314
8597
|
const fields = v(ctx, "_atf");
|
|
8315
8598
|
const errors = v(ctx, "_ate");
|
|
8316
|
-
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}`;
|
|
8317
8600
|
const traceId = ctx.coverage?.plan.attempts.get(p);
|
|
8318
8601
|
const traceRollback = traceId === void 0 ? "" : ` _ctx._grammarTrace?.write({ id: ${JSON.stringify(traceId)}, phase: 'rollback', offset: ${pos} });`;
|
|
8319
8602
|
const preGuard = [];
|
|
@@ -8329,7 +8612,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8329
8612
|
return {
|
|
8330
8613
|
stmts: [
|
|
8331
8614
|
...preGuard,
|
|
8332
|
-
`${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`,
|
|
8333
8616
|
...inner.stmts,
|
|
8334
8617
|
...emitIfFail(ctx, `!${inner.okVar}`, `{ ${rollback};${traceRollback}${inner.mayCommit ? ` if (_ctx._fc) ${committedFailBody(ctx)};` : ""} _ctx._fe = ${pos}; ${propagateFailBody(ctx)} }`)
|
|
8335
8618
|
],
|
|
@@ -8371,16 +8654,17 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8371
8654
|
const itemFailBreak = (sepEndVar, sepRb, postSepRb) => def.trailing === void 0 ? `${sepRb}break` : `${postSepRb}${curV} = ${sepEndVar}; break`;
|
|
8372
8655
|
const postSepMarks = () => {
|
|
8373
8656
|
if (def.trailing === void 0 || !ctx.capturing) return { decl: [], rb: "" };
|
|
8374
|
-
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");
|
|
8375
8658
|
return {
|
|
8376
8659
|
decl: [
|
|
8377
8660
|
`${ind(ctx)}const ${lv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8378
8661
|
`${ind(ctx)}const ${rw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8379
8662
|
`${ind(ctx)}const ${tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8380
8663
|
`${ind(ctx)}const ${lg} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8664
|
+
...rlg ? [`${ind(ctx)}const ${rlg} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8381
8665
|
`${ind(ctx)}const ${fl} = _ctx._fields ? _ctx._fields.length : 0`
|
|
8382
8666
|
],
|
|
8383
|
-
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}; `
|
|
8384
8668
|
};
|
|
8385
8669
|
};
|
|
8386
8670
|
if (rec) {
|
|
@@ -8418,6 +8702,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8418
8702
|
const markV = v(ctx, "_mk");
|
|
8419
8703
|
const markTl = v(ctx, "_mktl");
|
|
8420
8704
|
const markLog = v(ctx, "_mklg");
|
|
8705
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8421
8706
|
const markLv = v(ctx, "_mklv");
|
|
8422
8707
|
const markFld = v(ctx, "_mkf");
|
|
8423
8708
|
const spV = v(ctx, "_sp");
|
|
@@ -8425,13 +8710,14 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8425
8710
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8426
8711
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8427
8712
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8713
|
+
...markRootLog ? [`${ind(ctx)}const ${markRootLog} = _ctx._rootTriviaLog ? _ctx._rootTriviaLog.length : 0`] : [],
|
|
8428
8714
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8429
8715
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8430
8716
|
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8431
8717
|
...emitLineTrack(ctx, curV, spV)
|
|
8432
8718
|
);
|
|
8433
8719
|
sepAtPos = spV;
|
|
8434
|
-
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}; `;
|
|
8435
8721
|
const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8436
8722
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
|
|
8437
8723
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep2.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
@@ -8449,19 +8735,30 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8449
8735
|
);
|
|
8450
8736
|
} else {
|
|
8451
8737
|
const trivFn = ensureTriviaFn(ctx);
|
|
8738
|
+
const markRootLog = hasSelectedRootTrivia(ctx) ? v(ctx, "_mkrlg") : null;
|
|
8452
8739
|
const spV = v(ctx, "_sp");
|
|
8453
|
-
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
|
+
);
|
|
8454
8745
|
sepAtPos = spV;
|
|
8455
8746
|
const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8456
8747
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
|
|
8457
|
-
|
|
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;
|
|
8458
8751
|
const npV = v(ctx, "_np");
|
|
8459
|
-
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
|
+
);
|
|
8460
8757
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8461
8758
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8462
8759
|
stmts.push(
|
|
8463
8760
|
...nextStmts,
|
|
8464
|
-
...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}; ` : "")),
|
|
8465
8762
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
8466
8763
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
8467
8764
|
);
|
|
@@ -8556,6 +8853,7 @@ function emitNot(def, ctx, pos) {
|
|
|
8556
8853
|
const raw = sinksLive ? v(ctx, "_ntr") : null;
|
|
8557
8854
|
const tl = sinksLive ? v(ctx, "_ntt") : null;
|
|
8558
8855
|
const log = sinksLive ? v(ctx, "_ntg") : null;
|
|
8856
|
+
const rootLog = sinksLive && hasSelectedRootTrivia(ctx) ? v(ctx, "_ntrg") : null;
|
|
8559
8857
|
const fields = sinksLive ? v(ctx, "_ntf") : null;
|
|
8560
8858
|
const errors = sinksLive ? v(ctx, "_nte") : null;
|
|
8561
8859
|
const { stmts, okVar } = emitFallible(def.parser, ctx, pos, true);
|
|
@@ -8563,11 +8861,11 @@ function emitNot(def, ctx, pos) {
|
|
|
8563
8861
|
return {
|
|
8564
8862
|
stmts: [
|
|
8565
8863
|
...sinksLive ? [
|
|
8566
|
-
`${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`
|
|
8567
8865
|
] : [],
|
|
8568
8866
|
...stmts,
|
|
8569
8867
|
...sinksLive ? [
|
|
8570
|
-
`${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}`
|
|
8571
8869
|
] : [],
|
|
8572
8870
|
...emitIfFail(ctx, okVar, failBody(ctx, label2, pos))
|
|
8573
8871
|
],
|
|
@@ -8703,16 +9001,17 @@ function emitToken(def, ctx, pos) {
|
|
|
8703
9001
|
const sk = v(ctx, "_tokKinds");
|
|
8704
9002
|
const stl = v(ctx, "_tokTl");
|
|
8705
9003
|
const sol = v(ctx, "_tokLog");
|
|
9004
|
+
const srl = hasSelectedRootTrivia(ctx) ? v(ctx, "_tokRootLog") : null;
|
|
8706
9005
|
const sb = v(ctx, "_tokBuf");
|
|
8707
9006
|
const valV = v(ctx, "_tok");
|
|
8708
9007
|
return {
|
|
8709
9008
|
stmts: [
|
|
8710
|
-
`${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`,
|
|
8711
|
-
`${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`,
|
|
8712
9011
|
`${i}try {`,
|
|
8713
9012
|
...reindentStmts(inner.stmts, ctx.indent + 1).map((stmt) => stmt.replace(/^(\s*)(?:const|let)\s+/, "$1var ")),
|
|
8714
9013
|
`${i}} finally {`,
|
|
8715
|
-
`${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}`,
|
|
8716
9015
|
`${i}}`,
|
|
8717
9016
|
...emitIfFail(ctx, `!${inner.okVar}`, propagateFailBody(ctx)),
|
|
8718
9017
|
`${i}const ${valV} = input.slice(${pos}, ${inner.endVar})`,
|
|
@@ -8881,7 +9180,8 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8881
9180
|
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
8882
9181
|
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
8883
9182
|
const buildExpr = structural ? `{ _tag: 'node', type: ${JSON.stringify(def.type)}, span: ${nodeSpanV}, state: ${stV} ?? null, children: ${chV} }` : mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, nodeSpanV, tlV) : def.project !== void 0 ? emitNodeProjectExpr(def.type, def.project, chV) : `${buildRef(ctx)}[${buildIdx}](${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV})`;
|
|
8884
|
-
const
|
|
9183
|
+
const hostBuildArgs = `${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV}${def.tags !== void 0 && def.tags.length > 0 ? `, ${JSON.stringify(def.tags)}` : ""}`;
|
|
9184
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${hostBuildArgs})`;
|
|
8885
9185
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
8886
9186
|
const hostCollapseExpr = structural ? `_ctx.build !== undefined && _ctx.build._parsemanCstCollapse !== undefined && ${chV}.length === 1 && ${rawV}.length === 1 && _ctx.build._parsemanCstCollapse(${JSON.stringify(def.type)}, ${chV}[0], ${chV}, ${rawV}) ? ${chV}[0] : (${ndExpr})` : ndExpr;
|
|
8887
9187
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -9190,6 +9490,8 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9190
9490
|
case "grammar": {
|
|
9191
9491
|
const savedTrivia = ctx.activeTrivia;
|
|
9192
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;
|
|
9193
9495
|
if (def.clearTrivia) {
|
|
9194
9496
|
ctx.activeTrivia = void 0;
|
|
9195
9497
|
ctx.triviaKindLabels = void 0;
|
|
@@ -9200,13 +9502,38 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9200
9502
|
}
|
|
9201
9503
|
}
|
|
9202
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++;
|
|
9203
9509
|
const r = emit(def.parser, ctx, pos);
|
|
9510
|
+
if (opaqueRootCapture) ctx.indent--;
|
|
9204
9511
|
ctx.activeTrivia = savedTrivia;
|
|
9205
9512
|
ctx.triviaKindLabels = savedKindLabels;
|
|
9206
|
-
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
|
+
}
|
|
9207
9533
|
return {
|
|
9208
9534
|
...r,
|
|
9209
9535
|
stmts: [
|
|
9536
|
+
...strictScopeCheck === void 0 ? [] : [strictScopeCheck],
|
|
9210
9537
|
`${ind(ctx)}const ${savedCapture} = _ctx.captureTrivia; _ctx.captureTrivia = true`,
|
|
9211
9538
|
...r.stmts,
|
|
9212
9539
|
`${ind(ctx)}_ctx.captureTrivia = ${savedCapture}`
|
|
@@ -9344,7 +9671,7 @@ function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9344
9671
|
return false;
|
|
9345
9672
|
}
|
|
9346
9673
|
}
|
|
9347
|
-
return
|
|
9674
|
+
return childrenOf3(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9348
9675
|
}
|
|
9349
9676
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9350
9677
|
if (seen.has(p)) return false;
|
|
@@ -9363,7 +9690,7 @@ function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9363
9690
|
case "dispatch":
|
|
9364
9691
|
return false;
|
|
9365
9692
|
default:
|
|
9366
|
-
return
|
|
9693
|
+
return childrenOf3(d).some((child) => parserUsesRouted2(child, seen));
|
|
9367
9694
|
}
|
|
9368
9695
|
}
|
|
9369
9696
|
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -9378,9 +9705,9 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9378
9705
|
return false;
|
|
9379
9706
|
}
|
|
9380
9707
|
}
|
|
9381
|
-
return
|
|
9708
|
+
return childrenOf3(d).some((child) => hasDirectBuildDef(child, seen));
|
|
9382
9709
|
}
|
|
9383
|
-
function
|
|
9710
|
+
function childrenOf3(def) {
|
|
9384
9711
|
switch (def.tag) {
|
|
9385
9712
|
case "sequence":
|
|
9386
9713
|
case "choice":
|
|
@@ -9455,7 +9782,7 @@ function subtreeSizes(roots) {
|
|
|
9455
9782
|
const def = p._def;
|
|
9456
9783
|
let s = 1;
|
|
9457
9784
|
if (def.tag !== "lazy") {
|
|
9458
|
-
for (const child of
|
|
9785
|
+
for (const child of childrenOf3(def)) s += child._def.tag === "lazy" ? 1 : sz(child);
|
|
9459
9786
|
}
|
|
9460
9787
|
sizes.set(p, s);
|
|
9461
9788
|
return s;
|
|
@@ -9476,7 +9803,7 @@ function subtreeSizes(roots) {
|
|
|
9476
9803
|
return;
|
|
9477
9804
|
}
|
|
9478
9805
|
sz(p);
|
|
9479
|
-
for (const child of
|
|
9806
|
+
for (const child of childrenOf3(def)) visit(child);
|
|
9480
9807
|
};
|
|
9481
9808
|
for (const root of roots) visit(root);
|
|
9482
9809
|
return sizes;
|
|
@@ -9486,7 +9813,7 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9486
9813
|
const recursive = /* @__PURE__ */ new Set();
|
|
9487
9814
|
const descended = /* @__PURE__ */ new Set();
|
|
9488
9815
|
const active = /* @__PURE__ */ new Set();
|
|
9489
|
-
function
|
|
9816
|
+
function walk(p) {
|
|
9490
9817
|
const def = p._def;
|
|
9491
9818
|
if (def.tag === "lazy") {
|
|
9492
9819
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
@@ -9503,17 +9830,17 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9503
9830
|
return;
|
|
9504
9831
|
}
|
|
9505
9832
|
active.add(p);
|
|
9506
|
-
|
|
9833
|
+
walk(resolved);
|
|
9507
9834
|
active.delete(p);
|
|
9508
9835
|
return;
|
|
9509
9836
|
}
|
|
9510
9837
|
if (isHoistableTag(def.tag)) {
|
|
9511
9838
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
9512
9839
|
}
|
|
9513
|
-
for (const child of
|
|
9840
|
+
for (const child of childrenOf3(def)) walk(child);
|
|
9514
9841
|
}
|
|
9515
9842
|
const rootsArr = [...roots];
|
|
9516
|
-
for (const root of rootsArr)
|
|
9843
|
+
for (const root of rootsArr) walk(root);
|
|
9517
9844
|
return { counts, recursive, sizes: subtreeSizes(rootsArr) };
|
|
9518
9845
|
}
|
|
9519
9846
|
function ruleDependencies(ruleMap) {
|
|
@@ -9523,7 +9850,7 @@ function ruleDependencies(ruleMap) {
|
|
|
9523
9850
|
for (const [name, comb] of ruleMap) {
|
|
9524
9851
|
const found = /* @__PURE__ */ new Set();
|
|
9525
9852
|
const seen = /* @__PURE__ */ new Set();
|
|
9526
|
-
const
|
|
9853
|
+
const walk = (p, isRoot) => {
|
|
9527
9854
|
const def = p._def;
|
|
9528
9855
|
const boundary = def.tag === "lazy" ? nameOf.get(p) ?? p._ruleName : nameOf.get(p);
|
|
9529
9856
|
if (!isRoot && boundary !== void 0) {
|
|
@@ -9539,12 +9866,12 @@ function ruleDependencies(ruleMap) {
|
|
|
9539
9866
|
} catch {
|
|
9540
9867
|
return;
|
|
9541
9868
|
}
|
|
9542
|
-
|
|
9869
|
+
walk(resolved, false);
|
|
9543
9870
|
return;
|
|
9544
9871
|
}
|
|
9545
|
-
for (const child of
|
|
9872
|
+
for (const child of childrenOf3(def)) walk(child, false);
|
|
9546
9873
|
};
|
|
9547
|
-
|
|
9874
|
+
walk(comb, true);
|
|
9548
9875
|
deps.set(name, [...found]);
|
|
9549
9876
|
}
|
|
9550
9877
|
return deps;
|
|
@@ -9691,6 +10018,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9691
10018
|
runDuplicationDiagnostic(combinator, opts?.duplication);
|
|
9692
10019
|
markUnusedValues(combinator);
|
|
9693
10020
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
10021
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || combinator._meta.rootTriviaClassified === true;
|
|
9694
10022
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9695
10023
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9696
10024
|
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
@@ -9717,7 +10045,11 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9717
10045
|
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9718
10046
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9719
10047
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9720
|
-
...
|
|
10048
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10049
|
+
...grammarTrivia ? {
|
|
10050
|
+
activeTrivia: grammarTrivia,
|
|
10051
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10052
|
+
} : {},
|
|
9721
10053
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
9722
10054
|
};
|
|
9723
10055
|
const r = emit(combinator, ctx, "_pos");
|
|
@@ -9865,10 +10197,11 @@ function assertRuleName(name) {
|
|
|
9865
10197
|
);
|
|
9866
10198
|
}
|
|
9867
10199
|
}
|
|
9868
|
-
function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels) {
|
|
9869
|
-
const labels = rule._meta.triviaKindLabels
|
|
9870
|
-
|
|
9871
|
-
|
|
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,"} } })`;
|
|
9872
10205
|
}
|
|
9873
10206
|
function compileRuleMap(ruleMap, opts) {
|
|
9874
10207
|
runGatingDiagnosticRules(ruleMap, opts?.gating);
|
|
@@ -9876,6 +10209,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9876
10209
|
for (const [, rule] of ruleMap) markUnusedValues(rule);
|
|
9877
10210
|
const coverageWinners = opts?.coverage ? Object.fromEntries(ruleMap.filter(([, rule]) => rule._def.tag !== "lazy")) : void 0;
|
|
9878
10211
|
const grammarTrivia = opts?.trivia;
|
|
10212
|
+
const rootTriviaClassified = grammarTrivia?._meta.rootTriviaClassified === true || ruleMap.some(([, rule]) => rule._meta.rootTriviaClassified === true);
|
|
9879
10213
|
const grammarScanSkip = opts?.scanSkip ?? ruleMap.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9880
10214
|
const grammarHostMode = opts?.hostMode ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
9881
10215
|
const grammarTrackLines = opts?.trackLines === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -9902,7 +10236,11 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9902
10236
|
lineTracking: grammarTrackLines,
|
|
9903
10237
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(ruleMap.map(([, rule]) => rule), coverageWinners) } } : {},
|
|
9904
10238
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
9905
|
-
...
|
|
10239
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10240
|
+
...grammarTrivia ? {
|
|
10241
|
+
activeTrivia: grammarTrivia,
|
|
10242
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10243
|
+
} : {},
|
|
9906
10244
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
9907
10245
|
};
|
|
9908
10246
|
const seenNames = /* @__PURE__ */ new Map();
|
|
@@ -9990,7 +10328,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9990
10328
|
return [`function(input, _pos, _ctx) {`, ...body, `}`].join("\n");
|
|
9991
10329
|
};
|
|
9992
10330
|
const objBody = perEntry.map(({ key, rule, r }) => {
|
|
9993
|
-
const src = publicRuleWrapperSource(rule, entryFnText(r, rule), ctx.triviaKindLabels);
|
|
10331
|
+
const src = publicRuleWrapperSource(rule, entryFnText(r, rule), ctx.triviaKindLabels, ctx.rootTriviaClassified);
|
|
9994
10332
|
return ` ${JSON.stringify(key)}: ${src.split("\n").join("\n ")}`;
|
|
9995
10333
|
}).join(",\n");
|
|
9996
10334
|
const replacement = [
|
|
@@ -10009,6 +10347,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
10009
10347
|
// host check passes vacuously — see `withHostMode` in the plugin.
|
|
10010
10348
|
hostMode: ctx.hostMode ?? "ast",
|
|
10011
10349
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10350
|
+
reflection: collectGrammarReflection(ruleMap),
|
|
10012
10351
|
...ctx.coverage === void 0 ? {} : { coverageDefinitions: ctx.coverage.plan.definitions }
|
|
10013
10352
|
};
|
|
10014
10353
|
}
|
|
@@ -10018,6 +10357,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10018
10357
|
if (opts?.duplication !== void 0) runDuplicationDiagnosticRules(ruleMapArg, opts.duplication);
|
|
10019
10358
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
10020
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);
|
|
10021
10361
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
10022
10362
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10023
10363
|
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
@@ -10031,6 +10371,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10031
10371
|
return false;
|
|
10032
10372
|
}
|
|
10033
10373
|
});
|
|
10374
|
+
const nodeMeta = new Map(ruleMap.map(([name, rule]) => [name, collectGrammarReflection([[name, rule]], { followLazy: false })]));
|
|
10034
10375
|
const ctx = {
|
|
10035
10376
|
vars: 0,
|
|
10036
10377
|
indent: 1,
|
|
@@ -10060,7 +10401,11 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10060
10401
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10061
10402
|
ns,
|
|
10062
10403
|
deferFirstSetRefs: true,
|
|
10063
|
-
...
|
|
10404
|
+
...rootTriviaClassified ? { rootTriviaClassified: true } : {},
|
|
10405
|
+
...grammarTrivia ? {
|
|
10406
|
+
activeTrivia: grammarTrivia,
|
|
10407
|
+
triviaKindLabels: grammarTrivia._meta.triviaKindLabels
|
|
10408
|
+
} : {},
|
|
10064
10409
|
...grammarScanSkip ? { activeScanSkip: grammarScanSkip } : {}
|
|
10065
10410
|
};
|
|
10066
10411
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -10106,7 +10451,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10106
10451
|
scanExternal(resolved);
|
|
10107
10452
|
return;
|
|
10108
10453
|
}
|
|
10109
|
-
for (const child of
|
|
10454
|
+
for (const child of childrenOf3(def)) scanExternal(child);
|
|
10110
10455
|
};
|
|
10111
10456
|
for (const [, rule] of ruleMap) scanExternal(rule);
|
|
10112
10457
|
}
|
|
@@ -10192,7 +10537,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10192
10537
|
...r.stmts,
|
|
10193
10538
|
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
10194
10539
|
`}`
|
|
10195
|
-
].join("\n"), ctx.triviaKindLabels));
|
|
10540
|
+
].join("\n"), ctx.triviaKindLabels, ctx.rootTriviaClassified));
|
|
10196
10541
|
}
|
|
10197
10542
|
const firstSets = /* @__PURE__ */ new Map();
|
|
10198
10543
|
const firstSetRecipes = /* @__PURE__ */ new Map();
|
|
@@ -10228,6 +10573,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10228
10573
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10229
10574
|
hasDirectBuilders: ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
10230
10575
|
isRecognitionOnly: !hasSemanticReduction(ruleMap.map(([, rule]) => rule), externalRefs),
|
|
10576
|
+
nodeMeta,
|
|
10231
10577
|
mfFns: mfSrcs ? [] : ctx.mapFns,
|
|
10232
10578
|
buildFns: buildSrcs ? [] : ctx.buildFns
|
|
10233
10579
|
};
|
|
@@ -10248,7 +10594,7 @@ function hasExternalRuleRef(ruleMap) {
|
|
|
10248
10594
|
if (resolved === void 0) return p._ruleName !== void 0;
|
|
10249
10595
|
return visit(resolved);
|
|
10250
10596
|
}
|
|
10251
|
-
return
|
|
10597
|
+
return childrenOf3(def).some(visit);
|
|
10252
10598
|
};
|
|
10253
10599
|
return ruleMap.some(([, rule]) => visit(rule));
|
|
10254
10600
|
}
|
|
@@ -10270,7 +10616,7 @@ function hasSemanticReduction(roots, externalRefs) {
|
|
|
10270
10616
|
return true;
|
|
10271
10617
|
}
|
|
10272
10618
|
}
|
|
10273
|
-
return
|
|
10619
|
+
return childrenOf3(def).some(visit);
|
|
10274
10620
|
};
|
|
10275
10621
|
return roots.some(visit);
|
|
10276
10622
|
}
|
|
@@ -10343,7 +10689,7 @@ function withCtx(extra, combinator) {
|
|
|
10343
10689
|
}
|
|
10344
10690
|
|
|
10345
10691
|
// src/compiler/ir-serialize.ts
|
|
10346
|
-
function
|
|
10692
|
+
function childrenOf4(def) {
|
|
10347
10693
|
switch (def.tag) {
|
|
10348
10694
|
case "sequence":
|
|
10349
10695
|
case "choice":
|
|
@@ -10407,6 +10753,10 @@ function projectOpt(project) {
|
|
|
10407
10753
|
if (project === void 0) return void 0;
|
|
10408
10754
|
return `project: ${project}`;
|
|
10409
10755
|
}
|
|
10756
|
+
function tagsOpt(tags) {
|
|
10757
|
+
if (tags === void 0 || tags.length === 0) return void 0;
|
|
10758
|
+
return `tags: ${JSON.stringify(tags)}`;
|
|
10759
|
+
}
|
|
10410
10760
|
function matcherExpr(entry) {
|
|
10411
10761
|
switch (entry.kind) {
|
|
10412
10762
|
case "startsWith":
|
|
@@ -10536,6 +10886,7 @@ function evalRuleMapIR(ir) {
|
|
|
10536
10886
|
"transform",
|
|
10537
10887
|
"skip",
|
|
10538
10888
|
"trivia",
|
|
10889
|
+
"classifiedTrivia",
|
|
10539
10890
|
"label",
|
|
10540
10891
|
"field",
|
|
10541
10892
|
"expect",
|
|
@@ -10576,6 +10927,7 @@ function evalRuleMapIR(ir) {
|
|
|
10576
10927
|
transform,
|
|
10577
10928
|
skip,
|
|
10578
10929
|
trivia,
|
|
10930
|
+
classifiedTrivia,
|
|
10579
10931
|
label,
|
|
10580
10932
|
field,
|
|
10581
10933
|
expect,
|
|
@@ -10620,7 +10972,7 @@ var Serializer = class {
|
|
|
10620
10972
|
if (target) this.assertNoRuleRef(target, seen);
|
|
10621
10973
|
return;
|
|
10622
10974
|
}
|
|
10623
|
-
for (const child of
|
|
10975
|
+
for (const child of childrenOf4(c._def)) this.assertNoRuleRef(child, seen);
|
|
10624
10976
|
}
|
|
10625
10977
|
/** A `rules()` map wraps each rule value in a named `lazy` proxy; the real body is
|
|
10626
10978
|
* its target (compileLinkable unwraps the same way). A ref INSIDE a body stays a
|
|
@@ -10684,7 +11036,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10684
11036
|
this.counts.set(c, (this.counts.get(c) ?? 0) + 1);
|
|
10685
11037
|
if ((this.counts.get(c) ?? 0) > 1) return;
|
|
10686
11038
|
active.add(c);
|
|
10687
|
-
for (const child of
|
|
11039
|
+
for (const child of childrenOf4(def)) this.analyze(child, active);
|
|
10688
11040
|
active.delete(c);
|
|
10689
11041
|
}
|
|
10690
11042
|
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
@@ -10801,12 +11153,14 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10801
11153
|
case "node": {
|
|
10802
11154
|
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
10803
11155
|
const projectEntry = projectOpt(def.project);
|
|
11156
|
+
const tagEntry = tagsOpt(def.tags);
|
|
10804
11157
|
const optEntries = [
|
|
10805
11158
|
...def.unwrap ? ["unwrap: true"] : [],
|
|
10806
11159
|
...def.collapse ? ["collapse: true"] : [],
|
|
10807
11160
|
...projectEntry === void 0 ? [] : [projectEntry],
|
|
10808
11161
|
...def.captureTrivia ? ["captureTrivia: true"] : [],
|
|
10809
|
-
...def.trailingTrivia ? ["trailingTrivia: true"] : []
|
|
11162
|
+
...def.trailingTrivia ? ["trailingTrivia: true"] : [],
|
|
11163
|
+
...tagEntry === void 0 ? [] : [tagEntry]
|
|
10810
11164
|
];
|
|
10811
11165
|
const opts = optEntries.length > 0 ? `, { ${optEntries.join(", ")} }` : "";
|
|
10812
11166
|
if (def.type === void 0) {
|
|
@@ -10820,8 +11174,11 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10820
11174
|
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
10821
11175
|
}
|
|
10822
11176
|
case "grammar": {
|
|
10823
|
-
const
|
|
10824
|
-
|
|
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)})`;
|
|
10825
11182
|
}
|
|
10826
11183
|
case "withCtx": {
|
|
10827
11184
|
if (def.extraSrc === void 0) throw new Unserializable("withCtx without extraSrc");
|
|
@@ -10844,15 +11201,16 @@ function normalizeCstCollapse(collapse) {
|
|
|
10844
11201
|
}
|
|
10845
11202
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10846
11203
|
}
|
|
10847
|
-
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10848
|
-
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
11204
|
+
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
11205
|
+
return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children2] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
10849
11206
|
}
|
|
10850
|
-
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
11207
|
+
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
10851
11208
|
if (typeof typeOrOptions === "string") {
|
|
10852
11209
|
return buildCstNode(typeOrOptions, children2 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
10853
11210
|
}
|
|
10854
11211
|
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
10855
|
-
const
|
|
11212
|
+
const materializeTags = typeOrOptions?.tags === true;
|
|
11213
|
+
const host = (type, children3, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children3 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
10856
11214
|
host._parsemanCstOutput = true;
|
|
10857
11215
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
10858
11216
|
return host;
|
|
@@ -10873,7 +11231,7 @@ function pickPieces(pieces, names) {
|
|
|
10873
11231
|
};
|
|
10874
11232
|
for (const n of names) visit(n);
|
|
10875
11233
|
const filt = (m, pc) => new Map([...m].filter(([k]) => keep.has(k) && winner.get(k) === pc));
|
|
10876
|
-
return pieces.map((pc) => ({ ...pc, keys: pc.keys.filter((k) => keep.has(k) && winner.get(k) === pc), ruleFns: filt(pc.ruleFns, pc), wrappers: filt(pc.wrappers, pc), deps: filt(pc.deps, pc) })).filter((pc) => pc.keys.length > 0);
|
|
11234
|
+
return pieces.map((pc) => ({ ...pc, keys: pc.keys.filter((k) => keep.has(k) && winner.get(k) === pc), ruleFns: filt(pc.ruleFns, pc), wrappers: filt(pc.wrappers, pc), deps: filt(pc.deps, pc), nodeMeta: filt(pc.nodeMeta, pc) })).filter((pc) => pc.keys.length > 0);
|
|
10877
11235
|
}
|
|
10878
11236
|
function fusedBody(pieces) {
|
|
10879
11237
|
for (const p of pieces) {
|
|
@@ -10911,6 +11269,7 @@ function fusedBody(pieces) {
|
|
|
10911
11269
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
10912
11270
|
];
|
|
10913
11271
|
const wrapperEntries = [...winner].map(([k, p]) => `${JSON.stringify(k)}: ${p.wrappers.get(k)}`);
|
|
11272
|
+
const reflection = mergeGrammarReflections([...winner].map(([k, p]) => p.nodeMeta.get(k) ?? { nodes: [] }));
|
|
10914
11273
|
const { mode, elided } = hostModeOfPieces(pieces);
|
|
10915
11274
|
const rawBody = [
|
|
10916
11275
|
...lines,
|
|
@@ -10919,6 +11278,7 @@ function fusedBody(pieces) {
|
|
|
10919
11278
|
"}",
|
|
10920
11279
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_MODE.description)}), { value: ${JSON.stringify(mode)}, enumerable: false })`,
|
|
10921
11280
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_ELIDED.description)}), { value: ${JSON.stringify(elided)}, enumerable: false })`,
|
|
11281
|
+
`Object.defineProperty(_map, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`,
|
|
10922
11282
|
// …and on each rule FUNCTION, because `run(map.Rule, …)` is handed the rule, not the
|
|
10923
11283
|
// map, and would otherwise have nothing to check against. Done once at fuse time,
|
|
10924
11284
|
// before any rule has been called, so it costs nothing per parse.
|
|
@@ -11050,10 +11410,6 @@ function gate(predicate) {
|
|
|
11050
11410
|
};
|
|
11051
11411
|
}
|
|
11052
11412
|
|
|
11053
|
-
// src/cst/trivia-entries.ts
|
|
11054
|
-
var EMPTY_INDICES = Object.freeze([]);
|
|
11055
|
-
var EMPTY_GAPS = Object.freeze([]);
|
|
11056
|
-
|
|
11057
11413
|
// src/cst/offset-model.ts
|
|
11058
11414
|
var { isFinite } = Number;
|
|
11059
11415
|
|
|
@@ -11209,19 +11565,19 @@ function directBuilderUnsupportedBindings(src) {
|
|
|
11209
11565
|
// src/plugin/evaluator.ts
|
|
11210
11566
|
function stripTsFromSource(node2, code) {
|
|
11211
11567
|
const cuts = [];
|
|
11212
|
-
const
|
|
11568
|
+
const walk = (n) => {
|
|
11213
11569
|
if (!n || typeof n !== "object") return;
|
|
11214
11570
|
const rec = n;
|
|
11215
11571
|
if (typeof rec.type === "string" && rec.type.startsWith("TS") && typeof rec.start === "number" && typeof rec.end === "number") {
|
|
11216
11572
|
const ex = rec.expression;
|
|
11217
11573
|
if ((rec.type === "TSAsExpression" || rec.type === "TSSatisfiesExpression" || rec.type === "TSNonNullExpression" || rec.type === "TSInstantiationExpression") && ex && typeof ex.end === "number") {
|
|
11218
11574
|
cuts.push([ex.end, rec.end]);
|
|
11219
|
-
|
|
11575
|
+
walk(rec.expression);
|
|
11220
11576
|
return;
|
|
11221
11577
|
}
|
|
11222
11578
|
if (rec.type === "TSTypeAssertion" && ex && typeof ex.start === "number") {
|
|
11223
11579
|
cuts.push([rec.start, ex.start]);
|
|
11224
|
-
|
|
11580
|
+
walk(rec.expression);
|
|
11225
11581
|
return;
|
|
11226
11582
|
}
|
|
11227
11583
|
cuts.push([rec.start, rec.end]);
|
|
@@ -11231,11 +11587,11 @@ function stripTsFromSource(node2, code) {
|
|
|
11231
11587
|
if (key === "type" || key === "start" || key === "end") continue;
|
|
11232
11588
|
const v2 = rec[key];
|
|
11233
11589
|
if (Array.isArray(v2)) {
|
|
11234
|
-
for (const item of v2)
|
|
11235
|
-
} else if (v2 && typeof v2 === "object")
|
|
11590
|
+
for (const item of v2) walk(item);
|
|
11591
|
+
} else if (v2 && typeof v2 === "object") walk(v2);
|
|
11236
11592
|
}
|
|
11237
11593
|
};
|
|
11238
|
-
|
|
11594
|
+
walk(node2);
|
|
11239
11595
|
const start = node2.start;
|
|
11240
11596
|
const end = node2.end;
|
|
11241
11597
|
if (cuts.length === 0) return code.slice(start, end);
|
|
@@ -11305,6 +11661,9 @@ var SUPPORTED = {
|
|
|
11305
11661
|
optional: (...a) => optional(a[0]),
|
|
11306
11662
|
skip: (...a) => skip(a[0], a[1]),
|
|
11307
11663
|
trivia: (...a) => trivia(a[0]),
|
|
11664
|
+
classifiedTrivia: (...a) => classifiedTrivia(
|
|
11665
|
+
a[0]
|
|
11666
|
+
),
|
|
11308
11667
|
label: (...a) => label(a[0], a[1]),
|
|
11309
11668
|
field: (...a) => field(a[0], a[1]),
|
|
11310
11669
|
noTrivia: (...a) => noTrivia(a[0]),
|
|
@@ -11414,10 +11773,38 @@ function scopeGet(scope, name, mfs) {
|
|
|
11414
11773
|
if (isCombinator(entry)) return entry;
|
|
11415
11774
|
return null;
|
|
11416
11775
|
}
|
|
11776
|
+
function unwrapStaticExpr(expr) {
|
|
11777
|
+
let cur = expr;
|
|
11778
|
+
while (cur.type === "TSAsExpression" || cur.type === "TSSatisfiesExpression" || cur.type === "TSNonNullExpression" || cur.type === "TSTypeAssertion" || cur.type === "TSInstantiationExpression" || cur.type === "ParenthesizedExpression") {
|
|
11779
|
+
if (!cur.expression) break;
|
|
11780
|
+
cur = cur.expression;
|
|
11781
|
+
}
|
|
11782
|
+
return cur;
|
|
11783
|
+
}
|
|
11417
11784
|
function staticLiteralValue(expr) {
|
|
11418
|
-
const val = expr;
|
|
11785
|
+
const val = unwrapStaticExpr(expr);
|
|
11419
11786
|
return val.type === "Literal" || val.type === "BooleanLiteral" || val.type === "NumericLiteral" ? val.value : void 0;
|
|
11420
11787
|
}
|
|
11788
|
+
function staticStringArray(expr, scope) {
|
|
11789
|
+
const id = unwrapStaticExpr(expr);
|
|
11790
|
+
if (id.type === "Identifier" && scope !== void 0 && id.name !== void 0) {
|
|
11791
|
+
const scoped = scope.get(id.name);
|
|
11792
|
+
const value = isStaticValueEntry(scoped) ? scoped.value : scoped;
|
|
11793
|
+
return Array.isArray(value) && value.every((v2) => typeof v2 === "string") ? value : void 0;
|
|
11794
|
+
}
|
|
11795
|
+
const arr = id;
|
|
11796
|
+
if (arr.type !== "ArrayExpression" || !Array.isArray(arr.elements)) return void 0;
|
|
11797
|
+
const out = [];
|
|
11798
|
+
for (const el of arr.elements) {
|
|
11799
|
+
if (!el || el.type === "SpreadElement") return void 0;
|
|
11800
|
+
const value = staticLiteralValue(el);
|
|
11801
|
+
if (typeof value !== "string") return void 0;
|
|
11802
|
+
out.push(value);
|
|
11803
|
+
}
|
|
11804
|
+
return out;
|
|
11805
|
+
}
|
|
11806
|
+
var STATIC_NODE_OPTIONS_FAILED = /* @__PURE__ */ Symbol("parseman.staticNodeOptions.failed");
|
|
11807
|
+
var STATIC_NODE_OPTIONS_NOT_OPTIONS = /* @__PURE__ */ Symbol("parseman.staticNodeOptions.notOptions");
|
|
11421
11808
|
function staticNodeProject(expr) {
|
|
11422
11809
|
const literalValue = staticLiteralValue(expr);
|
|
11423
11810
|
if (typeof literalValue === "number" && Number.isInteger(literalValue) && literalValue >= 0) {
|
|
@@ -11426,23 +11813,60 @@ function staticNodeProject(expr) {
|
|
|
11426
11813
|
if (typeof literalValue === "number" || literalValue !== void 0) return { ok: false };
|
|
11427
11814
|
return { ok: false };
|
|
11428
11815
|
}
|
|
11429
|
-
function
|
|
11430
|
-
|
|
11816
|
+
function scopedStaticValue(expr, scope) {
|
|
11817
|
+
const unwrapped = unwrapStaticExpr(expr);
|
|
11818
|
+
if (unwrapped.type !== "Identifier" || unwrapped.name === "undefined") return { found: false };
|
|
11819
|
+
if (!scope.has(unwrapped.name)) return { found: false };
|
|
11820
|
+
const scoped = scope.get(unwrapped.name);
|
|
11821
|
+
const value = isStaticValueEntry(scoped) ? scoped.value : scoped;
|
|
11822
|
+
return { found: true, value };
|
|
11823
|
+
}
|
|
11824
|
+
function staticNodeOptionsFromValue(value) {
|
|
11825
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || isCombinator(value)) return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11826
|
+
const opts = {};
|
|
11827
|
+
const rec = value;
|
|
11828
|
+
for (const name of Object.keys(rec)) {
|
|
11829
|
+
const v2 = rec[name];
|
|
11830
|
+
if (name === "unwrap" || name === "collapse" || name === "captureTrivia" || name === "trailingTrivia") {
|
|
11831
|
+
if (v2 === true) opts[name] = true;
|
|
11832
|
+
else if (v2 !== false && v2 !== void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11833
|
+
} else if (name === "project") {
|
|
11834
|
+
if (typeof v2 !== "number" || !Number.isInteger(v2) || v2 < 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11835
|
+
opts.project = v2;
|
|
11836
|
+
} else if (name === "tags") {
|
|
11837
|
+
if (!Array.isArray(v2) || !v2.every((item) => typeof item === "string")) return STATIC_NODE_OPTIONS_FAILED;
|
|
11838
|
+
opts.tags = v2;
|
|
11839
|
+
}
|
|
11840
|
+
}
|
|
11841
|
+
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia || opts.tags !== void 0 ? opts : void 0;
|
|
11842
|
+
}
|
|
11843
|
+
function staticNodeOptions(expr, scope) {
|
|
11844
|
+
const unwrapped = unwrapStaticExpr(expr);
|
|
11845
|
+
const scoped = scopedStaticValue(unwrapped, scope);
|
|
11846
|
+
if (scoped.found) return staticNodeOptionsFromValue(scoped.value);
|
|
11847
|
+
if (unwrapped.type !== "ObjectExpression") return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11431
11848
|
const opts = {};
|
|
11432
|
-
for (const prop of
|
|
11849
|
+
for (const prop of unwrapped.properties) {
|
|
11850
|
+
if (prop.type !== "Property") return STATIC_NODE_OPTIONS_FAILED;
|
|
11433
11851
|
const p = prop;
|
|
11434
|
-
if (p.computed)
|
|
11852
|
+
if (p.computed) return STATIC_NODE_OPTIONS_FAILED;
|
|
11435
11853
|
const key = p.key;
|
|
11436
11854
|
const name = key.type === "Identifier" ? key.name : key.type === "Literal" ? String(key.value) : void 0;
|
|
11437
11855
|
if (name === "unwrap" || name === "collapse" || name === "captureTrivia" || name === "trailingTrivia") {
|
|
11438
|
-
|
|
11856
|
+
const value = staticLiteralValue(p.value);
|
|
11857
|
+
if (value === true) opts[name] = true;
|
|
11858
|
+
else if (value !== false && value !== void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11439
11859
|
} else if (name === "project") {
|
|
11440
11860
|
const project = staticNodeProject(p.value);
|
|
11441
|
-
if (project?.ok === false) return
|
|
11861
|
+
if (project?.ok === false) return STATIC_NODE_OPTIONS_FAILED;
|
|
11442
11862
|
if (project !== void 0) opts.project = project.value;
|
|
11863
|
+
} else if (name === "tags") {
|
|
11864
|
+
const tags = staticStringArray(p.value, scope);
|
|
11865
|
+
if (tags === void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11866
|
+
opts.tags = tags;
|
|
11443
11867
|
}
|
|
11444
11868
|
}
|
|
11445
|
-
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia ? opts : void 0;
|
|
11869
|
+
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia || opts.tags !== void 0 ? opts : void 0;
|
|
11446
11870
|
}
|
|
11447
11871
|
function exprToCombi(node2, scope, code, mfs) {
|
|
11448
11872
|
if (node2.type === "Identifier") return scopeGet(scope, node2.name, mfs);
|
|
@@ -11517,10 +11941,23 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
11517
11941
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
11518
11942
|
if (!isCombinator(inner)) return null;
|
|
11519
11943
|
const be = buildArg;
|
|
11520
|
-
const
|
|
11944
|
+
const buildExpr = be === void 0 || be.type === "SpreadElement" ? void 0 : unwrapStaticExpr(be);
|
|
11945
|
+
const buildArgOptions = be !== void 0 && be.type !== "SpreadElement" ? staticNodeOptions(buildArg, scope) : STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11946
|
+
if (buildArgOptions === STATIC_NODE_OPTIONS_FAILED) return null;
|
|
11947
|
+
const buildArgIsOptions = buildArgOptions !== STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11948
|
+
const scopedBuild = buildExpr === void 0 ? { found: false } : scopedStaticValue(buildExpr, scope);
|
|
11949
|
+
const absentBuild = buildExpr?.type === "Identifier" && buildExpr.name === "undefined" || buildExpr !== void 0 && staticLiteralValue(buildExpr) === null || scopedBuild.found && (scopedBuild.value === void 0 || scopedBuild.value === null);
|
|
11950
|
+
const hasBuild = be !== void 0 && be.type !== "SpreadElement" && !buildArgIsOptions && !absentBuild;
|
|
11521
11951
|
const buildSrc = hasBuild ? stripTsFromSource(be, code) : void 0;
|
|
11522
|
-
|
|
11523
|
-
|
|
11952
|
+
let opts;
|
|
11953
|
+
if (buildArgIsOptions) {
|
|
11954
|
+
opts = buildArgOptions;
|
|
11955
|
+
} else if (optsArg !== void 0) {
|
|
11956
|
+
if (optsArg.type === "SpreadElement") return null;
|
|
11957
|
+
const optsResult = staticNodeOptions(optsArg, scope);
|
|
11958
|
+
if (optsResult === STATIC_NODE_OPTIONS_FAILED || optsResult === STATIC_NODE_OPTIONS_NOT_OPTIONS) return null;
|
|
11959
|
+
opts = optsResult;
|
|
11960
|
+
}
|
|
11524
11961
|
try {
|
|
11525
11962
|
const combi = explicitType !== void 0 ? node(explicitType, inner, hasBuild ? () => null : void 0, opts) : node(inner, hasBuild ? () => null : void 0, opts);
|
|
11526
11963
|
if (combi._def.tag === "node" && buildSrc !== void 0) {
|
|
@@ -11743,6 +12180,10 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
11743
12180
|
}
|
|
11744
12181
|
}
|
|
11745
12182
|
function anyValue(node2, scope, code, mfs) {
|
|
12183
|
+
if (node2.type === "TSAsExpression" || node2.type === "TSSatisfiesExpression" || node2.type === "TSNonNullExpression" || node2.type === "TSTypeAssertion" || node2.type === "TSInstantiationExpression" || node2.type === "ParenthesizedExpression") {
|
|
12184
|
+
const inner = node2.expression;
|
|
12185
|
+
return inner ? anyValue(inner, scope, code, mfs) : null;
|
|
12186
|
+
}
|
|
11746
12187
|
if (node2.type === "Literal") {
|
|
11747
12188
|
if ("regex" in node2 && node2.regex !== null && node2.regex !== void 0) {
|
|
11748
12189
|
return new RegExp(node2.regex.pattern, node2.regex.flags);
|
|
@@ -11866,6 +12307,9 @@ function collectRuleKeys(retObj) {
|
|
|
11866
12307
|
}
|
|
11867
12308
|
return out;
|
|
11868
12309
|
}
|
|
12310
|
+
function evaluateStaticValue(node2, scope, code) {
|
|
12311
|
+
return anyValue(node2, scope, code, []);
|
|
12312
|
+
}
|
|
11869
12313
|
function flattenRuleEntries(retObj, scope, code) {
|
|
11870
12314
|
const out = [];
|
|
11871
12315
|
for (const prop of retObj.properties) {
|
|
@@ -12031,6 +12475,18 @@ function referencesAny(node2, names, scope) {
|
|
|
12031
12475
|
// src/plugin/index.ts
|
|
12032
12476
|
import { createHash } from "node:crypto";
|
|
12033
12477
|
var PARSEMAN_MODULE = "parseman";
|
|
12478
|
+
function unwrapStaticExpression(expr) {
|
|
12479
|
+
let cur = expr;
|
|
12480
|
+
while (cur.type === "TSAsExpression" || cur.type === "TSSatisfiesExpression" || cur.type === "TSNonNullExpression" || cur.type === "TSTypeAssertion" || cur.type === "TSInstantiationExpression" || cur.type === "ParenthesizedExpression") {
|
|
12481
|
+
if (!cur.expression) break;
|
|
12482
|
+
cur = cur.expression;
|
|
12483
|
+
}
|
|
12484
|
+
return cur;
|
|
12485
|
+
}
|
|
12486
|
+
function isStaticNullishExpression(expr) {
|
|
12487
|
+
const unwrapped = unwrapStaticExpression(expr);
|
|
12488
|
+
return unwrapped.type === "Identifier" && unwrapped.name === "undefined" || unwrapped.type === "Literal" && unwrapped.value === null;
|
|
12489
|
+
}
|
|
12034
12490
|
var _compiledResolver = null;
|
|
12035
12491
|
function getCompiledResolver() {
|
|
12036
12492
|
return _compiledResolver ??= new ResolverFactory({
|
|
@@ -12513,6 +12969,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12513
12969
|
ruleMap: evaluated.ruleMap,
|
|
12514
12970
|
hostMode: compiled?.hostMode ?? "ast",
|
|
12515
12971
|
hostBranchElided: compiled?.hostBranchElided ?? false,
|
|
12972
|
+
reflection: compiled?.reflection ?? { nodes: [] },
|
|
12516
12973
|
...compiled?.coverageDefinitions ? { coverageDefinitions: compiled.coverageDefinitions } : {},
|
|
12517
12974
|
...evaluated.trivia ? { trivia: evaluated.trivia } : {},
|
|
12518
12975
|
...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {},
|
|
@@ -12533,7 +12990,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12533
12990
|
const mapLit = (m, stripVals = false) => `new Map([${[...m].map(
|
|
12534
12991
|
([k, v2]) => `[${JSON.stringify(k)}, ${JSON.stringify(stripVals && typeof v2 === "string" ? stripIndent(v2) : v2)}]`
|
|
12535
12992
|
).join(", ")}])`;
|
|
12536
|
-
return `{ v: ${JSON.stringify(p.v)}, ns: ${JSON.stringify(p.ns)}, keys: ${JSON.stringify(p.keys)}, prelude: ${JSON.stringify(p.prelude.map(stripIndent))}, ruleFns: ${mapLit(p.ruleFns, true)}, wrappers: ${mapLit(p.wrappers, true)}, firstSets: ${mapLit(p.firstSets)}, nullable: ${p.nullable ? mapLit(p.nullable) : "new Map()"}, firstSetRecipes: ${p.firstSetRecipes ? mapLit(p.firstSetRecipes) : "new Map()"}, deps: ${mapLit(p.deps)}, hostMode: ${JSON.stringify(p.hostMode ?? "ast")}, hostBranchElided: ${p.hostBranchElided === true}, needsEmptyTl: ${p.needsEmptyTl}, needsHostReads: ${p.needsHostReads}, hasDirectBuilders: ${p.hasDirectBuilders === true}, isRecognitionOnly: ${p.isRecognitionOnly === true}, mfFns: [], buildFns: [] }`;
|
|
12993
|
+
return `{ v: ${JSON.stringify(p.v)}, ns: ${JSON.stringify(p.ns)}, keys: ${JSON.stringify(p.keys)}, prelude: ${JSON.stringify(p.prelude.map(stripIndent))}, ruleFns: ${mapLit(p.ruleFns, true)}, wrappers: ${mapLit(p.wrappers, true)}, firstSets: ${mapLit(p.firstSets)}, nullable: ${p.nullable ? mapLit(p.nullable) : "new Map()"}, firstSetRecipes: ${p.firstSetRecipes ? mapLit(p.firstSetRecipes) : "new Map()"}, deps: ${mapLit(p.deps)}, nodeMeta: ${mapLit(p.nodeMeta)}, hostMode: ${JSON.stringify(p.hostMode ?? "ast")}, hostBranchElided: ${p.hostBranchElided === true}, needsEmptyTl: ${p.needsEmptyTl}, needsHostReads: ${p.needsHostReads}, hasDirectBuilders: ${p.hasDirectBuilders === true}, isRecognitionOnly: ${p.isRecognitionOnly === true}, mfFns: [], buildFns: [] }`;
|
|
12537
12994
|
};
|
|
12538
12995
|
const isSpread = (it) => "__spreadLocal" in it;
|
|
12539
12996
|
const isIR = (it) => "ir" in it && !("ruleFns" in it);
|
|
@@ -12542,6 +12999,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12542
12999
|
const withCarriedPieces = (grammarExpr, list) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.composedPieces'), { value: ${serializeList(list)}, enumerable: false })`;
|
|
12543
13000
|
const withLeafMarker = (grammarExpr) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.leafComposed'), { value: true, enumerable: false })`;
|
|
12544
13001
|
const withHostMode = (grammarExpr, mode, elided) => `/* @__PURE__ */ (m => { for (const k of Object.keys(m)) { Object.defineProperty(m[k], Symbol.for('parseman.fusedHostMode'), { value: ${JSON.stringify(mode)}, enumerable: false }); Object.defineProperty(m[k], Symbol.for('parseman.fusedHostElided'), { value: ${JSON.stringify(elided)}, enumerable: false }) } Object.defineProperty(m, Symbol.for('parseman.fusedHostMode'), { value: ${JSON.stringify(mode)}, enumerable: false }); Object.defineProperty(m, Symbol.for('parseman.fusedHostElided'), { value: ${JSON.stringify(elided)}, enumerable: false }); return m })(${grammarExpr})`;
|
|
13002
|
+
const withGrammarReflection = (grammarExpr, reflection) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`;
|
|
12545
13003
|
const withCoverageDefinitions = (grammarExpr, definitions) => !grammarCoverage ? grammarExpr : `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.grammarCoverageDefinitions'), { value: Object.freeze(${JSON.stringify(definitions)}.map(Object.freeze)), enumerable: false })`;
|
|
12546
13004
|
const emittedCoverageDefinitions = (source) => {
|
|
12547
13005
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -12937,7 +13395,14 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12937
13395
|
const kind = vd.kind ?? "const";
|
|
12938
13396
|
if (d.id.type === "Identifier") {
|
|
12939
13397
|
const varName = d.id.name;
|
|
12940
|
-
if (!referencesAny(init, allNames, scope))
|
|
13398
|
+
if (!referencesAny(init, allNames, scope)) {
|
|
13399
|
+
const staticValue = evaluateStaticValue(init, scope, code);
|
|
13400
|
+
if (staticValue !== null && staticValue !== void 0 || isStaticNullishExpression(init)) {
|
|
13401
|
+
;
|
|
13402
|
+
scope.set(varName, staticValue);
|
|
13403
|
+
}
|
|
13404
|
+
continue;
|
|
13405
|
+
}
|
|
12941
13406
|
if (refNames.has(varName)) {
|
|
12942
13407
|
const refEntry = scope.get(varName);
|
|
12943
13408
|
const refCombi = refEntry?.combi ?? null;
|
|
@@ -12977,6 +13442,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12977
13442
|
);
|
|
12978
13443
|
if (compiledRules.replacement !== null) {
|
|
12979
13444
|
replacement = withHostMode(replacement, compiledRules.hostMode, compiledRules.hostBranchElided);
|
|
13445
|
+
replacement = withGrammarReflection(replacement, compiledRules.reflection);
|
|
12980
13446
|
}
|
|
12981
13447
|
if (exportPrefix && pieces && !pieces.mfFns.length && !pieces.buildFns.length) {
|
|
12982
13448
|
const ir = serializeRuleMap([...compiledRules.ruleMap], compiledRules.scanSkip);
|
|
@@ -13004,7 +13470,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
13004
13470
|
if (isComposeLeafCall(init)) {
|
|
13005
13471
|
const fused = compileComposeLeafCall(init);
|
|
13006
13472
|
if (!fused) {
|
|
13007
|
-
|
|
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
|
+
);
|
|
13008
13479
|
}
|
|
13009
13480
|
replacements.push({ start: init.start, end: init.end, replacement: fused.replacement });
|
|
13010
13481
|
markUsedImportedFactories(fused.importedFactories);
|
|
@@ -13033,6 +13504,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
13033
13504
|
scope.set(varName, combiArray);
|
|
13034
13505
|
continue;
|
|
13035
13506
|
}
|
|
13507
|
+
const staticValue = evaluateStaticValue(init, scope, code);
|
|
13508
|
+
if (staticValue !== null && staticValue !== void 0 || isStaticNullishExpression(init)) {
|
|
13509
|
+
;
|
|
13510
|
+
scope.set(varName, staticValue);
|
|
13511
|
+
continue;
|
|
13512
|
+
}
|
|
13036
13513
|
if (factoryDecls.has(varName)) continue;
|
|
13037
13514
|
warn(init.start, `"${varName}" references a parseman macro import but isn't a statically-evaluable combinator`);
|
|
13038
13515
|
continue;
|
|
@@ -13108,7 +13585,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
13108
13585
|
const replacementRanges = runtimeComposeFallback ? [] : replacements.map(({ start, end }) => ({ start, end }));
|
|
13109
13586
|
const isInsideReplacement = (start, end) => replacementRanges.some((r) => start >= r.start && end <= r.end);
|
|
13110
13587
|
const importedBindingStillReferenced = (local) => {
|
|
13111
|
-
const
|
|
13588
|
+
const walk = (node2, parent, parentKey) => {
|
|
13112
13589
|
if (!node2 || typeof node2 !== "object") return false;
|
|
13113
13590
|
const rec = node2;
|
|
13114
13591
|
if (rec.type === "ImportDeclaration") return false;
|
|
@@ -13123,14 +13600,14 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
13123
13600
|
if (key === "type" || key === "start" || key === "end") continue;
|
|
13124
13601
|
const value = rec[key];
|
|
13125
13602
|
if (Array.isArray(value)) {
|
|
13126
|
-
if (value.some((child) =>
|
|
13127
|
-
} else if (
|
|
13603
|
+
if (value.some((child) => walk(child, rec, key))) return true;
|
|
13604
|
+
} else if (walk(value, rec, key)) {
|
|
13128
13605
|
return true;
|
|
13129
13606
|
}
|
|
13130
13607
|
}
|
|
13131
13608
|
return false;
|
|
13132
13609
|
};
|
|
13133
|
-
return body.some((stmt) =>
|
|
13610
|
+
return body.some((stmt) => walk(stmt));
|
|
13134
13611
|
};
|
|
13135
13612
|
for (const imp of ordinaryImports) {
|
|
13136
13613
|
if (!runtimeComposeFallback && imp.specifiers.length > 0 && imp.specifiers.every(
|