xref: /illumos-gate/usr/src/cmd/sgs/yacc/common/y1.c (revision 8b80e8cb6855118d46f605e91b5ed4ce83417395)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 #include "dextern.h"
32 #include <sys/param.h>
33 #include <sys/errno.h>
34 #include <unistd.h>
35 #include <locale.h>
36 #include <stdarg.h>	/* For error() */
37 
38 static void mktbls(void);
39 static void others(void);
40 static void summary(void);
41 static wchar_t *chcopy(wchar_t *, wchar_t *);
42 static int setunion(int *, int *);
43 static void prlook(LOOKSETS *);
44 static void cpres(void);
45 static void cpfir(void);
46 static void cempty(void);
47 static void stagen(void);
48 static LOOKSETS *flset(LOOKSETS *);
49 static void exp_lkst(void);
50 static void exp_wsets(void);
51 static void exp_states(void);
52 static void exp_psmem(void);
53 
54 	/* lookahead computations */
55 
56 int TBITSET;
57 static int tbitset;	/* size of lookahead sets */
58 LOOKSETS *lkst;
59 static int lsetsize;
60 
61 static int nlset = 0; 	/* next lookahead set index */
62 int nolook = 0; 	/* flag to suppress lookahead computations */
63 static LOOKSETS clset;  /* temporary storage for lookahead computations */
64 
65 static ITEM *psmem, *zzmemsz;
66 static int new_pstsize = PSTSIZE;
67 
68 	/* working set computations */
69 
70 WSET *wsets;
71 int cwp;
72 static int wsetsz = 0;		/* number of WSET items in wsets block */
73 
74 	/* state information */
75 
76 int nstate = 0;			/* number of states */
77 static int nstatesz = NSTATES;	/* number of state space allocated	*/
78 ITEM **pstate;			/* ptr to descriptions of the states	*/
79 int *tystate;			/* contains type info about the states	*/
80 int *indgo;			/* index to the stored goto table	*/
81 static int *tmp_lset;
82 static int *tstates;		/* states generated by terminal gotos	*/
83 static int *ntstates;		/* states generated by non-term gotos	*/
84 static int *mstates;		/* chain of overflows of term/nonterm	*/
85 				/* generation lists			*/
86 
87 	/* storage for the actions in the parser */
88 
89 int *amem, *memp;		/* next free action table position */
90 int new_actsize = ACTSIZE;
91 
92 	/* other storage areas */
93 
94 int *temp1;		/* temp storate, indexed by terms+ntokens or states */
95 int lineno = 0;		/* current input line number */
96 int size;
97 static int fatfl = 1;  	/* if on, error is fatal */
98 static int nerrors = 0;	/* number of errors */
99 
100 	/* storage for information about the nonterminals */
101 
102 static int ***pres;		/* vector of pointers to productions	*/
103 				/* yielding each nonterminal		*/
104 static LOOKSETS **pfirst;	/* vector of pointers to first sets for	*/
105 				/* each nonterminal			*/
106 static int *pempty;		/* vector of nonterminals nontrivially	*/
107 				/* deriving e				*/
108 extern int nprodsz;
109 
110 int
111 main(int argc, char *argv[])
112 {
113 	(void) setlocale(LC_ALL, "");
114 #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
115 #define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
116 #endif
117 	(void) textdomain(TEXT_DOMAIN);
118 
119 	setup(argc, argv); 		/* initialize and read productions */
120 	TBITSET = NWORDS(ntoksz*LKFACTOR);
121 	tbitset = NWORDS(ntokens*LKFACTOR);
122 	mktbls();
123 	cpres(); 	/* make table of which productions yield a */
124 			/* given nonterminal */
125 	cempty(); 	/* make a table of which nonterminals can match	*/
126 			/* the empty string */
127 	cpfir(); 	/* make a table of firsts of nonterminals */
128 	stagen();	/* generate the states 	*/
129 	output();  	/* write the states and the tables */
130 	go2out();
131 	hideprod();
132 	summary();
133 	callopt();
134 	others();
135 	return (0);
136 }
137 
138 
139 static void
140 mktbls()
141 {
142 	int i;
143 
144 	size = ntoksz + nnontersz +1;
145 	if (size < nstatesz)
146 		size = nstatesz;
147 	if (size < new_memsize)
148 		size = new_memsize;
149 
150 	amem = (int *) malloc(sizeof (int) * new_actsize);
151 	psmem = (ITEM *) malloc(sizeof (ITEM) * new_pstsize);
152 	if ((psmem == NULL) || (amem == NULL))
153 /*
154  * TRANSLATION_NOTE  -- This is a message from yacc.
155  *	This message is passed to error() function.
156  *	This error happens when yacc could not allocate
157  *	initial memory to be used for internal tables.
158  *
159  *	You may just translate this as:
160  *	'Could not allocate internally used memory.'
161  */
162 		error(gettext(
163 		"couldn't allocate initial table"));
164 	zzmemsz = psmem;
165 	memp = amem;
166 
167 	/*
168 	 * For lkst
169 	 */
170 #define	INIT_LSIZE	nnontersz*LKFACTOR
171 	tmp_lset = (int *)
172 	    calloc((size_t)(TBITSET * (INIT_LSIZE+1)), sizeof (int));
173 	if (tmp_lset == NULL)
174 /*
175  * TRANSLATION_NOTE  -- This is a message from yacc.
176  *	This message is passed to error() function.
177  *	Yacc could not allocate memory for table named lookset.
178  *	Do not translate 'lookset'.
179  *
180  *	You may just translate this as:
181  *	'Could not allocate internally used memory.'
182  */
183 		error(gettext(
184 		"could not allocate lookset array"));
185 	lkst = (LOOKSETS *) malloc(sizeof (LOOKSETS) * (INIT_LSIZE + 1));
186 	for (i = 0; i <= INIT_LSIZE; ++i)
187 		lkst[i].lset = tmp_lset + TBITSET * i;
188 	tmp_lset = NULL;
189 
190 	/*
191 	 * For wsets
192 	 */
193 	tmp_lset = (int *)
194 	    calloc((size_t)(TBITSET * (nnontersz+1)), sizeof (int));
195 	if (tmp_lset == NULL)
196 		error(gettext(
197 		"could not allocate lookset array"));
198 	wsets = (WSET *) malloc(sizeof (WSET) * (nnontersz + 1));
199 	for (i = 0; i <= nnontersz; ++i)
200 		wsets[i].ws.lset = tmp_lset + TBITSET * i;
201 	tmp_lset = NULL;
202 
203 	clset.lset = (int *)malloc(sizeof (int)*TBITSET);
204 	tstates = (int *)malloc(sizeof (int)*(ntoksz + 1));
205 	ntstates = (int *)malloc(sizeof (int)*(nnontersz + 1));
206 	temp1 = (int *)malloc(sizeof (int)*size);
207 	pres = (int ***)malloc(sizeof (int **)*(nnontersz + 2));
208 	pfirst = (LOOKSETS **)malloc(sizeof (LOOKSETS *)*(nnontersz + 2));
209 	pempty = (int *)malloc(sizeof (int)*(nnontersz + 1));
210 
211 	pstate = (ITEM **)malloc(sizeof (ITEM *)*(nstatesz+2));
212 	tystate = (int *)malloc(sizeof (int)*nstatesz);
213 	indgo = (int *)malloc(sizeof (int)*nstatesz);
214 	mstates = (int *)malloc(sizeof (int)*nstatesz);
215 	defact = (int *)malloc(sizeof (int)*nstatesz);
216 
217 	if ((lkst == NULL) || (wsets == NULL) || (tstates == NULL) ||
218 	    (ntstates == NULL) || (temp1 == NULL) || (pres == NULL) ||
219 	    (pfirst == NULL) || (pempty == NULL) || (pstate == NULL) ||
220 	    (tystate == NULL) || (indgo == NULL) || (mstates == NULL) ||
221 	    (defact == NULL) || (clset.lset == NULL))
222 /*
223  * TRANSLATION_NOTE  -- This is a message from yacc.
224  *	This message is passed to error() function.
225  *	Do not translate mktbls(). It is a function name.
226  *
227  *	You may just translate this as:
228  *	'Could not allocate internally used memory.'
229  */
230 			error(gettext(
231 			"cannot allocate tables in mktbls()"));
232 
233 	aryfil(ntstates, nnontersz+1, 0);
234 	aryfil(tstates, ntoksz+1, 0);
235 	wsetsz = nnontersz + 1;
236 	lsetsize = INIT_LSIZE + 1;
237 }
238 
239 /* put out other arrays, copy the parsers */
240 static void
241 others()
242 {
243 	extern int gen_lines;
244 	int c, i, j;
245 	int tmpline;
246 
247 	finput = fopen(parser, "r");
248 	if (finput == NULL)
249 /*
250  * TRANSLATION_NOTE  -- This is a message from yacc.
251  *	This message is passed to error() function.
252  *	This error message is issued when yacc can not find
253  *	the parser to be copied.
254  */
255 		error(gettext(
256 		"cannot find parser %s"),
257 		    parser);
258 
259 	warray(L"yyr1", levprd, nprod);
260 
261 	aryfil(temp1, nprod, 0);
262 					/* had_act[i] is either 1 or 0 */
263 	PLOOP(1, i)
264 		temp1[i] = ((prdptr[i+1] - prdptr[i]-2) << 1) | had_act[i];
265 	warray(L"yyr2", temp1, nprod);
266 
267 	aryfil(temp1, nstate, -10000000);
268 	TLOOP(i)
269 		for (j = tstates[i]; j != 0; j = mstates[j])
270 			temp1[j] = tokset[i].value;
271 	NTLOOP(i)
272 		for (j = ntstates[i]; j != 0; j = mstates[j])
273 			temp1[j] = -i;
274 	warray(L"yychk", temp1, nstate);
275 
276 	warray(L"yydef", defact, nstate);
277 
278 	if ((fdebug = fopen(DEBUGNAME, "r")) == NULL)
279 		error("cannot open yacc.debug");
280 	while ((c = getwc(fdebug)) != EOF)
281 		(void) putwc(c, ftable);
282 	(void) fclose(fdebug);
283 	ZAPFILE(DEBUGNAME);
284 
285 	if (gen_lines)
286 		(void) fprintf(ftable, "# line\t1 \"%s\"\n", parser);
287 	tmpline = 1;
288 	/* copy parser text */
289 	while ((c = getwc(finput)) != EOF) {
290 		if (c == '\n')
291 			tmpline++;
292 		if (c == L'$') {
293 			if ((c = getwc(finput)) != L'A')
294 				(void) putwc(L'$', ftable);
295 			else { /* copy actions */
296 				tmpline++;
297 				faction = fopen(ACTNAME, "r");
298 				if (faction == NULL)
299 /*
300  * TRANSLATION_NOTE  -- This is a message from yacc.
301  *	This message is passed to error() function.
302  *	This error is issued when yacc can not open a
303  *	temporary file to be used. You do not need to
304  *	use the word 'tempfile'. You can translate it to
305  *	mean 'temporary file'.
306  */
307 					error(gettext(
308 					"cannot open action tempfile"));
309 				while ((c = getwc(faction)) != EOF)
310 					(void) putwc(c, ftable);
311 				(void) fclose(faction);
312 				if (gen_lines)
313 					(void) fprintf(ftable,
314 					    "\n# line\t%d \"%s\"",
315 					    tmpline,
316 					    parser);
317 				ZAPFILE(ACTNAME);
318 				c = getwc(finput);
319 			}
320 		}
321 		(void) putwc(c, ftable);
322 	}
323 	(void) fclose(ftable);
324 }
325 
326 
327 /* copies string q into p, returning next free char ptr */
328 static wchar_t *
329 chcopy(p, q)
330 wchar_t *p, *q;
331 {
332 	while (*p = *q++)
333 		++p;
334 	return (p);
335 }
336 
337 #define	ISIZE 400
338 /* creates output string for item pointed to by pp */
339 wchar_t *
340 writem(pp)
341 int *pp;
342 {
343 	int i, *p;
344 	static int isize = ISIZE;
345 	static wchar_t *sarr = NULL;
346 	wchar_t *q;
347 
348 	if (sarr == NULL) {
349 		sarr = (wchar_t *)malloc(sizeof (wchar_t) * isize);
350 		if (sarr == NULL)
351 /*
352  * TRANSLATION_NOTE  -- This is a message from yacc.
353  *	This message is passed to error() function.
354  *	This error is issued when yacc could not allocate
355  *	memory for internally used array.
356  *
357  *	You may just translate this as:
358  *	'Could not allocate internally used memory.'
359  */
360 			error(gettext(
361 			"could not allocate output string array"));
362 		for (i = 0; i < isize; ++i)
363 			sarr[i] = L' ';
364 	}
365 	for (p = pp; *p > 0; ++p) /* NULL */;
366 	p = prdptr[-*p];
367 	q = chcopy(sarr, nontrst[*p-NTBASE].name);
368 	q = chcopy(q, L" : ");
369 
370 	for (;;) {
371 		*q++ = ++p == pp ? L'_' : L' ';
372 		*q = 0;
373 		if ((i = *p) <= 0)
374 			break;
375 		q = chcopy(q, symnam(i));
376 		while (q > &sarr[isize-30]) {
377 			static wchar_t *sarrbase;
378 
379 			sarrbase = sarr;
380 			isize += ISIZE;
381 			sarr = (wchar_t *)
382 				realloc((char *)sarr, sizeof (*sarr) * isize);
383 			if (sarr == NULL)
384 /*
385  * TRANSLATION_NOTE  -- This is a message from yacc.
386  *	This message is passed to error() function.
387  *	This error is issued when yacc could not allocate
388  *	memory for internally used array.
389  *
390  *	You may just translate this as:
391  *	'Could not allocate internally used memory.'
392  */
393 				error(gettext(
394 				"cannot expand sarr arrays"));
395 			q = q - sarrbase + sarr;
396 		}
397 	}
398 
399 	/* an item calling for a reduction */
400 	if ((i = *pp) < 0) {
401 		q = chcopy(q, L"    (");
402 		(void) wsprintf(q, "%d)", -i);
403 	}
404 	return (sarr);
405 }
406 
407 /* return a pointer to the name of symbol i */
408 wchar_t *
409 symnam(int i)
410 {
411 	wchar_t *cp;
412 
413 	cp = (i >= NTBASE) ? nontrst[i-NTBASE].name : tokset[i].name;
414 	if (*cp == L' ')
415 		++cp;
416 	return (cp);
417 }
418 
419 static int zzcwp = 0;
420 static int zzclose = 0;
421 int zzgoent = 0;
422 int zzgobest = 0;
423 int zzacent = 0;
424 int zzexcp = 0;
425 int zzsrconf = 0;
426 int zzrrconf = 0;
427 
428 /* output the summary on the tty */
429 static void
430 summary()
431 {
432 	if (foutput != NULL) {
433 		(void) fprintf(foutput,
434 		    "\n%d/%d terminals, %d/%d nonterminals\n",
435 		    ntokens, ntoksz, nnonter, nnontersz);
436 		(void) fprintf(foutput,
437 		    "%d/%d grammar rules, %d/%d states\n",
438 		    nprod, nprodsz, nstate, nstatesz);
439 		(void) fprintf(foutput,
440 		"%d shift/reduce, %d reduce/reduce conflicts reported\n",
441 		    zzsrconf, zzrrconf);
442 		(void) fprintf(foutput,
443 		    "%d/%d working sets used\n", zzcwp, wsetsz);
444 		(void) fprintf(foutput,
445 		    "memory: states,etc. %" PRIdPTR
446 		    "/%d, parser %" PRIdPTR "/%d\n",
447 		    mem-tracemem, new_memsize,
448 		    memp-amem, new_actsize);
449 		(void) fprintf(foutput,
450 		    "%d/%d distinct lookahead sets\n", nlset, lsetsize);
451 		(void) fprintf(foutput,
452 		    "%d extra closures\n", zzclose - 2*nstate);
453 		(void) fprintf(foutput,
454 		    "%d shift entries, %d exceptions\n", zzacent, zzexcp);
455 		(void) fprintf(foutput,
456 		    "%d goto entries\n", zzgoent);
457 		(void) fprintf(foutput,
458 		    "%d entries saved by goto default\n", zzgobest);
459 	}
460 	if (zzsrconf != 0 || zzrrconf != 0) {
461 /*
462  * TRANSLATION_NOTE  -- This is a message from yacc.
463  *	You may just leave this message un-translated.
464  *	This message only makes sense to those who knows
465  *	how yacc works, and the person should know what
466  *	this message means in English.
467  */
468 		(void) fprintf(stderr, gettext(
469 		    "\nconflicts: "));
470 		if (zzsrconf)
471 			(void) fprintf(stderr, "%d shift/reduce", zzsrconf);
472 		if (zzsrconf && zzrrconf)
473 			(void) fprintf(stderr, ", ");
474 		if (zzrrconf)
475 			(void) fprintf(stderr, "%d reduce/reduce", zzrrconf);
476 		(void) fprintf(stderr, "\n");
477 	}
478 
479 	if (ftemp != NULL)
480 		(void) fclose(ftemp);
481 	if (fdefine != NULL)
482 		(void) fclose(fdefine);
483 }
484 
485 /* write out error comment */
486 /*PRINTFLIKE1*/
487 void
488 error(char *s, ...)
489 {
490 	extern char *infile;
491 	va_list	ap;
492 
493 	va_start(ap, s);
494 
495 	++nerrors;
496 	if (!lineno)
497 /*
498  * TRANSLATION_NOTE  -- This is a message from yacc.
499  *	This message is a prefix to the error messages
500  *	passed to error() function.
501  */
502 		(void) fprintf(stderr, gettext(
503 		    "command line: fatal: "));
504 	else {
505 		(void) fprintf(stderr, "\"%s\", ", infile);
506 /*
507  * TRANSLATION_NOTE  -- This is a message from yacc.
508  *	This message is a prefix to the error messages
509  *	passed to error() function.
510  */
511 		(void) fprintf(stderr, gettext(
512 		    "line %d: fatal: "),
513 		    lineno);
514 	}
515 	(void) vfprintf(stderr, s, ap);
516 	(void) fprintf(stderr, "\n");
517 	va_end(ap);
518 	if (!fatfl)
519 		return;
520 	summary();
521 	exit(1);
522 }
523 
524 /*
525  * Print out a warning message.
526  */
527 /*PRINTFLIKE2*/
528 void
529 warning(int flag, char *s, ...)
530 {
531 	extern char *infile;
532 	va_list	ap;
533 	va_start(ap, s);
534 
535 	(void) fprintf(stderr, "\"%s\", ", infile);
536 	/*
537 	 * If flag, print lineno as well.
538 	 */
539 	if (flag == 0)
540 /*
541  * TRANSLATION_NOTE  -- This is a message from yacc.
542  *	This message is a prefix to the warning messages
543  *	passed to warning() function.
544  */
545 		(void) fprintf(stderr, gettext(
546 		    "warning: "));
547 	else
548 /*
549  * TRANSLATION_NOTE  -- This is a message from yacc.
550  *	This message is a prefix to the warning messages
551  *	passed to warning() function.
552  */
553 		(void) fprintf(stderr, gettext(
554 		    "line %d: warning: "),
555 		    lineno);
556 	(void) vfprintf(stderr, s, ap);
557 	(void) fprintf(stderr, "\n");
558 	va_end(ap);
559 }
560 
561 /* set elements 0 through n-1 to c */
562 void
563 aryfil(v, n, c)
564 int *v, n, c;
565 {
566 	int i;
567 	for (i = 0; i < n; ++i)
568 		v[i] = c;
569 }
570 
571 /* set a to the union of a and b */
572 /* return 1 if b is not a subset of a, 0 otherwise */
573 static int
574 setunion(a, b)
575 int *a, *b;
576 {
577 	int i, x, sub;
578 
579 	sub = 0;
580 	SETLOOP(i) {
581 		*a = (x = *a) | *b++;
582 		if (*a++ != x)
583 			sub = 1;
584 	}
585 	return (sub);
586 }
587 
588 static void
589 prlook(p)
590 LOOKSETS *p;
591 {
592 	int j, *pp;
593 	pp = p->lset;
594 	if (pp == 0)
595 		(void) fprintf(foutput, "\tNULL");
596 	else {
597 		(void) fprintf(foutput, " { ");
598 		TLOOP(j) {
599 			if (BIT(pp, j))
600 				(void) fprintf(foutput,  WSFMT("%ws "),
601 				    symnam(j));
602 		}
603 		(void) fprintf(foutput,  "}");
604 	}
605 }
606 
607 /*
608  * compute an array with the beginnings of  productions yielding
609  * given nonterminals
610  * The array pres points to these lists
611  * the array pyield has the lists: the total size is only NPROD+1
612  */
613 static void
614 cpres()
615 {
616 	int **ptrpy;
617 	int **pyield;
618 	int c, j, i;
619 
620 	/*
621 	 * 2/29/88 -
622 	 * nprodsz is the size of the tables describing the productions.
623 	 * Normally this will be NPROD unless the production tables have
624 	 * been expanded, in which case the tables will be NPROD * N(where
625 	 * N is the number of times the tables had to be expanded.)
626 	 */
627 	if ((pyield = (int **) malloc(sizeof (int *) * nprodsz)) == NULL)
628 /*
629  * TRANSLATION_NOTE  -- This is a message from yacc.
630  *	This message is passed to error() function.
631  *	This error is issued when yacc could not allocate
632  *	memory for internally used array.
633  *
634  *	pyield is name of an array. You should not try to translate
635  *	this word.
636  *
637  *	You may just translate this as:
638  *	'Could not allocate internally used memory.'
639  */
640 		error(gettext(
641 		"cannot allocate space for pyield array"));
642 
643 	ptrpy = pyield;
644 
645 	NTLOOP(i) {
646 		c = i+NTBASE;
647 		pres[i] = ptrpy;
648 		fatfl = 0;  /* make undefined  symbols  nonfatal */
649 		PLOOP(0, j) {
650 			if (*prdptr[j] == c)  	/* linear search for all c's */
651 				*ptrpy++ =  prdptr[j] + 1;
652 		}
653 		if (pres[i] == ptrpy) { 		/* c not found */
654 /*
655  * TRANSLATION_NOTE  -- This is a message from yacc.
656  *	This message is passed to error() function.
657  *	Ask somebody who knows yacc how to translate nonterminal or
658  *	look at translated yacc document.
659  */
660 			error(gettext(
661 			"undefined nonterminal: %ws"),
662 			    nontrst[i].name);
663 		}
664 	}
665 	pres[i] = ptrpy;
666 	fatfl = 1;
667 	if (nerrors) {
668 		summary();
669 		exit(1);
670 	}
671 	if (ptrpy != &pyield[nprod])
672 /*
673  * TRANSLATION_NOTE  -- This is a message from yacc.
674  *	This message is passed to error() function.
675  *	This is an internal error message.
676  *	Very little use to user. You may leave it
677  *	un-translated.
678  *
679  *	pyied is name of an array. Do not translate it.
680  */
681 		error(gettext(
682 		"internal Yacc error: pyield %d"),
683 		    ptrpy-&pyield[nprod]);
684 }
685 
686 static int indebug = 0;
687 /* compute an array with the first of nonterminals */
688 static void
689 cpfir()
690 {
691 	int *p, **s, i, **t, ch, changes;
692 
693 	zzcwp = nnonter;
694 	NTLOOP(i) {
695 		aryfil(wsets[i].ws.lset, tbitset, 0);
696 		t = pres[i+1];
697 		/* initially fill the sets */
698 		for (s = pres[i]; s < t; ++s) {
699 			/* check if ch is non-terminal */
700 			for (p = *s; (ch = *p) > 0; ++p) {
701 				if (ch < NTBASE) { 	/* should be token */
702 					SETBIT(wsets[i].ws.lset, ch);
703 					break;
704 				} else if (!pempty[ch-NTBASE])
705 					break;
706 			}
707 		}
708 	}
709 
710 	/* now, reflect transitivity */
711 
712 	changes = 1;
713 	while (changes) {
714 		changes = 0;
715 		NTLOOP(i) {
716 			t = pres[i+1];
717 			for (s = pres[i]; s < t; ++s) {
718 				for (p = *s; (ch = (*p-NTBASE)) >= 0; ++p) {
719 					changes |= setunion(wsets[i].ws.lset,
720 					    wsets[ch].ws.lset);
721 					if (!pempty[ch])
722 						break;
723 				}
724 			}
725 		}
726 	}
727 
728 	NTLOOP(i)
729 		pfirst[i] = flset(&wsets[i].ws);
730 	if (!indebug)
731 		return;
732 	if ((foutput != NULL)) {
733 		NTLOOP(i) {
734 			(void) fprintf(foutput, WSFMT("\n%ws: "),
735 			    nontrst[i].name);
736 			prlook(pfirst[i]);
737 			(void) fprintf(foutput, " %d\n", pempty[i]);
738 		}
739 	}
740 }
741 
742 /* sorts last state,and sees if it equals earlier ones. returns state number */
743 int
744 state(int c)
745 {
746 	int size1, size2;
747 	int i;
748 	ITEM *p1, *p2, *k, *l, *q1, *q2;
749 	p1 = pstate[nstate];
750 	p2 = pstate[nstate+1];
751 	if (p1 == p2)
752 		return (0); /* null state */
753 	/* sort the items */
754 	for (k = p2 - 1; k > p1; k--) {	/* make k the biggest */
755 		for (l = k-1; l >= p1; --l)
756 			if (l->pitem > k->pitem) {
757 				int *s;
758 				LOOKSETS *ss;
759 				s = k->pitem;
760 				k->pitem = l->pitem;
761 				l->pitem = s;
762 				ss = k->look;
763 				k->look = l->look;
764 				l->look = ss;
765 			}
766 	}
767 	size1 = p2 - p1; /* size of state */
768 
769 	for (i = (c >= NTBASE) ? ntstates[c-NTBASE] : tstates[c];
770 	    i != 0; i = mstates[i]) {
771 		/* get ith state */
772 		q1 = pstate[i];
773 		q2 = pstate[i+1];
774 		size2 = q2 - q1;
775 		if (size1 != size2)
776 			continue;
777 		k = p1;
778 		for (l = q1; l < q2; l++) {
779 			if (l->pitem != k->pitem)
780 				break;
781 			++k;
782 		}
783 		if (l != q2)
784 			continue;
785 		/* found it */
786 		pstate[nstate+1] = pstate[nstate]; /* delete last state */
787 		/* fix up lookaheads */
788 		if (nolook)
789 			return (i);
790 		for (l = q1, k = p1; l < q2; ++l, ++k) {
791 			int s;
792 			SETLOOP(s)
793 				clset.lset[s] = l->look->lset[s];
794 			if (setunion(clset.lset, k->look->lset)) {
795 				tystate[i] = MUSTDO;
796 				/* register the new set */
797 				l->look = flset(&clset);
798 			}
799 		}
800 		return (i);
801 	}
802 	/* state is new */
803 	if (nolook)
804 /*
805  * TRANSLATION_NOTE  -- This is a message from yacc.
806  *	This message is passed to error() function.
807  *	You may leave this untranslated. Leave
808  *	state/nolook un-translated.
809  */
810 		error(gettext(
811 		"yacc state/nolook error"));
812 	pstate[nstate+2] = p2;
813 	if (nstate+1 >= nstatesz)
814 		exp_states();
815 	if (c >= NTBASE) {
816 		mstates[nstate] = ntstates[c - NTBASE];
817 		ntstates[c - NTBASE] = nstate;
818 	} else {
819 		mstates[nstate] = tstates[c];
820 		tstates[c] = nstate;
821 	}
822 	tystate[nstate] = MUSTDO;
823 	return (nstate++);
824 }
825 
826 static int pidebug = 0;
827 
828 void
829 putitem(ptr, lptr)
830 int *ptr;
831 LOOKSETS *lptr;
832 {
833 	register ITEM *j;
834 
835 	if (pidebug && (foutput != NULL))
836 		(void) fprintf(foutput,
837 			WSFMT("putitem(%ws), state %d\n"), writem(ptr), nstate);
838 	j = pstate[nstate+1];
839 	j->pitem = ptr;
840 	if (!nolook)
841 		j->look = flset(lptr);
842 	pstate[nstate+1] = ++j;
843 	if (j > zzmemsz) {
844 		zzmemsz = j;
845 		if (zzmemsz >=  &psmem[new_pstsize])
846 			exp_psmem();
847 			/* error("out of state space"); */
848 	}
849 }
850 
851 /*
852  * mark nonterminals which derive the empty string
853  * also, look for nonterminals which don't derive any token strings
854  */
855 static void
856 cempty()
857 {
858 #define	EMPTY 1
859 #define	WHOKNOWS 0
860 #define	OK 1
861 	int i, *p;
862 
863 	/*
864 	 * first, use the array pempty to detect productions
865 	 * that can never be reduced
866 	 */
867 
868 	/* set pempty to WHONOWS */
869 	aryfil(pempty, nnonter+1, WHOKNOWS);
870 
871 	/*
872 	 * now, look at productions, marking nonterminals which
873 	 * derive something
874 	 */
875 	more:
876 	PLOOP(0, i) {
877 		if (pempty[*prdptr[i] - NTBASE])
878 			continue;
879 		for (p = prdptr[i] + 1; *p >= 0; ++p)
880 			if (*p >= NTBASE && pempty[*p-NTBASE] == WHOKNOWS)
881 				break;
882 		if (*p < 0) { /* production can be derived */
883 			pempty[*prdptr[i]-NTBASE] = OK;
884 			goto more;
885 		}
886 	}
887 
888 	/* now, look at the nonterminals, to see if they are all OK */
889 
890 	NTLOOP(i) {
891 		/*
892 		 * the added production rises or falls as the
893 		 * start symbol ...
894 		 */
895 		if (i == 0)
896 			continue;
897 		if (pempty[i] != OK) {
898 			fatfl = 0;
899 /*
900  * TRANSLATION_NOTE  -- This is a message from yacc.
901  *	This message is passed to error() function.
902  *	Ask somebody who knows yacc how to translate nonterminal or
903  *	look at translated yacc document. Check how 'derive' is
904  *	translated in these documents also.
905  */
906 			error(gettext(
907 			"nonterminal %ws never derives any token string"),
908 			    nontrst[i].name);
909 		}
910 	}
911 
912 	if (nerrors) {
913 		summary();
914 		exit(1);
915 	}
916 
917 	/*
918 	 * now, compute the pempty array, to see which nonterminals
919 	 * derive the empty string
920 	 */
921 
922 	/* set pempty to WHOKNOWS */
923 
924 	aryfil(pempty, nnonter+1, WHOKNOWS);
925 
926 	/* loop as long as we keep finding empty nonterminals */
927 
928 again:
929 	PLOOP(1, i) {
930 		/* not known to be empty */
931 		if (pempty[*prdptr[i]-NTBASE] == WHOKNOWS) {
932 			for (p = prdptr[i]+1;
933 			    *p >= NTBASE && pempty[*p-NTBASE] == EMPTY; ++p)
934 				;
935 			/* we have a nontrivially empty nonterminal */
936 			if (*p < 0) {
937 				pempty[*prdptr[i]-NTBASE] = EMPTY;
938 				goto again; /* got one ... try for another */
939 			}
940 		}
941 	}
942 }
943 
944 /* generate the states */
945 static int gsdebug = 0;
946 static void
947 stagen()
948 {
949 	int i, j;
950 	int c;
951 	register WSET *p, *q;
952 
953 	/* initialize */
954 
955 	nstate = 0;
956 
957 	pstate[0] = pstate[1] = psmem;
958 	aryfil(clset.lset, tbitset, 0);
959 	putitem(prdptr[0] + 1, &clset);
960 	tystate[0] = MUSTDO;
961 	nstate = 1;
962 	pstate[2] = pstate[1];
963 
964 	aryfil(amem, new_actsize, 0);
965 
966 	/* now, the main state generation loop */
967 
968 	more:
969 	SLOOP(i) {
970 		if (tystate[i] != MUSTDO)
971 			continue;
972 		tystate[i] = DONE;
973 		aryfil(temp1, nnonter + 1, 0);
974 		/* take state i, close it, and do gotos */
975 		closure(i);
976 		WSLOOP(wsets, p) { /* generate goto's */
977 			if (p->flag)
978 				continue;
979 			p->flag = 1;
980 			c = *(p->pitem);
981 			if (c <= 1) {
982 				if (pstate[i+1]-pstate[i] <= p-wsets)
983 					tystate[i] = MUSTLOOKAHEAD;
984 				continue;
985 			}
986 			/* do a goto on c */
987 			WSLOOP(p, q) {
988 				/* this item contributes to the goto */
989 				if (c == *(q->pitem)) {
990 					putitem(q->pitem + 1, &q->ws);
991 					q->flag = 1;
992 				}
993 			}
994 			if (c < NTBASE)
995 				(void) state(c);  /* register new state */
996 			else temp1[c-NTBASE] = state(c);
997 		}
998 		if (gsdebug && (foutput != NULL)) {
999 			(void) fprintf(foutput,  "%d: ", i);
1000 			NTLOOP(j) {
1001 				if (temp1[j])
1002 					(void) fprintf(foutput,
1003 					    WSFMT("%ws %d, "), nontrst[j].name,
1004 					    temp1[j]);
1005 			}
1006 			(void) fprintf(foutput, "\n");
1007 		}
1008 		indgo[i] = apack(&temp1[1], nnonter - 1) - 1;
1009 		goto more; /* we have done one goto; do some more */
1010 	}
1011 	/* no more to do... stop */
1012 }
1013 
1014 /* generate the closure of state i */
1015 static int cldebug = 0; /* debugging flag for closure */
1016 
1017 void
1018 closure(int i)
1019 {
1020 	int c, ch, work, k;
1021 	register WSET *u, *v;
1022 	int *pi;
1023 	int **s, **t;
1024 	ITEM *q;
1025 	register ITEM *p;
1026 	int idx1 = 0;
1027 
1028 	++zzclose;
1029 
1030 	/* first, copy kernel of state i to wsets */
1031 	cwp = 0;
1032 	ITMLOOP(i, p, q) {
1033 		wsets[cwp].pitem = p->pitem;
1034 		wsets[cwp].flag = 1;    /* this item must get closed */
1035 		SETLOOP(k)
1036 			wsets[cwp].ws.lset[k] = p->look->lset[k];
1037 		WSBUMP(cwp);
1038 	}
1039 
1040 	/* now, go through the loop, closing each item */
1041 
1042 	work = 1;
1043 	while (work) {
1044 		work = 0;
1045 		/*
1046 		 * WSLOOP(wsets, u) {
1047 		 */
1048 		for (idx1 = 0; idx1 < cwp; idx1++) {
1049 			u = &wsets[idx1];
1050 			if (u->flag == 0)
1051 				continue;
1052 			c = *(u->pitem);  /* dot is before c */
1053 			if (c < NTBASE) {
1054 				u->flag = 0;
1055 				/*
1056 				 * only interesting case is where . is
1057 				 * before nonterminal
1058 				 */
1059 				continue;
1060 			}
1061 
1062 			/* compute the lookahead */
1063 			aryfil(clset.lset, tbitset, 0);
1064 
1065 			/* find items involving c */
1066 
1067 			WSLOOP(u, v) {
1068 				if (v->flag == 1 && *(pi = v->pitem) == c) {
1069 					v->flag = 0;
1070 					if (nolook)
1071 						continue;
1072 					while ((ch = *++pi) > 0) {
1073 						/* terminal symbol */
1074 						if (ch < NTBASE) {
1075 							SETBIT(clset.lset, ch);
1076 							break;
1077 						}
1078 						/* nonterminal symbol */
1079 						(void) setunion(clset.lset,
1080 						    pfirst[ch-NTBASE]->lset);
1081 						if (!pempty[ch-NTBASE])
1082 							break;
1083 					}
1084 					if (ch <= 0)
1085 						(void) setunion(clset.lset,
1086 						    v->ws.lset);
1087 				}
1088 			}
1089 
1090 			/*  now loop over productions derived from c */
1091 
1092 			c -= NTBASE; /* c is now nonterminal number */
1093 
1094 			t = pres[c+1];
1095 			for (s = pres[c]; s < t; ++s) {
1096 				/* put these items into the closure */
1097 				WSLOOP(wsets, v) { /* is the item there */
1098 					/* yes, it is there */
1099 					if (v->pitem == *s) {
1100 						if (nolook)
1101 							goto nexts;
1102 						if (setunion(v->ws.lset,
1103 						    clset.lset))
1104 							v->flag = work = 1;
1105 						goto nexts;
1106 					}
1107 				}
1108 
1109 				/*  not there; make a new entry */
1110 				if (cwp + 1 >= wsetsz)
1111 					exp_wsets();
1112 
1113 				wsets[cwp].pitem = *s;
1114 				wsets[cwp].flag = 1;
1115 				if (!nolook) {
1116 					work = 1;
1117 					SETLOOP(k)
1118 						wsets[cwp].ws.lset[k] =
1119 						    clset.lset[k];
1120 				}
1121 				WSBUMP(cwp);
1122 				nexts:;
1123 			}
1124 		}
1125 	}
1126 
1127 	/* have computed closure; flags are reset; return */
1128 
1129 	if (&wsets[cwp] > &wsets[zzcwp])
1130 		zzcwp = cwp;
1131 	if (cldebug && (foutput != NULL)) {
1132 		(void) fprintf(foutput, "\nState %d, nolook = %d\n", i, nolook);
1133 		WSLOOP(wsets, u) {
1134 			if (u->flag)
1135 				(void) fprintf(foutput, "flag set!\n");
1136 			u->flag = 0;
1137 			(void) fprintf(foutput, WSFMT("\t%ws"),
1138 			    writem(u->pitem));
1139 			prlook(&u->ws);
1140 			(void) fprintf(foutput,  "\n");
1141 		}
1142 	}
1143 }
1144 
1145 static LOOKSETS *
1146 flset(p)
1147 LOOKSETS *p;
1148 {
1149 	/* decide if the lookahead set pointed to by p is known */
1150 	/* return pointer to a perminent location for the set */
1151 
1152 	int j, *w;
1153 	int *u, *v;
1154 	register LOOKSETS *q;
1155 
1156 	for (q = &lkst[nlset]; q-- > lkst; ) {
1157 		u = p->lset;
1158 		v = q->lset;
1159 		w = & v[tbitset];
1160 		while (v < w)
1161 			if (*u++ != *v++)
1162 				goto more;
1163 		/* we have matched */
1164 		return (q);
1165 		more:;
1166 	}
1167 	/* add a new one */
1168 	q = &lkst[nlset++];
1169 	if (nlset >= lsetsize) {
1170 		exp_lkst();
1171 		q = &lkst[nlset++];
1172 	}
1173 	SETLOOP(j) q->lset[j] = p->lset[j];
1174 	return (q);
1175 }
1176 
1177 static void
1178 exp_lkst()
1179 {
1180 	int i, j;
1181 	static LOOKSETS *lookbase;
1182 
1183 	lookbase = lkst;
1184 	lsetsize += LSETSIZE;
1185 	tmp_lset = (int *)
1186 	    calloc((size_t)(TBITSET * (lsetsize-LSETSIZE)), sizeof (int));
1187 	if (tmp_lset == NULL)
1188 /*
1189  * TRANSLATION_NOTE  -- This is a message from yacc.
1190  *	This message is passed to error() function.
1191  *	Memory allocation error. Do not translate lookset.
1192  *
1193  *	You may just translate this as:
1194  *	'Could not allocate internally used memory.'
1195  */
1196 		error(gettext(
1197 		"could not expand lookset array"));
1198 	lkst = (LOOKSETS *) realloc((char *)lkst, sizeof (LOOKSETS) * lsetsize);
1199 	for (i = lsetsize-LSETSIZE, j = 0; i < lsetsize; ++i, ++j)
1200 		lkst[i].lset = tmp_lset + TBITSET * j;
1201 	tmp_lset = NULL;
1202 	if (lkst == NULL)
1203 /*
1204  * TRANSLATION_NOTE  -- This is a message from yacc.
1205  *	This message is passed to error() function.
1206  *	Memory allocation error. Do not translate lookset.
1207  *
1208  *	You may just translate this as:
1209  *	'Could not allocate internally used memory.'
1210  */
1211 		error(gettext(
1212 		"could not expand lookahead sets"));
1213 	for (i = 0; i <= nnonter; ++i)
1214 		pfirst[i] = pfirst[i] - lookbase + lkst;
1215 	for (i = 0; i <= nstate+1; ++i) {
1216 		if (psmem[i].look)
1217 			psmem[i].look = psmem[i].look - lookbase + lkst;
1218 		if (pstate[i]->look)
1219 			pstate[i]->look = pstate[i]->look - lookbase + lkst;
1220 	}
1221 }
1222 
1223 static void
1224 exp_wsets()
1225 {
1226 	int i, j;
1227 
1228 	wsetsz += WSETSIZE;
1229 	tmp_lset = (int *)
1230 	    calloc((size_t)(TBITSET * (wsetsz-WSETSIZE)), sizeof (int));
1231 	if (tmp_lset == NULL)
1232 /*
1233  * TRANSLATION_NOTE  -- This is a message from yacc.
1234  *	This message is passed to error() function.
1235  *	Memory allocation error. Do not translate lookset.
1236  *
1237  *	You may just translate this as:
1238  *	'Could not allocate internally used memory.'
1239  */
1240 		error(gettext(
1241 		"could not expand lookset array"));
1242 	wsets = (WSET *) realloc((char *)wsets, sizeof (WSET) * wsetsz);
1243 	for (i = wsetsz-WSETSIZE, j = 0; i < wsetsz; ++i, ++j)
1244 		wsets[i].ws.lset = tmp_lset + TBITSET * j;
1245 	tmp_lset = NULL;
1246 	if (wsets == NULL)
1247 /*
1248  * TRANSLATION_NOTE  -- This is a message from yacc.
1249  *	This message is passed to error() function.
1250  *	Memory allocation error. You may just transltate
1251  *	this as 'Could not allocate internally used memory.'
1252  *
1253  *	You may just translate this as:
1254  *	'Could not allocate internally used memory.'
1255  */
1256 		error(gettext(
1257 		"could not expand working sets"));
1258 }
1259 
1260 static void
1261 exp_states()
1262 {
1263 	nstatesz += NSTATES;
1264 
1265 	pstate = (ITEM **)
1266 	    realloc((char *)pstate, sizeof (ITEM *)*(nstatesz+2));
1267 	mstates = (int *)realloc((char *)mstates, sizeof (int)*nstatesz);
1268 	defact = (int *)realloc((char *)defact, sizeof (int)*nstatesz);
1269 	tystate = (int *)realloc((char *)tystate, sizeof (int)*nstatesz);
1270 	indgo = (int *)realloc((char *)indgo, sizeof (int)*nstatesz);
1271 
1272 	if ((*pstate == NULL) || (tystate == NULL) || (defact == NULL) ||
1273 	    (indgo == NULL) || (mstates == NULL))
1274 /*
1275  * TRANSLATION_NOTE  -- This is a message from yacc.
1276  *	This message is passed to error() function.
1277  *	Memory allocation error.
1278  *
1279  *	You may just translate this as:
1280  *	'Could not allocate internally used memory.'
1281  */
1282 		error(gettext(
1283 		"cannot expand table of states"));
1284 }
1285 
1286 static void
1287 exp_psmem()
1288 {
1289 	int i;
1290 
1291 	new_pstsize += PSTSIZE;
1292 	psmem = (ITEM *) realloc((char *)psmem, sizeof (ITEM) * new_pstsize);
1293 	if (psmem == NULL)
1294 /*
1295  * TRANSLATION_NOTE  -- This is a message from yacc.
1296  *	This message is passed to error() function.
1297  *	Memory allocation error.
1298  *
1299  *	You may just translate this as:
1300  *	'Could not allocate internally used memory.'
1301  */
1302 		error(gettext(
1303 		"cannot expand pstate memory"));
1304 
1305 	zzmemsz = zzmemsz - pstate[0] + psmem;
1306 	for (i = 1; i <= nstate+1; ++i)
1307 		pstate[i] = pstate[i] - pstate[0] + psmem;
1308 	pstate[0] = psmem;
1309 }
1310