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

Defined functions

UNION defined in line 303; used 5 times
arrdone defined in line 270; used 6 times
arrset defined in line 260; used 6 times
arrval defined in line 265; used 16 times
chcopy defined in line 167; used 3 times
compare defined in line 281; used 16 times
copy defined in line 274; never used
main defined in line 78; never used
prlook defined in line 319; used 2 times
settab defined in line 161; used 10 times
settty defined in line 154; used 15 times
summary defined in line 201; used 3 times
symnam defined in line 193; used 8 times
whereami defined in line 94; used 1 times
  • in line 81
windup defined in line 112; used 1 times
  • in line 91
yalloc defined in line 290; used 3 times

Defined variables

sccsid defined in line 8; never used
Last modified: 1985-04-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3201
Valid CSS Valid XHTML 1.0 Strict