📄 misc.c
字号:
static void#ifdef __STDC__pBlk( Junction *q, int btype )#elsepBlk( q, btype )Junction *q;int btype;#endif{ int k,a; Junction *alt, *p; q->end->pvisited = TRUE; if ( btype == aLoopBegin ) { require(q->p2!=NULL, "pBlk: invalid ()* block"); PRINT(q->p1); alt = (Junction *)q->p2; PRINT(alt->p1); if ( PrintAnnotate ) { printf(" /* Opt "); k = 1; while ( !set_nil(alt->fset[k]) ) { s_fprT(stdout, alt->fset[k]); if ( k++ == CLL_k ) break; if ( !set_nil(alt->fset[k]) ) printf(", "); } printf(" */\n"); } return; } for (a=1,alt=q; alt != NULL; alt= (Junction *) alt->p2, a++) { if ( alt->p1 != NULL ) PRINT(alt->p1); if ( PrintAnnotate ) { printf( " /* [%d] ", alt->altnum); k = 1; while ( !set_nil(alt->fset[k]) ) { s_fprT(stdout, alt->fset[k]); if ( k++ == CLL_k ) break; if ( !set_nil(alt->fset[k]) ) printf(", "); } if ( alt->p2 == NULL && btype == aOptBlk ) printf( " (optional branch) */\n"); else printf( " */\n"); } /* ignore implied empty alt of Plus blocks */ if ( alt->p2 != NULL && ((Junction *)alt->p2)->ignore ) break; if ( alt->p2 != NULL && !(((Junction *)alt->p2)->p2==NULL && btype == aOptBlk) ) { if ( pLevel == 1 ) { printf("\n"); if ( a+1==pAlt1 || a+1==pAlt2 ) printf("=>"); printf("\t"); } else printf(" "); printf("|"); if ( pLevel == 1 ) { p = (Junction *) ((Junction *)alt->p2)->p1; while ( p!=NULL ) { if ( p->ntype==nAction ) { p=(Junction *)((ActionNode *)p)->next; continue; } if ( p->ntype!=nJunction ) { break; } if ( p->jtype==EndBlk || p->jtype==EndRule ) { p = NULL; break; } p = (Junction *)p->p1; } if ( p==NULL ) printf("\n\t"); /* Empty alt? */ } } } q->end->pvisited = FALSE;}/* How to print out a junction */void#ifdef __STDC__pJunc( Junction *q )#elsepJunc( q )Junction *q;#endif{ int dum_k; int doing_rule; require(q!=NULL, "pJunc: NULL node"); require(q->ntype==nJunction, "pJunc: not junction"); if ( q->pvisited == TRUE ) return; q->pvisited = TRUE; switch ( q->jtype ) { case aSubBlk : if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); if ( q->end->p1 != NULL && ((Junction *)q->end->p1)->ntype==nJunction && ((Junction *)q->end->p1)->jtype == EndRule ) doing_rule = 1; else doing_rule = 0; pLevel++; if ( pLevel==1 ) { if ( pAlt1==1 ) printf("=>"); printf("\t"); } else printf(" "); if ( doing_rule ) { if ( pLevel==1 ) printf(" "); pBlk(q,q->jtype); } else { printf("("); if ( pLevel==1 ) printf(" "); pBlk(q,q->jtype); if ( pLevel>1 ) printf(" "); printf(")"); } if ( q->guess ) printf("?"); pLevel--; if ( PrintAnnotate ) freeBlkFsets(q); if ( q->end->p1 != NULL ) PRINT(q->end->p1); break; case aOptBlk : if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); pLevel++; if ( pLevel==1 ) { if ( pAlt1==1 ) printf("=>"); printf("\t"); } else printf(" "); printf("{"); if ( pLevel==1 ) printf(" "); pBlk(q,q->jtype); if ( pLevel>1 ) printf(" "); else printf("\n\t"); printf("}"); pLevel--; if ( PrintAnnotate ) freeBlkFsets(q); if ( q->end->p1 != NULL ) PRINT(q->end->p1); break; case aLoopBegin : if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); pLevel++; if ( pLevel==1 ) { if ( pAlt1==1 ) printf("=>"); printf("\t"); } else printf(" "); printf("("); if ( pLevel==1 ) printf(" "); pBlk(q,q->jtype); if ( pLevel>1 ) printf(" "); else printf("\n\t"); printf(")*"); pLevel--; if ( PrintAnnotate ) freeBlkFsets(q); if ( q->end->p1 != NULL ) PRINT(q->end->p1); break; case aLoopBlk : if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); pBlk(q,q->jtype); if ( PrintAnnotate ) freeBlkFsets(q); break; case aPlusBlk : if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); pLevel++; if ( pLevel==1 ) { if ( pAlt1==1 ) printf("=>"); printf("\t"); } else printf(" "); printf("("); if ( pLevel==1 ) printf(" "); pBlk(q,q->jtype); if ( pLevel>1 ) printf(" "); printf(")+"); pLevel--; if ( PrintAnnotate ) freeBlkFsets(q); if ( q->end->p1 != NULL ) PRINT(q->end->p1); break; case EndBlk : break; case RuleBlk : printf( "\n%s :\n", q->rname); PRINT(q->p1); if ( q->p2 != NULL ) PRINT(q->p2); break; case Generic : if ( q->p1 != NULL ) PRINT(q->p1); q->pvisited = FALSE; if ( q->p2 != NULL ) PRINT(q->p2); break; case EndRule : printf( "\n\t;\n"); break; } q->pvisited = FALSE;}/* How to print out a rule reference node */void#ifdef __STDC__pRuleRef( RuleRefNode *p )#elsepRuleRef( p )RuleRefNode *p;#endif{ require(p!=NULL, "pRuleRef: NULL node"); require(p->ntype==nRuleRef, "pRuleRef: not rule ref node"); printf( " %s", p->text); PRINT(p->next);}/* How to print out a terminal node */void#ifdef __STDC__pToken( TokNode *p )#elsepToken( p )TokNode *p;#endif{ require(p!=NULL, "pToken: NULL node"); require(p->ntype==nToken, "pToken: not token node"); if ( p->wild_card ) printf(" ."); printf( " %s", TerminalString(p->token)); PRINT(p->next);}/* How to print out a terminal node */void#ifdef __STDC__pAction( ActionNode *p )#elsepAction( p )ActionNode *p;#endif{ require(p!=NULL, "pAction: NULL node"); require(p->ntype==nAction, "pAction: not action node"); PRINT(p->next);} /* F i l l F o l l o w L i s t s *//* * Search all rules for all rule reference nodes, q to rule, r. * Add q->next to follow list dangling off of rule r. * i.e. * * r: -o-R-o-->o--> Ptr to node following rule r in another rule * | * o--> Ptr to node following another reference to r. * * This is the data structure employed to avoid FOLLOW set computation. We * simply compute the FIRST (reach) of the EndRule Node which follows the * list found at the end of all rules which are referenced elsewhere. Rules * not invoked by other rules have no follow list (r->end->p1==NULL). * Generally, only start symbols are not invoked by another rule. * * Note that this mechanism also gives a free cross-reference mechanism. * * The entire syntax diagram is layed out like this: * * SynDiag * | * v * o-->R1--o * | * o-->R2--o * | * ... * | * o-->Rn--o * */void#ifdef __STDC__FoLink( Node *p )#elseFoLink( p )Node *p;#endif{ RuleEntry *q; Junction *j = (Junction *) p; RuleRefNode *r = (RuleRefNode *) p; if ( p==NULL ) return; require(p->ntype>=1 && p->ntype<=NumNodeTypes, eMsgd("FoLink: invalid diagram node: ntype==%d",p->ntype)); switch ( p->ntype ) { case nJunction : if ( j->fvisited ) return; if ( j->jtype == EndRule ) return; j->fvisited = TRUE; FoLink( j->p1 ); FoLink( j->p2 );/* MR14 *//* MR14 */ /* Need to determine whether the guess block is an *//* MR14 */ /* of the form (alpha)? beta before follow sets are *//* MR14 */ /* computed. This is necessary to solve problem *//* MR14 */ /* of doing follow on the alpha of an (alpha)? beta block. *//* MR14 *//* MR14 */ /* This is performed by analysis_point as a side-effect. *//* MR14 *//* MR14 *//* MR14 */ if (j->jtype == aSubBlk && j->guess) {/* MR14 */ Junction *ignore;/* MR14 */ ignore=analysis_point(j);/* MR14 */ }/* MR14 */ return; case nRuleRef : if ( r->linked ) return; q = (RuleEntry *) hash_get(Rname, r->text); if ( q == NULL ) { warnFL( eMsg1("rule %s not defined",r->text), FileStr[r->file], r->line ); } else { if ( r->parms!=NULL && RulePtr[q->rulenum]->pdecl==NULL ) { warnFL( eMsg1("rule %s accepts no parameter(s)", r->text), FileStr[r->file], r->line ); } if ( r->parms==NULL && RulePtr[q->rulenum]->pdecl!=NULL ) { warnFL( eMsg1("rule %s requires parameter(s)", r->text), FileStr[r->file], r->line ); } if ( r->assign!=NULL && RulePtr[q->rulenum]->ret==NULL ) { warnFL( eMsg1("rule %s yields no return value(s)", r->text), FileStr[r->file], r->line ); } if ( r->assign==NULL && RulePtr[q->rulenum]->ret!=NULL ) { warnFL( eMsg1("rule %s returns a value(s)", r->text), FileStr[r->file], r->line ); } if ( !r->linked ) { addFoLink( r->next, r->rname, RulePtr[q->rulenum] ); r->linked = TRUE; } } FoLink( r->next ); return; case nToken : FoLink( ((TokNode *)p)->next ); return; case nAction : FoLink( ((ActionNode *)p)->next ); return; default : fatal_internal("invalid node type"); }}/* * Add a reference to the end of a rule. * * 'r' points to the RuleBlk node in a rule. r->end points to the last node * (EndRule jtype) in a rule. * * Initial: * r->end --> o * * After: * r->end --> o-->o--> Ptr to node following rule r in another rule * | * o--> Ptr to node following another reference to r. * * Note that the links are added to the head of the list so that r->end->p1 * always points to the most recently added follow-link. At the end, it should * point to the last reference found in the grammar (starting from the 1st rule). */void#ifdef __STDC__addFoLink( Node *p, char *rname, Junction *r )#elseaddFoLink( p, rname, r )Node *p;char *rname;Junction *r;#endif{ Junction *j; require(r!=NULL, "addFoLink: incorrect rule graph"); require(r->end!=NULL, "addFoLink: incorrect rule graph"); require(r->end->jtype==EndRule, "addFoLink: incorrect rule graph"); require(p!=NULL, "addFoLink: NULL FOLLOW link"); j = newJunction(); j->rname = rname; /* rname on follow links point to target rule */ j->p1 = p; /* link to other rule */ j->p2 = (Node *) r->end->p1;/* point to head of list */ r->end->p1 = (Node *) j; /* reset head to point to new node */}void#ifdef __STDC__GenCrossRef( Junction *p )#elseGenCrossRef( p )Junction *p;#endif{ set a; Junction *j; RuleEntry *q; unsigned e; require(p!=NULL, "GenCrossRef: why are you passing me a null grammar?"); printf("Cross Reference:\n\n"); a = empty; for (; p!=NULL; p = (Junction *)p->p2) { printf("Rule %20s referenced by {", p->rname); /* make a set of rules for uniqueness */ for (j = (Junction *)(p->end)->p1; j!=NULL; j = (Junction *)j->p2) { q = (RuleEntry *) hash_get(Rname, j->rname); require(q!=NULL, "GenCrossRef: FoLinks are screwed up"); set_orel(q->rulenum, &a); } for (; !set_nil(a); set_rm(e, a)) { e = set_int(a); printf(" %s", RulePtr[e]->rname); } printf(" }\n"); } set_free( a );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -