--- /dev/null
+package com.quantum.editors;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.EndOfLineRule;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPredicateRule;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+
+public class SQLPartitionScanner extends RuleBasedPartitionScanner {
+ public final static String SQL_COMMENT = "__sql_comment"; //$NON-NLS-1$
+ public final static String SQL_IDENTIFIER = "__sql_word"; //$NON-NLS-1$
+ public final static String SQL_STRING = "__sql_string"; //$NON-NLS-1$
+ public final static String SQL_KEYWORD = "__sql_keyword"; //$NON-NLS-1$
+ public final static String SQL_SYMBOL = "__sql_symbol"; //$NON-NLS-1$
+ public final static String SQL_SEPARATOR = "__sql_separator"; //$NON-NLS-1$
+ public final static String SQL_NUMERIC = "__sql_numeric"; //$NON-NLS-1$
+
+ private final static String[] KEYWORDS = {
+ "ALTER", //$NON-NLS-1$
+ "AND", //$NON-NLS-1$
+ "BY", //$NON-NLS-1$
+ "COLUMN", //$NON-NLS-1$
+ "CREATE", //$NON-NLS-1$
+ "DELETE", //$NON-NLS-1$
+ "DROP", //$NON-NLS-1$
+ "FROM", //$NON-NLS-1$
+ "GROUP", //$NON-NLS-1$
+ "INSERT", //$NON-NLS-1$
+ "INTO", //$NON-NLS-1$
+ "NOT", //$NON-NLS-1$
+ "NULL", //$NON-NLS-1$
+ "OR", //$NON-NLS-1$
+ "ORDER", //$NON-NLS-1$
+ "SELECT", //$NON-NLS-1$
+ "SEQUENCE", //$NON-NLS-1$
+ "SET", //$NON-NLS-1$
+ "TABLE", //$NON-NLS-1$
+ "UNION", //$NON-NLS-1$
+ "UNIQUE", //$NON-NLS-1$
+ "UPDATE", //$NON-NLS-1$
+ "USING", //$NON-NLS-1$
+ "VALUES", //$NON-NLS-1$
+ "VIEW", //$NON-NLS-1$
+ "WHEN", //$NON-NLS-1$
+ "WHERE" //$NON-NLS-1$
+ };
+
+ public SQLPartitionScanner() {
+
+ List rules = new ArrayList();
+
+ IToken comment = new Token(SQL_COMMENT);
+ IToken string = new Token(SQL_STRING);
+ IToken identifier = new Token(SQL_IDENTIFIER);
+ IToken keyword = new Token(SQL_KEYWORD);
+ IToken separator = new Token(SQL_SEPARATOR);
+ IToken symbol = new Token(SQL_SYMBOL);
+ IToken whitespace = new Token(IDocument.DEFAULT_CONTENT_TYPE);
+ IToken numeric = new Token(SQL_NUMERIC);
+
+ rules.add(new PredicateRuleAdapter(new WhitespaceRule(new WhitespaceDetector()), whitespace));
+ rules.add(new MultiLineRule("/*", "*/", comment)); //$NON-NLS-1$ //$NON-NLS-2$
+ rules.add(new EndOfLineRule("--", comment)); //$NON-NLS-1$
+ rules.add(new SingleLineRule("'", "'", string)); //$NON-NLS-1$ //$NON-NLS-2$
+ rules.add(new PredicateRuleAdapter(new SQLNumberRule(numeric), numeric));
+ SQLWordRule wordRule = new SQLWordRule(identifier);
+ for (int i = 0; i < KEYWORDS.length; i++) {
+ wordRule.addKeyword(KEYWORDS[i], keyword);
+ }
+ rules.add(new PredicateRuleAdapter(wordRule, keyword));
+ rules.add(new PredicateRuleAdapter(wordRule, identifier));
+ rules.add(new PredicateRuleAdapter(new SQLSeparatorRule(separator), separator));
+ rules.add(new PredicateRuleAdapter(new SymbolRule(symbol), symbol));
+
+ IPredicateRule[] result= new IPredicateRule[rules.size()];
+ rules.toArray(result);
+ setPredicateRules(result);
+ }
+}
+
+class PredicateRuleAdapter implements IPredicateRule {
+ IRule rule;
+ IToken token;
+ public PredicateRuleAdapter(IRule rule, IToken token) {
+ this.rule = rule;
+ this.token = token;
+ }
+
+ public IToken evaluate(ICharacterScanner scanner, boolean resume) {
+ return rule.evaluate(scanner);
+ }
+
+ public IToken getSuccessToken() {
+ return token;
+ }
+
+ public IToken evaluate(ICharacterScanner scanner) {
+ return rule.evaluate(scanner);
+ }
+
+}
+
+class SQLSeparatorRule implements IRule {
+ IToken token;
+ public SQLSeparatorRule(IToken token) {
+ this.token = token;
+ }
+ public IToken evaluate(ICharacterScanner scanner) {
+ char c = (char) scanner.read();
+ if (c == ';') {
+ return token;
+ }
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+
+}
+
+class SymbolRule implements IRule {
+ IToken token;
+ public SymbolRule(IToken token) {
+ this.token = token;
+ }
+ public IToken evaluate(ICharacterScanner scanner) {
+ int val = scanner.read();
+ if (val != ICharacterScanner.EOF) {
+ char c = (char) val;
+ if (!Character.isWhitespace(c) && !Character.isLetterOrDigit(c) && c != '_') {
+ return token;
+ }
+ }
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+
+}
+
+class WhitespaceDetector implements IWhitespaceDetector {
+
+ public boolean isWhitespace(char c) {
+ return Character.isWhitespace(c);
+ }
+}
+
+class SQLNumberRule implements IRule {
+ private IToken token;
+
+ public SQLNumberRule(IToken token) {
+ this.token = token;
+ }
+
+ public IToken evaluate(ICharacterScanner scanner) {
+ char c = (char) scanner.read();
+ if (Character.isDigit(c)) {
+ // postive numbers and zero
+ do {
+ c= (char) scanner.read();
+ } while (Character.isDigit(c) || c == '.');
+ scanner.unread();
+ return token;
+ } else if (c == '-') {
+ // negative numbers
+ c = (char) scanner.read();
+ if (Character.isDigit(c)) {
+ do {
+ c= (char) scanner.read();
+ } while (Character.isDigit(c) || c == '.');
+ scanner.unread();
+ return token;
+ } else {
+ scanner.unread();
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+ } else {
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+ }
+}
+
+class SQLWordRule implements IRule {
+ private IToken token;
+ private HashMap keywords = new HashMap();
+
+ public SQLWordRule(IToken token) {
+ this.token = token;
+ }
+
+ public void addKeyword(String word, IToken token) {
+ keywords.put(word.toUpperCase(), token);
+ }
+
+ public IToken evaluate(ICharacterScanner scanner) {
+ char c = (char) scanner.read();
+ if (Character.isLetter(c) || c == '_') {
+ StringBuffer value = new StringBuffer();
+ do {
+ value.append(c);
+ c= (char) scanner.read();
+ } while (Character.isLetterOrDigit(c) || c == '_');
+ scanner.unread();
+ IToken retVal = (IToken) keywords.get(value.toString().toUpperCase());
+ if (retVal != null) {
+ return retVal;
+ } else {
+ return token;
+ }
+ } else {
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+ }
+}
\ No newline at end of file