ast-parser: replace manual char scan in _parseRest with regex tokenizer
This commit is contained in:
@@ -45,47 +45,17 @@ export function parseAstLog(text) {
|
||||
return root;
|
||||
}
|
||||
|
||||
const _REST_TOKEN = /(\w+)='([^']*)'|(\w+)=(\S+)|'([^']*)'|(\S+)/g;
|
||||
|
||||
function _parseRest(rest) {
|
||||
const positionals = [];
|
||||
const props = {};
|
||||
let i = 0;
|
||||
const n = rest.length;
|
||||
let inProps = false;
|
||||
|
||||
while (i < n) {
|
||||
while (i < n && rest[i] === ' ') i++;
|
||||
if (i >= n) break;
|
||||
|
||||
if (rest[i] === "'") {
|
||||
const j = rest.indexOf("'", i + 1);
|
||||
const val = rest.slice(i + 1, j === -1 ? n : j);
|
||||
i = j === -1 ? n : j + 1;
|
||||
if (!inProps) positionals.push(val);
|
||||
} else {
|
||||
let j = i;
|
||||
while (j < n && rest[j] !== ' ') j++;
|
||||
const tok = rest.slice(i, j);
|
||||
i = j;
|
||||
|
||||
const eqIdx = tok.indexOf('=');
|
||||
if (eqIdx !== -1) {
|
||||
inProps = true;
|
||||
const key = tok.slice(0, eqIdx);
|
||||
let rawVal = tok.slice(eqIdx + 1);
|
||||
|
||||
if (rawVal.startsWith("'")) {
|
||||
const valStart = i - (tok.length - eqIdx - 1);
|
||||
const openPos = rest.indexOf("'", rest.lastIndexOf(key + '=', i) + key.length + 1);
|
||||
const closePos = rest.indexOf("'", openPos + 1);
|
||||
rawVal = closePos === -1 ? rest.slice(openPos + 1) : rest.slice(openPos + 1, closePos);
|
||||
i = closePos === -1 ? n : closePos + 1;
|
||||
}
|
||||
|
||||
props[key] = coerce(rawVal);
|
||||
} else if (!inProps) {
|
||||
positionals.push(coerce(tok));
|
||||
}
|
||||
}
|
||||
for (const [, kq, vq, kb, vb, qpos, bpos] of rest.matchAll(_REST_TOKEN)) {
|
||||
if (kq !== undefined) { inProps = true; props[kq] = coerce(vq); }
|
||||
else if (kb !== undefined) { inProps = true; props[kb] = coerce(vb); }
|
||||
else if (!inProps) { positionals.push(coerce(qpos ?? bpos)); }
|
||||
}
|
||||
|
||||
return { positionals, props };
|
||||
|
||||
Reference in New Issue
Block a user