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 2007 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 #include <limits.h> 33 34 /* 35 * return next line of input, throw away trailing '\n' 36 * and also throw away trailing blanks (spaces and tabs) 37 * returns 0 if eof is had immediately 38 */ 39 40 CHR * 41 getl(CHR *p) 42 { 43 int c; 44 CHR *s, *t, *u; 45 int blank = 0; 46 47 t = s = p; 48 while (((c = gch()) != 0) && c != '\n') { 49 if (t >= &p[BUF_SIZ]) 50 error("definitions too long"); 51 if (c == ' ' || c == '\t') { 52 if (!blank) { 53 blank = 1; 54 u = t; 55 } 56 } else 57 blank = 0; 58 59 *t++ = c; 60 } 61 if (blank) 62 *u = 0; 63 else 64 *t = 0; 65 66 if (c == 0 && s == t) 67 return ((CHR *) 0); 68 prev = '\n'; 69 pres = '\n'; 70 return (s); 71 } 72 73 int 74 space(int ch) 75 { 76 switch (ch) { 77 case ' ': 78 case '\t': 79 case '\n': 80 return (1); 81 } 82 return (0); 83 } 84 85 int 86 digit(int c) 87 { 88 return (c >= '0' && c <= '9'); 89 } 90 91 /* VARARGS1 */ 92 void 93 error(s, p, d) 94 char *s; 95 int p, d; 96 { 97 /* if(!eof) */ 98 if (!yyline) 99 (void) fprintf(errorf, "Command line: "); 100 else { 101 (void) fprintf(errorf, 102 !no_input ? "" : "\"%s\":", sargv[optind]); 103 (void) fprintf(errorf, "line %d: ", yyline); 104 } 105 (void) fprintf(errorf, "Error: "); 106 (void) fprintf(errorf, s, p, d); 107 (void) putc('\n', errorf); 108 if (fatal) 109 error_tail(); 110 } 111 112 void 113 error_tail(void) 114 { 115 #ifdef DEBUG 116 if (debug && sect != ENDSECTION) { 117 sect1dump(); 118 sect2dump(); 119 } 120 #endif 121 122 if (report == 1) 123 statistics(); 124 exit(1); 125 /* NOTREACHED */ 126 } 127 128 /* VARARGS1 */ 129 void 130 warning(s, p, d) 131 char *s; 132 int p, d; 133 { 134 if (!eof) 135 if (!yyline) 136 (void) fprintf(errorf, "Command line: "); 137 else { 138 (void) fprintf(errorf, 139 !no_input?"":"\"%s\":", sargv[optind]); 140 (void) fprintf(errorf, 141 "line %d: ", yyline); 142 } 143 (void) fprintf(errorf, "Warning: "); 144 (void) fprintf(errorf, s, p, d); 145 (void) putc('\n', errorf); 146 (void) fflush(errorf); 147 if (fout) 148 (void) fflush(fout); 149 (void) fflush(stdout); 150 } 151 152 int 153 index(int a, CHR *s) 154 { 155 int k; 156 for (k = 0; s[k]; k++) 157 if (s[k] == a) 158 return (k); 159 return (-1); 160 } 161 162 int 163 alpha(int c) 164 { 165 return ('a' <= c && c <= 'z' || 166 'A' <= c && c <= 'Z'); 167 } 168 169 int 170 printable(int c) 171 { 172 return (c > 040 && c < 0177); 173 } 174 175 void 176 lgate(void) 177 { 178 char fname[20]; 179 180 if (lgatflg) 181 return; 182 lgatflg = 1; 183 if (fout == NULL) { 184 (void) sprintf(fname, "lex.yy.%c", ratfor ? 'r' : 'c'); 185 fout = fopen(fname, "w"); 186 } 187 if (fout == NULL) 188 error("Can't open %s", fname); 189 if (ratfor) 190 (void) fprintf(fout, "#\n"); 191 phead1(); 192 } 193 194 /* 195 * scopy(ptr to str, ptr to str) - copy first arg str to second 196 * returns ptr to second arg 197 */ 198 void 199 scopy(CHR *s, CHR *t) 200 { 201 CHR *i; 202 i = t; 203 while (*i++ = *s++) 204 /* EMPTY */; 205 } 206 207 /* 208 * convert string t, return integer value 209 */ 210 int 211 siconv(CHR *t) 212 { 213 int i, sw; 214 CHR *s; 215 s = t; 216 while (space(*s)) 217 s++; 218 if (!digit(*s) && *s != '-') 219 error("missing translation value"); 220 sw = 0; 221 if (*s == '-') { 222 sw = 1; 223 s++; 224 } 225 if (!digit(*s)) 226 error("incomplete translation format"); 227 i = 0; 228 while ('0' <= *s && *s <= '9') 229 i = i * 10 + (*(s++)-'0'); 230 return (sw ? -i : i); 231 } 232 233 /* 234 * slength(ptr to str) - return integer length of string arg 235 * excludes '\0' terminator 236 */ 237 int 238 slength(CHR *s) 239 { 240 int n; 241 CHR *t; 242 t = s; 243 for (n = 0; *t++; n++) 244 /* EMPTY */; 245 return (n); 246 } 247 248 /* 249 * scomp(x,y) - return -1 if x < y, 250 * 0 if x == y, 251 * return 1 if x > y, all lexicographically 252 */ 253 int 254 scomp(CHR *x, CHR *y) 255 { 256 CHR *a, *d; 257 a = (CHR *) x; 258 d = (CHR *) y; 259 while (*a || *d) { 260 if (*a > *d) 261 return (1); 262 if (*a < *d) 263 return (-1); 264 a++; 265 d++; 266 } 267 return (0); 268 } 269 270 int 271 ctrans(CHR **ss) 272 { 273 int c, k; 274 if ((c = **ss) != '\\') 275 return (c); 276 switch (c = *++*ss) { 277 case 'a': 278 c = '\a'; 279 warning("\\a is ANSI C \"alert\" character"); 280 break; 281 case 'v': c = '\v'; break; 282 case 'n': c = '\n'; break; 283 case 't': c = '\t'; break; 284 case 'r': c = '\r'; break; 285 case 'b': c = '\b'; break; 286 case 'f': c = 014; break; /* form feed for ascii */ 287 case '\\': c = '\\'; break; 288 case 'x': { 289 int dd; 290 warning("\\x is ANSI C hex escape"); 291 if (digit((dd = *++*ss)) || 292 ('a' <= dd && dd <= 'f') || 293 ('A' <= dd && dd <= 'F')) { 294 c = 0; 295 while (digit(dd) || 296 ('A' <= dd && dd <= 'F') || 297 ('a' <= dd && dd <= 'f')) { 298 if (digit(dd)) 299 c = c*16 + dd - '0'; 300 else if (dd >= 'a') 301 c = c*16 + 10 + dd - 'a'; 302 else 303 c = c*16 + 10 + dd - 'A'; 304 dd = *++*ss; 305 } 306 } else 307 c = 'x'; 308 break; 309 } 310 case '0': case '1': case '2': case '3': 311 case '4': case '5': case '6': case '7': 312 c -= '0'; 313 while ((k = *(*ss+1)) >= '0' && k <= '7') { 314 c = c*8 + k - '0'; 315 (*ss)++; 316 } 317 break; 318 } 319 return (c); 320 } 321 322 void 323 cclinter(int sw) 324 { 325 /* sw = 1 ==> ccl */ 326 int i, j, k; 327 int m; 328 if (!sw) { /* is NCCL */ 329 for (i = 1; i < ncg; i++) 330 symbol[i] ^= 1; /* reverse value */ 331 } 332 for (i = 1; i < ncg; i++) 333 if (symbol[i]) 334 break; 335 if (i >= ncg) 336 return; 337 i = cindex[i]; 338 /* see if ccl is already in our table */ 339 j = 0; 340 if (i) { 341 for (j = 1; j < ncg; j++) { 342 if ((symbol[j] && cindex[j] != i) || 343 (!symbol[j] && cindex[j] == i)) 344 break; 345 } 346 } 347 if (j >= ncg) 348 return; /* already in */ 349 m = 0; 350 k = 0; 351 for (i = 1; i < ncg; i++) { 352 if (symbol[i]) { 353 if (!cindex[i]) { 354 cindex[i] = ccount; 355 symbol[i] = 0; 356 m = 1; 357 } else 358 k = 1; 359 } 360 } 361 /* m == 1 implies last value of ccount has been used */ 362 if (m) 363 ccount++; 364 if (k == 0) 365 return; /* is now in as ccount wholly */ 366 /* intersection must be computed */ 367 for (i = 1; i < ncg; i++) { 368 if (symbol[i]) { 369 m = 0; 370 j = cindex[i]; /* will be non-zero */ 371 for (k = 1; k < ncg; k++) { 372 if (cindex[k] == j) { 373 if (symbol[k]) 374 symbol[k] = 0; 375 else { 376 cindex[k] = ccount; 377 m = 1; 378 } 379 } 380 } 381 if (m) 382 ccount++; 383 } 384 } 385 } 386 387 int 388 usescape(int c) 389 { 390 char d; 391 switch (c) { 392 case 'a': 393 c = '\a'; 394 warning("\\a is ANSI C \"alert\" character"); break; 395 case 'v': c = '\v'; break; 396 case 'n': c = '\n'; break; 397 case 'r': c = '\r'; break; 398 case 't': c = '\t'; break; 399 case 'b': c = '\b'; break; 400 case 'f': c = 014; break; /* form feed for ascii */ 401 case 'x': { 402 int dd; 403 if (digit((dd = gch())) || 404 ('A' <= dd && dd <= 'F') || 405 ('a' <= dd && dd <= 'f')) { 406 c = 0; 407 while (digit(dd) || 408 ('A' <= dd && dd <= 'F') || 409 ('a' <= dd && dd <= 'f')) { 410 if (digit(dd)) 411 c = c*16 + dd - '0'; 412 else if (dd >= 'a') 413 c = c*16 + 10 + dd - 'a'; 414 else 415 c = c*16 + 10 + dd - 'A'; 416 if (!digit(peek) && 417 !('A' <= peek && peek <= 'F') && 418 !('a' <= peek && peek <= 'f')) 419 break; 420 dd = gch(); 421 } 422 423 } else 424 c = 'x'; 425 break; 426 } 427 case '0': case '1': case '2': case '3': 428 case '4': case '5': case '6': case '7': 429 c -= '0'; 430 while ('0' <= (d = gch()) && d <= '7') { 431 c = c * 8 + (d-'0'); 432 if (!('0' <= peek && peek <= '7')) break; 433 } 434 435 break; 436 } 437 438 if (handleeuc && !isascii(c)) { 439 char tmpchar = c & 0x00ff; 440 mbtowc((wchar_t *)&c, &tmpchar, sizeof (tmpchar)); 441 } 442 return (c); 443 } 444 445 int 446 lookup(CHR *s, CHR **t) 447 { 448 int i; 449 i = 0; 450 while (*t) { 451 if (scomp(s, *t) == 0) 452 return (i); 453 i++; 454 t++; 455 } 456 return (-1); 457 } 458 459 void 460 cpycom(CHR *p) 461 { 462 static CHR *t; 463 static int c; 464 t = p; 465 466 if (sargv[optind] == NULL) 467 (void) fprintf(fout, "\n# line %d\n", yyline); 468 else 469 (void) fprintf(fout, 470 "\n# line %d \"%s\"\n", yyline, sargv[optind]); 471 472 (void) putc(*t++, fout); 473 (void) putc(*t++, fout); 474 while (*t) { 475 while (*t == '*') { 476 (void) putc(*t++, fout); 477 if (*t == '/') 478 goto backcall; 479 } 480 /* 481 * FIX BUG #1058428, not parsing comments correctly 482 * that span more than one line 483 */ 484 if (*t != NULL) 485 (void) putc(*t++, fout); 486 } 487 (void) putc('\n', fout); 488 while (c = gch()) { 489 while (c == '*') { 490 (void) putc((char)c, fout); 491 if ((c = gch()) == '/') { 492 while ((c = gch()) == ' ' || c == '\t') 493 /* EMPTY */; 494 if (!space(c)) 495 error("unacceptable statement"); 496 prev = '\n'; 497 goto backcall; 498 } 499 } 500 (void) putc((char)c, fout); 501 } 502 error("unexpected EOF inside comment"); 503 backcall: 504 (void) putc('/', fout); 505 (void) putc('\n', fout); 506 } 507 508 /* 509 * copy C action to the next ; or closing 510 */ 511 int 512 cpyact(void) 513 { 514 int brac, c, mth; 515 static int sw, savline; 516 517 brac = 0; 518 sw = TRUE; 519 savline = yyline; 520 521 if (sargv[optind] == NULL) 522 (void) fprintf(fout, "\n# line %d\n", yyline); 523 else 524 (void) fprintf(fout, 525 "\n# line %d \"%s\"\n", yyline, sargv[optind]); 526 527 while (!eof) { 528 c = gch(); 529 swt: 530 switch (c) { 531 case '|': 532 if (brac == 0 && sw == TRUE) { 533 if (peek == '|') 534 (void) gch(); /* eat up an extra '|' */ 535 return (0); 536 } 537 break; 538 case ';': 539 if (brac == 0) { 540 (void) putwc(c, fout); 541 (void) putc('\n', fout); 542 return (1); 543 } 544 break; 545 case '{': 546 brac++; 547 savline = yyline; 548 break; 549 case '}': 550 brac--; 551 if (brac == 0) { 552 (void) putwc(c, fout); 553 (void) putc('\n', fout); 554 return (1); 555 } 556 break; 557 case '/': 558 (void) putwc(c, fout); 559 c = gch(); 560 if (c != '*') 561 goto swt; 562 (void) putwc(c, fout); 563 savline = yyline; 564 while (c = gch()) { 565 while (c == '*') { 566 (void) putwc(c, fout); 567 if ((c = gch()) == '/') { 568 (void) putc('/', fout); 569 while ((c = gch()) == ' ' || 570 c == '\t' || c == '\n') 571 (void) putwc(c, fout); 572 goto swt; 573 } 574 } 575 (void) putc((char)c, fout); 576 } 577 yyline = savline; 578 error("EOF inside comment"); 579 /* NOTREACHED */ 580 break; 581 case '\'': /* character constant */ 582 case '"': /* character string */ 583 mth = c; 584 (void) putwc(c, fout); 585 while (c = gch()) { 586 if (c == '\\') { 587 (void) putwc(c, fout); 588 c = gch(); 589 } 590 else 591 if (c == mth) 592 goto loop; 593 (void) putwc(c, fout); 594 if (c == '\n') { 595 yyline--; 596 error( 597 "Non-terminated string or character constant"); 598 } 599 } 600 error("EOF in string or character constant"); 601 /* NOTREACHED */ 602 break; 603 case '\0': 604 yyline = savline; 605 error("Action does not terminate"); 606 /* NOTREACHED */ 607 break; 608 default: 609 break; /* usual character */ 610 } 611 loop: 612 if (c != ' ' && c != '\t' && c != '\n') 613 sw = FALSE; 614 (void) putwc(c, fout); 615 if (peek == '\n' && !brac && copy_line) { 616 (void) putc('\n', fout); 617 return (1); 618 } 619 } 620 error("Premature EOF"); 621 return (0); 622 } 623 624 int 625 gch(void) 626 { 627 int c; 628 prev = pres; 629 c = pres = peek; 630 peek = pushptr > pushc ? *--pushptr : getwc(fin); 631 while (peek == EOF) { 632 if (no_input) { 633 if (!yyline) 634 error("Cannot read from -- %s", 635 sargv[optind]); 636 if (optind < sargc-1) { 637 yyline = 0; 638 if (fin != stdin) 639 (void) fclose(fin); 640 fin = fopen(sargv[++optind], "r"); 641 if (fin == NULL) 642 error("Cannot open file -- %s", 643 sargv[optind]); 644 peek = getwc(fin); 645 } else 646 break; 647 } else { 648 if (fin != stdin) 649 (void) fclose(fin); 650 if (!yyline) 651 error("Cannot read from -- standard input"); 652 else 653 break; 654 } 655 } 656 if (c == EOF) { 657 eof = TRUE; 658 return (0); 659 } 660 if (c == '\n') 661 yyline++; 662 return (c); 663 } 664 665 int 666 mn2(int a, int d, int c) 667 { 668 if (tptr >= treesize) { 669 tptr++; 670 error("Parse tree too big %s", 671 (treesize == TREESIZE ? "\nTry using %e num" : "")); 672 } 673 if (d >= treesize) { 674 error("Parse error"); 675 } 676 name[tptr] = a; 677 left[tptr] = d; 678 right[tptr] = c; 679 parent[tptr] = 0; 680 nullstr[tptr] = 0; 681 switch (a) { 682 case RSTR: 683 parent[d] = tptr; 684 break; 685 case BAR: 686 case RNEWE: 687 if (nullstr[d] || nullstr[c]) 688 nullstr[tptr] = TRUE; 689 parent[d] = parent[c] = tptr; 690 break; 691 case RCAT: 692 case DIV: 693 if (nullstr[d] && nullstr[c]) 694 nullstr[tptr] = TRUE; 695 parent[d] = parent[c] = tptr; 696 break; 697 /* XCU4: add RXSCON */ 698 case RXSCON: 699 case RSCON: 700 parent[d] = tptr; 701 nullstr[tptr] = nullstr[d]; 702 break; 703 #ifdef DEBUG 704 default: 705 warning("bad switch mn2 %d %d", a, d); 706 break; 707 #endif 708 } 709 return (tptr++); 710 } 711 712 int 713 mn1(int a, int d) 714 { 715 if (tptr >= treesize) { 716 tptr++; 717 error("Parse tree too big %s", 718 (treesize == TREESIZE ? "\nTry using %e num" : "")); 719 } 720 name[tptr] = a; 721 left[tptr] = d; 722 parent[tptr] = 0; 723 nullstr[tptr] = 0; 724 switch (a) { 725 case RCCL: 726 case RNCCL: 727 if (slength((CHR *)d) == 0) 728 nullstr[tptr] = TRUE; 729 break; 730 case STAR: 731 case QUEST: 732 nullstr[tptr] = TRUE; 733 parent[d] = tptr; 734 break; 735 case PLUS: 736 case CARAT: 737 nullstr[tptr] = nullstr[d]; 738 parent[d] = tptr; 739 break; 740 case S2FINAL: 741 nullstr[tptr] = TRUE; 742 break; 743 #ifdef DEBUG 744 case FINAL: 745 case S1FINAL: 746 break; 747 default: 748 warning("bad switch mn1 %d %d", a, d); 749 break; 750 #endif 751 } 752 return (tptr++); 753 } 754 755 int 756 mn0(int a) 757 { 758 if (tptr >= treesize) { 759 tptr++; 760 error("Parse tree too big %s", 761 (treesize == TREESIZE ? "\nTry using %e num" : "")); 762 } 763 764 name[tptr] = a; 765 parent[tptr] = 0; 766 nullstr[tptr] = 0; 767 if (ISOPERATOR(a)) { 768 switch (a) { 769 case DOT: break; 770 case RNULLS: nullstr[tptr] = TRUE; break; 771 #ifdef DEBUG 772 default: 773 warning("bad switch mn0 %d", a); 774 break; 775 #endif 776 } 777 } 778 return (tptr++); 779 } 780 781 void 782 munput(int t, CHR *p) 783 { 784 int i, j; 785 if (t == 'c') { 786 *pushptr++ = peek; 787 peek = *p; 788 } else if (t == 's') { 789 *pushptr++ = peek; 790 peek = p[0]; 791 i = slength(p); 792 for (j = i - 1; j >= 1; j--) 793 *pushptr++ = p[j]; 794 } 795 if (pushptr >= pushc + TOKENSIZE) 796 error("Too many characters pushed"); 797 } 798 799 int 800 dupl(int n) 801 { 802 /* duplicate the subtree whose root is n, return ptr to it */ 803 int i; 804 i = name[n]; 805 if (!ISOPERATOR(i)) 806 return (mn0(i)); 807 switch (i) { 808 case DOT: 809 case RNULLS: 810 return (mn0(i)); 811 case RCCL: case RNCCL: case FINAL: case S1FINAL: case S2FINAL: 812 return (mn1(i, left[n])); 813 case STAR: case QUEST: case PLUS: case CARAT: 814 return (mn1(i, dupl(left[n]))); 815 816 /* XCU4: add RXSCON */ 817 case RSTR: case RSCON: case RXSCON: 818 return (mn2(i, dupl(left[n]), right[n])); 819 case BAR: case RNEWE: case RCAT: case DIV: 820 return (mn2(i, dupl(left[n]), dupl(right[n]))); 821 } 822 return (0); 823 } 824 825 #ifdef DEBUG 826 void 827 allprint(CHR c) 828 { 829 switch (c) { 830 case 014: 831 (void) printf("\\f"); 832 charc++; 833 break; 834 case '\n': 835 (void) printf("\\n"); 836 charc++; 837 break; 838 case '\t': 839 (void) printf("\\t"); 840 charc++; 841 break; 842 case '\b': 843 (void) printf("\\b"); 844 charc++; 845 break; 846 case ' ': 847 (void) printf("\\_"); 848 break; 849 default: 850 if (!iswprint(c)) { 851 printf("\\x%-2x", c); /* up to fashion. */ 852 charc += 3; 853 } else 854 (void) putwc(c, stdout); 855 break; 856 } 857 charc++; 858 } 859 860 void 861 strpt(CHR *s) 862 { 863 charc = 0; 864 while (*s) { 865 allprint(*s++); 866 if (charc > LINESIZE) { 867 charc = 0; 868 (void) printf("\n\t"); 869 } 870 } 871 } 872 873 void 874 sect1dump(void) 875 { 876 int i; 877 (void) printf("Sect 1:\n"); 878 if (def[0]) { 879 (void) printf("str trans\n"); 880 i = -1; 881 while (def[++i]) 882 (void) printf("%ws\t%ws\n", def[i], subs[i]); 883 } 884 if (sname[0]) { 885 (void) printf("start names\n"); 886 i = -1; 887 while (sname[++i]) 888 (void) printf("%ws\n", sname[i]); 889 } 890 if (chset == TRUE) { 891 (void) printf("char set changed\n"); 892 for (i = 1; i < NCH; i++) { 893 if (i != ctable[i]) { 894 allprint(i); 895 (void) putchar(' '); 896 iswprint(ctable[i]) ? 897 (void) putwc(ctable[i], stdout) : 898 (void) printf("%d", ctable[i]); 899 (void) putchar('\n'); 900 } 901 } 902 } 903 } 904 905 void 906 sect2dump(void) 907 { 908 (void) printf("Sect 2:\n"); 909 treedump(); 910 } 911 912 void 913 treedump(void) 914 { 915 int t; 916 CHR *p; 917 (void) printf("treedump %d nodes:\n", tptr); 918 for (t = 0; t < tptr; t++) { 919 (void) printf("%4d ", t); 920 parent[t] ? (void) printf("p=%4d", parent[t]) : 921 (void) printf(" "); 922 (void) printf(" "); 923 if (!ISOPERATOR(name[t])) { 924 allprint(name[t]); 925 } else 926 switch (name[t]) { 927 case RSTR: 928 (void) printf("%d ", left[t]); 929 allprint(right[t]); 930 break; 931 case RCCL: 932 (void) printf("ccl "); 933 strpt(left[t]); 934 break; 935 case RNCCL: 936 (void) printf("nccl "); 937 strpt(left[t]); 938 break; 939 case DIV: 940 (void) printf("/ %d %d", left[t], right[t]); 941 break; 942 case BAR: 943 (void) printf("| %d %d", left[t], right[t]); 944 break; 945 case RCAT: 946 (void) printf("cat %d %d", left[t], right[t]); 947 break; 948 case PLUS: 949 (void) printf("+ %d", left[t]); 950 break; 951 case STAR: 952 (void) printf("* %d", left[t]); 953 break; 954 case CARAT: 955 (void) printf("^ %d", left[t]); 956 break; 957 case QUEST: 958 (void) printf("? %d", left[t]); 959 break; 960 case RNULLS: 961 (void) printf("nullstring"); 962 break; 963 case FINAL: 964 (void) printf("final %d", left[t]); 965 break; 966 case S1FINAL: 967 (void) printf("s1final %d", left[t]); 968 break; 969 case S2FINAL: 970 (void) printf("s2final %d", left[t]); 971 break; 972 case RNEWE: 973 (void) printf("new %d %d", left[t], right[t]); 974 break; 975 976 /* XCU4: add RXSCON */ 977 case RXSCON: 978 p = (CHR *)right[t]; 979 (void) printf("exstart %s", sname[*p++-1]); 980 while (*p) 981 (void) printf(", %ws", sname[*p++-1]); 982 (void) printf(" %d", left[t]); 983 break; 984 case RSCON: 985 p = (CHR *)right[t]; 986 (void) printf("start %s", sname[*p++-1]); 987 while (*p) 988 (void) printf(", %ws", sname[*p++-1]); 989 (void) printf(" %d", left[t]); 990 break; 991 case DOT: 992 printf("dot"); 993 break; 994 default: 995 (void) printf( 996 "unknown %d %d %d", name[t], left[t], right[t]); 997 break; 998 } 999 if (nullstr[t]) 1000 (void) printf("\t(null poss.)"); 1001 (void) putchar('\n'); 1002 } 1003 } 1004 #endif 1005