UNPKG

falcor-path-syntax

Version:
153 lines (131 loc) 3.67 kB
var TokenTypes = require('./../TokenTypes'); var DOT_SEPARATOR = '.'; var COMMA_SEPARATOR = ','; var OPENING_BRACKET = '['; var CLOSING_BRACKET = ']'; var OPENING_BRACE = '{'; var CLOSING_BRACE = '}'; var COLON = ':'; var ESCAPE = '\\'; var DOUBLE_OUOTES = '"'; var SINGE_OUOTES = "'"; var SPACE = " "; var SPECIAL_CHARACTERS = '\\\'"[]., '; var EXT_SPECIAL_CHARACTERS = '\\{}\'"[]., :'; var Tokenizer = module.exports = function(string, ext) { this._string = string; this._idx = -1; this._extended = ext; this.parseString = ''; }; Tokenizer.prototype = { /** * grabs the next token either from the peek operation or generates the * next token. */ next: function() { var nextToken = this._nextToken ? this._nextToken : getNext(this._string, this._idx, this._extended); this._idx = nextToken.idx; this._nextToken = false; this.parseString += nextToken.token.token; return nextToken.token; }, /** * will peak but not increment the tokenizer */ peek: function() { var nextToken = this._nextToken ? this._nextToken : getNext(this._string, this._idx, this._extended); this._nextToken = nextToken; return nextToken.token; } }; Tokenizer.toNumber = function toNumber(x) { if (!isNaN(+x)) { return +x; } return NaN; }; function toOutput(token, type, done) { return { token: token, done: done, type: type }; } function getNext(string, idx, ext) { var output = false; var token = ''; var specialChars = ext ? EXT_SPECIAL_CHARACTERS : SPECIAL_CHARACTERS; var done; do { done = idx + 1 >= string.length; if (done) { break; } // we have to peek at the next token var character = string[idx + 1]; if (character !== undefined && specialChars.indexOf(character) === -1) { token += character; ++idx; continue; } // The token to delimiting character transition. else if (token.length) { break; } ++idx; var type; switch (character) { case DOT_SEPARATOR: type = TokenTypes.dotSeparator; break; case COMMA_SEPARATOR: type = TokenTypes.commaSeparator; break; case OPENING_BRACKET: type = TokenTypes.openingBracket; break; case CLOSING_BRACKET: type = TokenTypes.closingBracket; break; case OPENING_BRACE: type = TokenTypes.openingBrace; break; case CLOSING_BRACE: type = TokenTypes.closingBrace; break; case SPACE: type = TokenTypes.space; break; case DOUBLE_OUOTES: case SINGE_OUOTES: type = TokenTypes.quote; break; case ESCAPE: type = TokenTypes.escape; break; case COLON: type = TokenTypes.colon; break; default: type = TokenTypes.unknown; break; } output = toOutput(character, type, false); break; } while (!done); if (!output && token.length) { output = toOutput(token, TokenTypes.token, false); } if (!output) { output = {done: true}; } return { token: output, idx: idx }; }