~ubuntu-branches/ubuntu/dapper/cdrdao/dapper

« back to all changes in this revision

Viewing changes to pccts/h/ast.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephan Hermann
  • Date: 2005-12-10 22:52:11 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20051210225211-rn7q0g36wlbc9a3r
Tags: 1:1.2.1-2ubuntu1
* Resynchronise with debian (orig. debian package)
* Merged debian/changelog to mention ubuntu uploads
* Re-Applied Michael Vogts patches

Show diffs side-by-side

added added

removed removed

Lines of Context:
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-2000
28
 
 */
29
 
 
30
 
#include "pcctscfg.h"
31
 
 
32
 
#ifdef PCCTS_USE_STDARG
33
 
#include "pccts_stdarg.h"
34
 
#else
35
 
#include <varargs.h>
36
 
#endif
37
 
 
38
 
/* ensure that tree manipulation variables are current after a rule
39
 
 * reference
40
 
 */
41
 
 
42
 
void
43
 
#ifdef __USE_PROTOS
44
 
zzlink(AST **_root, AST **_sibling, AST **_tail)
45
 
#else
46
 
zzlink(_root, _sibling, _tail)
47
 
AST **_root, **_sibling, **_tail;
48
 
#endif
49
 
{
50
 
        if ( *_sibling == NULL ) return;
51
 
        if ( *_root == NULL ) *_root = *_sibling;
52
 
        else if ( *_root != *_sibling ) (*_root)->down = *_sibling;
53
 
        if ( *_tail==NULL ) *_tail = *_sibling;
54
 
        while ( (*_tail)->right != NULL ) *_tail = (*_tail)->right;
55
 
}
56
 
 
57
 
AST *
58
 
#ifdef __USE_PROTOS
59
 
zzastnew(void)
60
 
#else
61
 
zzastnew()
62
 
#endif
63
 
{
64
 
        AST *p = (AST *) calloc(1, sizeof(AST));
65
 
        if ( p == NULL ) fprintf(stderr,"%s(%d): cannot allocate AST node\n",__FILE__,__LINE__);
66
 
        return p;
67
 
}
68
 
 
69
 
/* add a child node to the current sibling list */
70
 
void
71
 
#ifdef __USE_PROTOS
72
 
zzsubchild(AST **_root, AST **_sibling, AST **_tail)
73
 
#else
74
 
zzsubchild(_root, _sibling, _tail)
75
 
AST **_root, **_sibling, **_tail;
76
 
#endif
77
 
{
78
 
        AST *n;
79
 
        zzNON_GUESS_MODE {
80
 
        n = zzastnew();
81
 
#ifdef DEMAND_LOOK
82
 
        zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));
83
 
#else
84
 
        zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));
85
 
#endif
86
 
        zzastPush( n );
87
 
        if ( *_tail != NULL ) (*_tail)->right = n;
88
 
        else {
89
 
                *_sibling = n;
90
 
                if ( *_root != NULL ) (*_root)->down = *_sibling;
91
 
        }
92
 
        *_tail = n;
93
 
        if ( *_root == NULL ) *_root = *_sibling;
94
 
        }
95
 
}
96
 
 
97
 
/* make a new AST node.  Make the newly-created
98
 
 * node the root for the current sibling list.  If a root node already
99
 
 * exists, make the newly-created node the root of the current root.
100
 
 */
101
 
void
102
 
#ifdef __USE_PROTOS
103
 
zzsubroot(AST **_root, AST **_sibling, AST **_tail)
104
 
#else
105
 
zzsubroot(_root, _sibling, _tail)
106
 
AST **_root, **_sibling, **_tail;
107
 
#endif
108
 
{
109
 
        AST *n;
110
 
        zzNON_GUESS_MODE {
111
 
        n = zzastnew();
112
 
#ifdef DEMAND_LOOK
113
 
        zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));
114
 
#else
115
 
        zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));
116
 
#endif
117
 
        zzastPush( n );
118
 
        if ( *_root != NULL )
119
 
                if ( (*_root)->down == *_sibling ) *_sibling = *_tail = *_root;
