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

BaseTools/Source/C/VfrCompile/Pccts/antlr/build.c

Go to the documentation of this file.
00001 /*
00002  * build.c -- functions associated with building syntax diagrams.
00003  *
00004  * SOFTWARE RIGHTS
00005  *
00006  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
00007  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
00008  * company may do whatever they wish with source code distributed with
00009  * PCCTS or the code generated by PCCTS, including the incorporation of
00010  * PCCTS, or its output, into commerical software.
00011  *
00012  * We encourage users to develop software with PCCTS.  However, we do ask
00013  * that credit is given to us for developing PCCTS.  By "credit",
00014  * we mean that if you incorporate our source code into one of your
00015  * programs (commercial product, research project, or otherwise) that you
00016  * acknowledge this fact somewhere in the documentation, research report,
00017  * etc...  If you like PCCTS and have developed a nice tool with the
00018  * output, please mention that you developed it using PCCTS.  In
00019  * addition, we ask that this header remain intact in our source code.
00020  * As long as these guidelines are kept, we expect to continue enhancing
00021  * this system and expect to make other tools available as they are
00022  * completed.
00023  *
00024  * ANTLR 1.33
00025  * Terence Parr
00026  * Parr Research Corporation
00027  * with Purdue University and AHPCRC, University of Minnesota
00028  * 1989-2001
00029  */
00030 
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <ctype.h>
00034 #include "pcctscfg.h"
00035 #include "set.h"
00036 #include "syn.h"
00037 #include "hash.h"
00038 #include "generic.h"
00039 #include "dlgdef.h"
00040 
00041 #define SetBlk(g, t, approx, first_set_symbol) {                                \
00042                         ((Junction *)g.left)->jtype = t;                                                \
00043                         ((Junction *)g.left)->approx = approx;                                  \
00044                         ((Junction *)g.left)->pFirstSetSymbol = first_set_symbol;   \
00045                         ((Junction *)g.left)->end = (Junction *) g.right;               \
00046                         ((Junction *)g.right)->jtype = EndBlk;}
00047 
00048 /* Add the parameter string 'parm' to the parms field of a block-type junction
00049  * g.left points to the sentinel node on a block.  i.e. g.left->p1 points to
00050  * the actual junction with its jtype == some block-type.
00051  */
00052 void
00053 #ifdef __USE_PROTOS
00054 addParm( Node *p, char *parm )
00055 #else
00056 addParm( p, parm )
00057 Node *p;
00058 char *parm;
00059 #endif
00060 {
00061         char *q = (char *) malloc( strlen(parm) + 1 );
00062         require(p!=NULL, "addParm: NULL object\n");
00063         require(q!=NULL, "addParm: unable to alloc parameter\n");
00064 
00065         strcpy(q, parm);
00066         if ( p->ntype == nRuleRef )
00067         {
00068                 ((RuleRefNode *)p)->parms = q;
00069         }
00070         else if ( p->ntype == nJunction )
00071         {
00072                 ((Junction *)p)->parm = q;      /* only one parameter allowed on subrules */
00073         }
00074         else fatal_internal("addParm: invalid node for adding parm");
00075 }
00076 
00077 /*
00078  * Build an action node for the syntax diagram
00079  *
00080  * buildAction(ACTION) ::= --o-->ACTION-->o--
00081  *
00082  * Where o is a junction node.
00083  */
00084 Graph
00085 #ifdef __USE_PROTOS
00086 buildAction( char *action, int file, int line, int is_predicate )
00087 #else
00088 buildAction( action, file, line, is_predicate )
00089 char *action;
00090 int file;
00091 int line;
00092 int is_predicate;
00093 #endif
00094 {
00095         Junction *j1, *j2;
00096         Graph g;
00097         ActionNode *a;
00098         require(action!=NULL, "buildAction: invalid action");
00099         
00100         j1 = newJunction();
00101         j2 = newJunction();
00102         a = newActionNode();
00103         a->action = (char *) malloc( strlen(action)+1 );
00104         require(a->action!=NULL, "buildAction: cannot alloc space for action\n");
00105         strcpy(a->action, action);
00106         j1->p1 = (Node *) a;
00107         a->next = (Node *) j2;
00108         a->is_predicate = is_predicate;
00109 
00110     if (is_predicate) {
00111         PredEntry   *predEntry;
00112         char        *t;
00113         char        *key;
00114         char        *u;
00115         int         inverted=0;
00116 
00117         t=key=(char *)calloc(1,strlen(a->action)+1);
00118 
00119         for (u=a->action; *u != '\0' ; u++) {
00120           if (*u != ' ') {
00121             if (t==key && *u=='!') {
00122               inverted=!inverted;
00123             } else {
00124               *t++=*u;
00125             };
00126           };
00127         };
00128 
00129         *t='\0';
00130 
00131 
00132         predEntry=(PredEntry *)hash_get(Pname,key);
00133         a->predEntry=predEntry;
00134         if (predEntry != NULL) a->inverted=inverted;
00135     } else {
00136 /* MR12c */      char  *strStart=a->action;
00137 /* MR12c */      char  *strEnd;
00138 /* MR12c */      strEnd=strStart+strlen(strStart)-1;
00139 /* MR12c */      for ( ; strEnd >= strStart &&  isspace(*strEnd); strEnd--) *strEnd=0;
00140 /* MR12c */      while (*strStart != '\0' && isspace(*strStart)) strStart++;
00141 /* MR12c */      if (ci_strequ(strStart,"nohoist")) {
00142 /* MR12c */        a->noHoist=1;
00143 /* MR12c */      }
00144         }
00145 
00146         g.left = (Node *) j1; g.right = (Node *) j2;
00147         a->file = file;
00148         a->line = line;
00149         a->rname = CurRule;     /* MR10 */
00150         return g;
00151 }
00152 
00153 /*
00154  * Build a token node for the syntax diagram
00155  *
00156  * buildToken(TOKEN) ::= --o-->TOKEN-->o--
00157  *
00158  * Where o is a junction node.
00159  */
00160 Graph
00161 #ifdef __USE_PROTOS
00162 buildToken( char *text )
00163 #else
00164 buildToken( text )
00165 char *text;
00166 #endif
00167 {
00168         Junction *j1, *j2;
00169         Graph g;
00170         TokNode *t;
00171         require(text!=NULL, "buildToken: invalid token name");
00172         
00173         j1 = newJunction();
00174         j2 = newJunction();
00175         t = newTokNode();
00176         t->altstart = CurAltStart;
00177         if ( *text == '"' ) {t->label=FALSE; t->token = addTexpr( text );}
00178         else {t->label=TRUE; t->token = addTname( text );}
00179         j1->p1 = (Node *) t;
00180         t->next = (Node *) j2;
00181         g.left = (Node *) j1; g.right = (Node *) j2;
00182         return g;
00183 }
00184 
00185 /*
00186  * Build a wild-card node for the syntax diagram
00187  *
00188  * buildToken(TOKEN) ::= --o-->'.'-->o--
00189  *
00190  * Where o is a junction node.
00191  */
00192 Graph
00193 #ifdef __USE_PROTOS
00194 buildWildCard( char *text )
00195 #else
00196 buildWildCard( text )
00197 char *text;
00198 #endif
00199 {
00200         Junction *j1, *j2;
00201         Graph g;
00202         TokNode *t;
00203         TCnode *w;
00204         TermEntry *p;
00205         require(text!=NULL, "buildWildCard: invalid token name");
00206         
00207         j1 = newJunction();
00208         j2 = newJunction();
00209         t = newTokNode();
00210 
00211         /* If the ref a wild card, make a token class for it */
00212         if ( Tnum(WildCardString) == 0 )
00213         {
00214                 w = newTCnode;
00215                 w->tok = addTname( WildCardString );
00216                 set_orel(w->tok, &imag_tokens);
00217                 set_orel(w->tok, &tokclasses);
00218                 WildCardToken = w->tok;
00219                 require((p=(TermEntry *)hash_get(Tname, WildCardString)) != NULL,
00220                                 "hash table mechanism is broken");
00221                 p->classname = 1;       /* entry is class name, not token */
00222                 p->tclass = w;          /* save ptr to this tclass def */
00223                 list_add(&tclasses, (char *)w);
00224         }
00225         else {
00226                 p=(TermEntry *)hash_get(Tname, WildCardString);
00227                 require( p!= NULL, "hash table mechanism is broken");
00228                 w = p->tclass;
00229         }
00230 
00231         t->token = w->tok;
00232         t->wild_card = 1;
00233         t->tclass = w;
00234 
00235         t->altstart = CurAltStart;
00236         j1->p1 = (Node *) t;
00237         t->next = (Node *) j2;
00238         g.left = (Node *) j1; g.right = (Node *) j2;
00239         return g;
00240 }
00241 
00242 void
00243 #ifdef __USE_PROTOS
00244 setUpperRange(TokNode *t, char *text)
00245 #else
00246 setUpperRange(t, text)
00247 TokNode *t;
00248 char *text;
00249 #endif
00250 {
00251         require(t!=NULL, "setUpperRange: NULL token node");
00252         require(text!=NULL, "setUpperRange: NULL token string");
00253 
00254         if ( *text == '"' ) {t->upper_range = addTexpr( text );}
00255         else {t->upper_range = addTname( text );}
00256 }
00257 
00258 /*
00259  * Build a rule reference node of the syntax diagram
00260  *
00261  * buildRuleRef(RULE) ::= --o-->RULE-->o--
00262  *
00263  * Where o is a junction node.
00264  *
00265  * If rule 'text' has been defined already, don't alloc new space to store string.
00266  * Set r->text to point to old copy in string table.
00267  */
00268 Graph
00269 #ifdef __USE_PROTOS
00270 buildRuleRef( char *text )
00271 #else
00272 buildRuleRef( text )
00273 char *text;
00274 #endif
00275 {
00276         Junction *j1, *j2;
00277         Graph g;
00278         RuleRefNode *r;
00279         RuleEntry *p;
00280         require(text!=NULL, "buildRuleRef: invalid rule name");
00281         
00282         j1 = newJunction();
00283         j2 = newJunction();
00284         r = newRNode();
00285         r->altstart = CurAltStart;
00286         r->assign = NULL;
00287         if ( (p=(RuleEntry *)hash_get(Rname, text)) != NULL ) r->text = p->str;
00288         else r->text = mystrdup( text );
00289         j1->p1  = (Node *) r;
00290         r->next = (Node *) j2;
00291         g.left = (Node *) j1; g.right = (Node *) j2;
00292         return g;
00293 }
00294 
00295 /*
00296  * Or two subgraphs into one graph via:
00297  *
00298  * Or(G1, G2) ::= --o-G1-o--
00299  *                  |    ^
00300  *                                      v    |
00301  *                  o-G2-o
00302  *
00303  * Set the altnum of junction starting G2 to 1 + altnum of junction starting G1.
00304  * If, however, the G1 altnum is 0, make it 1 and then
00305  * make G2 altnum = G1 altnum + 1.
00306  */
00307 Graph
00308 #ifdef __USE_PROTOS
00309 Or( Graph g1, Graph g2 )
00310 #else
00311 Or( g1, g2 )
00312 Graph g1;
00313 Graph g2;
00314 #endif
00315 {
00316         Graph g;
00317         require(g1.left != NULL, "Or: invalid graph");
00318         require(g2.left != NULL && g2.right != NULL, "Or: invalid graph");
00319 
00320         ((Junction *)g1.left)->p2 = g2.left;
00321         ((Junction *)g2.right)->p1 = g1.right;
00322         /* set altnums */
00323         if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
00324         ((Junction *)g2.left)->altnum = ((Junction *)g1.left)->altnum + 1;
00325         g.left = g2.left;
00326         g.right = g1.right;
00327         return g;
00328 }
00329 
00330 /*
00331  * Catenate two subgraphs
00332  *
00333  * Cat(G1, G2) ::= --o-G1-o-->o-G2-o--
00334  * Cat(NULL,G2)::= --o-G2-o--
00335  * Cat(G1,NULL)::= --o-G1-o--
00336  */
00337 Graph
00338 #ifdef __USE_PROTOS
00339 Cat( Graph g1, Graph g2 )
00340 #else
00341 Cat( g1, g2 )
00342 Graph g1;
00343 Graph g2;
00344 #endif
00345 {
00346         Graph g;
00347         
00348         if ( g1.left == NULL && g1.right == NULL ) return g2;
00349         if ( g2.left == NULL && g2.right == NULL ) return g1;
00350         ((Junction *)g1.right)->p1 = g2.left;
00351         g.left = g1.left;
00352         g.right = g2.right;
00353         return g;
00354 }
00355 
00356 /*
00357  * Make a subgraph an optional block
00358  *
00359  * makeOpt(G) ::= --o-->o-G-o-->o--
00360  *                      |           ^
00361  *                                              v           |
00362  *                                          o-------o
00363  *
00364  * Note that this constructs {A|B|...|Z} as if (A|B|...|Z|) was found.
00365  *
00366  * The node on the far right is added so that every block owns its own
00367  * EndBlk node.
00368  */
00369 Graph
00370 #ifdef __USE_PROTOS
00371 makeOpt( Graph g1, int approx, char * pFirstSetSymbol )
00372 #else
00373 makeOpt( g1, approx, pFirstSetSymbol )
00374 Graph g1;
00375 int approx;
00376 char * pFirstSetSymbol;
00377 #endif
00378 {
00379         Junction *j1,*j2,*p;
00380         Graph g;
00381         require(g1.left != NULL && g1.right != NULL, "makeOpt: invalid graph");
00382 
00383         j1 = newJunction();
00384         j2 = newJunction();
00385         ((Junction *)g1.right)->p1 = (Node *) j2;       /* add node to G at end */
00386 
00387     /*  MR21
00388      *
00389      *  There is code in genBlk which recognizes the node created
00390      *  by emptyAlt() as a special case and bypasses it.  We don't
00391      *  want this to happen for the optBlk.
00392      */
00393 
00394         g = emptyAlt3(); /* MR21 */
00395         if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
00396         ((Junction *)g.left)->altnum = ((Junction *)g1.left)->altnum + 1;
00397         for(p=(Junction *)g1.left; p->p2!=NULL; p=(Junction *)p->p2)
00398                 {;}                                                                             /* find last alt */
00399         p->p2 = g.left;                                                         /* add optional alternative */
00400         ((Junction *)g.right)->p1 = (Node *)j2;         /* opt alt points to EndBlk */
00401         g1.right = (Node *)j2;
00402         SetBlk(g1, aOptBlk, approx, pFirstSetSymbol);
00403         j1->p1 = g1.left;                                                       /* add generic node in front */
00404         g.left = (Node *) j1;
00405         g.right = g1.right;
00406         return g;
00407 }
00408 
00409 /*
00410  * Make a graph into subblock
00411  *
00412  * makeBlk(G) ::= --o-->o-G-o-->o--
00413  *
00414  * The node on the far right is added so that every block owns its own
00415  * EndBlk node.
00416  */
00417 Graph
00418 #ifdef __USE_PROTOS
00419 makeBlk( Graph g1, int approx, char * pFirstSetSymbol )
00420 #else
00421 makeBlk( g1, approx, pFirstSetSymbol )
00422 Graph g1;
00423 int approx;
00424 char * pFirstSetSymbol;
00425 #endif
00426 {
00427         Junction *j,*j2;
00428         Graph g;
00429         require(g1.left != NULL && g1.right != NULL, "makeBlk: invalid graph");
00430 
00431         j = newJunction();
00432         j2 = newJunction();
00433         ((Junction *)g1.right)->p1 = (Node *) j2;       /* add node to G at end */
00434         g1.right = (Node *)j2;
00435         SetBlk(g1, aSubBlk, approx, pFirstSetSymbol);
00436         j->p1 = g1.left;                                                        /* add node in front */
00437         g.left = (Node *) j;
00438         g.right = g1.right;
00439 
00440         return g;
00441 }
00442 
00443 /*
00444  * Make a subgraph into a loop (closure) block -- (...)*
00445  *
00446  * makeLoop(G) ::=       |---|
00447  *                                           v   |
00448  *                         --o-->o-->o-G-o-->o--
00449  *                   |           ^
00450  *                   v           |
00451  *                                       o-----------o
00452  *
00453  * After making loop, always place generic node out front.  It becomes
00454  * the start of enclosing block.  The aLoopBlk is the target of the loop.
00455  *
00456  * Loop blks have TWO EndBlk nodes--the far right and the node that loops back
00457  * to the aLoopBlk node.  Node with which we can branch past loop == aLoopBegin and
00458  * one which is loop target == aLoopBlk.
00459  * The branch-past (initial) aLoopBegin node has end
00460  * pointing to the last EndBlk node.  The loop-target node has end==NULL.
00461  *
00462  * Loop blocks have a set of locks (from 1..CLL_k) on the aLoopBlk node.
00463  */
00464 Graph
00465 #ifdef __USE_PROTOS
00466 makeLoop( Graph g1, int approx, char * pFirstSetSymbol )
00467 #else
00468 makeLoop( g1, approx, pFirstSetSymbol)
00469 Graph g1;
00470 int approx;
00471 char * pFirstSetSymbol;
00472 #endif
00473 {
00474         Junction *back, *front, *begin;
00475         Graph g;
00476         require(g1.left != NULL && g1.right != NULL, "makeLoop: invalid graph");
00477 
00478         back = newJunction();
00479         front = newJunction();
00480         begin = newJunction();
00481         g = emptyAlt3();
00482         ((Junction *)g1.right)->p2 = g1.left;           /* add loop branch to G */
00483         ((Junction *)g1.right)->p1 = (Node *) back;     /* add node to G at end */
00484         ((Junction *)g1.right)->jtype = EndBlk;         /* mark 1st EndBlk node */
00485         ((Junction *)g1.left)->jtype = aLoopBlk;        /* mark 2nd aLoopBlk node */
00486         ((Junction *)g1.left)->end = (Junction *) g1.right;
00487         ((Junction *)g1.left)->lock = makelocks();
00488         ((Junction *)g1.left)->pred_lock = makelocks();
00489         g1.right = (Node *) back;
00490         begin->p1 = (Node *) g1.left;
00491         g1.left = (Node *) begin;
00492         begin->p2 = (Node *) g.left;                            /* make bypass arc */
00493         ((Junction *)g.right)->p1 = (Node *) back;
00494         SetBlk(g1, aLoopBegin, approx, pFirstSetSymbol);
00495         front->p1 = g1.left;                                            /* add node to front */
00496         g1.left = (Node *) front;
00497 
00498         return g1;
00499 }
00500 
00501 /*
00502  * Make a subgraph into a plus block -- (...)+ -- 1 or more times
00503  *
00504  * makePlus(G) ::=       |---|
00505  *                                       v   |
00506  *                         --o-->o-G-o-->o--
00507  *
00508  * After making loop, always place generic node out front.  It becomes
00509  * the start of enclosing block.  The aPlusBlk is the target of the loop.
00510  *
00511  * Plus blks have TWO EndBlk nodes--the far right and the node that loops back
00512  * to the aPlusBlk node.
00513  *
00514  * Plus blocks have a set of locks (from 1..CLL_k) on the aPlusBlk node.
00515  */
00516 Graph
00517 #ifdef __USE_PROTOS
00518 makePlus( Graph g1, int approx, char * pFirstSetSymbol)
00519 #else
00520 makePlus( g1, approx, pFirstSetSymbol)
00521 Graph g1;
00522 int approx;
00523 char * pFirstSetSymbol;
00524 #endif
00525 {
00526         int has_empty_alt_already = 0;
00527         Graph g;
00528         Junction *j2, *j3, *first_alt;
00529         Junction *last_alt=NULL, *p;
00530         require(g1.left != NULL && g1.right != NULL, "makePlus: invalid graph");
00531 
00532         first_alt = (Junction *)g1.left;
00533         j2 = newJunction();
00534         j3 = newJunction();
00535         if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
00536         ((Junction *)g1.right)->p2 = g1.left;           /* add loop branch to G */
00537         ((Junction *)g1.right)->p1 = (Node *) j2;       /* add node to G at end */
00538         ((Junction *)g1.right)->jtype = EndBlk;         /* mark 1st EndBlk node */
00539         g1.right = (Node *) j2;
00540         SetBlk(g1, aPlusBlk, approx, pFirstSetSymbol);
00541         ((Junction *)g1.left)->lock = makelocks();
00542         ((Junction *)g1.left)->pred_lock = makelocks();
00543         j3->p1 = g1.left;                                                       /* add node to front */
00544         g1.left = (Node *) j3;
00545 
00546         /* add an optional branch which is the "exit" branch of loop */
00547         /* FIRST, check to ensure that there does not already exist
00548          * an optional path.
00549          */
00550         /* find last alt */
00551         for(p=first_alt; p!=NULL; p=(Junction *)p->p2)
00552         {
00553                 if ( p->p1->ntype == nJunction &&
00554                          p->p1!=NULL &&
00555                          ((Junction *)p->p1)->jtype==Generic &&
00556                          ((Junction *)p->p1)->p1!=NULL &&
00557                          ((Junction *)((Junction *)p->p1)->p1)->jtype==EndBlk )
00558                 {
00559                         has_empty_alt_already = 1;
00560                 }
00561                 last_alt = p;
00562         }
00563         if ( !has_empty_alt_already )
00564         {
00565                 require(last_alt!=NULL, "last_alt==NULL; bad (..)+");
00566                 g = emptyAlt();
00567                 last_alt->p2 = g.left;
00568                 ((Junction *)g.right)->p1 = (Node *) j2;
00569 
00570                 /* make sure lookahead computation ignores this alt for
00571                 * FIRST("(..)+"); but it's still used for computing the FIRST
00572                 * of each alternative.
00573                 */
00574                 ((Junction *)g.left)->ignore = 1;
00575         }
00576 
00577         return g1;
00578 }
00579 
00580 /*
00581  * Return an optional path:  --o-->o--
00582  */
00583 
00584 Graph
00585 #ifdef __USE_PROTOS
00586 emptyAlt( void )
00587 #else
00588 emptyAlt( )
00589 #endif
00590 {
00591         Junction *j1, *j2;
00592         Graph g;
00593 
00594         j1 = newJunction();
00595         j2 = newJunction();
00596         j1->p1 = (Node *) j2;
00597         g.left = (Node *) j1;
00598         g.right = (Node *) j2;
00599         
00600         return g;
00601 }
00602 
00603 /*  MR21
00604  *
00605  *  There is code in genBlk which recognizes the node created
00606  *  by emptyAlt() as a special case and bypasses it.  We don't
00607  *  want this to happen for the optBlk.
00608  */
00609 
00610 Graph
00611 #ifdef __USE_PROTOS
00612 emptyAlt3( void )
00613 #else
00614 emptyAlt3( )
00615 #endif
00616 {
00617         Junction *j1, *j2, *j3;
00618         Graph g;
00619 
00620         j1 = newJunction();
00621         j2 = newJunction();
00622     j3 = newJunction();
00623         j1->p1 = (Node *) j2;
00624         j2->p1 = (Node *) j3;
00625         g.left = (Node *) j1;
00626         g.right = (Node *) j3;
00627         
00628         return g;
00629 }
00630 
00631 /* N o d e  A l l o c a t i o n */
00632 
00633 TokNode *
00634 #ifdef __USE_PROTOS
00635 newTokNode( void )
00636 #else
00637 newTokNode( )
00638 #endif
00639 {
00640         static TokNode *FreeList = NULL;
00641         TokNode *p, *newblk;
00642 
00643         if ( FreeList == NULL )
00644         {
00645                 newblk = (TokNode *)calloc(TokenBlockAllocSize, sizeof(TokNode));
00646                 if ( newblk == NULL )
00647                         fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
00648                 for (p=newblk; p<&(newblk[TokenBlockAllocSize]); p++)
00649                 {
00650                         p->next = (Node *)FreeList;     /* add all new token nodes to FreeList */
00651                         FreeList = p;
00652                 }
00653         }
00654         p = FreeList;
00655         FreeList = (TokNode *)FreeList->next;/* remove a TokNode node */
00656         p->next = NULL;                                         /* NULL the ptr we used */
00657     memset( (char *) p, 0, sizeof(TokNode));        /* MR10 */
00658         p->ntype = nToken;
00659         p->rname = CurRule;
00660         p->file = CurFile;
00661         p->line = zzline;
00662         p->altstart = NULL;
00663 
00664         return p;
00665 }
00666 
00667 RuleRefNode *
00668 #ifdef __USE_PROTOS
00669 newRNode( void )
00670 #else
00671 newRNode( )
00672 #endif
00673 {
00674         static RuleRefNode *FreeList = NULL;
00675         RuleRefNode *p, *newblk;
00676 
00677         if ( FreeList == NULL )
00678         {
00679                 newblk = (RuleRefNode *)calloc(RRefBlockAllocSize, sizeof(RuleRefNode));
00680                 if ( newblk == NULL )
00681                         fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
00682                 for (p=newblk; p<&(newblk[RRefBlockAllocSize]); p++)
00683                 {
00684                         p->next = (Node *)FreeList;     /* add all new rref nodes to FreeList */
00685                         FreeList = p;
00686                 }
00687         }
00688         p = FreeList;
00689         FreeList = (RuleRefNode *)FreeList->next;/* remove a Junction node */
00690         p->next = NULL;                                         /* NULL the ptr we used */
00691     memset( (char *) p, 0, sizeof(RuleRefNode));        /* MR10 */
00692         p->ntype = nRuleRef;
00693         p->rname = CurRule;
00694         p->file = CurFile;
00695         p->line = zzline;
00696         p->astnode = ASTinclude;
00697         p->altstart = NULL;
00698         
00699         return p;
00700 }
00701 
00702 static int junctionSeqNumber=0;         /* MR10 */
00703 
00704 Junction *
00705 #ifdef __USE_PROTOS
00706 newJunction( void )
00707 #else
00708 newJunction( )
00709 #endif
00710 {
00711         static Junction *FreeList = NULL;
00712         Junction *p, *newblk;
00713 
00714         if ( FreeList == NULL )
00715         {
00716                 newblk = (Junction *)calloc(JunctionBlockAllocSize, sizeof(Junction));
00717                 if ( newblk == NULL )
00718                         fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
00719                 for (p=newblk; p<&(newblk[JunctionBlockAllocSize]); p++)
00720                 {
00721                         p->p1 = (Node *)FreeList;       /* add all new Junction nodes to FreeList */
00722                         FreeList = p;
00723                 }
00724         }
00725         p = FreeList;
00726         FreeList = (Junction *)FreeList->p1;/* remove a Junction node */
00727         p->p1 = NULL;                                           /* NULL the ptr we used */
00728     memset( (char *) p, 0, sizeof(Junction));       /* MR10 */
00729         p->ntype = nJunction;
00730         p->visited = 0;
00731         p->jtype = Generic;
00732         p->rname = CurRule;
00733         p->file = CurFile;
00734         p->line = zzline;
00735         p->exception_label = NULL;
00736         p->fset = (set *) calloc(CLL_k+1, sizeof(set));
00737         require(p->fset!=NULL, "cannot allocate fset in newJunction");
00738     p->seq=++junctionSeqNumber;     /* MR10 */
00739 
00740         return p;
00741 }
00742 
00743 ActionNode *
00744 #ifdef __USE_PROTOS
00745 newActionNode( void )
00746 #else
00747 newActionNode( )
00748 #endif
00749 {
00750         static ActionNode *FreeList = NULL;
00751         ActionNode *p, *newblk;
00752 
00753         if ( FreeList == NULL )
00754         {
00755                 newblk = (ActionNode *)calloc(ActionBlockAllocSize, sizeof(ActionNode));
00756                 if ( newblk == NULL )
00757                         fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
00758                 for (p=newblk; p<&(newblk[ActionBlockAllocSize]); p++)
00759                 {
00760                         p->next = (Node *)FreeList;     /* add all new Action nodes to FreeList */
00761                         FreeList = p;
00762                 }
00763         }
00764         p = FreeList;
00765         FreeList = (ActionNode *)FreeList->next;/* remove an Action node */
00766     memset( (char *) p, 0, sizeof(ActionNode));     /* MR10 */
00767         p->ntype = nAction;
00768         p->next = NULL;                                         /* NULL the ptr we used */
00769         p->done = 0;
00770         p->pred_fail = NULL;
00771         p->guardpred = NULL;
00772     p->ampersandPred = NULL;
00773         return p;
00774 }
00775 
00776 /*
00777  * allocate the array of locks (1..CLL_k) used to inhibit infinite recursion.
00778  * Infinite recursion can occur in (..)* blocks, FIRST calcs and FOLLOW calcs.
00779  * Therefore, we need locks on aLoopBlk, RuleBlk, EndRule nodes.
00780  *
00781  * if ( lock[k]==TRUE ) then we have been here before looking for k tokens
00782  * of lookahead.
00783  */
00784 char *
00785 #ifdef __USE_PROTOS
00786 makelocks( void )
00787 #else
00788 makelocks( )
00789 #endif
00790 {
00791         char *p = (char *) calloc(CLL_k+1, sizeof(char));
00792         require(p!=NULL, "cannot allocate lock array");
00793         
00794         return p;
00795 }
00796 
00797 #if 0
00798 ** #ifdef __USE_PROTOS
00799 ** void my_memset(char *p,char value,int count)
00800 ** #else
00801 ** void my_memset(p,value,count)
00802 **   char      *p;
00803 **   char      value;
00804 **   int       count;
00805 ** #endif
00806 ** {
00807 **    int      i;
00808 **
00809 **    for (i=0; i<count; i++) {
00810 **     p[i]=value;
00811 **   };
00812 ** }
00813 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines