📄 hparse.c
字号:
if (succNode->pred->nUse < 0) succNode->pred->nUse = -succNode->pred->nUse; } FreeLinkSet(subNet->entryNode->pred); FreeLinkSet(subNet->exitNode->succ); subNet->entryNode->pred = p->pred; subNet->entryNode->pred->nUse++; subNet->exitNode->succ = p->succ; subNet->exitNode->succ->nUse++;}static void ExpandSubNetDefs(Link *chain){ Link p,q; HPNetwork *proto; HPNetwork subNet; p = *chain; *chain = NULL; while (p != NULL) { if (p->extName == subNetId) { if ((HPNetwork *) p->modelName->aux == NULL) HError(3130,"ExpandSubNetDefs: Variable %s is undefined",p->modelName->name); proto = (HPNetwork *) p->modelName->aux; subNet = CloneNetwork(*proto); SubstituteSubNet(&subNet,p); q = subNet.chain; while (q->chain != NULL) q=q->chain; q->chain = p->chain; FreeNode(p); /* free sub-net node */ p = subNet.chain; /* process its def instead */ } else { q = p->chain; /* form new chain in reverse order */ p->chain = *chain; *chain = p; p = q; } } } /* ----------------------- Scanner ------------------------ */#define ESCAPE '\\'#define SCANBUFMAX 255 /* amount read from input at one time */#define H_EOF '\0'enum _Symbol{NAMESYM, VARSYM, VARATSYM, LPARSYM, RPARSYM, LBRACESYM, RBRACESYM, LANGSYM, RANGSYM, LBRAKSYM, RBRAKSYM, LTRISYM,RTRISYM,EQSYM, SEMISYM, BARSYM, PERCENTSYM, EOFSYM}; static LabId ident; /* Current identifier, if any */static char inlyne[SCANBUFMAX+1]; /* (Portion of) current input line */static char ch; /* Current character */static enum _Symbol symbol; /* Current symbol */static int curpos; /* Current position in input line */static int curlen; /* Current length of input line */static FILE *f; /* Input stream *//* InitScan: initialise scanner to read from fname */static void InitScan(char *fname){ if ((f=fopen(fname,"r")) == NULL) HError(3110,"InitScan: Cannot open Network Defn file %s",fname); curlen=curpos=1; ch=' '; inlyne[0]=' '; inlyne[1]='\0';}/* PGetCh: get next input character -> ch */static void PGetCh(void){ if (curpos>=curlen) { if (fgets(inlyne,SCANBUFMAX,f)==NULL) { ch=H_EOF; return; } curpos=0; curlen=strlen(inlyne); if (inlyne[curlen-1] == '\n') inlyne[curlen-1]=' '; /* change newline,if any to space */ } ch = inlyne[curpos++];}/* PGetIdent: get identifer -> ident */static void PGetIdent(void){ int i=0; Ident id; do { if (ch==ESCAPE) PGetCh(); if (i<MAXIDENT) id[i++]=ch; PGetCh(); } while ( !isspace((int) ch) && ch!='{' && ch!='}' && ch!='[' && ch!=']' && ch!='<' && ch!='>' && ch!='(' && ch!=')' && ch!='=' && ch!=';' && ch!='|' && ch!='/' && ch!='%'); id[i]='\0'; ident = GetLabId(id,TRUE);}/* PGetSym: get next symbol -> symbol */static void PGetSym(void){ while (isspace((int) ch) || (ch=='/' && inlyne[curpos]=='*') ) { if (isspace((int) ch)) /* skip space */ PGetCh(); else { /* skip comment */ PGetCh(); PGetCh(); while (!(ch=='*' && inlyne[curpos]=='/')) PGetCh(); PGetCh(); PGetCh(); } } switch (ch) { case '$': PGetCh(); PGetIdent(); symbol=VARSYM; break; case '(': PGetCh(); symbol=LPARSYM; break; case ')': PGetCh(); symbol=RPARSYM; break; case '<': PGetCh(); if (ch=='<') {symbol=LTRISYM; PGetCh();} else symbol=LANGSYM; break; case '>': PGetCh(); if (ch=='>') {symbol=RTRISYM; PGetCh();} else symbol=RANGSYM; break; case '{': PGetCh(); symbol=LBRACESYM; break; case '}': PGetCh(); symbol=RBRACESYM; break; case '[': PGetCh(); symbol=LBRAKSYM; break; case ']': PGetCh(); symbol=RBRAKSYM; break; case '=': PGetCh(); symbol=EQSYM; break; case ';': PGetCh(); symbol=SEMISYM; break; case '|': PGetCh(); symbol=BARSYM; break; case '%': PGetCh(); symbol=PERCENTSYM; break; case H_EOF: symbol=EOFSYM; break; default: PGetIdent(); symbol=NAMESYM; break; }}/* ------------------------- Errors ------------------------ *//* ParseError: Print a parser error message then die */static void ParseError(int errn){ int i; fprintf(stderr,"%s\n",inlyne); for (i=1; i<curpos-1; i++) fputc(' ',stderr); fprintf(stderr, "^ *** Error %d\n",errn); switch(errn) { case 1: HError(3150,"ParseError: Unexpected EOF"); case 2: HError(3150,"ParseError: Garbage at end of file"); case 3: HError(3150,"ParseError: Factor expected"); case 4: HError(3150,"ParseError: variable expected"); case 5: HError(3150,"ParseError: = expected"); case 6: HError(3150,"ParseError: ; expected"); case 7: HError(3150,"ParseError: ) expected"); case 8: HError(3150,"ParseError: ] expected"); case 9: HError(3150,"ParseError: } expected"); case 10: HError(3150,"ParseError: > expected"); case 11: HError(3150,"ParseError: >> expected"); case 12: HError(3150,"ParseError: External name expected"); case 13: HError(3150,"ParseError: ( expected"); default: HError(3150,"ParseError: Unknown error number!!!"); }}/* --------------------------- Parser -------------------------------- *//* Each parser routine has two parameters: hd and tl. As each routine completes successfully, it uses these parameters to return the head and tail of a subnetwork representing the structure just parsed.*/LabId curId; /* name of current variable def, if any */static void PExpr(Link *hd, Link *tl);/* PModel: parse a model name and create a node for it */static void PModel(Link *hd, Link *tl){ Link p; p=CreateNode(ident,&curChain,LINKCHUNKSIZE,LINKCHUNKSIZE); *hd = *tl = p; PGetSym(); if (symbol==PERCENTSYM){ PGetSym(); if (symbol!=NAMESYM && symbol != PERCENTSYM) ParseError(12); if (symbol==PERCENTSYM) p->extName = NULL; else p->extName = ident; PGetSym(); }}/* PVariable: parse a variable name and create a node for variable */static void PVariable(Link *hd, Link *tl){ Link p; HPNetwork *proto; if((proto = (HPNetwork *)ident->aux) == NULL) HError(3130,"PVariable: Variable %s is undefined",ident->name); p=CreateNode(ident,&curChain,LINKCHUNKSIZE,LINKCHUNKSIZE); p->extName = subNetId; *hd = *tl = p; PGetSym();}/* PGroup: parse ( .. ) */static void PGroup(Link *hd, Link *tl){ PGetSym(); PExpr(hd,tl); if (symbol!=RPARSYM) ParseError(7); PGetSym();}/* POption: parse [ .. ] */static void POption(Link *hd, Link *tl){ Link eTail; PGetSym(); PExpr(hd, &eTail); *tl = CreateNode(NULL,&curChain,LINKCHUNKSIZE,LINKCHUNKSIZE); JoinNodes(*hd,*tl); JoinNodes(eTail,*tl); if (symbol!=RBRAKSYM) ParseError(8); PGetSym();}/* PRepetition0: parse { .. } */static void PRepetition0(Link *hd, Link *tl){ Link eHead, eTail; PGetSym(); PExpr(&eHead, &eTail); *hd = *tl = CreateNode(NULL,&curChain,LINKCHUNKSIZE,LINKCHUNKSIZE); JoinNodes(*tl,eHead); JoinNodes(eTail,*tl); if (symbol!=RBRACESYM) ParseError(9); PGetSym();}/* PRepetition1: parse < .. > */static void PRepetition1(Link *hd, Link *tl){ PGetSym(); PExpr(hd, tl); JoinNodes(*tl,*hd); if (symbol!=RANGSYM) ParseError(10); PGetSym();}/* PTriloop: parse << .. >> */static void PTriloop(Link *hd, Link *tl){ Link curChainSave; Link p; PGetSym(); curChainSave = curChain; curChain = NULL; PExpr(hd, tl); ExpandSubNetDefs(&curChain); p = curChain; while (p->chain != NULL) p=p->chain; p->chain=curChainSave; /* add on the old curChain */ MakeTriLoop(hd, tl); if (symbol!=RTRISYM) ParseError(11); PGetSym();}/* PFactor: parse a factor */static void PFactor(Link *hd, Link *tl){ switch(symbol) { case NAMESYM: PModel(hd,tl); break; case VARSYM: PVariable(hd,tl); break; case LPARSYM: PGroup(hd,tl); break; case LBRAKSYM: POption(hd,tl); break; case LBRACESYM: PRepetition0(hd,tl); break; case LANGSYM: PRepetition1(hd,tl); break; case LTRISYM: PTriloop(hd,tl); break; default: ParseError(3); }}/* PSequence: parse a sequence of factors */static void PSequence(Link *hd, Link *tl){ Link hd2, tl2; PFactor(hd,tl); while (symbol==NAMESYM || symbol==VARSYM || symbol==LBRAKSYM || symbol==LBRACESYM || symbol==LPARSYM || symbol==LTRISYM || symbol==LANGSYM) { PFactor(&hd2, &tl2); JoinNodes(*tl,hd2); *tl=tl2; } if ((*hd)->pred->numLinks != 0) { hd2 = *hd; *hd = CreateNode(NULL,&curChain,LINKCHUNKSIZE,LINKCHUNKSIZE); JoinNodes(*hd,hd2); } if ((*tl)->succ->numLinks != 0) { tl2 = *tl; *tl=CreateNode(NULL,&curChain,LINKCHUNKSIZE,LINKCHUNKSIZE); JoinNodes(tl2,*tl); }}/* PExpr: parse an expression */static void PExpr(Link *hd, Link *tl){ Link hd2, tl2; PSequence(hd,tl); hd2 = *hd, tl2 = *tl; *hd=CreateNode(NULL,&curChain,LINKCHUNKSIZE,LINKCHUNKSIZE); *tl=CreateNode(NULL,&curChain,LINKCHUNKSIZE,LINKCHUNKSIZE); JoinNodes(*hd,hd2); JoinNodes(tl2,*tl); while (symbol==BARSYM) { PGetSym(); PSequence(&hd2, &tl2); HeadMerge(*hd,hd2); TailMerge(tl2,*tl); }}/* PSubNet: parse a subnet def and store it */static void PSubNet(void){ Link hd,tl; if (symbol != VARSYM) ParseError(4); curId=ident; PGetSym(); if (symbol != EQSYM) ParseError(5); PGetSym(); curChain=NULL; PExpr(&hd,&tl); if (symbol != SEMISYM) ParseError(6); PGetSym(); DefineSubNet(curId,hd,tl,curChain);}static LabId enterExitId; /* for use in RemoveGlue *//* PNetwork: parse a complete network definition. If netOnly then there must be a main network expression and all subnet definitions are destroyed once the main net has been built. Otherwise, a main net expression is optional. If skipEpr then the main net is skipped even if it is there. */static void PNetwork(Link *hd, Link *tl, Boolean netOnly, Boolean skipExpr){ Link entryNode,exitNode; InitSubNetDefs(); enterExitId = GetLabId("$$$HPARSE_ENTEREXITNODE",TRUE); /* for use in RemoveGlue */ while (symbol != LPARSYM && symbol != EOFSYM) { PSubNet(); } curId=NULL; curChain=NULL; *hd = NULL; *tl = NULL; if ((!skipExpr && symbol == LPARSYM) || netOnly){ if (symbol != LPARSYM) ParseError(13); PGetSym(); entryNode = CreateNode(enterId,&curChain,LINKCHUNKSIZE,1); exitNode = CreateNode(exitId,&curChain,1,LINKCHUNKSIZE); PExpr(hd,tl); JoinNodes(entryNode,*hd); JoinNodes(*tl,exitNode); *hd=entryNode; *tl=exitNode; if (symbol != RPARSYM) ParseError(7); PGetSym(); } if (symbol!=EOFSYM && !skipExpr) ParseError(2); ExpandSubNetDefs(&curChain); if (netOnly) FreeSubNetDefs();}/* -------------------- Clean Up HParse Network ---------------------- *//* ReSizeNodes: scan the network and shrink all of its nodes */static void ReSizeNodes(HPNetwork *net){ Link p; p=net->chain; while (p!=NULL) { ShrinkNode(p); p=p->chain; }}/* DeleteLink: delete a link x from a linkSet ls */static void DeleteLink(Link x, LinkSet *ls) /* note: deletes the link whether ls is shared or not */{ Boolean found = FALSE; int i,j; i = 0; for (i=1; i<=ls->numLinks; i++) { if (ls->links[i] == x) { found = TRUE; break; } } if (found) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -