View Javadoc

1   /*
2    $Id: Token.java 4032 2006-08-30 07:18:49Z mguillem $
3   
4    Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5   
6    Redistribution and use of this software and associated documentation
7    ("Software"), with or without modification, are permitted provided
8    that the following conditions are met:
9   
10   1. Redistributions of source code must retain copyright
11      statements and notices.  Redistributions must also contain a
12      copy of this document.
13  
14   2. Redistributions in binary form must reproduce the
15      above copyright notice, this list of conditions and the
16      following disclaimer in the documentation and/or other
17      materials provided with the distribution.
18  
19   3. The name "groovy" must not be used to endorse or promote
20      products derived from this Software without prior written
21      permission of The Codehaus.  For written permission,
22      please contact info@codehaus.org.
23  
24   4. Products derived from this Software may not be called "groovy"
25      nor may "groovy" appear in their names without prior written
26      permission of The Codehaus. "groovy" is a registered
27      trademark of The Codehaus.
28  
29   5. Due credit should be given to The Codehaus -
30      http://groovy.codehaus.org/
31  
32   THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
33   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
36   THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43   OF THE POSSIBILITY OF SUCH DAMAGE.
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    // TOKEN INITIALIZATION AND SUCH
74  
75      private int type        = Types.UNKNOWN;  // the actual type identified by the lexer
76      private int meaning     = Types.UNKNOWN;  // an interpretation applied to the token after the fact
77  
78      private String     text = "";             // the text of the token
79      private int   startLine = -1;             // the source line on which the token begins
80      private int startColumn = -1;             // the source column on which the token begins
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   // NODE IDENTIFICATION AND MEANING
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   // MEMBER ACCESS
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   // OPERATIONS
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   // TOKEN FACTORIES
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 }