-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathcompiler.ts
54 lines (44 loc) · 1.36 KB
/
compiler.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
import type { RegexElement } from './types';
import { characterClasses, isCharacterClass } from './character-classes';
import { baseQuantifiers, isBaseQuantifier } from './quantifiers/base';
import { compileRepeat } from './quantifiers/repeat';
/**
* Generate RegExp object for elements.
*
* @param elements
* @returns
*/
export function buildRegex(...elements: RegexElement[]): RegExp {
const pattern = compileList(elements);
return new RegExp(pattern);
}
/**
* Generate regex pattern for elements.
* @param elements
* @returns
*/
export function buildPattern(...elements: RegexElement[]): string {
return compileList(elements);
}
// Recursive compilation
function compileList(elements: RegexElement[]): string {
return elements.map((c) => compileSingle(c)).join('');
}
function compileSingle(element: RegexElement): string {
if (typeof element === 'string') {
return element;
}
if (isCharacterClass(element)) {
return characterClasses[element.type];
}
const compiledChildren = compileList(element.children);
if (element.type === 'repeat') {
return compileRepeat(element.config, compiledChildren);
}
if (isBaseQuantifier(element)) {
const compiler = baseQuantifiers[element.type];
return compiler(compiledChildren);
}
// @ts-expect-error User passed incorrect type
throw new Error(`Unknown elements type ${element.type}`);
}