mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-24 04:27:59 +01:00
3590be1429
* match_query: unit test and rewrite for TypeScript * match_query: use new type for parse errors * match_query: avoid exceptional control flow in date parsing
52 lines
1.1 KiB
TypeScript
52 lines
1.1 KiB
TypeScript
import { matchAll, matchAny, matchNone, matchNot } from './boolean';
|
|
import { AstMatcher, ParseError, TokenList } from './types';
|
|
|
|
export function parseTokens(lexicalArray: TokenList): AstMatcher {
|
|
const operandStack: AstMatcher[] = [];
|
|
|
|
lexicalArray.forEach((token, i) => {
|
|
if (token === 'not_op') {
|
|
return;
|
|
}
|
|
|
|
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;
|
|
}
|