www.pudn.com > antlr-2_7_0.zip > ASTFactory.java


package antlr;

/* ANTLR Translator Generator
 * Project led by Terence Parr at http://www.jGuru.com
 * Software rights: http://www.antlr.org/RIGHTS.html
 *
 * $Id: //depot/code/org.antlr/release/antlr-2.7.0/antlr/ASTFactory.java#1 $
 */

import antlr.collections.AST;
import antlr.collections.impl.ASTArray;

/** AST Support code shared by TreeParser and Parser.
 *  We use delegation to share code (and have only one
 *  bit of code to maintain) rather than subclassing
 *  or superclassing (forces AST support code to be
 *  loaded even when you don't want to do AST stuff).
 *
 *  Typically, setASTNodeType is used to specify the
 *  type of node to create, but you can override
 *  create to make heterogeneous nodes etc...
 */
public class ASTFactory {
    /** Name of AST class to create during tree construction.
     *  Null implies that the create method should create
     *  a default AST type such as CommonAST.
     */
    protected String theASTNodeType = null;
    protected Class theASTNodeTypeClass = null;


    /** Add a child to the current AST */
    public void addASTChild(ASTPair currentAST, AST child) {
	if (child != null) {
	    if (currentAST.root == null) {
				// Make new child the current root
		currentAST.root = child;
	    } 
	    else {
		if (currentAST.child == null) {
		    // Add new child to current root
		    currentAST.root.setFirstChild(child);
		}
		else {
		    currentAST.child.setNextSibling(child);
		}
	    }
	    // Make new child the current child
	    currentAST.child = child;
	    currentAST.advanceChildToEnd();
	}
    }

    /** Create a new empty AST node; if the user did not specify
     *  an AST node type, then create a default one: CommonAST.
     */
    public AST create() {
	AST t = null;
	if (theASTNodeTypeClass == null) {
	    t = new CommonAST();
	} else {
	    try {
		t = (AST) theASTNodeTypeClass.newInstance(); // make a new one
	    } catch (Exception e) {
		antlr.Tool.warning("Can't create AST Node " + theASTNodeType);
		return null;
	    }
	}
	return t;
    }
    public AST create(int type) { 
	AST t = create();
	t.initialize(type,"");
	return t;	
    }
    public AST create(int type, String txt) { 
	AST t = create();
	t.initialize(type,txt);
	return t;	
    }

    /** Create a new empty AST node; if the user did not specify
     *  an AST node type, then create a default one: CommonAST.
     */
    public AST create(AST tr) { 
	if ( tr==null ) return null;		// create(null) == null
	AST t = create();
	t.initialize(tr);
	return t;	
    }

    public AST create(Token tok) { 
	AST t = create();
	t.initialize(tok);
	return t;	
    }

    /** Copy a single node.  clone() is not used because
     *  we want to return an AST not a plain object...a type
     *  safety issue.  Further, we want to have all AST node
     *  creation go through the factory so creation can be
     *  tracked.  Returns null if t is null.
     */
    public AST dup(AST t) {
	return create(t);		// if t==null, create returns null
    }

    /** Duplicate tree including siblings of root. */
    public AST dupList(AST t) {
	AST result = dupTree(t);            // if t == null, then result==null
	AST nt = result;
	while (t != null) {						// for each sibling of the root
	    t = t.getNextSibling();
	    nt.setNextSibling(dupTree(t));	// dup each subtree, building new tree
	    nt = nt.getNextSibling();
	}
	return result;
    }

    /**Duplicate a tree, assuming this is a root node of a tree--
     * duplicate that node and what's below; ignore siblings of root node.
     */
    public AST dupTree(AST t) {
	AST result = dup(t);		// make copy of root
	// copy all children of root.
	if ( t!=null ) {
	    result.setFirstChild( dupList(t.getFirstChild()) );
	}
	return result;
    }

    /** Make a tree from a list of nodes.  The first element in the
     *  array is the root.  If the root is null, then the tree is
     *  a simple list not a tree.  Handles null children nodes correctly.
     *  For example, build(a, b, null, c) yields tree (a b c).  build(null,a,b)
     *  yields tree (nil a b).
     */
    public AST make(AST[] nodes) {
	if ( nodes==null || nodes.length==0 ) return null;
	AST root = nodes[0];
	AST tail = null;
	if (root != null) {
	    root.setFirstChild(null);	// don't leave any old pointers set
	}
	// link in children;
	for (int i=1; i