1 package net.sourceforge.phpdt.sql.editors;
3 import java.util.ArrayList;
4 import java.util.HashMap;
7 import org.eclipse.jface.text.IDocument;
8 import org.eclipse.jface.text.rules.EndOfLineRule;
9 import org.eclipse.jface.text.rules.ICharacterScanner;
10 import org.eclipse.jface.text.rules.IPredicateRule;
11 import org.eclipse.jface.text.rules.IRule;
12 import org.eclipse.jface.text.rules.IToken;
13 import org.eclipse.jface.text.rules.IWhitespaceDetector;
14 import org.eclipse.jface.text.rules.MultiLineRule;
15 import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
16 import org.eclipse.jface.text.rules.SingleLineRule;
17 import org.eclipse.jface.text.rules.Token;
18 import org.eclipse.jface.text.rules.WhitespaceRule;
20 public class SQLPartitionScanner extends RuleBasedPartitionScanner {
21 public final static String SQL_COMMENT = "__sql_comment";
22 public final static String SQL_IDENTIFIER = "__sql_word";
23 public final static String SQL_STRING = "__sql_string";
24 public final static String SQL_KEYWORD = "__sql_keyword";
25 public final static String SQL_SYMBOL = "__sql_symbol";
26 public final static String SQL_SEPARATOR = "__sql_separator";
27 public final static String SQL_NUMERIC = "__sql_numeric";
29 private final static String[] KEYWORDS = {
59 public SQLPartitionScanner() {
61 List rules = new ArrayList();
63 IToken comment = new Token(SQL_COMMENT);
64 IToken string = new Token(SQL_STRING);
65 IToken identifier = new Token(SQL_IDENTIFIER);
66 IToken keyword = new Token(SQL_KEYWORD);
67 IToken separator = new Token(SQL_SEPARATOR);
68 IToken symbol = new Token(SQL_SYMBOL);
69 IToken whitespace = new Token(IDocument.DEFAULT_CONTENT_TYPE);
70 IToken numeric = new Token(SQL_NUMERIC);
72 rules.add(new PredicateRuleAdapter(new WhitespaceRule(new WhitespaceDetector()), whitespace));
73 rules.add(new MultiLineRule("/*", "*/", comment));
74 rules.add(new EndOfLineRule("--", comment));
75 rules.add(new SingleLineRule("'", "'", string));
76 rules.add(new PredicateRuleAdapter(new SQLNumberRule(numeric), numeric));
77 SQLWordRule wordRule = new SQLWordRule(identifier);
78 for (int i = 0; i < KEYWORDS.length; i++) {
79 wordRule.addKeyword(KEYWORDS[i], keyword);
81 rules.add(new PredicateRuleAdapter(wordRule, keyword));
82 rules.add(new PredicateRuleAdapter(wordRule, identifier));
83 rules.add(new PredicateRuleAdapter(new SQLSeparatorRule(separator), separator));
84 rules.add(new PredicateRuleAdapter(new SymbolRule(symbol), symbol));
86 IPredicateRule[] result= new IPredicateRule[rules.size()];
87 rules.toArray(result);
88 setPredicateRules(result);
92 class PredicateRuleAdapter implements IPredicateRule {
95 public PredicateRuleAdapter(IRule rule, IToken token) {
100 public IToken evaluate(ICharacterScanner scanner, boolean resume) {
101 return rule.evaluate(scanner);
104 public IToken getSuccessToken() {
108 public IToken evaluate(ICharacterScanner scanner) {
109 return rule.evaluate(scanner);
114 class SQLSeparatorRule implements IRule {
116 public SQLSeparatorRule(IToken token) {
119 public IToken evaluate(ICharacterScanner scanner) {
120 char c = (char) scanner.read();
125 return Token.UNDEFINED;
130 class SymbolRule implements IRule {
132 public SymbolRule(IToken token) {
135 public IToken evaluate(ICharacterScanner scanner) {
136 int val = scanner.read();
137 if (val != scanner.EOF) {
139 if (!Character.isWhitespace(c) && !Character.isLetterOrDigit(c) && c != '_') {
144 return Token.UNDEFINED;
149 class WhitespaceDetector implements IWhitespaceDetector {
151 public boolean isWhitespace(char c) {
152 return Character.isWhitespace(c);
156 class SQLNumberRule implements IRule {
157 private IToken token;
159 public SQLNumberRule(IToken token) {
163 public IToken evaluate(ICharacterScanner scanner) {
164 char c = (char) scanner.read();
165 if (Character.isDigit(c)) {
166 // postive numbers and zero
168 c= (char) scanner.read();
169 } while (Character.isDigit(c) || c == '.');
172 } else if (c == '-') {
174 c = (char) scanner.read();
175 if (Character.isDigit(c)) {
177 c= (char) scanner.read();
178 } while (Character.isDigit(c) || c == '.');
184 return Token.UNDEFINED;
188 return Token.UNDEFINED;
193 class SQLWordRule implements IRule {
194 private IToken token;
195 private HashMap keywords = new HashMap();
197 public SQLWordRule(IToken token) {
201 public void addKeyword(String word, IToken token) {
202 keywords.put(word.toUpperCase(), token);
205 public IToken evaluate(ICharacterScanner scanner) {
206 char c = (char) scanner.read();
207 if (Character.isLetter(c) || c == '_') {
208 StringBuffer value = new StringBuffer();
211 c= (char) scanner.read();
212 } while (Character.isLetterOrDigit(c) || c == '_');
214 IToken retVal = (IToken) keywords.get(value.toString().toUpperCase());
215 if (retVal != null) {
222 return Token.UNDEFINED;