⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 misc.c

📁 本工具提供一个词法分析器和语法分析器的集成开发环境
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* track the order in which they occur */	list_add(&ExprOrder, (void *)newExpr(p->str));	p->token = TokenNum++;	hash_add(Texpr, expr, (Entry *)p);	return p->token;}/* return the token number of 'term'.  Return 0 if no 'term' exists */int#ifdef __STDC__Tnum( char *term )#elseTnum( term )char *term;#endif{	TermEntry *p;	require(term!=NULL, "Tnum: invalid terminal");		if ( *term=='"' ) p = (TermEntry *) hash_get(Texpr, term);	else p = (TermEntry *) hash_get(Tname, term);	if ( p == NULL ) return 0;	else return p->token;}/* associate a Name with an expr.  If both have been already assigned * token numbers, then an error is reported.  Add the token or expr * that has not been added if no error.  This 'represents' the #token * ANTLR pseudo-op.  If both have not been defined, define them both * linked to same token number. */void#ifdef __STDC__Tklink( char *token, char *expr )#elseTklink( token, expr )char *token;char *expr;#endif{	TermEntry *p, *q;	require(token!=NULL && expr!=NULL, "Tklink: invalid token name and/or expr");	p = (TermEntry *) hash_get(Tname, token);	q = (TermEntry *) hash_get(Texpr, expr);	if ( p != NULL && q != NULL )	/* both defined */	{		warn( eMsg2("token name %s and rexpr %s already defined; ignored",					token, expr) );		return;	}	if ( p==NULL && q==NULL )		/* both not defined */	{		int t = addTname( token );		q = newTermEntry( expr );		hash_add(Texpr, expr, (Entry *)q);		q->token = t;		/* note: we use the actual ExprStr array		 * here as TokenInd doesn't exist yet		 */		ExprStr[t] = q->str;		/* track the order in which they occur */		list_add(&ExprOrder, (void *)newExpr(q->str));		return;	}	if ( p != NULL )				/* one is defined, one is not */	{		q = newTermEntry( expr );		hash_add(Texpr, expr, (Entry *)q);		q->token = p->token;		ExprStr[p->token] = q->str;	/* both expr and token str defined now */		list_add(&ExprOrder, (void *)newExpr(q->str));	}	else							/* trying to associate name with expr here*/	{		p = newTermEntry( token );		hash_add(Tname, token, (Entry *)p);		p->token = q->token;		TokenStr[p->token] = p->str;/* both expr and token str defined now */	}}/* * Given a string, this function allocates and returns a pointer to a * hash table record of size 'sz' whose "str" pointer is reset to a position * in the string table. */Entry *#ifdef __STDC__newEntry( char *text, int sz )#elsenewEntry( text, sz )char *text;int sz;#endif{	Entry *p;	require(text!=NULL, "new: NULL terminal");		if ( (p = (Entry *) calloc(1,sz)) == 0 )	{		fatal_internal("newEntry: out of memory for terminals\n");		exit(PCCTS_EXIT_FAILURE);	}	p->str = mystrdup(text);		return(p);}/* * add an element to a list. * * Any non-empty list has a sentinel node whose 'elem' pointer is really * a pointer to the last element.  (i.e. length(list) = #elemIn(list)+1). * Elements are appended to the list. */void#ifdef __STDC__list_add( ListNode **list, void *e )#elselist_add( list, e )ListNode **list;void *e;#endif{	ListNode *p, *tail;	require(e!=NULL, "list_add: attempting to add NULL list element");	p = newListNode;	require(p!=NULL, "list_add: cannot alloc new list node");	p->elem = e;	if ( *list == NULL )	{		ListNode *sentinel = newListNode;		require(sentinel!=NULL, "list_add: cannot alloc sentinel node");		*list=sentinel;		sentinel->next = p;		sentinel->elem = (char *)p;		/* set tail pointer */	}	else								/* find end of list */	{		tail = (ListNode *) (*list)->elem;	/* get tail pointer */		tail->next = p;		(*list)->elem = (char *) p;		/* reset tail */	}}/* MR10 list_free() frees the ListNode elements in the list       *//* MR10   if freeData then free the data elements of the list too */void#ifdef __STDC__list_free(ListNode **list,int freeData)#elselist_free(list,freeData)  ListNode      **list;  int           freeData;#endif{	ListNode *p;    ListNode *next;	if (list == NULL) return;    if (*list == NULL) return;	for (p=*list; p != NULL; p=next) {      next=p->next;      if (freeData && p->elem != NULL) {        free( (char *) p->elem);      };      free( (char *) p);    };    *list=NULL;}void#ifdef __STDC__list_apply( ListNode *list, void (*f)(void *) )#elselist_apply( list, f )ListNode *list;void (*f)();#endif{	ListNode *p;	require(f!=NULL, "list_apply: NULL function to apply");	if ( list == NULL ) return;	for (p = list->next; p!=NULL; p=p->next) (*f)( p->elem );}			/* F O L L O W  C y c l e  S t u f f */		/* make a key based upon (rulename, computation, k value). * Computation values are 'i'==FIRST, 'o'==FOLLOW. *//* MR10  Make the key all characters so it can be read easily   *//* MR10    by a simple dump program.  Also, separates           *//* MR10   'o' and 'i' from rule name                            */char *#ifdef __STDC__Fkey( char *rule, int computation, int k )#elseFkey( rule, computation, k )char *rule;int computation;int k;#endif{	static char key[MaxRuleName+2+2+1];                                 /* MR10 */	int i;		if ( k > 99 )                                                       /* MR10 */		fatal("k>99 is too big for this implementation of ANTLR!\n");   /* MR10 */	if ( (i=strlen(rule)) > MaxRuleName )                               /* MR10 */		fatal( eMsgd("rule name > max of %d\n", MaxRuleName) );         /* MR10 */	strcpy(key,rule);/* MR10 */     key[i]='*';/* MR10 */     key[i+1] = (int) computation;/* MR10 */     if (k < 10) {/* MR10 */       key[i+2] = (char) ( '0' + k);/* MR10 */  	 key[i+3] = '\0';/* MR10 */     } else {/* MR10 */       key[i+2] = (char) ( '0' + k/10);/* MR10 */       key[i+3] = (char) ( '0' + k % 10);/* MR10 */       key[i+4] = '\0';/* MR10 */     };	return key;}/* Push a rule onto the kth FOLLOW stack */void#ifdef __STDC__FoPush( char *rule, int k )#elseFoPush( rule, k )char *rule;int k;#endif{	RuleEntry *r;	require(rule!=NULL, "FoPush: tried to push NULL rule");	require(k<=CLL_k,	"FoPush: tried to access non-existent stack");	/*fprintf(stderr, "FoPush(%s)\n", rule);*/	r = (RuleEntry *) hash_get(Rname, rule);	if ( r == NULL ) {fatal_internal( eMsg1("rule %s must be defined but isn't", rule) );}	if ( FoStack[k] == NULL )		/* Does the kth stack exist yet? */	{		/*fprintf(stderr, "allocating FoStack\n");*/		FoStack[k] = (int *) calloc(FoStackSize, sizeof(int));		require(FoStack[k]!=NULL, "FoPush: cannot allocate FOLLOW stack\n");	}	if ( FoTOS[k] == NULL )	{		FoTOS[k]=FoStack[k];		*(FoTOS[k]) = r->rulenum;	}	else	{#ifdef MEMCHK		require(valid(FoStack[k]), "FoPush: invalid FoStack");#endif		if ( FoTOS[k] >= &(FoStack[k][FoStackSize-1]) )			fatal( eMsgd("exceeded max depth of FOLLOW recursion (%d)\n",						FoStackSize) );		require(FoTOS[k]>=FoStack[k],				eMsg1("FoPush: FoStack stack-ptr is playing out of its sandbox",					  rule));		++(FoTOS[k]);		*(FoTOS[k]) = r->rulenum;	}	{		/*****		int *p;****		fprintf(stderr, "FoStack[k=%d]:\n", k);****		for (p=FoStack[k]; p<=FoTOS[k]; p++)****		{****			fprintf(stderr, "\t%s\n", RulePtr[*p]->rname);****		}		*/	}}/* Pop one rule off of the FOLLOW stack.  TOS ptr is NULL if empty. */void#ifdef __STDC__FoPop( int k )#elseFoPop( k )int k;#endif{	require(k<=CLL_k, "FoPop: tried to access non-existent stack");	/*fprintf(stderr, "FoPop\n");*/	require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]),			"FoPop: FoStack stack-ptr is playing out of its sandbox");	if ( FoTOS[k] == FoStack[k] ) FoTOS[k] = NULL;	else (FoTOS[k])--;}/* Compute FOLLOW cycle. * Mark all FOLLOW sets for rules in cycle as incomplete. * Then, save cycle on the cycle list (Cycles) for later resolution. * The Cycle is stored in the form: *		(head of cycle==croot, rest of rules in cycle==cyclicDep) * * e.g. (Fo means "FOLLOW of", "-->" means requires or depends on) * *		Fo(x)-->Fo(a)-->Fo(b)-->Fo(c)-->Fo(x) *										   ^----Infinite recursion (cycle) * * the cycle would be: x -> {a,b,c} or stored as (x,{a,b,c}).  Fo(x) depends * on the FOLLOW of a,b, and c.  The root of a cycle is always complete after * Fo(x) finishes.  Fo(a,b,c) however are not.  It turns out that all rules * in a FOLLOW cycle have the same FOLLOW set. */void#ifdef __STDC__RegisterCycle( char *rule, int k )#elseRegisterCycle( rule, k )char *rule;int k;#endif{	CacheEntry *f;	Cycle *c;	int *p;	RuleEntry *r;	require(rule!=NULL, "RegisterCycle: tried to register NULL rule");	require(k<=CLL_k,	"RegisterCycle: tried to access non-existent stack");	/*fprintf(stderr, "RegisterCycle(%s)\n", rule);*/	/* Find cycle start */	r = (RuleEntry *) hash_get(Rname, rule);	require(r!=NULL,eMsg1("rule %s must be defined but isn't", rule));	require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]),			eMsg1("RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox",				  rule));/***	if ( FoTOS[k]<FoStack[k]||FoTOS[k]>&(FoStack[k][FoStackSize-1]) )****	{****		fprintf(stderr, "RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox\n",****						rule);****		fprintf(stderr, "RegisterCycle: sp==0x%x out of bounds 0x%x...0x%x\n",****						FoTOS[k], FoStack[k], &(FoStack[k][FoStackSize-1]));****		exit(PCCTS_EXIT_FAILURE);****	}****/#ifdef MEMCHK	require(valid(FoStack[k]), "RegisterCycle: invalid FoStack");#endif	for (p=FoTOS[k]; *p != r->rulenum && p >= FoStack[k]; --p) {;}	require(p>=FoStack[k], "RegisterCycle: FoStack is screwed up beyond belief");	if ( p == FoTOS[k] ) return;	/* don't worry about cycles to oneself */		/* compute cyclic dependents (rules in cycle except head) */	c = newCycle;	require(c!=NULL, "RegisterCycle: couldn't alloc new cycle");	c->cyclicDep = empty;	c->croot = *p++;		/* record root of cycle */	for (; p<=FoTOS[k]; p++)	{		/* Mark all dependent rules as incomplete */		f = (CacheEntry *) hash_get(Fcache, Fkey(RulePtr[*p]->rname,'o',k));		if ( f==NULL )		{			f = newCacheEntry( Fkey(RulePtr[*p]->rname,'o',k) );			hash_add(Fcache, Fkey(RulePtr[*p]->rname,'o',k), (Entry *)f);		}		f->incomplete = TRUE;				set_orel(*p, &(c->cyclicDep)); /* mark rule as dependent of croot */	}	list_add(&(Cycles[k]), (void *)c);}/* make all rules in cycle complete * * while ( some set has changed ) do *		for each cycle do *			if degree of FOLLOW set for croot > old degree then *				update all FOLLOW sets for rules in cyclic dependency *				change = TRUE *			endif *		endfor * endwhile */void#ifdef __STDC__ResolveFoCycles( int k )#elseResolveFoCycles( k )int k;#endif{	ListNode *p, *q;	Cycle *c;	int changed = 1;	CacheEntry *f,*g;	int r;/*  int i;  */  /* MR10 not useful */	unsigned d;    unsigned    *cursor;        /* MR10 */    unsigned    *origin;        /* MR10 */		/*fprintf(stderr, "Resolving following cycles for %d\n", k);*/	while ( changed )	{		changed = 0;/* MR10 i = 0;  */		for (p = Cycles[k]->next; p!=NULL; p=p->next)		{			c = (Cycle *) p->elem;			/*fprintf(stderr, "cycle %d: %s -->", i++, RulePtr[c->croot]->rname);*/			/*s_fprT(stderr, c->cyclicDep);*/			/*fprintf(stderr, "\n");*/			f = (CacheEntry *)					hash_get(Fcache, Fkey(RulePtr[c->croot]->rname,'o',k));			require(f!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[c->croot]->rname) );			if ( (d=set_deg(f->fset)) > c->deg )			{				/*fprintf(stderr, "Fo(%s) has changed\n", RulePtr[c->croot]->rname);*/				changed = 1;				c->deg = d;		/* update cycle FOLLOW set degree *//* MR10 */      origin=set_pdq(c->cyclicDep);/* MR10 */      for (cursor=origin; *cursor != nil; cursor++) {/* MR10 */         r=*cursor;/********		while ( !set_nil(c->cyclicDep) ) {      *****//********					r = set_int(c->cyclicDep);  *****//********					set_rm(r, c->cyclicDep);    *****/					/*fprintf(stderr, "updating Fo(%s)\n", RulePtr[r]->rname);*/					g = (CacheEntry *)							hash_get(Fcache, Fkey(RulePtr[r]->rname,'o',k));					require(g!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[r]->rname) );					set_orin(&(g->fset), f->fset);					g->incomplete = FALSE;				}/* MR10 */      free( (char *) origin);/* MR10 */      origin=NULL;			}		}/* MR10 - this if statement appears to be meaningless since i is always 0 *//* MR10		if ( i == 1 ) changed = 0;	*/ /* if only 1 cycle, no need to repeat */	}	/* kill Cycle list */	for (q = Cycles[k]->next; q != NULL; q=p)	{		p = q->next;		set_free( ((Cycle *)q->elem)->cyclicDep );		free((char *)q);	}	free( (char *)Cycles[k] );	Cycles[k] = NULL;}			/* P r i n t i n g  S y n t a x  D i a g r a m s */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -