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

📄 gen.c

📁 本工具提供一个词法分析器和语法分析器的集成开发环境
💻 C
📖 第 1 页 / 共 5 页
字号:
		if ( (e=g=set_pdq(fset[k])) == NULL ) fatal_internal("genExpr: cannot allocate IF expr pdq set");		for (; *e!=nil; e++)		{			if ( !firstTime ) _gen(" || ") else { _gen("("); firstTime = 0; }			on1line++;			if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }			_gen1("LA(%d)==",k);			if ( TokenString(*e) == NULL ) _gen1("%d", *e)			else _gen1("%s", TokenString(*e));		}		free( (char *)g );		_gen(")");		if ( k>max_k ) max_k = k;		if ( k == CLL_k ) break;		k++;		if ( k <= limit && !set_nil(fset[k]) ) { firstTime=1; _gen(" && "); }   /* MR11 */		on1line++;		if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }	}	return max_k;}/* * Generate code for any type of block.  If the last alternative in the block is * empty (not even an action) don't bother doing it.  This permits us to handle * optional and loop blocks as well. * * Only do this block, return after completing the block. * This routine is visible only to this file and cannot answer a TRANS message. */static set#ifdef __USE_PROTOSgenBlk( Junction *q, int jtype, int *max_k, int *need_right_curly )#elsegenBlk( q, jtype, max_k, need_right_curly )Junction *q;int jtype;int *max_k;int *need_right_curly;#endif{	set f;	Junction *alt;	int a_guess_in_block = 0;	require(q!=NULL,				"genBlk: invalid node");	require(q->ntype == nJunction,	"genBlk: not junction");	*need_right_curly=0;	if ( q->p2 == NULL )	/* only one alternative?  Then don't need if */	{			if (first_item_is_guess_block((Junction *)q->p1)!=NULL )		{            if (jtype != aLoopBlk && jtype != aOptBlk && jtype != aPlusBlk) {  			  warnFL("(...)? as only alternative of block is unnecessary", FileStr[q->file], q->line);            };   	   	    gen("zzGUESS\n");	/* guess anyway to make output code consistent *//* MR10 disable */  /**** gen("if ( !zzrv )\n"); ****//* MR10 */          gen("if ( !zzrv ) {\n"); tabs++; (*need_right_curly)++;        };		TRANS(q->p1);		return empty;		/* no decision to be made-->no error set */	}	f = First(q, 1, jtype, max_k);	for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )	{		if ( alt->p2 == NULL )					/* chk for empty alt */		{				Node *p = alt->p1;			if ( p->ntype == nJunction )			{				/* we have empty alt */				if ( ((Junction *)p)->p1 == (Node *)q->end )				{					break;						/* don't do this one, quit */				}			}		}/* MR10 */        if (alt->p2 == NULL &&/* MR10 */               ( q->jtype == aSubBlk || q->jtype == RuleBlk) ) {/* MR10 */          if (first_item_is_guess_block(alt)) {/* MR10 */               warnFL("(...)? as last alternative of block is unnecessary",/* MR10 */                                FileStr[alt->file],alt->line);/* MR10 */          };/* MR10 */        };		if ( alt != q ) gen("else ")		else		{			if ( DemandLookahead )				if ( !GenCC ) {gen1("LOOK(%d);\n", *max_k);}				else gen1("look(%d);\n", *max_k);		}		if ( alt!=q )		{			_gen("{\n");			tabs++;			(*need_right_curly)++;			/* code to restore state if a prev alt didn't follow guess */			if ( a_guess_in_block )				gen("if ( !zzrv ) zzGUESS_DONE;\n");		}		if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL )		{			a_guess_in_block = 1;			gen("zzGUESS\n");		}		gen("if ( ");		if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) _gen("!zzrv && ");		genExpr(alt);		_gen(" ) ");		_gen("{\n");		tabs++;		TRANS(alt->p1);		--tabs;		gen("}\n");/* MR10 */        if (alt->p2 == NULL) {/* MR10 */          if (first_item_is_guess_block(alt)) {/* MR10 */            gen("/* MR10 */ else {\n");/* MR10 */            tabs++;/* MR10 */  		  (*need_right_curly)++;/* MR10 */  		  /* code to restore state if a prev alt didn't follow guess *//* MR10 */            gen("/* MR10 */ if ( !zzrv ) zzGUESS_DONE;\n");/* MR10 */            gen("/* MR10 */ if (0) {}     /* last alternative of block is guess block */\n");/* MR10 */          };/* MR10 */        };	}	return f;}static int#ifdef __USE_PROTOShas_guess_block_as_first_item( Junction *q )#elsehas_guess_block_as_first_item( q )Junction *q;#endif{	Junction *alt;	for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )	{		if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) return 1;	}	return 0;}static int#ifdef __USE_PROTOShas_guess_block_as_last_item( Junction *q )#elsehas_guess_block_as_last_item( q )Junction *q;#endif{	Junction *alt;    if (q == NULL) return 0;	for (alt=q; alt->p2 != NULL && !( (Junction *) alt->p2)->ignore; alt= (Junction *) alt->p2 ) {};    return first_item_is_guess_block( (Junction *) alt->p1) != NULL;}/* return NULL if 1st item of alt is NOT (...)? block; else return ptr to aSubBlk node * of (...)?;  This function ignores actions and predicates. */Junction *#ifdef __USE_PROTOSfirst_item_is_guess_block( Junction *q )#elsefirst_item_is_guess_block( q )Junction *q;#endif{    /* MR14  Couldnt' find aSubBlock which was a guess block when it lay             behind aLoopBlk.  The aLoopBlk only appear in conjunction with             aLoopBegin, but the routine didn't know that.  I think.    */	while ( q!=NULL &&          ( q->ntype==nAction ) ||          ( q->ntype==nJunction && (q->jtype==Generic || q->jtype == aLoopBlk )) )	{		if ( q->ntype==nJunction ) q = (Junction *)q->p1;		else q = (Junction *) ((ActionNode *)q)->next;	}	if ( q==NULL ) return NULL;	if ( q->ntype!=nJunction ) return NULL;	if ( q->jtype!=aSubBlk ) return NULL;	if ( !q->guess ) return NULL;	return q;}/* MR1				                 					    *//* MR1  10-Apr-97 MR1 Routine to stringize failed semantic predicates msgs  *//* MR1				                                                        */#define STRINGIZEBUFSIZE 1024static char stringizeBuf[STRINGIZEBUFSIZE];char *#ifdef __USE_PROTOSstringize(char * s)#elsestringize(s)char *s;#endif{  char		*p;  char		*stop;  p=stringizeBuf;  stop=&stringizeBuf[1015];  if (s != 0) {    while (*s != 0) {      if (p >= stop) {	goto stringizeStop;      } else if (*s == '\n') {        *p++='\\';        *p++='n';        *p++='\\';	*p++=*s++;      } else if (*s == '\\') {	*p++=*s;	*p++=*s++;      } else if (*s == '\"') {        *p++='\\';	*p++=*s++;        while (*s != 0) {          if (p >= stop) {	     goto stringizeStop;	  } else if (*s == '\n') {	    *p++='\\';	    *p++=*s++;	  } else if (*s == '\\') {	    *p++=*s++;	    *p++=*s++;	  } else if (*s == '\"') {	    *p++='\\';	    *p++=*s++;	    break;	  } else {	    *p++=*s++;          };        };      } else if (*s == '\'') {	*p++=*s++;        while (*s != 0) {          if (p >= stop) {	     goto stringizeStop;	  } else if (*s == '\'') {	    *p++=*s++;	    break;	  } else if (*s == '\\') {	    *p++=*s++;	    *p++=*s++;	  } else if (*s == '\"') {	    *p++='\\';	    *p++=*s++;	    break;	  } else {	    *p++=*s++;          };        };      } else {        *p++=*s++;      };    };  };  goto stringizeExit;stringizeStop:  *p++='.';        	  *p++='.';        	  *p++='.';        	stringizeExit:  *p=0;  return stringizeBuf;}#ifdef __STDC__int isNullAction(char *s)#elseint isNullAction(s)  char  *s;#endif{  char  *p;  for (p=s; *p != '\0' ; p++) {    if (*p != ';' && *p !=' ') return 0;  };  return 1;}/* MR1									                                    *//* MR1	End of Routine to stringize code for failed predicates msgs         *//* MR1				                                                        *//* Generate an action.  Don't if action is NULL which means that it was already * handled as an init action. */void#ifdef __USE_PROTOSgenAction( ActionNode *p )#elsegenAction( p )ActionNode *p;#endif{	require(p!=NULL,			"genAction: invalid node and/or rule");	require(p->ntype==nAction,	"genAction: not action");		if ( !p->done )  /* MR10 */ /* MR11 */	{		if ( p->is_predicate)		{			if ( p->guardpred != NULL )			{                Predicate *guardDup=predicate_dup(p->guardpred); /* MR10 */                gen("if (!");       			guardDup=genPredTreeMain(guardDup, (Node *)p);                predicate_free(guardDup);			}/* MR10 */  else if (p->ampersandPred != NULL) {/* MR10 */      gen("if (!");/* MR10 */      p->ampersandPred=genPredTreeMain(p->ampersandPred, (Node *)p);/* MR10 */  }			else			{				gen("if (!(");				/* make sure that '#line n' is on front of line */				if ( GenLineInfo && p->file != -1 ) _gen("\n");				dumpPredAction(p,p->action, output, 0, p->file, p->line, 0);				_gen(")");			}			if ( p->pred_fail != NULL )			{				_gen(")\n");				tabs++;/* MR1				                                                        *//* MR1  10-Apr-97 MR1  Put {...} envelope around failed semantic predicates *//* MR1				                                                        */				gen1("{%s};\n", p->pred_fail);	                     /* MR1 */				tabs--;			}/* MR1						                                                *//* MR1  10-Apr-97 MR1	Properly stringize failed semantic predicates 	    *//* MR1				                                                        */			else _gen1(") {zzfailed_pred(\"%s\");}\n",               /* MR1 */					stringize(p->action));	                     /* MR1 */		}		else    /* not a predicate */		{            if (! isNullAction(p->action) && !p->noHoist) {  	  		  if ( FoundGuessBlk ) {				if ( GenCC ) {                  gen("if ( !guessing ) {\n");                } else {				  gen("zzNON_GUESS_MODE {\n");                };              };			  dumpAction(p->action, output, tabs, p->file, p->line, 1);			  if ( FoundGuessBlk ) gen("}\n");            };		}	}	TRANS(p->next)}/* *		if invoking rule has !noAST pass zzSTR to rule ref and zzlink it in *		else pass addr of temp root ptr (&_ast) (don't zzlink it in). * *		if ! modifies rule-ref, then never link it in and never pass zzSTR. *		Always pass address of temp root ptr. */void#ifdef __USE_PROTOSgenRuleRef( RuleRefNode *p )#elsegenRuleRef( p )RuleRefNode *p;#endif{	Junction *q;	char *handler_id = "";	RuleEntry *r, *r2;	char *parm = "", *exsig = "";    int     genRuleRef_emittedGuessGuard=0;     /* MR10 */	require(p!=NULL,			"genRuleRef: invalid node and/or rule");	require(p->ntype==nRuleRef, "genRuleRef: not rule reference");		if ( p->altstart!=NULL && p->altstart->exception_label!=NULL )		handler_id = p->altstart->exception_label;	r = (RuleEntry *) hash_get(Rname, p->text);	if ( r == NULL )	{		warnFL( eMsg1("rule %s not defined",					  p->text), FileStr[p->file], p->line );		return;	}/* MR8 5-Aug-97     Reported by S.Bochnak@microtool.com.pl                  *//*                  Don't do assign when no return values declared          *//*                  Move definition of q up and use it to guard p->assign   */	q = RulePtr[r->rulenum];	/* find definition of ref'd rule */  /* MR8 */	r2 = (RuleEntry *) hash_get(Rname, p->rname);	if ( r2 == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}    OutLineInfo(output,p->line,FileStr[p->file]);	if ( GenCC && GenAST ) {		gen("_ast = NULL;\n");	}	if ( FoundGuessBlk && p->assign!=NULL && q->ret != NULL ) {      /* MR8 */		if ( GenCC ) {          gen("if ( !guessing ) {\n");        } else {          gen("zzNON_GUESS_MODE {\n");        };        tabs++;                                                      /* MR11 */        genRuleRef_emittedGuessGuard=1;                              /* MR11 */    };	if ( FoundException ) exsig = "&_signal";	tab();	if ( GenAST )	{		if ( GenCC ) {/****			if ( r2->noAST || p->astnode==ASTexclude )****/			{/****				_gen("_ast = NULL;\n");****/				parm = "&_ast";			}/*** we always want to set just a pointer now, then set correctpointer after			else {				_gen("_astp =(_tail==NULL)?(&_sibling):(&(_tail->_right));\n");				parm = "_astp";			}****/		}		else {			if ( r2->noAST || p->astnode==ASTexclude )			{				_gen("_ast = NULL; ");				parm = "&_ast";			}			else parm = "zzSTR";		}		if ( p->assign!=NULL && q->ret!=NULL )                       /* MR8 */		{			if ( !HasComma(p->assign) ) {_gen1("%s = ",p->assign);}			else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);		}		if ( FoundException ) {			_gen5("%s%s(%s,&_signal%s%s); ",				  RulePrefix,				  p->text,				  parm,				  (p->parms!=NULL)?",":"",				  (p->parms!=NULL)?p->parms:"");			if ( p->ex_group!=NULL ) {				_gen("\n");				gen("if (_signal) {\n");				tabs++;				dumpException(p->ex_group, 0);				tabs--;				gen("}");			}			else {				_gen1("if (_signal) goto %s_handler;", handler_id);			}		}		else {			_gen5("%s%s(%s%s%s);",				  RulePrefix,				  p->text,				  parm,				  (p->parms!=NULL)?",":"",				  (p->parms!=NULL)?p->parms:"");		}		if ( GenCC && (r2->noAST || p->astnode==ASTexclude) )		{			/* rule has a ! or element does */			/* still need to assign to #i so we can play with it */			_gen("\n");			gen2("_ast%d%d = (AST *)_ast;", BlkLevel-1, p->elnum);		}

⌨️ 快捷键说明

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