1: # include <stdio.h> 2: # include "dextern" 3: 4: extern FILE *Fout, *Fin; 5: /* * * * * y a c c * * * * */ 6: 7: /* features to be fixed up ... 8: 9: *** Print estimate of total space needed for parser 10: *** Either list inputs on y.output, or list empty prdn's in states 11: *** Mention nonterms not used (or, rules. not reduced) as nonfatal error 12: *** Output states where conflicts were found by default on y.output 13: *** Engage in newspeak: production=>grammar rules, term=>token, etc. 14: *** handle # define, #ifdef, etc., in yacc actions, %{ %} 15: */ 16: 17: /* new features to be added 18: 19: *** reductions by single productions ( by request ) 20: *** follow sets for start symbol 21: *** option to only do slr(1) 22: *** easily changed array names on output 23: *** allocate core, rather than predefined 24: *** input controlled by a grammar 25: *** support multiple choices for conflicts 26: *** better conflict diagnostics 27: */ 28: 29: 30: 31: main(argc,argv) int argc; char *argv[]; { 32: auto int n; 33: 34: Fin = stdin; 35: Fout = stdout; 36: 37: whereami(); 38: setup(argc,argv); /* initialize and read productions */ 39: tbitset = (nterms+16)/16; 40: cpres(); /* make table of which productions yield a given nonterminal */ 41: cempty(); /* make a table of which nonterminals can match the empty string */ 42: cpfir(); /* make a table of e free first lists */ 43: stagen(); /* generate the states */ 44: output(); /* write the states and the tables */ 45: go2out(); 46: summary(); 47: windup(); 48: } 49: 50: whereami(){ /* sets the variable machine to UNIX, GCOS, or IBM */ 51: 52: int i; 53: 54: i = 1; 55: i = i << 30; 56: if( i == 0 ) { 57: machine = UNIX; 58: return; 59: } 60: i = i << 4; 61: if( i == 0 ){ 62: machine = IBM; 63: return; 64: } 65: machine = GCOS; 66: } 67: 68: windup(){ 69: /* no errors, do the optimization if appropriate */ 70: char *cp; 71: int i; 72: 73: cflush(stdout); 74: if( !oflag ) cexit(0); 75: 76: for( i=3; i<10; ++i ) cclose(i); 77: switch( machine ){ 78: 79: case GCOS: 80: if( rflag ){ 81: if( Foutput==0 ) system( "./yopt -r" ); 82: else system( "./yopt -rv" ); 83: } 84: else { 85: if( Foutput==0 ) system( "./yopt" ); 86: else system( "./yopt -v" ); 87: } 88: cexit(0); /* terminate */ 89: 90: case UNIX: 91: cp = "/usr/yacc/yopti"; 92: if( rflag ) execl( cp, cp, (Foutput==0)?"-r":"-rv", 0 ); 93: else if( Foutput==0 ) execl( cp, cp, 0 ); 94: else execl( cp, cp, "-v", 0 ); 95: error( "optimization execl call fails" ); 96: 97: case IBM: 98: if( rflag ){ 99: if( Foutput==0 ) system( "MH2019.yaccopt -r" ); 100: else system( "MH2019.yaccopt -rv" ); 101: } 102: else { 103: if( Foutput==0 ) system( "MH2019.yaccopt" ); 104: else system( "MH2019.yaccopt -v" ); 105: } 106: cexit(0); 107: 108: } 109: 110: } 111: 112: settty() 113: /* sets the output file to y.output */ 114: { 115: cflush( Foutput ); /* a bit of a cheat */ 116: cout = Foutput; 117: } 118: 119: settab(){ /* sets the output file to y.tab.c */ 120: 121: cflush( ftable ); 122: cout = ftable; 123: } 124: 125: char *chcopy( p, q ) char *p, *q; { 126: /* copies string q into p, returning next free char ptr */ 127: while( *p = *q++ ) ++p; 128: return( p ); 129: } 130: 131: char *writem(pp) struct item *pp; { /* creates output string for item pointed to by pp */ 132: int i,*p; 133: static char sarr[100]; 134: char *q; 135: 136: for( p=pp->pitem; *p>0 ; ++p ) ; 137: p = prdptr[-*p]; 138: q = chcopy( sarr, nontrst[*p-NTBASE].name ); 139: q = chcopy( q, " : " ); 140: 141: for(;;){ 142: *q++ = ++p==(pp->pitem) ? '_' : ' '; 143: if((i = *p) <= 0) break; 144: q = chcopy( q, symnam(i) ); 145: } 146: 147: *q = '\0' ; 148: return( sarr ); 149: } 150: 151: char *symnam(i){ /* return a pointer to the name of symbol i */ 152: char *cp; 153: 154: cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : trmset[i].name ; 155: if( *cp == ' ' ) ++cp; 156: return( cp ); 157: } 158: 159: summary(){ /* output the summary on the tty */ 160: 161: int i, s, *pn; 162: 163: 164: if (!rflag && !sflag) 165: { 166: settab(); 167: fprintf(Fout, "\nint nterms = %d;",nterms); 168: fprintf(Fout, "\nint nnonter = %d;", nnonter); 169: fprintf(Fout, "\nint nstate = %d;", nstate); 170: fprintf(Fout, "\nchar *yysterm[] = {"); 171: for (i=1;i<=nterms;i++) if( trmset[i].value >= 0400 ) fprintf(Fout, "\n\"%s\",",symnam(i)); 172: fprintf(Fout, "\n0 };\n" ); 173: fprintf(Fout, "\nchar *yysnter[] = {"); 174: for (i=0;i<nnonter;i++) fprintf(Fout, "\n\"%s\",",nontrst[i].name); 175: fprintf(Fout, "\n\"%s\" };\n",nontrst[nnonter].name); 176: } 177: 178: settty(); 179: fprintf(Fout, "\n%d/%d terminals, %d/%d nonterminals\n", nterms, tlim, 180: nnonter, ntlim ); 181: fprintf(Fout, "%d/%d grammar rules, %d/%d states\n", nprod, prdlim, nstate, stsize ); 182: fprintf(Fout, "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf ); 183: pn = pstate[nstate+1]; 184: fprintf(Fout, "%d/%d working sets used\n", zzcwset, wssize ); 185: fprintf(Fout, "memory: states,etc. %d/%d, parser %d/%d\n", pn-mem0, memsiz, 186: memact, actsiz ); 187: fprintf(Fout, "%d/%d distinct lookahead sets\n", nlset, lsetsz ); 188: fprintf(Fout, "%d extra closures\n", zzclose - 2*nstate ); 189: fprintf(Fout, "%d action entries\n", zzacent ); 190: fprintf(Fout, "%d action entries saved through merging %d states\n",zzacsave,zznsave); 191: fprintf(Fout, "%d goto entries\n", zzgoent ); 192: fprintf(Fout, "%d entries saved by goto default\n", zzgobest ); 193: if( zzsrconf!=0 || zzrrconf!=0 ){ 194: cflush( stderr ); 195: cout = stderr; 196: fprintf(Fout, "\nconflicts: "); 197: if( zzsrconf )fprintf(Fout, "%d shift/reduce" , zzsrconf ); 198: if( zzsrconf && zzrrconf )fprintf(Fout, ", " ); 199: if( zzrrconf )fprintf(Fout, "%d reduce/reduce" , zzrrconf ); 200: fprintf(Fout, "\n" ); 201: } 202: } 203: 204: error(s,a1){ /* write out error comment */ 205: 206: int c; 207: ++nerrors; 208: cflush( stderr ); 209: cout = stderr; /* set output to tty */ 210: fprintf(Fout, "\n fatal error: "); 211: fprintf(Fout, s,a1); 212: fprintf(Fout, ", line %d\n", lineno ); 213: if( !fatfl ) return; 214: summary(); 215: cexit(1); 216: } 217: 218: arrset(s) char s[]; { 219: fprintf(Fout, "\nint %s[] = {0", s ); 220: arrndx = 1; 221: } 222: 223: arrval(n){ 224: fprintf(Fout, ",%d",n); 225: if( (++arrndx%10) == 0 ) fprintf(Fout, "\n"); 226: } 227: 228: arrdone(){ 229: fprintf(Fout, ",-1};\n"); 230: } 231: 232: copy(v) char *v; { /* copy ctokn to v */ 233: char *p; 234: 235: p=ctokn; 236: while( *v++ = *p++ ); 237: } 238: 239: compare(v) char *v; { /* compare ctokn with v */ 240: char *p; 241: 242: for( p=ctokn; ; ++p ){ 243: if( *p != *v++ ) return( 0 ); 244: if( *p == 0 ) return(1); 245: } 246: } 247: 248: int *yalloc(n){ /* allocate n+1 words from vector mem */ 249: int *omem; 250: omem = mem; 251: mem += n+1; 252: if(mem-mem0 >= memsiz) error("memory overflow"); 253: return(omem); 254: } 255: 256: aryfil( v, n, c ) int *v,n,c; { /* set elements 0 through n-1 to c */ 257: int i; 258: for( i=0; i<n; ++i ) v[i] = c; 259: } 260: 261: sunion( a, b, c ) int *a, *b, *c; { 262: /* set a to the union of b and c */ 263: /* a may equal b */ 264: /* return 1 if c is not a subset of b, 0 otherwise */ 265: 266: _REGISTER int i, x, sub; 267: 268: sub = 0; 269: for( i=0; i<tbitset; ++i ){ 270: x = b[i] | c[i]; 271: if( x != b[i] ) sub=1; 272: a[i] = x; 273: } 274: return( sub ); 275: } 276: 277: prlook( pp ) int *pp;{ 278: int j; 279: pp = pp->lset; 280: if( pp == 0 ) fprintf(Fout, "\tNULL"); 281: else { 282: fprintf(Fout, " { " ); 283: for( j=1; j<=nterms; ++j ){ 284: if( (pp[j>>4]>>(j&017) )&01 != 0 ) fprintf(Fout, "%s ", symnam(j) ); 285: } 286: fprintf(Fout, "}" ); 287: } 288: }