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, "%ws ", symnam(j)); 596 } 597 (void) fprintf(foutput, "}"); 598 } 599 } 600 601 /* 602 * compute an array with the beginnings of productions yielding 603 * given nonterminals 604 * The array pres points to these lists 605 * the array pyield has the lists: the total size is only NPROD+1 606 */ 607 static void 608 cpres(void) 609 { 610 int **ptrpy; 611 int **pyield; 612 int c, j, i; 613 614 /* 615 * 2/29/88 - 616 * nprodsz is the size of the tables describing the productions. 617 * Normally this will be NPROD unless the production tables have 618 * been expanded, in which case the tables will be NPROD * N(where 619 * N is the number of times the tables had to be expanded.) 620 */ 621 if ((pyield = (int **) malloc(sizeof (int *) * nprodsz)) == NULL) 622 /* 623 * TRANSLATION_NOTE -- This is a message from yacc. 624 * This message is passed to error() function. 625 * This error is issued when yacc could not allocate 626 * memory for internally used array. 627 * 628 * pyield is name of an array. You should not try to translate 629 * this word. 630 * 631 * You may just translate this as: 632 * 'Could not allocate internally used memory.' 633 */ 634 error(gettext( 635 "cannot allocate space for pyield array")); 636 637 ptrpy = pyield; 638 639 NTLOOP(i) { 640 c = i+NTBASE; 641 pres[i] = ptrpy; 642 fatfl = 0; /* make undefined symbols nonfatal */ 643 PLOOP(0, j) { 644 if (*prdptr[j] == c) /* linear search for all c's */ 645 *ptrpy++ = prdptr[j] + 1; 646 } 647 if (pres[i] == ptrpy) { /* c not found */ 648 /* 649 * TRANSLATION_NOTE -- This is a message from yacc. 650 * This message is passed to error() function. 651 * Ask somebody who knows yacc how to translate nonterminal or 652 * look at translated yacc document. 653 */ 654 error(gettext( 655 "undefined nonterminal: %ws"), 656 nontrst[i].name); 657 } 658 } 659 pres[i] = ptrpy; 660 fatfl = 1; 661 if (nerrors) { 662 summary(); 663 exit(1); 664 } 665 if (ptrpy != &pyield[nprod]) 666 /* 667 * TRANSLATION_NOTE -- This is a message from yacc. 668 * This message is passed to error() function. 669 * This is an internal error message. 670 * Very little use to user. You may leave it 671 * un-translated. 672 * 673 * pyied is name of an array. Do not translate it. 674 */ 675 error(gettext( 676 "internal Yacc error: pyield %d"), 677 ptrpy-&pyield[nprod]); 678 } 679 680 static int indebug = 0; 681 /* compute an array with the first of nonterminals */ 682 static void 683 cpfir(void) 684 { 685 int *p, **s, i, **t, ch, changes; 686 687 zzcwp = nnonter; 688 NTLOOP(i) { 689 aryfil(wsets[i].ws.lset, tbitset, 0); 690 t = pres[i+1]; 691 /* initially fill the sets */ 692 for (s = pres[i]; s < t; ++s) { 693 /* check if ch is non-terminal */ 694 for (p = *s; (ch = *p) > 0; ++p) { 695 if (ch < NTBASE) { /* should be token */ 696 SETBIT(wsets[i].ws.lset, ch); 697 break; 698 } else if (!pempty[ch-NTBASE]) 699 break; 700 } 701 } 702 } 703 704 /* now, reflect transitivity */ 705 706 changes = 1; 707 while (changes) { 708 changes = 0; 709 NTLOOP(i) { 710 t = pres[i+1]; 711 for (s = pres[i]; s < t; ++s) { 712 for (p = *s; (ch = (*p-NTBASE)) >= 0; ++p) { 713 changes |= setunion(wsets[i].ws.lset, 714 wsets[ch].ws.lset); 715 if (!pempty[ch]) 716 break; 717 } 718 } 719 } 720 } 721 722 NTLOOP(i) 723 pfirst[i] = flset(&wsets[i].ws); 724 if (!indebug) 725 return; 726 if ((foutput != NULL)) { 727 NTLOOP(i) { 728 (void) fprintf(foutput, "\n%ws: ", nontrst[i].name); 729 prlook(pfirst[i]); 730 (void) fprintf(foutput, " %d\n", pempty[i]); 731 } 732 } 733 } 734 735 /* sorts last state,and sees if it equals earlier ones. returns state number */ 736 int 737 state(int c) 738 { 739 int size1, size2; 740 int i; 741 ITEM *p1, *p2, *k, *l, *q1, *q2; 742 p1 = pstate[nstate]; 743 p2 = pstate[nstate+1]; 744 if (p1 == p2) 745 return (0); /* null state */ 746 /* sort the items */ 747 for (k = p2 - 1; k > p1; k--) { /* make k the biggest */ 748 for (l = k-1; l >= p1; --l) 749 if (l->pitem > k->pitem) { 750 int *s; 751 LOOKSETS *ss; 752 s = k->pitem; 753 k->pitem = l->pitem; 754 l->pitem = s; 755 ss = k->look; 756 k->look = l->look; 757 l->look = ss; 758 } 759 } 760 size1 = p2 - p1; /* size of state */ 761 762 for (i = (c >= NTBASE) ? ntstates[c-NTBASE] : tstates[c]; 763 i != 0; i = mstates[i]) { 764 /* get ith state */ 765 q1 = pstate[i]; 766 q2 = pstate[i+1]; 767 size2 = q2 - q1; 768 if (size1 != size2) 769 continue; 770 k = p1; 771 for (l = q1; l < q2; l++) { 772 if (l->pitem != k->pitem) 773 break; 774 ++k; 775 } 776 if (l != q2) 777 continue; 778 /* found it */ 779 pstate[nstate+1] = pstate[nstate]; /* delete last state */ 780 /* fix up lookaheads */ 781 if (nolook) 782 return (i); 783 for (l = q1, k = p1; l < q2; ++l, ++k) { 784 int s; 785 SETLOOP(s) 786 clset.lset[s] = l->look->lset[s]; 787 if (setunion(clset.lset, k->look->lset)) { 788 tystate[i] = MUSTDO; 789 /* register the new set */ 790 l->look = flset(&clset); 791 } 792 } 793 return (i); 794 } 795 /* state is new */ 796 if (nolook) 797 /* 798 * TRANSLATION_NOTE -- This is a message from yacc. 799 * This message is passed to error() function. 800 * You may leave this untranslated. Leave 801 * state/nolook un-translated. 802 */ 803 error(gettext( 804 "yacc state/nolook error")); 805 pstate[nstate+2] = p2; 806 if (nstate+1 >= nstatesz) 807 exp_states(); 808 if (c >= NTBASE) { 809 mstates[nstate] = ntstates[c - NTBASE]; 810 ntstates[c - NTBASE] = nstate; 811 } else { 812 mstates[nstate] = tstates[c]; 813 tstates[c] = nstate; 814 } 815 tystate[nstate] = MUSTDO; 816 return (nstate++); 817 } 818 819 static int pidebug = 0; 820 821 void 822 putitem(int *ptr, LOOKSETS *lptr) 823 { 824 register ITEM *j; 825 826 if (pidebug && (foutput != NULL)) 827 (void) fprintf(foutput, 828 "putitem(%ws), state %d\n", writem(ptr), nstate); 829 j = pstate[nstate+1]; 830 j->pitem = ptr; 831 if (!nolook) 832 j->look = flset(lptr); 833 pstate[nstate+1] = ++j; 834 if (j > zzmemsz) { 835 zzmemsz = j; 836 if (zzmemsz >= &psmem[new_pstsize]) 837 exp_psmem(); 838 /* error("out of state space"); */ 839 } 840 } 841 842 /* 843 * mark nonterminals which derive the empty string 844 * also, look for nonterminals which don't derive any token strings 845 */ 846 static void 847 cempty(void) 848 { 849 #define EMPTY 1 850 #define WHOKNOWS 0 851 #define OK 1 852 int i, *p; 853 854 /* 855 * first, use the array pempty to detect productions 856 * that can never be reduced 857 */ 858 859 /* set pempty to WHONOWS */ 860 aryfil(pempty, nnonter+1, WHOKNOWS); 861 862 /* 863 * now, look at productions, marking nonterminals which 864 * derive something 865 */ 866 more: 867 PLOOP(0, i) { 868 if (pempty[*prdptr[i] - NTBASE]) 869 continue; 870 for (p = prdptr[i] + 1; *p >= 0; ++p) 871 if (*p >= NTBASE && pempty[*p-NTBASE] == WHOKNOWS) 872 break; 873 if (*p < 0) { /* production can be derived */ 874 pempty[*prdptr[i]-NTBASE] = OK; 875 goto more; 876 } 877 } 878 879 /* now, look at the nonterminals, to see if they are all OK */ 880 881 NTLOOP(i) { 882 /* 883 * the added production rises or falls as the 884 * start symbol ... 885 */ 886 if (i == 0) 887 continue; 888 if (pempty[i] != OK) { 889 fatfl = 0; 890 /* 891 * TRANSLATION_NOTE -- This is a message from yacc. 892 * This message is passed to error() function. 893 * Ask somebody who knows yacc how to translate nonterminal or 894 * look at translated yacc document. Check how 'derive' is 895 * translated in these documents also. 896 */ 897 error(gettext( 898 "nonterminal %ws never derives any token string"), 899 nontrst[i].name); 900 } 901 } 902 903 if (nerrors) { 904 summary(); 905 exit(1); 906 } 907 908 /* 909 * now, compute the pempty array, to see which nonterminals 910 * derive the empty string 911 */ 912 913 /* set pempty to WHOKNOWS */ 914 915 aryfil(pempty, nnonter+1, WHOKNOWS); 916 917 /* loop as long as we keep finding empty nonterminals */ 918 919 again: 920 PLOOP(1, i) { 921 /* not known to be empty */ 922 if (pempty[*prdptr[i]-NTBASE] == WHOKNOWS) { 923 for (p = prdptr[i]+1; 924 *p >= NTBASE && pempty[*p-NTBASE] == EMPTY; ++p) 925 ; 926 /* we have a nontrivially empty nonterminal */ 927 if (*p < 0) { 928 pempty[*prdptr[i]-NTBASE] = EMPTY; 929 goto again; /* got one ... try for another */ 930 } 931 } 932 } 933 } 934 935 /* generate the states */ 936 static int gsdebug = 0; 937 static void 938 stagen(void) 939 { 940 int i, j; 941 int c; 942 register WSET *p, *q; 943 944 /* initialize */ 945 946 nstate = 0; 947 948 pstate[0] = pstate[1] = psmem; 949 aryfil(clset.lset, tbitset, 0); 950 putitem(prdptr[0] + 1, &clset); 951 tystate[0] = MUSTDO; 952 nstate = 1; 953 pstate[2] = pstate[1]; 954 955 aryfil(amem, new_actsize, 0); 956 957 /* now, the main state generation loop */ 958 959 more: 960 SLOOP(i) { 961 if (tystate[i] != MUSTDO) 962 continue; 963 tystate[i] = DONE; 964 aryfil(temp1, nnonter + 1, 0); 965 /* take state i, close it, and do gotos */ 966 closure(i); 967 WSLOOP(wsets, p) { /* generate goto's */ 968 if (p->flag) 969 continue; 970 p->flag = 1; 971 c = *(p->pitem); 972 if (c <= 1) { 973 if (pstate[i+1]-pstate[i] <= p-wsets) 974 tystate[i] = MUSTLOOKAHEAD; 975 continue; 976 } 977 /* do a goto on c */ 978 WSLOOP(p, q) { 979 /* this item contributes to the goto */ 980 if (c == *(q->pitem)) { 981 putitem(q->pitem + 1, &q->ws); 982 q->flag = 1; 983 } 984 } 985 if (c < NTBASE) 986 (void) state(c); /* register new state */ 987 else temp1[c-NTBASE] = state(c); 988 } 989 if (gsdebug && (foutput != NULL)) { 990 (void) fprintf(foutput, "%d: ", i); 991 NTLOOP(j) { 992 if (temp1[j]) 993 (void) fprintf(foutput, 994 "%ws %d, ", nontrst[j].name, 995 temp1[j]); 996 } 997 (void) fprintf(foutput, "\n"); 998 } 999 indgo[i] = apack(&temp1[1], nnonter - 1) - 1; 1000 goto more; /* we have done one goto; do some more */ 1001 } 1002 /* no more to do... stop */ 1003 } 1004 1005 /* generate the closure of state i */ 1006 static int cldebug = 0; /* debugging flag for closure */ 1007 1008 void 1009 closure(int i) 1010 { 1011 int c, ch, work, k; 1012 register WSET *u, *v; 1013 int *pi; 1014 int **s, **t; 1015 ITEM *q; 1016 register ITEM *p; 1017 int idx1 = 0; 1018 1019 ++zzclose; 1020 1021 /* first, copy kernel of state i to wsets */ 1022 cwp = 0; 1023 ITMLOOP(i, p, q) { 1024 wsets[cwp].pitem = p->pitem; 1025 wsets[cwp].flag = 1; /* this item must get closed */ 1026 SETLOOP(k) 1027 wsets[cwp].ws.lset[k] = p->look->lset[k]; 1028 WSBUMP(cwp); 1029 } 1030 1031 /* now, go through the loop, closing each item */ 1032 1033 work = 1; 1034 while (work) { 1035 work = 0; 1036 /* 1037 * WSLOOP(wsets, u) { 1038 */ 1039 for (idx1 = 0; idx1 < cwp; idx1++) { 1040 u = &wsets[idx1]; 1041 if (u->flag == 0) 1042 continue; 1043 c = *(u->pitem); /* dot is before c */ 1044 if (c < NTBASE) { 1045 u->flag = 0; 1046 /* 1047 * only interesting case is where . is 1048 * before nonterminal 1049 */ 1050 continue; 1051 } 1052 1053 /* compute the lookahead */ 1054 aryfil(clset.lset, tbitset, 0); 1055 1056 /* find items involving c */ 1057 1058 WSLOOP(u, v) { 1059 if (v->flag == 1 && *(pi = v->pitem) == c) { 1060 v->flag = 0; 1061 if (nolook) 1062 continue; 1063 while ((ch = *++pi) > 0) { 1064 /* terminal symbol */ 1065 if (ch < NTBASE) { 1066 SETBIT(clset.lset, ch); 1067 break; 1068 } 1069 /* nonterminal symbol */ 1070 (void) setunion(clset.lset, 1071 pfirst[ch-NTBASE]->lset); 1072 if (!pempty[ch-NTBASE]) 1073 break; 1074 } 1075 if (ch <= 0) 1076 (void) setunion(clset.lset, 1077 v->ws.lset); 1078 } 1079 } 1080 1081 /* now loop over productions derived from c */ 1082 1083 c -= NTBASE; /* c is now nonterminal number */ 1084 1085 t = pres[c+1]; 1086 for (s = pres[c]; s < t; ++s) { 1087 /* put these items into the closure */ 1088 WSLOOP(wsets, v) { /* is the item there */ 1089 /* yes, it is there */ 1090 if (v->pitem == *s) { 1091 if (nolook) 1092 goto nexts; 1093 if (setunion(v->ws.lset, 1094 clset.lset)) 1095 v->flag = work = 1; 1096 goto nexts; 1097 } 1098 } 1099 1100 /* not there; make a new entry */ 1101 if (cwp + 1 >= wsetsz) 1102 exp_wsets(); 1103 1104 wsets[cwp].pitem = *s; 1105 wsets[cwp].flag = 1; 1106 if (!nolook) { 1107 work = 1; 1108 SETLOOP(k) 1109 wsets[cwp].ws.lset[k] = 1110 clset.lset[k]; 1111 } 1112 WSBUMP(cwp); 1113 nexts:; 1114 } 1115 } 1116 } 1117 1118 /* have computed closure; flags are reset; return */ 1119 1120 if (&wsets[cwp] > &wsets[zzcwp]) 1121 zzcwp = cwp; 1122 if (cldebug && (foutput != NULL)) { 1123 (void) fprintf(foutput, "\nState %d, nolook = %d\n", i, nolook); 1124 WSLOOP(wsets, u) { 1125 if (u->flag) 1126 (void) fprintf(foutput, "flag set!\n"); 1127 u->flag = 0; 1128 (void) fprintf(foutput, "\t%ws", writem(u->pitem)); 1129 prlook(&u->ws); 1130 (void) fprintf(foutput, "\n"); 1131 } 1132 } 1133 } 1134 1135 static LOOKSETS * 1136 flset(LOOKSETS *p) 1137 { 1138 /* decide if the lookahead set pointed to by p is known */ 1139 /* return pointer to a perminent location for the set */ 1140 1141 int j, *w; 1142 int *u, *v; 1143 register LOOKSETS *q; 1144 1145 for (q = &lkst[nlset]; q-- > lkst; ) { 1146 u = p->lset; 1147 v = q->lset; 1148 w = & v[tbitset]; 1149 while (v < w) 1150 if (*u++ != *v++) 1151 goto more; 1152 /* we have matched */ 1153 return (q); 1154 more:; 1155 } 1156 /* add a new one */ 1157 q = &lkst[nlset++]; 1158 if (nlset >= lsetsize) { 1159 exp_lkst(); 1160 q = &lkst[nlset++]; 1161 } 1162 SETLOOP(j) q->lset[j] = p->lset[j]; 1163 return (q); 1164 } 1165 1166 static void 1167 exp_lkst(void) 1168 { 1169 int i, j; 1170 static LOOKSETS *lookbase; 1171 1172 lookbase = lkst; 1173 lsetsize += LSETSIZE; 1174 tmp_lset = (int *) 1175 calloc((size_t)(TBITSET * (lsetsize-LSETSIZE)), sizeof (int)); 1176 if (tmp_lset == NULL) 1177 /* 1178 * TRANSLATION_NOTE -- This is a message from yacc. 1179 * This message is passed to error() function. 1180 * Memory allocation error. Do not translate lookset. 1181 * 1182 * You may just translate this as: 1183 * 'Could not allocate internally used memory.' 1184 */ 1185 error(gettext( 1186 "could not expand lookset array")); 1187 lkst = (LOOKSETS *) realloc((char *)lkst, sizeof (LOOKSETS) * lsetsize); 1188 for (i = lsetsize-LSETSIZE, j = 0; i < lsetsize; ++i, ++j) 1189 lkst[i].lset = tmp_lset + TBITSET * j; 1190 tmp_lset = NULL; 1191 if (lkst == NULL) 1192 /* 1193 * TRANSLATION_NOTE -- This is a message from yacc. 1194 * This message is passed to error() function. 1195 * Memory allocation error. Do not translate lookset. 1196 * 1197 * You may just translate this as: 1198 * 'Could not allocate internally used memory.' 1199 */ 1200 error(gettext( 1201 "could not expand lookahead sets")); 1202 for (i = 0; i <= nnonter; ++i) 1203 pfirst[i] = pfirst[i] - lookbase + lkst; 1204 for (i = 0; i <= nstate+1; ++i) { 1205 if (psmem[i].look) 1206 psmem[i].look = psmem[i].look - lookbase + lkst; 1207 if (pstate[i]->look) 1208 pstate[i]->look = pstate[i]->look - lookbase + lkst; 1209 } 1210 } 1211 1212 static void 1213 exp_wsets(void) 1214 { 1215 int i, j; 1216 1217 wsetsz += WSETSIZE; 1218 tmp_lset = (int *) 1219 calloc((size_t)(TBITSET * (wsetsz-WSETSIZE)), sizeof (int)); 1220 if (tmp_lset == NULL) 1221 /* 1222 * TRANSLATION_NOTE -- This is a message from yacc. 1223 * This message is passed to error() function. 1224 * Memory allocation error. Do not translate lookset. 1225 * 1226 * You may just translate this as: 1227 * 'Could not allocate internally used memory.' 1228 */ 1229 error(gettext( 1230 "could not expand lookset array")); 1231 wsets = (WSET *) realloc((char *)wsets, sizeof (WSET) * wsetsz); 1232 for (i = wsetsz-WSETSIZE, j = 0; i < wsetsz; ++i, ++j) 1233 wsets[i].ws.lset = tmp_lset + TBITSET * j; 1234 tmp_lset = NULL; 1235 if (wsets == NULL) 1236 /* 1237 * TRANSLATION_NOTE -- This is a message from yacc. 1238 * This message is passed to error() function. 1239 * Memory allocation error. You may just transltate 1240 * this as 'Could not allocate internally used memory.' 1241 * 1242 * You may just translate this as: 1243 * 'Could not allocate internally used memory.' 1244 */ 1245 error(gettext( 1246 "could not expand working sets")); 1247 } 1248 1249 static void 1250 exp_states(void) 1251 { 1252 nstatesz += NSTATES; 1253 1254 pstate = (ITEM **) 1255 realloc((char *)pstate, sizeof (ITEM *)*(nstatesz+2)); 1256 mstates = (int *)realloc((char *)mstates, sizeof (int)*nstatesz); 1257 defact = (int *)realloc((char *)defact, sizeof (int)*nstatesz); 1258 tystate = (int *)realloc((char *)tystate, sizeof (int)*nstatesz); 1259 indgo = (int *)realloc((char *)indgo, sizeof (int)*nstatesz); 1260 1261 if ((*pstate == NULL) || (tystate == NULL) || (defact == NULL) || 1262 (indgo == NULL) || (mstates == NULL)) 1263 /* 1264 * TRANSLATION_NOTE -- This is a message from yacc. 1265 * This message is passed to error() function. 1266 * Memory allocation error. 1267 * 1268 * You may just translate this as: 1269 * 'Could not allocate internally used memory.' 1270 */ 1271 error(gettext( 1272 "cannot expand table of states")); 1273 } 1274 1275 static void 1276 exp_psmem(void) 1277 { 1278 int i; 1279 1280 new_pstsize += PSTSIZE; 1281 psmem = (ITEM *) realloc((char *)psmem, sizeof (ITEM) * new_pstsize); 1282 if (psmem == NULL) 1283 /* 1284 * TRANSLATION_NOTE -- This is a message from yacc. 1285 * This message is passed to error() function. 1286 * Memory allocation error. 1287 * 1288 * You may just translate this as: 1289 * 'Could not allocate internally used memory.' 1290 */ 1291 error(gettext( 1292 "cannot expand pstate memory")); 1293 1294 zzmemsz = zzmemsz - pstate[0] + psmem; 1295 for (i = 1; i <= nstate+1; ++i) 1296 pstate[i] = pstate[i] - pstate[0] + psmem; 1297 pstate[0] = psmem; 1298 } 1299