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