EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

BaseTools/Source/C/VfrCompile/Pccts/h/ASTBase.cpp

Go to the documentation of this file.
00001 /* Abstract syntax tree manipulation functions
00002  *
00003  * SOFTWARE RIGHTS
00004  *
00005  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
00006  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
00007  * company may do whatever they wish with source code distributed with
00008  * PCCTS or the code generated by PCCTS, including the incorporation of
00009  * PCCTS, or its output, into commerical software.
00010  *
00011  * We encourage users to develop software with PCCTS.  However, we do ask
00012  * that credit is given to us for developing PCCTS.  By "credit",
00013  * we mean that if you incorporate our source code into one of your
00014  * programs (commercial product, research project, or otherwise) that you
00015  * acknowledge this fact somewhere in the documentation, research report,
00016  * etc...  If you like PCCTS and have developed a nice tool with the
00017  * output, please mention that you developed it using PCCTS.  In
00018  * addition, we ask that this header remain intact in our source code.
00019  * As long as these guidelines are kept, we expect to continue enhancing
00020  * this system and expect to make other tools available as they are
00021  * completed.
00022  *
00023  * ANTLR 1.33
00024  * Terence Parr
00025  * Parr Research Corporation
00026  * with Purdue University and AHPCRC, University of Minnesota
00027  * 1989-2000
00028  */
00029 
00030 #include "pcctscfg.h"
00031 
00032 #include "pccts_stdio.h"
00033 #include "pccts_stdarg.h"
00034 
00035 PCCTS_NAMESPACE_STD
00036 
00037 #define ANTLR_SUPPORT_CODE
00038 
00039 #include "ASTBase.h"
00040 
00041 /* ensure that tree manipulation variables are current after a rule
00042  * reference
00043  */
00044 void
00045 ASTBase::link(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
00046 {
00047         if ( *_sibling == NULL ) return;
00048         if ( *_root == NULL ) *_root = *_sibling;
00049         else if ( *_root != *_sibling ) (*_root)->_down = *_sibling;
00050         if ( *_tail==NULL ) *_tail = *_sibling;
00051         while ( (*_tail)->_right != NULL ) *_tail = (*_tail)->_right;
00052 }
00053 
00054 /* add a child node to the current sibling list */
00055 void
00056 ASTBase::subchild(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
00057 {
00058         if ( *_tail != NULL ) (*_tail)->_right = this;
00059         else {
00060                 *_sibling = this;
00061                 if ( *_root != NULL ) (*_root)->_down = *_sibling;
00062         }
00063         *_tail = this;
00064         if ( *_root == NULL ) *_root = *_sibling;
00065 }
00066 
00067 /* make a new AST node.  Make the newly-created
00068  * node the root for the current sibling list.  If a root node already
00069  * exists, make the newly-created node the root of the current root.
00070  */
00071 void
00072 ASTBase::subroot(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
00073 {
00074         if ( *_root != NULL )
00075                 if ( (*_root)->_down == *_sibling ) *_sibling = *_tail = *_root;
00076         *_root = this;
00077         (*_root)->_down = *_sibling;
00078 }
00079 
00080 /* Apply preorder_action(), etc.. to root then each sibling */
00081 //
00082 //  7-Apr-97 133MR1
00083 //      Fix suggested by Ron House (house@helios.usq.edu.au)
00084 //
00085 void
00086 ASTBase::preorder(void* pData /*= NULL*/ /* MR23 */)
00087 {
00088         ASTBase *tree = this;
00089 
00090         while ( tree!= NULL )
00091         {
00092                 if ( tree->_down != NULL ) {
00093                         tree->preorder_before_action(pData);            // MR1  
00094                 };
00095                 tree->preorder_action(pData);
00096                 if ( tree->_down!=NULL )
00097                 {
00098                         tree->_down->preorder(pData);
00099                         tree->preorder_after_action(pData);                     // MR1
00100                 }
00101                 tree = tree->_right;
00102         }
00103 }
00104 
00105 /* free all AST nodes in tree; apply func to each before freeing */
00106 void
00107 ASTBase::destroy()
00108 {
00109    ASTBase* tree = this;
00110    while (tree) {
00111       if (tree->_down) tree->_down->destroy();
00112 
00113       ASTBase* cur = tree;
00114       tree = tree->_right;
00115       delete cur;
00116    }
00117 }
00118 
00119 /* build a tree (root child1 child2 ... NULL)
00120  * If root is NULL, simply make the children siblings and return ptr
00121  * to 1st sibling (child1).  If root is not single node, return NULL.
00122  *
00123  * Siblings that are actually siblins lists themselves are handled
00124  * correctly.  For example #( NULL, #( NULL, A, B, C), D) results
00125  * in the tree ( NULL A B C D ).
00126  *
00127  * Requires at least two parameters with the last one being NULL.  If
00128  * both are NULL, return NULL.
00129  */
00130 ASTBase *
00131 ASTBase::tmake(ASTBase *root, ...)
00132 {
00133         va_list ap;
00134         register ASTBase *child, *sibling=NULL, *tail=NULL /*MR23*/, *w;
00135 
00136         va_start(ap, root);
00137 
00138         if ( root != NULL )
00139                 if ( root->_down != NULL ) {  
00140             root->reportOverwriteOfDownPointer();  /* MR21 Report problem which almost always an error */
00141             return NULL;
00142         }
00143         child = va_arg(ap, ASTBase *);
00144         while ( child != NULL )
00145         {
00146                 for (w=child; w->_right!=NULL; w=w->_right) {;} /* find end of child */
00147                 if ( sibling == NULL ) {sibling = child; tail = w;}
00148                 else {tail->_right = child; tail = w;}
00149                 child = va_arg(ap, ASTBase *);
00150         }
00151         if ( root==NULL ) root = sibling;
00152         else root->_down = sibling;
00153         va_end(ap);
00154         return root;
00155 }
00156 
00157 #ifndef PCCTS_NOT_USING_SOR
00158 
00159 /* tree duplicate */
00160 // forgot to check for NULL this (TJP July 23,1995)
00161 ASTBase *
00162 ASTBase::dup()
00163 {
00164         ASTBase *u, *t=this;
00165         
00166         if ( t == NULL ) return NULL;
00167 /*
00168         u = new ASTBase;
00169         *u = *t;
00170 */
00171         u = (ASTBase *)this->shallowCopy();
00172         if ( t->_right!=NULL ) u->_right = t->_right->dup();
00173         else u->_right = NULL;
00174         if ( t->_down!=NULL ) u->_down = t->_down->dup();
00175         else u->_down = NULL;
00176         return u;
00177 }
00178 #endif
00179 
00180 //
00181 //  7-Apr-97 133MR1
00182 //           Fix suggested by Asgeir Olafsson (olafsson@cstar.ac.com)
00183 //
00184 /* tree duplicate */
00185 
00186 #ifndef PCCTS_NOT_USING_SOR
00187 
00188 ASTBase *
00189 ASTDoublyLinkedBase::dup()
00190 {
00191         ASTDoublyLinkedBase *u, *t=this;
00192         
00193         if ( t == NULL ) return NULL;
00194         u = (ASTDoublyLinkedBase *)this->shallowCopy();
00195         u->_up = NULL;          /* set by calling invocation */
00196         u->_left = NULL;
00197         if (t->_right!=NULL) {                                          // MR1
00198           u->_right=t->_right->dup();                                   // MR1
00199           ((ASTDoublyLinkedBase *)u->_right)->_left = u;                // MR1
00200         } else {                                                        // MR1
00201           u->_right = NULL;                                             // MR1
00202         };                                                              // MR1
00203         if (t->_down!=NULL) {                                           // MR1
00204           u->_down = t->_down->dup();                                   // MR1
00205           ((ASTDoublyLinkedBase *)u->_down)->_up = u;                   // MR1
00206         } else {                                                        // MR1
00207           u->_down = NULL;                                              // MR1
00208         };                                                              // MR1
00209         return u;
00210 }
00211 
00212 #endif
00213 
00214 /*
00215  * Set the 'up', and 'left' pointers of all nodes in 't'.
00216  * Initial call is double_link(your_tree, NULL, NULL).
00217  */
00218 void
00219 ASTDoublyLinkedBase::double_link(ASTBase *left, ASTBase *up)
00220 {
00221     ASTDoublyLinkedBase *t = this;
00222 
00223     t->_left = (ASTDoublyLinkedBase *) left;
00224     t->_up = (ASTDoublyLinkedBase *) up;
00225     if (t->_down != NULL)
00226                 ((ASTDoublyLinkedBase *)t->_down)->double_link(NULL, t);
00227     if (t->_right != NULL)
00228                 ((ASTDoublyLinkedBase *)t->_right)->double_link(t, up);
00229 }
00230 
00231 // MR21 ASTBase::reportOverwriteOfDownPointer
00232 
00233 void ASTBase::reportOverwriteOfDownPointer()
00234 {
00235     panic("Attempt to overwrite down pointer in ASTBase::tmake");
00236 }
00237 
00238 // MR21 ASTBase::panic
00239 
00240 void ASTBase::panic(const char *msg)
00241 {
00242         /* MR23 */ printMessage(stderr,"ASTBase panic: %s\n", msg);
00243         exit(PCCTS_EXIT_FAILURE);
00244 }
00245 
00246 #ifdef PCCTS_NOT_USING_SOR
00247 //MR23
00248 int ASTBase::printMessage(FILE* pFile, const char* pFormat, ...)
00249 {
00250         va_list marker;
00251         va_start( marker, pFormat );
00252         int iRet = vfprintf(pFile, pFormat, marker);
00253         va_end( marker );
00254         return iRet;
00255 }
00256 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines