parseman 0.18.0 → 0.18.2
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/README.md +3 -2
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/repeat.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/index.cjs +258 -35
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +258 -35
- package/dist/index.js.map +3 -3
- package/dist/plugin/index.cjs +258 -35
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.js +258 -35
- package/dist/plugin/index.js.map +3 -3
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -349,13 +349,12 @@ function literal(value, opts = {}) {
|
|
|
349
349
|
if (end > input.length) {
|
|
350
350
|
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
351
351
|
}
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
if (matched) {
|
|
352
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
353
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
355
354
|
const span = { start: pos, end };
|
|
356
|
-
const leaf = { _tag: "leaf", value:
|
|
355
|
+
const leaf = { _tag: "leaf", value: matchedValue, span };
|
|
357
356
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
358
|
-
return { ok: true, value:
|
|
357
|
+
return { ok: true, value: matchedValue, span };
|
|
359
358
|
}
|
|
360
359
|
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
361
360
|
}
|
|
@@ -368,10 +367,102 @@ function registerRegexAnalyzer(analyzer) {
|
|
|
368
367
|
firstSetAnalyzer = analyzer;
|
|
369
368
|
}
|
|
370
369
|
var permissiveFirstSet = () => ({ firstSet: any(), canMatchNewline: true });
|
|
370
|
+
var SCAN_BAIL_AT = 64;
|
|
371
|
+
var SPACE_RANGES = [
|
|
372
|
+
[9, 13],
|
|
373
|
+
[32, 32],
|
|
374
|
+
[160, 160],
|
|
375
|
+
[5760, 5760],
|
|
376
|
+
[8192, 8202],
|
|
377
|
+
[8232, 8233],
|
|
378
|
+
[8239, 8239],
|
|
379
|
+
[8287, 8287],
|
|
380
|
+
[12288, 12288],
|
|
381
|
+
[65279, 65279]
|
|
382
|
+
];
|
|
383
|
+
var CLASS_ESCAPES = { t: 9, n: 10, r: 13, f: 12, v: 11, "0": 0 };
|
|
384
|
+
function shorthandRanges(ch) {
|
|
385
|
+
if (ch === "d") return [[48, 57]];
|
|
386
|
+
if (ch === "s") return SPACE_RANGES;
|
|
387
|
+
return [[48, 57], [65, 90], [97, 122], [95, 95]];
|
|
388
|
+
}
|
|
389
|
+
function inRanges(cp, ranges) {
|
|
390
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
391
|
+
const [lo, hi] = ranges[i];
|
|
392
|
+
if (cp >= lo && cp <= hi) return true;
|
|
393
|
+
}
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
function readClassRanges(body) {
|
|
397
|
+
if (body.startsWith("^")) return null;
|
|
398
|
+
const ranges = [];
|
|
399
|
+
let i = 0;
|
|
400
|
+
const readAtom = () => {
|
|
401
|
+
const ch = body[i];
|
|
402
|
+
if (ch === void 0) return null;
|
|
403
|
+
if (ch === "\\") {
|
|
404
|
+
const esc = body[i + 1];
|
|
405
|
+
if (esc === void 0) return null;
|
|
406
|
+
i += 2;
|
|
407
|
+
if (esc === "d" || esc === "w" || esc === "s") return { ranges: shorthandRanges(esc) };
|
|
408
|
+
if (esc in CLASS_ESCAPES) return { cp: CLASS_ESCAPES[esc] };
|
|
409
|
+
if (esc >= "a" && esc <= "z" || esc >= "A" && esc <= "Z") return null;
|
|
410
|
+
return { cp: esc.charCodeAt(0) };
|
|
411
|
+
}
|
|
412
|
+
i++;
|
|
413
|
+
return { cp: ch.charCodeAt(0) };
|
|
414
|
+
};
|
|
415
|
+
while (i < body.length) {
|
|
416
|
+
const lo = readAtom();
|
|
417
|
+
if (!lo) return null;
|
|
418
|
+
if ("ranges" in lo) {
|
|
419
|
+
ranges.push(...lo.ranges);
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
if (body[i] === "-" && body[i + 1] !== void 0 && body[i + 1] !== "]") {
|
|
423
|
+
i++;
|
|
424
|
+
const hi = readAtom();
|
|
425
|
+
if (!hi || "ranges" in hi) return null;
|
|
426
|
+
ranges.push([lo.cp, hi.cp]);
|
|
427
|
+
} else {
|
|
428
|
+
ranges.push([lo.cp, lo.cp]);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return ranges.length ? ranges : null;
|
|
432
|
+
}
|
|
433
|
+
function shortScanner(source, flags) {
|
|
434
|
+
if (/[imsuvy]/.test(flags)) return null;
|
|
435
|
+
let ranges = null;
|
|
436
|
+
let quant = "";
|
|
437
|
+
if (source[0] === "[") {
|
|
438
|
+
let end = 1;
|
|
439
|
+
while (end < source.length && source[end] !== "]") {
|
|
440
|
+
if (source[end] === "\\") end += 2;
|
|
441
|
+
else end++;
|
|
442
|
+
}
|
|
443
|
+
if (source[end] !== "]") return null;
|
|
444
|
+
ranges = readClassRanges(source.slice(1, end));
|
|
445
|
+
quant = source.slice(end + 1);
|
|
446
|
+
} else if (source[0] === "\\" && (source[1] === "d" || source[1] === "w" || source[1] === "s")) {
|
|
447
|
+
ranges = shorthandRanges(source[1]);
|
|
448
|
+
quant = source.slice(2);
|
|
449
|
+
}
|
|
450
|
+
if (!ranges || quant !== "+" && quant !== "*") return null;
|
|
451
|
+
const minOne = quant === "+";
|
|
452
|
+
return (input, pos) => {
|
|
453
|
+
let end = pos;
|
|
454
|
+
while (end < input.length && inRanges(input.charCodeAt(end), ranges)) {
|
|
455
|
+
end++;
|
|
456
|
+
if (end - pos >= SCAN_BAIL_AT) return void 0;
|
|
457
|
+
}
|
|
458
|
+
return minOne && end === pos ? null : end;
|
|
459
|
+
};
|
|
460
|
+
}
|
|
371
461
|
function regex(pattern, flags = "") {
|
|
372
462
|
const source = typeof pattern === "string" ? pattern : pattern.source;
|
|
373
463
|
const resolvedFlags = typeof pattern === "string" ? flags : pattern.flags;
|
|
374
464
|
const anchored = new RegExp(source, "y" + resolvedFlags.replace(/[gy]/g, ""));
|
|
465
|
+
const scan = shortScanner(source, resolvedFlags);
|
|
375
466
|
const { firstSet, canMatchNewline } = (firstSetAnalyzer ?? permissiveFirstSet)(source);
|
|
376
467
|
const meta = { firstSet, canMatchNewline, isTrivia: false };
|
|
377
468
|
return {
|
|
@@ -379,6 +470,15 @@ function regex(pattern, flags = "") {
|
|
|
379
470
|
_meta: meta,
|
|
380
471
|
_def: { tag: "regex", source, flags: resolvedFlags },
|
|
381
472
|
parse(input, pos, ctx) {
|
|
473
|
+
const scanEnd = scan?.(input, pos);
|
|
474
|
+
if (scanEnd !== void 0) {
|
|
475
|
+
if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
|
|
476
|
+
const value = input.slice(pos, scanEnd);
|
|
477
|
+
const span2 = { start: pos, end: scanEnd };
|
|
478
|
+
const leaf2 = { _tag: "leaf", value, span: span2 };
|
|
479
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf2);
|
|
480
|
+
return { ok: true, value, span: span2 };
|
|
481
|
+
}
|
|
382
482
|
anchored.lastIndex = pos;
|
|
383
483
|
const m = anchored.exec(input);
|
|
384
484
|
if (m === null) {
|
|
@@ -562,13 +662,10 @@ function choice(...args) {
|
|
|
562
662
|
};
|
|
563
663
|
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
564
664
|
const autoNot = !disjoint && !hasGates && strategy?.tag === "firstMatch" ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
565
|
-
let greedyRe = null;
|
|
566
665
|
let greedyLitMap = null;
|
|
567
666
|
let sortedParsers = null;
|
|
667
|
+
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
568
668
|
if (strategy?.tag === "greedyClassify") {
|
|
569
|
-
const regexDef = getCoreRegexDef(parsers[strategy.superIndex]);
|
|
570
|
-
const flags = "y" + regexDef.flags.replace(/[gy]/g, "");
|
|
571
|
-
greedyRe = new RegExp(regexDef.source, flags);
|
|
572
669
|
greedyLitMap = /* @__PURE__ */ new Map();
|
|
573
670
|
for (let i = 0; i < parsers.length; i++) {
|
|
574
671
|
if (i === strategy.superIndex) continue;
|
|
@@ -593,14 +690,21 @@ function choice(...args) {
|
|
|
593
690
|
const expected = [];
|
|
594
691
|
if (disjoint && pos < input.length) {
|
|
595
692
|
const code = input.codePointAt(pos);
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
if (
|
|
600
|
-
|
|
601
|
-
|
|
693
|
+
let parser2 = code < 128 ? asciiDispatch?.[code] ?? null : null;
|
|
694
|
+
if (!parser2) {
|
|
695
|
+
for (const p of parsers) {
|
|
696
|
+
if (inFirstSet(code, p._meta.firstSet)) {
|
|
697
|
+
parser2 = p;
|
|
698
|
+
break;
|
|
699
|
+
}
|
|
602
700
|
}
|
|
603
701
|
}
|
|
702
|
+
if (parser2) {
|
|
703
|
+
const result = parser2.parse(input, pos, ctx);
|
|
704
|
+
if (result.ok) return result;
|
|
705
|
+
expected.push(...result.expected);
|
|
706
|
+
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
707
|
+
}
|
|
604
708
|
return {
|
|
605
709
|
ok: false,
|
|
606
710
|
expected: parsers.flatMap((p) => {
|
|
@@ -776,6 +880,19 @@ function areDisjoint(sets) {
|
|
|
776
880
|
if (intersects(sets[i], sets[j])) return false;
|
|
777
881
|
return true;
|
|
778
882
|
}
|
|
883
|
+
function buildAsciiDispatch(parsers) {
|
|
884
|
+
const table = Array(128).fill(null);
|
|
885
|
+
for (const parser2 of parsers) {
|
|
886
|
+
const fs = parser2._meta.firstSet;
|
|
887
|
+
if (fs.kind !== "ranges") continue;
|
|
888
|
+
for (const { lo, hi } of fs.ranges) {
|
|
889
|
+
for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
|
|
890
|
+
table[code] = parser2;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
return table;
|
|
895
|
+
}
|
|
779
896
|
|
|
780
897
|
// src/cst/trivia-kinds.ts
|
|
781
898
|
function unwrapTrivia(p) {
|
|
@@ -897,6 +1014,7 @@ function recordTriviaChunks(ctx, chunks) {
|
|
|
897
1014
|
// src/combinators/trivia-skip.ts
|
|
898
1015
|
var NOOP_COMMIT = () => {
|
|
899
1016
|
};
|
|
1017
|
+
var fastTriviaCache = /* @__PURE__ */ new WeakMap();
|
|
900
1018
|
function needsDeferredTriviaCommit(ctx) {
|
|
901
1019
|
return ctx._triviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
902
1020
|
}
|
|
@@ -923,6 +1041,8 @@ function scanWithLabels(input, cur, ctx) {
|
|
|
923
1041
|
function advanceTrivia(input, cur, ctx) {
|
|
924
1042
|
const triviaP = ctx.trivia;
|
|
925
1043
|
if (!triviaP) return cur;
|
|
1044
|
+
const fast = fastTriviaScanner(triviaP);
|
|
1045
|
+
if (fast) return fast(input, cur);
|
|
926
1046
|
if (ctx.triviaKindLabels) {
|
|
927
1047
|
const scan = scanWithLabels(input, cur, ctx);
|
|
928
1048
|
return scan.end;
|
|
@@ -935,6 +1055,10 @@ function scanTrivia(input, cur, ctx) {
|
|
|
935
1055
|
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
936
1056
|
const log = ctx._triviaLog;
|
|
937
1057
|
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1058
|
+
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1059
|
+
if (fast && log === void 0 && !captureTl) {
|
|
1060
|
+
return { end: fast(input, cur), commit: NOOP_COMMIT };
|
|
1061
|
+
}
|
|
938
1062
|
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
939
1063
|
return scanWithLabels(input, cur, ctx);
|
|
940
1064
|
}
|
|
@@ -956,6 +1080,79 @@ function scanTrivia(input, cur, ctx) {
|
|
|
956
1080
|
const tr = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
957
1081
|
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
958
1082
|
}
|
|
1083
|
+
function fastTriviaScanner(trivia2) {
|
|
1084
|
+
const cached = fastTriviaCache.get(trivia2);
|
|
1085
|
+
if (cached !== void 0) return cached;
|
|
1086
|
+
const scanner = buildFastTriviaScanner(trivia2);
|
|
1087
|
+
fastTriviaCache.set(trivia2, scanner);
|
|
1088
|
+
return scanner;
|
|
1089
|
+
}
|
|
1090
|
+
function buildFastTriviaScanner(trivia2) {
|
|
1091
|
+
const core = trivia2._def.tag === "trivia" ? trivia2._def.parser : trivia2;
|
|
1092
|
+
const direct = regexTriviaScanner(core);
|
|
1093
|
+
if (direct) return direct;
|
|
1094
|
+
const repeat = core._def.tag === "oneOrMore" || core._def.tag === "many" && core._def.min >= 1 ? core._def.parser : null;
|
|
1095
|
+
if (!repeat) return null;
|
|
1096
|
+
const one = regexTriviaScanner(repeat);
|
|
1097
|
+
if (one) return loopScanner([one]);
|
|
1098
|
+
if (repeat._def.tag !== "choice") return null;
|
|
1099
|
+
const arms = repeat._def.parsers.map(regexTriviaScanner);
|
|
1100
|
+
if (arms.some((s) => s === null)) return null;
|
|
1101
|
+
return loopScanner(arms);
|
|
1102
|
+
}
|
|
1103
|
+
function loopScanner(arms) {
|
|
1104
|
+
return (input, cur) => {
|
|
1105
|
+
let pos = cur;
|
|
1106
|
+
scan: while (pos < input.length) {
|
|
1107
|
+
for (const arm of arms) {
|
|
1108
|
+
const end = arm(input, pos);
|
|
1109
|
+
if (end > pos) {
|
|
1110
|
+
pos = end;
|
|
1111
|
+
continue scan;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
break;
|
|
1115
|
+
}
|
|
1116
|
+
return pos;
|
|
1117
|
+
};
|
|
1118
|
+
}
|
|
1119
|
+
function regexTriviaScanner(parser2) {
|
|
1120
|
+
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1121
|
+
const ws = whitespaceSource(parser2._def.source);
|
|
1122
|
+
if (ws) return ws;
|
|
1123
|
+
return blockCommentSource(parser2._def.source) ? scanBlockComment : null;
|
|
1124
|
+
}
|
|
1125
|
+
function whitespaceSource(source) {
|
|
1126
|
+
const m = /^\[([ \\tnrf]+)\][*+]$/.exec(source);
|
|
1127
|
+
if (!m) return null;
|
|
1128
|
+
const chars = /* @__PURE__ */ new Set();
|
|
1129
|
+
for (let i = 0; i < m[1].length; i++) {
|
|
1130
|
+
const ch = m[1][i];
|
|
1131
|
+
if (ch !== "\\") {
|
|
1132
|
+
chars.add(ch.charCodeAt(0));
|
|
1133
|
+
continue;
|
|
1134
|
+
}
|
|
1135
|
+
const esc = m[1][++i];
|
|
1136
|
+
if (esc === "t") chars.add(9);
|
|
1137
|
+
else if (esc === "n") chars.add(10);
|
|
1138
|
+
else if (esc === "r") chars.add(13);
|
|
1139
|
+
else if (esc === "f") chars.add(12);
|
|
1140
|
+
else return null;
|
|
1141
|
+
}
|
|
1142
|
+
return (input, cur) => {
|
|
1143
|
+
let pos = cur;
|
|
1144
|
+
while (pos < input.length && chars.has(input.charCodeAt(pos))) pos++;
|
|
1145
|
+
return pos;
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
function blockCommentSource(source) {
|
|
1149
|
+
return source === "\\/\\*(?:[^*]|\\*(?!\\/))*\\*\\/" || source === "\\/\\*[^]*?\\*\\/";
|
|
1150
|
+
}
|
|
1151
|
+
function scanBlockComment(input, cur) {
|
|
1152
|
+
if (input.charCodeAt(cur) !== 47 || input.charCodeAt(cur + 1) !== 42) return cur;
|
|
1153
|
+
const close = input.indexOf("*/", cur + 2);
|
|
1154
|
+
return close === -1 ? cur : close + 2;
|
|
1155
|
+
}
|
|
959
1156
|
|
|
960
1157
|
// src/combinators/sequence.ts
|
|
961
1158
|
function sequence(...parsers) {
|
|
@@ -1094,11 +1291,15 @@ function optional(combinator) {
|
|
|
1094
1291
|
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1095
1292
|
isTrivia: false
|
|
1096
1293
|
};
|
|
1294
|
+
const firstSetSkippable = !matchesEmpty(combinator);
|
|
1097
1295
|
return {
|
|
1098
1296
|
_tag: "optional",
|
|
1099
1297
|
_meta: meta,
|
|
1100
1298
|
_def: { tag: "optional", parser: combinator },
|
|
1101
1299
|
parse(input, pos, ctx) {
|
|
1300
|
+
if (firstSetSkippable && ctx._probe === void 0 && !startsFirstSet(combinator, input, pos)) {
|
|
1301
|
+
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1302
|
+
}
|
|
1102
1303
|
const mark = saveTriviaMark(ctx);
|
|
1103
1304
|
const result = combinator.parse(input, pos, ctx);
|
|
1104
1305
|
if (result.ok) return result;
|
|
@@ -1107,6 +1308,15 @@ function optional(combinator) {
|
|
|
1107
1308
|
}
|
|
1108
1309
|
};
|
|
1109
1310
|
}
|
|
1311
|
+
function startsFirstSet(combinator, input, pos) {
|
|
1312
|
+
const fs = combinator._meta.firstSet;
|
|
1313
|
+
if (fs.kind === "any") return true;
|
|
1314
|
+
if (fs.kind === "empty") return false;
|
|
1315
|
+
const code = input.codePointAt(pos);
|
|
1316
|
+
if (code === void 0) return false;
|
|
1317
|
+
for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
1318
|
+
return false;
|
|
1319
|
+
}
|
|
1110
1320
|
function sepBy(combinator, separator) {
|
|
1111
1321
|
const meta = {
|
|
1112
1322
|
firstSet: combinator._meta.firstSet,
|
|
@@ -1414,7 +1624,7 @@ function transform(combinator, fn) {
|
|
|
1414
1624
|
parse(input, pos, ctx) {
|
|
1415
1625
|
const result = combinator.parse(input, pos, ctx);
|
|
1416
1626
|
if (!result.ok) return result;
|
|
1417
|
-
return {
|
|
1627
|
+
return { ok: true, value: fn(result.value, result.span), span: result.span };
|
|
1418
1628
|
}
|
|
1419
1629
|
};
|
|
1420
1630
|
}
|
|
@@ -1428,7 +1638,7 @@ function skip(main, skipped) {
|
|
|
1428
1638
|
if (!result.ok) return result;
|
|
1429
1639
|
const s = skipped.parse(input, result.span.end, ctx);
|
|
1430
1640
|
if (!s.ok) return result;
|
|
1431
|
-
return {
|
|
1641
|
+
return { ok: true, value: result.value, span: { start: result.span.start, end: s.span.end } };
|
|
1432
1642
|
}
|
|
1433
1643
|
};
|
|
1434
1644
|
}
|
|
@@ -1450,7 +1660,11 @@ function label(name, combinator) {
|
|
|
1450
1660
|
_tag: combinator._tag,
|
|
1451
1661
|
_meta: combinator._meta,
|
|
1452
1662
|
_def: { tag: "label", label: name, parser: combinator },
|
|
1453
|
-
parse
|
|
1663
|
+
parse(input, pos, ctx) {
|
|
1664
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1665
|
+
if (!result.ok) return { ok: false, expected: [name], span: result.span };
|
|
1666
|
+
return result;
|
|
1667
|
+
}
|
|
1454
1668
|
};
|
|
1455
1669
|
}
|
|
1456
1670
|
|
|
@@ -1662,9 +1876,9 @@ function expect(combinator, label2) {
|
|
|
1662
1876
|
|
|
1663
1877
|
// src/compiler/scannable-run.ts
|
|
1664
1878
|
var BACKSLASH = 92;
|
|
1665
|
-
var
|
|
1879
|
+
var CLASS_ESCAPES2 = { t: 9, n: 10, r: 13, f: 12, v: 11, "0": 0 };
|
|
1666
1880
|
var META = new Set("()[]{}*+?|^$.".split(""));
|
|
1667
|
-
var
|
|
1881
|
+
var SPACE_RANGES2 = [
|
|
1668
1882
|
[9, 13],
|
|
1669
1883
|
[32, 32],
|
|
1670
1884
|
[160, 160],
|
|
@@ -1677,9 +1891,9 @@ var SPACE_RANGES = [
|
|
|
1677
1891
|
[12288, 12288],
|
|
1678
1892
|
[65279, 65279]
|
|
1679
1893
|
];
|
|
1680
|
-
function
|
|
1894
|
+
function shorthandRanges2(ch) {
|
|
1681
1895
|
if (ch === "d") return [[48, 57]];
|
|
1682
|
-
if (ch === "s") return
|
|
1896
|
+
if (ch === "s") return SPACE_RANGES2;
|
|
1683
1897
|
return [[48, 57], [65, 90], [97, 122], [95, 95]];
|
|
1684
1898
|
}
|
|
1685
1899
|
function readUnicodeEscape(body, i) {
|
|
@@ -1703,8 +1917,8 @@ function parseClassRanges(body) {
|
|
|
1703
1917
|
const e = body[i + 1];
|
|
1704
1918
|
if (e === void 0) return null;
|
|
1705
1919
|
i += 2;
|
|
1706
|
-
if (e in
|
|
1707
|
-
if (e === "d" || e === "w" || e === "s") return { set:
|
|
1920
|
+
if (e in CLASS_ESCAPES2) return { cp: CLASS_ESCAPES2[e] };
|
|
1921
|
+
if (e === "d" || e === "w" || e === "s") return { set: shorthandRanges2(e) };
|
|
1708
1922
|
if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
1709
1923
|
return { cp: e.codePointAt(0) };
|
|
1710
1924
|
}
|
|
@@ -1730,9 +1944,9 @@ function parseClassRanges(body) {
|
|
|
1730
1944
|
return ranges.length ? ranges : null;
|
|
1731
1945
|
}
|
|
1732
1946
|
function classToRanges(cls) {
|
|
1733
|
-
if (cls === "\\d") return
|
|
1734
|
-
if (cls === "\\w") return
|
|
1735
|
-
if (cls === "\\s") return
|
|
1947
|
+
if (cls === "\\d") return shorthandRanges2("d");
|
|
1948
|
+
if (cls === "\\w") return shorthandRanges2("w");
|
|
1949
|
+
if (cls === "\\s") return shorthandRanges2("s");
|
|
1736
1950
|
const body = cls.slice(1, -1);
|
|
1737
1951
|
if (body.startsWith("^")) return null;
|
|
1738
1952
|
return parseClassRanges(body);
|
|
@@ -1750,7 +1964,7 @@ function literalCodePoints(frag) {
|
|
|
1750
1964
|
if (ch === "\\") {
|
|
1751
1965
|
const e = frag[i + 1];
|
|
1752
1966
|
if (e === void 0) return null;
|
|
1753
|
-
out.push(e in
|
|
1967
|
+
out.push(e in CLASS_ESCAPES2 ? CLASS_ESCAPES2[e] : e.codePointAt(0));
|
|
1754
1968
|
i += 2;
|
|
1755
1969
|
continue;
|
|
1756
1970
|
}
|
|
@@ -1843,7 +2057,7 @@ function parseSeqParts(source) {
|
|
|
1843
2057
|
if (e === "d" || e === "w" || e === "s") {
|
|
1844
2058
|
flush();
|
|
1845
2059
|
i += 2;
|
|
1846
|
-
i += runFrom(
|
|
2060
|
+
i += runFrom(shorthandRanges2(e), false, source[i]);
|
|
1847
2061
|
continue;
|
|
1848
2062
|
}
|
|
1849
2063
|
const uni = readUnicodeEscape(source, i);
|
|
@@ -1852,8 +2066,8 @@ function parseSeqParts(source) {
|
|
|
1852
2066
|
cp2 = uni.cp;
|
|
1853
2067
|
i = uni.next;
|
|
1854
2068
|
} else if (e === void 0) return null;
|
|
1855
|
-
else if (e in
|
|
1856
|
-
cp2 =
|
|
2069
|
+
else if (e in CLASS_ESCAPES2) {
|
|
2070
|
+
cp2 = CLASS_ESCAPES2[e];
|
|
1857
2071
|
i += 2;
|
|
1858
2072
|
} else if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
1859
2073
|
else {
|
|
@@ -1960,7 +2174,7 @@ function rangesSubset(sub, sup) {
|
|
|
1960
2174
|
}
|
|
1961
2175
|
function parseClassOperand(body) {
|
|
1962
2176
|
if (body === "\\d" || body === "\\w" || body === "\\s") {
|
|
1963
|
-
return { ranges:
|
|
2177
|
+
return { ranges: shorthandRanges2(body[1]), negated: false };
|
|
1964
2178
|
}
|
|
1965
2179
|
if (body.length >= 2 && body[0] === "[" && body[body.length - 1] === "]") {
|
|
1966
2180
|
let inner = body.slice(1, -1);
|
|
@@ -2393,7 +2607,7 @@ function parseScanShapeCore(source) {
|
|
|
2393
2607
|
}
|
|
2394
2608
|
m = /^\\([dws])([+*])$/.exec(source);
|
|
2395
2609
|
if (m) {
|
|
2396
|
-
return { kind: "chars", ranges:
|
|
2610
|
+
return { kind: "chars", ranges: shorthandRanges2(m[1]), minOne: m[2] === "+" };
|
|
2397
2611
|
}
|
|
2398
2612
|
m = /^(\[(?:\\.|[^\]])+\]|\\[dws])(\[(?:\\.|[^\]])+\]|\\[dws])\*$/.exec(source);
|
|
2399
2613
|
if (m) {
|
|
@@ -4508,8 +4722,17 @@ function emitDispatch(p, ctx, pos) {
|
|
|
4508
4722
|
return emit(def.parser, ctx, pos);
|
|
4509
4723
|
case "token":
|
|
4510
4724
|
return emitToken(def, ctx, pos);
|
|
4511
|
-
case "label":
|
|
4512
|
-
|
|
4725
|
+
case "label": {
|
|
4726
|
+
const inner = emitFallible(def.parser, ctx, pos);
|
|
4727
|
+
return {
|
|
4728
|
+
stmts: [
|
|
4729
|
+
...inner.stmts,
|
|
4730
|
+
...emitIfFail(ctx, `!${inner.okVar}`, failBody(ctx, JSON.stringify(def.label), "_ctx._fe"))
|
|
4731
|
+
],
|
|
4732
|
+
valueVar: inner.valVar,
|
|
4733
|
+
endVar: inner.endVar
|
|
4734
|
+
};
|
|
4735
|
+
}
|
|
4513
4736
|
case "grammar": {
|
|
4514
4737
|
const savedTrivia = ctx.activeTrivia;
|
|
4515
4738
|
const savedKindLabels = ctx.triviaKindLabels;
|