mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
51 lines
1.2 KiB
TypeScript
51 lines
1.2 KiB
TypeScript
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;
|
|
}
|