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