120
 
        *_root = n;
121
 
        (*_root)->down = *_sibling;
122
 
        }
123
 
}
124
 
 
125
 
/* Apply function to root then each sibling
126
 
 * example: print tree in child-sibling LISP-format (AST has token field)
127
 
 *
128
 
 *      void show(tree)
129
 
 *      AST *tree;
130
 
 *      {
131
 
 *              if ( tree == NULL ) return;
132
 
 *              printf(" %s", zztokens[tree->token]);
133
 
 *      }
134
 
 *
135
 
 *      void before() { printf(" ("); }
136
 
 *      void after()  { printf(" )"); }
137
 
 *
138
 
 *      LISPdump() { zzpre_ast(tree, show, before, after); }
139
 
 *
140
 
 */
141
 
void
142
 
#ifdef __USE_PROTOS
143
 
zzpre_ast(
144
 
          AST *tree,
145
 
          void (*func)(AST *),   /* apply this to each tree node */
146
 
          void (*before)(AST *), /* apply this to root of subtree before preordering it */
147
 
          void (*after)(AST *))  /* apply this to root of subtree after preordering it */
148
 
#else
149
 
zzpre_ast(tree, func, before, after)
150
 
AST *tree;
151
 
void (*func)(),   /* apply this to each tree node */
152
 
         (*before)(), /* apply this to root of subtree before preordering it */
153
 
         (*after)();  /* apply this to root of subtree after preordering it */
154
 
#endif
155
 
{
156
 
        while ( tree!= NULL )
157
 
        {
158
 
                if ( tree->down != NULL ) (*before)(tree);
159
 
                (*func)(tree);
160
 
                zzpre_ast(tree->down, func, before, after);
161
 
                if ( tree->down != NULL ) (*after)(tree);
162
 
                tree = tree->right;
163
 
        }
164
 
}
165
 
 
166
 
/* free all AST nodes in tree; apply func to each before freeing */
167
 
 
168
 
#if 0
169
 
////void
170
 
////#ifdef __USE_PROTOS
171
 
////zzfree_ast(AST *tree)
172
 
////#else
173
 
////zzfree_ast(tree)
174
 
////AST *tree;
175
 
////#endif
176
 
////{
177
 
////    if ( tree == NULL ) return;
178
 
////    zzfree_ast( tree->down );
179
 
////    zzfree_ast( tree->right );
180
 
////    zztfree( tree );
181
 
////}
182
 
#endif
183
 
 
184
 
/*
185
 
   MR19 Optimize freeing of the following structure to limit recursion
186
 
   SAKAI Kiyotaka (ksakai@isr.co.jp)
187
 
*/
188
 
 
189
 
/*
190
 
         NULL o
191
 
             / \
192
 
           NULL o
193
 
               / \
194
 
            NULL NULL
195
 
*/
196
 
 
197
 
/*
198
 
   MR21 Another refinement to replace recursion with iteration
199
 
   NAKAJIMA Mutsuki (muc@isr.co.jp).
200
 
*/
201
 
 
202
 
void
203
 
#ifdef __USE_PROTOS
204
 
zzfree_ast(AST *tree)
205
 
#else
206
 
zzfree_ast(tree)
207
 
AST *tree;
208
 
#endif
209
 
{
210
 
 
211
 
    AST *otree;
212
 
 
213
 
    if (tree == NULL) return;
214
 
 
215
 
    while (tree->down == NULL || tree->right == NULL) {
216
 
 
217
 
        if (tree->down == NULL && tree->right == NULL) {
218
 
            zztfree(tree);
219
 
            return;
220
 
        }
221
 
 
222
 
        otree = tree;
223
 
        if (tree->down == NULL) {
224
 
            tree = tree->right;
225
 
        } else {
226
 
            tree = tree->down;
227
 
        }
228
 
        zztfree( otree );
229
 
    }
230
 
 
231
 
    while (tree != NULL) {
232
 
        zzfree_ast(tree->down);
233
 
        otree = tree;
234
 
        tree = otree->right;
235
 
        zztfree(otree);
236
 
    }
237
 
}
238
 
 
239
 
