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 *
getl(CHR * p)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
space(int ch)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
digit(int c)86 digit(int c)
87 {
88 return (c >= '0' && c <= '9');
89 }
90
91 void
error(char * s,...)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
error_tail(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
warning(char * s,...)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
index(int a,CHR * s)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
alpha(int c)173 alpha(int c)
174 {
175 return (('a' <= c && c <= 'z') ||
176 ('A' <= c && c <= 'Z'));
177 }
178
179 int
printable(int c)180 printable(int c)
181 {
182 return (c > 040 && c < 0177);
183 }
184
185 void
lgate(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
scopy(CHR * s,CHR * t)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
siconv(CHR * t)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
slength(CHR * s)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
scomp(CHR * x,CHR * y)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
ctrans(CHR ** ss)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
cclinter(int sw)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
usescape(int c)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
lookup(CHR * s,CHR ** t)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
cpycom(CHR * p)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
cpyact(void)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
gch(void)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
mn2(int a,int d,int c)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
mn1(int a,int d)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
mn0(int a)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
munput(int t,CHR * p)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
dupl(int n)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
allprint(CHR c)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
strpt(CHR * s)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
sect1dump(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
sect2dump(void)916 sect2dump(void)
917 {
918 (void) printf("Sect 2:\n");
919 treedump();
920 }
921
922 void
treedump(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