View Javadoc

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