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