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