parseman 0.58.1 → 0.58.3
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/analysis/diagnostics.js +203 -37
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +212 -43
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +28 -4
- package/dist/compiler/token-capability.js.map +2 -2
- package/dist/compiler/token-scanner.d.ts.map +1 -1
- package/dist/index.js +207 -41
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +10 -3
- package/dist/language-service/index.js.map +2 -2
- package/dist/lead-ranges.d.ts +26 -0
- package/dist/lead-ranges.d.ts.map +1 -0
- package/dist/plugin/index.js +207 -41
- package/dist/plugin/index.js.map +3 -3
- package/dist/recovery/scan.d.ts.map +1 -1
- package/dist/regex/classes.d.ts +5 -3
- package/dist/regex/classes.d.ts.map +1 -1
- package/dist/regex/first-set.d.ts +7 -1
- package/dist/regex/first-set.d.ts.map +1 -1
- package/dist/run/index.js +10 -3
- package/dist/run/index.js.map +2 -2
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +8 -1
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/encode-baseline.d.ts.map +1 -1
- package/dist/table/index.js +206 -40
- package/dist/table/index.js.map +3 -3
- package/dist/table/program.d.ts.map +1 -1
- package/dist/table/scan-shapes.d.ts +1 -1
- package/dist/table/scan-shapes.d.ts.map +1 -1
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/table/trivia-gap.d.ts +11 -1
- package/dist/table/trivia-gap.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +2 -1
- package/src/cli/index.ts +18 -6
- package/src/combinators/choice.ts +4 -0
- package/src/combinators/first-set.ts +13 -4
- package/src/combinators/regex.ts +28 -9
- package/src/compiler/token-scanner.ts +4 -1
- package/src/lead-ranges.ts +53 -0
- package/src/recovery/scan.ts +2 -3
- package/src/regex/classes.ts +22 -7
- package/src/regex/first-set.ts +67 -12
- package/src/table/assemble.ts +42 -3
- package/src/table/compile-rule-map.ts +5 -3
- package/src/table/emit-assembly.ts +42 -8
- package/src/table/encode-baseline.ts +2 -1
- package/src/table/program.ts +2 -1
- package/src/table/scan-shapes.ts +5 -2
- package/src/table/site-labels.ts +2 -1
- package/src/table/trivia-gap.ts +19 -0
- package/src/version.ts +1 -1
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
// src/lead-ranges.ts
|
|
2
|
+
function rangesHaveLead(ranges, code) {
|
|
3
|
+
for (const r of ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
4
|
+
if (code <= 65535) return false;
|
|
5
|
+
const high = 55296 + (code - 65536 >> 10);
|
|
6
|
+
for (const r of ranges) if (high >= r.lo && high <= r.hi) return true;
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
function leadRanges(ranges) {
|
|
10
|
+
let out;
|
|
11
|
+
for (const r of ranges) {
|
|
12
|
+
const lo = Math.max(r.lo, 55296), hi = Math.min(r.hi, 56319);
|
|
13
|
+
if (lo <= hi) (out ??= [...ranges]).push({ lo: 65536 + (lo - 55296 << 10), hi: 65536 + (hi - 55296 << 10) + 1023 });
|
|
14
|
+
}
|
|
15
|
+
return out ?? ranges;
|
|
16
|
+
}
|
|
17
|
+
function implicitLeadsDropped(ranges) {
|
|
18
|
+
const implied = leadRanges(ranges.filter((r) => r.lo <= 65535)).filter((r) => r.lo > 65535);
|
|
19
|
+
const out = [];
|
|
20
|
+
for (const r of ranges) {
|
|
21
|
+
let pieces = [{ lo: r.lo, hi: r.hi }];
|
|
22
|
+
if (r.hi > 65535) for (const c of implied) {
|
|
23
|
+
pieces = pieces.flatMap((q2) => q2.hi < c.lo || q2.lo > c.hi ? [q2] : [...q2.lo < c.lo ? [{ lo: q2.lo, hi: c.lo - 1 }] : [], ...q2.hi > c.hi ? [{ lo: c.hi + 1, hi: q2.hi }] : []]);
|
|
24
|
+
}
|
|
25
|
+
out.push(...pieces);
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
|
|
1
30
|
// src/combinators/first-set.ts
|
|
2
31
|
function classifyFinalChoice(arms, resolve, activeTrivia) {
|
|
3
32
|
const firstSets = [];
|
|
@@ -59,8 +88,9 @@ function union(a, b) {
|
|
|
59
88
|
function intersects(a, b) {
|
|
60
89
|
if (a.kind === "any" || b.kind === "any") return true;
|
|
61
90
|
if (a.kind === "empty" || b.kind === "empty") return false;
|
|
62
|
-
|
|
63
|
-
|
|
91
|
+
const bs = leadRanges(b.ranges);
|
|
92
|
+
for (const ra of leadRanges(a.ranges)) {
|
|
93
|
+
for (const rb of bs) {
|
|
64
94
|
if (ra.lo <= rb.hi && rb.lo <= ra.hi) return true;
|
|
65
95
|
}
|
|
66
96
|
}
|
|
@@ -76,6 +106,9 @@ function startsFirstSet(combinator, input, pos) {
|
|
|
76
106
|
const code = input.codePointAt(pos);
|
|
77
107
|
if (code === void 0) return false;
|
|
78
108
|
for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
109
|
+
if (code <= 65535) return false;
|
|
110
|
+
const high = 55296 + (code - 65536 >> 10);
|
|
111
|
+
for (const r of fs.ranges) if (high >= r.lo && high <= r.hi) return true;
|
|
79
112
|
return false;
|
|
80
113
|
}
|
|
81
114
|
function fromRange(lo, hi) {
|
|
@@ -176,12 +209,13 @@ function narrowBy(acc, constraint) {
|
|
|
176
209
|
if (acc.kind === "any") return constraint;
|
|
177
210
|
if (acc.kind === "empty" || constraint.kind === "empty") return { kind: "empty" };
|
|
178
211
|
const ranges = [];
|
|
179
|
-
|
|
212
|
+
const bs = leadRanges(constraint.ranges);
|
|
213
|
+
for (const a of leadRanges(acc.ranges)) for (const b of bs) {
|
|
180
214
|
const lo = Math.max(a.lo, b.lo);
|
|
181
215
|
const hi = Math.min(a.hi, b.hi);
|
|
182
216
|
if (lo <= hi) ranges.push({ lo, hi });
|
|
183
217
|
}
|
|
184
|
-
return ranges.length === 0 ? { kind: "empty" } : { kind: "ranges", ranges };
|
|
218
|
+
return ranges.length === 0 ? { kind: "empty" } : { kind: "ranges", ranges: implicitLeadsDropped(ranges) };
|
|
185
219
|
}
|
|
186
220
|
function applyAssertion(fs, assertion) {
|
|
187
221
|
return assertion === null ? fs : fs.kind === "empty" ? assertion : narrowBy(fs, assertion);
|
|
@@ -717,11 +751,17 @@ function shorthandRanges(ch2) {
|
|
|
717
751
|
if (ch2 === "s") return SPACE_RANGES;
|
|
718
752
|
return [[48, 57], [65, 90], [97, 122], [95, 95]];
|
|
719
753
|
}
|
|
720
|
-
function readUnicodeEscape(body, i) {
|
|
754
|
+
function readUnicodeEscape(body, i, unicode = false) {
|
|
721
755
|
if (body[i] !== "\\" || body[i + 1] !== "u") return null;
|
|
722
756
|
const hex = body.slice(i + 2, i + 6);
|
|
723
757
|
if (!/^[0-9a-fA-F]{4}$/.test(hex)) return null;
|
|
724
|
-
|
|
758
|
+
const cp = Number.parseInt(hex, 16);
|
|
759
|
+
if (unicode && cp >= 55296 && cp <= 56319 && body[i + 6] === "\\" && body[i + 7] === "u") {
|
|
760
|
+
const lowHex = body.slice(i + 8, i + 12);
|
|
761
|
+
const low = /^[0-9a-fA-F]{4}$/.test(lowHex) ? Number.parseInt(lowHex, 16) : -1;
|
|
762
|
+
if (low >= 56320 && low <= 57343) return { cp: 65536 + (cp - 55296 << 10) + (low - 56320), next: i + 12 };
|
|
763
|
+
}
|
|
764
|
+
return { cp, next: i + 6 };
|
|
725
765
|
}
|
|
726
766
|
var META = new Set("()[]{}*+?|^$.".split(""));
|
|
727
767
|
function literalCodePoints(frag) {
|
|
@@ -733,6 +773,7 @@ function literalCodePoints(frag) {
|
|
|
733
773
|
const e = frag[i + 1];
|
|
734
774
|
if (e === void 0) return null;
|
|
735
775
|
if (!(e in CLASS_ESCAPES) && /\w/.test(e)) return null;
|
|
776
|
+
if (e === "0" && frag[i + 2] !== void 0 && frag[i + 2] >= "0" && frag[i + 2] <= "9") return null;
|
|
736
777
|
out.push(e in CLASS_ESCAPES ? CLASS_ESCAPES[e] : e.codePointAt(0));
|
|
737
778
|
i += 2;
|
|
738
779
|
continue;
|
|
@@ -773,14 +814,14 @@ function parseClassOperand(body) {
|
|
|
773
814
|
if (cps && cps.length === 1) return { ranges: [[cps[0], cps[0]]], negated: false };
|
|
774
815
|
return null;
|
|
775
816
|
}
|
|
776
|
-
function parseClassRanges(body) {
|
|
817
|
+
function parseClassRanges(body, unicode = false) {
|
|
777
818
|
const ranges = [];
|
|
778
819
|
let i = 0;
|
|
779
820
|
const readAtom = () => {
|
|
780
821
|
const ch2 = body[i];
|
|
781
822
|
if (ch2 === void 0) return null;
|
|
782
823
|
if (ch2 === "\\") {
|
|
783
|
-
const uni = readUnicodeEscape(body, i);
|
|
824
|
+
const uni = readUnicodeEscape(body, i, unicode);
|
|
784
825
|
if (uni) {
|
|
785
826
|
i = uni.next;
|
|
786
827
|
return { cp: uni.cp };
|
|
@@ -788,13 +829,15 @@ function parseClassRanges(body) {
|
|
|
788
829
|
const e = body[i + 1];
|
|
789
830
|
if (e === void 0) return null;
|
|
790
831
|
i += 2;
|
|
832
|
+
if (e === "0" && body[i] !== void 0 && body[i] >= "0" && body[i] <= "9" || e >= "1" && e <= "9") return null;
|
|
791
833
|
if (e in CLASS_ESCAPES) return { cp: CLASS_ESCAPES[e] };
|
|
792
834
|
if (e === "d" || e === "w" || e === "s") return { set: shorthandRanges(e) };
|
|
793
835
|
if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
794
836
|
return { cp: e.codePointAt(0) };
|
|
795
837
|
}
|
|
796
|
-
i
|
|
797
|
-
|
|
838
|
+
const cp = unicode ? body.codePointAt(i) : body.charCodeAt(i);
|
|
839
|
+
i += cp > 65535 ? 2 : 1;
|
|
840
|
+
return { cp };
|
|
798
841
|
};
|
|
799
842
|
while (i < body.length) {
|
|
800
843
|
const lo = readAtom();
|
|
@@ -2475,9 +2518,7 @@ function firstSetSentinel(fs) {
|
|
|
2475
2518
|
parse(input, pos) {
|
|
2476
2519
|
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
2477
2520
|
if (code !== void 0) {
|
|
2478
|
-
|
|
2479
|
-
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
2480
|
-
}
|
|
2521
|
+
if (rangesHaveLead(ranges, code)) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
2481
2522
|
}
|
|
2482
2523
|
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
2483
2524
|
}
|
|
@@ -2915,6 +2956,9 @@ function inFirstSet(code, fs) {
|
|
|
2915
2956
|
if (fs.kind === "any") return true;
|
|
2916
2957
|
if (fs.kind === "empty") return false;
|
|
2917
2958
|
for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
2959
|
+
if (code <= 65535) return false;
|
|
2960
|
+
const high = 55296 + (code - 65536 >> 10);
|
|
2961
|
+
for (const r of fs.ranges) if (high >= r.lo && high <= r.hi) return true;
|
|
2918
2962
|
return false;
|
|
2919
2963
|
}
|
|
2920
2964
|
function areDisjoint(sets) {
|
|
@@ -3479,7 +3523,7 @@ function rangesHaveNewline(ranges) {
|
|
|
3479
3523
|
return ranges.some(([lo, hi]) => lo <= 10 && 10 <= hi);
|
|
3480
3524
|
}
|
|
3481
3525
|
var BAIL = /* @__PURE__ */ Symbol("regex-bail");
|
|
3482
|
-
function parseRegex(src) {
|
|
3526
|
+
function parseRegex(src, unicode = false, sets = false) {
|
|
3483
3527
|
let i = 0;
|
|
3484
3528
|
const parseAlt = () => {
|
|
3485
3529
|
const arms = [parseSeq()];
|
|
@@ -3549,9 +3593,11 @@ function parseRegex(src) {
|
|
|
3549
3593
|
i++;
|
|
3550
3594
|
return charNode(fromRange(123, 123), false);
|
|
3551
3595
|
// a `{` with nothing to quantify is a literal brace
|
|
3552
|
-
default:
|
|
3553
|
-
i
|
|
3554
|
-
|
|
3596
|
+
default: {
|
|
3597
|
+
const cp = unicode ? src.codePointAt(i) : src.charCodeAt(i);
|
|
3598
|
+
i += cp > 65535 ? 2 : 1;
|
|
3599
|
+
return charNode(fromRange(cp, cp), ch2 === "\n");
|
|
3600
|
+
}
|
|
3555
3601
|
}
|
|
3556
3602
|
};
|
|
3557
3603
|
const parseGroup = () => {
|
|
@@ -3584,6 +3630,32 @@ function parseRegex(src) {
|
|
|
3584
3630
|
let k = i + 1;
|
|
3585
3631
|
const negated = src[k] === "^";
|
|
3586
3632
|
if (negated) k++;
|
|
3633
|
+
if (sets) {
|
|
3634
|
+
let depth = 1;
|
|
3635
|
+
let nested = false;
|
|
3636
|
+
while (k < src.length && depth > 0) {
|
|
3637
|
+
const c = src[k];
|
|
3638
|
+
if (c === "\\") {
|
|
3639
|
+
if (src[k + 1] === "q") nested = true;
|
|
3640
|
+
k += 2;
|
|
3641
|
+
continue;
|
|
3642
|
+
}
|
|
3643
|
+
if (c === "[") {
|
|
3644
|
+
depth++;
|
|
3645
|
+
nested = true;
|
|
3646
|
+
} else if (c === "]") {
|
|
3647
|
+
depth--;
|
|
3648
|
+
if (depth === 0) break;
|
|
3649
|
+
} else if ((c === "-" || c === "&") && src[k + 1] === c) nested = true;
|
|
3650
|
+
k++;
|
|
3651
|
+
}
|
|
3652
|
+
if (src[k] !== "]") throw BAIL;
|
|
3653
|
+
if (nested) {
|
|
3654
|
+
i = k + 1;
|
|
3655
|
+
return charNode(any(), true);
|
|
3656
|
+
}
|
|
3657
|
+
k = i + 1 + (negated ? 1 : 0);
|
|
3658
|
+
}
|
|
3587
3659
|
let body = "";
|
|
3588
3660
|
while (k < src.length && src[k] !== "]") {
|
|
3589
3661
|
if (src[k] === "\\") {
|
|
@@ -3596,7 +3668,7 @@ function parseRegex(src) {
|
|
|
3596
3668
|
}
|
|
3597
3669
|
if (src[k] !== "]") throw BAIL;
|
|
3598
3670
|
i = k + 1;
|
|
3599
|
-
const ranges = parseClassRanges(body);
|
|
3671
|
+
const ranges = parseClassRanges(body, unicode);
|
|
3600
3672
|
if (negated) return charNode(any(), !ranges || !rangesHaveNewline(ranges));
|
|
3601
3673
|
if (!ranges) return charNode(any(), true);
|
|
3602
3674
|
return charNode(rangesToSet(ranges), rangesHaveNewline(ranges));
|
|
@@ -3604,9 +3676,20 @@ function parseRegex(src) {
|
|
|
3604
3676
|
const parseEscape = () => {
|
|
3605
3677
|
const e = src[i + 1];
|
|
3606
3678
|
if (e === void 0) throw BAIL;
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
i
|
|
3679
|
+
const uni = readUnicodeEscape(src, i, unicode);
|
|
3680
|
+
if (uni !== null) {
|
|
3681
|
+
i = uni.next;
|
|
3682
|
+
return charNode(fromRange(uni.cp, uni.cp), uni.cp === 10);
|
|
3683
|
+
}
|
|
3684
|
+
if (e === "u" && src[i + 2] === "{") {
|
|
3685
|
+
const close = src.indexOf("}", i + 3);
|
|
3686
|
+
const hex = close < 0 ? "" : src.slice(i + 3, close);
|
|
3687
|
+
if (!unicode || !/^[0-9a-fA-F]{1,6}$/.test(hex)) {
|
|
3688
|
+
i += 2;
|
|
3689
|
+
return ANY;
|
|
3690
|
+
}
|
|
3691
|
+
const cp = Number.parseInt(hex, 16);
|
|
3692
|
+
i = close + 1;
|
|
3610
3693
|
return charNode(fromRange(cp, cp), cp === 10);
|
|
3611
3694
|
}
|
|
3612
3695
|
if (e === "x" && /^[0-9a-fA-F]{2}$/.test(src.slice(i + 2, i + 4))) {
|
|
@@ -3614,6 +3697,16 @@ function parseRegex(src) {
|
|
|
3614
3697
|
i += 4;
|
|
3615
3698
|
return charNode(fromRange(cp, cp), cp === 10);
|
|
3616
3699
|
}
|
|
3700
|
+
if (e === "c") {
|
|
3701
|
+
const x = src[i + 2];
|
|
3702
|
+
if (x !== void 0 && /^[A-Za-z]$/.test(x)) {
|
|
3703
|
+
const cp = x.charCodeAt(0) % 32;
|
|
3704
|
+
i += 3;
|
|
3705
|
+
return charNode(fromRange(cp, cp), cp === 10);
|
|
3706
|
+
}
|
|
3707
|
+
i += 2;
|
|
3708
|
+
return ANY;
|
|
3709
|
+
}
|
|
3617
3710
|
i += 2;
|
|
3618
3711
|
switch (e) {
|
|
3619
3712
|
case "d":
|
|
@@ -3641,8 +3734,16 @@ function parseRegex(src) {
|
|
|
3641
3734
|
return charNode(fromRange(12, 12), false);
|
|
3642
3735
|
case "v":
|
|
3643
3736
|
return charNode(fromRange(11, 11), false);
|
|
3737
|
+
// `\0` then a digit is a legacy octal escape (`\012` is a newline), not NUL.
|
|
3644
3738
|
case "0":
|
|
3645
|
-
return charNode(fromRange(0, 0), false);
|
|
3739
|
+
return src[i] !== void 0 && src[i] >= "0" && src[i] <= "9" ? ANY : charNode(fromRange(0, 0), false);
|
|
3740
|
+
// A property escape (`\p{…}`/`\P{…}`) matches one character of a class this
|
|
3741
|
+
// analyzer does not enumerate; `\k<name>` is a backreference, which may match empty.
|
|
3742
|
+
case "p":
|
|
3743
|
+
case "P":
|
|
3744
|
+
return charNode(any(), true);
|
|
3745
|
+
case "k":
|
|
3746
|
+
return ANY;
|
|
3646
3747
|
default:
|
|
3647
3748
|
if (e >= "1" && e <= "9") return ANY;
|
|
3648
3749
|
return charNode(fromRange(e.codePointAt(0), e.codePointAt(0)), e === "\n");
|
|
@@ -3716,10 +3817,10 @@ function regexCanMatchEmpty(source) {
|
|
|
3716
3817
|
return true;
|
|
3717
3818
|
}
|
|
3718
3819
|
}
|
|
3719
|
-
function firstSetFromRegex(source) {
|
|
3820
|
+
function firstSetFromRegex(source, flags = "") {
|
|
3720
3821
|
let ast;
|
|
3721
3822
|
try {
|
|
3722
|
-
ast = parseRegex(source);
|
|
3823
|
+
ast = parseRegex(source, flags.includes("u") || flags.includes("v"), flags.includes("v"));
|
|
3723
3824
|
} catch {
|
|
3724
3825
|
return { firstSet: any(), canMatchNewline: true };
|
|
3725
3826
|
}
|
|
@@ -3768,8 +3869,18 @@ function shortScanner(source, flags) {
|
|
|
3768
3869
|
return minOne && end === pos ? null : end;
|
|
3769
3870
|
};
|
|
3770
3871
|
}
|
|
3872
|
+
function coversNonAscii(ranges) {
|
|
3873
|
+
let next = 128;
|
|
3874
|
+
for (const r of [...ranges].sort((a, b) => a.lo - b.lo)) {
|
|
3875
|
+
if (r.lo > next) return false;
|
|
3876
|
+
if (r.hi >= next) next = r.hi + 1;
|
|
3877
|
+
if (next > 65535) return true;
|
|
3878
|
+
}
|
|
3879
|
+
return false;
|
|
3880
|
+
}
|
|
3771
3881
|
function asciiCaseFold(fs) {
|
|
3772
3882
|
if (fs.kind !== "ranges") return fs;
|
|
3883
|
+
if (fs.ranges.some((r) => r.hi >= 128) && !coversNonAscii(fs.ranges)) return any();
|
|
3773
3884
|
const ranges = fs.ranges.map((r) => ({ lo: r.lo, hi: r.hi }));
|
|
3774
3885
|
const add = (lo, hi) => {
|
|
3775
3886
|
if (lo <= hi) ranges.push({ lo, hi });
|
|
@@ -3794,7 +3905,7 @@ function regex(pattern, flags = "") {
|
|
|
3794
3905
|
const resolvedFlags = typeof pattern === "string" ? flags : pattern.flags;
|
|
3795
3906
|
const anchored = new RegExp(source, "y" + resolvedFlags.replace(/[gy]/g, ""));
|
|
3796
3907
|
const scan = shortScanner(source, resolvedFlags);
|
|
3797
|
-
const raw = firstSetFromRegex(source);
|
|
3908
|
+
const raw = firstSetFromRegex(source, resolvedFlags);
|
|
3798
3909
|
const firstSet2 = !resolvedFlags.includes("i") ? raw.firstSet : resolvedFlags.includes("u") || resolvedFlags.includes("v") ? any() : asciiCaseFold(raw.firstSet);
|
|
3799
3910
|
const canMatchNewline = raw.canMatchNewline;
|
|
3800
3911
|
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
@@ -4576,7 +4687,7 @@ function decodeClassSpec(spec) {
|
|
|
4576
4687
|
function resolveClass(spec) {
|
|
4577
4688
|
const ascii = new Uint8Array(128);
|
|
4578
4689
|
const hi = [];
|
|
4579
|
-
for (const { lo, hi: up } of decodeClassSpec(spec)) {
|
|
4690
|
+
for (const { lo, hi: up } of leadRanges(decodeClassSpec(spec))) {
|
|
4580
4691
|
if (lo < 128) for (let c = lo; c <= Math.min(up, 127); c++) ascii[c] = 1;
|
|
4581
4692
|
if (up >= 128) hi.push(Math.max(lo, 128), up);
|
|
4582
4693
|
}
|
|
@@ -8479,6 +8590,7 @@ function parseSeqParts(source) {
|
|
|
8479
8590
|
cp2 = uni.cp;
|
|
8480
8591
|
i = uni.next;
|
|
8481
8592
|
} else if (e === void 0) return null;
|
|
8593
|
+
else if (e >= "0" && e <= "9" && (e !== "0" || source[i + 2] !== void 0 && source[i + 2] >= "0" && source[i + 2] <= "9")) return null;
|
|
8482
8594
|
else if (e in CLASS_ESCAPES) {
|
|
8483
8595
|
cp2 = CLASS_ESCAPES[e];
|
|
8484
8596
|
i += 2;
|
|
@@ -9028,7 +9140,7 @@ function parseScanShapeCore(source) {
|
|
|
9028
9140
|
return null;
|
|
9029
9141
|
}
|
|
9030
9142
|
function scanShapeFromRegex(source, flags) {
|
|
9031
|
-
if (/[
|
|
9143
|
+
if (/[msuv]/.test(flags)) return null;
|
|
9032
9144
|
if (/i/.test(flags)) return caseFoldShape(source);
|
|
9033
9145
|
return parseScanShape(source);
|
|
9034
9146
|
}
|
|
@@ -9633,7 +9745,7 @@ function triviaLeadRanges(tri, trivia2) {
|
|
|
9633
9745
|
const fs = trivia2[tri]?._meta.firstSet;
|
|
9634
9746
|
if (fs === void 0) return void 0;
|
|
9635
9747
|
if (fs.kind === "empty") return [];
|
|
9636
|
-
return fs.kind === "ranges" && fs.ranges !== void 0 ? fs.ranges : void 0;
|
|
9748
|
+
return fs.kind === "ranges" && fs.ranges !== void 0 ? leadRanges(fs.ranges) : void 0;
|
|
9637
9749
|
}
|
|
9638
9750
|
|
|
9639
9751
|
// src/table/scalar-terminal.ts
|
|
@@ -10163,7 +10275,7 @@ if(ctx._errors!==undefined&&ctx._errors.length!==${t2}er)ctx._errors.length=${t2
|
|
|
10163
10275
|
if (!s.fd && !s.er) return `if(${t2}n)rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,undefined,undefined,${t2}lg,${t2}rt)`;
|
|
10164
10276
|
return `if(${t2}n){rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,${s.fd ? `${t2}fd` : "undefined"},${s.er ? `${t2}er` : "undefined"},${t2}lg,${t2}rt)}`;
|
|
10165
10277
|
}
|
|
10166
|
-
function emitTerm(callee, dst, t2, l, skip) {
|
|
10278
|
+
function emitTerm(callee, dst, t2, l, skip, miss) {
|
|
10167
10279
|
const fast = `const ${t2}v=${callee}(input,cur,ctx)
|
|
10168
10280
|
if(${t2}v===FAIL)return FAIL
|
|
10169
10281
|
${dst}=${t2}v
|
|
@@ -10181,7 +10293,12 @@ if(${t2}v===FAIL)return FAIL
|
|
|
10181
10293
|
${dst}=${t2}v
|
|
10182
10294
|
if(EC.e>${t2}s)cur=EC.e
|
|
10183
10295
|
else{rollbackScannedTriviaAt(ctx,${t2}tl,${t2}stl,${t2}lg,${t2}slg,${t2}rt,${t2}srt)}`;
|
|
10184
|
-
if (l.tri !== TRI_UNKNOWN) return scanned
|
|
10296
|
+
if (l.tri !== TRI_UNKNOWN) return miss === void 0 ? scanned : `const ${t2}c=input.charCodeAt(cur)
|
|
10297
|
+
if(${miss(`${t2}c`)}){
|
|
10298
|
+
${fast}
|
|
10299
|
+
}else{
|
|
10300
|
+
${scanned}
|
|
10301
|
+
}`;
|
|
10185
10302
|
return `if(ctx.trivia===undefined){
|
|
10186
10303
|
${fast}
|
|
10187
10304
|
}else{
|
|
@@ -10237,7 +10354,7 @@ function rebuildPools(cc, fx, disp, plan) {
|
|
|
10237
10354
|
})
|
|
10238
10355
|
};
|
|
10239
10356
|
}
|
|
10240
|
-
function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false, select) {
|
|
10357
|
+
function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false, select, scanSinkNeutral = false) {
|
|
10241
10358
|
const { code, k, fx, disp, dsp, triviaLabelled } = t2;
|
|
10242
10359
|
const swapLegal = !cfg.trackLines;
|
|
10243
10360
|
const hostCst = cfg.hostCst;
|
|
@@ -10313,7 +10430,7 @@ function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false, s
|
|
|
10313
10430
|
const op = code[ip];
|
|
10314
10431
|
sinkBits.set(
|
|
10315
10432
|
ip,
|
|
10316
|
-
op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC && (op === OP_REP || op === OP_REPV) ? 2 : 0)
|
|
10433
|
+
op === OP_SCAN || !scanSinkNeutral && op === OP_LEX_PROGRAM && t2.lexPrograms[code[ip + 1]].scan !== void 0 ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC && (op === OP_REP || op === OP_REPV) ? 2 : 0)
|
|
10317
10434
|
);
|
|
10318
10435
|
}
|
|
10319
10436
|
const sinkKids = [];
|
|
@@ -10486,6 +10603,12 @@ return 1
|
|
|
10486
10603
|
return `if(${gateMissTest(child)}){${miss}}
|
|
10487
10604
|
`;
|
|
10488
10605
|
}
|
|
10606
|
+
function triviaMiss(ki) {
|
|
10607
|
+
const leads = triviaLeadRanges(ki, t2.trivia);
|
|
10608
|
+
if (leads === void 0 || leads.length > 16) return void 0;
|
|
10609
|
+
if (leads.length === 0) return (c) => `${c}<55296`;
|
|
10610
|
+
return (c) => `${c}<55296&&!(${leads.map((r) => r.lo === r.hi ? `${c}===${r.lo}` : `(${c}>=${r.lo}&&${c}<=${r.hi})`).join("||")})`;
|
|
10611
|
+
}
|
|
10489
10612
|
function skipFor(l) {
|
|
10490
10613
|
if (l.tri < 0) return "_skipTrivia";
|
|
10491
10614
|
const ki = l.tri;
|
|
@@ -10496,8 +10619,13 @@ return 1
|
|
|
10496
10619
|
const nm = `_sk${skipPool.size}`;
|
|
10497
10620
|
skipPool.set(key, nm);
|
|
10498
10621
|
if (!hasScan) {
|
|
10499
|
-
|
|
10500
|
-
|
|
10622
|
+
const miss = triviaMiss(ki);
|
|
10623
|
+
const pre = miss === void 0 ? "" : `const c=input.charCodeAt(cur)
|
|
10624
|
+
if(${miss("c")})return cur
|
|
10625
|
+
`;
|
|
10626
|
+
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){${pre === "" ? "" : `
|
|
10627
|
+
${pre}`}return skipDeferredTrivia(input,cur,ctx)}` : `function ${nm}(input,cur,ctx){
|
|
10628
|
+
${pre}if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
|
|
10501
10629
|
return advanceTrivia(input,cur,ctx)}`);
|
|
10502
10630
|
return nm;
|
|
10503
10631
|
}
|
|
@@ -11081,7 +11209,7 @@ return v
|
|
|
11081
11209
|
);
|
|
11082
11210
|
} else {
|
|
11083
11211
|
const callee = leadingTriviaFieldAt(code, k, childIp) ? `(LEAD.at=cur,${kids[i]})` : kids[i];
|
|
11084
|
-
parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
11212
|
+
parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L), L.tri >= 0 ? triviaMiss(L.tri) : void 0));
|
|
11085
11213
|
}
|
|
11086
11214
|
names.push(vn);
|
|
11087
11215
|
}
|
|
@@ -12415,6 +12543,15 @@ function skipDeferredTrivia(input, cur, ctx) {
|
|
|
12415
12543
|
if (plain2) remember(cur, scan, ctx, input, triviaP);
|
|
12416
12544
|
return scan;
|
|
12417
12545
|
}
|
|
12546
|
+
function triviaLeadTable(triviaP) {
|
|
12547
|
+
const fs = triviaP._meta.firstSet;
|
|
12548
|
+
if (fs.kind === "any") return null;
|
|
12549
|
+
const table = new Uint8Array(128);
|
|
12550
|
+
if (fs.kind === "ranges") {
|
|
12551
|
+
for (const r of fs.ranges) for (let c = Math.max(0, r.lo); c <= Math.min(127, r.hi); c++) table[c] = 1;
|
|
12552
|
+
}
|
|
12553
|
+
return table;
|
|
12554
|
+
}
|
|
12418
12555
|
function clearRunEnd(input, cur, ctx, triviaP, plain2) {
|
|
12419
12556
|
const rootKinds = ctx._rootTriviaKindIndex;
|
|
12420
12557
|
const spec = triviaP?._meta.labeledTriviaSpec;
|
|
@@ -13075,7 +13212,23 @@ function assemble(t2, prog, cfg) {
|
|
|
13075
13212
|
}
|
|
13076
13213
|
return out;
|
|
13077
13214
|
}
|
|
13215
|
+
const LEAD_TABLES = trivia2.map((tp) => tp === void 0 ? null : triviaLeadTable(tp));
|
|
13216
|
+
let LEAD_OF;
|
|
13217
|
+
let LEAD_TABLE = null;
|
|
13218
|
+
function cannotStartTrivia(input, cur, triviaP) {
|
|
13219
|
+
if (triviaP !== LEAD_OF) {
|
|
13220
|
+
LEAD_OF = triviaP;
|
|
13221
|
+
const slot = trivia2.indexOf(triviaP);
|
|
13222
|
+
LEAD_TABLE = slot >= 0 ? LEAD_TABLES[slot] : triviaLeadTable(triviaP);
|
|
13223
|
+
}
|
|
13224
|
+
const table = LEAD_TABLE;
|
|
13225
|
+
if (table === null) return false;
|
|
13226
|
+
const c = input.charCodeAt(cur);
|
|
13227
|
+
return c < 128 && table[c] === 0;
|
|
13228
|
+
}
|
|
13078
13229
|
function skipTrivia(input, cur, ctx) {
|
|
13230
|
+
const t3 = ctx.trivia;
|
|
13231
|
+
if (t3 !== void 0 && cannotStartTrivia(input, cur, t3)) return cur;
|
|
13079
13232
|
const s = SCAN;
|
|
13080
13233
|
if (s !== null && ctx._triviaLog === void 0 && !(ctx.captureTrivia === true && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0))) {
|
|
13081
13234
|
return s(input, cur);
|
|
@@ -13090,7 +13243,8 @@ function assemble(t2, prog, cfg) {
|
|
|
13090
13243
|
const frames = [];
|
|
13091
13244
|
let depth = 0;
|
|
13092
13245
|
function nextTerm(child, input, cur, ctx) {
|
|
13093
|
-
|
|
13246
|
+
const t3 = ctx.trivia;
|
|
13247
|
+
if (t3 === void 0 || cannotStartTrivia(input, cur, t3)) {
|
|
13094
13248
|
const v2 = child(input, cur, ctx);
|
|
13095
13249
|
if (v2 === FAIL) return -1;
|
|
13096
13250
|
TERMV = v2;
|
|
@@ -13119,7 +13273,8 @@ function assemble(t2, prog, cfg) {
|
|
|
13119
13273
|
return cur;
|
|
13120
13274
|
}
|
|
13121
13275
|
function nextTermBuffered(child, input, cur, ctx) {
|
|
13122
|
-
|
|
13276
|
+
const t3 = ctx.trivia;
|
|
13277
|
+
if (t3 === void 0 || cannotStartTrivia(input, cur, t3)) {
|
|
13123
13278
|
const v2 = child(input, cur, ctx);
|
|
13124
13279
|
if (v2 === FAIL) return -1;
|
|
13125
13280
|
TERMV = v2;
|
|
@@ -13921,6 +14076,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13921
14076
|
const scopeTrivia = ki < 0 ? void 0 : trivia2[ki];
|
|
13922
14077
|
const scopeLabels = scopeTrivia?._meta.triviaKindLabels;
|
|
13923
14078
|
const scanFor = swapLegal && ki >= 0 && !triviaLabelled[ki] ? triviaScan[ki] : null;
|
|
14079
|
+
const scopeLead = ki < 0 ? null : LEAD_TABLES[ki];
|
|
13924
14080
|
const child = link(code[ip + 2]);
|
|
13925
14081
|
const scopePiece = code[ip] === OP_SCOPE_CAP ? (input, pos, ctx) => {
|
|
13926
14082
|
const saved = ctx.trivia;
|
|
@@ -13928,6 +14084,9 @@ function assemble(t2, prog, cfg) {
|
|
|
13928
14084
|
const savedScan = SCAN;
|
|
13929
14085
|
const savedCap = ctx.captureTrivia;
|
|
13930
14086
|
SCAN = scanFor;
|
|
14087
|
+
const savedLeadOf = LEAD_OF, savedLead = LEAD_TABLE;
|
|
14088
|
+
LEAD_OF = scopeTrivia;
|
|
14089
|
+
LEAD_TABLE = scopeLead;
|
|
13931
14090
|
ctx.trivia = scopeTrivia;
|
|
13932
14091
|
ctx.triviaKindLabels = scopeLabels;
|
|
13933
14092
|
ctx.captureTrivia = true;
|
|
@@ -13936,18 +14095,25 @@ function assemble(t2, prog, cfg) {
|
|
|
13936
14095
|
ctx.trivia = saved;
|
|
13937
14096
|
ctx.triviaKindLabels = savedLabels;
|
|
13938
14097
|
SCAN = savedScan;
|
|
14098
|
+
LEAD_OF = savedLeadOf;
|
|
14099
|
+
LEAD_TABLE = savedLead;
|
|
13939
14100
|
return v;
|
|
13940
14101
|
} : (input, pos, ctx) => {
|
|
13941
14102
|
const saved = ctx.trivia;
|
|
13942
14103
|
const savedLabels = ctx.triviaKindLabels;
|
|
13943
14104
|
const savedScan = SCAN;
|
|
13944
14105
|
SCAN = scanFor;
|
|
14106
|
+
const savedLeadOf = LEAD_OF, savedLead = LEAD_TABLE;
|
|
14107
|
+
LEAD_OF = scopeTrivia;
|
|
14108
|
+
LEAD_TABLE = scopeLead;
|
|
13945
14109
|
ctx.trivia = scopeTrivia;
|
|
13946
14110
|
ctx.triviaKindLabels = scopeLabels;
|
|
13947
14111
|
const v = child(input, pos, ctx);
|
|
13948
14112
|
ctx.trivia = saved;
|
|
13949
14113
|
ctx.triviaKindLabels = savedLabels;
|
|
13950
14114
|
SCAN = savedScan;
|
|
14115
|
+
LEAD_OF = savedLeadOf;
|
|
14116
|
+
LEAD_TABLE = savedLead;
|
|
13951
14117
|
return v;
|
|
13952
14118
|
};
|
|
13953
14119
|
return scopeRootPolicy(scopePiece, code[ip] === OP_SCOPE_PLAIN ? 0 : code[ip + 3]);
|