| Old Tokenize | export function old_tokenize(txt: string, postfix: boolean = true): Array<string> {
txt = clean(txt)
let infix_tokens: Array<string> = txt.split(QUERY_DELIMITER_PATTERN).map(tkn => tkn.trim()).filter(Boolean)
let i: number = 0
while (i < infix_tokens.length - 1) {
let current_token: string = infix_tokens[i]
let next_token: string = infix_tokens[i + 1]
if ((!(current_token in OPERATORS) && !(next_token in OPERATORS)) ||
(!(current_token in OPERATORS) && next_token === KEYWORDS.open) ||
(!(current_token in OPERATORS) && next_token === KEYWORDS.not) ||
(current_token === KEYWORDS.close && !(next_token in OPERATORS)) ||
(current_token === KEYWORDS.close && next_token === KEYWORDS.open) ||
(current_token === KEYWORDS.close && next_token === KEYWORDS.not))
{
infix_tokens.splice(i + 1, 0, KEYWORDS.and)
}
i++
}
if (!postfix) return infix_tokens
infix_tokens.reverse()
let held_tokens: Array<string> = []
let postfix_tokens: Array<string> = []
while (infix_tokens.length > 0) {
let tkn: string = infix_tokens.pop() as string
if (!(tkn in OPERATORS)) {
postfix_tokens.push(tkn)
continue
}
if (held_tokens.length === 0) {
held_tokens.push(tkn)
continue
} else if ((tkn === KEYWORDS.open) ||
(tkn === KEYWORDS.not && held_tokens.at(-1) === KEYWORDS.not) ||
(OPERATORS[tkn].precedence > OPERATORS[held_tokens.at(-1)!].precedence)) {
held_tokens.push(tkn)
continue
}
while (held_tokens.length > 0) {
if (OPERATORS[tkn].precedence > OPERATORS[held_tokens.at(-1)!].precedence) {
break
} else if (held_tokens.at(-1)! === KEYWORDS.open) {
held_tokens.pop()
break
}
postfix_tokens.push(held_tokens.pop()!)
}
if (tkn !== KEYWORDS.close) {
held_tokens.push(tkn)
}
}
while (held_tokens.length > 0) {
postfix_tokens.push(held_tokens.pop()!)
}
return postfix_tokens
}
| ready |
| New Tokenize | export function tokenize(txt: string = '', postfix: boolean = true): Array<string> {
txt = clean(txt)
let reverse_infix_tokens: Array<string> = txt.split(QUERY_DELIMITER_PATTERN).filter(tkn => !(/\s/.test(tkn))).filter(Boolean).toReversed()
let infix_tokens: Array<string> = []
while (reverse_infix_tokens.length > 0) {
infix_tokens.push(reverse_infix_tokens.pop()!)
if (infix_tokens.length < 2) continue
let second_last_tkn: string = infix_tokens.at(-2)!
let last_tkn: string = infix_tokens.at(-1)!
if ((!(second_last_tkn in OPERATORS) && !(last_tkn in OPERATORS)) ||
(!(second_last_tkn in OPERATORS) && last_tkn === KEYWORDS.open) ||
(!(second_last_tkn in OPERATORS) && last_tkn === KEYWORDS.not) ||
(second_last_tkn === KEYWORDS.close && !(last_tkn in OPERATORS)) ||
(second_last_tkn === KEYWORDS.close && last_tkn === KEYWORDS.open) ||
(second_last_tkn === KEYWORDS.close && last_tkn === KEYWORDS.not))
{
infix_tokens.splice(-1, 0, KEYWORDS.and)
}
}
if (!postfix) return infix_tokens
infix_tokens.reverse()
let held_tokens: Array<string> = []
let postfix_tokens: Array<string> = []
while (infix_tokens.length > 0) {
let tkn: string = infix_tokens.pop()!
if (!(tkn in OPERATORS)) {
postfix_tokens.push(tkn)
continue
}
if (held_tokens.length === 0) {
held_tokens.push(tkn)
continue
} else if ((tkn === KEYWORDS.open) ||
(tkn === KEYWORDS.not && held_tokens.at(-1) === KEYWORDS.not) ||
(OPERATORS[tkn].precedence > OPERATORS[held_tokens.at(-1)!].precedence)) {
held_tokens.push(tkn)
continue
}
while (held_tokens.length > 0) {
if (OPERATORS[tkn].precedence > OPERATORS[held_tokens.at(-1)!].precedence) {
break
} else if (held_tokens.at(-1)! === KEYWORDS.open) {
held_tokens.pop()
break
}
postfix_tokens.push(held_tokens.pop()!)
}
if (tkn !== KEYWORDS.close) {
held_tokens.push(tkn)
}
}
while (held_tokens.length > 0) {
postfix_tokens.push(held_tokens.pop()!)
}
return postfix_tokens
}
| ready |