UNPKG

75.4 kBJavaScriptView Raw
1/*! @author Toru Nagashima <https://github.com/mysticatea> */
2
3
4var ast = /*#__PURE__*/Object.freeze({
5
6});
7
8let largeIdStartRanges = undefined;
9let largeIdContinueRanges = undefined;
10function isIdStart(cp) {
11 if (cp < 0x41)
12 return false;
13 if (cp < 0x5b)
14 return true;
15 if (cp < 0x61)
16 return false;
17 if (cp < 0x7b)
18 return true;
19 return isLargeIdStart(cp);
20}
21function isIdContinue(cp) {
22 if (cp < 0x30)
23 return false;
24 if (cp < 0x3a)
25 return true;
26 if (cp < 0x41)
27 return false;
28 if (cp < 0x5b)
29 return true;
30 if (cp === 0x5f)
31 return true;
32 if (cp < 0x61)
33 return false;
34 if (cp < 0x7b)
35 return true;
36 return isLargeIdStart(cp) || isLargeIdContinue(cp);
37}
38function isLargeIdStart(cp) {
39 return isInRange(cp, largeIdStartRanges || (largeIdStartRanges = initLargeIdStartRanges()));
40}
41function isLargeIdContinue(cp) {
42 return isInRange(cp, largeIdContinueRanges ||
43 (largeIdContinueRanges = initLargeIdContinueRanges()));
44}
45function initLargeIdStartRanges() {
46 return restoreRanges("4q 0 b 0 5 0 6 m 2 u 2 cp 5 b f 4 8 0 2 0 3m 4 2 1 3 3 2 0 7 0 2 2 2 0 2 j 2 2a 2 3u 9 4l 2 11 3 0 7 14 20 q 5 3 1a 16 10 1 2 2q 2 0 g 1 8 1 b 2 3 0 h 0 2 t u 2g c 0 p w a 1 5 0 6 l 5 0 a 0 4 0 o o 8 a 1i k 2 h 1p 1h 4 0 j 0 8 9 g f 5 7 3 1 3 l 2 6 2 0 4 3 4 0 h 0 e 1 2 2 f 1 b 0 9 5 5 1 3 l 2 6 2 1 2 1 2 1 w 3 2 0 k 2 h 8 2 2 2 l 2 6 2 1 2 4 4 0 j 0 g 1 o 0 c 7 3 1 3 l 2 6 2 1 2 4 4 0 v 1 2 2 g 0 i 0 2 5 4 2 2 3 4 1 2 0 2 1 4 1 4 2 4 b n 0 1h 7 2 2 2 m 2 f 4 0 r 2 6 1 v 0 5 7 2 2 2 m 2 9 2 4 4 0 x 0 2 1 g 1 i 8 2 2 2 14 3 0 h 0 6 2 9 2 p 5 6 h 4 n 2 8 2 0 3 6 1n 1b 2 1 d 6 1n 1 2 0 2 4 2 n 2 0 2 9 2 1 a 0 3 4 2 0 m 3 x 0 1s 7 2 z s 4 38 16 l 0 h 5 5 3 4 0 4 1 8 2 5 c d 0 i 11 2 0 6 0 3 16 2 98 2 3 3 6 2 0 2 3 3 14 2 3 3 w 2 3 3 6 2 0 2 3 3 e 2 1k 2 3 3 1u 12 f h 2d 3 5 4 h7 3 g 2 p 6 22 4 a 8 c 2 3 f h f h f c 2 2 g 1f 10 0 5 0 1w 2g 8 14 2 0 6 1x b u 1e t 3 4 c 17 5 p 1j m a 1g 2b 0 2m 1a i 6 1k t e 1 b 17 r z 16 2 b z 3 8 8 16 3 2 16 3 2 5 2 1 4 0 6 5b 1t 7p 3 5 3 11 3 5 3 7 2 0 2 0 2 0 2 u 3 1g 2 6 2 0 4 2 2 6 4 3 3 5 5 c 6 2 2 6 39 0 e 0 h c 2u 0 5 0 3 9 2 0 3 5 7 0 2 0 2 0 2 f 3 3 6 4 5 0 i 14 22g 1a 2 1a 2 3o 7 3 4 1 d 11 2 0 6 0 3 1j 8 0 h m a 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 fb 2 q 8 8 4 3 4 5 2d 5 4 2 2h 2 3 6 16 2 2l i v 1d f e9 533 1t g70 4 wc 1w 19 3 7g 4 f b 1 l 1a h u 3 27 14 8 3 2u 3 1g 3 8 17 c 2 2 2 3 2 m u 1f f 1d 1r 5 4 0 2 1 c r b m q s 8 1a t 0 h 4 2 9 b 4 2 14 o 2 2 7 l m 4 0 4 1d 2 0 4 1 3 4 3 0 2 0 p 2 3 a 8 2 d 5 3 5 3 5 a 6 2 6 2 16 2 d 7 36 u 8mb d m 5 1c 6it a5 3 2x 13 6 d 4 6 0 2 9 2 c 2 4 2 0 2 1 2 1 2 2z y a2 j 1r 3 1h 15 b 39 4 2 3q 11 p 7 p c 2g 4 5 3 5 3 5 3 2 10 b 2 p 2 i 2 1 2 e 3 d z 3e 1y 1g 7g s 4 1c 1c v e t 6 11 b t 3 z 5 7 2 4 17 4d j z 5 z 5 13 9 1f 4d 8m a l b 7 49 5 3 0 2 17 2 1 4 0 3 m b m a u 1u i 2 1 b l b p 1z 1j 7 1 1t 0 g 3 2 2 2 s 17 s 4 s 10 7 2 r s 1h b l b i e h 33 20 1k 1e e 1e e z 9p 15 7 1 27 s b 0 9 l 2z k s m d 1g 24 18 x o r z u 0 3 0 9 y 4 0 d 1b f 3 m 0 2 0 10 h 2 o 2d 6 2 0 2 3 2 e 2 9 8 1a 13 7 3 1 3 l 2 6 2 1 2 4 4 0 j 0 d 4 4f 1g j 3 l 2 v 1b l 1 2 0 55 1a 16 3 11 1b l 0 1o 16 e 0 20 q 6e 17 39 1r w 7 3 0 3 7 2 1 2 n g 0 2 0 2n 7 3 12 h 0 2 0 t 0 b 13 8 0 m 0 c 19 k 0 z 1k 7c 8 2 10 i 0 1e t 35 6 2 1 2 11 m 0 q 5 2 1 2 v f 0 94 i 5a 0 28 pl 2v 32 i 5f 24d tq 34i g6 6nu fs 8 u 36 t j 1b h 3 w k 6 i j5 1r 3l 22 6 0 1v c 1t 1 2 0 t 4qf 9 yd 17 8 6wo 7y 1e 2 i 3 9 az 1s5 2y 6 c 4 8 8 9 4mf 2c 2 1y 2 1 3 0 3 1 3 3 2 b 2 0 2 6 2 1s 2 3 3 7 2 6 2 r 2 3 2 4 2 0 4 6 2 9f 3 o 2 o 2 u 2 o 2 u 2 o 2 u 2 o 2 u 2 o 2 7 1th 18 b 6 h 0 aa 17 105 5g 1o 1v 8 0 xh 3 2 q 2 1 2 0 3 0 2 9 2 3 2 0 2 0 7 0 5 0 2 0 2 0 2 2 2 1 2 0 3 0 2 0 2 0 2 0 2 0 2 1 2 0 3 3 2 6 2 3 2 3 2 0 2 9 2 g 6 2 2 4 2 g 3et wyl z 378 c 65 3 4g1 f 5rk 2e8 f1 15v 3t6");
47}
48function initLargeIdContinueRanges() {
49 return restoreRanges("53 0 g9 33 o 0 70 4 7e 18 2 0 2 1 2 1 2 0 21 a 1d u 7 0 2u 6 3 5 3 1 2 3 3 9 o 0 v q 2k a g 9 y 8 a 0 p 3 2 8 2 2 2 4 18 2 3c e 2 w 1j 2 2 h 2 6 b 1 3 9 i 2 1l 0 2 6 3 1 3 2 a 0 b 1 3 9 f 0 3 2 1l 0 2 4 5 1 3 2 4 0 l b 4 0 c 2 1l 0 2 7 2 2 2 2 l 1 3 9 b 5 2 2 1l 0 2 6 3 1 3 2 8 2 b 1 3 9 j 0 1o 4 4 2 2 3 a 0 f 9 h 4 1m 6 2 2 2 3 8 1 c 1 3 9 i 2 1l 0 2 6 2 2 2 3 8 1 c 1 3 9 h 3 1k 1 2 6 2 2 2 3 a 0 b 1 3 9 i 2 1z 0 5 5 2 0 2 7 7 9 3 1 1q 0 3 6 d 7 2 9 2g 0 3 8 c 5 3 9 1r 1 7 9 c 0 2 0 2 0 5 1 1e j 2 1 6 a 2 z a 0 2t j 2 9 d 3 5 2 2 2 3 6 4 3 e b 2 e jk 2 a 8 pt 2 u 2 u 1 v 1 1t v a 0 3 9 y 2 3 9 40 0 3b b 5 b b 9 3l a 1p 4 1m 9 2 s 3 a 7 9 n d 2 1 1s 4 1c g c 9 i 8 d 2 v c 3 9 19 d 1d j 9 9 7 9 3b 2 2 k 5 0 7 0 3 2 5j 1l 2 4 g0 1 k 0 3g c 5 0 4 b 2db 2 3y 0 2p v ff 5 2y 1 n7q 9 1y 0 5 9 x 1 29 1 7l 0 4 0 5 0 o 4 5 0 2c 1 1f h b 9 7 h e a t 7 q c 19 3 1c d g 9 c 0 b 9 1c d d 0 9 1 3 9 y 2 1f 0 2 2 3 1 6 1 2 0 16 4 6 1 6l 7 2 1 3 9 fmt 0 ki f h f 4 1 p 2 5d 9 12 0 ji 0 6b 0 46 4 86 9 120 2 2 1 6 3 15 2 5 0 4m 1 fy 3 9 9 aa 1 4a a 4w 2 1i e w 9 g 3 1a a 1i 9 7 2 11 d 2 9 6 1 19 0 d 2 1d d 9 3 2 b 2b b 7 0 4h b 6 9 7 3 1k 1 2 6 3 1 3 2 a 0 b 1 3 6 4 4 5d h a 9 5 0 2a j d 9 5y 6 3 8 s 1 2b g g 9 2a c 9 9 2c e 5 9 6r e 4m 9 1z 5 2 1 3 3 2 0 2 1 d 9 3c 6 3 6 4 0 t 9 15 6 2 3 9 0 a a 1b f ba 7 2 7 h 9 1l l 2 d 3f 5 4 0 2 1 2 6 2 0 9 9 1d 4 2 1 2 4 9 9 96 3 ewa 9 3r 4 1o 6 q 9 s6 0 2 1i 8 3 2a 0 c 1 f58 1 43r 4 4 5 9 7 3 6 v 3 45 2 13e 1d e9 1i 5 1d 9 0 f 0 n 4 2 e 11t 6 2 g 3 6 2 1 2 4 7a 6 a 9 bn d 15j 6 32 6 6 9 3o7 9 gvt3 6n");
50}
51function isInRange(cp, ranges) {
52 let l = 0, r = (ranges.length / 2) | 0, i = 0, min = 0, max = 0;
53 while (l < r) {
54 i = ((l + r) / 2) | 0;
55 min = ranges[2 * i];
56 max = ranges[2 * i + 1];
57 if (cp < min) {
58 r = i;
59 }
60 else if (cp > max) {
61 l = i + 1;
62 }
63 else {
64 return true;
65 }
66 }
67 return false;
68}
69function restoreRanges(data) {
70 let last = 0;
71 return data.split(" ").map(s => (last += parseInt(s, 36) | 0));
72}
73
74class DataSet {
75 constructor(raw2018, raw2019, raw2020, raw2021) {
76 this._raw2018 = raw2018;
77 this._raw2019 = raw2019;
78 this._raw2020 = raw2020;
79 this._raw2021 = raw2021;
80 }
81 get es2018() {
82 return (this._set2018 || (this._set2018 = new Set(this._raw2018.split(" "))));
83 }
84 get es2019() {
85 return (this._set2019 || (this._set2019 = new Set(this._raw2019.split(" "))));
86 }
87 get es2020() {
88 return (this._set2020 || (this._set2020 = new Set(this._raw2020.split(" "))));
89 }
90 get es2021() {
91 return (this._set2021 || (this._set2021 = new Set(this._raw2021.split(" "))));
92 }
93}
94const gcNameSet = new Set(["General_Category", "gc"]);
95const scNameSet = new Set(["Script", "Script_Extensions", "sc", "scx"]);
96const gcValueSets = new DataSet("C Cased_Letter Cc Cf Close_Punctuation Cn Co Combining_Mark Connector_Punctuation Control Cs Currency_Symbol Dash_Punctuation Decimal_Number Enclosing_Mark Final_Punctuation Format Initial_Punctuation L LC Letter Letter_Number Line_Separator Ll Lm Lo Lowercase_Letter Lt Lu M Mark Math_Symbol Mc Me Mn Modifier_Letter Modifier_Symbol N Nd Nl No Nonspacing_Mark Number Open_Punctuation Other Other_Letter Other_Number Other_Punctuation Other_Symbol P Paragraph_Separator Pc Pd Pe Pf Pi Po Private_Use Ps Punctuation S Sc Separator Sk Sm So Space_Separator Spacing_Mark Surrogate Symbol Titlecase_Letter Unassigned Uppercase_Letter Z Zl Zp Zs cntrl digit punct", "", "", "");
97const scValueSets = new DataSet("Adlam Adlm Aghb Ahom Anatolian_Hieroglyphs Arab Arabic Armenian Armi Armn Avestan Avst Bali Balinese Bamu Bamum Bass Bassa_Vah Batak Batk Beng Bengali Bhaiksuki Bhks Bopo Bopomofo Brah Brahmi Brai Braille Bugi Buginese Buhd Buhid Cakm Canadian_Aboriginal Cans Cari Carian Caucasian_Albanian Chakma Cham Cher Cherokee Common Copt Coptic Cprt Cuneiform Cypriot Cyrillic Cyrl Deseret Deva Devanagari Dsrt Dupl Duployan Egyp Egyptian_Hieroglyphs Elba Elbasan Ethi Ethiopic Geor Georgian Glag Glagolitic Gonm Goth Gothic Gran Grantha Greek Grek Gujarati Gujr Gurmukhi Guru Han Hang Hangul Hani Hano Hanunoo Hatr Hatran Hebr Hebrew Hira Hiragana Hluw Hmng Hung Imperial_Aramaic Inherited Inscriptional_Pahlavi Inscriptional_Parthian Ital Java Javanese Kaithi Kali Kana Kannada Katakana Kayah_Li Khar Kharoshthi Khmer Khmr Khoj Khojki Khudawadi Knda Kthi Lana Lao Laoo Latin Latn Lepc Lepcha Limb Limbu Lina Linb Linear_A Linear_B Lisu Lyci Lycian Lydi Lydian Mahajani Mahj Malayalam Mand Mandaic Mani Manichaean Marc Marchen Masaram_Gondi Meetei_Mayek Mend Mende_Kikakui Merc Mero Meroitic_Cursive Meroitic_Hieroglyphs Miao Mlym Modi Mong Mongolian Mro Mroo Mtei Mult Multani Myanmar Mymr Nabataean Narb Nbat New_Tai_Lue Newa Nko Nkoo Nshu Nushu Ogam Ogham Ol_Chiki Olck Old_Hungarian Old_Italic Old_North_Arabian Old_Permic Old_Persian Old_South_Arabian Old_Turkic Oriya Orkh Orya Osage Osge Osma Osmanya Pahawh_Hmong Palm Palmyrene Pau_Cin_Hau Pauc Perm Phag Phags_Pa Phli Phlp Phnx Phoenician Plrd Prti Psalter_Pahlavi Qaac Qaai Rejang Rjng Runic Runr Samaritan Samr Sarb Saur Saurashtra Sgnw Sharada Shavian Shaw Shrd Sidd Siddham SignWriting Sind Sinh Sinhala Sora Sora_Sompeng Soyo Soyombo Sund Sundanese Sylo Syloti_Nagri Syrc Syriac Tagalog Tagb Tagbanwa Tai_Le Tai_Tham Tai_Viet Takr Takri Tale Talu Tamil Taml Tang Tangut Tavt Telu Telugu Tfng Tglg Thaa Thaana Thai Tibetan Tibt Tifinagh Tirh Tirhuta Ugar Ugaritic Vai Vaii Wara Warang_Citi Xpeo Xsux Yi Yiii Zanabazar_Square Zanb Zinh Zyyy", "Dogr Dogra Gong Gunjala_Gondi Hanifi_Rohingya Maka Makasar Medefaidrin Medf Old_Sogdian Rohg Sogd Sogdian Sogo", "Elym Elymaic Hmnp Nand Nandinagari Nyiakeng_Puachue_Hmong Wancho Wcho", "Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi");
98const binPropertySets = new DataSet("AHex ASCII ASCII_Hex_Digit Alpha Alphabetic Any Assigned Bidi_C Bidi_Control Bidi_M Bidi_Mirrored CI CWCF CWCM CWKCF CWL CWT CWU Case_Ignorable Cased Changes_When_Casefolded Changes_When_Casemapped Changes_When_Lowercased Changes_When_NFKC_Casefolded Changes_When_Titlecased Changes_When_Uppercased DI Dash Default_Ignorable_Code_Point Dep Deprecated Dia Diacritic Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Ext Extender Gr_Base Gr_Ext Grapheme_Base Grapheme_Extend Hex Hex_Digit IDC IDS IDSB IDST IDS_Binary_Operator IDS_Trinary_Operator ID_Continue ID_Start Ideo Ideographic Join_C Join_Control LOE Logical_Order_Exception Lower Lowercase Math NChar Noncharacter_Code_Point Pat_Syn Pat_WS Pattern_Syntax Pattern_White_Space QMark Quotation_Mark RI Radical Regional_Indicator SD STerm Sentence_Terminal Soft_Dotted Term Terminal_Punctuation UIdeo Unified_Ideograph Upper Uppercase VS Variation_Selector White_Space XIDC XIDS XID_Continue XID_Start space", "Extended_Pictographic", "", "EBase EComp EMod EPres ExtPict");
99function isValidUnicodeProperty(version, name, value) {
100 if (gcNameSet.has(name)) {
101 return version >= 2018 && gcValueSets.es2018.has(value);
102 }
103 if (scNameSet.has(name)) {
104 return ((version >= 2018 && scValueSets.es2018.has(value)) ||
105 (version >= 2019 && scValueSets.es2019.has(value)) ||
106 (version >= 2020 && scValueSets.es2020.has(value)) ||
107 (version >= 2021 && scValueSets.es2021.has(value)));
108 }
109 return false;
110}
111function isValidLoneUnicodeProperty(version, value) {
112 return ((version >= 2018 && binPropertySets.es2018.has(value)) ||
113 (version >= 2019 && binPropertySets.es2019.has(value)) ||
114 (version >= 2021 && binPropertySets.es2021.has(value)));
115}
116
117const Backspace = 0x08;
118const CharacterTabulation = 0x09;
119const LineFeed = 0x0a;
120const LineTabulation = 0x0b;
121const FormFeed = 0x0c;
122const CarriageReturn = 0x0d;
123const ExclamationMark = 0x21;
124const DollarSign = 0x24;
125const LeftParenthesis = 0x28;
126const RightParenthesis = 0x29;
127const Asterisk = 0x2a;
128const PlusSign = 0x2b;
129const Comma = 0x2c;
130const HyphenMinus = 0x2d;
131const FullStop = 0x2e;
132const Solidus = 0x2f;
133const DigitZero = 0x30;
134const DigitOne = 0x31;
135const DigitSeven = 0x37;
136const DigitNine = 0x39;
137const Colon = 0x3a;
138const LessThanSign = 0x3c;
139const EqualsSign = 0x3d;
140const GreaterThanSign = 0x3e;
141const QuestionMark = 0x3f;
142const LatinCapitalLetterA = 0x41;
143const LatinCapitalLetterB = 0x42;
144const LatinCapitalLetterD = 0x44;
145const LatinCapitalLetterF = 0x46;
146const LatinCapitalLetterP = 0x50;
147const LatinCapitalLetterS = 0x53;
148const LatinCapitalLetterW = 0x57;
149const LatinCapitalLetterZ = 0x5a;
150const LowLine = 0x5f;
151const LatinSmallLetterA = 0x61;
152const LatinSmallLetterB = 0x62;
153const LatinSmallLetterC = 0x63;
154const LatinSmallLetterD = 0x64;
155const LatinSmallLetterF = 0x66;
156const LatinSmallLetterG = 0x67;
157const LatinSmallLetterI = 0x69;
158const LatinSmallLetterK = 0x6b;
159const LatinSmallLetterM = 0x6d;
160const LatinSmallLetterN = 0x6e;
161const LatinSmallLetterP = 0x70;
162const LatinSmallLetterR = 0x72;
163const LatinSmallLetterS = 0x73;
164const LatinSmallLetterT = 0x74;
165const LatinSmallLetterU = 0x75;
166const LatinSmallLetterV = 0x76;
167const LatinSmallLetterW = 0x77;
168const LatinSmallLetterX = 0x78;
169const LatinSmallLetterY = 0x79;
170const LatinSmallLetterZ = 0x7a;
171const LeftSquareBracket = 0x5b;
172const ReverseSolidus = 0x5c;
173const RightSquareBracket = 0x5d;
174const CircumflexAccent = 0x5e;
175const LeftCurlyBracket = 0x7b;
176const VerticalLine = 0x7c;
177const RightCurlyBracket = 0x7d;
178const ZeroWidthNonJoiner = 0x200c;
179const ZeroWidthJoiner = 0x200d;
180const LineSeparator = 0x2028;
181const ParagraphSeparator = 0x2029;
182const MinCodePoint = 0x00;
183const MaxCodePoint = 0x10ffff;
184function isLatinLetter(code) {
185 return ((code >= LatinCapitalLetterA && code <= LatinCapitalLetterZ) ||
186 (code >= LatinSmallLetterA && code <= LatinSmallLetterZ));
187}
188function isDecimalDigit(code) {
189 return code >= DigitZero && code <= DigitNine;
190}
191function isOctalDigit(code) {
192 return code >= DigitZero && code <= DigitSeven;
193}
194function isHexDigit(code) {
195 return ((code >= DigitZero && code <= DigitNine) ||
196 (code >= LatinCapitalLetterA && code <= LatinCapitalLetterF) ||
197 (code >= LatinSmallLetterA && code <= LatinSmallLetterF));
198}
199function isLineTerminator(code) {
200 return (code === LineFeed ||
201 code === CarriageReturn ||
202 code === LineSeparator ||
203 code === ParagraphSeparator);
204}
205function isValidUnicode(code) {
206 return code >= MinCodePoint && code <= MaxCodePoint;
207}
208function digitToInt(code) {
209 if (code >= LatinSmallLetterA && code <= LatinSmallLetterF) {
210 return code - LatinSmallLetterA + 10;
211 }
212 if (code >= LatinCapitalLetterA && code <= LatinCapitalLetterF) {
213 return code - LatinCapitalLetterA + 10;
214 }
215 return code - DigitZero;
216}
217function isLeadSurrogate(code) {
218 return code >= 0xd800 && code <= 0xdbff;
219}
220function isTrailSurrogate(code) {
221 return code >= 0xdc00 && code <= 0xdfff;
222}
223function combineSurrogatePair(lead, trail) {
224 return (lead - 0xd800) * 0x400 + (trail - 0xdc00) + 0x10000;
225}
226
227const legacyImpl = {
228 at(s, end, i) {
229 return i < end ? s.charCodeAt(i) : -1;
230 },
231 width(c) {
232 return 1;
233 },
234};
235const unicodeImpl = {
236 at(s, end, i) {
237 return i < end ? s.codePointAt(i) : -1;
238 },
239 width(c) {
240 return c > 0xffff ? 2 : 1;
241 },
242};
243class Reader {
244 constructor() {
245 this._impl = legacyImpl;
246 this._s = "";
247 this._i = 0;
248 this._end = 0;
249 this._cp1 = -1;
250 this._w1 = 1;
251 this._cp2 = -1;
252 this._w2 = 1;
253 this._cp3 = -1;
254 this._w3 = 1;
255 this._cp4 = -1;
256 }
257 get source() {
258 return this._s;
259 }
260 get index() {
261 return this._i;
262 }
263 get currentCodePoint() {
264 return this._cp1;
265 }
266 get nextCodePoint() {
267 return this._cp2;
268 }
269 get nextCodePoint2() {
270 return this._cp3;
271 }
272 get nextCodePoint3() {
273 return this._cp4;
274 }
275 reset(source, start, end, uFlag) {
276 this._impl = uFlag ? unicodeImpl : legacyImpl;
277 this._s = source;
278 this._end = end;
279 this.rewind(start);
280 }
281 rewind(index) {
282 const impl = this._impl;
283 this._i = index;
284 this._cp1 = impl.at(this._s, this._end, index);
285 this._w1 = impl.width(this._cp1);
286 this._cp2 = impl.at(this._s, this._end, index + this._w1);
287 this._w2 = impl.width(this._cp2);
288 this._cp3 = impl.at(this._s, this._end, index + this._w1 + this._w2);
289 this._w3 = impl.width(this._cp3);
290 this._cp4 = impl.at(this._s, this._end, index + this._w1 + this._w2 + this._w3);
291 }
292 advance() {
293 if (this._cp1 !== -1) {
294 const impl = this._impl;
295 this._i += this._w1;
296 this._cp1 = this._cp2;
297 this._w1 = this._w2;
298 this._cp2 = this._cp3;
299 this._w2 = impl.width(this._cp2);
300 this._cp3 = this._cp4;
301 this._w3 = impl.width(this._cp3);
302 this._cp4 = impl.at(this._s, this._end, this._i + this._w1 + this._w2 + this._w3);
303 }
304 }
305 eat(cp) {
306 if (this._cp1 === cp) {
307 this.advance();
308 return true;
309 }
310 return false;
311 }
312 eat2(cp1, cp2) {
313 if (this._cp1 === cp1 && this._cp2 === cp2) {
314 this.advance();
315 this.advance();
316 return true;
317 }
318 return false;
319 }
320 eat3(cp1, cp2, cp3) {
321 if (this._cp1 === cp1 && this._cp2 === cp2 && this._cp3 === cp3) {
322 this.advance();
323 this.advance();
324 this.advance();
325 return true;
326 }
327 return false;
328 }
329}
330
331class RegExpSyntaxError extends SyntaxError {
332 constructor(source, uFlag, index, message) {
333 if (source) {
334 if (!source.startsWith("/")) {
335 source = `/${source}/${uFlag ? "u" : ""}`;
336 }
337 source = `: ${source}`;
338 }
339 super(`Invalid regular expression${source}: ${message}`);
340 this.index = index;
341 }
342}
343
344function isSyntaxCharacter(cp) {
345 return (cp === CircumflexAccent ||
346 cp === DollarSign ||
347 cp === ReverseSolidus ||
348 cp === FullStop ||
349 cp === Asterisk ||
350 cp === PlusSign ||
351 cp === QuestionMark ||
352 cp === LeftParenthesis ||
353 cp === RightParenthesis ||
354 cp === LeftSquareBracket ||
355 cp === RightSquareBracket ||
356 cp === LeftCurlyBracket ||
357 cp === RightCurlyBracket ||
358 cp === VerticalLine);
359}
360function isRegExpIdentifierStart(cp) {
361 return isIdStart(cp) || cp === DollarSign || cp === LowLine;
362}
363function isRegExpIdentifierPart(cp) {
364 return (isIdContinue(cp) ||
365 cp === DollarSign ||
366 cp === LowLine ||
367 cp === ZeroWidthNonJoiner ||
368 cp === ZeroWidthJoiner);
369}
370function isUnicodePropertyNameCharacter(cp) {
371 return isLatinLetter(cp) || cp === LowLine;
372}
373function isUnicodePropertyValueCharacter(cp) {
374 return isUnicodePropertyNameCharacter(cp) || isDecimalDigit(cp);
375}
376class RegExpValidator {
377 constructor(options) {
378 this._reader = new Reader();
379 this._uFlag = false;
380 this._nFlag = false;
381 this._lastIntValue = 0;
382 this._lastMinValue = 0;
383 this._lastMaxValue = 0;
384 this._lastStrValue = "";
385 this._lastKeyValue = "";
386 this._lastValValue = "";
387 this._lastAssertionIsQuantifiable = false;
388 this._numCapturingParens = 0;
389 this._groupNames = new Set();
390 this._backreferenceNames = new Set();
391 this._options = options || {};
392 }
393 validateLiteral(source, start = 0, end = source.length) {
394 this._uFlag = this._nFlag = false;
395 this.reset(source, start, end);
396 this.onLiteralEnter(start);
397 if (this.eat(Solidus) && this.eatRegExpBody() && this.eat(Solidus)) {
398 const flagStart = this.index;
399 const uFlag = source.includes("u", flagStart);
400 this.validateFlags(source, flagStart, end);
401 this.validatePattern(source, start + 1, flagStart - 1, uFlag);
402 }
403 else if (start >= end) {
404 this.raise("Empty");
405 }
406 else {
407 const c = String.fromCodePoint(this.currentCodePoint);
408 this.raise(`Unexpected character '${c}'`);
409 }
410 this.onLiteralLeave(start, end);
411 }
412 validateFlags(source, start = 0, end = source.length) {
413 const existingFlags = new Set();
414 let global = false;
415 let ignoreCase = false;
416 let multiline = false;
417 let sticky = false;
418 let unicode = false;
419 let dotAll = false;
420 let hasIndices = false;
421 for (let i = start; i < end; ++i) {
422 const flag = source.charCodeAt(i);
423 if (existingFlags.has(flag)) {
424 this.raise(`Duplicated flag '${source[i]}'`);
425 }
426 existingFlags.add(flag);
427 if (flag === LatinSmallLetterG) {
428 global = true;
429 }
430 else if (flag === LatinSmallLetterI) {
431 ignoreCase = true;
432 }
433 else if (flag === LatinSmallLetterM) {
434 multiline = true;
435 }
436 else if (flag === LatinSmallLetterU && this.ecmaVersion >= 2015) {
437 unicode = true;
438 }
439 else if (flag === LatinSmallLetterY && this.ecmaVersion >= 2015) {
440 sticky = true;
441 }
442 else if (flag === LatinSmallLetterS && this.ecmaVersion >= 2018) {
443 dotAll = true;
444 }
445 else if (flag === LatinSmallLetterD && this.ecmaVersion >= 2022) {
446 hasIndices = true;
447 }
448 else {
449 this.raise(`Invalid flag '${source[i]}'`);
450 }
451 }
452 this.onFlags(start, end, global, ignoreCase, multiline, unicode, sticky, dotAll, hasIndices);
453 }
454 validatePattern(source, start = 0, end = source.length, uFlag = false) {
455 this._uFlag = uFlag && this.ecmaVersion >= 2015;
456 this._nFlag = uFlag && this.ecmaVersion >= 2018;
457 this.reset(source, start, end);
458 this.consumePattern();
459 if (!this._nFlag &&
460 this.ecmaVersion >= 2018 &&
461 this._groupNames.size > 0) {
462 this._nFlag = true;
463 this.rewind(start);
464 this.consumePattern();
465 }
466 }
467 get strict() {
468 return Boolean(this._options.strict || this._uFlag);
469 }
470 get ecmaVersion() {
471 return this._options.ecmaVersion || 2022;
472 }
473 onLiteralEnter(start) {
474 if (this._options.onLiteralEnter) {
475 this._options.onLiteralEnter(start);
476 }
477 }
478 onLiteralLeave(start, end) {
479 if (this._options.onLiteralLeave) {
480 this._options.onLiteralLeave(start, end);
481 }
482 }
483 onFlags(start, end, global, ignoreCase, multiline, unicode, sticky, dotAll, hasIndices) {
484 if (this._options.onFlags) {
485 this._options.onFlags(start, end, global, ignoreCase, multiline, unicode, sticky, dotAll, hasIndices);
486 }
487 }
488 onPatternEnter(start) {
489 if (this._options.onPatternEnter) {
490 this._options.onPatternEnter(start);
491 }
492 }
493 onPatternLeave(start, end) {
494 if (this._options.onPatternLeave) {
495 this._options.onPatternLeave(start, end);
496 }
497 }
498 onDisjunctionEnter(start) {
499 if (this._options.onDisjunctionEnter) {
500 this._options.onDisjunctionEnter(start);
501 }
502 }
503 onDisjunctionLeave(start, end) {
504 if (this._options.onDisjunctionLeave) {
505 this._options.onDisjunctionLeave(start, end);
506 }
507 }
508 onAlternativeEnter(start, index) {
509 if (this._options.onAlternativeEnter) {
510 this._options.onAlternativeEnter(start, index);
511 }
512 }
513 onAlternativeLeave(start, end, index) {
514 if (this._options.onAlternativeLeave) {
515 this._options.onAlternativeLeave(start, end, index);
516 }
517 }
518 onGroupEnter(start) {
519 if (this._options.onGroupEnter) {
520 this._options.onGroupEnter(start);
521 }
522 }
523 onGroupLeave(start, end) {
524 if (this._options.onGroupLeave) {
525 this._options.onGroupLeave(start, end);
526 }
527 }
528 onCapturingGroupEnter(start, name) {
529 if (this._options.onCapturingGroupEnter) {
530 this._options.onCapturingGroupEnter(start, name);
531 }
532 }
533 onCapturingGroupLeave(start, end, name) {
534 if (this._options.onCapturingGroupLeave) {
535 this._options.onCapturingGroupLeave(start, end, name);
536 }
537 }
538 onQuantifier(start, end, min, max, greedy) {
539 if (this._options.onQuantifier) {
540 this._options.onQuantifier(start, end, min, max, greedy);
541 }
542 }
543 onLookaroundAssertionEnter(start, kind, negate) {
544 if (this._options.onLookaroundAssertionEnter) {
545 this._options.onLookaroundAssertionEnter(start, kind, negate);
546 }
547 }
548 onLookaroundAssertionLeave(start, end, kind, negate) {
549 if (this._options.onLookaroundAssertionLeave) {
550 this._options.onLookaroundAssertionLeave(start, end, kind, negate);
551 }
552 }
553 onEdgeAssertion(start, end, kind) {
554 if (this._options.onEdgeAssertion) {
555 this._options.onEdgeAssertion(start, end, kind);
556 }
557 }
558 onWordBoundaryAssertion(start, end, kind, negate) {
559 if (this._options.onWordBoundaryAssertion) {
560 this._options.onWordBoundaryAssertion(start, end, kind, negate);
561 }
562 }
563 onAnyCharacterSet(start, end, kind) {
564 if (this._options.onAnyCharacterSet) {
565 this._options.onAnyCharacterSet(start, end, kind);
566 }
567 }
568 onEscapeCharacterSet(start, end, kind, negate) {
569 if (this._options.onEscapeCharacterSet) {
570 this._options.onEscapeCharacterSet(start, end, kind, negate);
571 }
572 }
573 onUnicodePropertyCharacterSet(start, end, kind, key, value, negate) {
574 if (this._options.onUnicodePropertyCharacterSet) {
575 this._options.onUnicodePropertyCharacterSet(start, end, kind, key, value, negate);
576 }
577 }
578 onCharacter(start, end, value) {
579 if (this._options.onCharacter) {
580 this._options.onCharacter(start, end, value);
581 }
582 }
583 onBackreference(start, end, ref) {
584 if (this._options.onBackreference) {
585 this._options.onBackreference(start, end, ref);
586 }
587 }
588 onCharacterClassEnter(start, negate) {
589 if (this._options.onCharacterClassEnter) {
590 this._options.onCharacterClassEnter(start, negate);
591 }
592 }
593 onCharacterClassLeave(start, end, negate) {
594 if (this._options.onCharacterClassLeave) {
595 this._options.onCharacterClassLeave(start, end, negate);
596 }
597 }
598 onCharacterClassRange(start, end, min, max) {
599 if (this._options.onCharacterClassRange) {
600 this._options.onCharacterClassRange(start, end, min, max);
601 }
602 }
603 get source() {
604 return this._reader.source;
605 }
606 get index() {
607 return this._reader.index;
608 }
609 get currentCodePoint() {
610 return this._reader.currentCodePoint;
611 }
612 get nextCodePoint() {
613 return this._reader.nextCodePoint;
614 }
615 get nextCodePoint2() {
616 return this._reader.nextCodePoint2;
617 }
618 get nextCodePoint3() {
619 return this._reader.nextCodePoint3;
620 }
621 reset(source, start, end) {
622 this._reader.reset(source, start, end, this._uFlag);
623 }
624 rewind(index) {
625 this._reader.rewind(index);
626 }
627 advance() {
628 this._reader.advance();
629 }
630 eat(cp) {
631 return this._reader.eat(cp);
632 }
633 eat2(cp1, cp2) {
634 return this._reader.eat2(cp1, cp2);
635 }
636 eat3(cp1, cp2, cp3) {
637 return this._reader.eat3(cp1, cp2, cp3);
638 }
639 raise(message) {
640 throw new RegExpSyntaxError(this.source, this._uFlag, this.index, message);
641 }
642 eatRegExpBody() {
643 const start = this.index;
644 let inClass = false;
645 let escaped = false;
646 for (;;) {
647 const cp = this.currentCodePoint;
648 if (cp === -1 || isLineTerminator(cp)) {
649 const kind = inClass ? "character class" : "regular expression";
650 this.raise(`Unterminated ${kind}`);
651 }
652 if (escaped) {
653 escaped = false;
654 }
655 else if (cp === ReverseSolidus) {
656 escaped = true;
657 }
658 else if (cp === LeftSquareBracket) {
659 inClass = true;
660 }
661 else if (cp === RightSquareBracket) {
662 inClass = false;
663 }
664 else if ((cp === Solidus && !inClass) ||
665 (cp === Asterisk && this.index === start)) {
666 break;
667 }
668 this.advance();
669 }
670 return this.index !== start;
671 }
672 consumePattern() {
673 const start = this.index;
674 this._numCapturingParens = this.countCapturingParens();
675 this._groupNames.clear();
676 this._backreferenceNames.clear();
677 this.onPatternEnter(start);
678 this.consumeDisjunction();
679 const cp = this.currentCodePoint;
680 if (this.currentCodePoint !== -1) {
681 if (cp === RightParenthesis) {
682 this.raise("Unmatched ')'");
683 }
684 if (cp === ReverseSolidus) {
685 this.raise("\\ at end of pattern");
686 }
687 if (cp === RightSquareBracket || cp === RightCurlyBracket) {
688 this.raise("Lone quantifier brackets");
689 }
690 const c = String.fromCodePoint(cp);
691 this.raise(`Unexpected character '${c}'`);
692 }
693 for (const name of this._backreferenceNames) {
694 if (!this._groupNames.has(name)) {
695 this.raise("Invalid named capture referenced");
696 }
697 }
698 this.onPatternLeave(start, this.index);
699 }
700 countCapturingParens() {
701 const start = this.index;
702 let inClass = false;
703 let escaped = false;
704 let count = 0;
705 let cp = 0;
706 while ((cp = this.currentCodePoint) !== -1) {
707 if (escaped) {
708 escaped = false;
709 }
710 else if (cp === ReverseSolidus) {
711 escaped = true;
712 }
713 else if (cp === LeftSquareBracket) {
714 inClass = true;
715 }
716 else if (cp === RightSquareBracket) {
717 inClass = false;
718 }
719 else if (cp === LeftParenthesis &&
720 !inClass &&
721 (this.nextCodePoint !== QuestionMark ||
722 (this.nextCodePoint2 === LessThanSign &&
723 this.nextCodePoint3 !== EqualsSign &&
724 this.nextCodePoint3 !== ExclamationMark))) {
725 count += 1;
726 }
727 this.advance();
728 }
729 this.rewind(start);
730 return count;
731 }
732 consumeDisjunction() {
733 const start = this.index;
734 let i = 0;
735 this.onDisjunctionEnter(start);
736 do {
737 this.consumeAlternative(i++);
738 } while (this.eat(VerticalLine));
739 if (this.consumeQuantifier(true)) {
740 this.raise("Nothing to repeat");
741 }
742 if (this.eat(LeftCurlyBracket)) {
743 this.raise("Lone quantifier brackets");
744 }
745 this.onDisjunctionLeave(start, this.index);
746 }
747 consumeAlternative(i) {
748 const start = this.index;
749 this.onAlternativeEnter(start, i);
750 while (this.currentCodePoint !== -1 && this.consumeTerm()) {
751 }
752 this.onAlternativeLeave(start, this.index, i);
753 }
754 consumeTerm() {
755 if (this._uFlag || this.strict) {
756 return (this.consumeAssertion() ||
757 (this.consumeAtom() && this.consumeOptionalQuantifier()));
758 }
759 return ((this.consumeAssertion() &&
760 (!this._lastAssertionIsQuantifiable ||
761 this.consumeOptionalQuantifier())) ||
762 (this.consumeExtendedAtom() && this.consumeOptionalQuantifier()));
763 }
764 consumeOptionalQuantifier() {
765 this.consumeQuantifier();
766 return true;
767 }
768 consumeAssertion() {
769 const start = this.index;
770 this._lastAssertionIsQuantifiable = false;
771 if (this.eat(CircumflexAccent)) {
772 this.onEdgeAssertion(start, this.index, "start");
773 return true;
774 }
775 if (this.eat(DollarSign)) {
776 this.onEdgeAssertion(start, this.index, "end");
777 return true;
778 }
779 if (this.eat2(ReverseSolidus, LatinCapitalLetterB)) {
780 this.onWordBoundaryAssertion(start, this.index, "word", true);
781 return true;
782 }
783 if (this.eat2(ReverseSolidus, LatinSmallLetterB)) {
784 this.onWordBoundaryAssertion(start, this.index, "word", false);
785 return true;
786 }
787 if (this.eat2(LeftParenthesis, QuestionMark)) {
788 const lookbehind = this.ecmaVersion >= 2018 && this.eat(LessThanSign);
789 let negate = false;
790 if (this.eat(EqualsSign) || (negate = this.eat(ExclamationMark))) {
791 const kind = lookbehind ? "lookbehind" : "lookahead";
792 this.onLookaroundAssertionEnter(start, kind, negate);
793 this.consumeDisjunction();
794 if (!this.eat(RightParenthesis)) {
795 this.raise("Unterminated group");
796 }
797 this._lastAssertionIsQuantifiable = !lookbehind && !this.strict;
798 this.onLookaroundAssertionLeave(start, this.index, kind, negate);
799 return true;
800 }
801 this.rewind(start);
802 }
803 return false;
804 }
805 consumeQuantifier(noConsume = false) {
806 const start = this.index;
807 let min = 0;
808 let max = 0;
809 let greedy = false;
810 if (this.eat(Asterisk)) {
811 min = 0;
812 max = Number.POSITIVE_INFINITY;
813 }
814 else if (this.eat(PlusSign)) {
815 min = 1;
816 max = Number.POSITIVE_INFINITY;
817 }
818 else if (this.eat(QuestionMark)) {
819 min = 0;
820 max = 1;
821 }
822 else if (this.eatBracedQuantifier(noConsume)) {
823 min = this._lastMinValue;
824 max = this._lastMaxValue;
825 }
826 else {
827 return false;
828 }
829 greedy = !this.eat(QuestionMark);
830 if (!noConsume) {
831 this.onQuantifier(start, this.index, min, max, greedy);
832 }
833 return true;
834 }
835 eatBracedQuantifier(noError) {
836 const start = this.index;
837 if (this.eat(LeftCurlyBracket)) {
838 this._lastMinValue = 0;
839 this._lastMaxValue = Number.POSITIVE_INFINITY;
840 if (this.eatDecimalDigits()) {
841 this._lastMinValue = this._lastMaxValue = this._lastIntValue;
842 if (this.eat(Comma)) {
843 this._lastMaxValue = this.eatDecimalDigits()
844 ? this._lastIntValue
845 : Number.POSITIVE_INFINITY;
846 }
847 if (this.eat(RightCurlyBracket)) {
848 if (!noError && this._lastMaxValue < this._lastMinValue) {
849 this.raise("numbers out of order in {} quantifier");
850 }
851 return true;
852 }
853 }
854 if (!noError && (this._uFlag || this.strict)) {
855 this.raise("Incomplete quantifier");
856 }
857 this.rewind(start);
858 }
859 return false;
860 }
861 consumeAtom() {
862 return (this.consumePatternCharacter() ||
863 this.consumeDot() ||
864 this.consumeReverseSolidusAtomEscape() ||
865 this.consumeCharacterClass() ||
866 this.consumeUncapturingGroup() ||
867 this.consumeCapturingGroup());
868 }
869 consumeDot() {
870 if (this.eat(FullStop)) {
871 this.onAnyCharacterSet(this.index - 1, this.index, "any");
872 return true;
873 }
874 return false;
875 }
876 consumeReverseSolidusAtomEscape() {
877 const start = this.index;
878 if (this.eat(ReverseSolidus)) {
879 if (this.consumeAtomEscape()) {
880 return true;
881 }
882 this.rewind(start);
883 }
884 return false;
885 }
886 consumeUncapturingGroup() {
887 const start = this.index;
888 if (this.eat3(LeftParenthesis, QuestionMark, Colon)) {
889 this.onGroupEnter(start);
890 this.consumeDisjunction();
891 if (!this.eat(RightParenthesis)) {
892 this.raise("Unterminated group");
893 }
894 this.onGroupLeave(start, this.index);
895 return true;
896 }
897 return false;
898 }
899 consumeCapturingGroup() {
900 const start = this.index;
901 if (this.eat(LeftParenthesis)) {
902 let name = null;
903 if (this.ecmaVersion >= 2018) {
904 if (this.consumeGroupSpecifier()) {
905 name = this._lastStrValue;
906 }
907 }
908 else if (this.currentCodePoint === QuestionMark) {
909 this.raise("Invalid group");
910 }
911 this.onCapturingGroupEnter(start, name);
912 this.consumeDisjunction();
913 if (!this.eat(RightParenthesis)) {
914 this.raise("Unterminated group");
915 }
916 this.onCapturingGroupLeave(start, this.index, name);
917 return true;
918 }
919 return false;
920 }
921 consumeExtendedAtom() {
922 return (this.consumeDot() ||
923 this.consumeReverseSolidusAtomEscape() ||
924 this.consumeReverseSolidusFollowedByC() ||
925 this.consumeCharacterClass() ||
926 this.consumeUncapturingGroup() ||
927 this.consumeCapturingGroup() ||
928 this.consumeInvalidBracedQuantifier() ||
929 this.consumeExtendedPatternCharacter());
930 }
931 consumeReverseSolidusFollowedByC() {
932 const start = this.index;
933 if (this.currentCodePoint === ReverseSolidus &&
934 this.nextCodePoint === LatinSmallLetterC) {
935 this._lastIntValue = this.currentCodePoint;
936 this.advance();
937 this.onCharacter(start, this.index, ReverseSolidus);
938 return true;
939 }
940 return false;
941 }
942 consumeInvalidBracedQuantifier() {
943 if (this.eatBracedQuantifier(true)) {
944 this.raise("Nothing to repeat");
945 }
946 return false;
947 }
948 consumePatternCharacter() {
949 const start = this.index;
950 const cp = this.currentCodePoint;
951 if (cp !== -1 && !isSyntaxCharacter(cp)) {
952 this.advance();
953 this.onCharacter(start, this.index, cp);
954 return true;
955 }
956 return false;
957 }
958 consumeExtendedPatternCharacter() {
959 const start = this.index;
960 const cp = this.currentCodePoint;
961 if (cp !== -1 &&
962 cp !== CircumflexAccent &&
963 cp !== DollarSign &&
964 cp !== ReverseSolidus &&
965 cp !== FullStop &&
966 cp !== Asterisk &&
967 cp !== PlusSign &&
968 cp !== QuestionMark &&
969 cp !== LeftParenthesis &&
970 cp !== RightParenthesis &&
971 cp !== LeftSquareBracket &&
972 cp !== VerticalLine) {
973 this.advance();
974 this.onCharacter(start, this.index, cp);
975 return true;
976 }
977 return false;
978 }
979 consumeGroupSpecifier() {
980 if (this.eat(QuestionMark)) {
981 if (this.eatGroupName()) {
982 if (!this._groupNames.has(this._lastStrValue)) {
983 this._groupNames.add(this._lastStrValue);
984 return true;
985 }
986 this.raise("Duplicate capture group name");
987 }
988 this.raise("Invalid group");
989 }
990 return false;
991 }
992 consumeAtomEscape() {
993 if (this.consumeBackreference() ||
994 this.consumeCharacterClassEscape() ||
995 this.consumeCharacterEscape() ||
996 (this._nFlag && this.consumeKGroupName())) {
997 return true;
998 }
999 if (this.strict || this._uFlag) {
1000 this.raise("Invalid escape");
1001 }
1002 return false;
1003 }
1004 consumeBackreference() {
1005 const start = this.index;
1006 if (this.eatDecimalEscape()) {
1007 const n = this._lastIntValue;
1008 if (n <= this._numCapturingParens) {
1009 this.onBackreference(start - 1, this.index, n);
1010 return true;
1011 }
1012 if (this.strict || this._uFlag) {
1013 this.raise("Invalid escape");
1014 }
1015 this.rewind(start);
1016 }
1017 return false;
1018 }
1019 consumeCharacterClassEscape() {
1020 const start = this.index;
1021 if (this.eat(LatinSmallLetterD)) {
1022 this._lastIntValue = -1;
1023 this.onEscapeCharacterSet(start - 1, this.index, "digit", false);
1024 return true;
1025 }
1026 if (this.eat(LatinCapitalLetterD)) {
1027 this._lastIntValue = -1;
1028 this.onEscapeCharacterSet(start - 1, this.index, "digit", true);
1029 return true;
1030 }
1031 if (this.eat(LatinSmallLetterS)) {
1032 this._lastIntValue = -1;
1033 this.onEscapeCharacterSet(start - 1, this.index, "space", false);
1034 return true;
1035 }
1036 if (this.eat(LatinCapitalLetterS)) {
1037 this._lastIntValue = -1;
1038 this.onEscapeCharacterSet(start - 1, this.index, "space", true);
1039 return true;
1040 }
1041 if (this.eat(LatinSmallLetterW)) {
1042 this._lastIntValue = -1;
1043 this.onEscapeCharacterSet(start - 1, this.index, "word", false);
1044 return true;
1045 }
1046 if (this.eat(LatinCapitalLetterW)) {
1047 this._lastIntValue = -1;
1048 this.onEscapeCharacterSet(start - 1, this.index, "word", true);
1049 return true;
1050 }
1051 let negate = false;
1052 if (this._uFlag &&
1053 this.ecmaVersion >= 2018 &&
1054 (this.eat(LatinSmallLetterP) ||
1055 (negate = this.eat(LatinCapitalLetterP)))) {
1056 this._lastIntValue = -1;
1057 if (this.eat(LeftCurlyBracket) &&
1058 this.eatUnicodePropertyValueExpression() &&
1059 this.eat(RightCurlyBracket)) {
1060 this.onUnicodePropertyCharacterSet(start - 1, this.index, "property", this._lastKeyValue, this._lastValValue || null, negate);
1061 return true;
1062 }
1063 this.raise("Invalid property name");
1064 }
1065 return false;
1066 }
1067 consumeCharacterEscape() {
1068 const start = this.index;
1069 if (this.eatControlEscape() ||
1070 this.eatCControlLetter() ||
1071 this.eatZero() ||
1072 this.eatHexEscapeSequence() ||
1073 this.eatRegExpUnicodeEscapeSequence() ||
1074 (!this.strict &&
1075 !this._uFlag &&
1076 this.eatLegacyOctalEscapeSequence()) ||
1077 this.eatIdentityEscape()) {
1078 this.onCharacter(start - 1, this.index, this._lastIntValue);
1079 return true;
1080 }
1081 return false;
1082 }
1083 consumeKGroupName() {
1084 const start = this.index;
1085 if (this.eat(LatinSmallLetterK)) {
1086 if (this.eatGroupName()) {
1087 const groupName = this._lastStrValue;
1088 this._backreferenceNames.add(groupName);
1089 this.onBackreference(start - 1, this.index, groupName);
1090 return true;
1091 }
1092 this.raise("Invalid named reference");
1093 }
1094 return false;
1095 }
1096 consumeCharacterClass() {
1097 const start = this.index;
1098 if (this.eat(LeftSquareBracket)) {
1099 const negate = this.eat(CircumflexAccent);
1100 this.onCharacterClassEnter(start, negate);
1101 this.consumeClassRanges();
1102 if (!this.eat(RightSquareBracket)) {
1103 this.raise("Unterminated character class");
1104 }
1105 this.onCharacterClassLeave(start, this.index, negate);
1106 return true;
1107 }
1108 return false;
1109 }
1110 consumeClassRanges() {
1111 const strict = this.strict || this._uFlag;
1112 for (;;) {
1113 const rangeStart = this.index;
1114 if (!this.consumeClassAtom()) {
1115 break;
1116 }
1117 const min = this._lastIntValue;
1118 if (!this.eat(HyphenMinus)) {
1119 continue;
1120 }
1121 this.onCharacter(this.index - 1, this.index, HyphenMinus);
1122 if (!this.consumeClassAtom()) {
1123 break;
1124 }
1125 const max = this._lastIntValue;
1126 if (min === -1 || max === -1) {
1127 if (strict) {
1128 this.raise("Invalid character class");
1129 }
1130 continue;
1131 }
1132 if (min > max) {
1133 this.raise("Range out of order in character class");
1134 }
1135 this.onCharacterClassRange(rangeStart, this.index, min, max);
1136 }
1137 }
1138 consumeClassAtom() {
1139 const start = this.index;
1140 const cp = this.currentCodePoint;
1141 if (cp !== -1 && cp !== ReverseSolidus && cp !== RightSquareBracket) {
1142 this.advance();
1143 this._lastIntValue = cp;
1144 this.onCharacter(start, this.index, this._lastIntValue);
1145 return true;
1146 }
1147 if (this.eat(ReverseSolidus)) {
1148 if (this.consumeClassEscape()) {
1149 return true;
1150 }
1151 if (!this.strict && this.currentCodePoint === LatinSmallLetterC) {
1152 this._lastIntValue = ReverseSolidus;
1153 this.onCharacter(start, this.index, this._lastIntValue);
1154 return true;
1155 }
1156 if (this.strict || this._uFlag) {
1157 this.raise("Invalid escape");
1158 }
1159 this.rewind(start);
1160 }
1161 return false;
1162 }
1163 consumeClassEscape() {
1164 const start = this.index;
1165 if (this.eat(LatinSmallLetterB)) {
1166 this._lastIntValue = Backspace;
1167 this.onCharacter(start - 1, this.index, this._lastIntValue);
1168 return true;
1169 }
1170 if (this._uFlag && this.eat(HyphenMinus)) {
1171 this._lastIntValue = HyphenMinus;
1172 this.onCharacter(start - 1, this.index, this._lastIntValue);
1173 return true;
1174 }
1175 let cp = 0;
1176 if (!this.strict &&
1177 !this._uFlag &&
1178 this.currentCodePoint === LatinSmallLetterC &&
1179 (isDecimalDigit((cp = this.nextCodePoint)) || cp === LowLine)) {
1180 this.advance();
1181 this.advance();
1182 this._lastIntValue = cp % 0x20;
1183 this.onCharacter(start - 1, this.index, this._lastIntValue);
1184 return true;
1185 }
1186 return (this.consumeCharacterClassEscape() || this.consumeCharacterEscape());
1187 }
1188 eatGroupName() {
1189 if (this.eat(LessThanSign)) {
1190 if (this.eatRegExpIdentifierName() && this.eat(GreaterThanSign)) {
1191 return true;
1192 }
1193 this.raise("Invalid capture group name");
1194 }
1195 return false;
1196 }
1197 eatRegExpIdentifierName() {
1198 if (this.eatRegExpIdentifierStart()) {
1199 this._lastStrValue = String.fromCodePoint(this._lastIntValue);
1200 while (this.eatRegExpIdentifierPart()) {
1201 this._lastStrValue += String.fromCodePoint(this._lastIntValue);
1202 }
1203 return true;
1204 }
1205 return false;
1206 }
1207 eatRegExpIdentifierStart() {
1208 const start = this.index;
1209 const forceUFlag = !this._uFlag && this.ecmaVersion >= 2020;
1210 let cp = this.currentCodePoint;
1211 this.advance();
1212 if (cp === ReverseSolidus &&
1213 this.eatRegExpUnicodeEscapeSequence(forceUFlag)) {
1214 cp = this._lastIntValue;
1215 }
1216 else if (forceUFlag &&
1217 isLeadSurrogate(cp) &&
1218 isTrailSurrogate(this.currentCodePoint)) {
1219 cp = combineSurrogatePair(cp, this.currentCodePoint);
1220 this.advance();
1221 }
1222 if (isRegExpIdentifierStart(cp)) {
1223 this._lastIntValue = cp;
1224 return true;
1225 }
1226 if (this.index !== start) {
1227 this.rewind(start);
1228 }
1229 return false;
1230 }
1231 eatRegExpIdentifierPart() {
1232 const start = this.index;
1233 const forceUFlag = !this._uFlag && this.ecmaVersion >= 2020;
1234 let cp = this.currentCodePoint;
1235 this.advance();
1236 if (cp === ReverseSolidus &&
1237 this.eatRegExpUnicodeEscapeSequence(forceUFlag)) {
1238 cp = this._lastIntValue;
1239 }
1240 else if (forceUFlag &&
1241 isLeadSurrogate(cp) &&
1242 isTrailSurrogate(this.currentCodePoint)) {
1243 cp = combineSurrogatePair(cp, this.currentCodePoint);
1244 this.advance();
1245 }
1246 if (isRegExpIdentifierPart(cp)) {
1247 this._lastIntValue = cp;
1248 return true;
1249 }
1250 if (this.index !== start) {
1251 this.rewind(start);
1252 }
1253 return false;
1254 }
1255 eatCControlLetter() {
1256 const start = this.index;
1257 if (this.eat(LatinSmallLetterC)) {
1258 if (this.eatControlLetter()) {
1259 return true;
1260 }
1261 this.rewind(start);
1262 }
1263 return false;
1264 }
1265 eatZero() {
1266 if (this.currentCodePoint === DigitZero &&
1267 !isDecimalDigit(this.nextCodePoint)) {
1268 this._lastIntValue = 0;
1269 this.advance();
1270 return true;
1271 }
1272 return false;
1273 }
1274 eatControlEscape() {
1275 if (this.eat(LatinSmallLetterF)) {
1276 this._lastIntValue = FormFeed;
1277 return true;
1278 }
1279 if (this.eat(LatinSmallLetterN)) {
1280 this._lastIntValue = LineFeed;
1281 return true;
1282 }
1283 if (this.eat(LatinSmallLetterR)) {
1284 this._lastIntValue = CarriageReturn;
1285 return true;
1286 }
1287 if (this.eat(LatinSmallLetterT)) {
1288 this._lastIntValue = CharacterTabulation;
1289 return true;
1290 }
1291 if (this.eat(LatinSmallLetterV)) {
1292 this._lastIntValue = LineTabulation;
1293 return true;
1294 }
1295 return false;
1296 }
1297 eatControlLetter() {
1298 const cp = this.currentCodePoint;
1299 if (isLatinLetter(cp)) {
1300 this.advance();
1301 this._lastIntValue = cp % 0x20;
1302 return true;
1303 }
1304 return false;
1305 }
1306 eatRegExpUnicodeEscapeSequence(forceUFlag = false) {
1307 const start = this.index;
1308 const uFlag = forceUFlag || this._uFlag;
1309 if (this.eat(LatinSmallLetterU)) {
1310 if ((uFlag && this.eatRegExpUnicodeSurrogatePairEscape()) ||
1311 this.eatFixedHexDigits(4) ||
1312 (uFlag && this.eatRegExpUnicodeCodePointEscape())) {
1313 return true;
1314 }
1315 if (this.strict || uFlag) {
1316 this.raise("Invalid unicode escape");
1317 }
1318 this.rewind(start);
1319 }
1320 return false;
1321 }
1322 eatRegExpUnicodeSurrogatePairEscape() {
1323 const start = this.index;
1324 if (this.eatFixedHexDigits(4)) {
1325 const lead = this._lastIntValue;
1326 if (isLeadSurrogate(lead) &&
1327 this.eat(ReverseSolidus) &&
1328 this.eat(LatinSmallLetterU) &&
1329 this.eatFixedHexDigits(4)) {
1330 const trail = this._lastIntValue;
1331 if (isTrailSurrogate(trail)) {
1332 this._lastIntValue = combineSurrogatePair(lead, trail);
1333 return true;
1334 }
1335 }
1336 this.rewind(start);
1337 }
1338 return false;
1339 }
1340 eatRegExpUnicodeCodePointEscape() {
1341 const start = this.index;
1342 if (this.eat(LeftCurlyBracket) &&
1343 this.eatHexDigits() &&
1344 this.eat(RightCurlyBracket) &&
1345 isValidUnicode(this._lastIntValue)) {
1346 return true;
1347 }
1348 this.rewind(start);
1349 return false;
1350 }
1351 eatIdentityEscape() {
1352 const cp = this.currentCodePoint;
1353 if (this.isValidIdentityEscape(cp)) {
1354 this._lastIntValue = cp;
1355 this.advance();
1356 return true;
1357 }
1358 return false;
1359 }
1360 isValidIdentityEscape(cp) {
1361 if (cp === -1) {
1362 return false;
1363 }
1364 if (this._uFlag) {
1365 return isSyntaxCharacter(cp) || cp === Solidus;
1366 }
1367 if (this.strict) {
1368 return !isIdContinue(cp);
1369 }
1370 if (this._nFlag) {
1371 return !(cp === LatinSmallLetterC || cp === LatinSmallLetterK);
1372 }
1373 return cp !== LatinSmallLetterC;
1374 }
1375 eatDecimalEscape() {
1376 this._lastIntValue = 0;
1377 let cp = this.currentCodePoint;
1378 if (cp >= DigitOne && cp <= DigitNine) {
1379 do {
1380 this._lastIntValue = 10 * this._lastIntValue + (cp - DigitZero);
1381 this.advance();
1382 } while ((cp = this.currentCodePoint) >= DigitZero &&
1383 cp <= DigitNine);
1384 return true;
1385 }
1386 return false;
1387 }
1388 eatUnicodePropertyValueExpression() {
1389 const start = this.index;
1390 if (this.eatUnicodePropertyName() && this.eat(EqualsSign)) {
1391 this._lastKeyValue = this._lastStrValue;
1392 if (this.eatUnicodePropertyValue()) {
1393 this._lastValValue = this._lastStrValue;
1394 if (isValidUnicodeProperty(this.ecmaVersion, this._lastKeyValue, this._lastValValue)) {
1395 return true;
1396 }
1397 this.raise("Invalid property name");
1398 }
1399 }
1400 this.rewind(start);
1401 if (this.eatLoneUnicodePropertyNameOrValue()) {
1402 const nameOrValue = this._lastStrValue;
1403 if (isValidUnicodeProperty(this.ecmaVersion, "General_Category", nameOrValue)) {
1404 this._lastKeyValue = "General_Category";
1405 this._lastValValue = nameOrValue;
1406 return true;
1407 }
1408 if (isValidLoneUnicodeProperty(this.ecmaVersion, nameOrValue)) {
1409 this._lastKeyValue = nameOrValue;
1410 this._lastValValue = "";
1411 return true;
1412 }
1413 this.raise("Invalid property name");
1414 }
1415 return false;
1416 }
1417 eatUnicodePropertyName() {
1418 this._lastStrValue = "";
1419 while (isUnicodePropertyNameCharacter(this.currentCodePoint)) {
1420 this._lastStrValue += String.fromCodePoint(this.currentCodePoint);
1421 this.advance();
1422 }
1423 return this._lastStrValue !== "";
1424 }
1425 eatUnicodePropertyValue() {
1426 this._lastStrValue = "";
1427 while (isUnicodePropertyValueCharacter(this.currentCodePoint)) {
1428 this._lastStrValue += String.fromCodePoint(this.currentCodePoint);
1429 this.advance();
1430 }
1431 return this._lastStrValue !== "";
1432 }
1433 eatLoneUnicodePropertyNameOrValue() {
1434 return this.eatUnicodePropertyValue();
1435 }
1436 eatHexEscapeSequence() {
1437 const start = this.index;
1438 if (this.eat(LatinSmallLetterX)) {
1439 if (this.eatFixedHexDigits(2)) {
1440 return true;
1441 }
1442 if (this._uFlag || this.strict) {
1443 this.raise("Invalid escape");
1444 }
1445 this.rewind(start);
1446 }
1447 return false;
1448 }
1449 eatDecimalDigits() {
1450 const start = this.index;
1451 this._lastIntValue = 0;
1452 while (isDecimalDigit(this.currentCodePoint)) {
1453 this._lastIntValue =
1454 10 * this._lastIntValue + digitToInt(this.currentCodePoint);
1455 this.advance();
1456 }
1457 return this.index !== start;
1458 }
1459 eatHexDigits() {
1460 const start = this.index;
1461 this._lastIntValue = 0;
1462 while (isHexDigit(this.currentCodePoint)) {
1463 this._lastIntValue =
1464 16 * this._lastIntValue + digitToInt(this.currentCodePoint);
1465 this.advance();
1466 }
1467 return this.index !== start;
1468 }
1469 eatLegacyOctalEscapeSequence() {
1470 if (this.eatOctalDigit()) {
1471 const n1 = this._lastIntValue;
1472 if (this.eatOctalDigit()) {
1473 const n2 = this._lastIntValue;
1474 if (n1 <= 3 && this.eatOctalDigit()) {
1475 this._lastIntValue = n1 * 64 + n2 * 8 + this._lastIntValue;
1476 }
1477 else {
1478 this._lastIntValue = n1 * 8 + n2;
1479 }
1480 }
1481 else {
1482 this._lastIntValue = n1;
1483 }
1484 return true;
1485 }
1486 return false;
1487 }
1488 eatOctalDigit() {
1489 const cp = this.currentCodePoint;
1490 if (isOctalDigit(cp)) {
1491 this.advance();
1492 this._lastIntValue = cp - DigitZero;
1493 return true;
1494 }
1495 this._lastIntValue = 0;
1496 return false;
1497 }
1498 eatFixedHexDigits(length) {
1499 const start = this.index;
1500 this._lastIntValue = 0;
1501 for (let i = 0; i < length; ++i) {
1502 const cp = this.currentCodePoint;
1503 if (!isHexDigit(cp)) {
1504 this.rewind(start);
1505 return false;
1506 }
1507 this._lastIntValue = 16 * this._lastIntValue + digitToInt(cp);
1508 this.advance();
1509 }
1510 return true;
1511 }
1512}
1513
1514const DummyPattern = {};
1515const DummyFlags = {};
1516const DummyCapturingGroup = {};
1517class RegExpParserState {
1518 constructor(options) {
1519 this._node = DummyPattern;
1520 this._flags = DummyFlags;
1521 this._backreferences = [];
1522 this._capturingGroups = [];
1523 this.source = "";
1524 this.strict = Boolean(options && options.strict);
1525 this.ecmaVersion = (options && options.ecmaVersion) || 2022;
1526 }
1527 get pattern() {
1528 if (this._node.type !== "Pattern") {
1529 throw new Error("UnknownError");
1530 }
1531 return this._node;
1532 }
1533 get flags() {
1534 if (this._flags.type !== "Flags") {
1535 throw new Error("UnknownError");
1536 }
1537 return this._flags;
1538 }
1539 onFlags(start, end, global, ignoreCase, multiline, unicode, sticky, dotAll, hasIndices) {
1540 this._flags = {
1541 type: "Flags",
1542 parent: null,
1543 start,
1544 end,
1545 raw: this.source.slice(start, end),
1546 global,
1547 ignoreCase,
1548 multiline,
1549 unicode,
1550 sticky,
1551 dotAll,
1552 hasIndices,
1553 };
1554 }
1555 onPatternEnter(start) {
1556 this._node = {
1557 type: "Pattern",
1558 parent: null,
1559 start,
1560 end: start,
1561 raw: "",
1562 alternatives: [],
1563 };
1564 this._backreferences.length = 0;
1565 this._capturingGroups.length = 0;
1566 }
1567 onPatternLeave(start, end) {
1568 this._node.end = end;
1569 this._node.raw = this.source.slice(start, end);
1570 for (const reference of this._backreferences) {
1571 const ref = reference.ref;
1572 const group = typeof ref === "number"
1573 ? this._capturingGroups[ref - 1]
1574 : this._capturingGroups.find(g => g.name === ref);
1575 reference.resolved = group;
1576 group.references.push(reference);
1577 }
1578 }
1579 onAlternativeEnter(start) {
1580 const parent = this._node;
1581 if (parent.type !== "Assertion" &&
1582 parent.type !== "CapturingGroup" &&
1583 parent.type !== "Group" &&
1584 parent.type !== "Pattern") {
1585 throw new Error("UnknownError");
1586 }
1587 this._node = {
1588 type: "Alternative",
1589 parent,
1590 start,
1591 end: start,
1592 raw: "",
1593 elements: [],
1594 };
1595 parent.alternatives.push(this._node);
1596 }
1597 onAlternativeLeave(start, end) {
1598 const node = this._node;
1599 if (node.type !== "Alternative") {
1600 throw new Error("UnknownError");
1601 }
1602 node.end = end;
1603 node.raw = this.source.slice(start, end);
1604 this._node = node.parent;
1605 }
1606 onGroupEnter(start) {
1607 const parent = this._node;
1608 if (parent.type !== "Alternative") {
1609 throw new Error("UnknownError");
1610 }
1611 this._node = {
1612 type: "Group",
1613 parent,
1614 start,
1615 end: start,
1616 raw: "",
1617 alternatives: [],
1618 };
1619 parent.elements.push(this._node);
1620 }
1621 onGroupLeave(start, end) {
1622 const node = this._node;
1623 if (node.type !== "Group" || node.parent.type !== "Alternative") {
1624 throw new Error("UnknownError");
1625 }
1626 node.end = end;
1627 node.raw = this.source.slice(start, end);
1628 this._node = node.parent;
1629 }
1630 onCapturingGroupEnter(start, name) {
1631 const parent = this._node;
1632 if (parent.type !== "Alternative") {
1633 throw new Error("UnknownError");
1634 }
1635 this._node = {
1636 type: "CapturingGroup",
1637 parent,
1638 start,
1639 end: start,
1640 raw: "",
1641 name,
1642 alternatives: [],
1643 references: [],
1644 };
1645 parent.elements.push(this._node);
1646 this._capturingGroups.push(this._node);
1647 }
1648 onCapturingGroupLeave(start, end) {
1649 const node = this._node;
1650 if (node.type !== "CapturingGroup" ||
1651 node.parent.type !== "Alternative") {
1652 throw new Error("UnknownError");
1653 }
1654 node.end = end;
1655 node.raw = this.source.slice(start, end);
1656 this._node = node.parent;
1657 }
1658 onQuantifier(start, end, min, max, greedy) {
1659 const parent = this._node;
1660 if (parent.type !== "Alternative") {
1661 throw new Error("UnknownError");
1662 }
1663 const element = parent.elements.pop();
1664 if (element == null ||
1665 element.type === "Quantifier" ||
1666 (element.type === "Assertion" && element.kind !== "lookahead")) {
1667 throw new Error("UnknownError");
1668 }
1669 const node = {
1670 type: "Quantifier",
1671 parent,
1672 start: element.start,
1673 end,
1674 raw: this.source.slice(element.start, end),
1675 min,
1676 max,
1677 greedy,
1678 element,
1679 };
1680 parent.elements.push(node);
1681 element.parent = node;
1682 }
1683 onLookaroundAssertionEnter(start, kind, negate) {
1684 const parent = this._node;
1685 if (parent.type !== "Alternative") {
1686 throw new Error("UnknownError");
1687 }
1688 const node = (this._node = {
1689 type: "Assertion",
1690 parent,
1691 start,
1692 end: start,
1693 raw: "",
1694 kind,
1695 negate,
1696 alternatives: [],
1697 });
1698 parent.elements.push(node);
1699 }
1700 onLookaroundAssertionLeave(start, end) {
1701 const node = this._node;
1702 if (node.type !== "Assertion" || node.parent.type !== "Alternative") {
1703 throw new Error("UnknownError");
1704 }
1705 node.end = end;
1706 node.raw = this.source.slice(start, end);
1707 this._node = node.parent;
1708 }
1709 onEdgeAssertion(start, end, kind) {
1710 const parent = this._node;
1711 if (parent.type !== "Alternative") {
1712 throw new Error("UnknownError");
1713 }
1714 parent.elements.push({
1715 type: "Assertion",
1716 parent,
1717 start,
1718 end,
1719 raw: this.source.slice(start, end),
1720 kind,
1721 });
1722 }
1723 onWordBoundaryAssertion(start, end, kind, negate) {
1724 const parent = this._node;
1725 if (parent.type !== "Alternative") {
1726 throw new Error("UnknownError");
1727 }
1728 parent.elements.push({
1729 type: "Assertion",
1730 parent,
1731 start,
1732 end,
1733 raw: this.source.slice(start, end),
1734 kind,
1735 negate,
1736 });
1737 }
1738 onAnyCharacterSet(start, end, kind) {
1739 const parent = this._node;
1740 if (parent.type !== "Alternative") {
1741 throw new Error("UnknownError");
1742 }
1743 parent.elements.push({
1744 type: "CharacterSet",
1745 parent,
1746 start,
1747 end,
1748 raw: this.source.slice(start, end),
1749 kind,
1750 });
1751 }
1752 onEscapeCharacterSet(start, end, kind, negate) {
1753 const parent = this._node;
1754 if (parent.type !== "Alternative" && parent.type !== "CharacterClass") {
1755 throw new Error("UnknownError");
1756 }
1757 parent.elements.push({
1758 type: "CharacterSet",
1759 parent,
1760 start,
1761 end,
1762 raw: this.source.slice(start, end),
1763 kind,
1764 negate,
1765 });
1766 }
1767 onUnicodePropertyCharacterSet(start, end, kind, key, value, negate) {
1768 const parent = this._node;
1769 if (parent.type !== "Alternative" && parent.type !== "CharacterClass") {
1770 throw new Error("UnknownError");
1771 }
1772 parent.elements.push({
1773 type: "CharacterSet",
1774 parent,
1775 start,
1776 end,
1777 raw: this.source.slice(start, end),
1778 kind,
1779 key,
1780 value,
1781 negate,
1782 });
1783 }
1784 onCharacter(start, end, value) {
1785 const parent = this._node;
1786 if (parent.type !== "Alternative" && parent.type !== "CharacterClass") {
1787 throw new Error("UnknownError");
1788 }
1789 parent.elements.push({
1790 type: "Character",
1791 parent,
1792 start,
1793 end,
1794 raw: this.source.slice(start, end),
1795 value,
1796 });
1797 }
1798 onBackreference(start, end, ref) {
1799 const parent = this._node;
1800 if (parent.type !== "Alternative") {
1801 throw new Error("UnknownError");
1802 }
1803 const node = {
1804 type: "Backreference",
1805 parent,
1806 start,
1807 end,
1808 raw: this.source.slice(start, end),
1809 ref,
1810 resolved: DummyCapturingGroup,
1811 };
1812 parent.elements.push(node);
1813 this._backreferences.push(node);
1814 }
1815 onCharacterClassEnter(start, negate) {
1816 const parent = this._node;
1817 if (parent.type !== "Alternative") {
1818 throw new Error("UnknownError");
1819 }
1820 this._node = {
1821 type: "CharacterClass",
1822 parent,
1823 start,
1824 end: start,
1825 raw: "",
1826 negate,
1827 elements: [],
1828 };
1829 parent.elements.push(this._node);
1830 }
1831 onCharacterClassLeave(start, end) {
1832 const node = this._node;
1833 if (node.type !== "CharacterClass" ||
1834 node.parent.type !== "Alternative") {
1835 throw new Error("UnknownError");
1836 }
1837 node.end = end;
1838 node.raw = this.source.slice(start, end);
1839 this._node = node.parent;
1840 }
1841 onCharacterClassRange(start, end) {
1842 const parent = this._node;
1843 if (parent.type !== "CharacterClass") {
1844 throw new Error("UnknownError");
1845 }
1846 const elements = parent.elements;
1847 const max = elements.pop();
1848 const hyphen = elements.pop();
1849 const min = elements.pop();
1850 if (!min ||
1851 !max ||
1852 !hyphen ||
1853 min.type !== "Character" ||
1854 max.type !== "Character" ||
1855 hyphen.type !== "Character" ||
1856 hyphen.value !== HyphenMinus) {
1857 throw new Error("UnknownError");
1858 }
1859 const node = {
1860 type: "CharacterClassRange",
1861 parent,
1862 start,
1863 end,
1864 raw: this.source.slice(start, end),
1865 min,
1866 max,
1867 };
1868 min.parent = node;
1869 max.parent = node;
1870 elements.push(node);
1871 }
1872}
1873class RegExpParser {
1874 constructor(options) {
1875 this._state = new RegExpParserState(options);
1876 this._validator = new RegExpValidator(this._state);
1877 }
1878 parseLiteral(source, start = 0, end = source.length) {
1879 this._state.source = source;
1880 this._validator.validateLiteral(source, start, end);
1881 const pattern = this._state.pattern;
1882 const flags = this._state.flags;
1883 const literal = {
1884 type: "RegExpLiteral",
1885 parent: null,
1886 start,
1887 end,
1888 raw: source,
1889 pattern,
1890 flags,
1891 };
1892 pattern.parent = literal;
1893 flags.parent = literal;
1894 return literal;
1895 }
1896 parseFlags(source, start = 0, end = source.length) {
1897 this._state.source = source;
1898 this._validator.validateFlags(source, start, end);
1899 return this._state.flags;
1900 }
1901 parsePattern(source, start = 0, end = source.length, uFlag = false) {
1902 this._state.source = source;
1903 this._validator.validatePattern(source, start, end, uFlag);
1904 return this._state.pattern;
1905 }
1906}
1907
1908class RegExpVisitor {
1909 constructor(handlers) {
1910 this._handlers = handlers;
1911 }
1912 visit(node) {
1913 switch (node.type) {
1914 case "Alternative":
1915 this.visitAlternative(node);
1916 break;
1917 case "Assertion":
1918 this.visitAssertion(node);
1919 break;
1920 case "Backreference":
1921 this.visitBackreference(node);
1922 break;
1923 case "CapturingGroup":
1924 this.visitCapturingGroup(node);
1925 break;
1926 case "Character":
1927 this.visitCharacter(node);
1928 break;
1929 case "CharacterClass":
1930 this.visitCharacterClass(node);
1931 break;
1932 case "CharacterClassRange":
1933 this.visitCharacterClassRange(node);
1934 break;
1935 case "CharacterSet":
1936 this.visitCharacterSet(node);
1937 break;
1938 case "Flags":
1939 this.visitFlags(node);
1940 break;
1941 case "Group":
1942 this.visitGroup(node);
1943 break;
1944 case "Pattern":
1945 this.visitPattern(node);
1946 break;
1947 case "Quantifier":
1948 this.visitQuantifier(node);
1949 break;
1950 case "RegExpLiteral":
1951 this.visitRegExpLiteral(node);
1952 break;
1953 default:
1954 throw new Error(`Unknown type: ${node.type}`);
1955 }
1956 }
1957 visitAlternative(node) {
1958 if (this._handlers.onAlternativeEnter) {
1959 this._handlers.onAlternativeEnter(node);
1960 }
1961 node.elements.forEach(this.visit, this);
1962 if (this._handlers.onAlternativeLeave) {
1963 this._handlers.onAlternativeLeave(node);
1964 }
1965 }
1966 visitAssertion(node) {
1967 if (this._handlers.onAssertionEnter) {
1968 this._handlers.onAssertionEnter(node);
1969 }
1970 if (node.kind === "lookahead" || node.kind === "lookbehind") {
1971 node.alternatives.forEach(this.visit, this);
1972 }
1973 if (this._handlers.onAssertionLeave) {
1974 this._handlers.onAssertionLeave(node);
1975 }
1976 }
1977 visitBackreference(node) {
1978 if (this._handlers.onBackreferenceEnter) {
1979 this._handlers.onBackreferenceEnter(node);
1980 }
1981 if (this._handlers.onBackreferenceLeave) {
1982 this._handlers.onBackreferenceLeave(node);
1983 }
1984 }
1985 visitCapturingGroup(node) {
1986 if (this._handlers.onCapturingGroupEnter) {
1987 this._handlers.onCapturingGroupEnter(node);
1988 }
1989 node.alternatives.forEach(this.visit, this);
1990 if (this._handlers.onCapturingGroupLeave) {
1991 this._handlers.onCapturingGroupLeave(node);
1992 }
1993 }
1994 visitCharacter(node) {
1995 if (this._handlers.onCharacterEnter) {
1996 this._handlers.onCharacterEnter(node);
1997 }
1998 if (this._handlers.onCharacterLeave) {
1999 this._handlers.onCharacterLeave(node);
2000 }
2001 }
2002 visitCharacterClass(node) {
2003 if (this._handlers.onCharacterClassEnter) {
2004 this._handlers.onCharacterClassEnter(node);
2005 }
2006 node.elements.forEach(this.visit, this);
2007 if (this._handlers.onCharacterClassLeave) {
2008 this._handlers.onCharacterClassLeave(node);
2009 }
2010 }
2011 visitCharacterClassRange(node) {
2012 if (this._handlers.onCharacterClassRangeEnter) {
2013 this._handlers.onCharacterClassRangeEnter(node);
2014 }
2015 this.visitCharacter(node.min);
2016 this.visitCharacter(node.max);
2017 if (this._handlers.onCharacterClassRangeLeave) {
2018 this._handlers.onCharacterClassRangeLeave(node);
2019 }
2020 }
2021 visitCharacterSet(node) {
2022 if (this._handlers.onCharacterSetEnter) {
2023 this._handlers.onCharacterSetEnter(node);
2024 }
2025 if (this._handlers.onCharacterSetLeave) {
2026 this._handlers.onCharacterSetLeave(node);
2027 }
2028 }
2029 visitFlags(node) {
2030 if (this._handlers.onFlagsEnter) {
2031 this._handlers.onFlagsEnter(node);
2032 }
2033 if (this._handlers.onFlagsLeave) {
2034 this._handlers.onFlagsLeave(node);
2035 }
2036 }
2037 visitGroup(node) {
2038 if (this._handlers.onGroupEnter) {
2039 this._handlers.onGroupEnter(node);
2040 }
2041 node.alternatives.forEach(this.visit, this);
2042 if (this._handlers.onGroupLeave) {
2043 this._handlers.onGroupLeave(node);
2044 }
2045 }
2046 visitPattern(node) {
2047 if (this._handlers.onPatternEnter) {
2048 this._handlers.onPatternEnter(node);
2049 }
2050 node.alternatives.forEach(this.visit, this);
2051 if (this._handlers.onPatternLeave) {
2052 this._handlers.onPatternLeave(node);
2053 }
2054 }
2055 visitQuantifier(node) {
2056 if (this._handlers.onQuantifierEnter) {
2057 this._handlers.onQuantifierEnter(node);
2058 }
2059 this.visit(node.element);
2060 if (this._handlers.onQuantifierLeave) {
2061 this._handlers.onQuantifierLeave(node);
2062 }
2063 }
2064 visitRegExpLiteral(node) {
2065 if (this._handlers.onRegExpLiteralEnter) {
2066 this._handlers.onRegExpLiteralEnter(node);
2067 }
2068 this.visitPattern(node.pattern);
2069 this.visitFlags(node.flags);
2070 if (this._handlers.onRegExpLiteralLeave) {
2071 this._handlers.onRegExpLiteralLeave(node);
2072 }
2073 }
2074}
2075
2076function parseRegExpLiteral(source, options) {
2077 return new RegExpParser(options).parseLiteral(String(source));
2078}
2079function validateRegExpLiteral(source, options) {
2080 return new RegExpValidator(options).validateLiteral(source);
2081}
2082function visitRegExpAST(node, handlers) {
2083 new RegExpVisitor(handlers).visit(node);
2084}
2085
2086export { ast as AST, RegExpParser, RegExpValidator, parseRegExpLiteral, validateRegExpLiteral, visitRegExpAST };
2087//# sourceMappingURL=index.mjs.map