Skip to content

Instantly share code, notes, and snippets.

@conartist6
Last active March 20, 2022 21:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save conartist6/4c96563aa8bed207a2518f97f81410cf to your computer and use it in GitHub Desktop.
Save conartist6/4c96563aa8bed207a2518f97f81410cf to your computer and use it in GitHub Desktop.
No-lib json tokenizer
const t = {
token: (value) => ({ type: 'token', value }),
literal: (value) => ({ type: 'literal', value }),
};
const escapes = {
'"': '"',
'\\': '\\',
b: '\b',
f: '\f',
n: '\n',
r: '\r',
t: '\t',
};
export function* tokenize (input) {
let state = 'base';
let escaped = false;
let literal = '';
for (const char of input) {
if (state === 'base') {
if (char === '"') {
state = 'string';
} else if ('{}[]:,'.includes(char)) {
yield t.token(char);
} else {
throw new SyntaxError();
}
} else if (state === 'string') {
if (escaped) {
if (escapes.hasOwnProperty(char)) {
literal += escapes[char];
} else if (char === 'u') {
// TODO handle unicode escapes : (
} else {
literal += char;
}
escaped = false;
} else if (char === '\\') {
escaped = true;
} else if (char === '"') {
yield t.literal(literal);
literal = '';
state = 'base';
} else {
literal += char;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment