ASTBase.cpp
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:6k
源码类别:

编译器/解释器

开发平台:

Others

  1. /* Abstract syntax tree manipulation functions
  2.  *
  3.  * SOFTWARE RIGHTS
  4.  *
  5.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  6.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  7.  * company may do whatever they wish with source code distributed with
  8.  * PCCTS or the code generated by PCCTS, including the incorporation of
  9.  * PCCTS, or its output, into commerical software.
  10.  *
  11.  * We encourage users to develop software with PCCTS.  However, we do ask
  12.  * that credit is given to us for developing PCCTS.  By "credit",
  13.  * we mean that if you incorporate our source code into one of your
  14.  * programs (commercial product, research project, or otherwise) that you
  15.  * acknowledge this fact somewhere in the documentation, research report,
  16.  * etc...  If you like PCCTS and have developed a nice tool with the
  17.  * output, please mention that you developed it using PCCTS.  In
  18.  * addition, we ask that this header remain intact in our source code.
  19.  * As long as these guidelines are kept, we expect to continue enhancing
  20.  * this system and expect to make other tools available as they are
  21.  * completed.
  22.  *
  23.  * ANTLR 1.33
  24.  * Terence Parr
  25.  * Parr Research Corporation
  26.  * with Purdue University and AHPCRC, University of Minnesota
  27.  * 1989-1998
  28.  */
  29. #include "pcctscfg.h"
  30. #include PCCTS_STDIO_H
  31. #include PCCTS_STDARG_H
  32. PCCTS_NAMESPACE_STD
  33. #define ANTLR_SUPPORT_CODE
  34. #include "ASTBase.h"
  35. /* ensure that tree manipulation variables are current after a rule
  36.  * reference
  37.  */
  38. void
  39. ASTBase::link(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
  40. {
  41. if ( *_sibling == NULL ) return;
  42. if ( *_root == NULL ) *_root = *_sibling;
  43. else if ( *_root != *_sibling ) (*_root)->_down = *_sibling;
  44. if ( *_tail==NULL ) *_tail = *_sibling;
  45. while ( (*_tail)->_right != NULL ) *_tail = (*_tail)->_right;
  46. }
  47. /* add a child node to the current sibling list */
  48. void
  49. ASTBase::subchild(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
  50. {
  51. if ( *_tail != NULL ) (*_tail)->_right = this;
  52. else {
  53. *_sibling = this;
  54. if ( *_root != NULL ) (*_root)->_down = *_sibling;
  55. }
  56. *_tail = this;
  57. if ( *_root == NULL ) *_root = *_sibling;
  58. }
  59. /* make a new AST node.  Make the newly-created
  60.  * node the root for the current sibling list.  If a root node already
  61.  * exists, make the newly-created node the root of the current root.
  62.  */
  63. void
  64. ASTBase::subroot(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
  65. {
  66. if ( *_root != NULL )
  67. if ( (*_root)->_down == *_sibling ) *_sibling = *_tail = *_root;
  68. *_root = this;
  69. (*_root)->_down = *_sibling;
  70. }
  71. /* Apply preorder_action(), etc.. to root then each sibling */
  72. //
  73. //  7-Apr-97 133MR1
  74. // Fix suggested by Ron House (house@helios.usq.edu.au)
  75. //
  76. void
  77. ASTBase::preorder()
  78. {
  79. ASTBase *tree = this;
  80. while ( tree!= NULL )
  81. {
  82. if ( tree->_down != NULL ) {
  83. tree->preorder_before_action();  // MR1
  84. };
  85. tree->preorder_action();
  86. if ( tree->_down!=NULL )
  87. {
  88. tree->_down->preorder();
  89. tree->preorder_after_action(); // MR1
  90. }
  91. tree = tree->_right;
  92. }
  93. }
  94. /* free all AST nodes in tree; apply func to each before freeing */
  95. void
  96. ASTBase::destroy()
  97. {
  98.    ASTBase* tree = this;
  99.    while (tree) {
  100.       if (tree->_down) tree->_down->destroy();
  101.       ASTBase* cur = tree;
  102.       tree = tree->_right;
  103.       delete cur;
  104.    }
  105. }
  106. /* build a tree (root child1 child2 ... NULL)
  107.  * If root is NULL, simply make the children siblings and return ptr
  108.  * to 1st sibling (child1).  If root is not single node, return NULL.
  109.  *
  110.  * Siblings that are actually siblins lists themselves are handled
  111.  * correctly.  For example #( NULL, #( NULL, A, B, C), D) results
  112.  * in the tree ( NULL A B C D ).
  113.  *
  114.  * Requires at least two parameters with the last one being NULL.  If
  115.  * both are NULL, return NULL.
  116.  */
  117. ASTBase *
  118. ASTBase::tmake(ASTBase *root, ...)
  119. {
  120. va_list ap;
  121. register ASTBase *child, *sibling=NULL, *tail, *w;
  122. va_start(ap, root);
  123. if ( root != NULL )
  124. if ( root->_down != NULL ) return NULL;
  125. child = va_arg(ap, ASTBase *);
  126. while ( child != NULL )
  127. {
  128. for (w=child; w->_right!=NULL; w=w->_right) {;} /* find end of child */
  129. if ( sibling == NULL ) {sibling = child; tail = w;}
  130. else {tail->_right = child; tail = w;}
  131. child = va_arg(ap, ASTBase *);
  132. }
  133. if ( root==NULL ) root = sibling;
  134. else root->_down = sibling;
  135. va_end(ap);
  136. return root;
  137. }
  138. #ifndef PCCTS_NOT_USING_SOR
  139. /* tree duplicate */
  140. // forgot to check for NULL this (TJP July 23,1995)
  141. ASTBase *
  142. ASTBase::dup()
  143. {
  144. ASTBase *u, *t=this;
  145. if ( t == NULL ) return NULL;
  146. /*
  147. u = new ASTBase;
  148. *u = *t;
  149. */
  150. u = (ASTBase *)this->shallowCopy();
  151. if ( t->_right!=NULL ) u->_right = t->_right->dup();
  152. else u->_right = NULL;
  153. if ( t->_down!=NULL ) u->_down = t->_down->dup();
  154. else u->_down = NULL;
  155. return u;
  156. }
  157. #endif
  158. //
  159. //  7-Apr-97 133MR1
  160. //        Fix suggested by Asgeir Olafsson (olafsson@cstar.ac.com)
  161. //
  162. /* tree duplicate */
  163. #ifndef PCCTS_NOT_USING_SOR
  164. ASTBase *
  165. ASTDoublyLinkedBase::dup()
  166. {
  167. ASTDoublyLinkedBase *u, *t=this;
  168. if ( t == NULL ) return NULL;
  169. u = (ASTDoublyLinkedBase *)this->shallowCopy();
  170. u->_up = NULL; /* set by calling invocation */
  171. u->_left = NULL;
  172. if (t->_right!=NULL) { // MR1
  173.           u->_right=t->_right->dup(); // MR1
  174.   ((ASTDoublyLinkedBase *)u->_right)->_left = u; // MR1
  175.         } else { // MR1
  176.   u->_right = NULL; // MR1
  177.         }; // MR1
  178. if (t->_down!=NULL) { // MR1
  179.      u->_down = t->_down->dup(); // MR1
  180.           ((ASTDoublyLinkedBase *)u->_down)->_up = u; // MR1
  181.         } else { // MR1
  182.   u->_down = NULL; // MR1
  183.         }; // MR1
  184. return u;
  185. }
  186. #endif
  187. /*
  188.  * Set the 'up', and 'left' pointers of all nodes in 't'.
  189.  * Initial call is double_link(your_tree, NULL, NULL).
  190.  */
  191. void
  192. ASTDoublyLinkedBase::double_link(ASTBase *left, ASTBase *up)
  193. {
  194.     ASTDoublyLinkedBase *t = this;
  195.     t->_left = (ASTDoublyLinkedBase *) left;
  196.     t->_up = (ASTDoublyLinkedBase *) up;
  197.     if (t->_down != NULL)
  198. ((ASTDoublyLinkedBase *)t->_down)->double_link(NULL, t);
  199.     if (t->_right != NULL)
  200. ((ASTDoublyLinkedBase *)t->_right)->double_link(t, up);
  201. }