📄 y1.c
字号:
#include "dextern.h"/* * variables used locally * lookahead computations */int tbitset; /* size of lookahead sets */struct looksets lkst [LSETSIZE];int nlset = 0; /* next lookahead set index */int nolook = 0; /* flag to suppress lookahead computations */struct looksets clset; /* temporary storage for lookahead computations *//* * working set computations */struct wset wsets[WSETSIZE];struct wset *cwp;/* * state information */int nstate = 0; /* number of states */struct item *pstate[NSTATES+2]; /* pointers to the descriptions of the states */int tystate[NSTATES]; /* contains type information about the states */int indgo[NSTATES]; /* index to the stored goto table */int tstates[NTERMS]; /* states generated by terminal gotos */int ntstates[NNONTERM]; /* states generated by nonterminal gotos */int mstates[NSTATES]; /* chain of overflows of term/nonterm generation lists *//* * storage for the actions in the parser */int amem[ACTSIZE]; /* action table storage */int *memp = amem; /* next free action table position *//* * other storage areas */int temp1[TEMPSIZE]; /* temporary storage, indexed by terms + ntokens or states */int lineno= 1; /* current input line number */int fatfl = 1; /* if on, error is fatal */int nerrors = 0; /* number of errors *//* * storage for information about the nonterminals */int **pres[NNONTERM+2]; /* vector of pointers to productions yielding each nonterminal */struct looksets *pfirst[NNONTERM+2]; /* vector of pointers to first sets for each nonterminal */int pempty[NNONTERM+1]; /* vector of nonterminals nontrivially deriving e */void others(void);char *chcopy(char *p, char *q);char *writem(int *pp);char *symnam(int i);void summary(void);void error(char *s, ...);void aryfil(int *v, int n, int c);int setunion(register int *a, register int *b);void prlook(struct looksets *p);void cpres(void);void cpfir(void);int state(int c);void putitem(int *ptr, struct looksets *lptr);void cempty(void);void stagen(void);void closure(int i);struct looksets *flset(struct looksets *p);int main(int argc,char *argv[]){ setup(argc,argv); yyparse(); /* initialize and read productions */ tbitset = NWORDS(ntokens); cpres(); /* make table of which productions yield a given nonterminal */ cempty(); /* make a table of which nonterminals can match the empty string */ cpfir(); /* make a table of firsts of nonterminals */ stagen(); /* generate the states */ output(); /* write the states and the tables */ go2out(); hideprod(); summary(); callopt(); others(); return 0;}/* * put out other arrays, copy the parsers */void others(void){ register int c, i, j; finput = fopen(PARSER, "r"); if(finput == NULL) error("cannot find parser %s", PARSER); warray("yyr1", levprd, nprod); aryfil(temp1, nprod, 0); PLOOP(1,i) temp1[i] = prdptr[i+1]-prdptr[i]-2; warray("yyr2", temp1, nprod); aryfil(temp1, nstate, -1000); TLOOP(i){ for(j=tstates[i]; j!=0; j=mstates[j]){ temp1[j] = tokset[i].value; } } NTLOOP(i){ for(j=ntstates[i]; j!=0; j=mstates[j]){ temp1[j] = -i; } } warray("yychk", temp1, nstate); warray("yydef", defact, nstate); /* copy parser text */ while((c=getc(finput)) != EOF){ if(c == '$'){ if((c=getc(finput)) != 'A') putc('$', ftable); else { /* copy actions */ faction = fopen(ACTNAME, "r"); if(faction == NULL) error("cannot reopen action tempfile"); while((c=getc(faction)) != EOF) putc(c, ftable); fclose(faction); ZAPFILE(ACTNAME); c = getc(finput); } } putc(c, ftable); } fclose(ftable);}/* * copies string q into p, returning next free char ptr */char *chcopy(char *p, char *q){ while((*p = *q++)) ++p; return(p);}#define ISIZE 400/* * creates output string for item pointed to by pp */char *writem(int *pp){ int i,*p; static char sarr[ISIZE]; char *q; for(p=pp; *p>0 ; ++p) ; p = prdptr[-*p]; q = chcopy(sarr, nontrst[*p-NTBASE].name); q = chcopy(q, " : "); for(;;){ *q++ = ++p==pp ? '_' : ' '; *q = '\0'; if((i = *p) <= 0) break; q = chcopy(q, symnam(i)); if(q> &sarr[ISIZE-30]) error("item too big"); } if((i = *pp) < 0){ /* an item calling for a reduction */ q = chcopy(q, " ("); sprintf(q, "%d)", -i); } return(sarr);}/* * return a pointer to the name of symbol i */char *symnam(int i){ char *cp; cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : tokset[i].name ; if(*cp == ' ') ++cp; return(cp);}struct wset *zzcwp = wsets;int zzgoent = 0;int zzgobest = 0;int zzacent = 0;int zzexcp = 0;int zzclose = 0;int zzsrconf = 0;int * zzmemsz = mem0;int zzrrconf = 0;/* * output the summary on the tty */void summary(void){ if(foutput!=NULL){ fprintf(foutput, "\n%d/%d terminals, %d/%d nonterminals\n", ntokens, NTERMS, nnonter, NNONTERM); fprintf(foutput, "%d/%d grammar rules, %d/%d states\n", nprod, NPROD, nstate, NSTATES); fprintf(foutput, "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf); fprintf(foutput, "%d/%d working sets used\n", zzcwp-wsets, WSETSIZE); fprintf(foutput, "memory: states,etc. %d/%d, parser %d/%d\n", zzmemsz-mem0, MEMSIZE, memp-amem, ACTSIZE); fprintf(foutput, "%d/%d distinct lookahead sets\n", nlset, LSETSIZE); fprintf(foutput, "%d extra closures\n", zzclose - 2*nstate); fprintf(foutput, "%d shift entries, %d exceptions\n", zzacent, zzexcp); fprintf(foutput, "%d goto entries\n", zzgoent); fprintf(foutput, "%d entries saved by goto default\n", zzgobest); } if(zzsrconf!=0 || zzrrconf!=0){ fprintf(stdout,"\nconflicts: "); if(zzsrconf) fprintf(stdout, "%d shift/reduce" , zzsrconf); if(zzsrconf && zzrrconf) fprintf(stdout, ", "); if(zzrrconf) fprintf(stdout, "%d reduce/reduce" , zzrrconf); fprintf(stdout, "\n"); } fclose(ftemp); if(fdefine != NULL) fclose(fdefine);}/* VARARGS1 *//* * write out error comment */void error(char *s, ...){ va_list ap; void * a; va_start(ap, s); ++nerrors; fprintf(stderr, "\n fatal error: "); a=va_arg(ap, void*); fprintf(stderr, s, a, va_arg(ap,void*)); va_end(ap); fprintf(stderr, ", line %d\n", lineno); if(!fatfl) return; summary(); ZAPFILE(ACTNAME); ZAPFILE(TEMPNAME); ZAPFILE(OFILE); if (fdefine != NULL) ZAPFILE(FILED); exit(1);}/* * set elements 0 through n-1 to c */void aryfil(int *v, int n, int c){ int i; for(i=0; i<n; ++i) v[i] = c;}/* * set a to the union of a and b * return 1 if b is not a subset of a, 0 otherwise */int setunion(register int *a, register int *b){ register int i, x, sub; sub = 0; SETLOOP(i){ *a = (x = *a)|*b++; if(*a++ != x) sub = 1; } return(sub);}void prlook(struct looksets *p){ register int j, *pp; pp = p->lset; if(pp == 0) fprintf(foutput, "\tNULL"); else { fprintf(foutput, " { "); TLOOP(j) { if(BIT(pp,j)) fprintf(foutput, "%s ", symnam(j)); } fprintf(foutput, "}"); }}/* * compute an array with the beginnings of productions yielding given nonterminals * The array pres points to these lists * the array pyield has the lists: the total size is only NPROD+1 */void cpres(void){ register int **pmem; register int c, j, i; static int * pyield[NPROD]; pmem = pyield; NTLOOP(i){ c = i+NTBASE; pres[i] = pmem; fatfl = 0; /* make undefined symbols nonfatal */ PLOOP(0,j){ if (*prdptr[j] == c) *pmem++ = prdptr[j]+1; } if(pres[i] == pmem){ error("nonterminal %s not defined!", nontrst[i].name); } } pres[i] = pmem; fatfl = 1; if(nerrors){ summary(); ZAPFILE(ACTNAME); ZAPFILE(TEMPNAME); ZAPFILE(OFILE); if (fdefine != NULL) ZAPFILE(FILED); exit(1); } if(pmem != &pyield[nprod]) error("internal Yacc error: pyield %d", pmem-&pyield[nprod]);}int indebug = 0;/* * compute an array with the first of nonterminals */void cpfir(void){ register int *p, **s, i, **t, ch, changes; zzcwp = &wsets[nnonter]; NTLOOP(i){ aryfil(wsets[i].ws.lset, tbitset, 0); t = pres[i+1]; for(s=pres[i]; s<t; ++s){ /* initially fill the sets */ for(p = *s; (ch = *p) > 0 ; ++p) { if(ch < NTBASE) { SETBIT(wsets[i].ws.lset, ch); break; } else if(!pempty[ch-NTBASE]) break; } } } /* now, reflect transitivity */ changes = 1; while(changes){ changes = 0; NTLOOP(i){ t = pres[i+1]; for(s=pres[i]; s<t; ++s){ for(p = *s; (ch = (*p-NTBASE)) >= 0; ++p) { changes |= setunion(wsets[i].ws.lset, wsets[ch].ws.lset); if(!pempty[ch]) break; } } } } NTLOOP(i) pfirst[i] = flset(&wsets[i].ws); if(!indebug) return; if((foutput!=NULL)){ NTLOOP(i) { fprintf(foutput, "\n%s: ", nontrst[i].name); prlook(pfirst[i]); fprintf(foutput, " %d\n", pempty[i]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -