Mirror: The magical sticky regex-based parser generator 馃
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};