1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 package org.codehaus.groovy.syntax;
48
49 import org.codehaus.groovy.GroovyBugError;
50
51
52 /***
53 * A <code>CSTNode</code> produced by the <code>Lexer</code>.
54 *
55 * @see antlr.Parser
56 * @see antlr.Token
57 * @see Reduction
58 * @see Types
59 *
60 * @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
61 * @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
62 *
63 * @version $Id: Token.java 4032 2006-08-30 07:18:49Z mguillem $
64 */
65
66 public class Token extends CSTNode
67 {
68 public static final Token NULL = new Token();
69 public static final Token EOF = new Token( Types.EOF, "", -1, -1 );
70
71
72
73
74
75 private int type = Types.UNKNOWN;
76 private int meaning = Types.UNKNOWN;
77
78 private String text = "";
79 private int startLine = -1;
80 private int startColumn = -1;
81
82
83 /***
84 * Initializes the Token with the specified information.
85 */
86
87 public Token( int type, String text, int startLine, int startColumn )
88 {
89 this.type = type;
90 this.meaning = type;
91 this.text = text;
92 this.startLine = startLine;
93 this.startColumn = startColumn;
94 }
95
96
97 /***
98 * Initializes the NULL Token.
99 */
100
101 private Token() { }
102
103
104
105 /***
106 * Returns a copy of this Token.
107 */
108
109 public Token dup()
110 {
111 Token token = new Token( this.type, this.text, this.startLine, this.startColumn );
112 token.setMeaning( this.meaning );
113
114 return token;
115 }
116
117
118
119
120
121
122
123
124 /***
125 * Returns the meaning of this node. If the node isEmpty(), returns
126 * the type of Token.NULL.
127 */
128
129 public int getMeaning()
130 {
131 return meaning;
132 }
133
134
135
136 /***
137 * Sets the meaning for this node (and it's root Token). Not
138 * valid if the node isEmpty(). Returns this token, for
139 * convenience.
140 */
141
142 public CSTNode setMeaning( int meaning )
143 {
144 this.meaning = meaning;
145 return this;
146 }
147
148
149
150 /***
151 * Returns the actual type of the node. If the node isEmpty(), returns
152 * the type of Token.NULL.
153 */
154
155 public int getType()
156 {
157 return type;
158 }
159
160
161
162
163
164
165
166
167 /***
168 * Returns the number of elements in the node (including root).
169 */
170
171 public int size()
172 {
173 return 1;
174 }
175
176
177
178 /***
179 * Returns the specified element, or null.
180 */
181
182 public CSTNode get( int index )
183 {
184 if( index > 0 )
185 {
186 throw new GroovyBugError( "attempt to access Token element other than root" );
187 }
188
189 return this;
190 }
191
192
193
194 /***
195 * Returns the root of the node. By convention, all nodes have
196 * a Token as the first element (or root), which indicates the type
197 * of the node. May return null if the node <code>isEmpty()</code>.
198 */
199
200 public Token getRoot()
201 {
202 return this;
203 }
204
205
206
207 /***
208 * Returns the text of the root node. Uses <code>getRoot(true)</code>
209 * to get the root, so you will only receive null in return if the
210 * root token returns it.
211 */
212
213 public String getRootText()
214 {
215 return text;
216 }
217
218
219
220 /***
221 * Returns the text of the token. Equivalent to
222 * <code>getRootText()</code> when called directly.
223 */
224
225 public String getText()
226 {
227 return text;
228 }
229
230
231
232 /***
233 * Not advisable, but if you need to adjust the token's text, this
234 * will do it.
235 */
236
237 public void setText( String text )
238 {
239 this.text = text;
240 }
241
242
243
244 /***
245 * Returns the starting line of the node. Returns -1
246 * if not known.
247 */
248
249 public int getStartLine()
250 {
251 return startLine;
252 }
253
254
255
256 /***
257 * Returns the starting column of the node. Returns -1
258 * if not known.
259 */
260
261 public int getStartColumn()
262 {
263 return startColumn;
264 }
265
266
267
268
269
270
271
272
273 /***
274 * Creates a <code>Reduction</code> from this token. Returns self if the
275 * node is already a <code>Reduction</code>.
276 */
277
278 public Reduction asReduction()
279 {
280 return new Reduction( this );
281 }
282
283
284
285 /***
286 * Creates a <code>Reduction</code> from this token, adding the supplied
287 * node as the second element.
288 */
289
290 public Reduction asReduction( CSTNode second )
291 {
292 Reduction created = asReduction();
293 created.add( second );
294 return created;
295 }
296
297
298
299 /***
300 * Creates a <code>Reduction</code> from this token, adding the supplied
301 * nodes as the second and third element, respectively.
302 */
303
304 public Reduction asReduction( CSTNode second, CSTNode third )
305 {
306 Reduction created = asReduction( second );
307 created.add( third );
308 return created;
309 }
310
311
312
313 /***
314 * Creates a <code>Reduction</code> from this token, adding the supplied
315 * nodes as the second, third, and fourth element, respectively.
316 */
317
318 public Reduction asReduction( CSTNode second, CSTNode third, CSTNode fourth )
319 {
320 Reduction created = asReduction( second, third );
321 created.add( fourth );
322 return created;
323 }
324
325
326
327
328
329
330
331
332 /***
333 * Creates a token that represents a keyword. Returns null if the
334 * specified text isn't a keyword.
335 */
336
337 public static Token newKeyword( String text, int startLine, int startColumn )
338 {
339
340 int type = Types.lookupKeyword( text );
341 if( type != Types.UNKNOWN )
342 {
343 return new Token( type, text, startLine, startColumn );
344 }
345
346 return null;
347
348 }
349
350
351 /***
352 * Creates a token that represents a double-quoted string.
353 */
354
355 public static Token newString( String text, int startLine, int startColumn )
356 {
357 return new Token( Types.STRING, text, startLine, startColumn );
358 }
359
360
361 /***
362 * Creates a token that represents an identifier.
363 */
364
365 public static Token newIdentifier( String text, int startLine, int startColumn )
366 {
367 return new Token( Types.IDENTIFIER, text, startLine, startColumn );
368 }
369
370
371 /***
372 * Creates a token that represents an integer.
373 */
374
375 public static Token newInteger( String text, int startLine, int startColumn )
376 {
377 return new Token( Types.INTEGER_NUMBER, text, startLine, startColumn );
378 }
379
380
381 /***
382 * Creates a token that represents a decimal number.
383 */
384
385 public static Token newDecimal( String text, int startLine, int startColumn )
386 {
387 return new Token( Types.DECIMAL_NUMBER, text, startLine, startColumn );
388 }
389
390
391 /***
392 * Creates a token that represents a symbol, using a library for the text.
393 */
394
395 public static Token newSymbol( int type, int startLine, int startColumn )
396 {
397 return new Token( type, Types.getText(type), startLine, startColumn );
398 }
399
400
401 /***
402 * Creates a token that represents a symbol, using a library for the type.
403 */
404
405 public static Token newSymbol( String type, int startLine, int startColumn )
406 {
407 return new Token( Types.lookupSymbol(type), type, startLine, startColumn );
408 }
409
410
411 /***
412 * Creates a token with the specified meaning.
413 */
414
415 public static Token newPlaceholder( int type )
416 {
417 Token token = new Token( Types.UNKNOWN, "", -1, -1 );
418 token.setMeaning( type );
419
420 return token;
421 }
422
423 }