]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/Pccts/h/ASTBase.cpp
1 /* Abstract syntax tree manipulation functions
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.
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
25 * Parr Research Corporation
26 * with Purdue University and AHPCRC, University of Minnesota
32 #include "pccts_stdio.h"
33 #include "pccts_stdarg.h"
37 #define ANTLR_SUPPORT_CODE
41 /* ensure that tree manipulation variables are current after a rule
45 ASTBase::link(ASTBase
**_root
, ASTBase
**_sibling
, ASTBase
**_tail
)
47 if ( *_sibling
== NULL
) return;
48 if ( *_root
== NULL
) *_root
= *_sibling
;
49 else if ( *_root
!= *_sibling
) (*_root
)->_down
= *_sibling
;
50 if ( *_tail
==NULL
) *_tail
= *_sibling
;
51 while ( (*_tail
)->_right
!= NULL
) *_tail
= (*_tail
)->_right
;
54 /* add a child node to the current sibling list */
56 ASTBase::subchild(ASTBase
**_root
, ASTBase
**_sibling
, ASTBase
**_tail
)
58 if ( *_tail
!= NULL
) (*_tail
)->_right
= this;
61 if ( *_root
!= NULL
) (*_root
)->_down
= *_sibling
;
64 if ( *_root
== NULL
) *_root
= *_sibling
;
67 /* make a new AST node. Make the newly-created
68 * node the root for the current sibling list. If a root node already
69 * exists, make the newly-created node the root of the current root.
72 ASTBase::subroot(ASTBase
**_root
, ASTBase
**_sibling
, ASTBase
**_tail
)
75 if ( (*_root
)->_down
== *_sibling
) *_sibling
= *_tail
= *_root
;
77 (*_root
)->_down
= *_sibling
;
80 /* Apply preorder_action(), etc.. to root then each sibling */
83 // Fix suggested by Ron House (house@helios.usq.edu.au)
86 ASTBase::preorder(void* pData
/*= NULL*/ /* MR23 */)
92 if ( tree
->_down
!= NULL
) {
93 tree
->preorder_before_action(pData
); // MR1
95 tree
->preorder_action(pData
);
96 if ( tree
->_down
!=NULL
)
98 tree
->_down
->preorder(pData
);
99 tree
->preorder_after_action(pData
); // MR1
105 /* free all AST nodes in tree; apply func to each before freeing */
109 ASTBase
* tree
= this;
111 if (tree
->_down
) tree
->_down
->destroy();
119 /* build a tree (root child1 child2 ... NULL)
120 * If root is NULL, simply make the children siblings and return ptr
121 * to 1st sibling (child1). If root is not single node, return NULL.
123 * Siblings that are actually siblins lists themselves are handled
124 * correctly. For example #( NULL, #( NULL, A, B, C), D) results
125 * in the tree ( NULL A B C D ).
127 * Requires at least two parameters with the last one being NULL. If
128 * both are NULL, return NULL.
131 ASTBase::tmake(ASTBase
*root
, ...)
134 register ASTBase
*child
, *sibling
=NULL
, *tail
=NULL
/*MR23*/, *w
;
139 if ( root
->_down
!= NULL
) {
140 root
->reportOverwriteOfDownPointer(); /* MR21 Report problem which almost always an error */
143 child
= va_arg(ap
, ASTBase
*);
144 while ( child
!= NULL
)
146 for (w
=child
; w
->_right
!=NULL
; w
=w
->_right
) {;} /* find end of child */
147 if ( sibling
== NULL
) {sibling
= child
; tail
= w
;}
148 else {tail
->_right
= child
; tail
= w
;}
149 child
= va_arg(ap
, ASTBase
*);
151 if ( root
==NULL
) root
= sibling
;
152 else root
->_down
= sibling
;
157 #ifndef PCCTS_NOT_USING_SOR
160 // forgot to check for NULL this (TJP July 23,1995)
166 if ( t
== NULL
) return NULL
;
171 u
= (ASTBase
*)this->shallowCopy();
172 if ( t
->_right
!=NULL
) u
->_right
= t
->_right
->dup();
173 else u
->_right
= NULL
;
174 if ( t
->_down
!=NULL
) u
->_down
= t
->_down
->dup();
175 else u
->_down
= NULL
;
182 // Fix suggested by Asgeir Olafsson (olafsson@cstar.ac.com)
186 #ifndef PCCTS_NOT_USING_SOR
189 ASTDoublyLinkedBase::dup()
191 ASTDoublyLinkedBase
*u
, *t
=this;
193 if ( t
== NULL
) return NULL
;
194 u
= (ASTDoublyLinkedBase
*)this->shallowCopy();
195 u
->_up
= NULL
; /* set by calling invocation */
197 if (t
->_right
!=NULL
) { // MR1
198 u
->_right
=t
->_right
->dup(); // MR1
199 ((ASTDoublyLinkedBase
*)u
->_right
)->_left
= u
; // MR1
201 u
->_right
= NULL
; // MR1
203 if (t
->_down
!=NULL
) { // MR1
204 u
->_down
= t
->_down
->dup(); // MR1
205 ((ASTDoublyLinkedBase
*)u
->_down
)->_up
= u
; // MR1
207 u
->_down
= NULL
; // MR1
215 * Set the 'up', and 'left' pointers of all nodes in 't'.
216 * Initial call is double_link(your_tree, NULL, NULL).
219 ASTDoublyLinkedBase::double_link(ASTBase
*left
, ASTBase
*up
)
221 ASTDoublyLinkedBase
*t
= this;
223 t
->_left
= (ASTDoublyLinkedBase
*) left
;
224 t
->_up
= (ASTDoublyLinkedBase
*) up
;
225 if (t
->_down
!= NULL
)
226 ((ASTDoublyLinkedBase
*)t
->_down
)->double_link(NULL
, t
);
227 if (t
->_right
!= NULL
)
228 ((ASTDoublyLinkedBase
*)t
->_right
)->double_link(t
, up
);
231 // MR21 ASTBase::reportOverwriteOfDownPointer
233 void ASTBase::reportOverwriteOfDownPointer()
235 panic("Attempt to overwrite down pointer in ASTBase::tmake");
238 // MR21 ASTBase::panic
240 void ASTBase::panic(const char *msg
)
242 /* MR23 */ printMessage(stderr
,"ASTBase panic: %s\n", msg
);
243 exit(PCCTS_EXIT_FAILURE
);
246 #ifdef PCCTS_NOT_USING_SOR
248 int ASTBase::printMessage(FILE* pFile
, const char* pFormat
, ...)
251 va_start( marker
, pFormat
);
252 int iRet
= vfprintf(pFile
, pFormat
, marker
);