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

Defined functions

UNION defined in line 293; used 5 times
arrdone defined in line 260; used 6 times
arrset defined in line 250; used 6 times
arrval defined in line 255; used 16 times
aryfil defined in line 288; used 9 times
chcopy defined in line 158; used 3 times
compare defined in line 271; used 16 times
copy defined in line 264; never used
error defined in line 236; used 41 times
main defined in line 69; never used
prlook defined in line 309; used 2 times
settab defined in line 152; used 10 times
settty defined in line 145; used 12 times
summary defined in line 192; used 3 times
symnam defined in line 184; used 8 times
whereami defined in line 85; used 1 times
  • in line 72
windup defined in line 103; used 1 times
  • in line 82
writem defined in line 164; used 3 times
yalloc defined in line 280; used 3 times
Last modified: 1981-01-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1067
Valid CSS Valid XHTML 1.0 Strict