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