build.c
资源名称:pccts133.zip [点击查看]
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:19k
源码类别:
编译器/解释器
开发平台:
Others
- /*
- * build.c -- functions associated with building syntax diagrams.
- *
- * SOFTWARE RIGHTS
- *
- * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
- * Set (PCCTS) -- PCCTS is in the public domain. An individual or
- * company may do whatever they wish with source code distributed with
- * PCCTS or the code generated by PCCTS, including the incorporation of
- * PCCTS, or its output, into commerical software.
- *
- * We encourage users to develop software with PCCTS. However, we do ask
- * that credit is given to us for developing PCCTS. By "credit",
- * we mean that if you incorporate our source code into one of your
- * programs (commercial product, research project, or otherwise) that you
- * acknowledge this fact somewhere in the documentation, research report,
- * etc... If you like PCCTS and have developed a nice tool with the
- * output, please mention that you developed it using PCCTS. In
- * addition, we ask that this header remain intact in our source code.
- * As long as these guidelines are kept, we expect to continue enhancing
- * this system and expect to make other tools available as they are
- * completed.
- *
- * ANTLR 1.33
- * Terence Parr
- * Parr Research Corporation
- * with Purdue University and AHPCRC, University of Minnesota
- * 1989-1998
- */
- #include <stdio.h>
- #include <ctype.h>
- #ifdef __cplusplus
- #ifndef __STDC__
- #define __STDC__
- #endif
- #endif
- #include "set.h"
- #include "syn.h"
- #include "hash.h"
- #include "generic.h"
- #include "dlgdef.h"
- #define SetBlk(g, t, approx) {
- ((Junction *)g.left)->jtype = t;
- ((Junction *)g.left)->approx = approx;
- ((Junction *)g.left)->end = (Junction *) g.right;
- ((Junction *)g.right)->jtype = EndBlk;}
- /* Add the parameter string 'parm' to the parms field of a block-type junction
- * g.left points to the sentinel node on a block. i.e. g.left->p1 points to
- * the actual junction with its jtype == some block-type.
- */
- void
- #ifdef __STDC__
- addParm( Node *p, char *parm )
- #else
- addParm( p, parm )
- Node *p;
- char *parm;
- #endif
- {
- char *q = (char *) malloc( strlen(parm) + 1 );
- require(p!=NULL, "addParm: NULL objectn");
- require(q!=NULL, "addParm: unable to alloc parametern");
- strcpy(q, parm);
- if ( p->ntype == nRuleRef )
- {
- ((RuleRefNode *)p)->parms = q;
- }
- else if ( p->ntype == nJunction )
- {
- ((Junction *)p)->parm = q; /* only one parameter allowed on subrules */
- }
- else fatal_internal("addParm: invalid node for adding parm");
- }
- /*
- * Build an action node for the syntax diagram
- *
- * buildAction(ACTION) ::= --o-->ACTION-->o--
- *
- * Where o is a junction node.
- */
- Graph
- #ifdef __STDC__
- buildAction( char *action, int file, int line, int is_predicate )
- #else
- buildAction( action, file, line, is_predicate )
- char *action;
- int file;
- int line;
- int is_predicate;
- #endif
- {
- Junction *j1, *j2;
- Graph g;
- ActionNode *a;
- require(action!=NULL, "buildAction: invalid action");
- j1 = newJunction();
- j2 = newJunction();
- a = newActionNode();
- a->action = (char *) malloc( strlen(action)+1 );
- require(a->action!=NULL, "buildAction: cannot alloc space for actionn");
- strcpy(a->action, action);
- j1->p1 = (Node *) a;
- a->next = (Node *) j2;
- a->is_predicate = is_predicate;
- if (is_predicate) {
- PredEntry *predEntry;
- char *t;
- char *key;
- char *u;
- int inverted=0;
- t=key=(char *)calloc(1,strlen(a->action)+1);
- for (u=a->action; *u != ' ' ; u++) {
- if (*u != ' ') {
- if (t==key && *u=='!') {
- inverted=!inverted;
- } else {
- *t++=*u;
- };
- };
- };
- *t=' ';
- predEntry=(PredEntry *)hash_get(Pname,key);
- a->predEntry=predEntry;
- if (predEntry != NULL) a->inverted=inverted;
- } else {
- /* MR12c */ char *strStart=a->action;
- /* MR12c */ char *strEnd;
- /* MR12c */ strEnd=strStart+strlen(strStart)-1;
- /* MR12c */ for ( ; strEnd >= strStart && isspace(*strEnd); strEnd--) *strEnd=0;
- /* MR12c */ while (*strStart != ' ' && isspace(*strStart)) strStart++;
- /* MR12c */ if (ci_strequ(strStart,"nohoist")) {
- /* MR12c */ a->noHoist=1;
- /* MR12c */ }
- };
- g.left = (Node *) j1; g.right = (Node *) j2;
- a->file = file;
- a->line = line;
- a->rname = CurRule; /* MR10 */
- return g;
- }
- /*
- * Build a token node for the syntax diagram
- *
- * buildToken(TOKEN) ::= --o-->TOKEN-->o--
- *
- * Where o is a junction node.
- */
- Graph
- #ifdef __STDC__
- buildToken( char *text )
- #else
- buildToken( text )
- char *text;
- #endif
- {
- Junction *j1, *j2;
- Graph g;
- TokNode *t;
- require(text!=NULL, "buildToken: invalid token name");
- j1 = newJunction();
- j2 = newJunction();
- t = newTokNode();
- t->altstart = CurAltStart;
- if ( *text == '"' ) {t->label=FALSE; t->token = addTexpr( text );}
- else {t->label=TRUE; t->token = addTname( text );}
- j1->p1 = (Node *) t;
- t->next = (Node *) j2;
- g.left = (Node *) j1; g.right = (Node *) j2;
- return g;
- }
- /*
- * Build a wild-card node for the syntax diagram
- *
- * buildToken(TOKEN) ::= --o-->'.'-->o--
- *
- * Where o is a junction node.
- */
- Graph
- #ifdef __STDC__
- buildWildCard( char *text )
- #else
- buildWildCard( text )
- char *text;
- #endif
- {
- Junction *j1, *j2;
- Graph g;
- TokNode *t;
- TCnode *w;
- TermEntry *p;
- require(text!=NULL, "buildWildCard: invalid token name");
- j1 = newJunction();
- j2 = newJunction();
- t = newTokNode();
- /* If the ref a wild card, make a token class for it */
- if ( Tnum(WildCardString) == 0 )
- {
- w = newTCnode;
- w->tok = addTname( WildCardString );
- set_orel(w->tok, &imag_tokens);
- set_orel(w->tok, &tokclasses);
- WildCardToken = w->tok;
- require((p=(TermEntry *)hash_get(Tname, WildCardString)) != NULL,
- "hash table mechanism is broken");
- p->classname = 1; /* entry is class name, not token */
- p->tclass = w; /* save ptr to this tclass def */
- list_add(&tclasses, (char *)w);
- }
- else {
- p=(TermEntry *)hash_get(Tname, WildCardString);
- require( p!= NULL, "hash table mechanism is broken");
- w = p->tclass;
- }
- t->token = w->tok;
- t->wild_card = 1;
- t->tclass = w;
- t->altstart = CurAltStart;
- j1->p1 = (Node *) t;
- t->next = (Node *) j2;
- g.left = (Node *) j1; g.right = (Node *) j2;
- return g;
- }
- void
- #ifdef __STDC__
- setUpperRange(TokNode *t, char *text)
- #else
- setUpperRange(t, text)
- TokNode *t;
- char *text;
- #endif
- {
- require(t!=NULL, "setUpperRange: NULL token node");
- require(text!=NULL, "setUpperRange: NULL token string");
- if ( *text == '"' ) {t->upper_range = addTexpr( text );}
- else {t->upper_range = addTname( text );}
- }
- /*
- * Build a rule reference node of the syntax diagram
- *
- * buildRuleRef(RULE) ::= --o-->RULE-->o--
- *
- * Where o is a junction node.
- *
- * If rule 'text' has been defined already, don't alloc new space to store string.
- * Set r->text to point to old copy in string table.
- */
- Graph
- #ifdef __STDC__
- buildRuleRef( char *text )
- #else
- buildRuleRef( text )
- char *text;
- #endif
- {
- Junction *j1, *j2;
- Graph g;
- RuleRefNode *r;
- RuleEntry *p;
- require(text!=NULL, "buildRuleRef: invalid rule name");
- j1 = newJunction();
- j2 = newJunction();
- r = newRNode();
- r->altstart = CurAltStart;
- r->assign = NULL;
- if ( (p=(RuleEntry *)hash_get(Rname, text)) != NULL ) r->text = p->str;
- else r->text = mystrdup( text );
- j1->p1 = (Node *) r;
- r->next = (Node *) j2;
- g.left = (Node *) j1; g.right = (Node *) j2;
- return g;
- }
- /*
- * Or two subgraphs into one graph via:
- *
- * Or(G1, G2) ::= --o-G1-o--
- * | ^
- * v |
- * o-G2-o
- *
- * Set the altnum of junction starting G2 to 1 + altnum of junction starting G1.
- * If, however, the G1 altnum is 0, make it 1 and then
- * make G2 altnum = G1 altnum + 1.
- */
- Graph
- #ifdef __STDC__
- Or( Graph g1, Graph g2 )
- #else
- Or( g1, g2 )
- Graph g1;
- Graph g2;
- #endif
- {
- Graph g;
- require(g1.left != NULL, "Or: invalid graph");
- require(g2.left != NULL && g2.right != NULL, "Or: invalid graph");
- ((Junction *)g1.left)->p2 = g2.left;
- ((Junction *)g2.right)->p1 = g1.right;
- /* set altnums */
- if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
- ((Junction *)g2.left)->altnum = ((Junction *)g1.left)->altnum + 1;
- g.left = g2.left;
- g.right = g1.right;
- return g;
- }
- /*
- * Catenate two subgraphs
- *
- * Cat(G1, G2) ::= --o-G1-o-->o-G2-o--
- * Cat(NULL,G2)::= --o-G2-o--
- * Cat(G1,NULL)::= --o-G1-o--
- */
- Graph
- #ifdef __STDC__
- Cat( Graph g1, Graph g2 )
- #else
- Cat( g1, g2 )
- Graph g1;
- Graph g2;
- #endif
- {
- Graph g;
- if ( g1.left == NULL && g1.right == NULL ) return g2;
- if ( g2.left == NULL && g2.right == NULL ) return g1;
- ((Junction *)g1.right)->p1 = g2.left;
- g.left = g1.left;
- g.right = g2.right;
- return g;
- }
- /*
- * Make a subgraph an optional block
- *
- * makeOpt(G) ::= --o-->o-G-o-->o--
- * | ^
- * v |
- * o-------o
- *
- * Note that this constructs {A|B|...|Z} as if (A|B|...|Z|) was found.
- *
- * The node on the far right is added so that every block owns its own
- * EndBlk node.
- */
- Graph
- #ifdef __STDC__
- makeOpt( Graph g1, int approx )
- #else
- makeOpt( g1, approx )
- Graph g1;
- int approx;
- #endif
- {
- Junction *j1,*j2,*p;
- Graph g;
- require(g1.left != NULL && g1.right != NULL, "makeOpt: invalid graph");
- j1 = newJunction();
- j2 = newJunction();
- ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */
- g = emptyAlt();
- if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
- ((Junction *)g.left)->altnum = ((Junction *)g1.left)->altnum + 1;
- for(p=(Junction *)g1.left; p->p2!=NULL; p=(Junction *)p->p2)
- {;} /* find last alt */
- p->p2 = g.left; /* add optional alternative */
- ((Junction *)g.right)->p1 = (Node *)j2; /* opt alt points to EndBlk */
- g1.right = (Node *)j2;
- SetBlk(g1, aOptBlk, approx);
- j1->p1 = g1.left; /* add generic node in front */
- g.left = (Node *) j1;
- g.right = g1.right;
- return g;
- }
- /*
- * Make a graph into subblock
- *
- * makeBlk(G) ::= --o-->o-G-o-->o--
- *
- * The node on the far right is added so that every block owns its own
- * EndBlk node.
- */
- Graph
- #ifdef __STDC__
- makeBlk( Graph g1, int approx )
- #else
- makeBlk( g1, approx )
- Graph g1;
- int approx;
- #endif
- {
- Junction *j,*j2;
- Graph g;
- require(g1.left != NULL && g1.right != NULL, "makeBlk: invalid graph");
- j = newJunction();
- j2 = newJunction();
- ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */
- g1.right = (Node *)j2;
- SetBlk(g1, aSubBlk, approx);
- j->p1 = g1.left; /* add node in front */
- g.left = (Node *) j;
- g.right = g1.right;
- return g;
- }
- /*
- * Make a subgraph into a loop (closure) block -- (...)*
- *
- * makeLoop(G) ::= |---|
- * v |
- * --o-->o-->o-G-o-->o--
- * | ^
- * v |
- * o-----------o
- *
- * After making loop, always place generic node out front. It becomes
- * the start of enclosing block. The aLoopBlk is the target of the loop.
- *
- * Loop blks have TWO EndBlk nodes--the far right and the node that loops back
- * to the aLoopBlk node. Node with which we can branch past loop == aLoopBegin and
- * one which is loop target == aLoopBlk.
- * The branch-past (initial) aLoopBegin node has end
- * pointing to the last EndBlk node. The loop-target node has end==NULL.
- *
- * Loop blocks have a set of locks (from 1..CLL_k) on the aLoopBlk node.
- */
- Graph
- #ifdef __STDC__
- makeLoop( Graph g1, int approx )
- #else
- makeLoop( g1, approx )
- Graph g1;
- int approx;
- #endif
- {
- Junction *back, *front, *begin;
- Graph g;
- require(g1.left != NULL && g1.right != NULL, "makeLoop: invalid graph");
- back = newJunction();
- front = newJunction();
- begin = newJunction();
- g = emptyAlt();
- ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */
- ((Junction *)g1.right)->p1 = (Node *) back; /* add node to G at end */
- ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */
- ((Junction *)g1.left)->jtype = aLoopBlk; /* mark 2nd aLoopBlk node */
- ((Junction *)g1.left)->end = (Junction *) g1.right;
- ((Junction *)g1.left)->lock = makelocks();
- ((Junction *)g1.left)->pred_lock = makelocks();
- g1.right = (Node *) back;
- begin->p1 = (Node *) g1.left;
- g1.left = (Node *) begin;
- begin->p2 = (Node *) g.left; /* make bypass arc */
- ((Junction *)g.right)->p1 = (Node *) back;
- SetBlk(g1, aLoopBegin, approx);
- front->p1 = g1.left; /* add node to front */
- g1.left = (Node *) front;
- return g1;
- }
- /*
- * Make a subgraph into a plus block -- (...)+ -- 1 or more times
- *
- * makePlus(G) ::= |---|
- * v |
- * --o-->o-G-o-->o--
- *
- * After making loop, always place generic node out front. It becomes
- * the start of enclosing block. The aPlusBlk is the target of the loop.
- *
- * Plus blks have TWO EndBlk nodes--the far right and the node that loops back
- * to the aPlusBlk node.
- *
- * Plus blocks have a set of locks (from 1..CLL_k) on the aPlusBlk node.
- */
- Graph
- #ifdef __STDC__
- makePlus( Graph g1, int approx )
- #else
- makePlus( g1, approx )
- Graph g1;
- int approx;
- #endif
- {
- int has_empty_alt_already = 0;
- Graph g;
- Junction *j2, *j3, *first_alt;
- Junction *last_alt=NULL, *p;
- require(g1.left != NULL && g1.right != NULL, "makePlus: invalid graph");
- first_alt = (Junction *)g1.left;
- j2 = newJunction();
- j3 = newJunction();
- if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
- ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */
- ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */
- ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */
- g1.right = (Node *) j2;
- SetBlk(g1, aPlusBlk, approx);
- ((Junction *)g1.left)->lock = makelocks();
- ((Junction *)g1.left)->pred_lock = makelocks();
- j3->p1 = g1.left; /* add node to front */
- g1.left = (Node *) j3;
- /* add an optional branch which is the "exit" branch of loop */
- /* FIRST, check to ensure that there does not already exist
- * an optional path.
- */
- /* find last alt */
- for(p=first_alt; p!=NULL; p=(Junction *)p->p2)
- {
- if ( p->p1->ntype == nJunction &&
- p->p1!=NULL &&
- ((Junction *)p->p1)->jtype==Generic &&
- ((Junction *)p->p1)->p1!=NULL &&
- ((Junction *)((Junction *)p->p1)->p1)->jtype==EndBlk )
- {
- has_empty_alt_already = 1;
- }
- last_alt = p;
- }
- if ( !has_empty_alt_already )
- {
- require(last_alt!=NULL, "last_alt==NULL; bad (..)+");
- g = emptyAlt();
- last_alt->p2 = g.left;
- ((Junction *)g.right)->p1 = (Node *) j2;
- /* make sure lookahead computation ignores this alt for
- * FIRST("(..)+"); but it's still used for computing the FIRST
- * of each alternative.
- */
- ((Junction *)g.left)->ignore = 1;
- }
- return g1;
- }
- /*
- * Return an optional path: --o-->o--
- */
- Graph
- #ifdef __STDC__
- emptyAlt( void )
- #else
- emptyAlt( )
- #endif
- {
- Junction *j1, *j2;
- Graph g;
- j1 = newJunction();
- j2 = newJunction();
- j1->p1 = (Node *) j2;
- g.left = (Node *) j1;
- g.right = (Node *) j2;
- return g;
- }
- /* N o d e A l l o c a t i o n */
- TokNode *
- #ifdef __STDC__
- newTokNode( void )
- #else
- newTokNode( )
- #endif
- {
- static TokNode *FreeList = NULL;
- TokNode *p, *newblk;
- if ( FreeList == NULL )
- {
- newblk = (TokNode *)calloc(TokenBlockAllocSize, sizeof(TokNode));
- if ( newblk == NULL )
- fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
- for (p=newblk; p<&(newblk[TokenBlockAllocSize]); p++)
- {
- p->next = (Node *)FreeList; /* add all new token nodes to FreeList */
- FreeList = p;
- }
- }
- p = FreeList;
- FreeList = (TokNode *)FreeList->next;/* remove a TokNode node */
- p->next = NULL; /* NULL the ptr we used */
- memset( (char *) p, 0, sizeof(TokNode)); /* MR10 */
- p->ntype = nToken;
- p->rname = CurRule;
- p->file = CurFile;
- p->line = zzline;
- p->altstart = NULL;
- return p;
- }
- RuleRefNode *
- #ifdef __STDC__
- newRNode( void )
- #else
- newRNode( )
- #endif
- {
- static RuleRefNode *FreeList = NULL;
- RuleRefNode *p, *newblk;
- if ( FreeList == NULL )
- {
- newblk = (RuleRefNode *)calloc(RRefBlockAllocSize, sizeof(RuleRefNode));
- if ( newblk == NULL )
- fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
- for (p=newblk; p<&(newblk[RRefBlockAllocSize]); p++)
- {
- p->next = (Node *)FreeList; /* add all new rref nodes to FreeList */
- FreeList = p;
- }
- }
- p = FreeList;
- FreeList = (RuleRefNode *)FreeList->next;/* remove a Junction node */
- p->next = NULL; /* NULL the ptr we used */
- memset( (char *) p, 0, sizeof(RuleRefNode)); /* MR10 */
- p->ntype = nRuleRef;
- p->rname = CurRule;
- p->file = CurFile;
- p->line = zzline;
- p->astnode = ASTinclude;
- p->altstart = NULL;
- return p;
- }
- static int junctionSeqNumber=0; /* MR10 */
- Junction *
- #ifdef __STDC__
- newJunction( void )
- #else
- newJunction( )
- #endif
- {
- static Junction *FreeList = NULL;
- Junction *p, *newblk;
- if ( FreeList == NULL )
- {
- newblk = (Junction *)calloc(JunctionBlockAllocSize, sizeof(Junction));
- if ( newblk == NULL )
- fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
- for (p=newblk; p<&(newblk[JunctionBlockAllocSize]); p++)
- {
- p->p1 = (Node *)FreeList; /* add all new Junction nodes to FreeList */
- FreeList = p;
- }
- }
- p = FreeList;
- FreeList = (Junction *)FreeList->p1;/* remove a Junction node */
- p->p1 = NULL; /* NULL the ptr we used */
- memset( (char *) p, 0, sizeof(Junction)); /* MR10 */
- p->ntype = nJunction;
- p->visited = 0;
- p->jtype = Generic;
- p->rname = CurRule;
- p->file = CurFile;
- p->line = zzline;
- p->exception_label = NULL;
- p->fset = (set *) calloc(CLL_k+1, sizeof(set));
- require(p->fset!=NULL, "cannot allocate fset in newJunction");
- p->seq=++junctionSeqNumber; /* MR10 */
- return p;
- }
- ActionNode *
- #ifdef __STDC__
- newActionNode( void )
- #else
- newActionNode( )
- #endif
- {
- static ActionNode *FreeList = NULL;
- ActionNode *p, *newblk;
- if ( FreeList == NULL )
- {
- newblk = (ActionNode *)calloc(ActionBlockAllocSize, sizeof(ActionNode));
- if ( newblk == NULL )
- fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
- for (p=newblk; p<&(newblk[ActionBlockAllocSize]); p++)
- {
- p->next = (Node *)FreeList; /* add all new Action nodes to FreeList */
- FreeList = p;
- }
- }
- p = FreeList;
- FreeList = (ActionNode *)FreeList->next;/* remove an Action node */
- memset( (char *) p, 0, sizeof(ActionNode)); /* MR10 */
- p->ntype = nAction;
- p->next = NULL; /* NULL the ptr we used */
- p->done = 0;
- p->pred_fail = NULL;
- p->guardpred = NULL;
- p->ampersandPred = NULL;
- return p;
- }
- /*
- * allocate the array of locks (1..CLL_k) used to inhibit infinite recursion.
- * Infinite recursion can occur in (..)* blocks, FIRST calcs and FOLLOW calcs.
- * Therefore, we need locks on aLoopBlk, RuleBlk, EndRule nodes.
- *
- * if ( lock[k]==TRUE ) then we have been here before looking for k tokens
- * of lookahead.
- */
- char *
- #ifdef __STDC__
- makelocks( void )
- #else
- makelocks( )
- #endif
- {
- char *p = (char *) calloc(CLL_k+1, sizeof(char));
- require(p!=NULL, "cannot allocate lock array");
- return p;
- }
- #if 0
- ** #ifdef __STDC__
- ** void my_memset(char *p,char value,int count)
- ** #else
- ** void my_memset(p,value,count)
- ** char *p;
- ** char value;
- ** int count;
- ** #endif
- ** {
- ** int i;
- **
- ** for (i=0; i<count; i++) {
- ** p[i]=value;
- ** };
- ** }
- #endif