parseman 0.42.0 → 0.42.1
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/parser.d.ts +6 -0
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +2 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +1 -0
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/index.cjs +149 -112
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +149 -112
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.cjs.map +1 -1
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/index.cjs +336 -100
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +336 -100
- package/dist/plugin/index.js.map +4 -4
- package/dist/spec/index.cjs +322 -307
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +322 -307
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +6 -0
- 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,333 @@ 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/combinators/parser.ts
|
|
1256
|
+
var RULE_ORDER = "__parsemanRuleOrder";
|
|
1257
|
+
function tagRule(r, key) {
|
|
1258
|
+
;
|
|
1259
|
+
r._ruleName = key;
|
|
1260
|
+
if (r._def.tag === "node" && r._def.type === void 0) r._def.type = key;
|
|
1261
|
+
}
|
|
1262
|
+
function isDefinableRef(v) {
|
|
1263
|
+
return !!v && typeof v === "object" && "_def" in v && v._def.tag === "lazy" && typeof v.define === "function";
|
|
1264
|
+
}
|
|
1265
|
+
function ruleNameOf(r) {
|
|
1266
|
+
return r._ruleName;
|
|
1267
|
+
}
|
|
1268
|
+
function isNamedRuleRefForAnotherRule(r, key) {
|
|
1269
|
+
const name = r._def.tag === "lazy" ? ruleNameOf(r) : void 0;
|
|
1270
|
+
return name !== void 0 && name !== key;
|
|
1271
|
+
}
|
|
1272
|
+
function rules(a, b) {
|
|
1273
|
+
const factory = typeof a === "function" ? a : b;
|
|
1274
|
+
const options = typeof a === "function" ? b : a;
|
|
1275
|
+
const cache = {};
|
|
1276
|
+
const proxy = new Proxy(cache, {
|
|
1277
|
+
get(target, key) {
|
|
1278
|
+
if (typeof key !== "string") return void 0;
|
|
1279
|
+
const record = target;
|
|
1280
|
+
if (!(key in record)) {
|
|
1281
|
+
const r = ref();
|
|
1282
|
+
tagRule(r, key);
|
|
1283
|
+
record[key] = r;
|
|
1284
|
+
}
|
|
1285
|
+
return record[key];
|
|
1286
|
+
}
|
|
1287
|
+
});
|
|
1288
|
+
const definitions = factory(proxy);
|
|
1289
|
+
for (const key of Object.keys(definitions)) {
|
|
1290
|
+
const placeholder = cache[key];
|
|
1291
|
+
const parser2 = definitions[key];
|
|
1292
|
+
if (placeholder === parser2) {
|
|
1293
|
+
throw new Error(`rules(): rule "${key}" cannot be a direct alias to itself`);
|
|
1294
|
+
}
|
|
1295
|
+
if (isDefinableRef(placeholder)) {
|
|
1296
|
+
if (!isNamedRuleRefForAnotherRule(parser2, key)) tagRule(parser2, key);
|
|
1297
|
+
placeholder.define(parser2);
|
|
1298
|
+
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
1299
|
+
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1300
|
+
} else if (isNamedRuleRefForAnotherRule(parser2, key)) {
|
|
1301
|
+
const alias = ref();
|
|
1302
|
+
tagRule(alias, key);
|
|
1303
|
+
alias.define(parser2);
|
|
1304
|
+
alias._meta.firstSet = parser2._meta.firstSet;
|
|
1305
|
+
alias._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1306
|
+
cache[key] = alias;
|
|
1307
|
+
} else {
|
|
1308
|
+
tagRule(parser2, key);
|
|
1309
|
+
cache[key] = parser2;
|
|
1115
1310
|
}
|
|
1116
1311
|
}
|
|
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
|
-
|
|
1312
|
+
if (options?.trivia != null) {
|
|
1313
|
+
for (const key of Object.keys(definitions)) {
|
|
1314
|
+
const rule = cache[key];
|
|
1315
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrivia = options.trivia;
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
if (options?.scanSkip != null) {
|
|
1319
|
+
for (const key of Object.keys(definitions)) {
|
|
1320
|
+
const rule = cache[key];
|
|
1321
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarScanSkip = options.scanSkip;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
if (options?.hostMode === "cst") {
|
|
1325
|
+
for (const key of Object.keys(definitions)) {
|
|
1326
|
+
const rule = cache[key];
|
|
1327
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
if (options?.trackLines === true) {
|
|
1331
|
+
for (const key of Object.keys(definitions)) {
|
|
1332
|
+
const rule = cache[key];
|
|
1333
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
1334
|
+
}
|
|
1335
|
+
for (const key of Object.keys(definitions)) {
|
|
1336
|
+
const rule = cache[key];
|
|
1337
|
+
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
1338
|
+
const wrapped = parser({ trackLines: true }, rule);
|
|
1339
|
+
tagRule(wrapped, key);
|
|
1340
|
+
wrapped._meta.grammarTrackLines = true;
|
|
1341
|
+
cache[key] = wrapped;
|
|
1141
1342
|
}
|
|
1142
1343
|
}
|
|
1143
1344
|
}
|
|
1144
|
-
|
|
1345
|
+
for (const key of Object.keys(definitions)) {
|
|
1346
|
+
markUnusedValues(cache[key]);
|
|
1347
|
+
}
|
|
1348
|
+
Object.defineProperty(cache, RULE_ORDER, {
|
|
1349
|
+
value: Object.keys(definitions),
|
|
1350
|
+
enumerable: false,
|
|
1351
|
+
configurable: true
|
|
1352
|
+
});
|
|
1353
|
+
return cache;
|
|
1145
1354
|
}
|
|
1146
1355
|
|
|
1147
1356
|
// src/analysis/duplication.ts
|
|
@@ -1396,135 +1605,6 @@ function regex(pattern, flags = "") {
|
|
|
1396
1605
|
};
|
|
1397
1606
|
}
|
|
1398
1607
|
|
|
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
1608
|
// src/combinators/trivia-skip.ts
|
|
1529
1609
|
var NOOP_COMMIT = () => {
|
|
1530
1610
|
};
|
|
@@ -2958,71 +3038,6 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
2958
3038
|
};
|
|
2959
3039
|
}
|
|
2960
3040
|
|
|
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
3041
|
// src/combinators/token.ts
|
|
3027
3042
|
function token(root) {
|
|
3028
3043
|
const meta = {
|