View Javadoc

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