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