xref: /plan9/sys/src/cmd/lex/sub1.c (revision 169d3509e3830be480b499459c3245b23637fe07)
13e12c5d1SDavid du Colombier # include "ldefs.h"
23e12c5d1SDavid du Colombier uchar *
getl(uchar * p)33e12c5d1SDavid du Colombier getl(uchar *p)	/* return next line of input, throw away trailing '\n' */
43e12c5d1SDavid du Colombier 	/* returns 0 if eof is had immediately */
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 	int c;
73e12c5d1SDavid du Colombier 	uchar *s, *t;
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier 	t = s = p;
103e12c5d1SDavid du Colombier 	while(((c = gch()) != 0) && c != '\n')
113e12c5d1SDavid du Colombier 		*t++ = c;
123e12c5d1SDavid du Colombier 	*t = 0;
133e12c5d1SDavid du Colombier 	if(c == 0 && s == t) return((uchar *)0);
143e12c5d1SDavid du Colombier 	prev = '\n';
153e12c5d1SDavid du Colombier 	pres = '\n';
163e12c5d1SDavid du Colombier 	return(s);
173e12c5d1SDavid du Colombier }
183e12c5d1SDavid du Colombier 
193e12c5d1SDavid du Colombier void
printerr(char * type,char * fmt,va_list argl)20219b2ee8SDavid du Colombier printerr(char *type, char *fmt, va_list argl)
21219b2ee8SDavid du Colombier {
22219b2ee8SDavid du Colombier 	char buf[1024];
23219b2ee8SDavid du Colombier 
24ce6131d3SDavid du Colombier 	if(!eof)fprint(errorf,"%s:%d  ", yyfile, yyline);
25219b2ee8SDavid du Colombier 	fprint(errorf,"(%s) ", type);
269a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, argl);
27219b2ee8SDavid du Colombier 	fprint(errorf, "%s\n", buf);
28219b2ee8SDavid du Colombier }
29219b2ee8SDavid du Colombier 
30219b2ee8SDavid du Colombier 
31219b2ee8SDavid du Colombier void
error(char * s,...)323e12c5d1SDavid du Colombier error(char *s,...)
333e12c5d1SDavid du Colombier {
343e12c5d1SDavid du Colombier 	va_list argl;
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier 	va_start(argl, s);
37219b2ee8SDavid du Colombier 	printerr("Error", s, argl);
383e12c5d1SDavid du Colombier 	va_end(argl);
393e12c5d1SDavid du Colombier # ifdef DEBUG
403e12c5d1SDavid du Colombier 	if(debug && sect != ENDSECTION) {
413e12c5d1SDavid du Colombier 		sect1dump();
423e12c5d1SDavid du Colombier 		sect2dump();
433e12c5d1SDavid du Colombier 	}
443e12c5d1SDavid du Colombier # endif
453e12c5d1SDavid du Colombier 	if(
463e12c5d1SDavid du Colombier # ifdef DEBUG
473e12c5d1SDavid du Colombier 		debug ||
483e12c5d1SDavid du Colombier # endif
493e12c5d1SDavid du Colombier 		report == 1) statistics();
503e12c5d1SDavid du Colombier 	exits("error");	/* error return code */
513e12c5d1SDavid du Colombier }
523e12c5d1SDavid du Colombier 
533e12c5d1SDavid du Colombier void
warning(char * s,...)543e12c5d1SDavid du Colombier warning(char *s,...)
553e12c5d1SDavid du Colombier {
563e12c5d1SDavid du Colombier 	va_list argl;
573e12c5d1SDavid du Colombier 
583e12c5d1SDavid du Colombier 	va_start(argl, s);
59219b2ee8SDavid du Colombier 	printerr("Warning", s, argl);
60219b2ee8SDavid du Colombier 	va_end(argl);
61219b2ee8SDavid du Colombier 	Bflush(&fout);
623e12c5d1SDavid du Colombier }
633e12c5d1SDavid du Colombier 
643e12c5d1SDavid du Colombier void
lgate(void)653e12c5d1SDavid du Colombier lgate(void)
663e12c5d1SDavid du Colombier {
67219b2ee8SDavid du Colombier 	int fd;
68219b2ee8SDavid du Colombier 
693e12c5d1SDavid du Colombier 	if (lgatflg) return;
703e12c5d1SDavid du Colombier 	lgatflg=1;
71219b2ee8SDavid du Colombier 	if(foutopen == 0){
72219b2ee8SDavid du Colombier 		fd = create("lex.yy.c", OWRITE, 0666);
73219b2ee8SDavid du Colombier 		if(fd < 0)
74ce6131d3SDavid du Colombier 			error("Can't open lex.yy.c: %r");
75219b2ee8SDavid du Colombier 		Binit(&fout, fd, OWRITE);
76219b2ee8SDavid du Colombier 		foutopen = 1;
773e12c5d1SDavid du Colombier 		}
783e12c5d1SDavid du Colombier 	phead1();
793e12c5d1SDavid du Colombier }
803e12c5d1SDavid du Colombier 
813e12c5d1SDavid du Colombier void
cclinter(int sw)823e12c5d1SDavid du Colombier cclinter(int sw)
833e12c5d1SDavid du Colombier {
843e12c5d1SDavid du Colombier 		/* sw = 1 ==> ccl */
853e12c5d1SDavid du Colombier 	int i, j, k;
863e12c5d1SDavid du Colombier 	int m;
873e12c5d1SDavid du Colombier 	if(!sw){		/* is NCCL */
883e12c5d1SDavid du Colombier 		for(i=1;i<NCH;i++)
893e12c5d1SDavid du Colombier 			symbol[i] ^= 1;			/* reverse value */
903e12c5d1SDavid du Colombier 	}
913e12c5d1SDavid du Colombier 	for(i=1;i<NCH;i++)
923e12c5d1SDavid du Colombier 		if(symbol[i]) break;
933e12c5d1SDavid du Colombier 	if(i >= NCH) return;
943e12c5d1SDavid du Colombier 	i = cindex[i];
953e12c5d1SDavid du Colombier 	/* see if ccl is already in our table */
963e12c5d1SDavid du Colombier 	j = 0;
973e12c5d1SDavid du Colombier 	if(i){
983e12c5d1SDavid du Colombier 		for(j=1;j<NCH;j++){
993e12c5d1SDavid du Colombier 			if((symbol[j] && cindex[j] != i) ||
1003e12c5d1SDavid du Colombier 			   (!symbol[j] && cindex[j] == i)) break;
1013e12c5d1SDavid du Colombier 		}
1023e12c5d1SDavid du Colombier 	}
1033e12c5d1SDavid du Colombier 	if(j >= NCH) return;		/* already in */
1043e12c5d1SDavid du Colombier 	m = 0;
1053e12c5d1SDavid du Colombier 	k = 0;
1063e12c5d1SDavid du Colombier 	for(i=1;i<NCH;i++)
1073e12c5d1SDavid du Colombier 		if(symbol[i]){
1083e12c5d1SDavid du Colombier 			if(!cindex[i]){
1093e12c5d1SDavid du Colombier 				cindex[i] = ccount;
1103e12c5d1SDavid du Colombier 				symbol[i] = 0;
1113e12c5d1SDavid du Colombier 				m = 1;
1123e12c5d1SDavid du Colombier 			} else k = 1;
1133e12c5d1SDavid du Colombier 		}
1143e12c5d1SDavid du Colombier 			/* m == 1 implies last value of ccount has been used */
1153e12c5d1SDavid du Colombier 	if(m)ccount++;
1163e12c5d1SDavid du Colombier 	if(k == 0) return;	/* is now in as ccount wholly */
1173e12c5d1SDavid du Colombier 	/* intersection must be computed */
1183e12c5d1SDavid du Colombier 	for(i=1;i<NCH;i++){
1193e12c5d1SDavid du Colombier 		if(symbol[i]){
1203e12c5d1SDavid du Colombier 			m = 0;
1213e12c5d1SDavid du Colombier 			j = cindex[i];	/* will be non-zero */
1223e12c5d1SDavid du Colombier 			for(k=1;k<NCH;k++){
1233e12c5d1SDavid du Colombier 				if(cindex[k] == j){
1243e12c5d1SDavid du Colombier 					if(symbol[k]) symbol[k] = 0;
1253e12c5d1SDavid du Colombier 					else {
1263e12c5d1SDavid du Colombier 						cindex[k] = ccount;
1273e12c5d1SDavid du Colombier 						m = 1;
1283e12c5d1SDavid du Colombier 					}
1293e12c5d1SDavid du Colombier 				}
1303e12c5d1SDavid du Colombier 			}
1313e12c5d1SDavid du Colombier 			if(m)ccount++;
1323e12c5d1SDavid du Colombier 		}
1333e12c5d1SDavid du Colombier 	}
1343e12c5d1SDavid du Colombier }
1353e12c5d1SDavid du Colombier 
1363e12c5d1SDavid du Colombier int
usescape(int c)1373e12c5d1SDavid du Colombier usescape(int c)
1383e12c5d1SDavid du Colombier {
1393e12c5d1SDavid du Colombier 	int d;
1403e12c5d1SDavid du Colombier 	switch(c){
1413e12c5d1SDavid du Colombier 	case 'n': c = '\n'; break;
1423e12c5d1SDavid du Colombier 	case 'r': c = '\r'; break;
1433e12c5d1SDavid du Colombier 	case 't': c = '\t'; break;
1443e12c5d1SDavid du Colombier 	case 'b': c = '\b'; break;
1453e12c5d1SDavid du Colombier 	case 'f': c = 014; break;		/* form feed for ascii */
1463e12c5d1SDavid du Colombier 	case '0': case '1': case '2': case '3':
1473e12c5d1SDavid du Colombier 	case '4': case '5': case '6': case '7':
1483e12c5d1SDavid du Colombier 		c -= '0';
1493e12c5d1SDavid du Colombier 		while('0' <= (d=gch()) && d <= '7'){
1503e12c5d1SDavid du Colombier 			c = c * 8 + (d-'0');
1513e12c5d1SDavid du Colombier 			if(!('0' <= peek && peek <= '7')) break;
1523e12c5d1SDavid du Colombier 			}
1533e12c5d1SDavid du Colombier 		break;
1543e12c5d1SDavid du Colombier 	}
1553e12c5d1SDavid du Colombier 	return(c);
1563e12c5d1SDavid du Colombier }
1573e12c5d1SDavid du Colombier 
1583e12c5d1SDavid du Colombier int
lookup(uchar * s,uchar ** t)1593e12c5d1SDavid du Colombier lookup(uchar *s, uchar **t)
1603e12c5d1SDavid du Colombier {
1613e12c5d1SDavid du Colombier 	int i;
1623e12c5d1SDavid du Colombier 	i = 0;
1633e12c5d1SDavid du Colombier 	while(*t){
1643e12c5d1SDavid du Colombier 		if(strcmp((char *)s, *(char **)t) == 0)
1653e12c5d1SDavid du Colombier 			return(i);
1663e12c5d1SDavid du Colombier 		i++;
1673e12c5d1SDavid du Colombier 		t++;
1683e12c5d1SDavid du Colombier 	}
1693e12c5d1SDavid du Colombier 	return(-1);
1703e12c5d1SDavid du Colombier }
1713e12c5d1SDavid du Colombier 
1723e12c5d1SDavid du Colombier int
cpyact(void)1733e12c5d1SDavid du Colombier cpyact(void)
1743e12c5d1SDavid du Colombier { /* copy C action to the next ; or closing } */
1753e12c5d1SDavid du Colombier 	int brac, c, mth;
1763e12c5d1SDavid du Colombier 	int savline, sw;
177ce6131d3SDavid du Colombier 	char *savfile;
1783e12c5d1SDavid du Colombier 
1793e12c5d1SDavid du Colombier 	brac = 0;
1803e12c5d1SDavid du Colombier 	sw = TRUE;
181219b2ee8SDavid du Colombier 	savline = 0;
182ce6131d3SDavid du Colombier 	savfile = "?";
1833e12c5d1SDavid du Colombier 
1843e12c5d1SDavid du Colombier while(!eof){
1853e12c5d1SDavid du Colombier 	c = gch();
1863e12c5d1SDavid du Colombier swt:
1873e12c5d1SDavid du Colombier 	switch( c ){
1883e12c5d1SDavid du Colombier 
1893e12c5d1SDavid du Colombier case '|':	if(brac == 0 && sw == TRUE){
1903e12c5d1SDavid du Colombier 			if(peek == '|')gch();		/* eat up an extra '|' */
1913e12c5d1SDavid du Colombier 			return(0);
1923e12c5d1SDavid du Colombier 		}
1933e12c5d1SDavid du Colombier 		break;
1943e12c5d1SDavid du Colombier 
1953e12c5d1SDavid du Colombier case ';':
1963e12c5d1SDavid du Colombier 		if( brac == 0 ){
197219b2ee8SDavid du Colombier 			Bputc(&fout, c);
198219b2ee8SDavid du Colombier 			Bputc(&fout, '\n');
1993e12c5d1SDavid du Colombier 			return(1);
2003e12c5d1SDavid du Colombier 		}
2013e12c5d1SDavid du Colombier 		break;
2023e12c5d1SDavid du Colombier 
2033e12c5d1SDavid du Colombier case '{':
2043e12c5d1SDavid du Colombier 		brac++;
2053e12c5d1SDavid du Colombier 		savline=yyline;
206ce6131d3SDavid du Colombier 		savfile=yyfile;
2073e12c5d1SDavid du Colombier 		break;
2083e12c5d1SDavid du Colombier 
2093e12c5d1SDavid du Colombier case '}':
2103e12c5d1SDavid du Colombier 		brac--;
2113e12c5d1SDavid du Colombier 		if( brac == 0 ){
212219b2ee8SDavid du Colombier 			Bputc(&fout, c);
213219b2ee8SDavid du Colombier 			Bputc(&fout, '\n');
2143e12c5d1SDavid du Colombier 			return(1);
2153e12c5d1SDavid du Colombier 		}
2163e12c5d1SDavid du Colombier 		break;
2173e12c5d1SDavid du Colombier 
2183e12c5d1SDavid du Colombier case '/':	/* look for comments */
219219b2ee8SDavid du Colombier 		Bputc(&fout, c);
2203e12c5d1SDavid du Colombier 		c = gch();
2213e12c5d1SDavid du Colombier 		if( c != '*' ) goto swt;
2223e12c5d1SDavid du Colombier 
2233e12c5d1SDavid du Colombier 		/* it really is a comment */
2243e12c5d1SDavid du Colombier 
225219b2ee8SDavid du Colombier 		Bputc(&fout, c);
2263e12c5d1SDavid du Colombier 		savline=yyline;
227ce6131d3SDavid du Colombier 		savfile=yyfile;
2283e12c5d1SDavid du Colombier 		while( c=gch() ){
2293e12c5d1SDavid du Colombier 			if( c=='*' ){
230219b2ee8SDavid du Colombier 				Bputc(&fout, c);
2313e12c5d1SDavid du Colombier 				if( (c=gch()) == '/' ) goto loop;
2323e12c5d1SDavid du Colombier 			}
233219b2ee8SDavid du Colombier 			Bputc(&fout, c);
2343e12c5d1SDavid du Colombier 		}
2353e12c5d1SDavid du Colombier 		yyline=savline;
236ce6131d3SDavid du Colombier 		yyfile=savfile;
2373e12c5d1SDavid du Colombier 		error( "EOF inside comment" );
2383e12c5d1SDavid du Colombier 
2393e12c5d1SDavid du Colombier case '\'':	/* character constant */
2403e12c5d1SDavid du Colombier 		mth = '\'';
2413e12c5d1SDavid du Colombier 		goto string;
2423e12c5d1SDavid du Colombier 
2433e12c5d1SDavid du Colombier case '"':	/* character string */
2443e12c5d1SDavid du Colombier 		mth = '"';
2453e12c5d1SDavid du Colombier 
2463e12c5d1SDavid du Colombier 	string:
2473e12c5d1SDavid du Colombier 
248219b2ee8SDavid du Colombier 		Bputc(&fout, c);
2493e12c5d1SDavid du Colombier 		while( c=gch() ){
2503e12c5d1SDavid du Colombier 			if( c=='\\' ){
251219b2ee8SDavid du Colombier 				Bputc(&fout, c);
2523e12c5d1SDavid du Colombier 				c=gch();
2533e12c5d1SDavid du Colombier 			}
2543e12c5d1SDavid du Colombier 			else if( c==mth ) goto loop;
255219b2ee8SDavid du Colombier 			Bputc(&fout, c);
2563e12c5d1SDavid du Colombier 			if (c == '\n') {
2573e12c5d1SDavid du Colombier 				yyline--;
2583e12c5d1SDavid du Colombier 				error( "Non-terminated string or character constant");
2593e12c5d1SDavid du Colombier 			}
2603e12c5d1SDavid du Colombier 		}
2613e12c5d1SDavid du Colombier 		error( "EOF in string or character constant" );
2623e12c5d1SDavid du Colombier 
2633e12c5d1SDavid du Colombier case '\0':
2643e12c5d1SDavid du Colombier 		yyline = savline;
265ce6131d3SDavid du Colombier 		yyfile = savfile;
2663e12c5d1SDavid du Colombier 		error("Action does not terminate");
2673e12c5d1SDavid du Colombier default:
2683e12c5d1SDavid du Colombier 		break;		/* usual character */
2693e12c5d1SDavid du Colombier 		}
2703e12c5d1SDavid du Colombier loop:
2713e12c5d1SDavid du Colombier 	if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;
272219b2ee8SDavid du Colombier 	Bputc(&fout, c);
2733e12c5d1SDavid du Colombier 	}
2743e12c5d1SDavid du Colombier 	error("Premature EOF");
275219b2ee8SDavid du Colombier 	return(0);
2763e12c5d1SDavid du Colombier }
2773e12c5d1SDavid du Colombier 
2783e12c5d1SDavid du Colombier int
gch(void)2793e12c5d1SDavid du Colombier gch(void){
2803e12c5d1SDavid du Colombier 	int c;
2813e12c5d1SDavid du Colombier 	prev = pres;
2823e12c5d1SDavid du Colombier 	c = pres = peek;
283219b2ee8SDavid du Colombier 	peek = pushptr > pushc ? *--pushptr : Bgetc(fin);
284219b2ee8SDavid du Colombier 	if(peek == Beof && sargc > 1){
285219b2ee8SDavid du Colombier 		Bterm(fin);
286ce6131d3SDavid du Colombier 		yyfile = sargv[fptr++];
287ce6131d3SDavid du Colombier 		fin = Bopen(yyfile,OREAD);
288219b2ee8SDavid du Colombier 		if(fin == 0)
289ce6131d3SDavid du Colombier 			error("%s - cannot open file: %r",yyfile);
290219b2ee8SDavid du Colombier 		peek = Bgetc(fin);
2913e12c5d1SDavid du Colombier 		sargc--;
2923e12c5d1SDavid du Colombier 		sargv++;
2933e12c5d1SDavid du Colombier 	}
294219b2ee8SDavid du Colombier 	if(c == Beof) {
2953e12c5d1SDavid du Colombier 		eof = TRUE;
296219b2ee8SDavid du Colombier 		Bterm(fin);
2977b6cd6eaSDavid du Colombier 		fin = 0;
2983e12c5d1SDavid du Colombier 		return(0);
2993e12c5d1SDavid du Colombier 	}
3003e12c5d1SDavid du Colombier 	if(c == '\n')yyline++;
3013e12c5d1SDavid du Colombier 	return(c);
3023e12c5d1SDavid du Colombier }
3033e12c5d1SDavid du Colombier 
3043e12c5d1SDavid du Colombier int
mn2(int a,int d,uintptr c)305*169d3509SDavid du Colombier mn2(int a, int d, uintptr c)
3063e12c5d1SDavid du Colombier {
3073e12c5d1SDavid du Colombier 	name[tptr] = a;
3083e12c5d1SDavid du Colombier 	left[tptr] = d;
3093e12c5d1SDavid du Colombier 	right[tptr] = c;
3103e12c5d1SDavid du Colombier 	parent[tptr] = 0;
3113e12c5d1SDavid du Colombier 	nullstr[tptr] = 0;
3123e12c5d1SDavid du Colombier 	switch(a){
3133e12c5d1SDavid du Colombier 	case RSTR:
3143e12c5d1SDavid du Colombier 		parent[d] = tptr;
3153e12c5d1SDavid du Colombier 		break;
3163e12c5d1SDavid du Colombier 	case BAR:
3173e12c5d1SDavid du Colombier 	case RNEWE:
3183e12c5d1SDavid du Colombier 		if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE;
3193e12c5d1SDavid du Colombier 		parent[d] = parent[c] = tptr;
3203e12c5d1SDavid du Colombier 		break;
3213e12c5d1SDavid du Colombier 	case RCAT:
3223e12c5d1SDavid du Colombier 	case DIV:
3233e12c5d1SDavid du Colombier 		if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE;
3243e12c5d1SDavid du Colombier 		parent[d] = parent[c] = tptr;
3253e12c5d1SDavid du Colombier 		break;
3263e12c5d1SDavid du Colombier 	case RSCON:
3273e12c5d1SDavid du Colombier 		parent[d] = tptr;
3283e12c5d1SDavid du Colombier 		nullstr[tptr] = nullstr[d];
3293e12c5d1SDavid du Colombier 		break;
3303e12c5d1SDavid du Colombier # ifdef DEBUG
3313e12c5d1SDavid du Colombier 	default:
3323e12c5d1SDavid du Colombier 		warning("bad switch mn2 %d %d",a,d);
3333e12c5d1SDavid du Colombier 		break;
3343e12c5d1SDavid du Colombier # endif
3353e12c5d1SDavid du Colombier 		}
3363e12c5d1SDavid du Colombier 	if(tptr > treesize)
3373e12c5d1SDavid du Colombier 		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
3383e12c5d1SDavid du Colombier 	return(tptr++);
3393e12c5d1SDavid du Colombier }
3403e12c5d1SDavid du Colombier 
3413e12c5d1SDavid du Colombier int
mnp(int a,void * p)34274f16c81SDavid du Colombier mnp(int a, void *p)
34374f16c81SDavid du Colombier {
34474f16c81SDavid du Colombier 	name[tptr] = a;
34574f16c81SDavid du Colombier 	left[tptr] = 0;
34674f16c81SDavid du Colombier 	parent[tptr] = 0;
34774f16c81SDavid du Colombier 	nullstr[tptr] = 0;
34874f16c81SDavid du Colombier 	ptr[tptr] = p;
34974f16c81SDavid du Colombier 	switch(a){
35074f16c81SDavid du Colombier 	case RCCL:
35174f16c81SDavid du Colombier 	case RNCCL:
35274f16c81SDavid du Colombier 		if(strlen(p) == 0) nullstr[tptr] = TRUE;
35374f16c81SDavid du Colombier 		break;
35474f16c81SDavid du Colombier 	default:
3551fa40b8eSDavid du Colombier 		error("bad switch mnp %d %P", a, p);
35674f16c81SDavid du Colombier 		break;
35774f16c81SDavid du Colombier 	}
35874f16c81SDavid du Colombier 	if(tptr > treesize)
35974f16c81SDavid du Colombier 		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
36074f16c81SDavid du Colombier 	return(tptr++);
36174f16c81SDavid du Colombier }
36274f16c81SDavid du Colombier 
36374f16c81SDavid du Colombier int
mn1(int a,int d)3643e12c5d1SDavid du Colombier mn1(int a, int d)
3653e12c5d1SDavid du Colombier {
3663e12c5d1SDavid du Colombier 	name[tptr] = a;
3673e12c5d1SDavid du Colombier 	left[tptr] = d;
3683e12c5d1SDavid du Colombier 	parent[tptr] = 0;
3693e12c5d1SDavid du Colombier 	nullstr[tptr] = 0;
3703e12c5d1SDavid du Colombier 	switch(a){
3713e12c5d1SDavid du Colombier 	case STAR:
3723e12c5d1SDavid du Colombier 	case QUEST:
3733e12c5d1SDavid du Colombier 		nullstr[tptr] = TRUE;
3743e12c5d1SDavid du Colombier 		parent[d] = tptr;
3753e12c5d1SDavid du Colombier 		break;
3763e12c5d1SDavid du Colombier 	case PLUS:
3773e12c5d1SDavid du Colombier 	case CARAT:
3783e12c5d1SDavid du Colombier 		nullstr[tptr] = nullstr[d];
3793e12c5d1SDavid du Colombier 		parent[d] = tptr;
3803e12c5d1SDavid du Colombier 		break;
3813e12c5d1SDavid du Colombier 	case S2FINAL:
3823e12c5d1SDavid du Colombier 		nullstr[tptr] = TRUE;
3833e12c5d1SDavid du Colombier 		break;
3843e12c5d1SDavid du Colombier # ifdef DEBUG
3853e12c5d1SDavid du Colombier 	case FINAL:
3863e12c5d1SDavid du Colombier 	case S1FINAL:
3873e12c5d1SDavid du Colombier 		break;
3883e12c5d1SDavid du Colombier 	default:
3893e12c5d1SDavid du Colombier 		warning("bad switch mn1 %d %d",a,d);
3903e12c5d1SDavid du Colombier 		break;
3913e12c5d1SDavid du Colombier # endif
3923e12c5d1SDavid du Colombier 	}
3933e12c5d1SDavid du Colombier 	if(tptr > treesize)
3943e12c5d1SDavid du Colombier 		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
3953e12c5d1SDavid du Colombier 	return(tptr++);
3963e12c5d1SDavid du Colombier }
3973e12c5d1SDavid du Colombier 
3983e12c5d1SDavid du Colombier int
mn0(int a)3993e12c5d1SDavid du Colombier mn0(int a)
4003e12c5d1SDavid du Colombier {
4013e12c5d1SDavid du Colombier 	name[tptr] = a;
4023e12c5d1SDavid du Colombier 	parent[tptr] = 0;
4033e12c5d1SDavid du Colombier 	nullstr[tptr] = 0;
4043e12c5d1SDavid du Colombier 	if(a >= NCH) switch(a){
4053e12c5d1SDavid du Colombier 	case RNULLS: nullstr[tptr] = TRUE; break;
4063e12c5d1SDavid du Colombier # ifdef DEBUG
4073e12c5d1SDavid du Colombier 	default:
4083e12c5d1SDavid du Colombier 		warning("bad switch mn0 %d",a);
4093e12c5d1SDavid du Colombier 		break;
4103e12c5d1SDavid du Colombier # endif
4113e12c5d1SDavid du Colombier 	}
4123e12c5d1SDavid du Colombier 	if(tptr > treesize)
4133e12c5d1SDavid du Colombier 		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
4143e12c5d1SDavid du Colombier 	return(tptr++);
4153e12c5d1SDavid du Colombier }
4163e12c5d1SDavid du Colombier 
4173e12c5d1SDavid du Colombier void
munputc(int p)4183e12c5d1SDavid du Colombier munputc(int p)
4193e12c5d1SDavid du Colombier {
4203e12c5d1SDavid du Colombier 	*pushptr++ = peek;		/* watch out for this */
4213e12c5d1SDavid du Colombier 	peek = p;
4223e12c5d1SDavid du Colombier 	if(pushptr >= pushc+TOKENSIZE)
4233e12c5d1SDavid du Colombier 		error("Too many characters pushed");
4243e12c5d1SDavid du Colombier }
4253e12c5d1SDavid du Colombier 
4263e12c5d1SDavid du Colombier void
munputs(uchar * p)4273e12c5d1SDavid du Colombier munputs(uchar *p)
4283e12c5d1SDavid du Colombier {
4293e12c5d1SDavid du Colombier 	int i,j;
4303e12c5d1SDavid du Colombier 	*pushptr++ = peek;
4313e12c5d1SDavid du Colombier 	peek = p[0];
4323e12c5d1SDavid du Colombier 	i = strlen((char*)p);
4333e12c5d1SDavid du Colombier 	for(j = i-1; j>=1; j--)
4343e12c5d1SDavid du Colombier 		*pushptr++ = p[j];
4353e12c5d1SDavid du Colombier 	if(pushptr >= pushc+TOKENSIZE)
4363e12c5d1SDavid du Colombier 		error("Too many characters pushed");
4373e12c5d1SDavid du Colombier }
4383e12c5d1SDavid du Colombier 
4393e12c5d1SDavid du Colombier int
dupl(int n)4403e12c5d1SDavid du Colombier dupl(int n)
4413e12c5d1SDavid du Colombier {
4423e12c5d1SDavid du Colombier 	/* duplicate the subtree whose root is n, return ptr to it */
4433e12c5d1SDavid du Colombier 	int i;
4443e12c5d1SDavid du Colombier 
4453e12c5d1SDavid du Colombier 	i = name[n];
4463e12c5d1SDavid du Colombier 	if(i < NCH) return(mn0(i));
4473e12c5d1SDavid du Colombier 	switch(i){
4483e12c5d1SDavid du Colombier 	case RNULLS:
4493e12c5d1SDavid du Colombier 		return(mn0(i));
4501fa40b8eSDavid du Colombier 	case RCCL: case RNCCL:
4511fa40b8eSDavid du Colombier 		return(mnp(i,ptr[n]));
4521fa40b8eSDavid du Colombier 	case FINAL: case S1FINAL: case S2FINAL:
4533e12c5d1SDavid du Colombier 		return(mn1(i,left[n]));
4543e12c5d1SDavid du Colombier 	case STAR: case QUEST: case PLUS: case CARAT:
4553e12c5d1SDavid du Colombier 		return(mn1(i,dupl(left[n])));
4563e12c5d1SDavid du Colombier 	case RSTR: case RSCON:
4573e12c5d1SDavid du Colombier 		return(mn2(i,dupl(left[n]),right[n]));
4583e12c5d1SDavid du Colombier 	case BAR: case RNEWE: case RCAT: case DIV:
4593e12c5d1SDavid du Colombier 		return(mn2(i,dupl(left[n]),dupl(right[n])));
4603e12c5d1SDavid du Colombier # ifdef DEBUG
4613e12c5d1SDavid du Colombier 	default:
4623e12c5d1SDavid du Colombier 		warning("bad switch dupl %d",n);
4633e12c5d1SDavid du Colombier # endif
4643e12c5d1SDavid du Colombier 	}
4653e12c5d1SDavid du Colombier 	return(0);
4663e12c5d1SDavid du Colombier }
4673e12c5d1SDavid du Colombier 
4683e12c5d1SDavid du Colombier # ifdef DEBUG
4693e12c5d1SDavid du Colombier void
allprint(int c)4703e12c5d1SDavid du Colombier allprint(int c)
4713e12c5d1SDavid du Colombier {
4728f856f24SDavid du Colombier 	if(c < 0)
4738f856f24SDavid du Colombier 		c += 256;	/* signed char */
4743e12c5d1SDavid du Colombier 	switch(c){
4753e12c5d1SDavid du Colombier 		case 014:
476219b2ee8SDavid du Colombier 			print("\\f");
4773e12c5d1SDavid du Colombier 			charc++;
4783e12c5d1SDavid du Colombier 			break;
4793e12c5d1SDavid du Colombier 		case '\n':
480219b2ee8SDavid du Colombier 			print("\\n");
4813e12c5d1SDavid du Colombier 			charc++;
4823e12c5d1SDavid du Colombier 			break;
4833e12c5d1SDavid du Colombier 		case '\t':
484219b2ee8SDavid du Colombier 			print("\\t");
4853e12c5d1SDavid du Colombier 			charc++;
4863e12c5d1SDavid du Colombier 			break;
4873e12c5d1SDavid du Colombier 		case '\b':
488219b2ee8SDavid du Colombier 			print("\\b");
4893e12c5d1SDavid du Colombier 			charc++;
4903e12c5d1SDavid du Colombier 			break;
4913e12c5d1SDavid du Colombier 		case ' ':
492219b2ee8SDavid du Colombier 			print("\\\bb");
4933e12c5d1SDavid du Colombier 			break;
4943e12c5d1SDavid du Colombier 		default:
4953e12c5d1SDavid du Colombier 			if(!isprint(c)){
496219b2ee8SDavid du Colombier 				print("\\%-3o",c);
4973e12c5d1SDavid du Colombier 				charc += 3;
4983e12c5d1SDavid du Colombier 			} else
499219b2ee8SDavid du Colombier 				print("%c", c);
5003e12c5d1SDavid du Colombier 			break;
5013e12c5d1SDavid du Colombier 	}
5023e12c5d1SDavid du Colombier 	charc++;
5033e12c5d1SDavid du Colombier }
5043e12c5d1SDavid du Colombier 
5053e12c5d1SDavid du Colombier void
strpt(uchar * s)5063e12c5d1SDavid du Colombier strpt(uchar *s)
5073e12c5d1SDavid du Colombier {
5083e12c5d1SDavid du Colombier 	charc = 0;
5093e12c5d1SDavid du Colombier 	while(*s){
5103e12c5d1SDavid du Colombier 		allprint(*s++);
5113e12c5d1SDavid du Colombier 		if(charc > LINESIZE){
5123e12c5d1SDavid du Colombier 			charc = 0;
513219b2ee8SDavid du Colombier 			print("\n\t");
5143e12c5d1SDavid du Colombier 		}
5153e12c5d1SDavid du Colombier 	}
5163e12c5d1SDavid du Colombier }
5173e12c5d1SDavid du Colombier 
5183e12c5d1SDavid du Colombier void
sect1dump(void)5193e12c5d1SDavid du Colombier sect1dump(void)
5203e12c5d1SDavid du Colombier {
5213e12c5d1SDavid du Colombier 	int i;
5223e12c5d1SDavid du Colombier 
523219b2ee8SDavid du Colombier 	print("Sect 1:\n");
5243e12c5d1SDavid du Colombier 	if(def[0]){
525219b2ee8SDavid du Colombier 		print("str	trans\n");
5263e12c5d1SDavid du Colombier 		i = -1;
5273e12c5d1SDavid du Colombier 		while(def[++i])
528219b2ee8SDavid du Colombier 			print("%s\t%s\n",def[i],subs[i]);
5293e12c5d1SDavid du Colombier 	}
5303e12c5d1SDavid du Colombier 	if(sname[0]){
531219b2ee8SDavid du Colombier 		print("start names\n");
5323e12c5d1SDavid du Colombier 		i = -1;
5333e12c5d1SDavid du Colombier 		while(sname[++i])
534219b2ee8SDavid du Colombier 			print("%s\n",sname[i]);
5353e12c5d1SDavid du Colombier 	}
5363e12c5d1SDavid du Colombier }
5373e12c5d1SDavid du Colombier 
5383e12c5d1SDavid du Colombier void
sect2dump(void)5393e12c5d1SDavid du Colombier sect2dump(void)
5403e12c5d1SDavid du Colombier {
541219b2ee8SDavid du Colombier 	print("Sect 2:\n");
5423e12c5d1SDavid du Colombier 	treedump();
5433e12c5d1SDavid du Colombier }
5443e12c5d1SDavid du Colombier 
5453e12c5d1SDavid du Colombier void
treedump(void)5463e12c5d1SDavid du Colombier treedump(void)
5473e12c5d1SDavid du Colombier {
5483e12c5d1SDavid du Colombier 	int t;
5493e12c5d1SDavid du Colombier 	uchar *p;
550219b2ee8SDavid du Colombier 	print("treedump %d nodes:\n",tptr);
5513e12c5d1SDavid du Colombier 	for(t=0;t<tptr;t++){
552219b2ee8SDavid du Colombier 		print("%4d ",t);
553219b2ee8SDavid du Colombier 		parent[t] ? print("p=%4d",parent[t]) : print("      ");
554219b2ee8SDavid du Colombier 		print("  ");
5553e12c5d1SDavid du Colombier 		if(name[t] < NCH)
5563e12c5d1SDavid du Colombier 				allprint(name[t]);
5573e12c5d1SDavid du Colombier 		else switch(name[t]){
5583e12c5d1SDavid du Colombier 			case RSTR:
559219b2ee8SDavid du Colombier 				print("%d ",left[t]);
5603e12c5d1SDavid du Colombier 				allprint(right[t]);
5613e12c5d1SDavid du Colombier 				break;
5623e12c5d1SDavid du Colombier 			case RCCL:
563219b2ee8SDavid du Colombier 				print("ccl ");
5641fa40b8eSDavid du Colombier 				allprint(ptr[t]);
5653e12c5d1SDavid du Colombier 				break;
5663e12c5d1SDavid du Colombier 			case RNCCL:
567219b2ee8SDavid du Colombier 				print("nccl ");
5681fa40b8eSDavid du Colombier 				allprint(ptr[t]);
5693e12c5d1SDavid du Colombier 				break;
5703e12c5d1SDavid du Colombier 			case DIV:
571219b2ee8SDavid du Colombier 				print("/ %d %d",left[t],right[t]);
5723e12c5d1SDavid du Colombier 				break;
5733e12c5d1SDavid du Colombier 			case BAR:
574219b2ee8SDavid du Colombier 				print("| %d %d",left[t],right[t]);
5753e12c5d1SDavid du Colombier 				break;
5763e12c5d1SDavid du Colombier 			case RCAT:
577219b2ee8SDavid du Colombier 				print("cat %d %d",left[t],right[t]);
5783e12c5d1SDavid du Colombier 				break;
5793e12c5d1SDavid du Colombier 			case PLUS:
580219b2ee8SDavid du Colombier 				print("+ %d",left[t]);
5813e12c5d1SDavid du Colombier 				break;
5823e12c5d1SDavid du Colombier 			case STAR:
583219b2ee8SDavid du Colombier 				print("* %d",left[t]);
5843e12c5d1SDavid du Colombier 				break;
5853e12c5d1SDavid du Colombier 			case CARAT:
586219b2ee8SDavid du Colombier 				print("^ %d",left[t]);
5873e12c5d1SDavid du Colombier 				break;
5883e12c5d1SDavid du Colombier 			case QUEST:
589219b2ee8SDavid du Colombier 				print("? %d",left[t]);
5903e12c5d1SDavid du Colombier 				break;
5913e12c5d1SDavid du Colombier 			case RNULLS:
592219b2ee8SDavid du Colombier 				print("nullstring");
5933e12c5d1SDavid du Colombier 				break;
5943e12c5d1SDavid du Colombier 			case FINAL:
595219b2ee8SDavid du Colombier 				print("final %d",left[t]);
5963e12c5d1SDavid du Colombier 				break;
5973e12c5d1SDavid du Colombier 			case S1FINAL:
598219b2ee8SDavid du Colombier 				print("s1final %d",left[t]);
5993e12c5d1SDavid du Colombier 				break;
6003e12c5d1SDavid du Colombier 			case S2FINAL:
601219b2ee8SDavid du Colombier 				print("s2final %d",left[t]);
6023e12c5d1SDavid du Colombier 				break;
6033e12c5d1SDavid du Colombier 			case RNEWE:
604219b2ee8SDavid du Colombier 				print("new %d %d",left[t],right[t]);
6053e12c5d1SDavid du Colombier 				break;
6063e12c5d1SDavid du Colombier 			case RSCON:
6073e12c5d1SDavid du Colombier 				p = (uchar *)right[t];
608219b2ee8SDavid du Colombier 				print("start %s",sname[*p++-1]);
6093e12c5d1SDavid du Colombier 				while(*p)
610219b2ee8SDavid du Colombier 					print(", %s",sname[*p++-1]);
611219b2ee8SDavid du Colombier 				print(" %d",left[t]);
6123e12c5d1SDavid du Colombier 				break;
6133e12c5d1SDavid du Colombier 			default:
614219b2ee8SDavid du Colombier 				print("unknown %d %d %d",name[t],left[t],right[t]);
6153e12c5d1SDavid du Colombier 				break;
6163e12c5d1SDavid du Colombier 		}
617219b2ee8SDavid du Colombier 		if(nullstr[t])print("\t(null poss.)");
618219b2ee8SDavid du Colombier 		print("\n");
6193e12c5d1SDavid du Colombier 	}
6203e12c5d1SDavid du Colombier }
6213e12c5d1SDavid du Colombier # endif
622