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