📄 y1.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)y1.c 1.1 11/7/83";#endif not lint# include "dextern"# include "yaccpar.h"/************************************************************************ * * * Copyright (c) 1983 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * Modification History * * Stephen Reilly, 07-Nov-83 * 001- We no longer read yaccpar, which is the template parser, it is now * in an include file called yaccpar.h. The reason for this is * so yacc can be part of the binary kit. * ***********************************************************************/ /* 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 */main(argc,argv) int argc; char *argv[]; { setup(argc,argv); /* 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(); exit(0); }others(){ /* put out other arrays, copy the parsers */ register c, i, j; char **t, *p;/* SLR001 * * We no longer read the file yaccpar it is not part of an include * file * * 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 *//* SLR001 * This protion of the code has been rewritten so it now read the * data structer called yacclin which contains the template parser */ for ( t = yacclin ; *t; t++ ) { p = *t; while ( (c= *p++ ) != '\0' ) { if( c == '$' ){ if( (c= *p++ ) != '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 = *p++; } } putc( c, ftable ); } } fclose( ftable ); }char *chcopy( p, q ) char *p, *q; { /* copies string q into p, returning next free char ptr */ while( *p = *q++ ) ++p; return( p ); }# define ISIZE 400char *writem(pp) int *pp; { /* creates output string for item pointed to by 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 ); }char *symnam(i){ /* return a pointer to the name of symbol 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;summary(){ /* output the summary on the tty */ 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 */error(s,a1) char *s; { /* write out error comment */ ++nerrors; fprintf( stderr, "\n fatal error: "); fprintf( stderr, s,a1); fprintf( stderr, ", line %d\n", lineno ); if( !fatfl ) return; summary(); exit(1); }aryfil( v, n, c ) int *v,n,c; { /* set elements 0 through n-1 to c */ int i; for( i=0; i<n; ++i ) v[i] = c; }setunion( a, b ) register *a, *b; { /* set a to the union of a and b */ /* return 1 if b is not a subset of a, 0 otherwise */ register i, x, sub; sub = 0; SETLOOP(i){ *a = (x = *a)|*b++; if( *a++ != x ) sub = 1; } return( sub ); }prlook( p ) struct looksets *p;{ register 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, "}" ); } }cpres(){ /* 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 */ register **pmem; register 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(); exit(1); } if( pmem != &pyield[nprod] ) error( "internal Yacc error: pyield %d", pmem-&pyield[nprod] ); }int indebug = 0;cpfir() { /* compute an array with the first of nonterminals */ register *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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -