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 }