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

编译器/解释器

开发平台:

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. #ifdef __STDC__
  31. #include PCCTS_STDARG_H
  32. #else
  33. #include <varargs.h>
  34. #endif
  35. /* ensure that tree manipulation variables are current after a rule
  36.  * reference
  37.  */
  38. void
  39. #ifdef __STDC__
  40. zzlink(AST **_root, AST **_sibling, AST **_tail)
  41. #else
  42. zzlink(_root, _sibling, _tail)
  43. AST **_root, **_sibling, **_tail;
  44. #endif
  45. {
  46. if ( *_sibling == NULL ) return;
  47. if ( *_root == NULL ) *_root = *_sibling;
  48. else if ( *_root != *_sibling ) (*_root)->down = *_sibling;
  49. if ( *_tail==NULL ) *_tail = *_sibling;
  50. while ( (*_tail)->right != NULL ) *_tail = (*_tail)->right;
  51. }
  52. AST *
  53. #ifdef __STDC__
  54. zzastnew(void)
  55. #else
  56. zzastnew()
  57. #endif
  58. {
  59. AST *p = (AST *) calloc(1, sizeof(AST));
  60. if ( p == NULL ) fprintf(stderr,"%s(%d): cannot allocate AST noden",__FILE__,__LINE__);
  61. return p;
  62. }
  63. /* add a child node to the current sibling list */
  64. void
  65. #ifdef __STDC__
  66. zzsubchild(AST **_root, AST **_sibling, AST **_tail)
  67. #else
  68. zzsubchild(_root, _sibling, _tail)
  69. AST **_root, **_sibling, **_tail;
  70. #endif
  71. {
  72. AST *n;
  73. zzNON_GUESS_MODE {
  74. n = zzastnew();
  75. #ifdef DEMAND_LOOK
  76. zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));
  77. #else
  78. zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));
  79. #endif
  80. zzastPush( n );
  81. if ( *_tail != NULL ) (*_tail)->right = n;
  82. else {
  83. *_sibling = n;
  84. if ( *_root != NULL ) (*_root)->down = *_sibling;
  85. }
  86. *_tail = n;
  87. if ( *_root == NULL ) *_root = *_sibling;
  88. }
  89. }
  90. /* make a new AST node.  Make the newly-created
  91.  * node the root for the current sibling list.  If a root node already
  92.  * exists, make the newly-created node the root of the current root.
  93.  */
  94. void
  95. #ifdef __STDC__
  96. zzsubroot(AST **_root, AST **_sibling, AST **_tail)
  97. #else
  98. zzsubroot(_root, _sibling, _tail)
  99. AST **_root, **_sibling, **_tail;
  100. #endif
  101. {
  102. AST *n;
  103. zzNON_GUESS_MODE {
  104. n = zzastnew();
  105. #ifdef DEMAND_LOOK
  106. zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));
  107. #else
  108. zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));
  109. #endif
  110. zzastPush( n );
  111. if ( *_root != NULL )
  112. if ( (*_root)->down == *_sibling ) *_sibling = *_tail = *_root;
  113. *_root = n;
  114. (*_root)->down = *_sibling;
  115. }
  116. }
  117. /* Apply function to root then each sibling
  118.  * example: print tree in child-sibling LISP-format (AST has token field)
  119.  *
  120.  * void show(tree)
  121.  * AST *tree;
  122.  * {
  123.  * if ( tree == NULL ) return;
  124.  * printf(" %s", zztokens[tree->token]);
  125.  * }
  126.  *
  127.  * void before() { printf(" ("); }
  128.  * void after()  { printf(" )"); }
  129.  *
  130.  * LISPdump() { zzpre_ast(tree, show, before, after); }
  131.  *
  132.  */
  133. void
  134. #ifdef __STDC__
  135. zzpre_ast(
  136.   AST *tree,
  137.   void (*func)(AST *),   /* apply this to each tree node */
  138.   void (*before)(AST *), /* apply this to root of subtree before preordering it */
  139.   void (*after)(AST *))  /* apply this to root of subtree after preordering it */
  140. #else
  141. zzpre_ast(tree, func, before, after)
  142. AST *tree;
  143. void (*func)(),   /* apply this to each tree node */
  144.  (*before)(), /* apply this to root of subtree before preordering it */
  145.  (*after)();  /* apply this to root of subtree after preordering it */
  146. #endif
  147. {
  148. while ( tree!= NULL )
  149. {
  150. if ( tree->down != NULL ) (*before)(tree);
  151. (*func)(tree);
  152. zzpre_ast(tree->down, func, before, after);
  153. if ( tree->down != NULL ) (*after)(tree);
  154. tree = tree->right;
  155. }
  156. }
  157. /* free all AST nodes in tree; apply func to each before freeing */
  158. void
  159. #ifdef __STDC__
  160. zzfree_ast(AST *tree)
  161. #else
  162. zzfree_ast(tree)
  163. AST *tree;
  164. #endif
  165. {
  166. if ( tree == NULL ) return;
  167. zzfree_ast( tree->down );
  168. zzfree_ast( tree->right );
  169. zztfree( tree );
  170. }
  171. /* build a tree (root child1 child2 ... NULL)
  172.  * If root is NULL, simply make the children siblings and return ptr
  173.  * to 1st sibling (child1).  If root is not single node, return NULL.
  174.  *
  175.  * Siblings that are actually siblins lists themselves are handled
  176.  * correctly.  For example #( NULL, #( NULL, A, B, C), D) results
  177.  * in the tree ( NULL A B C D ).
  178.  *
  179.  * Requires at least two parameters with the last one being NULL.  If
  180.  * both are NULL, return NULL.
  181.  */
  182. #ifdef __STDC__
  183. AST *zztmake(AST *rt, ...)
  184. #else
  185. AST *zztmake(va_alist)
  186. va_dcl
  187. #endif
  188. {
  189. va_list ap;
  190. register AST *child, *sibling=NULL, *tail, *w;
  191. AST *root;
  192. #ifdef __STDC__
  193. va_start(ap, rt);
  194. root = rt;
  195. #else
  196. va_start(ap);
  197. root = va_arg(ap, AST *);
  198. #endif
  199. if ( root != NULL )
  200. if ( root->down != NULL ) return NULL;
  201. child = va_arg(ap, AST *);
  202. while ( child != NULL )
  203. {
  204. for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */
  205. if ( sibling == NULL ) {sibling = child; tail = w;}
  206. else {tail->right = child; tail = w;}
  207. child = va_arg(ap, AST *);
  208. }
  209. if ( root==NULL ) root = sibling;
  210. else root->down = sibling;
  211. va_end(ap);
  212. return root;
  213. }
  214. /* tree duplicate */
  215. AST *
  216. #ifdef __STDC__
  217. zzdup_ast(AST *t)
  218. #else
  219. zzdup_ast(t)
  220. AST *t;
  221. #endif
  222. {
  223. AST *u;
  224. if ( t == NULL ) return NULL;
  225. u = zzastnew();
  226. *u = *t;
  227. #ifdef zzAST_DOUBLE
  228. u->up = NULL; /* set by calling invocation */
  229. u->left = NULL;
  230. #endif
  231. u->right = zzdup_ast(t->right);
  232. u->down = zzdup_ast(t->down);
  233. #ifdef zzAST_DOUBLE
  234. if ( u->right!=NULL ) u->right->left = u;
  235. if ( u->down!=NULL ) u->down->up = u;
  236. #endif
  237. return u;
  238. }
  239. void
  240. #ifdef __STDC__
  241. zztfree(AST *t)
  242. #else
  243. zztfree(t)
  244. AST *t;
  245. #endif
  246. {
  247. #ifdef zzd_ast
  248. zzd_ast( t );
  249. #endif
  250. free( t );
  251. }
  252. #ifdef zzAST_DOUBLE
  253. /*
  254.  * Set the 'up', and 'left' pointers of all nodes in 't'.
  255.  * Initial call is double_link(your_tree, NULL, NULL).
  256.  */
  257. void
  258. #ifdef __STDC__
  259. zzdouble_link(AST *t, AST *left, AST *up)
  260. #else
  261. zzdouble_link(t, left, up)
  262. AST *t, *left, *up;
  263. #endif
  264. {
  265. if ( t==NULL ) return;
  266. t->left = left;
  267. t->up = up;
  268. zzdouble_link(t->down, NULL, t);
  269. zzdouble_link(t->right, t, up);
  270. }
  271. #endif