mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-15 20:30:39 -07:00
51 lines
1.3 KiB
TypeScript
51 lines
1.3 KiB
TypeScript
const rBlank = /\s/
|
|
const rPunctuation = /[<>=!]/
|
|
|
|
enum ParseState {
|
|
INIT = 1,
|
|
SINGLE_QUOTE = 2,
|
|
DOUBLE_QUOTE = 4,
|
|
QUOTE = 6,
|
|
BRACKET = 8
|
|
}
|
|
|
|
export function * tokenize (expr: string): IterableIterator<string> {
|
|
const N = expr.length
|
|
const stack = [ParseState.INIT]
|
|
let str = ''
|
|
let lastIsPunc = false
|
|
|
|
for (let i = 0; i < N; i++) {
|
|
const c = expr[i]
|
|
const top = stack[stack.length - 1]
|
|
const isPunc = rPunctuation.test(c)
|
|
if (c === '\\') {
|
|
str += expr.substr(i++, 2)
|
|
} else if (top === ParseState.SINGLE_QUOTE && c === "'") {
|
|
str += c
|
|
stack.pop()
|
|
} else if (top === ParseState.DOUBLE_QUOTE && c === '"') {
|
|
str += c
|
|
stack.pop()
|
|
} else if (ParseState.QUOTE & top) {
|
|
str += c
|
|
} else if (top === ParseState.BRACKET && c === ']') {
|
|
str += c
|
|
stack.pop()
|
|
} else if (top === ParseState.INIT && rBlank.exec(c)) {
|
|
if (str) yield str
|
|
str = ''
|
|
} else if (top === ParseState.INIT && isPunc !== lastIsPunc) {
|
|
if (str) yield str
|
|
str = c
|
|
} else {
|
|
if (c === '"') stack.push(ParseState.DOUBLE_QUOTE)
|
|
else if (c === "'") stack.push(ParseState.SINGLE_QUOTE)
|
|
else if (c === '[') stack.push(ParseState.BRACKET)
|
|
str += c
|
|
}
|
|
lastIsPunc = isPunc
|
|
}
|
|
if (str) yield str
|
|
}
|