|
|
1.1 root 1: static char *sccsid = "@(#)ey1.c 4.1 (Berkeley) 3/1/81";
2: /* (c) 1979 Regents of the University of California */
3: # include "ey.h"
4: /* * * * * e y a c c * * * * */
5:
6: /**** NB -----
7: *
8: * This version of yacc, known as "eyacc" has been slightly but
9: * importantly modified to allow error recovery in the UNIX Pascal
10: * translator "pi" and also in "pix".
11: *
12: * Changes here include:
13: *
14: * 1) Enumeration of test actions when "error" is an input token.
15: *
16: * 2) Change to the encoding of the action entries. Test entries
17: * are encoded as the arithmetic inverse of the symbol being tested
18: * for. This is an optimization that makes the parser run at the
19: * same speed even though, with error productions and enumerated
20: * lookaheads, it would normally be much slower. Of course the
21: * same thing could be done to the regular yacc...
22: *
23: * 3) Different table sizes
24: *
25: * 4) Recognizes form feeds
26: *
27: * 5) Also most of the numbers for the sizes of the tables have been
28: * increased, to an extent to allow for "eyacc"ing of the Pascal grammar
29: * and of a grammar which I have for "EUCLID".
30: *
31: * There seem to be subtle dependencies between the various magic
32: * numbers... I found some of them but to be safe most of the limits
33: * are very generous... for this reason "eyacc" will most likely
34: * have to run separate i/d... no matter.
35: *
36: * Bill Joy
37: * Computer Science Division
38: * EECS Department
39: * University of California, Berkeley
40: * Berkeley, California 94704
41: *
42: * Office: (415) 642-4948
43: * Home: (415) 524-4510
44: ****/
45:
46: /* features to be fixed up ...
47:
48: *** Print estimate of total space needed for parser
49: *** Either list inputs on y.output, or list empty prdn's in states
50: *** Mention nonterms not used (or, rules. not reduced) as nonfatal error
51: *** Output states where conflicts were found by default on y.output
52: *** Engage in newspeak: production=>grammar rules, term=>token, etc.
53: *** handle # define, #ifdef, etc., in yacc actions, %{ %}
54: */
55:
56: /* new features to be added
57:
58: *** reductions by single productions ( by request )
59: *** follow sets for start symbol
60: *** option to only do slr(1)
61: *** easily changed array names on output
62: *** allocate core, rather than predefined
63: *** input controlled by a grammar
64: *** support multiple choices for conflicts
65: *** better conflict diagnostics
66: */
67:
68: extern char *symnam();
69:
70: main(argc,argv) int argc; char *argv[]; {
71: auto int n;
72:
73: whereami();
74: setup(argc,argv); /* initialize and read productions */
75: tbitset = (nterms+16)/16;
76: cpres(); /* make table of which productions yield a given nonterminal */
77: cempty(); /* make a table of which nonterminals can match the empty string */
78: cpfir(); /* make a table of e free first lists */
79: stagen(); /* generate the states */
80: output(); /* write the states and the tables */
81: go2out();
82: summary();
83: windup();
84: }
85:
86: whereami(){ /* sets the variable machine to UNIX, GCOS, or IBM */
87:
88: int i;
89:
90: i = 1;
91: i = i << 30;
92: if( i == 0 ) {
93: machine = UNIX;
94: return;
95: }
96: i = i << 4;
97: if( i == 0 ){
98: machine = IBM;
99: return;
100: }
101: machine = GCOS;
102: }
103:
104: windup(){
105: /* no errors, do the optimization if appropriate */
106: char *cp;
107: int i;
108:
109: if( !oflag ) cexit(0);
110:
111: switch( machine ){
112:
113: case GCOS:
114: if( rflag ){
115: if( foutput<0 ) system( "./yopt -r" );
116: else system( "./yopt -rv" );
117: }
118: else {
119: if( foutput<0 ) system( "./yopt" );
120: else system( "./yopt -v" );
121: }
122: cexit(0); /* terminate */
123:
124: case UNIX:
125: cp = "/usr/nlib/yaccopt";
126: if( rflag ) execl( cp, cp, (foutput<0)?"-r":"-rv", 0 );
127: else if( foutput<0 ) execl( cp, cp, 0 );
128: else execl( cp, cp, "-v", 0 );
129: error( "optimization execl call fails" );
130:
131: case IBM:
132: if( rflag ){
133: if( foutput<0 ) system( "MH2019.yaccopt -r" );
134: else system( "MH2019.yaccopt -rv" );
135: }
136: else {
137: if( foutput<0 ) system( "MH2019.yaccopt" );
138: else system( "MH2019.yaccopt -v" );
139: }
140: cexit(0);
141:
142: }
143:
144: }
145:
146: settty()
147: /* sets the output file to y.output */
148: {
149: cflush( foutput ); /* a bit of a cheat */
150: cout = foutput;
151: }
152:
153: settab(){ /* sets the output file to y.tab.c */
154:
155: cflush( ftable );
156: cout = ftable;
157: }
158:
159: char *chcopy( p, q ) char *p, *q; {
160: /* copies string q into p, returning next free char ptr */
161: while( *p = *q++ ) ++p;
162: return( p );
163: }
164:
165: char *writem(pp) struct item *pp; { /* creates output string for item pointed to by pp */
166: int i,*p;
167: static char sarr[100];
168: char *q;
169:
170: for( p=pp->pitem; *p>0 ; ++p ) ;
171: p = prdptr[-*p];
172: q = chcopy( sarr, nontrst[*p-NTBASE].name );
173: q = chcopy( q, " : " );
174:
175: for(;;){
176: *q++ = ++p==(pp->pitem) ? '_' : ' ';
177: if((i = *p) <= 0) break;
178: q = chcopy( q, symnam(i) );
179: }
180:
181: *q = '\0' ;
182: return( sarr );
183: }
184:
185: char *symnam(i){ /* return a pointer to the name of symbol i */
186: char *cp;
187:
188: cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : trmset[i].name ;
189: if( *cp == ' ' ) ++cp;
190: return( cp );
191: }
192:
193: summary(){ /* output the summary on the tty */
194:
195: int i, s;
196: struct item *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", (int *)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 ) struct looksets *pp;{
312: int j;
313: pp = (struct looksets *)pp->lset;
314: if( pp == 0 ) fprintf( cout , "\tNULL");
315: else {
316: fprintf( cout , " { " );
317: for( j=1; j<=nterms; ++j ){
318: if( (((int *)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.