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.
@@ -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
- ranges.push({ lo, hi });
1118
- return { kind: "ranges", ranges };
1119
- }
1120
- function inFirstSet(code, fs) {
1121
- if (fs.kind === "any") return true;
1122
- if (fs.kind === "empty") return false;
1123
- for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
1124
- return false;
1125
- }
1126
- function areDisjoint(sets) {
1127
- if (sets.some((s) => s.kind === "any")) return false;
1128
- for (let i = 0; i < sets.length; i++)
1129
- for (let j2 = i + 1; j2 < sets.length; j2++)
1130
- if (intersects(sets[i], sets[j2])) return false;
1131
- return true;
1132
- }
1133
- function buildAsciiDispatch(parsers) {
1134
- const table = Array(128).fill(-1);
1135
- for (let i = 0; i < parsers.length; i++) {
1136
- const fs = parsers[i]._meta.firstSet;
1137
- if (fs.kind !== "ranges") continue;
1138
- for (const { lo, hi } of fs.ranges) {
1139
- for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
1140
- table[code] = i;
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
- return table;
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 = {