|
|
1.1 ! root 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: cflush(1); ! 109: if( !oflag ) cexit(0); ! 110: ! 111: for( i=3; i<10; ++i ) cclose(i); ! 112: switch( machine ){ ! 113: ! 114: case GCOS: ! 115: if( rflag ){ ! 116: if( foutput<0 ) system( "./yopt -r" ); ! 117: else system( "./yopt -rv" ); ! 118: } ! 119: else { ! 120: if( foutput<0 ) system( "./yopt" ); ! 121: else system( "./yopt -v" ); ! 122: } ! 123: cexit(0); /* terminate */ ! 124: ! 125: case UNIX: ! 126: cp = "/usr/nlib/yaccopt"; ! 127: if( rflag ) execl( cp, cp, (foutput<0)?"-r":"-rv", 0 ); ! 128: else if( foutput<0 ) execl( cp, cp, 0 ); ! 129: else execl( cp, cp, "-v", 0 ); ! 130: error( "optimization execl call fails" ); ! 131: ! 132: case IBM: ! 133: if( rflag ){ ! 134: if( foutput<0 ) system( "MH2019.yaccopt -r" ); ! 135: else system( "MH2019.yaccopt -rv" ); ! 136: } ! 137: else { ! 138: if( foutput<0 ) system( "MH2019.yaccopt" ); ! 139: else system( "MH2019.yaccopt -v" ); ! 140: } ! 141: cexit(0); ! 142: ! 143: } ! 144: ! 145: } ! 146: ! 147: settty() ! 148: /* sets the output file to y.output */ ! 149: { ! 150: cflush( foutput ); /* a bit of a cheat */ ! 151: cout = foutput; ! 152: } ! 153: ! 154: settab(){ /* sets the output file to y.tab.c */ ! 155: ! 156: cflush( ftable ); ! 157: cout = ftable; ! 158: } ! 159: ! 160: char *chcopy( p, q ) char *p, *q; { ! 161: /* copies string q into p, returning next free char ptr */ ! 162: while( *p = *q++ ) ++p; ! 163: return( p ); ! 164: } ! 165: ! 166: char *writem(pp) struct item *pp; { /* creates output string for item pointed to by pp */ ! 167: int i,*p; ! 168: static char sarr[100]; ! 169: char *q; ! 170: ! 171: for( p=pp->pitem; *p>0 ; ++p ) ; ! 172: p = prdptr[-*p]; ! 173: q = chcopy( sarr, nontrst[*p-NTBASE].name ); ! 174: q = chcopy( q, " : " ); ! 175: ! 176: for(;;){ ! 177: *q++ = ++p==(pp->pitem) ? '_' : ' '; ! 178: if((i = *p) <= 0) break; ! 179: q = chcopy( q, symnam(i) ); ! 180: } ! 181: ! 182: *q = '\0' ; ! 183: return( sarr ); ! 184: } ! 185: ! 186: char *symnam(i){ /* return a pointer to the name of symbol i */ ! 187: char *cp; ! 188: ! 189: cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : trmset[i].name ; ! 190: if( *cp == ' ' ) ++cp; ! 191: return( cp ); ! 192: } ! 193: ! 194: summary(){ /* output the summary on the tty */ ! 195: ! 196: int i, s, *pn; ! 197: ! 198: ! 199: if( !rflag ){ ! 200: settab(); ! 201: fprintf( cout , "\nint nterms %d;",nterms); ! 202: fprintf( cout , "\nint nnonter %d;", nnonter); ! 203: fprintf( cout , "\nint nstate %d;", nstate); ! 204: fprintf( cout , "\nchar *yysterm[] {"); ! 205: for (i=1;i<=nterms;i++) if( trmset[i].value >= 0400 ) fprintf( cout , "\n\"%s\",",symnam(i)); ! 206: fprintf( cout , "\n0 };\n" ); ! 207: fprintf( cout , "\nchar *yysnter[] {"); ! 208: for (i=0;i<nnonter;i++) fprintf( cout , "\n\"%s\",",nontrst[i].name); ! 209: fprintf( cout , "\n\"%s\" };\n",nontrst[nnonter].name); ! 210: } ! 211: ! 212: settty(); ! 213: fprintf( cout , "\n%d/%d terminals, %d/%d nonterminals\n", nterms, tlim, ! 214: nnonter, ntlim ); ! 215: fprintf( cout , "%d/%d grammar rules, %d/%d states\n", nprod, prdlim, nstate, stsize ); ! 216: fprintf( cout , "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf ); ! 217: pn = pstate[nstate+1]; ! 218: fprintf( cout , "%d/%d working sets used\n", zzcwset, wssize ); ! 219: fprintf( cout , "memory: states,etc. %d/%d, parser %d/%d\n", pn-mem0, memsiz, ! 220: memact, actsiz ); ! 221: fprintf( cout , "%d/%d distinct lookahead sets\n", nlset, lsetsz ); ! 222: fprintf( cout , "%d extra closures\n", zzclose - 2*nstate ); ! 223: fprintf( cout , "%d action entries\n", zzacent ); ! 224: fprintf( cout , "%d action entries saved through merging %d states\n",zzacsave,zznsave); ! 225: fprintf( cout , "%d goto entries\n", zzgoent ); ! 226: fprintf( cout , "%d entries saved by goto default\n", zzgobest ); ! 227: if( zzsrconf!=0 || zzrrconf!=0 ){ ! 228: cflush( errfileno ); ! 229: cout = errfileno; ! 230: fprintf( cout , "\nconflicts: "); ! 231: if( zzsrconf )fprintf( cout , "%d shift/reduce" , zzsrconf ); ! 232: if( zzsrconf && zzrrconf )fprintf( cout , ", " ); ! 233: if( zzrrconf )fprintf( cout , "%d reduce/reduce" , zzrrconf ); ! 234: fprintf( cout , "\n" ); ! 235: } ! 236: } ! 237: ! 238: error(s,a1){ /* write out error comment */ ! 239: ! 240: int c; ! 241: ++nerrors; ! 242: cflush( errfileno ); ! 243: cout = errfileno; /* set output to tty */ ! 244: fprintf( cout , "\n fatal error: "); ! 245: fprintf( cout , s,a1); ! 246: fprintf( cout , ", line %d\n", lineno ); ! 247: if( !fatfl ) return; ! 248: summary(); ! 249: cexit(1); ! 250: } ! 251: ! 252: arrset(s) char s[]; { ! 253: fprintf( cout , "\nint %s[] {0", s ); ! 254: arrndx = 1; ! 255: } ! 256: ! 257: arrval(n){ ! 258: fprintf( cout , ",%d",n); ! 259: if( (++arrndx%10) == 0 ) fprintf( cout , "\n"); ! 260: } ! 261: ! 262: arrdone(){ ! 263: fprintf( cout , ",-1};\n"); ! 264: } ! 265: ! 266: copy(v) char *v; { /* copy ctokn to v */ ! 267: char *p; ! 268: ! 269: p=ctokn; ! 270: while( *v++ = *p++ ); ! 271: } ! 272: ! 273: compare(v) char *v; { /* compare ctokn with v */ ! 274: char *p; ! 275: ! 276: for( p=ctokn; ; ++p ){ ! 277: if( *p != *v++ ) return( 0 ); ! 278: if( *p == 0 ) return(1); ! 279: } ! 280: } ! 281: ! 282: int *yalloc(n){ /* allocate n+1 words from vector mem */ ! 283: int *omem; ! 284: omem = mem; ! 285: mem += n+1; ! 286: if(mem-mem0 >= memsiz) error("memory overflow"); ! 287: return(omem); ! 288: } ! 289: ! 290: aryfil( v, n, c ) int *v,n,c; { /* set elements 0 through n-1 to c */ ! 291: int i; ! 292: for( i=0; i<n; ++i ) v[i] = c; ! 293: } ! 294: ! 295: UNION( a, b, c ) int *a, *b, *c; { ! 296: /* set a to the UNION of b and c */ ! 297: /* a may equal b */ ! 298: /* return 1 if c is not a subset of b, 0 otherwise */ ! 299: ! 300: _REGISTER int i, x, sub; ! 301: ! 302: sub = 0; ! 303: for( i=0; i<tbitset; ++i ){ ! 304: x = b[i] | c[i]; ! 305: if( x != b[i] ) sub=1; ! 306: a[i] = x; ! 307: } ! 308: return( sub ); ! 309: } ! 310: ! 311: prlook( pp ) int *pp;{ ! 312: int j; ! 313: pp = pp->lset; ! 314: if( pp == 0 ) fprintf( cout , "\tNULL"); ! 315: else { ! 316: fprintf( cout , " { " ); ! 317: for( j=1; j<=nterms; ++j ){ ! 318: if( (pp[j>>4]>>(j&017) )&01 != 0 ) fprintf( cout , "%s ", symnam(j) ); ! 319: } ! 320: fprintf( cout , "}" ); ! 321: } ! 322: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.