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