var types = [ "SLASH", "LSB", "RSB", "LCB", "RCB", "COLON", "COMMA", "DOT", "REM", "GT", "GTE", "LT", "LTE", "EQ", "NEQ", "LIKE", "NLIKE", "AND", "OR", "NOT", "ADDRESS", "OID", "OID_LITERAL", "TIME", "TIMEDIFF", "INTEGER_LITERAL", "FLOAT_LITERAL", "BOOL_LITERAL", "ID" ]; var errors = { "-2": "end of search", "-1": "not found any lexemes or errors or anything else", "0": "success", "1": "found unknown symbol", "2": "not found close quote or singleQuote", "3": "Unexpected symbol in oid structure", "4": "Not found close bracket for Oid", }; var Lexer = function(_string){ this._last_found_lexeme = {error: -1}; this._end = false; this._error = false; this._string = _string; this._state = 1; this._yy_char = null; this._yy_lex_start = 0; this._yy_cursor = 0; this._yy_marker = 0; this._yy_accept = 0; }; Lexer.prototype = { types: types, errors: errors, _notFoundCloseQuote: function() { this._error = true; this._last_found_lexeme = { error: 2, start: this._yy_lex_start, end: this._yy_cursor }; console.log( print_f("Not found close quote start: %s", this._yy_cursor)); }, _unknownSymbol: function(){ this._error = true; this._last_found_lexeme = { error: 1, start: this._yy_lex_start, end: this._yy_cursor }; console.log( print_f("Found unknown symbol on position: %s", this._yy_cursor)); }, _oidUnexpectedSymbol: function(){ this._error = true; this._last_found_lexeme = { error: 3, start: this._yy_lex_start, end: this._yy_cursor }; console.log( print_f("Found unknown symbol in Oid on position: %s", this._yy_cursor)); }, _oidNotFoundCloseBracket: function(){ this._error = true; this._last_found_lexeme = { error: 4, start: this._yy_lex_start, end: this._yy_cursor }; console.log( print_f("Not found close bracket for Oid")); }, _foundLexeme: function(_lexeme) { console.log(print_f("found lex: %s; start: %s; end: %s; result => %s", _lexeme, this._yy_lex_start, this._yy_cursor, this._string.substring(this._yy_lex_start, this._yy_cursor))); this._last_found_lexeme = { error: 0, lexeme: _lexeme, value: this._string.substring(this._yy_lex_start, this._yy_cursor), start: this._yy_lex_start, end: this._yy_cursor }; }, _foundOidLexeme: function(_lexeme, _lsb, _rsb) { console.log(print_f("found lex: %s; start: %s; end: %s; result => %s", _lexeme, this._yy_lex_start, this._yy_cursor, this._string.substring(this._yy_lex_start, this._yy_cursor))); this._last_found_lexeme = { error: 0, lexeme: _lexeme, value: this._string.substring(this._yy_lex_start, this._yy_cursor), start: this._yy_lex_start, end: this._yy_cursor, lsb: _lsb, rsb: _rsb }; }, _endOfString: function(){ console.log(print_f("search end\n")); this._end = true; this._last_found_lexeme = { error: -2 }; }, _searchString: function () { var _quote = this._string[this._yy_cursor - 1]; var found_back_slash = false; while(this._yy_cursor < this._string.length){ this._yy_char = this._string[this._yy_cursor]; if(_quote == '"') { switch (this._yy_char) { case "\\": found_back_slash = true; break; case '"': if(!found_back_slash) { this._yy_cursor++; this._foundLexeme("STRING_LITERAL"); return; } found_back_slash = false; break; } } else if(_quote == "'") { switch (this._yy_char) { case "\\": found_back_slash = true; break; case "'": if(!found_back_slash) { this._yy_cursor++; this._foundLexeme("STRING_LITERAL"); return; } found_back_slash = false; break; } } this._yy_cursor++; } this._notFoundCloseQuote(); }, _searchOid: function (){ var lsb, rsb; var state = 0; while(this._yy_cursor < this._string.length){ switch(state){ case 0: this._yy_char = this._string[this._yy_cursor]; (function(){ switch(this._yy_char){ case " ": state = 0; this._yy_cursor++; break; case "[": lsb = {start: this._yy_cursor, end: this._yy_cursor + 1}; state = 1; break; default: state = 5; } }.bind(this))(); break; case 1: this._yy_char = this._string[++this._yy_cursor]; (function(){ switch(this._yy_char){ case " ": state = 1; break; case "0": case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": state = 2; break; case "]": state = 4; break; default: state = 5; } }.bind(this))(); break; case 2: this._yy_char = this._string[++this._yy_cursor]; (function(){ switch(this._yy_char){ case " ": case "0": case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": state = 2; break; case ".": state = 3; break; case "]": state = 4; break; default: state = 5; } }.bind(this))(); break; case 3: this._yy_char = this._string[++this._yy_cursor]; (function(){ switch(this._yy_char){ case " ": case "0": case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": state = 2; break; default: state = 5; } }.bind(this))(); break; case 4: rsb = {start: this._yy_cursor, end: this._yy_cursor + 1}; ++this._yy_cursor; this._foundOidLexeme("OID_LITERAL", lsb, rsb); return; case 5: this._oidUnexpectedSymbol(); return; } } this._oidNotFoundCloseBracket(); }, _set_next: function(){ this._yy_accept = 0; this._state = 1; this._yy_lex_start = this._yy_cursor; this._yy_marker = this._yy_cursor; }, next: function(){ if(this._end || this._error) return null; this.search(); return this.token(); }, token: function(){ return this._last_found_lexeme; }, search: function(){ if(this._end) return false; while(true){ switch(id) { START/*!re2c re2c:define:YYCTYPE = _r2c_var_; re2c:define:YYCURSOR = this._yy_cursor; re2c:define:YYMARKER = this._yy_marker; re2c:yyfill:enable = 0; D = [0-9]; DSEQ = D+; end = "\x00"; L = [A-Za-z_]; CR = "\r"; LF = "\n"; CRLF = CR?LF; INTEGER = "-"?D+; SP = " "; TAB = "\t"; DELIM = SP|TAB|CR|LF; LSB = "["; SLASH = "/"; RSB = "]"; LCB = "("; RCB = ")"; COLON = ":"; COMMA = ","; DOT = "."; REM = "%"; GT = ">"; GTE = ">="; LT = "<"; LTE = "<="; EQ = "=="; NEQ = "!="; AND = 'AND'; OR = 'OR'; NOT = 'NOT'; LIKE = 'LIKE'; NLIKE = 'NLIKE'; ADDRESS = "Address"; TIME = "Time"; OID = "Oid"; TIMEDIFF = "TimeDiff"; ID = L(L|D)*; BOOL_LITERAL = 'true'|'false'; INTEGER_LITERAL = INTEGER; FLOAT_LITERAL = "-"? D* "." D+ ("e" "-"? D+)?; QU = "\""; SQU = "'"; end { this._endOfString(); return; } SLASH { this._foundLexeme("SLASH"); this._set_next(); return; } LSB { this._foundLexeme("LSB"); this._set_next(); return; } RSB { this._foundLexeme("RSB"); this._set_next(); return; } LCB { this._foundLexeme("LCB"); this._set_next(); return; } RCB { this._foundLexeme("RCB"); this._set_next(); return; } COLON { this._foundLexeme("COLON"); this._set_next(); return; } COMMA { this._foundLexeme("COMMA"); this._set_next(); return; } DOT { this._foundLexeme("DOT"); this._set_next(); return; } REM { this._foundLexeme("REM"); this._set_next(); return; } GT { this._foundLexeme("GT"); this._set_next(); return; } GTE { this._foundLexeme("GTE"); this._set_next(); return; } LT { this._foundLexeme("LT"); this._set_next(); return; } LTE { this._foundLexeme("LTE"); this._set_next(); return; } EQ { this._foundLexeme("EQ"); this._set_next(); return; } NEQ { this._foundLexeme("NEQ"); this._set_next(); return; } LIKE { this._foundLexeme("LIKE"); this._set_next(); return; } NLIKE { this._foundLexeme("NLIKE"); this._set_next(); return; } AND { this._foundLexeme("AND"); this._set_next(); return; } OR { this._foundLexeme("OR"); this._set_next(); return; } NOT { this._foundLexeme("NOT"); this._set_next(); return; } ADDRESS { this._foundLexeme("ADDRESS"); this._set_next(); return; } TIME { this._foundLexeme("TIME"); this._set_next(); return; } TIMEDIFF { this._foundLexeme("TIMEDIFF"); this._set_next(); return; } OID { id = 100000001; break; } INTEGER_LITERAL { this._foundLexeme("INTEGER_LITERAL"); this._set_next(); return; } FLOAT_LITERAL { this._foundLexeme("FLOAT_LITERAL"); this._set_next(); return; } BOOL_LITERAL { this._foundLexeme("BOOL_LITERAL"); this._set_next(); return; } ID { this._foundLexeme("ID"); this._set_next(); return; } DELIM { this._set_next(); break; } QU|SQU { id = 100000000; break;} [^] { this._unknownSymbol(); this._set_next(); return; } */END &&STRING case 100000000: this._searchString(); this._set_next(); return; && &&>OID case 100000001: this._searchOid(); this._set_next(); return; && var print_f = function() { var r_str = ""; var next = arguments[0]; var rx = /(%[a-zA-Z]{1})/; var a = 1, match; while (match = rx.exec(next)) { var prev = next.substring(0, match.index); var macro = next.substring(match.index + 1, match.index + 2); next = next.substring(match.index + 2, next.length); r_str += prev; var arg = arguments[a]; if (arg !== undefined) { switch (macro) { case "s": r_str += arg.toString(); break; case "i": r_str += parseInt(arg); break; case "f": r_str += parseFloat(arg); break; } } else { r_str += "%" + macro; } a++; } r_str += next; return r_str; };