import { matchAll, matchAny, matchNone, matchNot } from './boolean'; import { AstMatcher, ParseError, TokenList } from './types'; export function parseTokens(lexicalArray: TokenList): AstMatcher { const operandStack: AstMatcher[] = []; for (let i = 0; i < lexicalArray.length; i += 1) { const token = lexicalArray[i]; if (token === 'not_op') { continue; } let intermediate: AstMatcher; if (typeof token === 'string') { const op2 = operandStack.pop(); const op1 = operandStack.pop(); if (typeof op1 === 'undefined' || typeof op2 === 'undefined') { throw new ParseError('Missing operand.'); } if (token === 'and_op') { intermediate = matchAll(op1, op2); } else { intermediate = matchAny(op1, op2); } } else { intermediate = token; } if (lexicalArray[i + 1] === 'not_op') { operandStack.push(matchNot(intermediate)); } else { operandStack.push(intermediate); } } if (operandStack.length > 1) { throw new ParseError('Missing operator.'); } const op1 = operandStack.pop(); if (typeof op1 === 'undefined') { return matchNone(); } return op1; }