| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- const tokenize = (input) => {
- let current = 0;
- let tokens = [];
- while (current < input.length) {
- let char = input[current];
- if (char === '\\') {
- current++;
- continue;
- }
- if (char === '{') {
- tokens.push({
- type: 'brace',
- value: '{',
- });
- current++;
- continue;
- }
- if (char === '}') {
- tokens.push({
- type: 'brace',
- value: '}',
- });
- current++;
- continue;
- }
- if (char === '[') {
- tokens.push({
- type: 'paren',
- value: '[',
- });
- current++;
- continue;
- }
- if (char === ']') {
- tokens.push({
- type: 'paren',
- value: ']',
- });
- current++;
- continue;
- }
- if (char === ':') {
- tokens.push({
- type: 'separator',
- value: ':',
- });
- current++;
- continue;
- }
- if (char === ',') {
- tokens.push({
- type: 'delimiter',
- value: ',',
- });
- current++;
- continue;
- }
- if (char === '"') {
- let value = '';
- let danglingQuote = false;
- char = input[++current];
- while (char !== '"') {
- if (current === input.length) {
- danglingQuote = true;
- break;
- }
- if (char === '\\') {
- current++;
- if (current === input.length) {
- danglingQuote = true;
- break;
- }
- value += char + input[current];
- char = input[++current];
- }
- else {
- value += char;
- char = input[++current];
- }
- }
- char = input[++current];
- if (!danglingQuote) {
- tokens.push({
- type: 'string',
- value,
- });
- }
- continue;
- }
- let WHITESPACE = /\s/;
- if (char && WHITESPACE.test(char)) {
- current++;
- continue;
- }
- let NUMBERS = /[0-9]/;
- if ((char && NUMBERS.test(char)) || char === '-' || char === '.') {
- let value = '';
- if (char === '-') {
- value += char;
- char = input[++current];
- }
- while ((char && NUMBERS.test(char)) || char === '.') {
- value += char;
- char = input[++current];
- }
- tokens.push({
- type: 'number',
- value,
- });
- continue;
- }
- let LETTERS = /[a-z]/i;
- if (char && LETTERS.test(char)) {
- let value = '';
- while (char && LETTERS.test(char)) {
- if (current === input.length) {
- break;
- }
- value += char;
- char = input[++current];
- }
- if (value == 'true' || value == 'false' || value === 'null') {
- tokens.push({
- type: 'name',
- value,
- });
- }
- else {
- // unknown token, e.g. `nul` which isn't quite `null`
- current++;
- continue;
- }
- continue;
- }
- current++;
- }
- return tokens;
- }, strip = (tokens) => {
- if (tokens.length === 0) {
- return tokens;
- }
- let lastToken = tokens[tokens.length - 1];
- switch (lastToken.type) {
- case 'separator':
- tokens = tokens.slice(0, tokens.length - 1);
- return strip(tokens);
- break;
- case 'number':
- let lastCharacterOfLastToken = lastToken.value[lastToken.value.length - 1];
- if (lastCharacterOfLastToken === '.' || lastCharacterOfLastToken === '-') {
- tokens = tokens.slice(0, tokens.length - 1);
- return strip(tokens);
- }
- case 'string':
- let tokenBeforeTheLastToken = tokens[tokens.length - 2];
- if (tokenBeforeTheLastToken?.type === 'delimiter') {
- tokens = tokens.slice(0, tokens.length - 1);
- return strip(tokens);
- }
- else if (tokenBeforeTheLastToken?.type === 'brace' && tokenBeforeTheLastToken.value === '{') {
- tokens = tokens.slice(0, tokens.length - 1);
- return strip(tokens);
- }
- break;
- case 'delimiter':
- tokens = tokens.slice(0, tokens.length - 1);
- return strip(tokens);
- break;
- }
- return tokens;
- }, unstrip = (tokens) => {
- let tail = [];
- tokens.map((token) => {
- if (token.type === 'brace') {
- if (token.value === '{') {
- tail.push('}');
- }
- else {
- tail.splice(tail.lastIndexOf('}'), 1);
- }
- }
- if (token.type === 'paren') {
- if (token.value === '[') {
- tail.push(']');
- }
- else {
- tail.splice(tail.lastIndexOf(']'), 1);
- }
- }
- });
- if (tail.length > 0) {
- tail.reverse().map((item) => {
- if (item === '}') {
- tokens.push({
- type: 'brace',
- value: '}',
- });
- }
- else if (item === ']') {
- tokens.push({
- type: 'paren',
- value: ']',
- });
- }
- });
- }
- return tokens;
- }, generate = (tokens) => {
- let output = '';
- tokens.map((token) => {
- switch (token.type) {
- case 'string':
- output += '"' + token.value + '"';
- break;
- default:
- output += token.value;
- break;
- }
- });
- return output;
- }, partialParse = (input) => JSON.parse(generate(unstrip(strip(tokenize(input)))));
- export { partialParse };
- //# sourceMappingURL=parser.mjs.map
|