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 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #include "ldefs.c" 34 #include <limits.h> 35 36 /* 37 * return next line of input, throw away trailing '\n' 38 * and also throw away trailing blanks (spaces and tabs) 39 * returns 0 if eof is had immediately 40 */ 41 42 CHR * 43 getl(CHR *p) 44 { 45 int c; 46 CHR *s, *t, *u; 47 int blank = 0; 48 49 t = s = p; 50 while (((c = gch()) != 0) && c != '\n') { 51 if (t >= &p[BUF_SIZ]) 52 error("definitions too long"); 53 if (c == ' ' || c == '\t') { 54 if (!blank) { 55 blank = 1; 56 u = t; 57 } 58 } else 59 blank = 0; 60 61 *t++ = c; 62 } 63 if (blank) 64 *u = 0; 65 else 66 *t = 0; 67 68 if (c == 0 && s == t) 69 return ((CHR *) 0); 70 prev = '\n'; 71 pres = '\n'; 72 return (s); 73 } 74 75 int 76 space(int ch) 77 { 78 switch (ch) { 79 case ' ': 80 case '\t': 81 case '\n': 82 return (1); 83 } 84 return (0); 85 } 86 87 int 88 digit(int c) 89 { 90 return (c >= '0' && c <= '9'); 91 } 92 93 /* VARARGS1 */ 94 void 95 error(s, p, d) 96 char *s; 97 int p, d; 98 { 99 /* if(!eof) */ 100 if (!yyline) 101 (void) fprintf(errorf, "Command line: "); 102 else { 103 (void) fprintf(errorf, 104 !no_input ? "" : "\"%s\":", sargv[optind]); 105 (void) fprintf(errorf, "line %d: ", yyline); 106 } 107 (void) fprintf(errorf, "Error: "); 108 (void) fprintf(errorf, s, p, d); 109 (void) putc('\n', errorf); 110 if (fatal) 111 error_tail(); 112 } 113 114 void 115 error_tail(void) 116 { 117 #ifdef DEBUG 118 if (debug && sect != ENDSECTION) { 119 sect1dump(); 120 sect2dump(); 121 } 122 #endif 123 124 if (report == 1) 125 statistics(); 126 exit(1); 127 /* NOTREACHED */ 128 } 129 130 /* VARARGS1 */ 131 void 132 warning(s, p, d) 133 char *s; 134 int p, d; 135 { 136 if (!eof) 137 if (!yyline) 138 (void) fprintf(errorf, "Command line: "); 139 else { 140 (void) fprintf(errorf, 141 !no_input?"":"\"%s\":", sargv[optind]); 142 (void) fprintf(errorf, 143 "line %d: ", yyline); 144 } 145 (void) fprintf(errorf, "Warning: "); 146 (void) fprintf(errorf, s, p, d); 147 (void) putc('\n', errorf); 148 (void) fflush(errorf); 149 if (fout) 150 (void) fflush(fout); 151 (void) fflush(stdout); 152 } 153 154 int 155 index(int a, CHR *s) 156 { 157 int k; 158 for (k = 0; s[k]; k++) 159 if (s[k] == a) 160 return (k); 161 return (-1); 162 } 163 164 int 165 alpha(int c) 166 { 167 return ('a' <= c && c <= 'z' || 168 'A' <= c && c <= 'Z'); 169 } 170 171 int 172 printable(int c) 173 { 174 return (c > 040 && c < 0177); 175 } 176 177 void 178 lgate(void) 179 { 180 char fname[20]; 181 182 if (lgatflg) 183 return; 184 lgatflg = 1; 185 if (fout == NULL) { 186 (void) sprintf(fname, "lex.yy.%c", ratfor ? 'r' : 'c'); 187 fout = fopen(fname, "w"); 188 } 189 if (fout == NULL) 190 error("Can't open %s", fname); 191 if (ratfor) 192 (void) fprintf(fout, "#\n"); 193 phead1(); 194 } 195 196 /* 197 * scopy(ptr to str, ptr to str) - copy first arg str to second 198 * returns ptr to second arg 199 */ 200 void 201 scopy(CHR *s, CHR *t) 202 { 203 CHR *i; 204 i = t; 205 while (*i++ = *s++); 206 } 207 208 /* 209 * convert string t, return integer value 210 */ 211 int 212 siconv(CHR *t) 213 { 214 int i, sw; 215 CHR *s; 216 s = t; 217 while (space(*s)) 218 s++; 219 if (!digit(*s) && *s != '-') 220 error("missing translation value"); 221 sw = 0; 222 if (*s == '-') { 223 sw = 1; 224 s++; 225 } 226 if (!digit(*s)) 227 error("incomplete translation format"); 228 i = 0; 229 while ('0' <= *s && *s <= '9') 230 i = i * 10 + (*(s++)-'0'); 231 return (sw ? -i : i); 232 } 233 234 /* 235 * slength(ptr to str) - return integer length of string arg 236 * excludes '\0' terminator 237 */ 238 int 239 slength(CHR *s) 240 { 241 int n; 242 CHR *t; 243 t = s; 244 for (n = 0; *t++; n++); 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 if (!space(c)) 494 error("unacceptable statement"); 495 prev = '\n'; 496 goto backcall; 497 } 498 } 499 (void) putc((char)c, fout); 500 } 501 error("unexpected EOF inside comment"); 502 backcall: 503 (void) putc('/', fout); 504 (void) putc('\n', fout); 505 } 506 507 /* 508 * copy C action to the next ; or closing 509 */ 510 int 511 cpyact(void) 512 { 513 int brac, c, mth; 514 static int sw, savline; 515 516 brac = 0; 517 sw = TRUE; 518 savline = yyline; 519 520 if (sargv[optind] == NULL) 521 (void) fprintf(fout, "\n# line %d\n", yyline); 522 else 523 (void) fprintf(fout, 524 "\n# line %d \"%s\"\n", yyline, sargv[optind]); 525 526 while (!eof) { 527 c = gch(); 528 swt: 529 switch (c) { 530 case '|': 531 if (brac == 0 && sw == TRUE) { 532 if (peek == '|') 533 (void) gch(); /* eat up an extra '|' */ 534 return (0); 535 } 536 break; 537 case ';': 538 if (brac == 0) { 539 (void) putwc(c, fout); 540 (void) putc('\n', fout); 541 return (1); 542 } 543 break; 544 case '{': 545 brac++; 546 savline = yyline; 547 break; 548 case '}': 549 brac--; 550 if (brac == 0) { 551 (void) putwc(c, fout); 552 (void) putc('\n', fout); 553 return (1); 554 } 555 break; 556 case '/': 557 (void) putwc(c, fout); 558 c = gch(); 559 if (c != '*') 560 goto swt; 561 (void) putwc(c, fout); 562 savline = yyline; 563 while (c = gch()) { 564 while (c == '*') { 565 (void) putwc(c, fout); 566 if ((c = gch()) == '/') { 567 (void) putc('/', fout); 568 while ((c = gch()) == ' ' || 569 c == '\t' || c == '\n') 570 (void) putwc(c, fout); 571 goto swt; 572 } 573 } 574 (void) putc((char)c, fout); 575 } 576 yyline = savline; 577 error("EOF inside comment"); 578 /* NOTREACHED */ 579 break; 580 case '\'': /* character constant */ 581 case '"': /* character string */ 582 mth = c; 583 (void) putwc(c, fout); 584 while (c = gch()) { 585 if (c == '\\') { 586 (void) putwc(c, fout); 587 c = gch(); 588 } 589 else 590 if (c == mth) 591 goto loop; 592 (void) putwc(c, fout); 593 if (c == '\n') { 594 yyline--; 595 error( 596 "Non-terminated string or character constant"); 597 } 598 } 599 error("EOF in string or character constant"); 600 /* NOTREACHED */ 601 break; 602 case '\0': 603 yyline = savline; 604 error("Action does not terminate"); 605 /* NOTREACHED */ 606 break; 607 default: 608 break; /* usual character */ 609 } 610 loop: 611 if (c != ' ' && c != '\t' && c != '\n') 612 sw = FALSE; 613 (void) putwc(c, fout); 614 if (peek == '\n' && !brac && copy_line) { 615 (void) putc('\n', fout); 616 return (1); 617 } 618 } 619 error("Premature EOF"); 620 return (0); 621 } 622 623 int 624 gch(void) 625 { 626 int c; 627 prev = pres; 628 c = pres = peek; 629 peek = pushptr > pushc ? *--pushptr : getwc(fin); 630 while (peek == EOF) { 631 if (no_input) { 632 if (!yyline) 633 error("Cannot read from -- %s", 634 sargv[optind]); 635 if (optind < sargc-1) { 636 yyline = 0; 637 if (fin != stdin) 638 (void) fclose(fin); 639 fin = fopen(sargv[++optind], "r"); 640 if (fin == NULL) 641 error("Cannot open file -- %s", 642 sargv[optind]); 643 peek = getwc(fin); 644 } else 645 break; 646 } else { 647 if (fin != stdin) 648 (void) fclose(fin); 649 if (!yyline) 650 error("Cannot read from -- standard input"); 651 else 652 break; 653 } 654 } 655 if (c == EOF) { 656 eof = TRUE; 657 return (0); 658 } 659 if (c == '\n') 660 yyline++; 661 return (c); 662 } 663 664 int 665 mn2(int a, int d, int c) 666 { 667 if (tptr >= treesize) { 668 tptr++; 669 error("Parse tree too big %s", 670 (treesize == TREESIZE ? "\nTry using %e num" : "")); 671 } 672 if (d >= treesize) { 673 error("Parse error"); 674 } 675 name[tptr] = a; 676 left[tptr] = d; 677 right[tptr] = c; 678 parent[tptr] = 0; 679 nullstr[tptr] = 0; 680 switch (a) { 681 case RSTR: 682 parent[d] = tptr; 683 break; 684 case BAR: 685 case RNEWE: 686 if (nullstr[d] || nullstr[c]) 687 nullstr[tptr] = TRUE; 688 parent[d] = parent[c] = tptr; 689 break; 690 case RCAT: 691 case DIV: 692 if (nullstr[d] && nullstr[c]) 693 nullstr[tptr] = TRUE; 694 parent[d] = parent[c] = tptr; 695 break; 696 /* XCU4: add RXSCON */ 697 case RXSCON: 698 case RSCON: 699 parent[d] = tptr; 700 nullstr[tptr] = nullstr[d]; 701 break; 702 #ifdef DEBUG 703 default: 704 warning("bad switch mn2 %d %d", a, d); 705 break; 706 #endif 707 } 708 return (tptr++); 709 } 710 711 int 712 mn1(int a, int d) 713 { 714 if (tptr >= treesize) { 715 tptr++; 716 error("Parse tree too big %s", 717 (treesize == TREESIZE ? "\nTry using %e num" : "")); 718 } 719 name[tptr] = a; 720 left[tptr] = d; 721 parent[tptr] = 0; 722 nullstr[tptr] = 0; 723 switch (a) { 724 case RCCL: 725 case RNCCL: 726 if (slength((CHR *)d) == 0) 727 nullstr[tptr] = TRUE; 728 break; 729 case STAR: 730 case QUEST: 731 nullstr[tptr] = TRUE; 732 parent[d] = tptr; 733 break; 734 case PLUS: 735 case CARAT: 736 nullstr[tptr] = nullstr[d]; 737 parent[d] = tptr; 738 break; 739 case S2FINAL: 740 nullstr[tptr] = TRUE; 741 break; 742 #ifdef DEBUG 743 case FINAL: 744 case S1FINAL: 745 break; 746 default: 747 warning("bad switch mn1 %d %d", a, d); 748 break; 749 #endif 750 } 751 return (tptr++); 752 } 753 754 int 755 mn0(int a) 756 { 757 if (tptr >= treesize) { 758 tptr++; 759 error("Parse tree too big %s", 760 (treesize == TREESIZE ? "\nTry using %e num" : "")); 761 } 762 763 name[tptr] = a; 764 parent[tptr] = 0; 765 nullstr[tptr] = 0; 766 if (ISOPERATOR(a)) { 767 switch (a) { 768 case DOT: break; 769 case RNULLS: nullstr[tptr] = TRUE; break; 770 #ifdef DEBUG 771 default: 772 warning("bad switch mn0 %d", a); 773 break; 774 #endif 775 } 776 } 777 return (tptr++); 778 } 779 780 void 781 munput(int t, CHR *p) 782 { 783 int i, j; 784 if (t == 'c') { 785 *pushptr++ = peek; 786 peek = *p; 787 } else if (t == 's') { 788 *pushptr++ = peek; 789 peek = p[0]; 790 i = slength(p); 791 for (j = i - 1; j >= 1; j--) 792 *pushptr++ = p[j]; 793 } 794 if (pushptr >= pushc + TOKENSIZE) 795 error("Too many characters pushed"); 796 } 797 798 int 799 dupl(int n) 800 { 801 /* duplicate the subtree whose root is n, return ptr to it */ 802 int i; 803 i = name[n]; 804 if (!ISOPERATOR(i)) 805 return (mn0(i)); 806 switch (i) { 807 case DOT: 808 case RNULLS: 809 return (mn0(i)); 810 case RCCL: case RNCCL: case FINAL: case S1FINAL: case S2FINAL: 811 return (mn1(i, left[n])); 812 case STAR: case QUEST: case PLUS: case CARAT: 813 return (mn1(i, dupl(left[n]))); 814 815 /* XCU4: add RXSCON */ 816 case RSTR: case RSCON: case RXSCON: 817 return (mn2(i, dupl(left[n]), right[n])); 818 case BAR: case RNEWE: case RCAT: case DIV: 819 return (mn2(i, dupl(left[n]), dupl(right[n]))); 820 } 821 return (0); 822 } 823 824 #ifdef DEBUG 825 void 826 allprint(CHR c) 827 { 828 switch (c) { 829 case 014: 830 (void) printf("\\f"); 831 charc++; 832 break; 833 case '\n': 834 (void) printf("\\n"); 835 charc++; 836 break; 837 case '\t': 838 (void) printf("\\t"); 839 charc++; 840 break; 841 case '\b': 842 (void) printf("\\b"); 843 charc++; 844 break; 845 case ' ': 846 (void) printf("\\_"); 847 break; 848 default: 849 if (!iswprint(c)) { 850 printf("\\x%-2x", c); /* up to fashion. */ 851 charc += 3; 852 } else 853 (void) putwc(c, stdout); 854 break; 855 } 856 charc++; 857 } 858 859 void 860 strpt(CHR *s) 861 { 862 charc = 0; 863 while (*s) { 864 allprint(*s++); 865 if (charc > LINESIZE) { 866 charc = 0; 867 (void) printf("\n\t"); 868 } 869 } 870 } 871 872 void 873 sect1dump(void) 874 { 875 int i; 876 (void) printf("Sect 1:\n"); 877 if (def[0]) { 878 (void) printf("str trans\n"); 879 i = -1; 880 while (def[++i]) 881 (void) printf("%ws\t%ws\n", def[i], subs[i]); 882 } 883 if (sname[0]) { 884 (void) printf("start names\n"); 885 i = -1; 886 while (sname[++i]) 887 (void) printf("%ws\n", sname[i]); 888 } 889 if (chset == TRUE) { 890 (void) printf("char set changed\n"); 891 for (i = 1; i < NCH; i++) { 892 if (i != ctable[i]) { 893 allprint(i); 894 (void) putchar(' '); 895 iswprint(ctable[i]) ? 896 (void) putwc(ctable[i], stdout) : 897 (void) printf("%d", ctable[i]); 898 (void) putchar('\n'); 899 } 900 } 901 } 902 } 903 904 void 905 sect2dump(void) 906 { 907 (void) printf("Sect 2:\n"); 908 treedump(); 909 } 910 911 void 912 treedump(void) 913 { 914 int t; 915 CHR *p; 916 (void) printf("treedump %d nodes:\n", tptr); 917 for (t = 0; t < tptr; t++) { 918 (void) printf("%4d ", t); 919 parent[t] ? (void) printf("p=%4d", parent[t]) : 920 (void) printf(" "); 921 (void) printf(" "); 922 if (!ISOPERATOR(name[t])) { 923 allprint(name[t]); 924 } else 925 switch (name[t]) { 926 case RSTR: 927 (void) printf("%d ", left[t]); 928 allprint(right[t]); 929 break; 930 case RCCL: 931 (void) printf("ccl "); 932 strpt(left[t]); 933 break; 934 case RNCCL: 935 (void) printf("nccl "); 936 strpt(left[t]); 937 break; 938 case DIV: 939 (void) printf("/ %d %d", left[t], right[t]); 940 break; 941 case BAR: 942 (void) printf("| %d %d", left[t], right[t]); 943 break; 944 case RCAT: 945 (void) printf("cat %d %d", left[t], right[t]); 946 break; 947 case PLUS: 948 (void) printf("+ %d", left[t]); 949 break; 950 case STAR: 951 (void) printf("* %d", left[t]); 952 break; 953 case CARAT: 954 (void) printf("^ %d", left[t]); 955 break; 956 case QUEST: 957 (void) printf("? %d", left[t]); 958 break; 959 case RNULLS: 960 (void) printf("nullstring"); 961 break; 962 case FINAL: 963 (void) printf("final %d", left[t]); 964 break; 965 case S1FINAL: 966 (void) printf("s1final %d", left[t]); 967 break; 968 case S2FINAL: 969 (void) printf("s2final %d", left[t]); 970 break; 971 case RNEWE: 972 (void) printf("new %d %d", left[t], right[t]); 973 break; 974 975 /* XCU4: add RXSCON */ 976 case RXSCON: 977 p = (CHR *)right[t]; 978 (void) printf("exstart %s", sname[*p++-1]); 979 while (*p) 980 (void) printf(", %ws", sname[*p++-1]); 981 (void) printf(" %d", left[t]); 982 break; 983 case RSCON: 984 p = (CHR *)right[t]; 985 (void) printf("start %s", sname[*p++-1]); 986 while (*p) 987 (void) printf(", %ws", sname[*p++-1]); 988 (void) printf(" %d", left[t]); 989 break; 990 case DOT: 991 printf("dot"); 992 break; 993 default: 994 (void) printf( 995 "unknown %d %d %d", name[t], left[t], right[t]); 996 break; 997 } 998 if (nullstr[t]) 999 (void) printf("\t(null poss.)"); 1000 (void) putchar('\n'); 1001 } 1002 } 1003 #endif 1004