blob: ce0860e0888df9d4efa5378c26009d9570295ddf [file] [log] [blame]
/*
$Id$
Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
Redistribution and use of this software and associated documentation
("Software"), with or without modification, are permitted provided
that the following conditions are met:
1. Redistributions of source code must retain copyright
statements and notices. Redistributions must also contain a
copy of this document.
2. Redistributions in binary form must reproduce the
above copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
3. The name "groovy" must not be used to endorse or promote
products derived from this Software without prior written
permission of The Codehaus. For written permission,
please contact info@codehaus.org.
4. Products derived from this Software may not be called "groovy"
nor may "groovy" appear in their names without prior written
permission of The Codehaus. "groovy" is a registered
trademark of The Codehaus.
5. Due credit should be given to The Codehaus -
http://groovy.codehaus.org/
THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.groovy.syntax;
import org.codehaus.groovy.GroovyBugError;
/**
* A <code>CSTNode</code> produced by the <code>Lexer</code>.
*
* @see antlr.Parser
* @see antlr.Token
* @see Reduction
* @see Types
*
* @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
* @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
*
* @version $Id$
*/
public class Token extends CSTNode
{
public static final Token NULL = new Token();
public static final Token EOF = new Token( Types.EOF, "", -1, -1 );
//---------------------------------------------------------------------------
// TOKEN INITIALIZATION AND SUCH
private int type = Types.UNKNOWN; // the actual type identified by the lexer
private int meaning = Types.UNKNOWN; // an interpretation applied to the token after the fact
private String text = ""; // the text of the token
private int startLine = -1; // the source line on which the token begins
private int startColumn = -1; // the source column on which the token begins
/**
* Initializes the Token with the specified information.
*/
public Token( int type, String text, int startLine, int startColumn )
{
this.type = type;
this.meaning = type;
this.text = text;
this.startLine = startLine;
this.startColumn = startColumn;
}
/**
* Initializes the NULL Token.
*/
private Token() { }
/**
* Returns a copy of this Token.
*/
public Token dup()
{
Token token = new Token( this.type, this.text, this.startLine, this.startColumn );
token.setMeaning( this.meaning );
return token;
}
//---------------------------------------------------------------------------
// NODE IDENTIFICATION AND MEANING
/**
* Returns the meaning of this node. If the node isEmpty(), returns
* the type of Token.NULL.
*/
public int getMeaning()
{
return meaning;
}
/**
* Sets the meaning for this node (and it's root Token). Not
* valid if the node isEmpty(). Returns this token, for
* convenience.
*/
public CSTNode setMeaning( int meaning )
{
this.meaning = meaning;
return this;
}
/**
* Returns the actual type of the node. If the node isEmpty(), returns
* the type of Token.NULL.
*/
public int getType()
{
return type;
}
//---------------------------------------------------------------------------
// MEMBER ACCESS
/**
* Returns the number of elements in the node (including root).
*/
public int size()
{
return 1;
}
/**
* Returns the specified element, or null.
*/
public CSTNode get( int index )
{
if( index > 0 )
{
throw new GroovyBugError( "attempt to access Token element other than root" );
}
return this;
}
/**
* Returns the root of the node. By convention, all nodes have
* a Token as the first element (or root), which indicates the type
* of the node. May return null if the node <code>isEmpty()</code>.
*/
public Token getRoot()
{
return this;
}
/**
* Returns the text of the root node. Uses <code>getRoot(true)</code>
* to get the root, so you will only receive null in return if the
* root token returns it.
*/
public String getRootText()
{
return text;
}
/**
* Returns the text of the token. Equivalent to
* <code>getRootText()</code> when called directly.
*/
public String getText()
{
return text;
}
/**
* Not advisable, but if you need to adjust the token's text, this
* will do it.
*/
public void setText( String text )
{
this.text = text;
}
/**
* Returns the starting line of the node. Returns -1
* if not known.
*/
public int getStartLine()
{
return startLine;
}
/**
* Returns the starting column of the node. Returns -1
* if not known.
*/
public int getStartColumn()
{
return startColumn;
}
//---------------------------------------------------------------------------
// OPERATIONS
/**
* Creates a <code>Reduction</code> from this token. Returns self if the
* node is already a <code>Reduction</code>.
*/
public Reduction asReduction()
{
return new Reduction( this );
}
/**
* Creates a <code>Reduction</code> from this token, adding the supplied
* node as the second element.
*/
public Reduction asReduction( CSTNode second )
{
Reduction created = asReduction();
created.add( second );
return created;
}
/**
* Creates a <code>Reduction</code> from this token, adding the supplied
* nodes as the second and third element, respectively.
*/
public Reduction asReduction( CSTNode second, CSTNode third )
{
Reduction created = asReduction( second );
created.add( third );
return created;
}
/**
* Creates a <code>Reduction</code> from this token, adding the supplied
* nodes as the second, third, and fourth element, respectively.
*/
public Reduction asReduction( CSTNode second, CSTNode third, CSTNode fourth )
{
Reduction created = asReduction( second, third );
created.add( fourth );
return created;
}
//---------------------------------------------------------------------------
// TOKEN FACTORIES
/**
* Creates a token that represents a keyword. Returns null if the
* specified text isn't a keyword.
*/
public static Token newKeyword( String text, int startLine, int startColumn )
{
int type = Types.lookupKeyword( text );
if( type != Types.UNKNOWN )
{
return new Token( type, text, startLine, startColumn );
}
return null;
}
/**
* Creates a token that represents a double-quoted string.
*/
public static Token newString( String text, int startLine, int startColumn )
{
return new Token( Types.STRING, text, startLine, startColumn );
}
/**
* Creates a token that represents an identifier.
*/
public static Token newIdentifier( String text, int startLine, int startColumn )
{
return new Token( Types.IDENTIFIER, text, startLine, startColumn );
}
/**
* Creates a token that represents an integer.
*/
public static Token newInteger( String text, int startLine, int startColumn )
{
return new Token( Types.INTEGER_NUMBER, text, startLine, startColumn );
}
/**
* Creates a token that represents a decimal number.
*/
public static Token newDecimal( String text, int startLine, int startColumn )
{
return new Token( Types.DECIMAL_NUMBER, text, startLine, startColumn );
}
/**
* Creates a token that represents a symbol, using a library for the text.
*/
public static Token newSymbol( int type, int startLine, int startColumn )
{
return new Token( type, Types.getText(type), startLine, startColumn );
}
/**
* Creates a token that represents a symbol, using a library for the type.
*/
public static Token newSymbol( String type, int startLine, int startColumn )
{
return new Token( Types.lookupSymbol(type), type, startLine, startColumn );
}
/**
* Creates a token with the specified meaning.
*/
public static Token newPlaceholder( int type )
{
Token token = new Token( Types.UNKNOWN, "", -1, -1 );
token.setMeaning( type );
return token;
}
}