1: 
   2: /* (c) 1979 Regents of the University of California */
   3: # include "ey.h"
   4:   /*     * * * *    e y a c c     * * * *     */
   5: 
   6:   /**** NB -----
   7:    *
   8:    * This version of yacc, known as "eyacc" has been slightly but
   9:    * importantly modified to allow error recovery in the UNIX Pascal
  10:    * translator "pi" and also in "pix".
  11:    *
  12:    * Changes here include:
  13:    *
  14:    * 1) Enumeration of test actions when "error" is an input token.
  15:    *
  16:    * 2) Change to the encoding of the action entries.  Test entries
  17:    *    are encoded as the arithmetic inverse of the symbol being tested
  18:    *	for.  This is an optimization that makes the parser run at the
  19:    *	same speed even though, with error productions and enumerated
  20:    *	lookaheads, it would normally be much slower.  Of course the
  21:    *	same thing could be done to the regular yacc...
  22:    *
  23:    * 3) Different table sizes
  24:    *
  25:    * 4) Recognizes form feeds
  26:    *
  27:    * 5) Also most of the numbers for the sizes of the tables have been
  28:    *	increased, to an extent to allow for "eyacc"ing of the Pascal grammar
  29:    *	and of a grammar which I have for "EUCLID".
  30:    *
  31:    *	There seem to be subtle dependencies between the various magic
  32:    *	numbers... I found some of them but to be safe most of the limits
  33:    *	are very generous... for this reason "eyacc" will most likely
  34:    *	have to run separate i/d... no matter.
  35:    *
  36:    *					Bill Joy
  37:    *					Computer Science Division
  38:    *					EECS Department
  39:    *					University of California, Berkeley
  40:    *					Berkeley, California  94704
  41:    *
  42:    *					Office:	(415) 642-4948
  43:    *					Home:	(415) 524-4510
  44:    ****/
  45: 
  46:   /*      features to be fixed up ...
  47: 
  48:   ***  Print estimate of total space needed for parser
  49:   ***  Either list inputs on y.output, or list empty prdn's in states
  50:   ***  Mention nonterms not used (or, rules. not reduced) as nonfatal error
  51:   ***  Output states where conflicts were found by default on y.output
  52:   ***  Engage in newspeak: production=>grammar rules, term=>token, etc.
  53:   ***  handle # define, #ifdef, etc., in yacc actions, %{ %}
  54:   */
  55: 
  56:   /*      new features to be added
  57: 
  58:   ***  reductions by single productions ( by request )
  59:   ***  follow sets for start symbol
  60:   ***  option to only do slr(1)
  61:   ***  easily changed array names on output
  62:   ***  allocate core, rather than predefined
  63:   ***  input controlled by a grammar
  64:   ***  support multiple choices for  conflicts
  65:   ***  better conflict diagnostics
  66:   */
  67: 
  68: extern char *symnam();
  69: 
  70: main(argc,argv) int argc; char *argv[]; {
  71:   auto int n;
  72: 
  73:   whereami();
  74:   setup(argc,argv); /* initialize and read productions */
  75:   tbitset = (nterms+16)/16;
  76:   cpres(); /* make table of which productions yield a given nonterminal */
  77:   cempty(); /* make a table of which nonterminals can match the empty string */
  78:   cpfir(); /* make a table of e free first lists */
  79:   stagen(); /* generate the states */
  80:   output();  /* write the states and the tables */
  81:   go2out();
  82:   summary();
  83:   windup();
  84:   }
  85: 
  86: whereami(){ /* sets the variable machine to UNIX, GCOS, or IBM */
  87: 
  88:   int i;
  89: 
  90:   i = 1;
  91:   i = i << 30;
  92:   if( i == 0 ) {
  93:     machine = UNIX;
  94:     return;
  95:     }
  96:   i = i << 4;
  97:   if( i == 0 ){
  98:     machine = IBM;
  99:     return;
 100:     }
 101:   machine = GCOS;
 102:   }
 103: 
 104: windup(){
 105:   /* no errors, do the optimization if appropriate */
 106:   char *cp;
 107:   int i;
 108: 
 109:   if( !oflag ) cexit(0);
 110: 
 111:   switch( machine ){
 112: 
 113:   case GCOS:
 114:     if( rflag ){
 115:       if( foutput<0 ) system( "./yopt -r" );
 116:       else system( "./yopt -rv" );
 117:       }
 118:     else {
 119:       if( foutput<0 ) system( "./yopt" );
 120:       else system( "./yopt -v" );
 121:       }
 122:     cexit(0);  /* terminate */
 123: 
 124:   case UNIX:
 125:     cp = "/usr/nlib/yaccopt";
 126:     if( rflag ) execl( cp, cp, (foutput<0)?"-r":"-rv", 0 );
 127:     else if( foutput<0 ) execl( cp, cp, 0 );
 128:     else execl( cp, cp, "-v", 0 );
 129:     error( "optimization execl call fails" );
 130: 
 131:   case IBM:
 132:     if( rflag ){
 133:       if( foutput<0 ) system( "MH2019.yaccopt -r" );
 134:       else system( "MH2019.yaccopt -rv" );
 135:       }
 136:     else {
 137:       if( foutput<0 ) system( "MH2019.yaccopt" );
 138:       else system( "MH2019.yaccopt -v" );
 139:       }
 140:     cexit(0);
 141: 
 142:     }
 143: 
 144:   }
 145: 
 146: settty()
 147: /*	sets the output file to y.output */
 148: {
 149:     cflush( foutput );  /* a bit of a cheat */
 150:     cout = foutput;
 151:     }
 152: 
 153: settab(){ /* sets the output file to y.tab.c */
 154: 
 155:     cflush( ftable );
 156:     cout = ftable;
 157:     }
 158: 
 159: char *chcopy( p, q )  char *p, *q; {
 160:     /* copies string q into p, returning next free char ptr */
 161:     while( *p = *q++ ) ++p;
 162:     return( p );
 163:     }
 164: 
 165: char *writem(pp) struct item *pp; { /* creates output string for item pointed to by pp */
 166:     int i,*p;
 167:     static char sarr[100];
 168:     char *q;
 169: 
 170:     for( p=pp->pitem; *p>0 ; ++p ) ;
 171:     p = prdptr[-*p];
 172:     q = chcopy( sarr, nontrst[*p-NTBASE].name );
 173:     q = chcopy( q, " : " );
 174: 
 175:     for(;;){
 176:         *q++ = ++p==(pp->pitem) ? '_' : ' ';
 177:         if((i = *p) <= 0) break;
 178:         q = chcopy( q, symnam(i) );
 179:         }
 180: 
 181:     *q = '\0' ;
 182:     return( sarr );
 183:     }
 184: 
 185: char *symnam(i){ /* return a pointer to the name of symbol i */
 186:     char *cp;
 187: 
 188:     cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : trmset[i].name ;
 189:     if( *cp == ' ' ) ++cp;
 190:     return( cp );
 191:     }
 192: 
 193: summary(){ /* output the summary on the tty */
 194: 
 195:   int i, s, *pn;
 196: 
 197: 
 198:     if( !rflag ){
 199:         settab();
 200:         fprintf( cout , "\nint nterms = %d;",nterms);
 201:         fprintf( cout , "\nint nnonter = %d;", nnonter);
 202:         fprintf( cout , "\nint nstate = %d;", nstate);
 203:         fprintf( cout , "\nchar *yysterm[] = {");
 204:         for (i=1;i<=nterms;i++) if( trmset[i].value >= 0400 ) fprintf( cout , "\n\"%s\",",symnam(i));
 205:         fprintf( cout ,  "\n0 };\n" );
 206:         fprintf( cout , "\nchar *yysnter[] = {");
 207:         for (i=0;i<nnonter;i++) fprintf( cout , "\n\"%s\",",nontrst[i].name);
 208:         fprintf( cout , "\n\"%s\" };\n",nontrst[nnonter].name);
 209:         }
 210: 
 211:   settty();
 212:   fprintf( cout , "\n%d/%d terminals, %d/%d nonterminals\n", nterms, tlim,
 213:       nnonter, ntlim );
 214:   fprintf( cout , "%d/%d grammar rules, %d/%d states\n", nprod, prdlim, nstate, stsize );
 215:   fprintf( cout , "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf );
 216:   pn = pstate[nstate+1];
 217:   fprintf( cout , "%d/%d working sets used\n", zzcwset,  wssize );
 218:   fprintf( cout , "memory: states,etc. %d/%d, parser %d/%d\n", pn-mem0, memsiz,
 219:       memact, actsiz );
 220:   fprintf( cout , "%d/%d distinct lookahead sets\n", nlset, lsetsz );
 221:   fprintf( cout , "%d extra closures\n", zzclose - 2*nstate );
 222:   fprintf( cout , "%d action entries\n", zzacent );
 223:   fprintf( cout , "%d action entries saved through merging %d states\n",zzacsave,zznsave);
 224:   fprintf( cout , "%d goto entries\n", zzgoent );
 225:   fprintf( cout , "%d entries saved by goto default\n", zzgobest );
 226:   if( zzsrconf!=0 || zzrrconf!=0 ){
 227:     cflush( errfileno );
 228:     cout = errfileno;
 229:     fprintf( cout , "\nconflicts: ");
 230:     if( zzsrconf )fprintf( cout ,  "%d shift/reduce" , zzsrconf );
 231:     if( zzsrconf && zzrrconf )fprintf( cout ,  ", " );
 232:     if( zzrrconf )fprintf( cout ,  "%d reduce/reduce" , zzrrconf );
 233:     fprintf( cout ,  "\n" );
 234:     }
 235:   }
 236: 
 237: error(s,a1){ /* write out error comment */
 238: 
 239:     int c;
 240:     ++nerrors;
 241:     cflush( errfileno );
 242:     cout = errfileno;   /* set output to tty */
 243:     fprintf( cout , "\n fatal error: ");
 244:     fprintf( cout , s,a1);
 245:         fprintf( cout , ", line %d\n", lineno );
 246:     if( !fatfl ) return;
 247:     summary();
 248:     cexit(1);
 249:     }
 250: 
 251: arrset(s) char s[]; {
 252:     fprintf( cout , "\nint %s[] = {0", s );
 253:     arrndx = 1;
 254:     }
 255: 
 256: arrval(n){
 257:     fprintf( cout , ",%d",n);
 258:     if( (++arrndx%10) == 0 ) fprintf( cout , "\n");
 259:     }
 260: 
 261: arrdone(){
 262:     fprintf( cout , ",-1};\n");
 263:     }
 264: 
 265: copy(v) char *v; {  /* copy ctokn to v */
 266:     char *p;
 267: 
 268:     p=ctokn;
 269:     while( *v++ = *p++ );
 270:     }
 271: 
 272: compare(v) char *v; {   /* compare ctokn with v */
 273:     char *p;
 274: 
 275:     for( p=ctokn; ; ++p ){
 276:         if( *p != *v++ ) return( 0 );
 277:         if( *p == 0 ) return(1);
 278:         }
 279:     }
 280: 
 281: int *yalloc(n){ /* allocate n+1 words from vector mem */
 282:     int *omem;
 283:     omem = mem;
 284:     mem += n+1;
 285:     if(mem-mem0 >= memsiz) error("memory overflow");
 286:     return(omem);
 287:     }
 288: 
 289: aryfil( v, n, c ) int *v,n,c; { /* set elements 0 through n-1 to c */
 290:   int i;
 291:   for( i=0; i<n; ++i ) v[i] = c;
 292:   }
 293: 
 294: UNION( a, b, c ) int *a, *b, *c; {
 295:   /* set a to the UNION of b and c */
 296:   /* a may equal b */
 297:   /* return 1 if c is not a subset of b, 0 otherwise */
 298: 
 299:   _REGISTER int i, x, sub;
 300: 
 301:   sub = 0;
 302:   for( i=0; i<tbitset; ++i ){
 303:     x = b[i] | c[i];
 304:     if( x != b[i] ) sub=1;
 305:     a[i] = x;
 306:     }
 307:   return( sub );
 308:   }
 309: 
 310: prlook( pp ) int *pp;{
 311:     int j;
 312:     pp = pp->lset;
 313:     if( pp == 0 ) fprintf( cout , "\tNULL");
 314:     else {
 315:         fprintf( cout , " { " );
 316:         for( j=1; j<=nterms; ++j ){
 317:             if( (pp[j>>4]>>(j&017) )&01 != 0 ) fprintf( cout ,  "%s ", symnam(j) );
 318:             }
 319:         fprintf( cout ,  "}" );
 320:         }
 321:     }

Defined functions

UNION defined in line 294; used 5 times
arrdone defined in line 261; used 6 times
arrset defined in line 251; used 6 times
arrval defined in line 256; used 16 times
aryfil defined in line 289; used 9 times
chcopy defined in line 159; used 3 times
compare defined in line 272; used 16 times
copy defined in line 265; never used
error defined in line 237; used 41 times
main defined in line 70; never used
prlook defined in line 310; used 2 times
settab defined in line 153; used 10 times
settty defined in line 146; used 12 times
summary defined in line 193; used 3 times
symnam defined in line 185; used 8 times
whereami defined in line 86; used 1 times
  • in line 73
windup defined in line 104; used 1 times
  • in line 83
writem defined in line 165; used 3 times
yalloc defined in line 281; used 3 times
Last modified: 1986-05-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3105
Valid CSS Valid XHTML 1.0 Strict