ASTFactory.java
上传用户:afrynkmhm
上传日期:2007-01-06
资源大小:1262k
文件大小:6k
源码类别:

编译器/解释器

开发平台:

Others

  1. package antlr;
  2. /* ANTLR Translator Generator
  3.  * Project led by Terence Parr at http://www.jGuru.com
  4.  * Software rights: http://www.antlr.org/RIGHTS.html
  5.  *
  6.  * $Id: //depot/code/org.antlr/release/antlr-2.7.0/antlr/ASTFactory.java#1 $
  7.  */
  8. import antlr.collections.AST;
  9. import antlr.collections.impl.ASTArray;
  10. /** AST Support code shared by TreeParser and Parser.
  11.  *  We use delegation to share code (and have only one
  12.  *  bit of code to maintain) rather than subclassing
  13.  *  or superclassing (forces AST support code to be
  14.  *  loaded even when you don't want to do AST stuff).
  15.  *
  16.  *  Typically, setASTNodeType is used to specify the
  17.  *  type of node to create, but you can override
  18.  *  create to make heterogeneous nodes etc...
  19.  */
  20. public class ASTFactory {
  21.     /** Name of AST class to create during tree construction.
  22.      *  Null implies that the create method should create
  23.      *  a default AST type such as CommonAST.
  24.      */
  25.     protected String theASTNodeType = null;
  26.     protected Class theASTNodeTypeClass = null;
  27.     /** Add a child to the current AST */
  28.     public void addASTChild(ASTPair currentAST, AST child) {
  29. if (child != null) {
  30.     if (currentAST.root == null) {
  31. // Make new child the current root
  32. currentAST.root = child;
  33.     } 
  34.     else {
  35. if (currentAST.child == null) {
  36.     // Add new child to current root
  37.     currentAST.root.setFirstChild(child);
  38. }
  39. else {
  40.     currentAST.child.setNextSibling(child);
  41. }
  42.     }
  43.     // Make new child the current child
  44.     currentAST.child = child;
  45.     currentAST.advanceChildToEnd();
  46. }
  47.     }
  48.     /** Create a new empty AST node; if the user did not specify
  49.      *  an AST node type, then create a default one: CommonAST.
  50.      */
  51.     public AST create() {
  52. AST t = null;
  53. if (theASTNodeTypeClass == null) {
  54.     t = new CommonAST();
  55. } else {
  56.     try {
  57. t = (AST) theASTNodeTypeClass.newInstance(); // make a new one
  58.     } catch (Exception e) {
  59. antlr.Tool.warning("Can't create AST Node " + theASTNodeType);
  60. return null;
  61.     }
  62. }
  63. return t;
  64.     }
  65.     public AST create(int type) { 
  66. AST t = create();
  67. t.initialize(type,"");
  68. return t;
  69.     }
  70.     public AST create(int type, String txt) { 
  71. AST t = create();
  72. t.initialize(type,txt);
  73. return t;
  74.     }
  75.     /** Create a new empty AST node; if the user did not specify
  76.      *  an AST node type, then create a default one: CommonAST.
  77.      */
  78.     public AST create(AST tr) { 
  79. if ( tr==null ) return null; // create(null) == null
  80. AST t = create();
  81. t.initialize(tr);
  82. return t;
  83.     }
  84.     public AST create(Token tok) { 
  85. AST t = create();
  86. t.initialize(tok);
  87. return t;
  88.     }
  89.     /** Copy a single node.  clone() is not used because
  90.      *  we want to return an AST not a plain object...a type
  91.      *  safety issue.  Further, we want to have all AST node
  92.      *  creation go through the factory so creation can be
  93.      *  tracked.  Returns null if t is null.
  94.      */
  95.     public AST dup(AST t) {
  96. return create(t); // if t==null, create returns null
  97.     }
  98.     /** Duplicate tree including siblings of root. */
  99.     public AST dupList(AST t) {
  100. AST result = dupTree(t);            // if t == null, then result==null
  101. AST nt = result;
  102. while (t != null) { // for each sibling of the root
  103.     t = t.getNextSibling();
  104.     nt.setNextSibling(dupTree(t)); // dup each subtree, building new tree
  105.     nt = nt.getNextSibling();
  106. }
  107. return result;
  108.     }
  109.     /**Duplicate a tree, assuming this is a root node of a tree--
  110.      * duplicate that node and what's below; ignore siblings of root node.
  111.      */
  112.     public AST dupTree(AST t) {
  113. AST result = dup(t); // make copy of root
  114. // copy all children of root.
  115. if ( t!=null ) {
  116.     result.setFirstChild( dupList(t.getFirstChild()) );
  117. }
  118. return result;
  119.     }
  120.     /** Make a tree from a list of nodes.  The first element in the
  121.      *  array is the root.  If the root is null, then the tree is
  122.      *  a simple list not a tree.  Handles null children nodes correctly.
  123.      *  For example, build(a, b, null, c) yields tree (a b c).  build(null,a,b)
  124.      *  yields tree (nil a b).
  125.      */
  126.     public AST make(AST[] nodes) {
  127. if ( nodes==null || nodes.length==0 ) return null;
  128. AST root = nodes[0];
  129. AST tail = null;
  130. if (root != null) {
  131.     root.setFirstChild(null); // don't leave any old pointers set
  132. }
  133. // link in children;
  134. for (int i=1; i<nodes.length; i++) {
  135.     if ( nodes[i]==null ) continue; // ignore null nodes
  136.     if (root == null) {
  137. // Set the root and set it up for a flat list
  138. root = tail = nodes[i];
  139.     }
  140.     else if ( tail==null ) {
  141. root.setFirstChild(nodes[i]);
  142. tail = root.getFirstChild();
  143.     }
  144.     else {
  145. tail.setNextSibling(nodes[i]);
  146. tail = tail.getNextSibling();
  147.     }
  148.     // Chase tail to last sibling
  149.     while (tail.getNextSibling() != null) {
  150. tail = tail.getNextSibling();
  151.     }
  152. }
  153. return root;
  154.     }
  155.     /** Make a tree from a list of nodes, where the nodes are contained
  156.      * in an ASTArray object
  157.      */
  158.     public AST make(ASTArray nodes) {
  159. return make(nodes.array);
  160.     }
  161.     /** Make an AST the root of current AST */
  162.     public void makeASTRoot(ASTPair currentAST, AST root) {
  163. if (root != null) {
  164.     // Add the current root as a child of new root
  165.     root.addChild(currentAST.root);
  166.     // The new current child is the last sibling of the old root
  167.     currentAST.child = currentAST.root;
  168.     currentAST.advanceChildToEnd();
  169.     // Set the new root
  170.     currentAST.root = root;
  171. }
  172.     }
  173.     public void setASTNodeType(String t) {
  174. theASTNodeType = t;
  175. try {
  176.     theASTNodeTypeClass = Class.forName(t); // get class def
  177. } catch (Exception e) {
  178.     // either class not found,
  179.     // class is interface/abstract, or
  180.     // class or initializer is not accessible.
  181.     antlr.Tool.warning("Can't find/access AST Node type"+t);
  182. }
  183.     }
  184. }