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