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