|
|
1.1 ! root 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.2 (Berkeley) 9/22/88"; ! 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: setup(argc,argv); /* initialize and read productions */ ! 82: tbitset = (nterms+16)/16; ! 83: cpres(); /* make table of which productions yield a given nonterminal */ ! 84: cempty(); /* make a table of which nonterminals can match the empty string */ ! 85: cpfir(); /* make a table of e free first lists */ ! 86: stagen(); /* generate the states */ ! 87: output(); /* write the states and the tables */ ! 88: go2out(); ! 89: summary(); ! 90: exit(0); ! 91: } ! 92: ! 93: settty() ! 94: /* sets the output file to y.output */ ! 95: { ! 96: cflush( foutput ); /* a bit of a cheat */ ! 97: cout = foutput; ! 98: } ! 99: ! 100: settab(){ /* sets the output file to y.tab.c */ ! 101: ! 102: cflush( ftable ); ! 103: cout = ftable; ! 104: } ! 105: ! 106: char *chcopy( p, q ) char *p, *q; { ! 107: /* copies string q into p, returning next free char ptr */ ! 108: while( *p = *q++ ) ++p; ! 109: return( p ); ! 110: } ! 111: ! 112: char *writem(pp) struct item *pp; { /* creates output string for item pointed to by pp */ ! 113: int i,*p; ! 114: static char sarr[100]; ! 115: char *q; ! 116: ! 117: for( p=pp->pitem; *p>0 ; ++p ) ; ! 118: p = prdptr[-*p]; ! 119: q = chcopy( sarr, nontrst[*p-NTBASE].name ); ! 120: q = chcopy( q, " : " ); ! 121: ! 122: for(;;){ ! 123: *q++ = ++p==(pp->pitem) ? '_' : ' '; ! 124: if((i = *p) <= 0) break; ! 125: q = chcopy( q, symnam(i) ); ! 126: } ! 127: ! 128: *q = '\0' ; ! 129: return( sarr ); ! 130: } ! 131: ! 132: char *symnam(i){ /* return a pointer to the name of symbol i */ ! 133: char *cp; ! 134: ! 135: cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : trmset[i].name ; ! 136: if( *cp == ' ' ) ++cp; ! 137: return( cp ); ! 138: } ! 139: ! 140: summary(){ /* output the summary on the tty */ ! 141: ! 142: int i, s, *pn; ! 143: ! 144: ! 145: if( !rflag ){ ! 146: settab(); ! 147: fprintf( cout , "\nint nterms %d;",nterms); ! 148: fprintf( cout , "\nint nnonter %d;", nnonter); ! 149: fprintf( cout , "\nint nstate %d;", nstate); ! 150: fprintf( cout , "\nchar *yysterm[] {"); ! 151: for (i=1;i<=nterms;i++) if( trmset[i].value >= 0400 ) fprintf( cout , "\n\"%s\",",symnam(i)); ! 152: fprintf( cout , "\n0 };\n" ); ! 153: fprintf( cout , "\nchar *yysnter[] {"); ! 154: for (i=0;i<nnonter;i++) fprintf( cout , "\n\"%s\",",nontrst[i].name); ! 155: fprintf( cout , "\n\"%s\" };\n",nontrst[nnonter].name); ! 156: } ! 157: ! 158: settty(); ! 159: fprintf( cout , "\n%d/%d terminals, %d/%d nonterminals\n", nterms, tlim, ! 160: nnonter, ntlim ); ! 161: fprintf( cout , "%d/%d grammar rules, %d/%d states\n", nprod, prdlim, nstate, stsize ); ! 162: fprintf( cout , "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf ); ! 163: pn = (int *)pstate[nstate+1]; ! 164: fprintf( cout , "%d/%d working sets used\n", zzcwset, wssize ); ! 165: fprintf( cout , "memory: states,etc. %d/%d, parser %d/%d\n", pn-mem0, memsiz, ! 166: memact, actsiz ); ! 167: fprintf( cout , "%d/%d distinct lookahead sets\n", nlset, lsetsz ); ! 168: fprintf( cout , "%d extra closures\n", zzclose - 2*nstate ); ! 169: fprintf( cout , "%d action entries\n", zzacent ); ! 170: fprintf( cout , "%d action entries saved through merging %d states\n",zzacsave,zznsave); ! 171: fprintf( cout , "%d goto entries\n", zzgoent ); ! 172: fprintf( cout , "%d entries saved by goto default\n", zzgobest ); ! 173: fprintf( cout , "%d lookahead sets saved\n", savedlook); ! 174: if( zzsrconf!=0 || zzrrconf!=0 ){ ! 175: cflush( errfileno ); ! 176: cout = errfileno; ! 177: fprintf( cout , "\nconflicts: "); ! 178: if( zzsrconf )fprintf( cout , "%d shift/reduce" , zzsrconf ); ! 179: if( zzsrconf && zzrrconf )fprintf( cout , ", " ); ! 180: if( zzrrconf )fprintf( cout , "%d reduce/reduce" , zzrrconf ); ! 181: fprintf( cout , "\n" ); ! 182: } ! 183: } ! 184: ! 185: error(s,a1){ /* write out error comment */ ! 186: ! 187: int c; ! 188: ++nerrors; ! 189: cflush( errfileno ); ! 190: cout = errfileno; /* set output to tty */ ! 191: fprintf( cout , "\n fatal error: "); ! 192: fprintf( cout , s,a1); ! 193: fprintf( cout , ", line %d\n", lineno ); ! 194: if( !fatfl ) return; ! 195: summary(); ! 196: cexit(1); ! 197: } ! 198: ! 199: arrset(s) char s[]; { ! 200: fprintf( cout , "\nint %s[] {0", s ); ! 201: arrndx = 1; ! 202: } ! 203: ! 204: arrval(n){ ! 205: fprintf( cout , ",%d",n); ! 206: if( (++arrndx%10) == 0 ) fprintf( cout , "\n"); ! 207: } ! 208: ! 209: arrdone(){ ! 210: fprintf( cout , ",-1};\n"); ! 211: } ! 212: ! 213: copy(v) char *v; { /* copy ctokn to v */ ! 214: char *p; ! 215: ! 216: p=ctokn; ! 217: while( *v++ = *p++ ); ! 218: } ! 219: ! 220: compare(v) char *v; { /* compare ctokn with v */ ! 221: char *p; ! 222: ! 223: for( p=ctokn; ; ++p ){ ! 224: if( *p != *v++ ) return( 0 ); ! 225: if( *p == 0 ) return(1); ! 226: } ! 227: } ! 228: ! 229: int *yalloc(n){ /* allocate n+1 words from vector mem */ ! 230: int *omem; ! 231: omem = mem; ! 232: mem += n+1; ! 233: if(mem-mem0 >= memsiz) error("memory overflow"); ! 234: return(omem); ! 235: } ! 236: ! 237: aryfil( v, n, c ) int *v,n,c; { /* set elements 0 through n-1 to c */ ! 238: int i; ! 239: for( i=0; i<n; ++i ) v[i] = c; ! 240: } ! 241: ! 242: UNION( a, b, c ) int *a, *b, *c; { ! 243: /* set a to the UNION of b and c */ ! 244: /* a may equal b */ ! 245: /* return 1 if c is not a subset of b, 0 otherwise */ ! 246: ! 247: _REGISTER int i, x, sub; ! 248: ! 249: sub = 0; ! 250: for( i=0; i<tbitset; ++i ){ ! 251: x = b[i] | c[i]; ! 252: if( x != b[i] ) sub=1; ! 253: a[i] = x; ! 254: } ! 255: return( sub ); ! 256: } ! 257: ! 258: prlook( p ) struct looksets *p;{ ! 259: int j, *pp; ! 260: pp = p->lset; ! 261: if( pp == 0 ) fprintf( cout , "\tNULL"); ! 262: else { ! 263: fprintf( cout , " { " ); ! 264: for( j=1; j<=nterms; ++j ){ ! 265: if( (pp[j>>4]>>(j&017) )&01 != 0 ) fprintf( cout , "%s ", symnam(j) ); ! 266: } ! 267: fprintf( cout , "}" ); ! 268: } ! 269: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.