private void decipher_unquoted_state() { string curupper = cur.ToUpper(); foreach (string word in sqlkeywords) if (curupper == word) { curstate = VxSqlToken.TokenType.Keyword; break; } }
public void tokenize(string q) { last = null; tokens = new List<VxSqlToken>(); reset_state(); for (int i = 0; i < q.Length; ++i) { char c = q[i]; char peek = i < q.Length - 1 ? q[i + 1] : '\0'; switch (curstate) { case VxSqlToken.TokenType.None: VxSqlToken.TokenType singletoken_state = get_singletoken_state(c); if (isalpha(c) || c == '_' || c == '@' || c == '#') { curstate = VxSqlToken.TokenType.Unquoted; cur += c; if (!isidentifierchar(peek)) { decipher_unquoted_state(); save_and_reset_state(); } } else if (c == '\'') curstate = VxSqlToken.TokenType.SingleQuoted; else if (c == '"') curstate = VxSqlToken.TokenType.DoubleQuoted; else if (c == '[') curstate = VxSqlToken.TokenType.Delimited; else if (c == '-' && peek == '-') { ++i; curstate = VxSqlToken.TokenType.Comment; } else if (c == '/' && peek == '*') { ++i; curstate = VxSqlToken.TokenType.DelimitedComment; } else if (isdigit(c)) { curstate = VxSqlToken.TokenType.Numeric; cur += c; if (!isnumericchar(peek)) save_and_reset_state(); } else if (c == '.' && isdigit(peek)) { curstate = VxSqlToken.TokenType.Numeric; cur += c; } else if (singletoken_state != VxSqlToken.TokenType.None) { cur += c; curstate = singletoken_state; save_and_reset_state(); } else if (!isspace(c)) { cur += c; curstate = VxSqlToken.TokenType.ERROR_UNKNOWN; save_and_reset_state(); } else //whitespace curspace += c; break; case VxSqlToken.TokenType.Unquoted: cur += c; if (!isidentifierchar(peek)) { decipher_unquoted_state(); save_and_reset_state(); } break; case VxSqlToken.TokenType.SingleQuoted: if (c == '\'') { if (peek == '\'') { cur += "''"; ++i; } else save_and_reset_state(); } else cur += c; break; case VxSqlToken.TokenType.DoubleQuoted: if (c == '"') { if (peek == '"') { cur += "\"\""; ++i; } else save_and_reset_state(); } else cur += c; break; case VxSqlToken.TokenType.Delimited: if (c == ']') save_and_reset_state(); else cur += c; break; case VxSqlToken.TokenType.Comment: // NOTE: In T-Sql, a 'GO' command within a comment generates an // error, but our tokenizer doesn't need to care about this. if (c == '\n') { save_and_reset_state(); curspace += c; } else cur += c; break; case VxSqlToken.TokenType.DelimitedComment: // NOTE: In T-Sql, a 'GO' command within a comment generates an // error, but our tokenizer doesn't need to care about this. if (c == '*' && peek == '/') { ++i; save_and_reset_state(); } else cur += c; break; case VxSqlToken.TokenType.Numeric: if (c == 'E' || c == 'e') { curstate = VxSqlToken.TokenType.Scientific; cur += 'e'; if (peek == '-' || peek == '+') { ++i; cur += peek; } else if (!isdigit(peek)) { curstate = VxSqlToken.TokenType.Numeric; save_and_reset_state(); } } else { cur += c; if (!isnumericchar(peek)) save_and_reset_state(); } break; case VxSqlToken.TokenType.Scientific: cur += c; if (!isdigit(peek)) { curstate = VxSqlToken.TokenType.Numeric; save_and_reset_state(); } break; default: break; } } if (curstate != VxSqlToken.TokenType.None) save_and_reset_state(); if (curspace != "") { if (last != null) last.trailing_space = curspace; else { last = new VxSqlToken(VxSqlToken.TokenType.None, "", curspace); tokens.Add(last); } } /* Console.WriteLine("GOT A REQUEST FROM VERSAPLEX:"); Console.WriteLine("Original Query: {0}", q); Console.WriteLine("Broken down:"); foreach (VxSqlToken t in tokens) { Console.WriteLine("Token: {0}: {1}", t.type.ToString(), t.name); } */ }
private void reset_state() { cur = ""; curspace = ""; curstate = VxSqlToken.TokenType.None; }