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