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