blob: b89fc3b33ad9903477b19e00c1a888319aa2e691 [file] [log] [blame]
package org.antlr.runtime.tree {
import org.antlr.runtime.CommonToken;
import org.antlr.runtime.Token;
import org.antlr.runtime.TokenConstants;
/** A TreeAdaptor that works with any Tree implementation. It provides
* really just factory methods; all the work is done by BaseTreeAdaptor.
* If you would like to have different tokens created than ClassicToken
* objects, you need to override this and then set the parser tree adaptor to
* use your subclass.
*
* To get your parser to build nodes of a different type, override
* create(Token), errorNode(), and to be safe, YourTreeClass.dupNode().
* dupNode is called to duplicate nodes during rewrite operations.
*/
public class CommonTreeAdaptor extends BaseTreeAdaptor {
/** Duplicate a node. This is part of the factory;
* override if you want another kind of node to be built.
*
* I could use reflection to prevent having to override this
* but reflection is slow.
*/
public override function dupNode(t:Object):Object {
if ( t==null ) {
return null;
}
return (Tree(t)).dupNode();
}
public override function createWithPayload(payload:Token):Object {
return CommonTree.createFromToken(payload);
}
/** Tell me how to create a token for use with imaginary token nodes.
* For example, there is probably no input symbol associated with imaginary
* token DECL, but you need to create it as a payload or whatever for
* the DECL node as in ^(DECL type ID).
*
* If you care what the token payload objects' type is, you should
* override this method and any other createToken variant.
*/
public override function createTokenFromType(tokenType:int, text:String):Token {
return new CommonToken(tokenType, text);
}
/** Tell me how to create a token for use with imaginary token nodes.
* For example, there is probably no input symbol associated with imaginary
* token DECL, but you need to create it as a payload or whatever for
* the DECL node as in ^(DECL type ID).
*
* This is a variant of createToken where the new token is derived from
* an actual real input token. Typically this is for converting '{'
* tokens to BLOCK etc... You'll see
*
* r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
*
* If you care what the token payload objects' type is, you should
* override this method and any other createToken variant.
*/
public override function createToken(fromToken:Token):Token {
return CommonToken.cloneToken(fromToken);
}
/** Track start/stop token for subtree root created for a rule.
* Only works with Tree nodes. For rules that match nothing,
* seems like this will yield start=i and stop=i-1 in a nil node.
* Might be useful info so I'll not force to be i..i.
*/
public override function setTokenBoundaries(t:Object, startToken:Token, stopToken:Token):void {
if ( t==null ) {
return;
}
var start:int = 0;
var stop:int = 0;
if ( startToken!=null ) {
start = startToken.tokenIndex;
}
if ( stopToken!=null ) {
stop = stopToken.tokenIndex;
}
Tree(t).tokenStartIndex = start;
Tree(t).tokenStopIndex = stop;
}
public override function getTokenStartIndex(t:Object):int {
if ( t==null ) {
return -1;
}
return Tree(t).tokenStartIndex;
}
public override function getTokenStopIndex(t:Object):int {
if ( t==null ) {
return -1;
}
return Tree(t).tokenStopIndex;
}
public override function getText(t:Object):String {
if ( t==null ) {
return null;
}
return Tree(t).text;
}
public override function getType(t:Object):int {
if ( t==null ) {
return TokenConstants.INVALID_TOKEN_TYPE;
}
return Tree(t).type;;
}
/** What is the Token associated with this node? If
* you are not using CommonTree, then you must
* override this in your own adaptor.
*/
public override function getToken(t:Object):Token {
if ( t is CommonTree ) {
return CommonTree(t).token;
}
return null; // no idea what to do
}
public override function getChild(t:Object, i:int):Object {
if ( t==null ) {
return null;
}
return Tree(t).getChild(i);
}
public override function getChildCount(t:Object):int {
if ( t==null ) {
return 0;
}
return Tree(t).childCount;
}
public override function getParent(t:Object):Object {
if (t == null) {
return null;
}
return Tree(t).parent;
}
public override function setParent(t:Object, parent:Object):void {
if (t != null) {
Tree(t).parent = Tree(parent);
}
}
public override function getChildIndex(t:Object):int {
if (t == null) {
return 0;
}
return Tree(t).childIndex;
}
public override function setChildIndex(t:Object, index:int):void {
if (t != null) {
Tree(t).childIndex = index;
}
}
public override function replaceChildren(parent:Object, startChildIndex:int, stopChildIndex:int, t:Object):void {
if ( parent!=null ) {
Tree(parent).replaceChildren(startChildIndex, stopChildIndex, t);
}
}
}
}