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.js
CHANGED
|
@@ -357,92 +357,6 @@ function markUnusedValues(root) {
|
|
|
357
357
|
visit(resolveRoot(root), true);
|
|
358
358
|
}
|
|
359
359
|
|
|
360
|
-
// src/combinators/parser.ts
|
|
361
|
-
var RULE_ORDER = "__parsemanRuleOrder";
|
|
362
|
-
function tagRule(r, key) {
|
|
363
|
-
;
|
|
364
|
-
r._ruleName = key;
|
|
365
|
-
if (r._def.tag === "node" && r._def.type === void 0) r._def.type = key;
|
|
366
|
-
}
|
|
367
|
-
function isDefinableRef(v) {
|
|
368
|
-
return !!v && typeof v === "object" && "_def" in v && v._def.tag === "lazy" && typeof v.define === "function";
|
|
369
|
-
}
|
|
370
|
-
function ruleNameOf(r) {
|
|
371
|
-
return r._ruleName;
|
|
372
|
-
}
|
|
373
|
-
function isNamedRuleRefForAnotherRule(r, key) {
|
|
374
|
-
const name = r._def.tag === "lazy" ? ruleNameOf(r) : void 0;
|
|
375
|
-
return name !== void 0 && name !== key;
|
|
376
|
-
}
|
|
377
|
-
function rules(a, b) {
|
|
378
|
-
const factory = typeof a === "function" ? a : b;
|
|
379
|
-
const options = typeof a === "function" ? b : a;
|
|
380
|
-
const cache = {};
|
|
381
|
-
const proxy = new Proxy(cache, {
|
|
382
|
-
get(target, key) {
|
|
383
|
-
if (typeof key !== "string") return void 0;
|
|
384
|
-
const record = target;
|
|
385
|
-
if (!(key in record)) {
|
|
386
|
-
const r = ref();
|
|
387
|
-
tagRule(r, key);
|
|
388
|
-
record[key] = r;
|
|
389
|
-
}
|
|
390
|
-
return record[key];
|
|
391
|
-
}
|
|
392
|
-
});
|
|
393
|
-
const definitions = factory(proxy);
|
|
394
|
-
for (const key of Object.keys(definitions)) {
|
|
395
|
-
const placeholder = cache[key];
|
|
396
|
-
const parser2 = definitions[key];
|
|
397
|
-
if (placeholder === parser2) {
|
|
398
|
-
throw new Error(`rules(): rule "${key}" cannot be a direct alias to itself`);
|
|
399
|
-
}
|
|
400
|
-
if (isDefinableRef(placeholder)) {
|
|
401
|
-
if (!isNamedRuleRefForAnotherRule(parser2, key)) tagRule(parser2, key);
|
|
402
|
-
placeholder.define(parser2);
|
|
403
|
-
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
404
|
-
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
405
|
-
} else if (isNamedRuleRefForAnotherRule(parser2, key)) {
|
|
406
|
-
const alias = ref();
|
|
407
|
-
tagRule(alias, key);
|
|
408
|
-
alias.define(parser2);
|
|
409
|
-
alias._meta.firstSet = parser2._meta.firstSet;
|
|
410
|
-
alias._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
411
|
-
cache[key] = alias;
|
|
412
|
-
} else {
|
|
413
|
-
tagRule(parser2, key);
|
|
414
|
-
cache[key] = parser2;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
if (options?.trivia != null) {
|
|
418
|
-
for (const key of Object.keys(definitions)) {
|
|
419
|
-
const rule = cache[key];
|
|
420
|
-
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrivia = options.trivia;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
if (options?.scanSkip != null) {
|
|
424
|
-
for (const key of Object.keys(definitions)) {
|
|
425
|
-
const rule = cache[key];
|
|
426
|
-
if (rule && !rule._meta.isTrivia) rule._meta.grammarScanSkip = options.scanSkip;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
if (options?.hostMode === "cst") {
|
|
430
|
-
for (const key of Object.keys(definitions)) {
|
|
431
|
-
const rule = cache[key];
|
|
432
|
-
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
for (const key of Object.keys(definitions)) {
|
|
436
|
-
markUnusedValues(cache[key]);
|
|
437
|
-
}
|
|
438
|
-
Object.defineProperty(cache, RULE_ORDER, {
|
|
439
|
-
value: Object.keys(definitions),
|
|
440
|
-
enumerable: false,
|
|
441
|
-
configurable: true
|
|
442
|
-
});
|
|
443
|
-
return cache;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
360
|
// src/line-index.ts
|
|
447
361
|
function createLineIndex() {
|
|
448
362
|
return { lineStarts: [0] };
|
|
@@ -1110,38 +1024,432 @@ function codesToFirstSet(codes) {
|
|
|
1110
1024
|
if (codes[i] === hi + 1) {
|
|
1111
1025
|
hi = codes[i];
|
|
1112
1026
|
} else {
|
|
1113
|
-
ranges.push({ lo, hi });
|
|
1114
|
-
lo = hi = codes[i];
|
|
1027
|
+
ranges.push({ lo, hi });
|
|
1028
|
+
lo = hi = codes[i];
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
ranges.push({ lo, hi });
|
|
1032
|
+
return { kind: "ranges", ranges };
|
|
1033
|
+
}
|
|
1034
|
+
function inFirstSet(code, fs) {
|
|
1035
|
+
if (fs.kind === "any") return true;
|
|
1036
|
+
if (fs.kind === "empty") return false;
|
|
1037
|
+
for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
1038
|
+
return false;
|
|
1039
|
+
}
|
|
1040
|
+
function areDisjoint(sets) {
|
|
1041
|
+
if (sets.some((s) => s.kind === "any")) return false;
|
|
1042
|
+
for (let i = 0; i < sets.length; i++)
|
|
1043
|
+
for (let j2 = i + 1; j2 < sets.length; j2++)
|
|
1044
|
+
if (intersects(sets[i], sets[j2])) return false;
|
|
1045
|
+
return true;
|
|
1046
|
+
}
|
|
1047
|
+
function buildAsciiDispatch(parsers) {
|
|
1048
|
+
const table = Array(128).fill(-1);
|
|
1049
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1050
|
+
const fs = parsers[i]._meta.firstSet;
|
|
1051
|
+
if (fs.kind !== "ranges") continue;
|
|
1052
|
+
for (const { lo, hi } of fs.ranges) {
|
|
1053
|
+
for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
|
|
1054
|
+
table[code] = i;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
return table;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
// src/cst/trivia-kinds.ts
|
|
1062
|
+
function unwrapTrivia(p) {
|
|
1063
|
+
let cur = p;
|
|
1064
|
+
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1065
|
+
return cur;
|
|
1066
|
+
}
|
|
1067
|
+
function peelLabel(p) {
|
|
1068
|
+
if (p._def.tag === "label") return { label: p._def.label, parser: p._def.parser };
|
|
1069
|
+
return null;
|
|
1070
|
+
}
|
|
1071
|
+
function analyzeLabeledTrivia(trivia2) {
|
|
1072
|
+
let core = unwrapTrivia(trivia2);
|
|
1073
|
+
let minRepeats = 1;
|
|
1074
|
+
if (core._def.tag === "oneOrMore") {
|
|
1075
|
+
core = core._def.parser;
|
|
1076
|
+
minRepeats = 1;
|
|
1077
|
+
} else if (core._def.tag === "many") {
|
|
1078
|
+
core = core._def.parser;
|
|
1079
|
+
minRepeats = 0;
|
|
1080
|
+
}
|
|
1081
|
+
const arms = [];
|
|
1082
|
+
if (core._def.tag === "choice") {
|
|
1083
|
+
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1084
|
+
const peeled = peelLabel(core._def.parsers[i]);
|
|
1085
|
+
if (!peeled) return null;
|
|
1086
|
+
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1087
|
+
}
|
|
1088
|
+
} else {
|
|
1089
|
+
const peeled = peelLabel(core);
|
|
1090
|
+
if (!peeled) return null;
|
|
1091
|
+
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1092
|
+
}
|
|
1093
|
+
return { labels: arms.map((a) => a.label), arms, minRepeats };
|
|
1094
|
+
}
|
|
1095
|
+
function matchArmAt(input, pos, arm) {
|
|
1096
|
+
const r = arm.parse(input, pos, { trackLines: false });
|
|
1097
|
+
if (!r.ok || r.span.end <= pos) return null;
|
|
1098
|
+
return { end: r.span.end };
|
|
1099
|
+
}
|
|
1100
|
+
function scanLabeledTriviaChunks(input, cur, spec) {
|
|
1101
|
+
const chunks = [];
|
|
1102
|
+
let pos = cur;
|
|
1103
|
+
while (pos < input.length) {
|
|
1104
|
+
let matched = null;
|
|
1105
|
+
for (const arm of spec.arms) {
|
|
1106
|
+
const m = matchArmAt(input, pos, arm.parser);
|
|
1107
|
+
if (m) {
|
|
1108
|
+
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1109
|
+
break;
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
if (!matched) break;
|
|
1113
|
+
chunks.push({ start: pos, end: matched.end, kindIndex: matched.kindIndex });
|
|
1114
|
+
pos = matched.end;
|
|
1115
|
+
}
|
|
1116
|
+
if (chunks.length < spec.minRepeats) {
|
|
1117
|
+
return { end: cur, chunks: [] };
|
|
1118
|
+
}
|
|
1119
|
+
return { end: pos, chunks };
|
|
1120
|
+
}
|
|
1121
|
+
function scanFastWsCommentsChunks(input, cur, wsKind, commentKind) {
|
|
1122
|
+
const chunks = [];
|
|
1123
|
+
let pos = cur;
|
|
1124
|
+
while (pos < input.length) {
|
|
1125
|
+
const c = input.charCodeAt(pos);
|
|
1126
|
+
if (c === 32 || c === 9 || c === 10 || c === 13 || c === 12) {
|
|
1127
|
+
const start = pos;
|
|
1128
|
+
pos++;
|
|
1129
|
+
while (pos < input.length) {
|
|
1130
|
+
const c2 = input.charCodeAt(pos);
|
|
1131
|
+
if (c2 === 32 || c2 === 9 || c2 === 10 || c2 === 13 || c2 === 12) pos++;
|
|
1132
|
+
else break;
|
|
1133
|
+
}
|
|
1134
|
+
chunks.push({ start, end: pos, kindIndex: wsKind });
|
|
1135
|
+
continue;
|
|
1136
|
+
}
|
|
1137
|
+
if (c === 47 && input.charCodeAt(pos + 1) === 42) {
|
|
1138
|
+
let j2 = pos + 2;
|
|
1139
|
+
while (j2 + 1 < input.length && !(input.charCodeAt(j2) === 42 && input.charCodeAt(j2 + 1) === 47)) j2++;
|
|
1140
|
+
if (j2 + 1 < input.length && input.charCodeAt(j2) === 42 && input.charCodeAt(j2 + 1) === 47) {
|
|
1141
|
+
const start = pos;
|
|
1142
|
+
pos = j2 + 2;
|
|
1143
|
+
chunks.push({ start, end: pos, kindIndex: commentKind });
|
|
1144
|
+
continue;
|
|
1145
|
+
}
|
|
1146
|
+
break;
|
|
1147
|
+
}
|
|
1148
|
+
break;
|
|
1149
|
+
}
|
|
1150
|
+
return { end: pos, chunks };
|
|
1151
|
+
}
|
|
1152
|
+
function tryFastLabeledScan(input, cur, trivia2) {
|
|
1153
|
+
const spec = analyzeLabeledTrivia(trivia2);
|
|
1154
|
+
if (!spec || spec.arms.length !== 2) return null;
|
|
1155
|
+
const wsArm = spec.arms.find((a) => {
|
|
1156
|
+
const src = getCoreRegexDef(a.parser)?.source;
|
|
1157
|
+
return src != null && !src.includes("\\*");
|
|
1158
|
+
});
|
|
1159
|
+
const commentArm = spec.arms.find((a) => {
|
|
1160
|
+
const src = getCoreRegexDef(a.parser)?.source;
|
|
1161
|
+
return src != null && src.includes("\\*");
|
|
1162
|
+
});
|
|
1163
|
+
if (!wsArm || !commentArm) return null;
|
|
1164
|
+
const { chunks } = scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1165
|
+
if (chunks.length < spec.minRepeats) return { end: cur, chunks: [] };
|
|
1166
|
+
return scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1167
|
+
}
|
|
1168
|
+
function recordTriviaChunks(ctx, chunks) {
|
|
1169
|
+
const kinds = ctx.triviaKindLabels;
|
|
1170
|
+
const mask = ctx._triviaCaptureMask;
|
|
1171
|
+
for (const ch of chunks) {
|
|
1172
|
+
pushTriviaLogEntry(ctx, ch.start, ch.end, kinds ? ch.kindIndex : void 0);
|
|
1173
|
+
if (ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)) {
|
|
1174
|
+
if (mask === void 0 || kinds === void 0 || (mask & 1 << ch.kindIndex) !== 0) {
|
|
1175
|
+
pushCstTriviaEntry(ctx, ch.start, ch.end, kinds ? ch.kindIndex : void 0);
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
function triviaKindMask(labels, keep) {
|
|
1181
|
+
if (!labels) return void 0;
|
|
1182
|
+
let mask = 0;
|
|
1183
|
+
for (const name of keep) {
|
|
1184
|
+
const idx = labels.indexOf(name);
|
|
1185
|
+
if (idx >= 0) mask |= 1 << idx;
|
|
1186
|
+
}
|
|
1187
|
+
return mask;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
// src/combinators/grammar.ts
|
|
1191
|
+
function annotateResultLines(result, index) {
|
|
1192
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
1193
|
+
const errors = annotated.errors;
|
|
1194
|
+
if (errors) {
|
|
1195
|
+
;
|
|
1196
|
+
annotated.errors = errors.map((error) => ({
|
|
1197
|
+
...error,
|
|
1198
|
+
span: annotateSpan(error.span, index)
|
|
1199
|
+
}));
|
|
1200
|
+
}
|
|
1201
|
+
return annotated;
|
|
1202
|
+
}
|
|
1203
|
+
function createParseLineContext(input, pos) {
|
|
1204
|
+
const lineIndex = createLineIndex();
|
|
1205
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
1206
|
+
return { lineIndex, lineScannedTo: pos };
|
|
1207
|
+
}
|
|
1208
|
+
function parser(opts, root) {
|
|
1209
|
+
const clearTrivia = opts.trivia === null;
|
|
1210
|
+
return {
|
|
1211
|
+
_tag: "grammar",
|
|
1212
|
+
_meta: root._meta,
|
|
1213
|
+
_def: {
|
|
1214
|
+
tag: "grammar",
|
|
1215
|
+
parser: root,
|
|
1216
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
1217
|
+
clearTrivia,
|
|
1218
|
+
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
1219
|
+
trackLines: opts.trackLines ?? false
|
|
1220
|
+
},
|
|
1221
|
+
parse(input, pos, _ctx) {
|
|
1222
|
+
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
1223
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
1224
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
1225
|
+
const ctx = {
|
|
1226
|
+
..._ctx,
|
|
1227
|
+
trackLines,
|
|
1228
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
1229
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
1230
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
1231
|
+
...clearTrivia ? {
|
|
1232
|
+
trivia: void 0,
|
|
1233
|
+
triviaKindLabels: void 0
|
|
1234
|
+
} : opts.trivia != null ? {
|
|
1235
|
+
trivia: opts.trivia,
|
|
1236
|
+
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
1237
|
+
} : {},
|
|
1238
|
+
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
1239
|
+
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
1240
|
+
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
1241
|
+
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
1242
|
+
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
1243
|
+
// (capture all).
|
|
1244
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
1245
|
+
};
|
|
1246
|
+
const result = root.parse(input, pos ?? 0, ctx);
|
|
1247
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
1248
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
1249
|
+
}
|
|
1250
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
// src/cst/reflection.ts
|
|
1256
|
+
var GRAMMAR_REFLECTION = /* @__PURE__ */ Symbol.for("parseman.grammarReflection");
|
|
1257
|
+
function childrenOf(def) {
|
|
1258
|
+
switch (def.tag) {
|
|
1259
|
+
case "sequence":
|
|
1260
|
+
case "choice":
|
|
1261
|
+
return def.parsers;
|
|
1262
|
+
case "dispatch":
|
|
1263
|
+
return [
|
|
1264
|
+
def.selector,
|
|
1265
|
+
...def.cases.map((c) => c.parser),
|
|
1266
|
+
...def.matchers ? def.matchers.map((c) => c.parser) : [],
|
|
1267
|
+
...def.otherwise ? [def.otherwise] : []
|
|
1268
|
+
];
|
|
1269
|
+
case "many":
|
|
1270
|
+
case "oneOrMore":
|
|
1271
|
+
case "optional":
|
|
1272
|
+
case "attempt":
|
|
1273
|
+
case "transform":
|
|
1274
|
+
case "trivia":
|
|
1275
|
+
case "token":
|
|
1276
|
+
case "leaf":
|
|
1277
|
+
case "label":
|
|
1278
|
+
case "field":
|
|
1279
|
+
case "not":
|
|
1280
|
+
case "peek":
|
|
1281
|
+
case "node":
|
|
1282
|
+
case "withCtx":
|
|
1283
|
+
case "recover":
|
|
1284
|
+
case "expect":
|
|
1285
|
+
return [def.parser];
|
|
1286
|
+
case "grammar":
|
|
1287
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
1288
|
+
case "sepBy":
|
|
1289
|
+
return [def.parser, def.separator];
|
|
1290
|
+
case "skip":
|
|
1291
|
+
return [def.main, def.skipped];
|
|
1292
|
+
case "scanTo":
|
|
1293
|
+
return [def.sentinel, ...def.skip];
|
|
1294
|
+
case "literal":
|
|
1295
|
+
case "regex":
|
|
1296
|
+
case "keywords":
|
|
1297
|
+
case "routed":
|
|
1298
|
+
case "guard":
|
|
1299
|
+
case "lazy":
|
|
1300
|
+
case "unknown":
|
|
1301
|
+
return [];
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
function addNode(out, def) {
|
|
1305
|
+
if (def.type === void 0) return;
|
|
1306
|
+
const existing = out.get(def.type);
|
|
1307
|
+
if (existing === void 0) {
|
|
1308
|
+
out.set(def.type, def.tags === void 0 ? [] : [...def.tags]);
|
|
1309
|
+
return;
|
|
1310
|
+
}
|
|
1311
|
+
if (def.tags === void 0) return;
|
|
1312
|
+
for (const tag of def.tags) {
|
|
1313
|
+
if (!existing.includes(tag)) existing.push(tag);
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
1317
|
+
if (seen.has(parser2)) return;
|
|
1318
|
+
seen.add(parser2);
|
|
1319
|
+
const def = parser2._def;
|
|
1320
|
+
if (def.tag === "lazy") {
|
|
1321
|
+
if (followLazy) {
|
|
1322
|
+
try {
|
|
1323
|
+
collectFromCombinator(def.thunk(), out, seen, followLazy);
|
|
1324
|
+
} catch {
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
1329
|
+
if (def.tag === "node") addNode(out, def);
|
|
1330
|
+
for (const child of childrenOf(def)) collectFromCombinator(child, out, seen, followLazy);
|
|
1331
|
+
}
|
|
1332
|
+
function collectGrammarReflection(ruleMap, opts) {
|
|
1333
|
+
const byType = /* @__PURE__ */ new Map();
|
|
1334
|
+
const followLazy = opts?.followLazy !== false;
|
|
1335
|
+
for (const [, rule] of ruleMap) {
|
|
1336
|
+
if (!followLazy && rule._def.tag === "lazy") {
|
|
1337
|
+
try {
|
|
1338
|
+
const resolved = rule._def.thunk();
|
|
1339
|
+
if (resolved._def.tag !== "lazy") collectFromCombinator(resolved, byType, /* @__PURE__ */ new Set(), false);
|
|
1340
|
+
} catch {
|
|
1341
|
+
}
|
|
1342
|
+
continue;
|
|
1343
|
+
}
|
|
1344
|
+
collectFromCombinator(rule, byType, /* @__PURE__ */ new Set(), followLazy);
|
|
1345
|
+
}
|
|
1346
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
1347
|
+
}
|
|
1348
|
+
function attachGrammarReflection(grammar, reflection) {
|
|
1349
|
+
Object.defineProperty(grammar, GRAMMAR_REFLECTION, { value: reflection, enumerable: false, configurable: true });
|
|
1350
|
+
return grammar;
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
// src/combinators/parser.ts
|
|
1354
|
+
var RULE_ORDER = "__parsemanRuleOrder";
|
|
1355
|
+
function tagRule(r, key) {
|
|
1356
|
+
;
|
|
1357
|
+
r._ruleName = key;
|
|
1358
|
+
if (r._def.tag === "node" && r._def.type === void 0) r._def.type = key;
|
|
1359
|
+
}
|
|
1360
|
+
function isDefinableRef(v) {
|
|
1361
|
+
return !!v && typeof v === "object" && "_def" in v && v._def.tag === "lazy" && typeof v.define === "function";
|
|
1362
|
+
}
|
|
1363
|
+
function ruleNameOf(r) {
|
|
1364
|
+
return r._ruleName;
|
|
1365
|
+
}
|
|
1366
|
+
function isNamedRuleRefForAnotherRule(r, key) {
|
|
1367
|
+
const name = r._def.tag === "lazy" ? ruleNameOf(r) : void 0;
|
|
1368
|
+
return name !== void 0 && name !== key;
|
|
1369
|
+
}
|
|
1370
|
+
function rules(a, b) {
|
|
1371
|
+
const factory = typeof a === "function" ? a : b;
|
|
1372
|
+
const options = typeof a === "function" ? b : a;
|
|
1373
|
+
const cache = {};
|
|
1374
|
+
const proxy = new Proxy(cache, {
|
|
1375
|
+
get(target, key) {
|
|
1376
|
+
if (typeof key !== "string") return void 0;
|
|
1377
|
+
const record = target;
|
|
1378
|
+
if (!(key in record)) {
|
|
1379
|
+
const r = ref();
|
|
1380
|
+
tagRule(r, key);
|
|
1381
|
+
record[key] = r;
|
|
1382
|
+
}
|
|
1383
|
+
return record[key];
|
|
1384
|
+
}
|
|
1385
|
+
});
|
|
1386
|
+
const definitions = factory(proxy);
|
|
1387
|
+
for (const key of Object.keys(definitions)) {
|
|
1388
|
+
const placeholder = cache[key];
|
|
1389
|
+
const parser2 = definitions[key];
|
|
1390
|
+
if (placeholder === parser2) {
|
|
1391
|
+
throw new Error(`rules(): rule "${key}" cannot be a direct alias to itself`);
|
|
1392
|
+
}
|
|
1393
|
+
if (isDefinableRef(placeholder)) {
|
|
1394
|
+
if (!isNamedRuleRefForAnotherRule(parser2, key)) tagRule(parser2, key);
|
|
1395
|
+
placeholder.define(parser2);
|
|
1396
|
+
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
1397
|
+
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1398
|
+
} else if (isNamedRuleRefForAnotherRule(parser2, key)) {
|
|
1399
|
+
const alias = ref();
|
|
1400
|
+
tagRule(alias, key);
|
|
1401
|
+
alias.define(parser2);
|
|
1402
|
+
alias._meta.firstSet = parser2._meta.firstSet;
|
|
1403
|
+
alias._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1404
|
+
cache[key] = alias;
|
|
1405
|
+
} else {
|
|
1406
|
+
tagRule(parser2, key);
|
|
1407
|
+
cache[key] = parser2;
|
|
1115
1408
|
}
|
|
1116
1409
|
}
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
const
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1410
|
+
if (options?.trivia != null) {
|
|
1411
|
+
for (const key of Object.keys(definitions)) {
|
|
1412
|
+
const rule = cache[key];
|
|
1413
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrivia = options.trivia;
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
if (options?.scanSkip != null) {
|
|
1417
|
+
for (const key of Object.keys(definitions)) {
|
|
1418
|
+
const rule = cache[key];
|
|
1419
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarScanSkip = options.scanSkip;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
if (options?.hostMode === "cst") {
|
|
1423
|
+
for (const key of Object.keys(definitions)) {
|
|
1424
|
+
const rule = cache[key];
|
|
1425
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
if (options?.trackLines === true) {
|
|
1429
|
+
for (const key of Object.keys(definitions)) {
|
|
1430
|
+
const rule = cache[key];
|
|
1431
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
1432
|
+
}
|
|
1433
|
+
for (const key of Object.keys(definitions)) {
|
|
1434
|
+
const rule = cache[key];
|
|
1435
|
+
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
1436
|
+
const wrapped = parser({ trackLines: true }, rule);
|
|
1437
|
+
tagRule(wrapped, key);
|
|
1438
|
+
wrapped._meta.grammarTrackLines = true;
|
|
1439
|
+
cache[key] = wrapped;
|
|
1141
1440
|
}
|
|
1142
1441
|
}
|
|
1143
1442
|
}
|
|
1144
|
-
|
|
1443
|
+
for (const key of Object.keys(definitions)) {
|
|
1444
|
+
markUnusedValues(cache[key]);
|
|
1445
|
+
}
|
|
1446
|
+
Object.defineProperty(cache, RULE_ORDER, {
|
|
1447
|
+
value: Object.keys(definitions),
|
|
1448
|
+
enumerable: false,
|
|
1449
|
+
configurable: true
|
|
1450
|
+
});
|
|
1451
|
+
attachGrammarReflection(cache, collectGrammarReflection(Object.keys(definitions).map((key) => [key, cache[key]])));
|
|
1452
|
+
return cache;
|
|
1145
1453
|
}
|
|
1146
1454
|
|
|
1147
1455
|
// src/analysis/duplication.ts
|
|
@@ -1396,135 +1704,6 @@ function regex(pattern, flags = "") {
|
|
|
1396
1704
|
};
|
|
1397
1705
|
}
|
|
1398
1706
|
|
|
1399
|
-
// src/cst/trivia-kinds.ts
|
|
1400
|
-
function unwrapTrivia(p) {
|
|
1401
|
-
let cur = p;
|
|
1402
|
-
while (cur._def.tag === "trivia") cur = cur._def.parser;
|
|
1403
|
-
return cur;
|
|
1404
|
-
}
|
|
1405
|
-
function peelLabel(p) {
|
|
1406
|
-
if (p._def.tag === "label") return { label: p._def.label, parser: p._def.parser };
|
|
1407
|
-
return null;
|
|
1408
|
-
}
|
|
1409
|
-
function analyzeLabeledTrivia(trivia2) {
|
|
1410
|
-
let core = unwrapTrivia(trivia2);
|
|
1411
|
-
let minRepeats = 1;
|
|
1412
|
-
if (core._def.tag === "oneOrMore") {
|
|
1413
|
-
core = core._def.parser;
|
|
1414
|
-
minRepeats = 1;
|
|
1415
|
-
} else if (core._def.tag === "many") {
|
|
1416
|
-
core = core._def.parser;
|
|
1417
|
-
minRepeats = 0;
|
|
1418
|
-
}
|
|
1419
|
-
const arms = [];
|
|
1420
|
-
if (core._def.tag === "choice") {
|
|
1421
|
-
for (let i = 0; i < core._def.parsers.length; i++) {
|
|
1422
|
-
const peeled = peelLabel(core._def.parsers[i]);
|
|
1423
|
-
if (!peeled) return null;
|
|
1424
|
-
arms.push({ label: peeled.label, kindIndex: i, parser: peeled.parser });
|
|
1425
|
-
}
|
|
1426
|
-
} else {
|
|
1427
|
-
const peeled = peelLabel(core);
|
|
1428
|
-
if (!peeled) return null;
|
|
1429
|
-
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1430
|
-
}
|
|
1431
|
-
return { labels: arms.map((a) => a.label), arms, minRepeats };
|
|
1432
|
-
}
|
|
1433
|
-
function matchArmAt(input, pos, arm) {
|
|
1434
|
-
const r = arm.parse(input, pos, { trackLines: false });
|
|
1435
|
-
if (!r.ok || r.span.end <= pos) return null;
|
|
1436
|
-
return { end: r.span.end };
|
|
1437
|
-
}
|
|
1438
|
-
function scanLabeledTriviaChunks(input, cur, spec) {
|
|
1439
|
-
const chunks = [];
|
|
1440
|
-
let pos = cur;
|
|
1441
|
-
while (pos < input.length) {
|
|
1442
|
-
let matched = null;
|
|
1443
|
-
for (const arm of spec.arms) {
|
|
1444
|
-
const m = matchArmAt(input, pos, arm.parser);
|
|
1445
|
-
if (m) {
|
|
1446
|
-
matched = { end: m.end, kindIndex: arm.kindIndex };
|
|
1447
|
-
break;
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
if (!matched) break;
|
|
1451
|
-
chunks.push({ start: pos, end: matched.end, kindIndex: matched.kindIndex });
|
|
1452
|
-
pos = matched.end;
|
|
1453
|
-
}
|
|
1454
|
-
if (chunks.length < spec.minRepeats) {
|
|
1455
|
-
return { end: cur, chunks: [] };
|
|
1456
|
-
}
|
|
1457
|
-
return { end: pos, chunks };
|
|
1458
|
-
}
|
|
1459
|
-
function scanFastWsCommentsChunks(input, cur, wsKind, commentKind) {
|
|
1460
|
-
const chunks = [];
|
|
1461
|
-
let pos = cur;
|
|
1462
|
-
while (pos < input.length) {
|
|
1463
|
-
const c = input.charCodeAt(pos);
|
|
1464
|
-
if (c === 32 || c === 9 || c === 10 || c === 13 || c === 12) {
|
|
1465
|
-
const start = pos;
|
|
1466
|
-
pos++;
|
|
1467
|
-
while (pos < input.length) {
|
|
1468
|
-
const c2 = input.charCodeAt(pos);
|
|
1469
|
-
if (c2 === 32 || c2 === 9 || c2 === 10 || c2 === 13 || c2 === 12) pos++;
|
|
1470
|
-
else break;
|
|
1471
|
-
}
|
|
1472
|
-
chunks.push({ start, end: pos, kindIndex: wsKind });
|
|
1473
|
-
continue;
|
|
1474
|
-
}
|
|
1475
|
-
if (c === 47 && input.charCodeAt(pos + 1) === 42) {
|
|
1476
|
-
let j2 = pos + 2;
|
|
1477
|
-
while (j2 + 1 < input.length && !(input.charCodeAt(j2) === 42 && input.charCodeAt(j2 + 1) === 47)) j2++;
|
|
1478
|
-
if (j2 + 1 < input.length && input.charCodeAt(j2) === 42 && input.charCodeAt(j2 + 1) === 47) {
|
|
1479
|
-
const start = pos;
|
|
1480
|
-
pos = j2 + 2;
|
|
1481
|
-
chunks.push({ start, end: pos, kindIndex: commentKind });
|
|
1482
|
-
continue;
|
|
1483
|
-
}
|
|
1484
|
-
break;
|
|
1485
|
-
}
|
|
1486
|
-
break;
|
|
1487
|
-
}
|
|
1488
|
-
return { end: pos, chunks };
|
|
1489
|
-
}
|
|
1490
|
-
function tryFastLabeledScan(input, cur, trivia2) {
|
|
1491
|
-
const spec = analyzeLabeledTrivia(trivia2);
|
|
1492
|
-
if (!spec || spec.arms.length !== 2) return null;
|
|
1493
|
-
const wsArm = spec.arms.find((a) => {
|
|
1494
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1495
|
-
return src != null && !src.includes("\\*");
|
|
1496
|
-
});
|
|
1497
|
-
const commentArm = spec.arms.find((a) => {
|
|
1498
|
-
const src = getCoreRegexDef(a.parser)?.source;
|
|
1499
|
-
return src != null && src.includes("\\*");
|
|
1500
|
-
});
|
|
1501
|
-
if (!wsArm || !commentArm) return null;
|
|
1502
|
-
const { chunks } = scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1503
|
-
if (chunks.length < spec.minRepeats) return { end: cur, chunks: [] };
|
|
1504
|
-
return scanFastWsCommentsChunks(input, cur, wsArm.kindIndex, commentArm.kindIndex);
|
|
1505
|
-
}
|
|
1506
|
-
function recordTriviaChunks(ctx, chunks) {
|
|
1507
|
-
const kinds = ctx.triviaKindLabels;
|
|
1508
|
-
const mask = ctx._triviaCaptureMask;
|
|
1509
|
-
for (const ch of chunks) {
|
|
1510
|
-
pushTriviaLogEntry(ctx, ch.start, ch.end, kinds ? ch.kindIndex : void 0);
|
|
1511
|
-
if (ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)) {
|
|
1512
|
-
if (mask === void 0 || kinds === void 0 || (mask & 1 << ch.kindIndex) !== 0) {
|
|
1513
|
-
pushCstTriviaEntry(ctx, ch.start, ch.end, kinds ? ch.kindIndex : void 0);
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
|
-
function triviaKindMask(labels, keep) {
|
|
1519
|
-
if (!labels) return void 0;
|
|
1520
|
-
let mask = 0;
|
|
1521
|
-
for (const name of keep) {
|
|
1522
|
-
const idx = labels.indexOf(name);
|
|
1523
|
-
if (idx >= 0) mask |= 1 << idx;
|
|
1524
|
-
}
|
|
1525
|
-
return mask;
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
1707
|
// src/combinators/trivia-skip.ts
|
|
1529
1708
|
var NOOP_COMMIT = () => {
|
|
1530
1709
|
};
|
|
@@ -2896,13 +3075,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
2896
3075
|
const collapse = opts?.collapse === true;
|
|
2897
3076
|
const captureTrivia = opts?.captureTrivia === true;
|
|
2898
3077
|
const trailingTrivia = opts?.trailingTrivia === true;
|
|
3078
|
+
const tags = opts?.tags;
|
|
2899
3079
|
if (unwrap && collapse) {
|
|
2900
3080
|
throw new Error("node() options cannot set both unwrap and collapse");
|
|
2901
3081
|
}
|
|
2902
3082
|
if (project !== void 0 && (unwrap || collapse)) {
|
|
2903
3083
|
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
2904
3084
|
}
|
|
2905
|
-
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;
|
|
3085
|
+
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;
|
|
2906
3086
|
const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
2907
3087
|
const clonesState = build ? buildReadsState(def) : project === void 0;
|
|
2908
3088
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
@@ -2948,7 +3128,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
2948
3128
|
const cstOutput = cstOutputHost(ctx.build);
|
|
2949
3129
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
2950
3130
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
2951
|
-
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 };
|
|
3131
|
+
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 };
|
|
2952
3132
|
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 };
|
|
2953
3133
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
2954
3134
|
pushCstChild(ctx, built, rawEntry);
|
|
@@ -2958,71 +3138,6 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
2958
3138
|
};
|
|
2959
3139
|
}
|
|
2960
3140
|
|
|
2961
|
-
// src/combinators/grammar.ts
|
|
2962
|
-
function annotateResultLines(result, index) {
|
|
2963
|
-
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
2964
|
-
const errors = annotated.errors;
|
|
2965
|
-
if (errors) {
|
|
2966
|
-
;
|
|
2967
|
-
annotated.errors = errors.map((error) => ({
|
|
2968
|
-
...error,
|
|
2969
|
-
span: annotateSpan(error.span, index)
|
|
2970
|
-
}));
|
|
2971
|
-
}
|
|
2972
|
-
return annotated;
|
|
2973
|
-
}
|
|
2974
|
-
function createParseLineContext(input, pos) {
|
|
2975
|
-
const lineIndex = createLineIndex();
|
|
2976
|
-
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
2977
|
-
return { lineIndex, lineScannedTo: pos };
|
|
2978
|
-
}
|
|
2979
|
-
function parser(opts, root) {
|
|
2980
|
-
const clearTrivia = opts.trivia === null;
|
|
2981
|
-
return {
|
|
2982
|
-
_tag: "grammar",
|
|
2983
|
-
_meta: root._meta,
|
|
2984
|
-
_def: {
|
|
2985
|
-
tag: "grammar",
|
|
2986
|
-
parser: root,
|
|
2987
|
-
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2988
|
-
clearTrivia,
|
|
2989
|
-
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2990
|
-
trackLines: opts.trackLines ?? false
|
|
2991
|
-
},
|
|
2992
|
-
parse(input, pos, _ctx) {
|
|
2993
|
-
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2994
|
-
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2995
|
-
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
2996
|
-
const ctx = {
|
|
2997
|
-
..._ctx,
|
|
2998
|
-
trackLines,
|
|
2999
|
-
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
3000
|
-
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
3001
|
-
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
3002
|
-
...clearTrivia ? {
|
|
3003
|
-
trivia: void 0,
|
|
3004
|
-
triviaKindLabels: void 0
|
|
3005
|
-
} : opts.trivia != null ? {
|
|
3006
|
-
trivia: opts.trivia,
|
|
3007
|
-
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
3008
|
-
} : {},
|
|
3009
|
-
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
3010
|
-
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
3011
|
-
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
3012
|
-
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
3013
|
-
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
3014
|
-
// (capture all).
|
|
3015
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
3016
|
-
};
|
|
3017
|
-
const result = root.parse(input, pos ?? 0, ctx);
|
|
3018
|
-
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
3019
|
-
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
3020
|
-
}
|
|
3021
|
-
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
3022
|
-
}
|
|
3023
|
-
};
|
|
3024
|
-
}
|
|
3025
|
-
|
|
3026
3141
|
// src/combinators/token.ts
|
|
3027
3142
|
function token(root) {
|
|
3028
3143
|
const meta = {
|
|
@@ -3305,15 +3420,16 @@ function normalizeCstCollapse(collapse) {
|
|
|
3305
3420
|
}
|
|
3306
3421
|
return typeof collapse === "function" ? collapse : void 0;
|
|
3307
3422
|
}
|
|
3308
|
-
function buildCstNode(type, children, _fields, span, _rawChildren, _triviaLog, state) {
|
|
3309
|
-
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children] };
|
|
3423
|
+
function buildCstNode(type, children, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
3424
|
+
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] };
|
|
3310
3425
|
}
|
|
3311
|
-
function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, triviaLog, state) {
|
|
3426
|
+
function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
3312
3427
|
if (typeof typeOrOptions === "string") {
|
|
3313
3428
|
return buildCstNode(typeOrOptions, children ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
3314
3429
|
}
|
|
3315
3430
|
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
3316
|
-
const
|
|
3431
|
+
const materializeTags = typeOrOptions?.tags === true;
|
|
3432
|
+
const host = (type, children2, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children2 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
3317
3433
|
host._parsemanCstOutput = true;
|
|
3318
3434
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
3319
3435
|
return host;
|