/
regexp.ts
215 lines (211 loc) · 10.2 KB
/
regexp.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
import * as t from 'assert';
import { Context } from '../../src/common';
import { Token } from '../../src/token';
import { create } from '../../src/parser';
import { scanSingleToken } from '../../src/lexer/scan';
describe('Lexer - Regular expressions', () => {
const tokens: [Context, string, string, string][] = [
// None unicode regular expression
[Context.AllowRegExp, '/\\\n/', '\\\n', ''],
[Context.AllowRegExp, '/a|b/', 'a|b', ''],
[Context.AllowRegExp, '/a|b/', 'a|b', ''],
[Context.AllowRegExp, '/a|b/', 'a|b', ''],
[Context.AllowRegExp, '/abc$/', 'abc$', ''],
[Context.AllowRegExp, '/a*?/', 'a*?', ''],
[Context.AllowRegExp, '/$/', '$', ''],
[Context.AllowRegExp, '/(a)\\1/', '(a)\\1', ''],
[Context.AllowRegExp, '/[abc-]/', '[abc-]', ''],
[Context.AllowRegExp, '/a*?/', 'a*?', ''],
[Context.AllowRegExp, '/a*?/', 'a*?', ''],
[Context.AllowRegExp, '/[a-z]+/', '[a-z]+', ''],
[Context.AllowRegExp, '/[0-9]+/', '[0-9]+', ''],
[Context.AllowRegExp, '/ +/', ' +', ''],
[Context.AllowRegExp, '/[0-9]+.[0-9]+/', '[0-9]+.[0-9]+', ''],
[
Context.AllowRegExp,
'/^-?(?:[0-9]|[1-9][0-9]+)(?:.[0-9]+)?(?:[eE][-+]?[0-9]+)?\b/',
'^-?(?:[0-9]|[1-9][0-9]+)(?:.[0-9]+)?(?:[eE][-+]?[0-9]+)?\b',
''
],
[Context.AllowRegExp, '/^{/', '^{', ''],
[Context.AllowRegExp, '/^}/', '^}', ''],
[Context.AllowRegExp, '/^true\b/', '^true\b', ''],
[Context.AllowRegExp, '/^null\b/', '^null\b', ''],
[Context.AllowRegExp, '/a*?/g', 'a*?', 'g'],
[Context.AllowRegExp, '/a?/', 'a?', ''],
[Context.AllowRegExp, '/a+/', 'a+', ''],
[Context.AllowRegExp, '/a+b/', 'a+b', ''],
[Context.AllowRegExp, '/a??/', 'a??', ''],
[Context.AllowRegExp, '/a{0}/', 'a{0}', ''],
[Context.AllowRegExp, '/a{5}/', 'a{5}', ''],
[Context.AllowRegExp, '/a{12}/', 'a{12}', ''],
[Context.AllowRegExp, '/a{2,}/', 'a{2,}', ''],
[Context.AllowRegExp, '/a{56}/', 'a{56}', ''],
[Context.AllowRegExp, '/a{7,7}/', 'a{7,7}', ''],
[Context.AllowRegExp, '/a{9,94}/', 'a{9,94}', ''],
[Context.AllowRegExp, '/a{6,61}/', 'a{6,61}', ''],
[Context.AllowRegExp, '/a{3,38}/', 'a{3,38}', ''],
[Context.AllowRegExp, '/a{23,37}/', 'a{23,37}', ''],
[Context.AllowRegExp, '/a{56,60}/', 'a{56,60}', ''],
[Context.AllowRegExp, '/a{,2}/', 'a{,2}', ''],
[Context.AllowRegExp, '/a{,61}/', 'a{,61}', ''],
[Context.AllowRegExp, '/foo/gy', 'foo', 'gy'],
[Context.AllowRegExp, '/foo/igy', 'foo', 'igy'],
[Context.AllowRegExp, '/\\D/', '\\D', ''],
[Context.AllowRegExp, '/\\r/', '\\r', ''],
[Context.AllowRegExp, '/\\s/', '\\s', ''],
[Context.AllowRegExp, '/\\v/', '\\v', ''],
[Context.AllowRegExp, '/\\S/', '\\S', ''],
[Context.AllowRegExp, '/\\W/', '\\W', ''],
[Context.AllowRegExp, '/\\w/', '\\w', ''],
[Context.AllowRegExp, '/\\t/', '\\t', ''],
[Context.AllowRegExp, '/\\n/', '\\n', ''],
[Context.AllowRegExp, '/\\f/', '\\f', ''],
[Context.AllowRegExp, '/\\d/', '\\d', ''],
[Context.AllowRegExp, '/abc\\D/', 'abc\\D', ''],
[Context.AllowRegExp, '/abc\\n/', 'abc\\n', ''],
[Context.AllowRegExp, '/abc\\S/', 'abc\\S', ''],
[Context.AllowRegExp, '/\\fabcd/', '\\fabcd', ''],
[Context.AllowRegExp, '/\\Dabcd/', '\\Dabcd', ''],
[Context.AllowRegExp, '/\\Sabcd/', '\\Sabcd', ''],
[Context.AllowRegExp, '/\\wabcd/', '\\wabcd', ''],
[Context.AllowRegExp, '/\\Wabcd/', '\\Wabcd', ''],
[Context.AllowRegExp, '/abc\\sdeff/', 'abc\\sdeff', ''],
[Context.AllowRegExp, '/abc\\ddeff/', 'abc\\ddeff', ''],
[Context.AllowRegExp, '/abc\\Wdeff/', 'abc\\Wdeff', ''],
[Context.AllowRegExp, '/\\$abcd/', '\\$abcd', ''],
[Context.AllowRegExp, '/abc\\$abcd/', 'abc\\$abcd', ''],
[Context.AllowRegExp, '/\\./', '\\.', ''],
[Context.AllowRegExp, '/\\*/', '\\*', ''],
[Context.AllowRegExp, '/\\+/', '\\+', ''],
[Context.AllowRegExp, '/\\?/', '\\?', ''],
[Context.AllowRegExp, '/\\(/', '\\(', ''],
[Context.AllowRegExp, '/\\[/', '\\[', ''],
[Context.AllowRegExp, '/\\)/', '\\)', ''],
[Context.AllowRegExp, '/\\|/', '\\|', ''],
[Context.AllowRegExp, '/\\}/', '\\}', ''],
[Context.AllowRegExp, '/abc\\\\/', 'abc\\\\', ''],
[Context.AllowRegExp, '/abc\\(/', 'abc\\(', ''],
[Context.AllowRegExp, '/\\.def/', '\\.def', ''],
[Context.AllowRegExp, '/\\`/', '\\`', ''],
[Context.AllowRegExp, '/a|(|)/', 'a|(|)', ''],
[Context.AllowRegExp, '/\\cv/', '\\cv', ''],
[Context.AllowRegExp, '/\\cj/', '\\cj', ''],
[
Context.AllowRegExp,
'/(((((((((((((((((((((a)))))))))))))))))))))\\20/',
'(((((((((((((((((((((a)))))))))))))))))))))\\20',
''
],
[Context.AllowRegExp, '/x\\ud810\\ud810/', 'x\\ud810\\ud810', ''],
[Context.AllowRegExp, '/x\\udabcy/', 'x\\udabcy', ''],
[Context.AllowRegExp, '/\\udd00\\udd00y/', '\\udd00\\udd00y', ''],
[Context.AllowRegExp, '/\\ud900\\udd00\\ud900y/', '\\ud900\\udd00\\ud900y', ''],
[Context.AllowRegExp, '/[\\ufdd0-\\ufdef]/', '[\\ufdd0-\\ufdef]', ''],
[Context.AllowRegExp, '/[\\u{FDD0}-\\u{FDEF}]/u', '[\\u{FDD0}-\\u{FDEF}]', 'u'],
[Context.AllowRegExp, '/[i]/', '[i]', ''],
[Context.AllowRegExp, '/[j]/', '[j]', ''],
[Context.AllowRegExp, '/[s]/', '[s]', ''],
[Context.AllowRegExp, '/[x]/', '[x]', ''],
[Context.AllowRegExp, '/[Q]/', '[Q]', ''],
[Context.AllowRegExp, '/[-]/', '[-]', ''],
[Context.AllowRegExp, '/[^-J]/g', '[^-J]', 'g'],
[Context.AllowRegExp, '/[abc\\D]/', '[abc\\D]', ''],
[Context.AllowRegExp, '/[\\dabcd]/', '[\\dabcd]', ''],
[Context.AllowRegExp | Context.OptionsRaw, '/[\\$]/', '[\\$]', ''],
[Context.AllowRegExp, '/[abc\\$]/', '[abc\\$]', ''],
[Context.AllowRegExp, '/[\\?def]/', '[\\?def]', ''],
[Context.AllowRegExp, '/[\\cT]/', '[\\cT]', ''],
[Context.AllowRegExp, '/[\\xc3]/', '[\\xc3]', ''],
[Context.AllowRegExp, '/[\\ud800\\ud800\\udc00]/', '[\\ud800\\ud800\\udc00]', ''],
[Context.AllowRegExp, '/[x\\da-z]/', '[x\\da-z]', ''],
[Context.AllowRegExp, '/[x\\SA-S]/', '[x\\SA-S]', ''],
[Context.AllowRegExp, '/[A-Z\\D]/', '[A-Z\\D]', ''],
[Context.AllowRegExp, '/[\\u5000-\\u6000]/', '[\\u5000-\\u6000]', ''],
[Context.AllowRegExp, '/[--0]/', '[--0]', ''],
[Context.AllowRegExp, '/a(?:a(?:b)c)c/', 'a(?:a(?:b)c)c', ''],
[Context.AllowRegExp, '/(?=(?=b)c)c/', '(?=(?=b)c)c', ''],
[Context.AllowRegExp, '/(?=a(?=b)c)/', '(?=a(?=b)c)', ''],
[Context.AllowRegExp, '/a(?=a(?=b)c)/', 'a(?=a(?=b)c)', ''],
[Context.AllowRegExp, '/a(?=a(?=b)c)/', 'a(?=a(?=b)c)', ''],
[Context.AllowRegExp, '/a(?!a(?!b)c)c/', 'a(?!a(?!b)c)c', ''],
[Context.AllowRegExp, '/a(?!b(?!c)d)e/', 'a(?!b(?!c)d)e', ''],
[Context.AllowRegExp, '/[^a-z]{4}/', '[^a-z]{4}', ''],
[Context.AllowRegExp, '/1?1/mig', '1?1', 'mig'],
[Context.AllowRegExp, '/.*/sm', '.*', 'sm'],
[Context.AllowRegExp, '/.*/ms', '.*', 'ms'],
[Context.AllowRegExp, '/.*/sy', '.*', 'sy'],
[Context.AllowRegExp, '/.*/ys', '.*', 'ys'],
[Context.AllowRegExp, '/.*/s', '.*', 's'],
[Context.AllowRegExp, '/.*/m', '.*', 'm'],
[Context.AllowRegExp, '/.*/y', '.*', 'y'],
[Context.AllowRegExp, '/\\%([0-9]*)\\[(\\^)?(\\]?[^\\]]*)\\]/', '\\%([0-9]*)\\[(\\^)?(\\]?[^\\]]*)\\]', '']
];
for (const [ctx, op, value, flags] of tokens) {
it(`scans '${op}' at the end`, () => {
const state = create(op, '', undefined);
const found = scanSingleToken(state, ctx, 0);
t.deepEqual(
{
token: found,
hasNext: state.index < state.source.length,
value: (state.tokenRegExp as any).pattern,
flags: (state.tokenRegExp as any).flags
},
{
token: Token.RegularExpression,
hasNext: false,
value,
flags
}
);
});
}
function fail(name: string, source: string, context: Context) {
it(name, () => {
const state = create(source, '', undefined);
t.throws(() => scanSingleToken(state, context, 0));
});
}
fail('fails on /i/ii', '/ ', Context.AllowRegExp);
fail('fails on /i/ii', '/\n$/\n', Context.AllowRegExp);
fail('fails on /i/ii', '/\r$/\n', Context.AllowRegExp);
fail('fails on /i/ii', '/\u2028$/\n', Context.AllowRegExp);
fail('fails on /i/ii', '/\u2029$/\n', Context.AllowRegExp);
fail('fails on /i/ii', '/\u2028$/\n', Context.AllowRegExp);
fail('fails on /i/ii', '/$\r/', Context.AllowRegExp);
fail('fails on /i/ii', '/$\u2028/', Context.AllowRegExp);
fail('fails on /i/ii', '/$\u2029/', Context.AllowRegExp);
fail('fails on /i/ii', '/i/igui', Context.AllowRegExp);
fail('fails on /i/ii', '/i/mmgui', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ggui', Context.AllowRegExp);
fail('fails on /i/ii', '/i/guui', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /\\B*/u', '/\\B*/u', Context.AllowRegExp);
fail('fails on \\b+/u', '\\b+/u', Context.AllowRegExp);
fail('fails on /[d-G\\r]/', '/[d-G\\r]/', Context.AllowRegExp);
fail('fails on /[d-G\\r/', '/[d-G\\r/', Context.AllowRegExp);
fail('fails on /]', '/]', Context.AllowRegExp);
fail('fails on /x{1,}{1}/', '/x{1,}{1}/', Context.AllowRegExp);
fail('fails on /{1,}/', '/{1,}/', Context.AllowRegExp);
fail('fails on /x{1,}{1}/', '/x{1,}{1}/', Context.AllowRegExp);
fail('fails on /a(?=b(?!cde/', '/a(?=b(?!cde/', Context.AllowRegExp);
fail('fails on /a(', '/(', Context.AllowRegExp);
fail('fails on /(?=b(?!cde/', '/(?=b(?!cde/', Context.AllowRegExp);
fail('fails on /[abc\\udeff', '/[abc\\udeff', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/yy', Context.AllowRegExp);
fail('fails on /i/ii', '/i/ss', Context.AllowRegExp);
fail('fails on /i/ii', '/i/፰', Context.AllowRegExp);
});