KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > parser > diagnose > LexStream


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.compiler.parser.diagnose;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.core.compiler.InvalidInputException;
15 import org.eclipse.jdt.internal.compiler.parser.Scanner;
16 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
17 import org.eclipse.jdt.internal.compiler.util.Util;
18
19 public class LexStream implements TerminalTokens {
20     public static final int IS_AFTER_JUMP = 1;
21     public static final int LBRACE_MISSING = 2;
22         
23     public static class Token{
24         int kind;
25         char[] name;
26         int start;
27         int end;
28         int line;
29         int flags;
30         
31         public String JavaDoc toString() {
32             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
33             buffer.append(name).append('[').append(kind).append(']');
34             buffer.append('{').append(start).append(',').append(end).append('}').append(line);
35             return buffer.toString();
36         }
37
38     }
39
40     private int tokenCacheIndex;
41     private int tokenCacheEOFIndex;
42     private Token[] tokenCache;
43
44     private int currentIndex = -1;
45
46     private Scanner scanner;
47     private int[] intervalStartToSkip;
48     private int[] intervalEndToSkip;
49     private int[] intervalFlagsToSkip;
50     
51     private int previousInterval = -1;
52     private int currentInterval = -1;
53     
54     public LexStream(int size, Scanner scanner, int[] intervalStartToSkip, int[] intervalEndToSkip, int[] intervalFlagsToSkip, int firstToken, int init, int eof) {
55         this.tokenCache = new Token[size];
56         this.tokenCacheIndex = 0;
57         this.tokenCacheEOFIndex = Integer.MAX_VALUE;
58         this.tokenCache[0] = new Token();
59         this.tokenCache[0].kind = firstToken;
60         this.tokenCache[0].name = CharOperation.NO_CHAR;
61         this.tokenCache[0].start = init;
62         this.tokenCache[0].end = init;
63         this.tokenCache[0].line = 0;
64         
65         this.intervalStartToSkip = intervalStartToSkip;
66         this.intervalEndToSkip = intervalEndToSkip;
67         this.intervalFlagsToSkip = intervalFlagsToSkip;
68         
69         scanner.resetTo(init, eof);
70         this.scanner = scanner;
71     }
72     
73     private void readTokenFromScanner(){
74         int length = tokenCache.length;
75         boolean tokenNotFound = true;
76         
77         while(tokenNotFound) {
78             try {
79                 int tokenKind = scanner.getNextToken();
80                 if(tokenKind != TokenNameEOF) {
81                     int start = scanner.getCurrentTokenStartPosition();
82                     int end = scanner.getCurrentTokenEndPosition();
83                     
84                     int nextInterval = currentInterval + 1;
85                     if(intervalStartToSkip.length == 0 ||
86                             nextInterval >= intervalStartToSkip.length ||
87                             start < intervalStartToSkip[nextInterval]) {
88                         Token token = new Token();
89                         token.kind = tokenKind;
90                         token.name = scanner.getCurrentTokenSource();
91                         token.start = start;
92                         token.end = end;
93                         token.line = Util.getLineNumber(end, scanner.lineEnds, 0, scanner.linePtr);
94                         
95                         if(currentInterval != previousInterval && (intervalFlagsToSkip[currentInterval] & RangeUtil.IGNORE) == 0){
96                             token.flags = IS_AFTER_JUMP;
97                             if((intervalFlagsToSkip[currentInterval] & RangeUtil.LBRACE_MISSING) != 0){
98                                 token.flags |= LBRACE_MISSING;
99                             }
100                         }
101                         previousInterval = currentInterval;
102
103                         tokenCache[++tokenCacheIndex % length] = token;
104                         
105                         tokenNotFound = false;
106                     } else {
107                         scanner.resetTo(intervalEndToSkip[++currentInterval] + 1, scanner.eofPosition - 1);
108                     }
109                 } else {
110                     int start = scanner.getCurrentTokenStartPosition();
111                     int end = scanner.getCurrentTokenEndPosition();
112                     Token token = new Token();
113                     token.kind = tokenKind;
114                     token.name = CharOperation.NO_CHAR;
115                     token.start = start;
116                     token.end = end;
117                     token.line = Util.getLineNumber(end, scanner.lineEnds, 0, scanner.linePtr);
118                     
119                     tokenCache[++tokenCacheIndex % length] = token;
120                     
121                     tokenCacheEOFIndex = tokenCacheIndex;
122                     tokenNotFound = false;
123                 }
124             } catch (InvalidInputException e) {
125                 // return next token
126
}
127         }
128     }
129     
130     public Token token(int index) {
131         if(index < 0) {
132             Token eofToken = new Token();
133             eofToken.kind = TokenNameEOF;
134             eofToken.name = CharOperation.NO_CHAR;
135             return eofToken;
136         }
137         if(this.tokenCacheEOFIndex >= 0 && index > this.tokenCacheEOFIndex) {
138             return token(this.tokenCacheEOFIndex);
139         }
140         int length = tokenCache.length;
141         if(index > this.tokenCacheIndex) {
142             int tokensToRead = index - this.tokenCacheIndex;
143             while(tokensToRead-- != 0) {
144                 readTokenFromScanner();
145             }
146         } else if(this.tokenCacheIndex - length >= index) {
147             return null;
148         }
149         
150         return tokenCache[index % length];
151     }
152     
153     
154     
155     public int getToken() {
156         return currentIndex = next(currentIndex);
157     }
158     
159     public int previous(int tokenIndex) {
160         return tokenIndex > 0 ? tokenIndex - 1 : 0;
161     }
162
163     public int next(int tokenIndex) {
164         return tokenIndex < this.tokenCacheEOFIndex ? tokenIndex + 1 : this.tokenCacheEOFIndex;
165     }
166
167     public boolean afterEol(int i) {
168         return i < 1 ? true : line(i - 1) < line(i);
169     }
170     
171     public void reset() {
172         currentIndex = -1;
173     }
174     
175     public void reset(int i) {
176         currentIndex = previous(i);
177     }
178
179     public int badtoken() {
180         return 0;
181     }
182
183     public int kind(int tokenIndex) {
184         return token(tokenIndex).kind;
185     }
186     
187     public char[] name(int tokenIndex) {
188         return token(tokenIndex).name;
189     }
190
191     public int line(int tokenIndex) {
192         return token(tokenIndex).line;
193     }
194     
195     public int start(int tokenIndex) {
196         return token(tokenIndex).start;
197     }
198     
199     public int end(int tokenIndex) {
200         return token(tokenIndex).end;
201     }
202     
203     public int flags(int tokenIndex) {
204         return token(tokenIndex).flags;
205     }
206     
207     public boolean isInsideStream(int index) {
208         if(this.tokenCacheEOFIndex >= 0 && index > this.tokenCacheEOFIndex) {
209             return false;
210         } else if(index > this.tokenCacheIndex) {
211             return true;
212         } else if(this.tokenCacheIndex - tokenCache.length >= index) {
213             return false;
214         } else {
215             return true;
216         }
217     }
218     
219     /* (non-Javadoc)
220      * @see java.lang.Object#toString()
221      */

222     public String JavaDoc toString() {
223         StringBuffer JavaDoc res = new StringBuffer JavaDoc();
224         
225         String JavaDoc source = new String JavaDoc(scanner.source);
226         if(currentIndex < 0) {
227             int previousEnd = -1;
228             for (int i = 0; i < intervalStartToSkip.length; i++) {
229                 int intervalStart = intervalStartToSkip[i];
230                 int intervalEnd = intervalEndToSkip[i];
231                 
232                 res.append(source.substring(previousEnd + 1, intervalStart));
233                 res.append('<');
234                 res.append('@');
235                 res.append(source.substring(intervalStart, intervalEnd + 1));
236                 res.append('@');
237                 res.append('>');
238                 
239                 previousEnd = intervalEnd;
240             }
241             res.append(source.substring(previousEnd + 1));
242         } else {
243             Token token = token(currentIndex);
244             int curtokKind = token.kind;
245             int curtokStart = token.start;
246             int curtokEnd = token.end;
247             
248             int previousEnd = -1;
249             for (int i = 0; i < intervalStartToSkip.length; i++) {
250                 int intervalStart = intervalStartToSkip[i];
251                 int intervalEnd = intervalEndToSkip[i];
252                 
253                 if(curtokStart >= previousEnd && curtokEnd <= intervalStart) {
254                     res.append(source.substring(previousEnd + 1, curtokStart));
255                     res.append('<');
256                     res.append('#');
257                     res.append(source.substring(curtokStart, curtokEnd + 1));
258                     res.append('#');
259                     res.append('>');
260                     res.append(source.substring(curtokEnd+1, intervalStart));
261                 } else {
262                     res.append(source.substring(previousEnd + 1, intervalStart));
263                 }
264                 res.append('<');
265                 res.append('@');
266                 res.append(source.substring(intervalStart, intervalEnd + 1));
267                 res.append('@');
268                 res.append('>');
269                 
270                 previousEnd = intervalEnd;
271             }
272             if(curtokStart >= previousEnd) {
273                 res.append(source.substring(previousEnd + 1, curtokStart));
274                 res.append('<');
275                 res.append('#');
276                 if(curtokKind == TokenNameEOF) {
277                     res.append("EOF#>"); //$NON-NLS-1$
278
} else {
279                     res.append(source.substring(curtokStart, curtokEnd + 1));
280                     res.append('#');
281                     res.append('>');
282                     res.append(source.substring(curtokEnd+1));
283                 }
284             } else {
285                 res.append(source.substring(previousEnd + 1));
286             }
287         }
288         
289         return res.toString();
290     }
291 }
292
Popular Tags