1export const parse = (quasis, expressions) => {
2 let quasiIndex = 0;
3 let stackIndex = 0;
4
5 const sequenceStack = [];
6 const rootSequence = [];
7
8 let currentGroup = null;
9 let lastMatch;
10 let currentSequence = rootSequence;
11
12 while (stackIndex < quasis.length + expressions.length) {
13 if (stackIndex % 2 !== 0) {
14 currentSequence.push({
15 expression: expressions[stackIndex++ >> 1],
16 });
17 }
18
19 const quasi = quasis[stackIndex >> 1];
20 while (quasiIndex < quasi.length) {
21 const char = quasi[quasiIndex++];
22
23 if (char === ' ' || char === '\t' || char === '\r' || char === '\n') {
24 continue;
25 } else if (char === '|' && currentSequence.length) {
26 currentSequence = currentSequence.alternation = [];
27 continue;
28 } else if (char === ')' && currentSequence.length) {
29 currentGroup = null;
30 currentSequence = sequenceStack.pop();
31 if (currentSequence) continue;
32 } else if (char === '(') {
33 currentGroup = {
34 sequence: [],
35 };
36
37 sequenceStack.push(currentSequence);
38 currentSequence.push(currentGroup);
39 currentSequence = currentGroup.sequence;
40 continue;
41 } else if (char === '?' && !currentSequence.length && currentGroup) {
42 const nextChar = quasi[quasiIndex++];
43 if (nextChar === ':') {
44 currentGroup.capture = nextChar;
45 continue;
46 } else if (nextChar === '=') {
47 currentGroup.capture = nextChar;
48 continue;
49 } else if (nextChar === '!') {
50 currentGroup.capture = nextChar;
51 continue;
52 }
53 } else if (
54 (char === '?' || char === '+' || char === '*') &&
55 (lastMatch = currentSequence[currentSequence.length - 1])
56 ) {
57 lastMatch.quantifier = char;
58 continue;
59 }
60
61 throw new SyntaxError('Unexpected token "' + char + '"');
62 }
63
64 stackIndex++;
65 quasiIndex = 0;
66 }
67
68 return rootSequence;
69};