initial quantum version
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.quantum.sql / src / com / quantum / editors / SQLPartitionScanner.java
diff --git a/archive/net.sourceforge.phpeclipse.quantum.sql/src/com/quantum/editors/SQLPartitionScanner.java b/archive/net.sourceforge.phpeclipse.quantum.sql/src/com/quantum/editors/SQLPartitionScanner.java
new file mode 100644 (file)
index 0000000..01898d1
--- /dev/null
@@ -0,0 +1,225 @@
+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