xref: /original-bsd/old/lex/sub1.c (revision 13ec26c3)
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 *
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 	}
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 
40 digit(c)
41 {
42 	return(c>='0' && c <= '9');
43 }
44 
45 #if __STDC__
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__
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 	}
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 
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 }
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 }
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 */
146 scopy(s,t)
147   char *s, *t; {
148 	register char *i;
149 	i = t;
150 	while(*i++ = *s++);
151 	return;
152 	}
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 */
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 */
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 	}
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 }
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 	}
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 	}
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 	}
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 }
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 	}
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 	}
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 	}
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 	}
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 
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
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 	}
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 	}
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 	}
650 sect2dump(){
651 	printf("Sect 2:\n");
652 	treedump();
653 	}
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