1 #ifndef lint
2 static char sccsid[] = "@(#)sub1.c 4.6 (Berkeley) 02/16/92";
3 #endif
4
5 # include "ldefs.c"
6 # if __STDC__
7 # include <stdarg.h>
8 # else
9 # include <varargs.h>
10 #endif
11
12 char *
getl(p)13 getl(p) /* return next line of input, throw away trailing '\n' */
14 /* returns 0 if eof is had immediately */
15 char *p;
16 {
17 register int c;
18 register char *s, *t;
19 t = s = p;
20 while(((c = gch()) != 0) && c != '\n')
21 *t++ = c;
22 *t = 0;
23 if(c == 0 && s == t) return(0);
24 prev = '\n';
25 pres = '\n';
26 return(s);
27 }
space(ch)28 space(ch)
29 {
30 switch(ch)
31 {
32 case ' ':
33 case '\t':
34 case '\n':
35 return(1);
36 }
37 return(0);
38 }
39
digit(c)40 digit(c)
41 {
42 return(c>='0' && c <= '9');
43 }
44
45 #if __STDC__
error(char * s,...)46 error(char *s, ...)
47 #else
48 error(s, va_alist)
49 char *s;
50 va_dcl
51 #endif
52 {
53 va_list ap;
54
55 fprintf(errorf,"\"%s\", line %d: (Error) ",
56 fptr > 0 ? sargv[fptr] : "<stdin>", yyline);
57 #if __STDC__
58 va_start(ap, s);
59 #else
60 va_start(ap);
61 #endif
62 vfprintf(errorf, s, ap);
63 va_end(ap);
64 putc('\n', errorf);
65 # ifdef DEBUG
66 if(debug && sect != ENDSECTION) {
67 sect1dump();
68 sect2dump();
69 }
70 # endif
71 if(
72 # ifdef DEBUG
73 debug ||
74 # endif
75 report == 1) statistics();
76 exit(1); /* error return code */
77 }
78
79 #if __STDC__
warning(char * s,...)80 warning(char *s, ...)
81 #else
82 warning(s, va_alist)
83 char *s;
84 va_dcl
85 #endif
86 {
87 va_list ap;
88
89 fprintf(errorf,"\"%s\", line %d: (Warning) ",
90 fptr > 0 ? sargv[fptr] : "<stdin>", yyline);
91 #if __STDC__
92 va_start(ap, s);
93 #else
94 va_start(ap);
95 #endif
96 vfprintf(errorf, s, ap);
97 va_end(ap);
98 putc('\n',errorf);
99 fflush(errorf);
100 fflush(fout);
101 fflush(stdout);
102 }
index(a,s)103 index(a,s)
104 char *s;
105 {
106 register int k;
107 for(k=0; s[k]; k++)
108 if (s[k]== a)
109 return(k);
110 return(-1);
111 }
112
alpha(c)113 alpha(c)
114 int c; {
115 # ifdef ASCII
116 return('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z');
117 # endif
118 # ifdef EBCDIC
119 return(index(c,"abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") >= 0);
120 # endif
121 }
printable(c)122 printable(c)
123 {
124 # ifdef ASCII
125 return( c>040 && c < 0177);
126 # endif
127 # ifdef EBCDIC
128 return(index(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,;:><+*)('&%!-=\"")>=0);
129 # endif
130 }
lgate()131 lgate()
132 {
133 char fname[20];
134 if (lgatflg) return;
135 lgatflg=1;
136 if(fout == NULL){
137 sprintf(fname, "lex.yy.%c", ratfor ? 'r' : 'c' );
138 fout = fopen(fname, "w");
139 }
140 if(fout == NULL) error("Can't open %s",fname);
141 if(ratfor) fprintf( fout, "#\n");
142 phead1();
143 }
144 /* scopy(ptr to str, ptr to str) - copy first arg str to second */
145 /* returns ptr to second arg */
scopy(s,t)146 scopy(s,t)
147 char *s, *t; {
148 register char *i;
149 i = t;
150 while(*i++ = *s++);
151 return;
152 }
siconv(t)153 siconv(t) /* convert string t, return integer value */
154 char *t; {
155 register int i,sw;
156 register char *s;
157 s = t;
158 while(!(('0' <= *s && *s <= '9') || *s == '-') && *s) s++;
159 sw = 0;
160 if(*s == '-'){ /* neg */
161 sw = 1;
162 s++;
163 }
164 i = 0;
165 while('0' <= *s && *s <= '9')
166 i = i * 10 + (*(s++)-'0');
167 return(sw ? -i : i);
168 }
169 /* slength(ptr to str) - return integer length of string arg */
170 /* excludes '\0' terminator */
slength(s)171 slength(s)
172 char *s; {
173 register int n;
174 register char *t;
175 t = s;
176 for (n = 0; *t++; n++);
177 return(n);
178 }
179 /* scomp(x,y) - return -1 if x < y,
180 0 if x == y,
181 return 1 if x > y, all lexicographically */
scomp(x,y)182 scomp(x,y)
183 char *x,*y; {
184 register char *a,*d;
185 a = x;
186 d = y;
187 while(*a || *d){
188 if(*a > *d)
189 return(1); /* greater */
190 if(*a < *d)
191 return(-1); /* less */
192 a++;
193 d++;
194 }
195 return(0); /* equal */
196 }
ctrans(ss)197 ctrans(ss)
198 char **ss;
199 {
200 register int c, k;
201 if ((c = **ss) != '\\')
202 return(c);
203 switch(c= *++*ss)
204 {
205 case 'n': c = '\n'; break;
206 case 't': c = '\t'; break;
207 case 'r': c = '\r'; break;
208 case 'b': c = '\b'; break;
209 case 'f': c = 014; break; /* form feed for ascii */
210 case '\\': c = '\\'; break;
211 case '0': case '1': case '2': case '3':
212 case '4': case '5': case '6': case '7':
213 c -= '0';
214 while ((k = *(*ss+1)) >= '0' && k <= '7')
215 {
216 c = c*8 + k - '0';
217 (*ss)++;
218 }
219 break;
220 }
221 return(c);
222 }
cclinter(sw)223 cclinter(sw)
224 int sw; {
225 /* sw = 1 ==> ccl */
226 register int i, j, k;
227 int m;
228 if(!sw){ /* is NCCL */
229 for(i=1;i<NCH;i++)
230 symbol[i] ^= 1; /* reverse value */
231 }
232 for(i=1;i<NCH;i++)
233 if(symbol[i]) break;
234 if(i >= NCH) return;
235 i = cindex[i];
236 /* see if ccl is already in our table */
237 j = 0;
238 if(i){
239 for(j=1;j<NCH;j++){
240 if((symbol[j] && cindex[j] != i) ||
241 (!symbol[j] && cindex[j] == i)) break;
242 }
243 }
244 if(j >= NCH) return; /* already in */
245 m = 0;
246 k = 0;
247 for(i=1;i<NCH;i++)
248 if(symbol[i]){
249 if(!cindex[i]){
250 cindex[i] = ccount;
251 symbol[i] = 0;
252 m = 1;
253 }
254 else k = 1;
255 }
256 /* m == 1 implies last value of ccount has been used */
257 if(m)ccount++;
258 if(k == 0) return; /* is now in as ccount wholly */
259 /* intersection must be computed */
260 for(i=1;i<NCH;i++){
261 if(symbol[i]){
262 m = 0;
263 j = cindex[i]; /* will be non-zero */
264 for(k=1;k<NCH;k++){
265 if(cindex[k] == j){
266 if(symbol[k]) symbol[k] = 0;
267 else {
268 cindex[k] = ccount;
269 m = 1;
270 }
271 }
272 }
273 if(m)ccount++;
274 }
275 }
276 return;
277 }
usescape(c)278 usescape(c)
279 int c; {
280 register char d;
281 switch(c){
282 case 'n': c = '\n'; break;
283 case 'r': c = '\r'; break;
284 case 't': c = '\t'; break;
285 case 'b': c = '\b'; break;
286 case 'f': c = 014; break; /* form feed for ascii */
287 case '0': case '1': case '2': case '3':
288 case '4': case '5': case '6': case '7':
289 c -= '0';
290 while('0' <= (d=gch()) && d <= '7'){
291 c = c * 8 + (d-'0');
292 if(!('0' <= peek && peek <= '7')) break;
293 }
294 break;
295 }
296 return(c);
297 }
lookup(s,t)298 lookup(s,t)
299 char *s;
300 char **t; {
301 register int i;
302 i = 0;
303 while(*t){
304 if(scomp(s,*t) == 0)
305 return(i);
306 i++;
307 t++;
308 }
309 return(-1);
310 }
cpyact()311 cpyact(){ /* copy C action to the next ; or closing } */
312 register int brac, c, mth;
313 int savline, sw;
314
315 brac = 0;
316 sw = TRUE;
317
318 while(!eof){
319 c = gch();
320 swt:
321 switch( c ){
322
323 case '|': if(brac == 0 && sw == TRUE){
324 if(peek == '|')gch(); /* eat up an extra '|' */
325 return(0);
326 }
327 break;
328
329 case ';':
330 if( brac == 0 ){
331 putc(c,fout);
332 putc('\n',fout);
333 return(1);
334 }
335 break;
336
337 case '{':
338 brac++;
339 savline=yyline;
340 break;
341
342 case '}':
343 brac--;
344 if( brac == 0 ){
345 putc(c,fout);
346 putc('\n',fout);
347 return(1);
348 }
349 break;
350
351 case '/': /* look for comments */
352 putc(c,fout);
353 c = gch();
354 if( c != '*' ) goto swt;
355
356 /* it really is a comment */
357
358 putc(c,fout);
359 savline=yyline;
360 while( c=gch() ){
361 if( c=='*' ){
362 putc(c,fout);
363 if( (c=gch()) == '/' ) goto loop;
364 }
365 putc(c,fout);
366 }
367 yyline=savline;
368 error( "EOF inside comment" );
369
370 case '\'': /* character constant */
371 mth = '\'';
372 goto string;
373
374 case '"': /* character string */
375 mth = '"';
376
377 string:
378
379 putc(c,fout);
380 while( c=gch() ){
381 if( c=='\\' ){
382 putc(c,fout);
383 c=gch();
384 }
385 else if( c==mth ) goto loop;
386 putc(c,fout);
387 if (c == '\n')
388 {
389 yyline--;
390 error( "Non-terminated string or character constant");
391 }
392 }
393 error( "EOF in string or character constant" );
394
395 case '\0':
396 yyline = savline;
397 error("Action does not terminate");
398 default:
399 break; /* usual character */
400 }
401 loop:
402 if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;
403 putc(c,fout);
404 }
405 error("Premature EOF");
406 }
gch()407 gch(){
408 register int c;
409 static int hadeof;
410
411 if (hadeof) {
412 hadeof = 0;
413 yyline = 0;
414 }
415 prev = pres;
416 c = pres = peek;
417 peek = pushptr > pushc ? *--pushptr : getc(fin);
418 if(peek == EOF && sargc > 1){
419 hadeof = 1;
420 fclose(fin);
421 fin = fopen(sargv[++fptr],"r");
422 if(fin == NULL) {
423 yyline = 0;
424 error("Cannot open file %s",sargv[fptr]);
425 }
426 peek = getc(fin);
427 sargc--;
428 }
429 if(c == EOF) {
430 eof = TRUE;
431 fclose(fin);
432 return(0);
433 }
434 if(c == '\n')yyline++;
435 return(c);
436 }
mn2(a,d,c)437 mn2(a,d,c)
438 int a,d,c;
439 {
440 name[tptr] = a;
441 left[tptr] = d;
442 right[tptr] = c;
443 parent[tptr] = 0;
444 nullstr[tptr] = 0;
445 switch(a){
446 case RSTR:
447 parent[d] = tptr;
448 break;
449 case BAR:
450 case RNEWE:
451 if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE;
452 parent[d] = parent[c] = tptr;
453 break;
454 case RCAT:
455 case DIV:
456 if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE;
457 parent[d] = parent[c] = tptr;
458 break;
459 case RSCON:
460 parent[d] = tptr;
461 nullstr[tptr] = nullstr[d];
462 break;
463 # ifdef DEBUG
464 default:
465 warning("bad switch mn2 %d %d",a,d);
466 break;
467 # endif
468 }
469 if(tptr > treesize)
470 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
471 return(tptr++);
472 }
mn1(a,d)473 mn1(a,d)
474 int a,d;
475 {
476 name[tptr] = a;
477 left[tptr] = d;
478 parent[tptr] = 0;
479 nullstr[tptr] = 0;
480 switch(a){
481 case RCCL:
482 case RNCCL:
483 if(slength(d) == 0) nullstr[tptr] = TRUE;
484 break;
485 case STAR:
486 case QUEST:
487 nullstr[tptr] = TRUE;
488 parent[d] = tptr;
489 break;
490 case PLUS:
491 case CARAT:
492 nullstr[tptr] = nullstr[d];
493 parent[d] = tptr;
494 break;
495 case S2FINAL:
496 nullstr[tptr] = TRUE;
497 break;
498 # ifdef DEBUG
499 case FINAL:
500 case S1FINAL:
501 break;
502 default:
503 warning("bad switch mn1 %d %d",a,d);
504 break;
505 # endif
506 }
507 if(tptr > treesize)
508 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
509 return(tptr++);
510 }
mn0(a)511 mn0(a)
512 int a;
513 {
514 name[tptr] = a;
515 parent[tptr] = 0;
516 nullstr[tptr] = 0;
517 if(a >= NCH) switch(a){
518 case RNULLS: nullstr[tptr] = TRUE; break;
519 # ifdef DEBUG
520 default:
521 warning("bad switch mn0 %d",a);
522 break;
523 # endif
524 }
525 if(tptr > treesize)
526 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
527 return(tptr++);
528 }
munput(t,p)529 munput(t,p) /* implementation dependent */
530 char *p;
531 int t; {
532 register int i,j;
533 if(t == 'c'){
534 *pushptr++ = peek; /* watch out for this */
535 peek = (int)p;
536 }
537 else if(t == 's'){
538 *pushptr++ = peek;
539 peek = p[0];
540 i = slength(p);
541 for(j = i-1; j>=1; j--)
542 *pushptr++ = p[j];
543 }
544 # ifdef DEBUG
545 else error("Unrecognized munput option %c",t);
546 # endif
547 if(pushptr >= pushc+TOKENSIZE)
548 error("Too many characters pushed");
549 return;
550 }
551
dupl(n)552 dupl(n)
553 int n; {
554 /* duplicate the subtree whose root is n, return ptr to it */
555 register int i;
556 i = name[n];
557 if(i < NCH) return(mn0(i));
558 switch(i){
559 case RNULLS:
560 return(mn0(i));
561 case RCCL: case RNCCL: case FINAL: case S1FINAL: case S2FINAL:
562 return(mn1(i,left[n]));
563 case STAR: case QUEST: case PLUS: case CARAT:
564 return(mn1(i,dupl(left[n])));
565 case RSTR: case RSCON:
566 return(mn2(i,dupl(left[n]),right[n]));
567 case BAR: case RNEWE: case RCAT: case DIV:
568 return(mn2(i,dupl(left[n]),dupl(right[n])));
569 # ifdef DEBUG
570 default:
571 warning("bad switch dupl %d",n);
572 # endif
573 }
574 return(0);
575 }
576 # ifdef DEBUG
allprint(c)577 allprint(c)
578 char c; {
579 switch(c){
580 case 014:
581 printf("\\f");
582 charc++;
583 break;
584 case '\n':
585 printf("\\n");
586 charc++;
587 break;
588 case '\t':
589 printf("\\t");
590 charc++;
591 break;
592 case '\b':
593 printf("\\b");
594 charc++;
595 break;
596 case ' ':
597 printf("\\\bb");
598 break;
599 default:
600 if(!printable(c)){
601 printf("\\%-3o",c);
602 charc += 3;
603 }
604 else
605 putchar(c);
606 break;
607 }
608 charc++;
609 return;
610 }
strpt(s)611 strpt(s)
612 char *s; {
613 charc = 0;
614 while(*s){
615 allprint(*s++);
616 if(charc > LINESIZE){
617 charc = 0;
618 printf("\n\t");
619 }
620 }
621 return;
622 }
sect1dump()623 sect1dump(){
624 register int i;
625 printf("Sect 1:\n");
626 if(def[0]){
627 printf("str trans\n");
628 i = -1;
629 while(def[++i])
630 printf("%s\t%s\n",def[i],subs[i]);
631 }
632 if(sname[0]){
633 printf("start names\n");
634 i = -1;
635 while(sname[++i])
636 printf("%s\n",sname[i]);
637 }
638 if(chset == TRUE){
639 printf("char set changed\n");
640 for(i=1;i<NCH;i++){
641 if(i != ctable[i]){
642 allprint(i);
643 putchar(' ');
644 printable(ctable[i]) ? putchar(ctable[i]) : printf("%d",ctable[i]);
645 putchar('\n');
646 }
647 }
648 }
649 }
sect2dump()650 sect2dump(){
651 printf("Sect 2:\n");
652 treedump();
653 }
treedump()654 treedump()
655 {
656 register int t;
657 register char *p;
658 printf("treedump %d nodes:\n",tptr);
659 for(t=0;t<tptr;t++){
660 printf("%4d ",t);
661 parent[t] ? printf("p=%4d",parent[t]) : printf(" ");
662 printf(" ");
663 if(name[t] < NCH) {
664 allprint(name[t]);
665 }
666 else switch(name[t]){
667 case RSTR:
668 printf("%d ",left[t]);
669 allprint(right[t]);
670 break;
671 case RCCL:
672 printf("ccl ");
673 strpt(left[t]);
674 break;
675 case RNCCL:
676 printf("nccl ");
677 strpt(left[t]);
678 break;
679 case DIV:
680 printf("/ %d %d",left[t],right[t]);
681 break;
682 case BAR:
683 printf("| %d %d",left[t],right[t]);
684 break;
685 case RCAT:
686 printf("cat %d %d",left[t],right[t]);
687 break;
688 case PLUS:
689 printf("+ %d",left[t]);
690 break;
691 case STAR:
692 printf("* %d",left[t]);
693 break;
694 case CARAT:
695 printf("^ %d",left[t]);
696 break;
697 case QUEST:
698 printf("? %d",left[t]);
699 break;
700 case RNULLS:
701 printf("nullstring");
702 break;
703 case FINAL:
704 printf("final %d",left[t]);
705 break;
706 case S1FINAL:
707 printf("s1final %d",left[t]);
708 break;
709 case S2FINAL:
710 printf("s2final %d",left[t]);
711 break;
712 case RNEWE:
713 printf("new %d %d",left[t],right[t]);
714 break;
715 case RSCON:
716 p = right[t];
717 printf("start %s",sname[*p++-1]);
718 while(*p)
719 printf(", %s",sname[*p++-1]);
720 printf(" %d",left[t]);
721 break;
722 default:
723 printf("unknown %d %d %d",name[t],left[t],right[t]);
724 break;
725 }
726 if(nullstr[t])printf("\t(null poss.)");
727 putchar('\n');
728 }
729 }
730 # endif
731