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