hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

y1.c (24864B)


      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 1990 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 /*	from OpenSolaris "y1.c	6.27	05/06/08 SMI"	*/
     31 
     32 /*
     33  * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany
     34  *
     35  * Sccsid @(#)y1.c	1.7 (gritter) 11/26/05
     36  */
     37 
     38 #include "dextern"
     39 #include <sys/param.h>
     40 #include <errno.h>
     41 #include <unistd.h>
     42 #include <locale.h>
     43 #include <stdarg.h>	/* For error() */
     44 #include <wchar.h>
     45 
     46 static void mktbls(void);
     47 static void others(void);
     48 static void summary(void);
     49 static wchar_t *chcopy(wchar_t *, wchar_t *);
     50 static int setunion(int *, int *);
     51 static void prlook(LOOKSETS *);
     52 static void cpres(void);
     53 static void cpfir(void);
     54 static void cempty(void);
     55 static void stagen(void);
     56 static LOOKSETS *flset(LOOKSETS *);
     57 static void exp_lkst(void);
     58 static void exp_wsets(void);
     59 static void exp_states(void);
     60 static void exp_psmem(void);
     61 
     62 	/* lookahead computations */
     63 
     64 int TBITSET;
     65 static int tbitset;	/* size of lookahead sets */
     66 LOOKSETS *lkst;
     67 static int lsetsize;
     68 
     69 static int nlset = 0; 	/* next lookahead set index */
     70 int nolook = 0; 	/* flag to suppress lookahead computations */
     71 static LOOKSETS clset;  /* temporary storage for lookahead computations */
     72 
     73 static ITEM *psmem, *zzmemsz;
     74 static int new_pstsize = PSTSIZE;
     75 
     76 	/* working set computations */
     77 
     78 WSET *wsets;
     79 int cwp;
     80 static int wsetsz = 0;		/* number of WSET items in wsets block */
     81 
     82 	/* state information */
     83 
     84 int nstate = 0;			/* number of states */
     85 static int nstatesz = NSTATES;	/* number of state space allocated	*/
     86 ITEM **pstate;			/* ptr to descriptions of the states	*/
     87 int *tystate;			/* contains type info about the states	*/
     88 int *indgo;			/* index to the stored goto table	*/
     89 static int *tmp_lset;
     90 static int *tstates;		/* states generated by terminal gotos	*/
     91 static int *ntstates;		/* states generated by non-term gotos	*/
     92 static int *mstates;		/* chain of overflows of term/nonterm	*/
     93 				/* generation lists			*/
     94 
     95 	/* storage for the actions in the parser */
     96 
     97 int *amem, *memp;		/* next free action table position */
     98 int new_actsize = ACTSIZE;
     99 
    100 	/* other storage areas */
    101 
    102 int *temp1;		/* temp storate, indexed by terms+ntokens or states */
    103 int lineno = 0;		/* current input line number */
    104 int size;
    105 static int fatfl = 1;  	/* if on, error is fatal */
    106 static int nerrors = 0;	/* number of errors */
    107 
    108 	/* storage for information about the nonterminals */
    109 
    110 static int ***pres;		/* vector of pointers to productions	*/
    111 				/* yielding each nonterminal		*/
    112 static LOOKSETS **pfirst;	/* vector of pointers to first sets for	*/
    113 				/* each nonterminal			*/
    114 static int *pempty;		/* vector of nonterminals nontrivially	*/
    115 				/* deriving e				*/
    116 extern int nprodsz;
    117 
    118 static char *sav_argv0;
    119 char run_directory[MAXPATHLEN];
    120 char current_work_directory[MAXPATHLEN];
    121 
    122 int 
    123 main(int argc, char *argv[])
    124 {
    125 	setlocale(LC_CTYPE, "");
    126 
    127 	sav_argv0 = argv[0];
    128 	setup(argc, argv); 		/* initialize and read productions */
    129 	TBITSET = NWORDS(ntoksz*LKFACTOR);
    130 	tbitset = NWORDS(ntokens*LKFACTOR);
    131 	mktbls();
    132 	cpres(); 	/* make table of which productions yield a */
    133 			/* given nonterminal */
    134 	cempty(); 	/* make a table of which nonterminals can match	*/
    135 			/* the empty string */
    136 	cpfir(); 	/* make a table of firsts of nonterminals */
    137 	stagen();	/* generate the states 	*/
    138 	output();  	/* write the states and the tables */
    139 	go2out();
    140 	hideprod();
    141 	summary();
    142 	callopt();
    143 	others();
    144 	return 0;
    145 }
    146 
    147 
    148 static void 
    149 mktbls(void)
    150 {
    151 	int i;
    152 
    153 	size = ntoksz + nnontersz +1;
    154 	if (size < nstatesz)
    155 		size = nstatesz;
    156 	if (size < new_memsize)
    157 		size = new_memsize;
    158 
    159 	amem = malloc(sizeof (int) * new_actsize);
    160 	psmem = malloc(sizeof (ITEM) * new_pstsize);
    161 	if ((psmem == NULL) || (amem == NULL))
    162 		error("couldn't allocate initial table");
    163 	zzmemsz = psmem;
    164 	memp = amem;
    165 
    166 	/*
    167 	 * For lkst
    168 	 */
    169 #define	INIT_LSIZE	nnontersz*LKFACTOR
    170 	tmp_lset = calloc((size_t)(TBITSET * (INIT_LSIZE+1)), sizeof (int));
    171 	if (tmp_lset == NULL)
    172 		error("could not allocate lookset array");
    173 	lkst = malloc(sizeof (LOOKSETS) * (INIT_LSIZE + 1));
    174 	for (i = 0; i <= INIT_LSIZE; ++i)
    175 		lkst[i].lset = tmp_lset + TBITSET * i;
    176 	tmp_lset = NULL;
    177 
    178 	/*
    179 	 * For wsets
    180 	 */
    181 	tmp_lset = calloc((size_t)(TBITSET * (nnontersz+1)), sizeof (int));
    182 	if (tmp_lset == NULL)
    183 		error("could not allocate lookset array");
    184 	wsets = (WSET *) malloc(sizeof (WSET) * (nnontersz + 1));
    185 	for (i = 0; i <= nnontersz; ++i)
    186 		wsets[i].ws.lset = tmp_lset + TBITSET * i;
    187 	tmp_lset = NULL;
    188 
    189 	clset.lset = malloc(sizeof (int)*TBITSET);
    190 	tstates = malloc(sizeof (int)*(ntoksz + 1));
    191 	ntstates = malloc(sizeof (int)*(nnontersz + 1));
    192 	temp1 = malloc(sizeof (int)*size);
    193 	pres = malloc(sizeof (int **)*(nnontersz + 2));
    194 	pfirst = malloc(sizeof (LOOKSETS *)*(nnontersz + 2));
    195 	pempty = malloc(sizeof (int)*(nnontersz + 1));
    196 
    197 	pstate = malloc(sizeof (ITEM *)*(nstatesz+2));
    198 	tystate = malloc(sizeof (int)*nstatesz);
    199 	indgo = malloc(sizeof (int)*nstatesz);
    200 	mstates = malloc(sizeof (int)*nstatesz);
    201 	defact = malloc(sizeof (int)*nstatesz);
    202 
    203 	if ((lkst == NULL) || (wsets == NULL) || (tstates == NULL) ||
    204 	    (ntstates == NULL) || (temp1 == NULL) || (pres == NULL) ||
    205 	    (pfirst == NULL) || (pempty == NULL) || (pstate == NULL) ||
    206 	    (tystate == NULL) || (indgo == NULL) || (mstates == NULL) ||
    207 	    (defact == NULL) || (clset.lset == NULL))
    208 			error("cannot allocate tables in mktbls()");
    209 
    210 	aryfil(ntstates, nnontersz+1, 0);
    211 	aryfil(tstates, ntoksz+1, 0);
    212 	wsetsz = nnontersz + 1;
    213 	lsetsize = INIT_LSIZE + 1;
    214 }
    215 
    216 /* put out other arrays, copy the parsers */
    217 static void 
    218 others(void)
    219 {
    220 	extern int gen_lines;
    221 	register int c, i, j;
    222 	int tmpline;
    223 
    224 	/* This  routine has been "stolen" from the driver */
    225 	if (parser == NULL)
    226 		parser = PARSER;
    227 
    228 	finput = fopen(parser, "r");
    229 	if (finput == NULL)
    230 		error("cannot find parser %s", parser);
    231 
    232 	warray(L"yyr1", levprd, nprod);
    233 
    234 	aryfil(temp1, nprod, 0);
    235 					/* had_act[i] is either 1 or 0 */
    236 	PLOOP(1, i)
    237 		temp1[i] = ((prdptr[i+1] - prdptr[i]-2) << 1) | had_act[i];
    238 	warray(L"yyr2", temp1, nprod);
    239 
    240 	aryfil(temp1, nstate, -10000000);
    241 	TLOOP(i)
    242 		for (j = tstates[i]; j != 0; j = mstates[j])
    243 			temp1[j] = tokset[i].value;
    244 	NTLOOP(i)
    245 		for (j = ntstates[i]; j != 0; j = mstates[j])
    246 			temp1[j] = -i;
    247 	warray(L"yychk", temp1, nstate);
    248 
    249 	warray(L"yydef", defact, nstate);
    250 
    251 	if ((fdebug = fopen(DEBUGNAME, "r")) == NULL)
    252 		error("cannot open yacc.debug");
    253 	while ((c = getwc(fdebug)) != EOF)
    254 		putwc(c, ftable);
    255 	fclose(fdebug);
    256 	ZAPFILE(DEBUGNAME);
    257 
    258 	if (gen_lines)
    259 		fprintf(ftable, "# line\t1 \"%s\"\n", parser);
    260 	tmpline = 1;
    261 	/* copy parser text */
    262 	while ((c = getwc(finput)) != EOF) {
    263 		if (c == '\n')
    264 			tmpline++;
    265 		if (c == L'$') {
    266 			if ((c = getwc(finput)) != L'A')
    267 				putwc(L'$', ftable);
    268 			else { /* copy actions */
    269 				tmpline++;
    270 				faction = fopen(ACTNAME, "r");
    271 				if (faction == NULL)
    272 					error("cannot open action tempfile");
    273 				while ((c = getwc(faction)) != EOF)
    274 					putwc(c, ftable);
    275 				fclose(faction);
    276 				if (gen_lines)
    277 					fprintf(ftable,
    278 						"\n# line\t%d \"%s\"",
    279 						tmpline,
    280 						parser);
    281 				ZAPFILE(ACTNAME);
    282 				c = getwc(finput);
    283 			}
    284 		}
    285 		putwc(c, ftable);
    286 	}
    287 	fclose(ftable);
    288 }
    289 
    290 
    291 /* copies string q into p, returning next free char ptr */
    292 static wchar_t *
    293 chcopy(wchar_t *p, wchar_t *q)
    294 {
    295 	while (*p = *q++)
    296 		++p;
    297 	return (p);
    298 }
    299 
    300 #define	ISIZE 400
    301 /* creates output string for item pointed to by pp */
    302 wchar_t *
    303 writem(int *pp)
    304 {
    305 	int i, *p;
    306 	static int isize = ISIZE;
    307 	static wchar_t *sarr = NULL;
    308 	wchar_t *q;
    309 
    310 	if (sarr == NULL) {
    311 		sarr = malloc(sizeof (wchar_t) * isize);
    312 		if (sarr == NULL)
    313 			error("could not allocate output string array");
    314 		for (i = 0; i < isize; ++i)
    315 			sarr[i] = L' ';
    316 	}
    317 	for (p = pp; *p > 0; ++p) /* EMPTY */;
    318 	p = prdptr[-*p];
    319 	q = chcopy(sarr, nontrst[*p-NTBASE].name);
    320 	q = chcopy(q, L" : ");
    321 
    322 	for (;;) {
    323 		*q++ = ++p == pp ? L'_' : L' ';
    324 		*q = 0;
    325 		if ((i = *p) <= 0)
    326 			break;
    327 		q = chcopy(q, symnam(i));
    328 		while (q > &sarr[isize-30]) {
    329 			static wchar_t *sarrbase;
    330 
    331 			sarrbase = sarr;
    332 			isize += ISIZE;
    333 			sarr = realloc(sarr, sizeof (*sarr) * isize);
    334 			if (sarr == NULL)
    335 				error("cannot expand sarr arrays");
    336 			q = q - sarrbase + sarr;
    337 		}
    338 	}
    339 
    340 	/* an item calling for a reduction */
    341 	if ((i = *pp) < 0) {
    342 		q = chcopy(q, L"    (");
    343 		swprintf(q, q + isize - sarr, L"%d)", -i);
    344 	}
    345 	return (sarr);
    346 }
    347 
    348 /* return a pointer to the name of symbol i */
    349 wchar_t *
    350 symnam(int i)
    351 {
    352 	wchar_t *cp;
    353 
    354 	cp = (i >= NTBASE) ? nontrst[i-NTBASE].name : tokset[i].name;
    355 	if (*cp == L' ')
    356 		++cp;
    357 	return (cp);
    358 }
    359 
    360 static int zzcwp = 0;
    361 static int zzclose = 0;
    362 int zzgoent = 0;
    363 int zzgobest = 0;
    364 int zzacent = 0;
    365 int zzexcp = 0;
    366 int zzsrconf = 0;
    367 int zzrrconf = 0;
    368 
    369 /* output the summary on the tty */
    370 static void 
    371 summary(void)
    372 {
    373 	if (foutput != NULL) {
    374 		fprintf(foutput,
    375 			"\n%d/%d terminals, %d/%d nonterminals\n",
    376 			ntokens, ntoksz, nnonter, nnontersz);
    377 		fprintf(foutput,
    378 			"%d/%d grammar rules, %d/%d states\n",
    379 			nprod, nprodsz, nstate, nstatesz);
    380 		fprintf(foutput,
    381 		"%d shift/reduce, %d reduce/reduce conflicts reported\n",
    382 			zzsrconf, zzrrconf);
    383 		fprintf(foutput,
    384 			"%d/%d working sets used\n", zzcwp, wsetsz);
    385 		fprintf(foutput,
    386 			"memory: states,etc. %d/%d, parser %d/%d\n",
    387 			mem-tracemem, new_memsize, memp-amem, new_actsize);
    388 		fprintf(foutput,
    389 			"%d/%d distinct lookahead sets\n", nlset, lsetsize);
    390 		fprintf(foutput,
    391 			"%d extra closures\n", zzclose - 2*nstate);
    392 		fprintf(foutput,
    393 			"%d shift entries, %d exceptions\n", zzacent, zzexcp);
    394 		fprintf(foutput,
    395 			"%d goto entries\n", zzgoent);
    396 		fprintf(foutput,
    397 			"%d entries saved by goto default\n", zzgobest);
    398 	}
    399 	if (zzsrconf != 0 || zzrrconf != 0) {
    400 		fprintf(stderr, "\nconflicts: ");
    401 		if (zzsrconf)
    402 			fprintf(stderr, "%d shift/reduce", zzsrconf);
    403 		if (zzsrconf && zzrrconf)
    404 			fprintf(stderr, ", ");
    405 		if (zzrrconf)
    406 			fprintf(stderr, "%d reduce/reduce", zzrrconf);
    407 		fprintf(stderr, "\n");
    408 	}
    409 
    410 	if (ftemp != NULL)
    411 		fclose(ftemp);
    412 	if (fdefine != NULL)
    413 		fclose(fdefine);
    414 }
    415 
    416 /* write out error comment */
    417 void
    418 error(char *s, ...)
    419 {
    420 	extern char *infile;
    421 	va_list	ap;
    422 
    423 	va_start(ap, s);
    424 
    425 	++nerrors;
    426 	if (!lineno)
    427 		fprintf(stderr, "command line: fatal: ");
    428 	else {
    429 		fprintf(stderr, "\"%s\", ", infile);
    430 		fprintf(stderr, "line %d: fatal: ", lineno);
    431 	}
    432 	vfprintf(stderr, s, ap);
    433 	fprintf(stderr, "\n");
    434 	va_end(ap);
    435 	if (!fatfl)
    436 		return;
    437 	summary();
    438 	exit(1);
    439 }
    440 
    441 /*
    442  * Print out a warning message.
    443  */
    444 void
    445 warning(int flag, char *s, ...)
    446 {
    447 	extern char *infile;
    448 	va_list	ap;
    449 	va_start(ap, s);
    450 
    451 	fprintf(stderr, "\"%s\", ", infile);
    452 	/*
    453 	 * If flag, print lineno as well.
    454 	 */
    455 	if (flag == 0)
    456 		fprintf(stderr, "warning: ");
    457 	else
    458 		fprintf(stderr, "line %d: warning: ", lineno);
    459 	vfprintf(stderr, s, ap);
    460 	fprintf(stderr, "\n");
    461 	va_end(ap);
    462 }
    463 
    464 /* set elements 0 through n-1 to c */
    465 void 
    466 aryfil(int *v, int n, int c)
    467 {
    468 	int i;
    469 	for (i = 0; i < n; ++i)
    470 		v[i] = c;
    471 }
    472 
    473 /* set a to the union of a and b */
    474 /* return 1 if b is not a subset of a, 0 otherwise */
    475 static int
    476 setunion(register int *a, register int *b)
    477 {
    478 	register int i, x, sub;
    479 
    480 	sub = 0;
    481 	SETLOOP(i) {
    482 		*a = (x = *a) | *b++;
    483 		if (*a++ != x)
    484 			sub = 1;
    485 	}
    486 	return (sub);
    487 }
    488 
    489 static void 
    490 prlook(LOOKSETS *p)
    491 {
    492 	register int j, *pp;
    493 	pp = p->lset;
    494 	if (pp == 0)
    495 		fprintf(foutput, "\tNULL");
    496 	else {
    497 		fprintf(foutput, " { ");
    498 		TLOOP(j) {
    499 			if (BIT(pp, j))
    500 				fprintf(foutput,  "%ls ", symnam(j));
    501 		}
    502 		fprintf(foutput,  "}");
    503 	}
    504 }
    505 
    506 /*
    507  * compute an array with the beginnings of  productions yielding
    508  * given nonterminals
    509  * The array pres points to these lists
    510  * the array pyield has the lists: the total size is only NPROD+1
    511  */
    512 static void 
    513 cpres(void)
    514 {
    515 	register int **ptrpy;
    516 	int **pyield;
    517 	register int c, j, i;
    518 
    519 	/*
    520 	 * 2/29/88 -
    521 	 * nprodsz is the size of the tables describing the productions.
    522 	 * Normally this will be NPROD unless the production tables have
    523 	 * been expanded, in which case the tables will be NPROD * N(where
    524 	 * N is the number of times the tables had to be expanded.)
    525 	 */
    526 	if ((pyield = malloc(sizeof (int *) * nprodsz)) == NULL)
    527 		error("cannot allocate space for pyield array");
    528 
    529 	ptrpy = pyield;
    530 
    531 	NTLOOP(i) {
    532 		c = i+NTBASE;
    533 		pres[i] = ptrpy;
    534 		fatfl = 0;  /* make undefined  symbols  nonfatal */
    535 		PLOOP(0, j) {
    536 			if (*prdptr[j] == c)  	/* linear search for all c's */
    537 				*ptrpy++ =  prdptr[j] + 1;
    538 		}
    539 		if (pres[i] == ptrpy) { 		/* c not found */
    540 			error("undefined nonterminal: %ls", nontrst[i].name);
    541 		}
    542 	}
    543 	pres[i] = ptrpy;
    544 	fatfl = 1;
    545 	if (nerrors) {
    546 		summary();
    547 		exit(1);
    548 	}
    549 	if (ptrpy != &pyield[nprod])
    550 		error("internal Yacc error: pyield %d", ptrpy-&pyield[nprod]);
    551 }
    552 
    553 static int indebug = 0;
    554 /* compute an array with the first of nonterminals */
    555 static void 
    556 cpfir(void)
    557 {
    558 	register int *p, **s, i, **t, ch, changes;
    559 
    560 	zzcwp = nnonter;
    561 	NTLOOP(i) {
    562 		aryfil(wsets[i].ws.lset, tbitset, 0);
    563 		t = pres[i+1];
    564 		/* initially fill the sets */
    565 		for (s = pres[i]; s < t; ++s) {
    566 			/* check if ch is non-terminal */
    567 			for (p = *s; (ch = *p) > 0; ++p) {
    568 				if (ch < NTBASE) { 	/* should be token */
    569 					SETBIT(wsets[i].ws.lset, ch);
    570 					break;
    571 				} else if (!pempty[ch-NTBASE])
    572 					break;
    573 			}
    574 		}
    575 	}
    576 
    577 	/* now, reflect transitivity */
    578 
    579 	changes = 1;
    580 	while (changes) {
    581 		changes = 0;
    582 		NTLOOP(i) {
    583 			t = pres[i+1];
    584 			for (s = pres[i]; s < t; ++s) {
    585 				for (p = *s; (ch = (*p-NTBASE)) >= 0; ++p) {
    586 					changes |= setunion(wsets[i].ws.lset,
    587 							wsets[ch].ws.lset);
    588 					if (!pempty[ch])
    589 						break;
    590 				}
    591 			}
    592 		}
    593 	}
    594 
    595 	NTLOOP(i)
    596 		pfirst[i] = flset(&wsets[i].ws);
    597 	if (!indebug)
    598 		return;
    599 	if ((foutput != NULL)) {
    600 		NTLOOP(i) {
    601 			fprintf(foutput, "\n%ls: ", nontrst[i].name);
    602 			prlook(pfirst[i]);
    603 			fprintf(foutput, " %d\n", pempty[i]);
    604 		}
    605 	}
    606 }
    607 
    608 /* sorts last state,and sees if it equals earlier ones. returns state number */
    609 int
    610 state(int c)
    611 {
    612 	int size1, size2;
    613 	register int i;
    614 	ITEM *p1, *p2, *k, *l, *q1, *q2;
    615 	p1 = pstate[nstate];
    616 	p2 = pstate[nstate+1];
    617 	if (p1 == p2)
    618 		return (0); /* null state */
    619 	/* sort the items */
    620 	for (k = p2 - 1; k > p1; k--) {	/* make k the biggest */
    621 		for (l = k-1; l >= p1; --l)
    622 			if (l->pitem > k->pitem) {
    623 				int *s;
    624 				LOOKSETS *ss;
    625 				s = k->pitem;
    626 				k->pitem = l->pitem;
    627 				l->pitem = s;
    628 				ss = k->look;
    629 				k->look = l->look;
    630 				l->look = ss;
    631 			}
    632 	}
    633 	size1 = p2 - p1; /* size of state */
    634 
    635 	for (i = (c >= NTBASE) ? ntstates[c-NTBASE] : tstates[c];
    636 			i != 0;
    637 			i = mstates[i]) {
    638 		/* get ith state */
    639 		q1 = pstate[i];
    640 		q2 = pstate[i+1];
    641 		size2 = q2 - q1;
    642 		if (size1 != size2)
    643 			continue;
    644 		k = p1;
    645 		for (l = q1; l < q2; l++) {
    646 			if (l->pitem != k->pitem)
    647 				break;
    648 			++k;
    649 		}
    650 		if (l != q2)
    651 			continue;
    652 		/* found it */
    653 		pstate[nstate+1] = pstate[nstate]; /* delete last state */
    654 		/* fix up lookaheads */
    655 		if (nolook)
    656 			return (i);
    657 		for (l = q1, k = p1; l < q2; ++l, ++k) {
    658 			int s;
    659 			SETLOOP(s)
    660 				clset.lset[s] = l->look->lset[s];
    661 			if (setunion(clset.lset, k->look->lset)) {
    662 				tystate[i] = MUSTDO;
    663 				/* register the new set */
    664 				l->look = flset(&clset);
    665 			}
    666 		}
    667 		return (i);
    668 	}
    669 	/* state is new */
    670 	if (nolook)
    671 		error("yacc state/nolook error");
    672 	pstate[nstate+2] = p2;
    673 	if (nstate+1 >= nstatesz)
    674 		exp_states();
    675 	if (c >= NTBASE) {
    676 		mstates[nstate] = ntstates[c - NTBASE];
    677 		ntstates[c - NTBASE] = nstate;
    678 	} else {
    679 		mstates[nstate] = tstates[c];
    680 		tstates[c] = nstate;
    681 	}
    682 	tystate[nstate] = MUSTDO;
    683 	return (nstate++);
    684 }
    685 
    686 static int pidebug = 0;
    687 
    688 void 
    689 putitem(int *ptr, LOOKSETS *lptr)
    690 {
    691 	register ITEM *j;
    692 
    693 	if (pidebug && (foutput != NULL))
    694 		fprintf(foutput,
    695 			"putitem(%ls), state %d\n", writem(ptr), nstate);
    696 	j = pstate[nstate+1];
    697 	j->pitem = ptr;
    698 	if (!nolook)
    699 		j->look = flset(lptr);
    700 	pstate[nstate+1] = ++j;
    701 	if (j > zzmemsz) {
    702 		zzmemsz = j;
    703 		if (zzmemsz >=  &psmem[new_pstsize])
    704 			exp_psmem();
    705 			/* error("out of state space"); */
    706 	}
    707 }
    708 
    709 /*
    710  * mark nonterminals which derive the empty string
    711  * also, look for nonterminals which don't derive any token strings
    712  */
    713 static void 
    714 cempty(void)
    715 {
    716 #define	EMPTY 1
    717 #define	WHOKNOWS 0
    718 #define	OK 1
    719 	register int i, *p;
    720 
    721 	/*
    722 	 * first, use the array pempty to detect productions
    723 	 * that can never be reduced
    724 	 */
    725 
    726 	/* set pempty to WHONOWS */
    727 	aryfil(pempty, nnonter+1, WHOKNOWS);
    728 
    729 	/*
    730 	 * now, look at productions, marking nonterminals which
    731 	 * derive something
    732 	 */
    733 	more:
    734 	PLOOP(0, i) {
    735 		if (pempty[*prdptr[i] - NTBASE])
    736 			continue;
    737 		for (p = prdptr[i] + 1; *p >= 0; ++p)
    738 			if (*p >= NTBASE && pempty[*p-NTBASE] == WHOKNOWS)
    739 				break;
    740 		if (*p < 0) { /* production can be derived */
    741 			pempty[*prdptr[i]-NTBASE] = OK;
    742 			goto more;
    743 		}
    744 	}
    745 
    746 	/* now, look at the nonterminals, to see if they are all OK */
    747 
    748 	NTLOOP(i) {
    749 		/*
    750 		 * the added production rises or falls as the
    751 		 * start symbol ...
    752 		 */
    753 		if (i == 0)
    754 			continue;
    755 		if (pempty[i] != OK) {
    756 			fatfl = 0;
    757 			error("nonterminal %ls never derives any token string",
    758 			nontrst[i].name);
    759 		}
    760 	}
    761 
    762 	if (nerrors) {
    763 		summary();
    764 		exit(1);
    765 	}
    766 
    767 	/*
    768 	 * now, compute the pempty array, to see which nonterminals
    769 	 * derive the empty string
    770 	 */
    771 
    772 	/* set pempty to WHOKNOWS */
    773 
    774 	aryfil(pempty, nnonter+1, WHOKNOWS);
    775 
    776 	/* loop as long as we keep finding empty nonterminals */
    777 
    778 again:
    779 	PLOOP(1, i) {
    780 		/* not known to be empty */
    781 		if (pempty[*prdptr[i]-NTBASE] == WHOKNOWS) {
    782 			for (p = prdptr[i]+1;
    783 				*p >= NTBASE && pempty[*p-NTBASE] == EMPTY;
    784 				++p);
    785 			/* we have a nontrivially empty nonterminal */
    786 			if (*p < 0) {
    787 				pempty[*prdptr[i]-NTBASE] = EMPTY;
    788 				goto again; /* got one ... try for another */
    789 			}
    790 		}
    791 	}
    792 }
    793 
    794 /* generate the states */
    795 static int gsdebug = 0;
    796 static void 
    797 stagen(void)
    798 {
    799 	int i, j;
    800 	register int c;
    801 	register WSET *p, *q;
    802 
    803 	/* initialize */
    804 
    805 	nstate = 0;
    806 
    807 	pstate[0] = pstate[1] = psmem;
    808 	aryfil(clset.lset, tbitset, 0);
    809 	putitem(prdptr[0] + 1, &clset);
    810 	tystate[0] = MUSTDO;
    811 	nstate = 1;
    812 	pstate[2] = pstate[1];
    813 
    814 	aryfil(amem, new_actsize, 0);
    815 
    816 	/* now, the main state generation loop */
    817 
    818 	more:
    819 	SLOOP(i) {
    820 		if (tystate[i] != MUSTDO)
    821 			continue;
    822 		tystate[i] = DONE;
    823 		aryfil(temp1, nnonter + 1, 0);
    824 		/* take state i, close it, and do gotos */
    825 		closure(i);
    826 		WSLOOP(wsets, p) { /* generate goto's */
    827 			if (p->flag)
    828 				continue;
    829 			p->flag = 1;
    830 			c = *(p->pitem);
    831 			if (c <= 1) {
    832 				if (pstate[i+1]-pstate[i] <= p-wsets)
    833 					tystate[i] = MUSTLOOKAHEAD;
    834 				continue;
    835 			}
    836 			/* do a goto on c */
    837 			WSLOOP(p, q) {
    838 				/* this item contributes to the goto */
    839 				if (c == *(q->pitem)) {
    840 					putitem(q->pitem + 1, &q->ws);
    841 					q->flag = 1;
    842 				}
    843 			}
    844 			if (c < NTBASE)
    845 				state(c);  /* register new state */
    846 			else temp1[c-NTBASE] = state(c);
    847 		}
    848 		if (gsdebug && (foutput != NULL)) {
    849 			fprintf(foutput,  "%d: ", i);
    850 			NTLOOP(j) {
    851 				if (temp1[j])
    852 					fprintf(foutput,
    853 						"%ls %d, ", nontrst[j].name,
    854 						temp1[j]);
    855 			}
    856 			fprintf(foutput, "\n");
    857 		}
    858 		indgo[i] = apack(&temp1[1], nnonter - 1) - 1;
    859 		goto more; /* we have done one goto; do some more */
    860 	}
    861 	/* no more to do... stop */
    862 }
    863 
    864 /* generate the closure of state i */
    865 static int cldebug = 0; /* debugging flag for closure */
    866 void 
    867 closure(int i)
    868 {
    869 	int c, ch, work, k;
    870 	register WSET *u, *v;
    871 	int *pi;
    872 	int **s, **t;
    873 	ITEM *q;
    874 	register ITEM *p;
    875 	int idx1 = 0;
    876 
    877 	++zzclose;
    878 
    879 	/* first, copy kernel of state i to wsets */
    880 	cwp = 0;
    881 	ITMLOOP(i, p, q) {
    882 		wsets[cwp].pitem = p->pitem;
    883 		wsets[cwp].flag = 1;    /* this item must get closed */
    884 		SETLOOP(k)
    885 			wsets[cwp].ws.lset[k] = p->look->lset[k];
    886 		WSBUMP(cwp);
    887 	}
    888 
    889 	/* now, go through the loop, closing each item */
    890 
    891 	work = 1;
    892 	while (work) {
    893 		work = 0;
    894 		/*
    895 		 * WSLOOP(wsets, u) {
    896 		 */
    897 		for (idx1 = 0; idx1 < cwp; idx1++) {
    898 			u = &wsets[idx1];
    899 			if (u->flag == 0)
    900 				continue;
    901 			c = *(u->pitem);  /* dot is before c */
    902 			if (c < NTBASE) {
    903 				u->flag = 0;
    904 				/*
    905 				 * only interesting case is where . is
    906 				 * before nonterminal
    907 				 */
    908 				continue;
    909 			}
    910 
    911 			/* compute the lookahead */
    912 			aryfil(clset.lset, tbitset, 0);
    913 
    914 			/* find items involving c */
    915 
    916 			WSLOOP(u, v) {
    917 				if (v->flag == 1 && *(pi = v->pitem) == c) {
    918 					v->flag = 0;
    919 					if (nolook)
    920 						continue;
    921 					while ((ch = *++pi) > 0) {
    922 						/* terminal symbol */
    923 						if (ch < NTBASE) {
    924 							SETBIT(clset.lset, ch);
    925 							break;
    926 						}
    927 						/* nonterminal symbol */
    928 						setunion(clset.lset,
    929 						pfirst[ch-NTBASE]->lset);
    930 						if (!pempty[ch-NTBASE])
    931 							break;
    932 					}
    933 					if (ch <= 0)
    934 						setunion(clset.lset,
    935 								v->ws.lset);
    936 				}
    937 			}
    938 
    939 			/*  now loop over productions derived from c */
    940 
    941 			c -= NTBASE; /* c is now nonterminal number */
    942 
    943 			t = pres[c+1];
    944 			for (s = pres[c]; s < t; ++s) {
    945 				/* put these items into the closure */
    946 				WSLOOP(wsets, v) { /* is the item there */
    947 					/* yes, it is there */
    948 					if (v->pitem == *s) {
    949 						if (nolook)
    950 							goto nexts;
    951 						if (setunion(v->ws.lset,
    952 							clset.lset))
    953 							v->flag = work = 1;
    954 						goto nexts;
    955 					}
    956 				}
    957 
    958 				/*  not there; make a new entry */
    959 				if (cwp + 1 >= wsetsz)
    960 					exp_wsets();
    961 
    962 				wsets[cwp].pitem = *s;
    963 				wsets[cwp].flag = 1;
    964 				if (!nolook) {
    965 					work = 1;
    966 					SETLOOP(k)
    967 						wsets[cwp].ws.lset[k] =
    968 							clset.lset[k];
    969 				}
    970 				WSBUMP(cwp);
    971 				nexts:;
    972 			}
    973 		}
    974 	}
    975 
    976 	/* have computed closure; flags are reset; return */
    977 
    978 	if (&wsets[cwp] > &wsets[zzcwp])
    979 		zzcwp = cwp;
    980 	if (cldebug && (foutput != NULL)) {
    981 		fprintf(foutput, "\nState %d, nolook = %d\n", i, nolook);
    982 		WSLOOP(wsets, u) {
    983 			if (u->flag)
    984 				fprintf(foutput, "flag set!\n");
    985 			u->flag = 0;
    986 			fprintf(foutput, "\t%ls", writem(u->pitem));
    987 			prlook(&u->ws);
    988 			fprintf(foutput,  "\n");
    989 		}
    990 	}
    991 }
    992 
    993 static LOOKSETS *
    994 flset(LOOKSETS *p)
    995 {
    996 	/* decide if the lookahead set pointed to by p is known */
    997 	/* return pointer to a perminent location for the set */
    998 
    999 	int j, *w;
   1000 	register int *u, *v;
   1001 	register LOOKSETS *q;
   1002 
   1003 	for (q = &lkst[nlset]; q-- > lkst; ) {
   1004 		u = p->lset;
   1005 		v = q->lset;
   1006 		w = & v[tbitset];
   1007 		while (v < w)
   1008 			if (*u++ != *v++)
   1009 				goto more;
   1010 		/* we have matched */
   1011 		return (q);
   1012 		more:;
   1013 	}
   1014 	/* add a new one */
   1015 	q = &lkst[nlset++];
   1016 	if (nlset >= lsetsize) {
   1017 		exp_lkst();
   1018 		q = &lkst[nlset++];
   1019 	}
   1020 	SETLOOP(j) q->lset[j] = p->lset[j];
   1021 	return (q);
   1022 }
   1023 
   1024 static void 
   1025 exp_lkst(void)
   1026 {
   1027 	int i, j;
   1028 	static LOOKSETS *lookbase;
   1029 
   1030 	lookbase = lkst;
   1031 	lsetsize += LSETSIZE;
   1032 	tmp_lset = calloc(TBITSET * (lsetsize-LSETSIZE), sizeof (int));
   1033 	if (tmp_lset == NULL)
   1034 		error("could not expand lookset array");
   1035 	lkst = realloc(lkst, sizeof (LOOKSETS) * lsetsize);
   1036 	for (i = lsetsize-LSETSIZE, j = 0; i < lsetsize; ++i, ++j)
   1037 		lkst[i].lset = tmp_lset + TBITSET * j;
   1038 	tmp_lset = NULL;
   1039 	if (lkst == NULL)
   1040 		error("could not expand lookahead sets");
   1041 	for (i = 0; i <= nnonter; ++i)
   1042 		pfirst[i] = pfirst[i] - lookbase + lkst;
   1043 	for (i = 0; i <= nstate+1; ++i) {
   1044 		if (psmem[i].look)
   1045 			psmem[i].look = psmem[i].look - lookbase + lkst;
   1046 		if (pstate[i]->look)
   1047 			pstate[i]->look = pstate[i]->look - lookbase + lkst;
   1048 	}
   1049 }
   1050 
   1051 static void 
   1052 exp_wsets(void)
   1053 {
   1054 	int i, j;
   1055 
   1056 	wsetsz += WSETSIZE;
   1057 	tmp_lset = calloc(TBITSET * (wsetsz-WSETSIZE), sizeof (int));
   1058 	if (tmp_lset == NULL)
   1059 		error("could not expand lookset array");
   1060 	wsets = realloc(wsets, sizeof (WSET) * wsetsz);
   1061 	for (i = wsetsz-WSETSIZE, j = 0; i < wsetsz; ++i, ++j)
   1062 		wsets[i].ws.lset = tmp_lset + TBITSET * j;
   1063 	tmp_lset = NULL;
   1064 	if (wsets == NULL)
   1065 		error("could not expand working sets");
   1066 }
   1067 
   1068 static void 
   1069 exp_states(void)
   1070 {
   1071 	nstatesz += NSTATES;
   1072 
   1073 	pstate = realloc(pstate, sizeof (ITEM *)*(nstatesz+2));
   1074 	mstates = realloc(mstates, sizeof (int)*nstatesz);
   1075 	defact = realloc(defact, sizeof (int)*nstatesz);
   1076 	tystate = realloc(tystate, sizeof (int)*nstatesz);
   1077 	indgo = realloc(indgo, sizeof (int)*nstatesz);
   1078 
   1079 	if ((*pstate == NULL) || (tystate == NULL) || (defact == NULL) ||
   1080 		(indgo == NULL) || (mstates == NULL))
   1081 		error("cannot expand table of states");
   1082 }
   1083 
   1084 static void 
   1085 exp_psmem(void)
   1086 {
   1087 	int i;
   1088 
   1089 	new_pstsize += PSTSIZE;
   1090 	psmem = realloc(psmem, sizeof (ITEM) * new_pstsize);
   1091 	if (psmem == NULL)
   1092 		error("cannot expand pstate memory");
   1093 
   1094 	zzmemsz = zzmemsz - pstate[0] + psmem;
   1095 	for (i = 1; i <= nstate+1; ++i)
   1096 		pstate[i] = pstate[i] - pstate[0] + psmem;
   1097 	pstate[0] = psmem;
   1098 }