parseman 0.42.0 → 0.43.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/node.d.ts +21 -7
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +23 -2
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +6 -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 +7 -1
- package/dist/compiler/linker.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/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/index.cjs +375 -195
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +375 -195
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs +25 -33
- 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 +25 -33
- 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 +654 -173
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +654 -173
- package/dist/plugin/index.js.map +4 -4
- package/dist/spec/index.cjs +429 -313
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +429 -313
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/spec/index.cjs
CHANGED
|
@@ -391,92 +391,6 @@ function markUnusedValues(root) {
|
|
|
391
391
|
visit(resolveRoot(root), true);
|
|
392
392
|
}
|
|
393
393
|
|
|
394
|
-
// src/combinators/parser.ts
|
|
395
|
-
var RULE_ORDER = "__parsemanRuleOrder";
|
|
396
|
-
function tagRule(r, key) {
|
|
397
|
-
;
|
|
398
|
-
r._ruleName = key;
|
|
399
|
-
if (r._def.tag === "node" && r._def.type === void 0) r._def.type = key;
|
|
400
|
-
}
|
|
401
|
-
function isDefinableRef(v) {
|
|
402
|
-
return !!v && typeof v === "object" && "_def" in v && v._def.tag === "lazy" && typeof v.define === "function";
|
|
403
|
-
}
|
|
404
|
-
function ruleNameOf(r) {
|
|
405
|
-
return r._ruleName;
|
|
406
|
-
}
|
|
407
|
-
function isNamedRuleRefForAnotherRule(r, key) {
|
|
408
|
-
const name = r._def.tag === "lazy" ? ruleNameOf(r) : void 0;
|
|
409
|
-
return name !== void 0 && name !== key;
|
|
410
|
-
}
|
|
411
|
-
function rules(a, b) {
|
|
412
|
-
const factory = typeof a === "function" ? a : b;
|
|
413
|
-
const options = typeof a === "function" ? b : a;
|
|
414
|
-
const cache = {};
|
|
415
|
-
const proxy = new Proxy(cache, {
|
|
416
|
-
get(target, key) {
|
|
417
|
-
if (typeof key !== "string") return void 0;
|
|
418
|
-
const record = target;
|
|
419
|
-
if (!(key in record)) {
|
|
420
|
-
const r = ref();
|
|
421
|
-
tagRule(r, key);
|
|
422
|
-
record[key] = r;
|
|
423
|
-
}
|
|
424
|
-
return record[key];
|
|
425
|
-
}
|
|
426
|
-
});
|
|
427
|
-
const definitions = factory(proxy);
|
|
428
|
-
for (const key of Object.keys(definitions)) {
|
|
429
|
-
const placeholder = cache[key];
|
|
430
|
-
const parser2 = definitions[key];
|
|
431
|
-
if (placeholder === parser2) {
|
|
432
|
-
throw new Error(`rules(): rule "${key}" cannot be a direct alias to itself`);
|
|
433
|
-
}
|
|
434
|
-
if (isDefinableRef(placeholder)) {
|
|
435
|
-
if (!isNamedRuleRefForAnotherRule(parser2, key)) tagRule(parser2, key);
|
|
436
|
-
placeholder.define(parser2);
|
|
437
|
-
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
438
|
-
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
439
|
-
} else if (isNamedRuleRefForAnotherRule(parser2, key)) {
|
|
440
|
-
const alias = ref();
|
|
441
|
-
tagRule(alias, key);
|
|
442
|
-
alias.define(parser2);
|
|
443
|
-
alias._meta.firstSet = parser2._meta.firstSet;
|
|
444
|
-
alias._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
445
|
-
cache[key] = alias;
|
|
446
|
-
} else {
|
|
447
|
-
tagRule(parser2, key);
|
|
448
|
-
cache[key] = parser2;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
if (options?.trivia != null) {
|
|
452
|
-
for (const key of Object.keys(definitions)) {
|
|
453
|
-
const rule = cache[key];
|
|
454
|
-
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrivia = options.trivia;
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
if (options?.scanSkip != null) {
|
|
458
|
-
for (const key of Object.keys(definitions)) {
|
|
459
|
-
const rule = cache[key];
|
|
460
|
-
if (rule && !rule._meta.isTrivia) rule._meta.grammarScanSkip = options.scanSkip;
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
if (options?.hostMode === "cst") {
|
|
464
|
-
for (const key of Object.keys(definitions)) {
|
|
465
|
-
const rule = cache[key];
|
|
466
|
-
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
for (const key of Object.keys(definitions)) {
|
|
470
|
-
markUnusedValues(cache[key]);
|
|
471
|
-
}
|
|
472
|
-
Object.defineProperty(cache, RULE_ORDER, {
|
|
473
|
-
value: Object.keys(definitions),
|
|
474
|
-
enumerable: false,
|
|
475
|
-
configurable: true
|
|
476
|
-
});
|
|
477
|
-
return cache;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
394
|
// src/line-index.ts
|
|
481
395
|
function createLineIndex() {
|
|
482
396
|
return { lineStarts: [0] };
|
|
@@ -1144,38 +1058,432 @@ function codesToFirstSet(codes) {
|
|
|
1144
1058
|
if (codes[i] === hi + 1) {
|
|
1145
1059
|
hi = codes[i];
|
|
1146
1060
|
} else {
|
|
1147
|
-
ranges.push({ lo, hi });
|
|
1148
|
-
lo = hi = codes[i];
|
|
1061
|
+
ranges.push({ lo, hi });
|
|
1062
|
+
lo = hi = codes[i];
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
ranges.push({ lo, hi });
|
|
1066
|
+
return { kind: "ranges", ranges };
|
|
1067
|
+
}
|
|
1068
|
+
function inFirstSet(code, fs) {
|
|
1069
|
+
if (fs.kind === "any") return true;
|
|
1070
|
+
if (fs.kind === "empty") return false;
|
|
1071
|
+
for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
1072
|
+
return false;
|
|
1073
|
+
}
|
|
1074
|
+
function areDisjoint(sets) {
|
|
1075
|
+
if (sets.some((s) => s.kind === "any")) return false;
|
|
1076
|
+
for (let i = 0; i < sets.length; i++)
|
|
1077
|
+
for (let j2 = i + 1; j2 < sets.length; j2++)
|
|
1078
|
+
if (intersects(sets[i], sets[j2])) return false;
|
|
1079
|
+
return true;
|
|
1080
|
+
}
|
|
1081
|
+
function buildAsciiDispatch(parsers) {
|
|
1082
|
+
const table = Array(128).fill(-1);
|
|
1083
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1084
|
+
const fs = parsers[i]._meta.firstSet;
|
|
1085
|
+
if (fs.kind !== "ranges") continue;
|
|
1086
|
+
for (const { lo, hi } of fs.ranges) {
|
|
1087
|
+
for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
|
|
1088
|
+
table[code] = i;
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
return table;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
// src/cst/trivia-kinds.ts
|
|
1096
|
+
function unwrapTrivia(p) {
|
|
1097
|
+
let cur = p;
|
|
1098
|
+
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1099
|
+
return cur;
|
|
1100
|
+
}
|
|
1101
|
+
function peelLabel(p) {
|
|
1102
|
+
if (p._def.tag === "label") return { label: p._def.label, parser: p._def.parser };
|
|
1103
|
+
return null;
|
|
1104
|
+
}
|
|
1105
|
+
function analyzeLabeledTrivia(trivia2) {
|
|
1106
|
+
let core = unwrapTrivia(trivia2);
|
|
1107
|
+
let minRepeats = 1;
|
|
1108
|
+
if (core._def.tag === "oneOrMore") {
|
|
1109
|
+
core = core._def.parser;
|
|
1110
|
+
minRepeats = 1;
|
|
1111
|
+
} else if (core._def.tag === "many") {
|
|
1112
|
+
core = core._def.parser;
|
|
1113
|
+
minRepeats = 0;
|
|
1114
|
+
}
|
|
1115
|
+
const arms = [];
|
|
1116
|
+
if (core._def.tag === "choice") {
|
|
1117
|
+
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1118
|
+
const peeled = peelLabel(core._def.parsers[i]);
|
|
1119
|
+
if (!peeled) return null;
|
|
1120
|
+
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1121
|
+
}
|
|
1122
|
+
} else {
|
|
1123
|
+
const peeled = peelLabel(core);
|
|
1124
|
+
if (!peeled) return null;
|
|
1125
|
+
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1126
|
+
}
|
|
1127
|
+
return { labels: arms.map((a) => a.label), arms, minRepeats };
|
|
1128
|
+
}
|
|
1129
|
+
function matchArmAt(input, pos, arm) {
|
|
1130
|
+
const r = arm.parse(input, pos, { trackLines: false });
|
|
1131
|
+
if (!r.ok || r.span.end <= pos) return null;
|
|
1132
|
+
return { end: r.span.end };
|
|
1133
|
+
}
|
|
1134
|
+
function scanLabeledTriviaChunks(input, cur, spec) {
|
|
1135
|
+
const chunks = [];
|
|
1136
|
+
let pos = cur;
|
|
1137
|
+
while (pos < input.length) {
|
|
1138
|
+
let matched = null;
|
|
1139
|
+
for (const arm of spec.arms) {
|
|
1140
|
+
const m = matchArmAt(input, pos, arm.parser);
|
|
1141
|
+
if (m) {
|
|
1142
|
+
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1143
|
+
break;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
if (!matched) break;
|
|
1147
|
+
chunks.push({ start: pos, end: matched.end, kindIndex: matched.kindIndex });
|
|
1148
|
+
pos = matched.end;
|
|
1149
|
+
}
|
|
1150
|
+
if (chunks.length < spec.minRepeats) {
|
|
1151
|
+
return { end: cur, chunks: [] };
|
|
1152
|
+
}
|
|
1153
|
+
return { end: pos, chunks };
|
|
1154
|
+
}
|
|
1155
|
+
function scanFastWsCommentsChunks(input, cur, wsKind, commentKind) {
|
|
1156
|
+
const chunks = [];
|
|
1157
|
+
let pos = cur;
|
|
1158
|
+
while (pos < input.length) {
|
|
1159
|
+
const c = input.charCodeAt(pos);
|
|
1160
|
+
if (c === 32 || c === 9 || c === 10 || c === 13 || c === 12) {
|
|
1161
|
+
const start = pos;
|
|
1162
|
+
pos++;
|
|
1163
|
+
while (pos < input.length) {
|
|
1164
|
+
const c2 = input.charCodeAt(pos);
|
|
1165
|
+
if (c2 === 32 || c2 === 9 || c2 === 10 || c2 === 13 || c2 === 12) pos++;
|
|
1166
|
+
else break;
|
|
1167
|
+
}
|
|
1168
|
+
chunks.push({ start, end: pos, kindIndex: wsKind });
|
|
1169
|
+
continue;
|
|
1170
|
+
}
|
|
1171
|
+
if (c === 47 && input.charCodeAt(pos + 1) === 42) {
|
|
1172
|
+
let j2 = pos + 2;
|
|
1173
|
+
while (j2 + 1 < input.length && !(input.charCodeAt(j2) === 42 && input.charCodeAt(j2 + 1) === 47)) j2++;
|
|
1174
|
+
if (j2 + 1 < input.length && input.charCodeAt(j2) === 42 && input.charCodeAt(j2 + 1) === 47) {
|
|
1175
|
+
const start = pos;
|
|
1176
|
+
pos = j2 + 2;
|
|
1177
|
+
chunks.push({ start, end: pos, kindIndex: commentKind });
|
|
1178
|
+
continue;
|
|
1179
|
+
}
|
|
1180
|
+
break;
|
|
1181
|
+
}
|
|
1182
|
+
break;
|
|
1183
|
+
}
|
|
1184
|
+
return { end: pos, chunks };
|
|
1185
|
+
}
|
|
1186
|
+
function tryFastLabeledScan(input, cur, trivia2) {
|
|
1187
|
+
const spec = analyzeLabeledTrivia(trivia2);
|
|
1188
|
+
if (!spec || spec.arms.length !== 2) return null;
|
|
1189
|
+
const wsArm = spec.arms.find((a) => {
|
|
1190
|
+
const src = getCoreRegexDef(a.parser)?.source;
|
|
1191
|
+
return src != null && !src.includes("\\*");
|
|
1192
|
+
});
|
|
1193
|
+
const commentArm = spec.arms.find((a) => {
|
|
1194
|
+
const src = getCoreRegexDef(a.parser)?.source;
|
|
1195
|
+
return src != null && src.includes("\\*");
|
|
1196
|
+
});
|
|
1197
|
+
if (!wsArm || !commentArm) return null;
|
|
1198
|
+
const { chunks } = scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1199
|
+
if (chunks.length < spec.minRepeats) return { end: cur, chunks: [] };
|
|
1200
|
+
return scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1201
|
+
}
|
|
1202
|
+
function recordTriviaChunks(ctx, chunks) {
|
|
1203
|
+
const kinds = ctx.triviaKindLabels;
|
|
1204
|
+
const mask = ctx._triviaCaptureMask;
|
|
1205
|
+
for (const ch of chunks) {
|
|
1206
|
+
pushTriviaLogEntry(ctx, ch.start, ch.end, kinds ? ch.kindIndex : void 0);
|
|
1207
|
+
if (ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)) {
|
|
1208
|
+
if (mask === void 0 || kinds === void 0 || (mask & 1 << ch.kindIndex) !== 0) {
|
|
1209
|
+
pushCstTriviaEntry(ctx, ch.start, ch.end, kinds ? ch.kindIndex : void 0);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
function triviaKindMask(labels, keep) {
|
|
1215
|
+
if (!labels) return void 0;
|
|
1216
|
+
let mask = 0;
|
|
1217
|
+
for (const name of keep) {
|
|
1218
|
+
const idx = labels.indexOf(name);
|
|
1219
|
+
if (idx >= 0) mask |= 1 << idx;
|
|
1220
|
+
}
|
|
1221
|
+
return mask;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
// src/combinators/grammar.ts
|
|
1225
|
+
function annotateResultLines(result, index) {
|
|
1226
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
1227
|
+
const errors = annotated.errors;
|
|
1228
|
+
if (errors) {
|
|
1229
|
+
;
|
|
1230
|
+
annotated.errors = errors.map((error) => ({
|
|
1231
|
+
...error,
|
|
1232
|
+
span: annotateSpan(error.span, index)
|
|
1233
|
+
}));
|
|
1234
|
+
}
|
|
1235
|
+
return annotated;
|
|
1236
|
+
}
|
|
1237
|
+
function createParseLineContext(input, pos) {
|
|
1238
|
+
const lineIndex = createLineIndex();
|
|
1239
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
1240
|
+
return { lineIndex, lineScannedTo: pos };
|
|
1241
|
+
}
|
|
1242
|
+
function parser(opts, root) {
|
|
1243
|
+
const clearTrivia = opts.trivia === null;
|
|
1244
|
+
return {
|
|
1245
|
+
_tag: "grammar",
|
|
1246
|
+
_meta: root._meta,
|
|
1247
|
+
_def: {
|
|
1248
|
+
tag: "grammar",
|
|
1249
|
+
parser: root,
|
|
1250
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
1251
|
+
clearTrivia,
|
|
1252
|
+
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
1253
|
+
trackLines: opts.trackLines ?? false
|
|
1254
|
+
},
|
|
1255
|
+
parse(input, pos, _ctx) {
|
|
1256
|
+
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
1257
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
1258
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
1259
|
+
const ctx = {
|
|
1260
|
+
..._ctx,
|
|
1261
|
+
trackLines,
|
|
1262
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
1263
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
1264
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
1265
|
+
...clearTrivia ? {
|
|
1266
|
+
trivia: void 0,
|
|
1267
|
+
triviaKindLabels: void 0
|
|
1268
|
+
} : opts.trivia != null ? {
|
|
1269
|
+
trivia: opts.trivia,
|
|
1270
|
+
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
1271
|
+
} : {},
|
|
1272
|
+
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
1273
|
+
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
1274
|
+
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
1275
|
+
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
1276
|
+
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
1277
|
+
// (capture all).
|
|
1278
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
1279
|
+
};
|
|
1280
|
+
const result = root.parse(input, pos ?? 0, ctx);
|
|
1281
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
1282
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
1283
|
+
}
|
|
1284
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
1285
|
+
}
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
// src/cst/reflection.ts
|
|
1290
|
+
var GRAMMAR_REFLECTION = /* @__PURE__ */ Symbol.for("parseman.grammarReflection");
|
|
1291
|
+
function childrenOf(def) {
|
|
1292
|
+
switch (def.tag) {
|
|
1293
|
+
case "sequence":
|
|
1294
|
+
case "choice":
|
|
1295
|
+
return def.parsers;
|
|
1296
|
+
case "dispatch":
|
|
1297
|
+
return [
|
|
1298
|
+
def.selector,
|
|
1299
|
+
...def.cases.map((c) => c.parser),
|
|
1300
|
+
...def.matchers ? def.matchers.map((c) => c.parser) : [],
|
|
1301
|
+
...def.otherwise ? [def.otherwise] : []
|
|
1302
|
+
];
|
|
1303
|
+
case "many":
|
|
1304
|
+
case "oneOrMore":
|
|
1305
|
+
case "optional":
|
|
1306
|
+
case "attempt":
|
|
1307
|
+
case "transform":
|
|
1308
|
+
case "trivia":
|
|
1309
|
+
case "token":
|
|
1310
|
+
case "leaf":
|
|
1311
|
+
case "label":
|
|
1312
|
+
case "field":
|
|
1313
|
+
case "not":
|
|
1314
|
+
case "peek":
|
|
1315
|
+
case "node":
|
|
1316
|
+
case "withCtx":
|
|
1317
|
+
case "recover":
|
|
1318
|
+
case "expect":
|
|
1319
|
+
return [def.parser];
|
|
1320
|
+
case "grammar":
|
|
1321
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
1322
|
+
case "sepBy":
|
|
1323
|
+
return [def.parser, def.separator];
|
|
1324
|
+
case "skip":
|
|
1325
|
+
return [def.main, def.skipped];
|
|
1326
|
+
case "scanTo":
|
|
1327
|
+
return [def.sentinel, ...def.skip];
|
|
1328
|
+
case "literal":
|
|
1329
|
+
case "regex":
|
|
1330
|
+
case "keywords":
|
|
1331
|
+
case "routed":
|
|
1332
|
+
case "guard":
|
|
1333
|
+
case "lazy":
|
|
1334
|
+
case "unknown":
|
|
1335
|
+
return [];
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
function addNode(out, def) {
|
|
1339
|
+
if (def.type === void 0) return;
|
|
1340
|
+
const existing = out.get(def.type);
|
|
1341
|
+
if (existing === void 0) {
|
|
1342
|
+
out.set(def.type, def.tags === void 0 ? [] : [...def.tags]);
|
|
1343
|
+
return;
|
|
1344
|
+
}
|
|
1345
|
+
if (def.tags === void 0) return;
|
|
1346
|
+
for (const tag of def.tags) {
|
|
1347
|
+
if (!existing.includes(tag)) existing.push(tag);
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
1351
|
+
if (seen.has(parser2)) return;
|
|
1352
|
+
seen.add(parser2);
|
|
1353
|
+
const def = parser2._def;
|
|
1354
|
+
if (def.tag === "lazy") {
|
|
1355
|
+
if (followLazy) {
|
|
1356
|
+
try {
|
|
1357
|
+
collectFromCombinator(def.thunk(), out, seen, followLazy);
|
|
1358
|
+
} catch {
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
return;
|
|
1362
|
+
}
|
|
1363
|
+
if (def.tag === "node") addNode(out, def);
|
|
1364
|
+
for (const child of childrenOf(def)) collectFromCombinator(child, out, seen, followLazy);
|
|
1365
|
+
}
|
|
1366
|
+
function collectGrammarReflection(ruleMap, opts) {
|
|
1367
|
+
const byType = /* @__PURE__ */ new Map();
|
|
1368
|
+
const followLazy = opts?.followLazy !== false;
|
|
1369
|
+
for (const [, rule] of ruleMap) {
|
|
1370
|
+
if (!followLazy && rule._def.tag === "lazy") {
|
|
1371
|
+
try {
|
|
1372
|
+
const resolved = rule._def.thunk();
|
|
1373
|
+
if (resolved._def.tag !== "lazy") collectFromCombinator(resolved, byType, /* @__PURE__ */ new Set(), false);
|
|
1374
|
+
} catch {
|
|
1375
|
+
}
|
|
1376
|
+
continue;
|
|
1377
|
+
}
|
|
1378
|
+
collectFromCombinator(rule, byType, /* @__PURE__ */ new Set(), followLazy);
|
|
1379
|
+
}
|
|
1380
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
1381
|
+
}
|
|
1382
|
+
function attachGrammarReflection(grammar, reflection) {
|
|
1383
|
+
Object.defineProperty(grammar, GRAMMAR_REFLECTION, { value: reflection, enumerable: false, configurable: true });
|
|
1384
|
+
return grammar;
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
// src/combinators/parser.ts
|
|
1388
|
+
var RULE_ORDER = "__parsemanRuleOrder";
|
|
1389
|
+
function tagRule(r, key) {
|
|
1390
|
+
;
|
|
1391
|
+
r._ruleName = key;
|
|
1392
|
+
if (r._def.tag === "node" && r._def.type === void 0) r._def.type = key;
|
|
1393
|
+
}
|
|
1394
|
+
function isDefinableRef(v) {
|
|
1395
|
+
return !!v && typeof v === "object" && "_def" in v && v._def.tag === "lazy" && typeof v.define === "function";
|
|
1396
|
+
}
|
|
1397
|
+
function ruleNameOf(r) {
|
|
1398
|
+
return r._ruleName;
|
|
1399
|
+
}
|
|
1400
|
+
function isNamedRuleRefForAnotherRule(r, key) {
|
|
1401
|
+
const name = r._def.tag === "lazy" ? ruleNameOf(r) : void 0;
|
|
1402
|
+
return name !== void 0 && name !== key;
|
|
1403
|
+
}
|
|
1404
|
+
function rules(a, b) {
|
|
1405
|
+
const factory = typeof a === "function" ? a : b;
|
|
1406
|
+
const options = typeof a === "function" ? b : a;
|
|
1407
|
+
const cache = {};
|
|
1408
|
+
const proxy = new Proxy(cache, {
|
|
1409
|
+
get(target, key) {
|
|
1410
|
+
if (typeof key !== "string") return void 0;
|
|
1411
|
+
const record = target;
|
|
1412
|
+
if (!(key in record)) {
|
|
1413
|
+
const r = ref();
|
|
1414
|
+
tagRule(r, key);
|
|
1415
|
+
record[key] = r;
|
|
1416
|
+
}
|
|
1417
|
+
return record[key];
|
|
1418
|
+
}
|
|
1419
|
+
});
|
|
1420
|
+
const definitions = factory(proxy);
|
|
1421
|
+
for (const key of Object.keys(definitions)) {
|
|
1422
|
+
const placeholder = cache[key];
|
|
1423
|
+
const parser2 = definitions[key];
|
|
1424
|
+
if (placeholder === parser2) {
|
|
1425
|
+
throw new Error(`rules(): rule "${key}" cannot be a direct alias to itself`);
|
|
1426
|
+
}
|
|
1427
|
+
if (isDefinableRef(placeholder)) {
|
|
1428
|
+
if (!isNamedRuleRefForAnotherRule(parser2, key)) tagRule(parser2, key);
|
|
1429
|
+
placeholder.define(parser2);
|
|
1430
|
+
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
1431
|
+
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1432
|
+
} else if (isNamedRuleRefForAnotherRule(parser2, key)) {
|
|
1433
|
+
const alias = ref();
|
|
1434
|
+
tagRule(alias, key);
|
|
1435
|
+
alias.define(parser2);
|
|
1436
|
+
alias._meta.firstSet = parser2._meta.firstSet;
|
|
1437
|
+
alias._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1438
|
+
cache[key] = alias;
|
|
1439
|
+
} else {
|
|
1440
|
+
tagRule(parser2, key);
|
|
1441
|
+
cache[key] = parser2;
|
|
1149
1442
|
}
|
|
1150
1443
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
const
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1444
|
+
if (options?.trivia != null) {
|
|
1445
|
+
for (const key of Object.keys(definitions)) {
|
|
1446
|
+
const rule = cache[key];
|
|
1447
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrivia = options.trivia;
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
if (options?.scanSkip != null) {
|
|
1451
|
+
for (const key of Object.keys(definitions)) {
|
|
1452
|
+
const rule = cache[key];
|
|
1453
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarScanSkip = options.scanSkip;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
if (options?.hostMode === "cst") {
|
|
1457
|
+
for (const key of Object.keys(definitions)) {
|
|
1458
|
+
const rule = cache[key];
|
|
1459
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
if (options?.trackLines === true) {
|
|
1463
|
+
for (const key of Object.keys(definitions)) {
|
|
1464
|
+
const rule = cache[key];
|
|
1465
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
1466
|
+
}
|
|
1467
|
+
for (const key of Object.keys(definitions)) {
|
|
1468
|
+
const rule = cache[key];
|
|
1469
|
+
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
1470
|
+
const wrapped = parser({ trackLines: true }, rule);
|
|
1471
|
+
tagRule(wrapped, key);
|
|
1472
|
+
wrapped._meta.grammarTrackLines = true;
|
|
1473
|
+
cache[key] = wrapped;
|
|
1175
1474
|
}
|
|
1176
1475
|
}
|
|
1177
1476
|
}
|
|
1178
|
-
|
|
1477
|
+
for (const key of Object.keys(definitions)) {
|
|
1478
|
+
markUnusedValues(cache[key]);
|
|
1479
|
+
}
|
|
1480
|
+
Object.defineProperty(cache, RULE_ORDER, {
|
|
1481
|
+
value: Object.keys(definitions),
|
|
1482
|
+
enumerable: false,
|
|
1483
|
+
configurable: true
|
|
1484
|
+
});
|
|
1485
|
+
attachGrammarReflection(cache, collectGrammarReflection(Object.keys(definitions).map((key) => [key, cache[key]])));
|
|
1486
|
+
return cache;
|
|
1179
1487
|
}
|
|
1180
1488
|
|
|
1181
1489
|
// src/analysis/duplication.ts
|
|
@@ -1430,135 +1738,6 @@ function regex(pattern, flags = "") {
|
|
|
1430
1738
|
};
|
|
1431
1739
|
}
|
|
1432
1740
|
|
|
1433
|
-
// src/cst/trivia-kinds.ts
|
|
1434
|
-
function unwrapTrivia(p) {
|
|
1435
|
-
let cur = p;
|
|
1436
|
-
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1437
|
-
return cur;
|
|
1438
|
-
}
|
|
1439
|
-
function peelLabel(p) {
|
|
1440
|
-
if (p._def.tag === "label") return { label: p._def.label, parser: p._def.parser };
|
|
1441
|
-
return null;
|
|
1442
|
-
}
|
|
1443
|
-
function analyzeLabeledTrivia(trivia2) {
|
|
1444
|
-
let core = unwrapTrivia(trivia2);
|
|
1445
|
-
let minRepeats = 1;
|
|
1446
|
-
if (core._def.tag === "oneOrMore") {
|
|
1447
|
-
core = core._def.parser;
|
|
1448
|
-
minRepeats = 1;
|
|
1449
|
-
} else if (core._def.tag === "many") {
|
|
1450
|
-
core = core._def.parser;
|
|
1451
|
-
minRepeats = 0;
|
|
1452
|
-
}
|
|
1453
|
-
const arms = [];
|
|
1454
|
-
if (core._def.tag === "choice") {
|
|
1455
|
-
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1456
|
-
const peeled = peelLabel(core._def.parsers[i]);
|
|
1457
|
-
if (!peeled) return null;
|
|
1458
|
-
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1459
|
-
}
|
|
1460
|
-
} else {
|
|
1461
|
-
const peeled = peelLabel(core);
|
|
1462
|
-
if (!peeled) return null;
|
|
1463
|
-
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1464
|
-
}
|
|
1465
|
-
return { labels: arms.map((a) => a.label), arms, minRepeats };
|
|
1466
|
-
}
|
|
1467
|
-
function matchArmAt(input, pos, arm) {
|
|
1468
|
-
const r = arm.parse(input, pos, { trackLines: false });
|
|
1469
|
-
if (!r.ok || r.span.end <= pos) return null;
|
|
1470
|
-
return { end: r.span.end };
|
|
1471
|
-
}
|
|
1472
|
-
function scanLabeledTriviaChunks(input, cur, spec) {
|
|
1473
|
-
const chunks = [];
|
|
1474
|
-
let pos = cur;
|
|
1475
|
-
while (pos < input.length) {
|
|
1476
|
-
let matched = null;
|
|
1477
|
-
for (const arm of spec.arms) {
|
|
1478
|
-
const m = matchArmAt(input, pos, arm.parser);
|
|
1479
|
-
if (m) {
|
|
1480
|
-
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1481
|
-
break;
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
if (!matched) break;
|
|
1485
|
-
chunks.push({ start: pos, end: matched.end, kindIndex: matched.kindIndex });
|
|
1486
|
-
pos = matched.end;
|
|
1487
|
-
}
|
|
1488
|
-
if (chunks.length < spec.minRepeats) {
|
|
1489
|
-
return { end: cur, chunks: [] };
|
|
1490
|
-
}
|
|
1491
|
-
return { end: pos, chunks };
|
|
1492
|
-
}
|
|
1493
|
-
function scanFastWsCommentsChunks(input, cur, wsKind, commentKind) {
|
|
1494
|
-
const chunks = [];
|
|
1495
|
-
let pos = cur;
|
|
1496
|
-
while (pos < input.length) {
|
|
1497
|
-
const c = input.charCodeAt(pos);
|
|
1498
|
-
if (c === 32 || c === 9 || c === 10 || c === 13 || c === 12) {
|
|
1499
|
-
const start = pos;
|
|
1500
|
-
pos++;
|
|
1501
|
-
while (pos < input.length) {
|
|
1502
|
-
const c2 = input.charCodeAt(pos);
|
|
1503
|
-
if (c2 === 32 || c2 === 9 || c2 === 10 || c2 === 13 || c2 === 12) pos++;
|
|
1504
|
-
else break;
|
|
1505
|
-
}
|
|
1506
|
-
chunks.push({ start, end: pos, kindIndex: wsKind });
|
|
1507
|
-
continue;
|
|
1508
|
-
}
|
|
1509
|
-
if (c === 47 && input.charCodeAt(pos + 1) === 42) {
|
|
1510
|
-
let j2 = pos + 2;
|
|
1511
|
-
while (j2 + 1 < input.length && !(input.charCodeAt(j2) === 42 && input.charCodeAt(j2 + 1) === 47)) j2++;
|
|
1512
|
-
if (j2 + 1 < input.length && input.charCodeAt(j2) === 42 && input.charCodeAt(j2 + 1) === 47) {
|
|
1513
|
-
const start = pos;
|
|
1514
|
-
pos = j2 + 2;
|
|
1515
|
-
chunks.push({ start, end: pos, kindIndex: commentKind });
|
|
1516
|
-
continue;
|
|
1517
|
-
}
|
|
1518
|
-
break;
|
|
1519
|
-
}
|
|
1520
|
-
break;
|
|
1521
|
-
}
|
|
1522
|
-
return { end: pos, chunks };
|
|
1523
|
-
}
|
|
1524
|
-
function tryFastLabeledScan(input, cur, trivia2) {
|
|
1525
|
-
const spec = analyzeLabeledTrivia(trivia2);
|
|
1526
|
-
if (!spec || spec.arms.length !== 2) return null;
|
|
1527
|
-
const wsArm = spec.arms.find((a) => {
|
|
1528
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1529
|
-
return src != null && !src.includes("\\*");
|
|
1530
|
-
});
|
|
1531
|
-
const commentArm = spec.arms.find((a) => {
|
|
1532
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1533
|
-
return src != null && src.includes("\\*");
|
|
1534
|
-
});
|
|
1535
|
-
if (!wsArm || !commentArm) return null;
|
|
1536
|
-
const { chunks } = scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1537
|
-
if (chunks.length < spec.minRepeats) return { end: cur, chunks: [] };
|
|
1538
|
-
return scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1539
|
-
}
|
|
1540
|
-
function recordTriviaChunks(ctx, chunks) {
|
|
1541
|
-
const kinds = ctx.triviaKindLabels;
|
|
1542
|
-
const mask = ctx._triviaCaptureMask;
|
|
1543
|
-
for (const ch of chunks) {
|
|
1544
|
-
pushTriviaLogEntry(ctx, ch.start, ch.end, kinds ? ch.kindIndex : void 0);
|
|
1545
|
-
if (ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)) {
|
|
1546
|
-
if (mask === void 0 || kinds === void 0 || (mask & 1 << ch.kindIndex) !== 0) {
|
|
1547
|
-
pushCstTriviaEntry(ctx, ch.start, ch.end, kinds ? ch.kindIndex : void 0);
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
function triviaKindMask(labels, keep) {
|
|
1553
|
-
if (!labels) return void 0;
|
|
1554
|
-
let mask = 0;
|
|
1555
|
-
for (const name of keep) {
|
|
1556
|
-
const idx = labels.indexOf(name);
|
|
1557
|
-
if (idx >= 0) mask |= 1 << idx;
|
|
1558
|
-
}
|
|
1559
|
-
return mask;
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
1741
|
// src/combinators/trivia-skip.ts
|
|
1563
1742
|
var NOOP_COMMIT = () => {
|
|
1564
1743
|
};
|
|
@@ -2930,13 +3109,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
2930
3109
|
const collapse = opts?.collapse === true;
|
|
2931
3110
|
const captureTrivia = opts?.captureTrivia === true;
|
|
2932
3111
|
const trailingTrivia = opts?.trailingTrivia === true;
|
|
3112
|
+
const tags = opts?.tags;
|
|
2933
3113
|
if (unwrap && collapse) {
|
|
2934
3114
|
throw new Error("node() options cannot set both unwrap and collapse");
|
|
2935
3115
|
}
|
|
2936
3116
|
if (project !== void 0 && (unwrap || collapse)) {
|
|
2937
3117
|
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
2938
3118
|
}
|
|
2939
|
-
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;
|
|
3119
|
+
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;
|
|
2940
3120
|
const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
2941
3121
|
const clonesState = build ? buildReadsState(def) : project === void 0;
|
|
2942
3122
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
@@ -2982,7 +3162,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
2982
3162
|
const cstOutput = cstOutputHost(ctx.build);
|
|
2983
3163
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
2984
3164
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
2985
|
-
const built = unwrap && children.length === 1 ? unwrapChild(children[0]) : collapse && children.length === 1 ? children[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children[0], children, rawChildren) ? children[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children, fields, span, rawChildren, triviaLog, hostState) : projectChild(children, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children, fields, span, rawChildren, triviaLog, hostState) : build(children, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children, 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 };
|
|
3165
|
+
const built = unwrap && children.length === 1 ? unwrapChild(children[0]) : collapse && children.length === 1 ? children[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children[0], children, rawChildren) ? children[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children, fields, span, rawChildren, triviaLog, hostState, tags) : projectChild(children, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children, fields, span, rawChildren, triviaLog, hostState, tags) : build(children, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children, 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 };
|
|
2986
3166
|
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 };
|
|
2987
3167
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
2988
3168
|
pushCstChild(ctx, built, rawEntry);
|
|
@@ -2992,71 +3172,6 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
2992
3172
|
};
|
|
2993
3173
|
}
|
|
2994
3174
|
|
|
2995
|
-
// src/combinators/grammar.ts
|
|
2996
|
-
function annotateResultLines(result, index) {
|
|
2997
|
-
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
2998
|
-
const errors = annotated.errors;
|
|
2999
|
-
if (errors) {
|
|
3000
|
-
;
|
|
3001
|
-
annotated.errors = errors.map((error) => ({
|
|
3002
|
-
...error,
|
|
3003
|
-
span: annotateSpan(error.span, index)
|
|
3004
|
-
}));
|
|
3005
|
-
}
|
|
3006
|
-
return annotated;
|
|
3007
|
-
}
|
|
3008
|
-
function createParseLineContext(input, pos) {
|
|
3009
|
-
const lineIndex = createLineIndex();
|
|
3010
|
-
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
3011
|
-
return { lineIndex, lineScannedTo: pos };
|
|
3012
|
-
}
|
|
3013
|
-
function parser(opts, root) {
|
|
3014
|
-
const clearTrivia = opts.trivia === null;
|
|
3015
|
-
return {
|
|
3016
|
-
_tag: "grammar",
|
|
3017
|
-
_meta: root._meta,
|
|
3018
|
-
_def: {
|
|
3019
|
-
tag: "grammar",
|
|
3020
|
-
parser: root,
|
|
3021
|
-
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
3022
|
-
clearTrivia,
|
|
3023
|
-
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
3024
|
-
trackLines: opts.trackLines ?? false
|
|
3025
|
-
},
|
|
3026
|
-
parse(input, pos, _ctx) {
|
|
3027
|
-
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
3028
|
-
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
3029
|
-
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
3030
|
-
const ctx = {
|
|
3031
|
-
..._ctx,
|
|
3032
|
-
trackLines,
|
|
3033
|
-
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
3034
|
-
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
3035
|
-
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
3036
|
-
...clearTrivia ? {
|
|
3037
|
-
trivia: void 0,
|
|
3038
|
-
triviaKindLabels: void 0
|
|
3039
|
-
} : opts.trivia != null ? {
|
|
3040
|
-
trivia: opts.trivia,
|
|
3041
|
-
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
3042
|
-
} : {},
|
|
3043
|
-
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
3044
|
-
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
3045
|
-
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
3046
|
-
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
3047
|
-
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
3048
|
-
// (capture all).
|
|
3049
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
3050
|
-
};
|
|
3051
|
-
const result = root.parse(input, pos ?? 0, ctx);
|
|
3052
|
-
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
3053
|
-
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
3054
|
-
}
|
|
3055
|
-
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
3056
|
-
}
|
|
3057
|
-
};
|
|
3058
|
-
}
|
|
3059
|
-
|
|
3060
3175
|
// src/combinators/token.ts
|
|
3061
3176
|
function token(root) {
|
|
3062
3177
|
const meta = {
|
|
@@ -3339,15 +3454,16 @@ function normalizeCstCollapse(collapse) {
|
|
|
3339
3454
|
}
|
|
3340
3455
|
return typeof collapse === "function" ? collapse : void 0;
|
|
3341
3456
|
}
|
|
3342
|
-
function buildCstNode(type, children, _fields, span, _rawChildren, _triviaLog, state) {
|
|
3343
|
-
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children] };
|
|
3457
|
+
function buildCstNode(type, children, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
3458
|
+
return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children] };
|
|
3344
3459
|
}
|
|
3345
|
-
function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, triviaLog, state) {
|
|
3460
|
+
function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
3346
3461
|
if (typeof typeOrOptions === "string") {
|
|
3347
3462
|
return buildCstNode(typeOrOptions, children ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
3348
3463
|
}
|
|
3349
3464
|
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
3350
|
-
const
|
|
3465
|
+
const materializeTags = typeOrOptions?.tags === true;
|
|
3466
|
+
const host = (type, children2, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children2 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
3351
3467
|
host._parsemanCstOutput = true;
|
|
3352
3468
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
3353
3469
|
return host;
|