blob: 8a0031fd21cfa50bb98ed78ab284f8a2417f4002 [file] [log] [blame]
/*
* Copyright 2003-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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;
}
}