xref: /csrg-svn/old/yacc/y1.c (revision 10932)
1*10932Srrh #ifndef lint
2*10932Srrh static char sccsid[] = "@(#)y1.c	4.1	(Berkeley)	02/11/83";
3*10932Srrh #endif not lint
4*10932Srrh 
5*10932Srrh # include "dextern"
6*10932Srrh 
7*10932Srrh 	/* variables used locally */
8*10932Srrh 
9*10932Srrh 	/* lookahead computations */
10*10932Srrh 
11*10932Srrh int tbitset;  /* size of lookahead sets */
12*10932Srrh struct looksets lkst [ LSETSIZE ];
13*10932Srrh int nlset = 0; /* next lookahead set index */
14*10932Srrh int nolook = 0; /* flag to suppress lookahead computations */
15*10932Srrh struct looksets clset;  /* temporary storage for lookahead computations */
16*10932Srrh 
17*10932Srrh 	/* working set computations */
18*10932Srrh 
19*10932Srrh struct wset wsets[ WSETSIZE ];
20*10932Srrh struct wset *cwp;
21*10932Srrh 
22*10932Srrh 	/* state information */
23*10932Srrh 
24*10932Srrh int nstate = 0;		/* number of states */
25*10932Srrh struct item *pstate[NSTATES+2];	/* pointers to the descriptions of the states */
26*10932Srrh int tystate[NSTATES];	/* contains type information about the states */
27*10932Srrh int indgo[NSTATES];		/* index to the stored goto table */
28*10932Srrh int tstates[ NTERMS ]; /* states generated by terminal gotos */
29*10932Srrh int ntstates[ NNONTERM ]; /* states generated by nonterminal gotos */
30*10932Srrh int mstates[ NSTATES ]; /* chain of overflows of term/nonterm generation lists  */
31*10932Srrh 
32*10932Srrh 	/* storage for the actions in the parser */
33*10932Srrh 
34*10932Srrh int amem[ACTSIZE];	/* action table storage */
35*10932Srrh int *memp = amem;	/* next free action table position */
36*10932Srrh 
37*10932Srrh 	/* other storage areas */
38*10932Srrh 
39*10932Srrh int temp1[TEMPSIZE]; /* temporary storage, indexed by terms + ntokens or states */
40*10932Srrh int lineno= 1; /* current input line number */
41*10932Srrh int fatfl = 1;  	/* if on, error is fatal */
42*10932Srrh int nerrors = 0;	/* number of errors */
43*10932Srrh 
44*10932Srrh 	/* storage for information about the nonterminals */
45*10932Srrh 
46*10932Srrh int **pres[NNONTERM+2];  /* vector of pointers to productions yielding each nonterminal */
47*10932Srrh struct looksets *pfirst[NNONTERM+2];  /* vector of pointers to first sets for each nonterminal */
48*10932Srrh int pempty[NNONTERM+1];  /* vector of nonterminals nontrivially deriving e */
49*10932Srrh 
50*10932Srrh main(argc,argv) int argc; char *argv[]; {
51*10932Srrh 
52*10932Srrh 	setup(argc,argv); /* initialize and read productions */
53*10932Srrh 	tbitset = NWORDS(ntokens);
54*10932Srrh 	cpres(); /* make table of which productions yield a given nonterminal */
55*10932Srrh 	cempty(); /* make a table of which nonterminals can match the empty string */
56*10932Srrh 	cpfir(); /* make a table of firsts of nonterminals */
57*10932Srrh 	stagen(); /* generate the states */
58*10932Srrh 	output();  /* write the states and the tables */
59*10932Srrh 	go2out();
60*10932Srrh 	hideprod();
61*10932Srrh 	summary();
62*10932Srrh 	callopt();
63*10932Srrh 	others();
64*10932Srrh 	exit(0);
65*10932Srrh 	}
66*10932Srrh 
67*10932Srrh others(){ /* put out other arrays, copy the parsers */
68*10932Srrh 	register c, i, j;
69*10932Srrh 
70*10932Srrh 	finput = fopen( PARSER, "r" );
71*10932Srrh 	if( finput == NULL ) error( "cannot find parser %s", PARSER );
72*10932Srrh 
73*10932Srrh 	warray( "yyr1", levprd, nprod );
74*10932Srrh 
75*10932Srrh 	aryfil( temp1, nprod, 0 );
76*10932Srrh 	PLOOP(1,i)temp1[i] = prdptr[i+1]-prdptr[i]-2;
77*10932Srrh 	warray( "yyr2", temp1, nprod );
78*10932Srrh 
79*10932Srrh 	aryfil( temp1, nstate, -1000 );
80*10932Srrh 	TLOOP(i){
81*10932Srrh 		for( j=tstates[i]; j!=0; j=mstates[j] ){
82*10932Srrh 			temp1[j] = tokset[i].value;
83*10932Srrh 			}
84*10932Srrh 		}
85*10932Srrh 	NTLOOP(i){
86*10932Srrh 		for( j=ntstates[i]; j!=0; j=mstates[j] ){
87*10932Srrh 			temp1[j] = -i;
88*10932Srrh 			}
89*10932Srrh 		}
90*10932Srrh 	warray( "yychk", temp1, nstate );
91*10932Srrh 
92*10932Srrh 	warray( "yydef", defact, nstate );
93*10932Srrh 
94*10932Srrh 	/* copy parser text */
95*10932Srrh 
96*10932Srrh 	while( (c=getc(finput) ) != EOF ){
97*10932Srrh 		if( c == '$' ){
98*10932Srrh 			if( (c=getc(finput)) != 'A' ) putc( '$', ftable );
99*10932Srrh 			else { /* copy actions */
100*10932Srrh 				faction = fopen( ACTNAME, "r" );
101*10932Srrh 				if( faction == NULL ) error( "cannot reopen action tempfile" );
102*10932Srrh 				while( (c=getc(faction) ) != EOF ) putc( c, ftable );
103*10932Srrh 				fclose(faction);
104*10932Srrh 				ZAPFILE(ACTNAME);
105*10932Srrh 				c = getc(finput);
106*10932Srrh 				}
107*10932Srrh 			}
108*10932Srrh 		putc( c, ftable );
109*10932Srrh 		}
110*10932Srrh 
111*10932Srrh 	fclose( ftable );
112*10932Srrh 	}
113*10932Srrh 
114*10932Srrh char *chcopy( p, q )  char *p, *q; {
115*10932Srrh 	/* copies string q into p, returning next free char ptr */
116*10932Srrh 	while( *p = *q++ ) ++p;
117*10932Srrh 	return( p );
118*10932Srrh 	}
119*10932Srrh 
120*10932Srrh # define ISIZE 400
121*10932Srrh char *writem(pp) int *pp; { /* creates output string for item pointed to by pp */
122*10932Srrh 	int i,*p;
123*10932Srrh 	static char sarr[ISIZE];
124*10932Srrh 	char *q;
125*10932Srrh 
126*10932Srrh 	for( p=pp; *p>0 ; ++p ) ;
127*10932Srrh 	p = prdptr[-*p];
128*10932Srrh 	q = chcopy( sarr, nontrst[*p-NTBASE].name );
129*10932Srrh 	q = chcopy( q, " : " );
130*10932Srrh 
131*10932Srrh 	for(;;){
132*10932Srrh 		*q++ = ++p==pp ? '_' : ' ';
133*10932Srrh 		*q = '\0';
134*10932Srrh 		if((i = *p) <= 0) break;
135*10932Srrh 		q = chcopy( q, symnam(i) );
136*10932Srrh 		if( q> &sarr[ISIZE-30] ) error( "item too big" );
137*10932Srrh 		}
138*10932Srrh 
139*10932Srrh 	if( (i = *pp) < 0 ){ /* an item calling for a reduction */
140*10932Srrh 		q = chcopy( q, "    (" );
141*10932Srrh 		sprintf( q, "%d)", -i );
142*10932Srrh 		}
143*10932Srrh 
144*10932Srrh 	return( sarr );
145*10932Srrh 	}
146*10932Srrh 
147*10932Srrh char *symnam(i){ /* return a pointer to the name of symbol i */
148*10932Srrh 	char *cp;
149*10932Srrh 
150*10932Srrh 	cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : tokset[i].name ;
151*10932Srrh 	if( *cp == ' ' ) ++cp;
152*10932Srrh 	return( cp );
153*10932Srrh 	}
154*10932Srrh 
155*10932Srrh struct wset *zzcwp = wsets;
156*10932Srrh int zzgoent = 0;
157*10932Srrh int zzgobest = 0;
158*10932Srrh int zzacent = 0;
159*10932Srrh int zzexcp = 0;
160*10932Srrh int zzclose = 0;
161*10932Srrh int zzsrconf = 0;
162*10932Srrh int * zzmemsz = mem0;
163*10932Srrh int zzrrconf = 0;
164*10932Srrh 
165*10932Srrh summary(){ /* output the summary on the tty */
166*10932Srrh 
167*10932Srrh 	if( foutput!=NULL ){
168*10932Srrh 		fprintf( foutput, "\n%d/%d terminals, %d/%d nonterminals\n", ntokens, NTERMS,
169*10932Srrh 			    nnonter, NNONTERM );
170*10932Srrh 		fprintf( foutput, "%d/%d grammar rules, %d/%d states\n", nprod, NPROD, nstate, NSTATES );
171*10932Srrh 		fprintf( foutput, "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf );
172*10932Srrh 		fprintf( foutput, "%d/%d working sets used\n", zzcwp-wsets,  WSETSIZE );
173*10932Srrh 		fprintf( foutput, "memory: states,etc. %d/%d, parser %d/%d\n", zzmemsz-mem0, MEMSIZE,
174*10932Srrh 			    memp-amem, ACTSIZE );
175*10932Srrh 		fprintf( foutput, "%d/%d distinct lookahead sets\n", nlset, LSETSIZE );
176*10932Srrh 		fprintf( foutput, "%d extra closures\n", zzclose - 2*nstate );
177*10932Srrh 		fprintf( foutput, "%d shift entries, %d exceptions\n", zzacent, zzexcp );
178*10932Srrh 		fprintf( foutput, "%d goto entries\n", zzgoent );
179*10932Srrh 		fprintf( foutput, "%d entries saved by goto default\n", zzgobest );
180*10932Srrh 		}
181*10932Srrh 	if( zzsrconf!=0 || zzrrconf!=0 ){
182*10932Srrh 		  fprintf( stdout,"\nconflicts: ");
183*10932Srrh 		  if( zzsrconf )fprintf( stdout, "%d shift/reduce" , zzsrconf );
184*10932Srrh 		  if( zzsrconf && zzrrconf )fprintf( stdout, ", " );
185*10932Srrh 		  if( zzrrconf )fprintf( stdout, "%d reduce/reduce" , zzrrconf );
186*10932Srrh 		  fprintf( stdout, "\n" );
187*10932Srrh 		  }
188*10932Srrh 
189*10932Srrh 	fclose( ftemp );
190*10932Srrh 	if( fdefine != NULL ) fclose( fdefine );
191*10932Srrh 	}
192*10932Srrh 
193*10932Srrh /* VARARGS1 */
194*10932Srrh error(s,a1) char *s; { /* write out error comment */
195*10932Srrh 
196*10932Srrh 	++nerrors;
197*10932Srrh 	fprintf( stderr, "\n fatal error: ");
198*10932Srrh 	fprintf( stderr, s,a1);
199*10932Srrh 	fprintf( stderr, ", line %d\n", lineno );
200*10932Srrh 	if( !fatfl ) return;
201*10932Srrh 	summary();
202*10932Srrh 	exit(1);
203*10932Srrh 	}
204*10932Srrh 
205*10932Srrh aryfil( v, n, c ) int *v,n,c; { /* set elements 0 through n-1 to c */
206*10932Srrh 	int i;
207*10932Srrh 	for( i=0; i<n; ++i ) v[i] = c;
208*10932Srrh 	}
209*10932Srrh 
210*10932Srrh setunion( a, b ) register *a, *b; {
211*10932Srrh 	/* set a to the union of a and b */
212*10932Srrh 	/* return 1 if b is not a subset of a, 0 otherwise */
213*10932Srrh 	register i, x, sub;
214*10932Srrh 
215*10932Srrh 	sub = 0;
216*10932Srrh 	SETLOOP(i){
217*10932Srrh 		*a = (x = *a)|*b++;
218*10932Srrh 		if( *a++ != x ) sub = 1;
219*10932Srrh 		}
220*10932Srrh 	return( sub );
221*10932Srrh 	}
222*10932Srrh 
223*10932Srrh prlook( p ) struct looksets *p;{
224*10932Srrh 	register j, *pp;
225*10932Srrh 	pp = p->lset;
226*10932Srrh 	if( pp == 0 ) fprintf( foutput, "\tNULL");
227*10932Srrh 	else {
228*10932Srrh 		fprintf( foutput, " { " );
229*10932Srrh 		TLOOP(j) {
230*10932Srrh 			if( BIT(pp,j) ) fprintf( foutput,  "%s ", symnam(j) );
231*10932Srrh 			}
232*10932Srrh 		fprintf( foutput,  "}" );
233*10932Srrh 		}
234*10932Srrh 	}
235*10932Srrh 
236*10932Srrh cpres(){ /* compute an array with the beginnings of  productions yielding given nonterminals
237*10932Srrh 	The array pres points to these lists */
238*10932Srrh 	/* the array pyield has the lists: the total size is only NPROD+1 */
239*10932Srrh 	register **pmem;
240*10932Srrh 	register c, j, i;
241*10932Srrh 	static int * pyield[NPROD];
242*10932Srrh 
243*10932Srrh 	pmem = pyield;
244*10932Srrh 
245*10932Srrh 	NTLOOP(i){
246*10932Srrh 		c = i+NTBASE;
247*10932Srrh 		pres[i] = pmem;
248*10932Srrh 		fatfl = 0;  /* make undefined  symbols  nonfatal */
249*10932Srrh 		PLOOP(0,j){
250*10932Srrh 			if (*prdptr[j] == c) *pmem++ =  prdptr[j]+1;
251*10932Srrh 			}
252*10932Srrh 		if(pres[i] == pmem){
253*10932Srrh 			error("nonterminal %s not defined!", nontrst[i].name);
254*10932Srrh 			}
255*10932Srrh 		}
256*10932Srrh 	pres[i] = pmem;
257*10932Srrh 	fatfl = 1;
258*10932Srrh 	if( nerrors ){
259*10932Srrh 		summary();
260*10932Srrh 		exit(1);
261*10932Srrh 		}
262*10932Srrh 	if( pmem != &pyield[nprod] ) error( "internal Yacc error: pyield %d", pmem-&pyield[nprod] );
263*10932Srrh 	}
264*10932Srrh 
265*10932Srrh int indebug = 0;
266*10932Srrh cpfir() {
267*10932Srrh 	/* compute an array with the first of nonterminals */
268*10932Srrh 	register *p, **s, i, **t, ch, changes;
269*10932Srrh 
270*10932Srrh 	zzcwp = &wsets[nnonter];
271*10932Srrh 	NTLOOP(i){
272*10932Srrh 		aryfil( wsets[i].ws.lset, tbitset, 0 );
273*10932Srrh 		t = pres[i+1];
274*10932Srrh 		for( s=pres[i]; s<t; ++s ){ /* initially fill the sets */
275*10932Srrh 			for( p = *s; (ch = *p) > 0 ; ++p ) {
276*10932Srrh 				if( ch < NTBASE ) {
277*10932Srrh 					SETBIT( wsets[i].ws.lset, ch );
278*10932Srrh 					break;
279*10932Srrh 					}
280*10932Srrh 				else if( !pempty[ch-NTBASE] ) break;
281*10932Srrh 				}
282*10932Srrh 			}
283*10932Srrh 		}
284*10932Srrh 
285*10932Srrh 	/* now, reflect transitivity */
286*10932Srrh 
287*10932Srrh 	changes = 1;
288*10932Srrh 	while( changes ){
289*10932Srrh 		changes = 0;
290*10932Srrh 		NTLOOP(i){
291*10932Srrh 			t = pres[i+1];
292*10932Srrh 			for( s=pres[i]; s<t; ++s ){
293*10932Srrh 				for( p = *s; ( ch = (*p-NTBASE) ) >= 0; ++p ) {
294*10932Srrh 					changes |= setunion( wsets[i].ws.lset, wsets[ch].ws.lset );
295*10932Srrh 					if( !pempty[ch] ) break;
296*10932Srrh 					}
297*10932Srrh 				}
298*10932Srrh 			}
299*10932Srrh 		}
300*10932Srrh 
301*10932Srrh 	NTLOOP(i) pfirst[i] = flset( &wsets[i].ws );
302*10932Srrh 	if( !indebug ) return;
303*10932Srrh 	if( (foutput!=NULL) ){
304*10932Srrh 		NTLOOP(i) {
305*10932Srrh 			fprintf( foutput,  "\n%s: ", nontrst[i].name );
306*10932Srrh 			prlook( pfirst[i] );
307*10932Srrh 			fprintf( foutput,  " %d\n", pempty[i] );
308*10932Srrh 			}
309*10932Srrh 		}
310*10932Srrh 	}
311*10932Srrh 
312*10932Srrh state(c){ /* sorts last state,and sees if it equals earlier ones. returns state number */
313*10932Srrh 	int size1,size2;
314*10932Srrh 	register i;
315*10932Srrh 	struct item *p1, *p2, *k, *l, *q1, *q2;
316*10932Srrh 	p1 = pstate[nstate];
317*10932Srrh 	p2 = pstate[nstate+1];
318*10932Srrh 	if(p1==p2) return(0); /* null state */
319*10932Srrh 	/* sort the items */
320*10932Srrh 	for(k=p2-1;k>p1;k--) {	/* make k the biggest */
321*10932Srrh 		for(l=k-1;l>=p1;--l)if( l->pitem > k->pitem ){
322*10932Srrh 			int *s;
323*10932Srrh 			struct looksets *ss;
324*10932Srrh 			s = k->pitem;
325*10932Srrh 			k->pitem = l->pitem;
326*10932Srrh 			l->pitem = s;
327*10932Srrh 			ss = k->look;
328*10932Srrh 			k->look = l->look;
329*10932Srrh 			l->look = ss;
330*10932Srrh 			}
331*10932Srrh 		}
332*10932Srrh 	size1 = p2 - p1; /* size of state */
333*10932Srrh 
334*10932Srrh 	for( i= (c>=NTBASE)?ntstates[c-NTBASE]:tstates[c]; i != 0; i = mstates[i] ) {
335*10932Srrh 		/* get ith state */
336*10932Srrh 		q1 = pstate[i];
337*10932Srrh 		q2 = pstate[i+1];
338*10932Srrh 		size2 = q2 - q1;
339*10932Srrh 		if (size1 != size2) continue;
340*10932Srrh 		k=p1;
341*10932Srrh 		for(l=q1;l<q2;l++) {
342*10932Srrh 			if( l->pitem != k->pitem ) break;
343*10932Srrh 			++k;
344*10932Srrh 			}
345*10932Srrh 		if (l != q2) continue;
346*10932Srrh 		/* found it */
347*10932Srrh 		pstate[nstate+1] = pstate[nstate]; /* delete last state */
348*10932Srrh 		/* fix up lookaheads */
349*10932Srrh 		if( nolook ) return(i);
350*10932Srrh 		for( l=q1,k=p1; l<q2; ++l,++k ){
351*10932Srrh 			int s;
352*10932Srrh 			SETLOOP(s) clset.lset[s] = l->look->lset[s];
353*10932Srrh 			if( setunion( clset.lset, k->look->lset ) ) {
354*10932Srrh 				tystate[i] = MUSTDO;
355*10932Srrh 				/* register the new set */
356*10932Srrh 				l->look = flset( &clset );
357*10932Srrh 				}
358*10932Srrh 			}
359*10932Srrh 		return (i);
360*10932Srrh 		}
361*10932Srrh 	/* state is new */
362*10932Srrh 	if( nolook ) error( "yacc state/nolook error" );
363*10932Srrh 	pstate[nstate+2] = p2;
364*10932Srrh 	if(nstate+1 >= NSTATES) error("too many states" );
365*10932Srrh 	if( c >= NTBASE ){
366*10932Srrh 		mstates[ nstate ] = ntstates[ c-NTBASE ];
367*10932Srrh 		ntstates[ c-NTBASE ] = nstate;
368*10932Srrh 		}
369*10932Srrh 	else {
370*10932Srrh 		mstates[ nstate ] = tstates[ c ];
371*10932Srrh 		tstates[ c ] = nstate;
372*10932Srrh 		}
373*10932Srrh 	tystate[nstate]=MUSTDO;
374*10932Srrh 	return(nstate++);
375*10932Srrh 	}
376*10932Srrh 
377*10932Srrh int pidebug = 0; /* debugging flag for putitem */
378*10932Srrh putitem( ptr, lptr )  int *ptr;  struct looksets *lptr; {
379*10932Srrh 	register struct item *j;
380*10932Srrh 
381*10932Srrh 	if( pidebug && (foutput!=NULL) ) {
382*10932Srrh 		fprintf( foutput, "putitem(%s), state %d\n", writem(ptr), nstate );
383*10932Srrh 		}
384*10932Srrh 	j = pstate[nstate+1];
385*10932Srrh 	j->pitem = ptr;
386*10932Srrh 	if( !nolook ) j->look = flset( lptr );
387*10932Srrh 	pstate[nstate+1] = ++j;
388*10932Srrh 	if( (int *)j > zzmemsz ){
389*10932Srrh 		zzmemsz = (int *)j;
390*10932Srrh 		if( zzmemsz >=  &mem0[MEMSIZE] ) error( "out of state space" );
391*10932Srrh 		}
392*10932Srrh 	}
393*10932Srrh 
394*10932Srrh cempty(){ /* mark nonterminals which derive the empty string */
395*10932Srrh 	/* also, look for nonterminals which don't derive any token strings */
396*10932Srrh 
397*10932Srrh # define EMPTY 1
398*10932Srrh # define WHOKNOWS 0
399*10932Srrh # define OK 1
400*10932Srrh 
401*10932Srrh 	register i, *p;
402*10932Srrh 
403*10932Srrh 	/* first, use the array pempty to detect productions that can never be reduced */
404*10932Srrh 	/* set pempty to WHONOWS */
405*10932Srrh 	aryfil( pempty, nnonter+1, WHOKNOWS );
406*10932Srrh 
407*10932Srrh 	/* now, look at productions, marking nonterminals which derive something */
408*10932Srrh 
409*10932Srrh 	more:
410*10932Srrh 	PLOOP(0,i){
411*10932Srrh 		if( pempty[ *prdptr[i] - NTBASE ] ) continue;
412*10932Srrh 		for( p=prdptr[i]+1; *p>=0; ++p ){
413*10932Srrh 			if( *p>=NTBASE && pempty[ *p-NTBASE ] == WHOKNOWS ) break;
414*10932Srrh 			}
415*10932Srrh 		if( *p < 0 ){ /* production can be derived */
416*10932Srrh 			pempty[ *prdptr[i]-NTBASE ] = OK;
417*10932Srrh 			goto more;
418*10932Srrh 			}
419*10932Srrh 		}
420*10932Srrh 
421*10932Srrh 	/* now, look at the nonterminals, to see if they are all OK */
422*10932Srrh 
423*10932Srrh 	NTLOOP(i){
424*10932Srrh 		/* the added production rises or falls as the start symbol ... */
425*10932Srrh 		if( i == 0 ) continue;
426*10932Srrh 		if( pempty[ i ] != OK ) {
427*10932Srrh 			fatfl = 0;
428*10932Srrh 			error( "nonterminal %s never derives any token string", nontrst[i].name );
429*10932Srrh 			}
430*10932Srrh 		}
431*10932Srrh 
432*10932Srrh 	if( nerrors ){
433*10932Srrh 		summary();
434*10932Srrh 		exit(1);
435*10932Srrh 		}
436*10932Srrh 
437*10932Srrh 	/* now, compute the pempty array, to see which nonterminals derive the empty string */
438*10932Srrh 
439*10932Srrh 	/* set pempty to WHOKNOWS */
440*10932Srrh 
441*10932Srrh 	aryfil( pempty, nnonter+1, WHOKNOWS );
442*10932Srrh 
443*10932Srrh 	/* loop as long as we keep finding empty nonterminals */
444*10932Srrh 
445*10932Srrh again:
446*10932Srrh 	PLOOP(1,i){
447*10932Srrh 		if( pempty[ *prdptr[i]-NTBASE ]==WHOKNOWS ){ /* not known to be empty */
448*10932Srrh 			for( p=prdptr[i]+1; *p>=NTBASE && pempty[*p-NTBASE]==EMPTY ; ++p ) ;
449*10932Srrh 			if( *p < 0 ){ /* we have a nontrivially empty nonterminal */
450*10932Srrh 				pempty[*prdptr[i]-NTBASE] = EMPTY;
451*10932Srrh 				goto again; /* got one ... try for another */
452*10932Srrh 				}
453*10932Srrh 			}
454*10932Srrh 		}
455*10932Srrh 
456*10932Srrh 	}
457*10932Srrh 
458*10932Srrh int gsdebug = 0;
459*10932Srrh stagen(){ /* generate the states */
460*10932Srrh 
461*10932Srrh 	int i, j;
462*10932Srrh 	register c;
463*10932Srrh 	register struct wset *p, *q;
464*10932Srrh 
465*10932Srrh 	/* initialize */
466*10932Srrh 
467*10932Srrh 	nstate = 0;
468*10932Srrh 	/* THIS IS FUNNY from the standpoint of portability */
469*10932Srrh 	/* it represents the magic moment when the mem0 array, which has
470*10932Srrh 	/* been holding the productions, starts to hold item pointers, of a
471*10932Srrh 	/* different type... */
472*10932Srrh 	/* someday, alloc should be used to allocate all this stuff... for now, we
473*10932Srrh 	/* accept that if pointers don't fit in integers, there is a problem... */
474*10932Srrh 
475*10932Srrh 	pstate[0] = pstate[1] = (struct item *)mem;
476*10932Srrh 	aryfil( clset.lset, tbitset, 0 );
477*10932Srrh 	putitem( prdptr[0]+1, &clset );
478*10932Srrh 	tystate[0] = MUSTDO;
479*10932Srrh 	nstate = 1;
480*10932Srrh 	pstate[2] = pstate[1];
481*10932Srrh 
482*10932Srrh 	aryfil( amem, ACTSIZE, 0 );
483*10932Srrh 
484*10932Srrh 	/* now, the main state generation loop */
485*10932Srrh 
486*10932Srrh 	more:
487*10932Srrh 	SLOOP(i){
488*10932Srrh 		if( tystate[i] != MUSTDO ) continue;
489*10932Srrh 		tystate[i] = DONE;
490*10932Srrh 		aryfil( temp1, nnonter+1, 0 );
491*10932Srrh 		/* take state i, close it, and do gotos */
492*10932Srrh 		closure(i);
493*10932Srrh 		WSLOOP(wsets,p){ /* generate goto's */
494*10932Srrh 			if( p->flag ) continue;
495*10932Srrh 			p->flag = 1;
496*10932Srrh 			c = *(p->pitem);
497*10932Srrh 			if( c <= 1 ) {
498*10932Srrh 				if( pstate[i+1]-pstate[i] <= p-wsets ) tystate[i] = MUSTLOOKAHEAD;
499*10932Srrh 				continue;
500*10932Srrh 				}
501*10932Srrh 			/* do a goto on c */
502*10932Srrh 			WSLOOP(p,q){
503*10932Srrh 				if( c == *(q->pitem) ){ /* this item contributes to the goto */
504*10932Srrh 					putitem( q->pitem + 1, &q->ws );
505*10932Srrh 					q->flag = 1;
506*10932Srrh 					}
507*10932Srrh 				}
508*10932Srrh 			if( c < NTBASE ) {
509*10932Srrh 				state(c);  /* register new state */
510*10932Srrh 				}
511*10932Srrh 			else {
512*10932Srrh 				temp1[c-NTBASE] = state(c);
513*10932Srrh 				}
514*10932Srrh 			}
515*10932Srrh 		if( gsdebug && (foutput!=NULL) ){
516*10932Srrh 			fprintf( foutput,  "%d: ", i );
517*10932Srrh 			NTLOOP(j) {
518*10932Srrh 				if( temp1[j] ) fprintf( foutput,  "%s %d, ", nontrst[j].name, temp1[j] );
519*10932Srrh 				}
520*10932Srrh 			fprintf( foutput, "\n");
521*10932Srrh 			}
522*10932Srrh 		indgo[i] = apack( &temp1[1], nnonter-1 ) - 1;
523*10932Srrh 		goto more; /* we have done one goto; do some more */
524*10932Srrh 		}
525*10932Srrh 	/* no more to do... stop */
526*10932Srrh 	}
527*10932Srrh 
528*10932Srrh int cldebug = 0; /* debugging flag for closure */
529*10932Srrh closure(i){ /* generate the closure of state i */
530*10932Srrh 
531*10932Srrh 	int c, ch, work, k;
532*10932Srrh 	register struct wset *u, *v;
533*10932Srrh 	int *pi;
534*10932Srrh 	int **s, **t;
535*10932Srrh 	struct item *q;
536*10932Srrh 	register struct item *p;
537*10932Srrh 
538*10932Srrh 	++zzclose;
539*10932Srrh 
540*10932Srrh 	/* first, copy kernel of state i to wsets */
541*10932Srrh 
542*10932Srrh 	cwp = wsets;
543*10932Srrh 	ITMLOOP(i,p,q){
544*10932Srrh 		cwp->pitem = p->pitem;
545*10932Srrh 		cwp->flag = 1;    /* this item must get closed */
546*10932Srrh 		SETLOOP(k) cwp->ws.lset[k] = p->look->lset[k];
547*10932Srrh 		WSBUMP(cwp);
548*10932Srrh 		}
549*10932Srrh 
550*10932Srrh 	/* now, go through the loop, closing each item */
551*10932Srrh 
552*10932Srrh 	work = 1;
553*10932Srrh 	while( work ){
554*10932Srrh 		work = 0;
555*10932Srrh 		WSLOOP(wsets,u){
556*10932Srrh 
557*10932Srrh 			if( u->flag == 0 ) continue;
558*10932Srrh 			c = *(u->pitem);  /* dot is before c */
559*10932Srrh 
560*10932Srrh 			if( c < NTBASE ){
561*10932Srrh 				u->flag = 0;
562*10932Srrh 				continue;  /* only interesting case is where . is before nonterminal */
563*10932Srrh 				}
564*10932Srrh 
565*10932Srrh 			/* compute the lookahead */
566*10932Srrh 			aryfil( clset.lset, tbitset, 0 );
567*10932Srrh 
568*10932Srrh 			/* find items involving c */
569*10932Srrh 
570*10932Srrh 			WSLOOP(u,v){
571*10932Srrh 				if( v->flag == 1 && *(pi=v->pitem) == c ){
572*10932Srrh 					v->flag = 0;
573*10932Srrh 					if( nolook ) continue;
574*10932Srrh 					while( (ch= *++pi)>0 ){
575*10932Srrh 						if( ch < NTBASE ){ /* terminal symbol */
576*10932Srrh 							SETBIT( clset.lset, ch );
577*10932Srrh 							break;
578*10932Srrh 							}
579*10932Srrh 						/* nonterminal symbol */
580*10932Srrh 						setunion( clset.lset, pfirst[ch-NTBASE]->lset );
581*10932Srrh 						if( !pempty[ch-NTBASE] ) break;
582*10932Srrh 						}
583*10932Srrh 					if( ch<=0 ) setunion( clset.lset, v->ws.lset );
584*10932Srrh 					}
585*10932Srrh 				}
586*10932Srrh 
587*10932Srrh 			/*  now loop over productions derived from c */
588*10932Srrh 
589*10932Srrh 			c -= NTBASE; /* c is now nonterminal number */
590*10932Srrh 
591*10932Srrh 			t = pres[c+1];
592*10932Srrh 			for( s=pres[c]; s<t; ++s ){
593*10932Srrh 				/* put these items into the closure */
594*10932Srrh 				WSLOOP(wsets,v){ /* is the item there */
595*10932Srrh 					if( v->pitem == *s ){ /* yes, it is there */
596*10932Srrh 						if( nolook ) goto nexts;
597*10932Srrh 						if( setunion( v->ws.lset, clset.lset ) ) v->flag = work = 1;
598*10932Srrh 						goto nexts;
599*10932Srrh 						}
600*10932Srrh 					}
601*10932Srrh 
602*10932Srrh 				/*  not there; make a new entry */
603*10932Srrh 				if( cwp-wsets+1 >= WSETSIZE ) error( "working set overflow" );
604*10932Srrh 				cwp->pitem = *s;
605*10932Srrh 				cwp->flag = 1;
606*10932Srrh 				if( !nolook ){
607*10932Srrh 					work = 1;
608*10932Srrh 					SETLOOP(k) cwp->ws.lset[k] = clset.lset[k];
609*10932Srrh 					}
610*10932Srrh 				WSBUMP(cwp);
611*10932Srrh 
612*10932Srrh 			nexts: ;
613*10932Srrh 				}
614*10932Srrh 
615*10932Srrh 			}
616*10932Srrh 		}
617*10932Srrh 
618*10932Srrh 	/* have computed closure; flags are reset; return */
619*10932Srrh 
620*10932Srrh 	if( cwp > zzcwp ) zzcwp = cwp;
621*10932Srrh 	if( cldebug && (foutput!=NULL) ){
622*10932Srrh 		fprintf( foutput, "\nState %d, nolook = %d\n", i, nolook );
623*10932Srrh 		WSLOOP(wsets,u){
624*10932Srrh 			if( u->flag ) fprintf( foutput, "flag set!\n");
625*10932Srrh 			u->flag = 0;
626*10932Srrh 			fprintf( foutput, "\t%s", writem(u->pitem));
627*10932Srrh 			prlook( &u->ws );
628*10932Srrh 			fprintf( foutput,  "\n" );
629*10932Srrh 			}
630*10932Srrh 		}
631*10932Srrh 	}
632*10932Srrh 
633*10932Srrh struct looksets *flset( p )   struct looksets *p; {
634*10932Srrh 	/* decide if the lookahead set pointed to by p is known */
635*10932Srrh 	/* return pointer to a perminent location for the set */
636*10932Srrh 
637*10932Srrh 	register struct looksets *q;
638*10932Srrh 	int j, *w;
639*10932Srrh 	register *u, *v;
640*10932Srrh 
641*10932Srrh 	for( q = &lkst[nlset]; q-- > lkst; ){
642*10932Srrh 		u = p->lset;
643*10932Srrh 		v = q->lset;
644*10932Srrh 		w = & v[tbitset];
645*10932Srrh 		while( v<w) if( *u++ != *v++ ) goto more;
646*10932Srrh 		/* we have matched */
647*10932Srrh 		return( q );
648*10932Srrh 		more: ;
649*10932Srrh 		}
650*10932Srrh 	/* add a new one */
651*10932Srrh 	q = &lkst[nlset++];
652*10932Srrh 	if( nlset >= LSETSIZE )error("too many lookahead sets" );
653*10932Srrh 	SETLOOP(j){
654*10932Srrh 		q->lset[j] = p->lset[j];
655*10932Srrh 		}
656*10932Srrh 	return( q );
657*10932Srrh 	}
658