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 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #include "ldefs.h" 32 33 static void add(int **array, int n); 34 static void follow(int v); 35 static void first(int v); 36 static void nextstate(int s, int c); 37 static void packtrans(int st, CHR *tch, int *tst, int cnt, int tryit); 38 static void acompute(int s); 39 static void rprint(int *a, char *s, int n); 40 static void shiftr(int *a, int n); 41 static void upone(int *a, int n); 42 static void bprint(char *a, char *s, int n); 43 static int notin(int n); 44 static int member(int d, CHR *t); 45 46 #ifdef PP 47 static void padd(int **array, int n); 48 #endif 49 50 void 51 cfoll(int v) 52 { 53 int i, j, k; 54 CHR *p; 55 i = name[v]; 56 if (!ISOPERATOR(i)) 57 i = 1; 58 switch (i) { 59 case 1: case RSTR: case RCCL: case RNCCL: case RNULLS: 60 for (j = 0; j < tptr; j++) 61 tmpstat[j] = FALSE; 62 count = 0; 63 follow(v); 64 #ifdef PP 65 padd(foll, v); /* packing version */ 66 #else 67 add(foll, v); /* no packing version */ 68 #endif 69 if (i == RSTR) 70 cfoll(left[v]); 71 else if (i == RCCL || i == RNCCL) { 72 for (j = 1; j < ncg; j++) 73 symbol[j] = (i == RNCCL); 74 p = (CHR *) left[v]; 75 while (*p) 76 symbol[*p++] = (i == RCCL); 77 p = pcptr; 78 for (j = 1; j < ncg; j++) 79 if (symbol[j]) { 80 for (k = 0; p + k < pcptr; k++) 81 if (cindex[j] == 82 *(p + k)) 83 break; 84 if (p + k >= pcptr) 85 *pcptr++ = cindex[j]; 86 } 87 *pcptr++ = 0; 88 if (pcptr > pchar + pchlen) 89 error( 90 "Too many packed character classes"); 91 left[v] = (int)p; 92 name[v] = RCCL; /* RNCCL eliminated */ 93 #ifdef DEBUG 94 if (debug && *p) { 95 (void) printf("ccl %d: %d", v, *p++); 96 while (*p) 97 (void) printf(", %d", *p++); 98 (void) putchar('\n'); 99 } 100 #endif 101 } 102 break; 103 case CARAT: 104 cfoll(left[v]); 105 break; 106 107 /* XCU4: add RXSCON */ 108 case RXSCON: 109 110 case STAR: case PLUS: case QUEST: case RSCON: 111 cfoll(left[v]); 112 break; 113 case BAR: case RCAT: case DIV: case RNEWE: 114 cfoll(left[v]); 115 cfoll(right[v]); 116 break; 117 #ifdef DEBUG 118 case FINAL: 119 case S1FINAL: 120 case S2FINAL: 121 break; 122 default: 123 warning("bad switch cfoll %d", v); 124 #endif 125 } 126 } 127 128 #ifdef DEBUG 129 void 130 pfoll(void) 131 { 132 int i, k, *p; 133 int j; 134 /* print sets of chars which may follow positions */ 135 (void) printf("pos\tchars\n"); 136 for (i = 0; i < tptr; i++) 137 if (p = foll[i]) { 138 j = *p++; 139 if (j >= 1) { 140 (void) printf("%d:\t%d", i, *p++); 141 for (k = 2; k <= j; k++) 142 (void) printf(", %d", *p++); 143 (void) putchar('\n'); 144 } 145 } 146 } 147 #endif 148 149 static void 150 add(int **array, int n) 151 { 152 int i, *temp; 153 CHR *ctemp; 154 temp = nxtpos; 155 ctemp = tmpstat; 156 array[n] = nxtpos; /* note no packing is done in positions */ 157 *temp++ = count; 158 for (i = 0; i < tptr; i++) 159 if (ctemp[i] == TRUE) 160 *temp++ = i; 161 nxtpos = temp; 162 if (nxtpos >= positions+maxpos) 163 error( 164 "Too many positions %s", 165 (maxpos == MAXPOS ? "\nTry using %p num" : "")); 166 } 167 168 static void 169 follow(int v) 170 { 171 int p; 172 if (v >= tptr-1) 173 return; 174 p = parent[v]; 175 if (p == 0) 176 return; 177 switch (name[p]) { 178 /* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */ 179 case RSTR: 180 if (tmpstat[p] == FALSE) { 181 count++; 182 tmpstat[p] = TRUE; 183 } 184 break; 185 case STAR: case PLUS: 186 first(v); 187 follow(p); 188 break; 189 case BAR: case QUEST: case RNEWE: 190 follow(p); 191 break; 192 case RCAT: case DIV: 193 if (v == left[p]) { 194 if (nullstr[right[p]]) 195 follow(p); 196 first(right[p]); 197 } 198 else 199 follow(p); 200 break; 201 /* XCU4: add RXSCON */ 202 case RXSCON: 203 case RSCON: case CARAT: 204 follow(p); 205 break; 206 #ifdef DEBUG 207 default: 208 warning("bad switch follow %d", p); 209 #endif 210 } 211 } 212 213 /* 214 * Check if I have a RXSCON in my upper node 215 */ 216 static int 217 check_me(int v) 218 { 219 int tmp = parent[v]; 220 221 while (name[tmp] != RNEWE) { 222 if (name[tmp] == RXSCON) 223 return (1); 224 tmp = parent[tmp]; 225 } 226 return (0); 227 } 228 229 /* calculate set of positions with v as root which can be active initially */ 230 static void 231 first(int v) 232 { 233 int i; 234 CHR *p; 235 i = name[v]; 236 if (!ISOPERATOR(i)) 237 i = 1; 238 switch (i) { 239 case 1: case RCCL: case RNCCL: 240 case RNULLS: case FINAL: 241 case S1FINAL: case S2FINAL: 242 /* 243 * XCU4: if we are working on an exclusive start state and 244 * the parent of this position is not RXSCON or RSTR this 245 * is not an active position. 246 * 247 * (There is a possibility that RSXCON appreas as the 248 * (parent)* node. Check it by check_me().) 249 */ 250 if ((exclusive[stnum/2]) && 251 ISOPERATOR(name[parent[v]]) && 252 (name[parent[v]] != RXSCON) && 253 (name[parent[v]] != RSTR) && 254 (check_me(v) == 0)) { 255 break; 256 } 257 if (tmpstat[v] == FALSE) { 258 count++; 259 tmpstat[v] = TRUE; 260 } 261 break; 262 case BAR: case RNEWE: 263 first(left[v]); 264 first(right[v]); 265 break; 266 case CARAT: 267 if (stnum % 2 == 1) 268 first(left[v]); 269 break; 270 /* XCU4: add RXSCON */ 271 case RXSCON: 272 case RSCON: 273 i = stnum/2 +1; 274 p = (CHR *) right[v]; 275 while (*p) 276 if (*p++ == i) { 277 first(left[v]); 278 break; 279 } 280 break; 281 case STAR: case QUEST: 282 case PLUS: case RSTR: 283 /* 284 * XCU4: if we are working on an exclusive start state and 285 * the parent of this position is not RXSCON or RSTR this 286 * is not an active position. 287 * 288 * (There is a possibility that RSXCON appreas as the 289 * (parent)* node. Check it by check_me().) 290 */ 291 if ((exclusive[stnum/2]) && 292 ISOPERATOR(name[parent[v]]) && 293 (name[parent[v]] != RXSCON) && 294 (name[parent[v]] != RSTR) && 295 (check_me(v) == 0)) { 296 break; 297 } 298 first(left[v]); 299 break; 300 case RCAT: case DIV: 301 first(left[v]); 302 if (nullstr[left[v]]) 303 first(right[v]); 304 break; 305 #ifdef DEBUG 306 default: 307 warning("bad switch first %d", v); 308 #endif 309 } 310 } 311 312 void 313 cgoto(void) 314 { 315 int i, j; 316 static int s; 317 int npos, curpos, n; 318 int tryit; 319 CHR tch[MAXNCG]; 320 int tst[MAXNCG]; 321 CHR *q; 322 /* generate initial state, for each start condition */ 323 if (ratfor) { 324 (void) fprintf(fout, "blockdata\n"); 325 (void) fprintf(fout, "common /Lvstop/ vstop\n"); 326 (void) fprintf(fout, "define Svstop %d\n", nstates+1); 327 (void) fprintf(fout, "integer vstop(Svstop)\n"); 328 } else 329 (void) fprintf(fout, "int yyvstop[] = {\n0,\n"); 330 while (stnum < 2 || stnum/2 < sptr) { 331 for (i = 0; i < tptr; i++) 332 tmpstat[i] = 0; 333 count = 0; 334 if (tptr > 0) 335 first(tptr-1); 336 add(state, stnum); 337 #ifdef DEBUG 338 if (debug) { 339 if (stnum > 1) 340 (void) printf("%ws:\n", sname[stnum/2]); 341 pstate(stnum); 342 } 343 #endif 344 stnum++; 345 } 346 stnum--; 347 /* even stnum = might not be at line begin */ 348 /* odd stnum = must be at line begin */ 349 /* even states can occur anywhere, odd states only at line begin */ 350 for (s = 0; s <= stnum; s++) { 351 tryit = FALSE; 352 cpackflg[s] = FALSE; 353 sfall[s] = -1; 354 acompute(s); 355 for (i = 0; i < ncg; i++) 356 symbol[i] = 0; 357 npos = *state[s]; 358 for (i = 1; i <= npos; i++) { 359 curpos = *(state[s]+i); 360 if (!ISOPERATOR(name[curpos])) 361 symbol[name[curpos]] = TRUE; 362 else { 363 switch (name[curpos]) { 364 case RCCL: 365 tryit = TRUE; 366 q = (CHR *)left[curpos]; 367 while (*q) { 368 for (j = 1; j < ncg; j++) 369 if (cindex[j] == *q) 370 symbol[j] = 371 TRUE; 372 q++; 373 } 374 break; 375 case RSTR: 376 symbol[right[curpos]] = TRUE; 377 break; 378 #ifdef DEBUG 379 case RNULLS: 380 case FINAL: 381 case S1FINAL: 382 case S2FINAL: 383 break; 384 default: 385 warning( 386 "bad switch cgoto %d state %d", 387 curpos, s); 388 break; 389 #endif 390 } 391 } 392 } 393 #ifdef DEBUG 394 if (debug) { 395 printf("State %d transitions on char-group {", s); 396 charc = 0; 397 for (i = 1; i < ncg; i++) { 398 if (symbol[i]) { 399 printf("%d,", i); 400 } 401 if (i == ncg-1) 402 printf("}\n"); 403 if (charc > LINESIZE/4) { 404 charc = 0; 405 printf("\n\t"); 406 } 407 } 408 } 409 #endif 410 /* for each char, calculate next state */ 411 n = 0; 412 for (i = 1; i < ncg; i++) { 413 if (symbol[i]) { 414 /* executed for each state, transition pair */ 415 nextstate(s, i); 416 xstate = notin(stnum); 417 if (xstate == -2) 418 warning("bad state %d %o", s, i); 419 else if (xstate == -1) { 420 if (stnum+1 >= nstates) { 421 stnum++; 422 error("Too many states %s", 423 (nstates == NSTATES ? 424 "\nTry using %n num":"")); 425 } 426 add(state, ++stnum); 427 #ifdef DEBUG 428 if (debug) 429 pstate(stnum); 430 #endif 431 tch[n] = i; 432 tst[n++] = stnum; 433 } else { /* xstate >= 0 ==> state exists */ 434 tch[n] = i; 435 tst[n++] = xstate; 436 } 437 } 438 } 439 tch[n] = 0; 440 tst[n] = -1; 441 /* pack transitions into permanent array */ 442 if (n > 0) 443 packtrans(s, tch, tst, n, tryit); 444 else 445 gotof[s] = -1; 446 } 447 (void) (ratfor ? fprintf(fout, "end\n") : fprintf(fout, "0};\n")); 448 } 449 450 /* 451 * Beware -- 70% of total CPU time is spent in this subroutine - 452 * if you don't believe me - try it yourself ! 453 */ 454 static void 455 nextstate(int s, int c) 456 { 457 int j, *newpos; 458 CHR *temp, *tz; 459 int *pos, i, *f, num, curpos, number; 460 /* state to goto from state s on char c */ 461 num = *state[s]; 462 temp = tmpstat; 463 pos = state[s] + 1; 464 for (i = 0; i < num; i++) { 465 curpos = *pos++; 466 j = name[curpos]; 467 if ((!ISOPERATOR(j)) && j == c || 468 j == RSTR && c == right[curpos] || 469 j == RCCL && member(c, (CHR *) left[curpos])) { 470 f = foll[curpos]; 471 number = *f; 472 newpos = f+1; 473 for (j = 0; j < number; j++) 474 temp[*newpos++] = 2; 475 } 476 } 477 j = 0; 478 tz = temp + tptr; 479 while (temp < tz) { 480 if (*temp == 2) { 481 j++; 482 *temp++ = 1; 483 } 484 else 485 *temp++ = 0; 486 } 487 count = j; 488 } 489 490 static int 491 notin(int n) 492 { /* see if tmpstat occurs previously */ 493 int *j, k; 494 CHR *temp; 495 int i; 496 if (count == 0) 497 return (-2); 498 temp = tmpstat; 499 for (i = n; i >= 0; i--) { /* for each state */ 500 j = state[i]; 501 if (count == *j++) { 502 for (k = 0; k < count; k++) 503 if (!temp[*j++]) 504 break; 505 if (k >= count) 506 return (i); 507 } 508 } 509 return (-1); 510 } 511 512 static void 513 packtrans(int st, CHR *tch, int *tst, int cnt, int tryit) 514 { 515 /* 516 * pack transitions into nchar, nexts 517 * nchar is terminated by '\0', nexts uses cnt, followed by elements 518 * gotof[st] = index into nchr, nexts for state st 519 * sfall[st] = t implies t is fall back state for st 520 * == -1 implies no fall back 521 */ 522 523 int cmin, cval, tcnt, diff, p, *ast; 524 int i, j, k; 525 CHR *ach; 526 int go[MAXNCG], temp[MAXNCG], index, c; 527 int swork[MAXNCG]; 528 CHR cwork[MAXNCG]; 529 int upper; 530 531 rcount += (long)cnt; 532 cmin = -1; 533 cval = ncg; 534 ast = tst; 535 ach = tch; 536 /* try to pack transitions using ccl's */ 537 if (!optim) 538 goto nopack; /* skip all compaction */ 539 if (tryit) { /* ccl's used */ 540 for (i = 1; i < ncg; i++) { 541 go[i] = temp[i] = -1; 542 symbol[i] = 1; 543 } 544 for (i = 0; i < cnt; i++) { 545 index = (unsigned char) tch[i]; 546 if ((index >= 0) && (index < NCH)) { 547 go[index] = tst[i]; 548 symbol[index] = 0; 549 } else { 550 (void) fprintf(stderr, 551 "lex`sub2`packtran: tch[%d] out of bounds (%d)\n", 552 i, (int)tch[i]); 553 } 554 } 555 for (i = 0; i < cnt; i++) { 556 c = match[tch[i]]; 557 if (go[c] != tst[i] || c == tch[i]) 558 temp[tch[i]] = tst[i]; 559 } 560 /* fill in error entries */ 561 for (i = 1; i < ncg; i++) 562 if (symbol[i]) 563 temp[i] = -2; /* error trans */ 564 /* count them */ 565 k = 0; 566 for (i = 1; i < ncg; i++) 567 if (temp[i] != -1) 568 k++; 569 if (k < cnt) { /* compress by char */ 570 #ifdef DEBUG 571 if (debug) 572 (void) printf( 573 "use compression %d, %d vs %d\n", st, k, cnt); 574 #endif 575 k = 0; 576 for (i = 1; i < ncg; i++) 577 if (temp[i] != -1) { 578 cwork[k] = i; 579 swork[k++] = 580 (temp[i] == -2 ? -1 : temp[i]); 581 } 582 cwork[k] = 0; 583 #ifdef PC 584 ach = cwork; 585 ast = swork; 586 cnt = k; 587 cpackflg[st] = TRUE; 588 #endif 589 } 590 } 591 /* 592 * get most similar state 593 * reject state with more transitions, 594 * state already represented by a third state, 595 * and state which is compressed by char if ours is not to be 596 */ 597 for (i = 0; i < st; i++) { 598 if (sfall[i] != -1) 599 continue; 600 if (cpackflg[st] == 1) 601 if (!(cpackflg[i] == 1)) 602 continue; 603 p = gotof[i]; 604 if (p == -1) /* no transitions */ 605 continue; 606 tcnt = nexts[p]; 607 if (tcnt > cnt) 608 continue; 609 diff = 0; 610 k = 0; 611 j = 0; 612 upper = p + tcnt; 613 while (ach[j] && p < upper) { 614 while (ach[j] < nchar[p] && ach[j]) { 615 diff++; 616 j++; 617 } 618 if (ach[j] == 0) 619 break; 620 if (ach[j] > nchar[p]) { 621 diff = ncg; 622 break; 623 } 624 /* ach[j] == nchar[p] */ 625 if (ast[j] != nexts[++p] || 626 ast[j] == -1 || 627 (cpackflg[st] && ach[j] != match[ach[j]])) 628 diff++; 629 j++; 630 } 631 while (ach[j]) { 632 diff++; 633 j++; 634 } 635 if (p < upper) 636 diff = ncg; 637 if (diff < cval && diff < tcnt) { 638 cval = diff; 639 cmin = i; 640 if (cval == 0) 641 break; 642 } 643 } 644 /* cmin = state "most like" state st */ 645 #ifdef DEBUG 646 if (debug) 647 (void) printf("select st %d for st %d diff %d\n", 648 cmin, st, cval); 649 #endif 650 #ifdef PS 651 if (cmin != -1) { /* if we can use st cmin */ 652 gotof[st] = nptr; 653 k = 0; 654 sfall[st] = cmin; 655 p = gotof[cmin] + 1; 656 j = 0; 657 while (ach[j]) { 658 /* if cmin has a transition on c, then so will st */ 659 /* st may be "larger" than cmin, however */ 660 while (ach[j] < nchar[p-1] && ach[j]) { 661 k++; 662 nchar[nptr] = ach[j]; 663 nexts[++nptr] = ast[j]; 664 j++; 665 } 666 if (nchar[p-1] == 0) 667 break; 668 if (ach[j] > nchar[p-1]) { 669 warning("bad transition %d %d", st, cmin); 670 goto nopack; 671 } 672 /* ach[j] == nchar[p-1] */ 673 if (ast[j] != nexts[p] || 674 ast[j] == -1 || 675 (cpackflg[st] && ach[j] != match[ach[j]])) { 676 k++; 677 nchar[nptr] = ach[j]; 678 nexts[++nptr] = ast[j]; 679 } 680 p++; 681 j++; 682 } 683 while (ach[j]) { 684 nchar[nptr] = ach[j]; 685 nexts[++nptr] = ast[j++]; 686 k++; 687 } 688 nexts[gotof[st]] = cnt = k; 689 nchar[nptr++] = 0; 690 } else { 691 #endif 692 nopack: 693 /* stick it in */ 694 gotof[st] = nptr; 695 nexts[nptr] = cnt; 696 for (i = 0; i < cnt; i++) { 697 nchar[nptr] = ach[i]; 698 nexts[++nptr] = ast[i]; 699 } 700 nchar[nptr++] = 0; 701 #ifdef PS 702 } 703 #endif 704 if (cnt < 1) { 705 gotof[st] = -1; 706 nptr--; 707 } else 708 if (nptr > ntrans) 709 error( 710 "Too many transitions %s", 711 (ntrans == NTRANS ? "\nTry using %a num" : "")); 712 } 713 714 #ifdef DEBUG 715 void 716 pstate(int s) 717 { 718 int *p, i, j; 719 (void) printf("State %d:\n", s); 720 p = state[s]; 721 i = *p++; 722 if (i == 0) 723 return; 724 (void) printf("%4d", *p++); 725 for (j = 1; j < i; j++) { 726 (void) printf(", %4d", *p++); 727 if (j%30 == 0) 728 (void) putchar('\n'); 729 } 730 (void) putchar('\n'); 731 } 732 #endif 733 734 static int 735 member(int d, CHR *t) 736 { 737 int c; 738 CHR *s; 739 c = d; 740 s = t; 741 c = cindex[c]; 742 while (*s) 743 if (*s++ == c) 744 return (1); 745 return (0); 746 } 747 748 #ifdef DEBUG 749 void 750 stprt(int i) 751 { 752 int p, t; 753 (void) printf("State %d:", i); 754 /* print actions, if any */ 755 t = atable[i]; 756 if (t != -1) 757 (void) printf(" final"); 758 (void) putchar('\n'); 759 if (cpackflg[i] == TRUE) 760 (void) printf("backup char in use\n"); 761 if (sfall[i] != -1) 762 (void) printf("fall back state %d\n", sfall[i]); 763 p = gotof[i]; 764 if (p == -1) 765 return; 766 (void) printf("(%d transitions)\n", nexts[p]); 767 while (nchar[p]) { 768 charc = 0; 769 if (nexts[p+1] >= 0) 770 (void) printf("%d\t", nexts[p+1]); 771 else 772 (void) printf("err\t"); 773 allprint(nchar[p++]); 774 while (nexts[p] == nexts[p+1] && nchar[p]) { 775 if (charc > LINESIZE) { 776 charc = 0; 777 (void) printf("\n\t"); 778 } 779 allprint(nchar[p++]); 780 } 781 (void) putchar('\n'); 782 } 783 (void) putchar('\n'); 784 } 785 #endif 786 787 /* compute action list = set of poss. actions */ 788 static void 789 acompute(int s) 790 { 791 int *p, i, j; 792 int q, r; 793 int cnt, m; 794 int temp[MAXPOSSTATE], k, neg[MAXPOSSTATE], n; 795 k = 0; 796 n = 0; 797 p = state[s]; 798 cnt = *p++; 799 if (cnt > MAXPOSSTATE) 800 error("Too many positions for one state - acompute"); 801 for (i = 0; i < cnt; i++) { 802 q = *p; 803 if (name[q] == FINAL) 804 temp[k++] = left[q]; 805 else if (name[q] == S1FINAL) { 806 temp[k++] = left[q]; 807 if ((r = left[q]) >= NACTIONS) 808 error( 809 "INTERNAL ERROR:left[%d]==%d>=NACTIONS", q, r); 810 extra[r] = 1; 811 } else if (name[q] == S2FINAL) 812 neg[n++] = left[q]; 813 p++; 814 } 815 atable[s] = -1; 816 if (k < 1 && n < 1) 817 return; 818 #ifdef DEBUG 819 if (debug) 820 (void) printf("final %d actions:", s); 821 #endif 822 /* sort action list */ 823 for (i = 0; i < k; i++) 824 for (j = i+1; j < k; j++) 825 if (temp[j] < temp[i]) { 826 m = temp[j]; 827 temp[j] = temp[i]; 828 temp[i] = m; 829 } 830 /* remove dups */ 831 for (i = 0; i < k-1; i++) 832 if (temp[i] == temp[i+1]) 833 temp[i] = 0; 834 /* copy to permanent quarters */ 835 atable[s] = aptr; 836 #ifdef DEBUG 837 if (!ratfor) 838 (void) fprintf(fout, "/* actions for state %d */", s); 839 #endif 840 (void) putc('\n', fout); 841 for (i = 0; i < k; i++) 842 if (temp[i] != 0) { 843 (void) (ratfor ? 844 fprintf(fout, "data vstop(%d)/%d/\n", 845 aptr, temp[i]) : 846 fprintf(fout, "%d,\n", temp[i])); 847 #ifdef DEBUG 848 if (debug) 849 (void) printf("%d ", temp[i]); 850 #endif 851 aptr++; 852 } 853 for (i = 0; i < n; i++) { /* copy fall back actions - all neg */ 854 ratfor ? 855 (void) fprintf(fout, "data vstop(%d)/%d/\n", aptr, neg[i]) : 856 (void) fprintf(fout, "%d,\n", neg[i]); 857 aptr++; 858 #ifdef DEBUG 859 if (debug) 860 (void) printf("%d ", neg[i]); 861 #endif 862 } 863 #ifdef DEBUG 864 if (debug) 865 (void) putchar('\n'); 866 #endif 867 (void) (ratfor ? fprintf(fout, "data vstop (%d)/0/\n", aptr) : 868 fprintf(fout, "0, \n")); 869 aptr++; 870 } 871 872 #ifdef DEBUG 873 void 874 pccl(void) 875 { 876 /* print character class sets */ 877 int i, j; 878 (void) printf("char class intersection\n"); 879 for (i = 0; i < ccount; i++) { 880 charc = 0; 881 (void) printf("class %d:\n\t", i); 882 for (j = 1; j < ncg; j++) 883 if (cindex[j] == i) { 884 allprint(j); 885 if (charc > LINESIZE) { 886 (void) printf("\n\t"); 887 charc = 0; 888 } 889 } 890 (void) putchar('\n'); 891 } 892 charc = 0; 893 (void) printf("match:\n"); 894 for (i = 0; i < ncg; i++) { 895 allprint(match[i]); 896 if (charc > LINESIZE) { 897 (void) putchar('\n'); 898 charc = 0; 899 } 900 } 901 (void) putchar('\n'); 902 } 903 #endif 904 905 void 906 mkmatch(void) 907 { 908 int i; 909 CHR tab[MAXNCG]; 910 for (i = 0; i < ccount; i++) 911 tab[i] = 0; 912 for (i = 1; i < ncg; i++) 913 if (tab[cindex[i]] == 0) 914 tab[cindex[i]] = i; 915 /* tab[i] = principal char for new ccl i */ 916 for (i = 1; i < ncg; i++) 917 match[i] = tab[cindex[i]]; 918 } 919 920 void 921 layout(void) 922 { 923 /* format and output final program's tables */ 924 int i, j, k; 925 int top, bot, startup, omin; 926 startup = 0; 927 for (i = 0; i < outsize; i++) 928 verify[i] = advance[i] = 0; 929 omin = 0; 930 yytop = 0; 931 for (i = 0; i <= stnum; i++) { /* for each state */ 932 j = gotof[i]; 933 if (j == -1) { 934 stoff[i] = 0; 935 continue; 936 } 937 bot = j; 938 while (nchar[j]) 939 j++; 940 top = j - 1; 941 #if DEBUG 942 if (debug) { 943 (void) printf("State %d: (layout)\n", i); 944 for (j = bot; j <= top; j++) { 945 (void) printf(" %o", nchar[j]); 946 if (j % 10 == 0) 947 (void) putchar('\n'); 948 } 949 (void) putchar('\n'); 950 } 951 #endif 952 while (verify[omin+ZCH]) 953 omin++; 954 startup = omin; 955 #if DEBUG 956 if (debug) 957 (void) printf( 958 "bot,top %d, %d startup begins %d\n", 959 bot, top, startup); 960 #endif 961 if (chset) { 962 do { 963 startup += 1; 964 if (startup > outsize - ZCH) 965 error("output table overflow"); 966 for (j = bot; j <= top; j++) { 967 k = startup+ctable[nchar[j]]; 968 if (verify[k]) 969 break; 970 } 971 } while (j <= top); 972 #if DEBUG 973 if (debug) 974 (void) printf(" startup will be %d\n", 975 startup); 976 #endif 977 /* have found place */ 978 for (j = bot; j <= top; j++) { 979 k = startup + ctable[nchar[j]]; 980 if (ctable[nchar[j]] <= 0) 981 (void) printf( 982 "j %d nchar %d ctable.nch %d\n", 983 j, (int)nchar[j], ctable[nchar[k]]); 984 verify[k] = i + 1; /* state number + 1 */ 985 advance[k] = nexts[j+1]+1; 986 if (yytop < k) 987 yytop = k; 988 } 989 } else { 990 do { 991 startup += 1; 992 if (startup > outsize - ZCH) 993 error("output table overflow"); 994 for (j = bot; j <= top; j++) { 995 k = startup + nchar[j]; 996 if (verify[k]) 997 break; 998 } 999 } while (j <= top); 1000 /* have found place */ 1001 #if DEBUG 1002 if (debug) 1003 (void) printf(" startup going to be %d\n", startup); 1004 #endif 1005 for (j = bot; j <= top; j++) { 1006 k = startup + nchar[j]; 1007 verify[k] = i+1; /* state number + 1 */ 1008 advance[k] = nexts[j+1] + 1; 1009 if (yytop < k) 1010 yytop = k; 1011 } 1012 } 1013 stoff[i] = startup; 1014 } 1015 1016 /* stoff[i] = offset into verify, advance for trans for state i */ 1017 /* put out yywork */ 1018 if (ratfor) { 1019 (void) fprintf(fout, "define YYTOPVAL %d\n", yytop); 1020 rprint(verify, "verif", yytop+1); 1021 rprint(advance, "advan", yytop+1); 1022 shiftr(stoff, stnum); 1023 rprint(stoff, "stoff", stnum+1); 1024 shiftr(sfall, stnum); 1025 upone(sfall, stnum+1); 1026 rprint(sfall, "fall", stnum+1); 1027 bprint(extra, "extra", casecount+1); 1028 bprint((char *)match, "match", ncg); 1029 shiftr(atable, stnum); 1030 rprint(atable, "atable", stnum+1); 1031 } 1032 (void) fprintf(fout, 1033 "# define YYTYPE %s\n", stnum+1 >= NCH ? "int" : "unsigned char"); 1034 (void) fprintf(fout, 1035 "struct yywork { YYTYPE verify, advance; } yycrank[] = {\n"); 1036 for (i = 0; i <= yytop; i += 4) { 1037 for (j = 0; j < 4; j++) { 1038 k = i+j; 1039 if (verify[k]) 1040 (void) fprintf(fout, 1041 "%d,%d,\t", verify[k], advance[k]); 1042 else 1043 (void) fprintf(fout, "0,0,\t"); 1044 } 1045 (void) putc('\n', fout); 1046 } 1047 (void) fprintf(fout, "0,0};\n"); 1048 1049 /* put out yysvec */ 1050 1051 (void) fprintf(fout, "struct yysvf yysvec[] = {\n"); 1052 (void) fprintf(fout, "0,\t0,\t0,\n"); 1053 for (i = 0; i <= stnum; i++) { /* for each state */ 1054 if (cpackflg[i]) 1055 stoff[i] = -stoff[i]; 1056 (void) fprintf(fout, "yycrank+%d,\t", stoff[i]); 1057 if (sfall[i] != -1) 1058 (void) fprintf(fout, 1059 "yysvec+%d,\t", sfall[i]+1); /* state + 1 */ 1060 else 1061 (void) fprintf(fout, "0,\t\t"); 1062 if (atable[i] != -1) 1063 (void) fprintf(fout, "yyvstop+%d,", atable[i]); 1064 else 1065 (void) fprintf(fout, "0,\t"); 1066 #ifdef DEBUG 1067 (void) fprintf(fout, "\t\t/* state %d */", i); 1068 #endif 1069 (void) putc('\n', fout); 1070 } 1071 (void) fprintf(fout, "0,\t0,\t0};\n"); 1072 1073 /* put out yymatch */ 1074 1075 (void) fprintf(fout, "struct yywork *yytop = yycrank+%d;\n", yytop); 1076 (void) fprintf(fout, "struct yysvf *yybgin = yysvec+1;\n"); 1077 if (optim) { 1078 if (handleeuc) { 1079 (void) fprintf(fout, "int yymatch[] = {\n"); 1080 } else { 1081 (void) fprintf(fout, "char yymatch[] = {\n"); 1082 } 1083 if (chset == 0) { /* no chset, put out in normal order */ 1084 for (i = 0; i < ncg; i += 8) { 1085 for (j = 0; j < 8; j++) { 1086 int fbch; 1087 fbch = match[i+j]; 1088 (void) fprintf(fout, "%3d, ", fbch); 1089 } 1090 (void) putc('\n', fout); 1091 } 1092 } else { 1093 int *fbarr; 1094 /*LINTED: E_BAD_PTR_CAST_ALIGN*/ 1095 fbarr = (int *)myalloc(2*MAXNCG, sizeof (*fbarr)); 1096 if (fbarr == 0) 1097 error("No space for char table reverse", 0); 1098 for (i = 0; i < MAXNCG; i++) 1099 fbarr[i] = 0; 1100 for (i = 0; i < ncg; i++) 1101 fbarr[ctable[i]] = ctable[match[i]]; 1102 for (i = 0; i < ncg; i += 8) { 1103 for (j = 0; j < 8; j++) 1104 (void) fprintf(fout, "0%-3o,", 1105 fbarr[i+j]); 1106 (void) putc('\n', fout); 1107 } 1108 free(fbarr); 1109 } 1110 (void) fprintf(fout, "0};\n"); 1111 } 1112 /* put out yyextra */ 1113 (void) fprintf(fout, "char yyextra[] = {\n"); 1114 for (i = 0; i < casecount; i += 8) { 1115 for (j = 0; j < 8; j++) 1116 (void) fprintf(fout, "%d,", i+j < NACTIONS ? 1117 extra[i+j] : 0); 1118 (void) putc('\n', fout); 1119 } 1120 (void) fprintf(fout, "0};\n"); 1121 if (handleeuc) { 1122 /* Put out yycgidtbl */ 1123 (void) fprintf(fout, "#define YYNCGIDTBL %d\n", ncgidtbl); 1124 (void) fprintf(fout, "\tunsigned long yycgidtbl[]={"); 1125 /* 1126 * Use "unsigned long" instead of "lchar" to minimize 1127 * the name-space polution for the application program. 1128 */ 1129 for (i = 0; i < ncgidtbl; ++i) { 1130 if (i%8 == 0) 1131 (void) fprintf(fout, "\n\t\t"); 1132 (void) fprintf(fout, "0x%08x, ", (int)yycgidtbl[i]); 1133 } 1134 (void) fprintf(fout, "\n\t0};\n"); 1135 } 1136 } 1137 1138 static void 1139 rprint(int *a, char *s, int n) 1140 { 1141 int i; 1142 (void) fprintf(fout, "block data\n"); 1143 (void) fprintf(fout, "common /L%s/ %s\n", s, s); 1144 (void) fprintf(fout, "define S%s %d\n", s, n); 1145 (void) fprintf(fout, "integer %s (S%s)\n", s, s); 1146 for (i = 1; i <= n; i++) { 1147 if (i%8 == 1) 1148 (void) fprintf(fout, "data "); 1149 (void) fprintf(fout, "%s (%d)/%d/", s, i, a[i]); 1150 (void) fprintf(fout, (i%8 && i < n) ? ", " : "\n"); 1151 } 1152 (void) fprintf(fout, "end\n"); 1153 } 1154 1155 static void 1156 shiftr(int *a, int n) 1157 { 1158 int i; 1159 for (i = n; i >= 0; i--) 1160 a[i+1] = a[i]; 1161 } 1162 1163 static void 1164 upone(int *a, int n) 1165 { 1166 int i; 1167 for (i = 0; i <= n; i++) 1168 a[i]++; 1169 } 1170 1171 static void 1172 bprint(char *a, char *s, int n) 1173 { 1174 int i, j, k; 1175 (void) fprintf(fout, "block data\n"); 1176 (void) fprintf(fout, "common /L%s/ %s\n", s, s); 1177 (void) fprintf(fout, "define S%s %d\n", s, n); 1178 (void) fprintf(fout, "integer %s (S%s)\n", s, s); 1179 for (i = 1; i < n; i += 8) { 1180 (void) fprintf(fout, "data %s (%d)/%d/", s, i, a[i]); 1181 for (j = 1; j < 8; j++) { 1182 k = i+j; 1183 if (k < n) 1184 (void) fprintf(fout, 1185 ", %s (%d)/%d/", s, k, a[k]); 1186 } 1187 (void) putc('\n', fout); 1188 } 1189 (void) fprintf(fout, "end\n"); 1190 } 1191 1192 #ifdef PP 1193 static void 1194 padd(int **array, int n) 1195 { 1196 int i, *j, k; 1197 array[n] = nxtpos; 1198 if (count == 0) { 1199 *nxtpos++ = 0; 1200 return; 1201 } 1202 for (i = tptr-1; i >= 0; i--) { 1203 j = array[i]; 1204 if (j && *j++ == count) { 1205 for (k = 0; k < count; k++) 1206 if (!tmpstat[*j++]) 1207 break; 1208 if (k >= count) { 1209 array[n] = array[i]; 1210 return; 1211 } 1212 } 1213 } 1214 add(array, n); 1215 } 1216 #endif 1217