/* build a tree (root child1 child2 ... NULL)
240
 
 * If root is NULL, simply make the children siblings and return ptr
241
 
 * to 1st sibling (child1).  If root is not single node, return NULL.
242
 
 *
243
 
 * Siblings that are actually siblins lists themselves are handled
244
 
 * correctly.  For example #( NULL, #( NULL, A, B, C), D) results
245
 
 * in the tree ( NULL A B C D ).
246
 
 *
247
 
 * Requires at least two parameters with the last one being NULL.  If
248
 
 * both are NULL, return NULL.
249
 
 */
250
 
#ifdef PCCTS_USE_STDARG
251
 
AST *zztmake(AST *rt, ...)
252
 
#else
253
 
AST *zztmake(va_alist)
254
 
va_dcl
255
 
#endif
256
 
{
257
 
        va_list ap;
258
 
        register AST *child, *sibling=NULL, *tail=NULL /* MR20 */, *w;
259
 
        AST *root;
260
 
 
261
 
#ifdef PCCTS_USE_STDARG
262
 
        va_start(ap, rt);
263
 
        root = rt;
264
 
#else
265
 
        va_start(ap);
266
 
        root = va_arg(ap, AST *);
267
 
#endif
268
 
 
269
 
        if ( root != NULL )
270
 
                if ( root->down != NULL ) return NULL;
271
 
        child = va_arg(ap, AST *);
272
 
        while ( child != NULL )
273
 
        {
274
 
                for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */
275
 
                if ( sibling == NULL ) {sibling = child; tail = w;}
276
 
                else {tail->right = child; tail = w;}
277
 
                child = va_arg(ap, AST *);
278
 
        }
279
 
        if ( root==NULL ) root = sibling;
280
 
        else root->down = sibling;
281
 
        va_end(ap);
282
 
        return root;
283
 
}
284
 
 
285
 
/* tree duplicate */
286
 
AST *
287
 
#ifdef __USE_PROTOS
288
 
zzdup_ast(AST *t)
289
 
#else
290
 
zzdup_ast(t)
291
 
AST *t;
292
 
#endif
293
 
{
294
 
        AST *u;
295
 
        
296
 
        if ( t == NULL ) return NULL;
297
 
        u = zzastnew();
298
 
        *u = *t;
299
 
#ifdef zzAST_DOUBLE
300
 
        u->up = NULL;           /* set by calling invocation */
301
 
        u->left = NULL;
302
 
#endif
303
 
        u->right = zzdup_ast(t->right);
304
 
        u->down = zzdup_ast(t->down);
305
 
#ifdef zzAST_DOUBLE
306
 
        if ( u->right!=NULL ) u->right->left = u;
307
 
        if ( u->down!=NULL ) u->down->up = u;
308
 
#endif
309
 
        return u;
310
 
}
311
 
 
312
 
void
313
 
#ifdef __USE_PROTOS
314
 
zztfree(AST *t)
315
 
#else
316
 
zztfree(t)
317
 
AST *t;
318
 
#endif
319
 
{
320
 
#ifdef zzd_ast
321
 
        zzd_ast( t );
322
 
#endif
323
 
        free( t );
324
 
}
325
 
 
326
 
#ifdef zzAST_DOUBLE
327
 
/*
328
 
 * Set the 'up', and 'left' pointers of all nodes in 't'.
329
 
 * Initial call is double_link(your_tree, NULL, NULL).
330
 
 */
331
 
void
332
 
#ifdef __USE_PROTOS
333
 
zzdouble_link(AST *t, AST *left, AST *up)
334
 
#else
335
 
zzdouble_link(t, left, up)
336
 
AST *t, *left, *up;
337
 
#endif
338
 
{
339
 
        if ( t==NULL ) return;
340
 
        t->left = left;
341
 
        t->up = up;
342
 
        zzdouble_link(t->down, NULL, t);
343
 
        zzdouble_link(t->right, t, up);
344
 
}
345
 
#endif