latest quantum sources 2.3.2
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.quantum.sql / src / com / quantum / sql / parser / SQLLexx.java
1 package com.quantum.sql.parser;
2
3 import java.util.Vector;
4
5 public class SQLLexx {
6         private static String endline = ";"; //$NON-NLS-1$
7         private static String dash = "-"; //$NON-NLS-1$
8         private static String group = "/"; //$NON-NLS-1$
9         /**
10          * Parses a SQL text into tokens. 
11          * @param text
12          * @return a vector of Token objects.
13          */
14         public static Vector parse(String text) {
15                 Vector tokens = new Vector();
16                 StringPointer p = new StringPointer(text);
17                 try {
18                         while (!p.isDone()) {
19                                 int offset = p.getOffset();
20                                 char c = p.getNext();
21                                 // Adds END_OF_LINE token
22                                 if (c == '\n') {
23                                         tokens.addElement(new Token(Token.END_OF_LINE, "\n", offset, offset + 1));      
24                                 }
25                                 // Adds WHITESPACE token;
26                                 else if (Character.isWhitespace(c)) {
27                                         StringBuffer value = new StringBuffer();
28                                         while (Character.isWhitespace(c) && !p.isDone()) {
29                                                 value.append(c);
30                                                 c = p.getNext();
31                                         }
32                                         // done because of is done
33                                         if (Character.isWhitespace(c)) {
34                                                 value.append(c);
35                                         } else if (!p.isDone()){
36                                                 p.back();
37                                         }
38                                         tokens.addElement(new Token(Token.WHITESPACE, value.toString(), offset, offset + value.length()));
39                                 // Adds IDENTIFIER token (can be reserved SQL word or not);
40                                 } else if (Character.isLetter(c) || c == '_' || c == '$') {
41                                         StringBuffer value = new StringBuffer();
42                                         while ((Character.isLetterOrDigit(c) || c == '_'  || c == '$') && !p.isDone()) {
43                                                 value.append(c);
44                                                 c = p.getNext();
45                                         }
46                                         if ((Character.isLetterOrDigit(c) || c == '_')) {
47                                                 value.append(c);
48                                         } else if (!p.isDone()){
49                                                 p.back();
50                                         }
51                                         tokens.addElement(new Token(Token.IDENTIFIER, value.toString(), offset, offset + value.length()));
52                                 // Adds LITERAL token;
53                                 } else if (c == '\'') {
54                                         StringBuffer value = new StringBuffer();
55                                         value.append(c);
56                                         if (!p.isDone()) {
57                                                 c = p.getNext();
58                                                 while (c != '\'' && c != '\n' && !p.isDone()) {
59                                                         value.append(c);
60                                                         c = p.getNext();
61                                                 }
62                                                 if (c == '\'' || p.isDone()) {
63                                                         value.append(c);
64                                                 } else if (!p.isDone()){
65                                                         p.back();
66                                                 }
67                                         }
68                                         tokens.addElement(new Token(Token.LITERAL, value.toString(), offset, offset + value.length()));
69                                 // Adds COMMENT token (or SYMBOL (dash) if only one dash);
70                                 } else if (c == '-') {
71                                         p.mark();
72                                         if (p.isDone()) {
73                                                 tokens.addElement(new Token(Token.SYMBOL, dash, offset, offset + 1));
74                                         } else {
75                                                 char next = p.getNext();
76                                                 if (next == '-') {
77                                                         StringBuffer value = new StringBuffer("--"); //$NON-NLS-1$
78                                                         if (!p.isDone()) {
79                                                                 c = p.getNext();
80                                                                 while (c != '\n' && !p.isDone()) {
81                                                                         value.append(c);
82                                                                         c = p.getNext();
83                                                                 }
84                                                                 if (p.isDone()) {
85                                                                         value.append(c);
86                                                                 } else {
87                                                                         p.back();
88                                                                 }
89                                                         }
90                                                         tokens.addElement(new Token(Token.COMMENT, value.toString(), offset, offset + value.length()));
91                                                 } else {
92                                                         tokens.addElement(new Token(Token.SYMBOL, dash, offset, offset + 1));
93                                                         p.reset();
94                                                 }
95                                         }
96                                 // Adds SEPARATOR token (;),  considers the rest of the line as COMMENT token;
97                                 } else if (c == ';') {
98                                         tokens.addElement(new Token(Token.SEPARATOR, endline, offset, offset + 1));
99                                         StringBuffer value = new StringBuffer();
100                                         if (!p.isDone()) {
101                                                 c = p.getNext();
102                                                 while (c != '\n' && !p.isDone()) {
103                                                         value.append(c);
104                                                         c = p.getNext();
105                                                 }
106                                                 if (p.isDone()) {
107                                                         value.append(c);
108                                                 } else {
109                                                         p.back();
110                                                 }
111                                                 // We add to the offset so as to skip the initial ';'
112                                                 offset++;
113                                                 tokens.addElement(new Token(Token.COMMENT, value.toString(), offset, offset + value.length()));
114                                         }
115                                 // Adds NUMERIC token;
116                                 } else if (Character.isDigit(c)) {
117                                         StringBuffer value = new StringBuffer();
118                                         while ((Character.isDigit(c) || c == '.') && !p.isDone()) {
119                                                 value.append(c);
120                                                 c = p.getNext();
121                                         }
122                                         if ((Character.isDigit(c) || c == '.')) {
123                                                 value.append(c);
124                                         } else {
125                                                 p.back();
126                                         }
127                                         tokens.addElement(new Token(Token.NUMERIC, value.toString(), offset, offset + value.length()));
128                                 // Adds COMMENT token (or GROUP (slash) if only one slash);
129                                 } else if (c == '/') {
130                                         p.mark();
131                                         // If we have '/*', it's a comment till '*/' found or eof
132                                         if (p.peek() == '*') {
133                                                 tokens.addElement(tokenizeComment(p, offset));
134                                         } else {
135                                                 // It's not '/*' , so it's a group token
136                                                 // BCH ??? what's this business about groups?  
137                                                 // Shouldn't '/' be a divide operator?
138                                                 tokens.addElement(new Token(Token.SYMBOL, new String(new char[] {c}) /*group*/, offset, offset + 1));
139                                                 p.reset();
140                                         }
141                                 // Adds SYMBOL token;
142                                 } else {
143                                         tokens.addElement(new Token(Token.SYMBOL, new String(new char[] {c}), offset, offset + 1));
144                                 }
145                         }
146                 } catch (RuntimeException e) {
147                         e.printStackTrace();
148                 }
149                 
150 //              System.out.println("-------------------");
151 //              for (int i = 0; i < tokens.size(); i++) {
152 //                      System.out.println((Token) tokens.elementAt(i));
153 //              }
154                 return tokens;
155         }
156         /**
157          * @param tokens
158          * @param p
159          * @param offset
160          */
161         private static Token tokenizeComment(StringPointer p, int offset) {
162                 char c;
163                 StringBuffer value = new StringBuffer();
164                 c = p.getNext();
165                 value.append('/');
166                 while (!( c == '*' && p.peek() == '/' ) && !p.isDone()) {
167                         value.append(c);
168                         c = p.getNext();
169                 }
170                 if (!p.isDone()){
171                         value.append(c);
172                         c = p.getNext();
173                         value.append(c);        
174                 }
175                 return new Token(Token.COMMENT, value.toString(), offset, offset + value.length());
176         }
177 }