630 lines · 10.5 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ # include "ldefs.h"uchar *getl(uchar *p)	/* return next line of input, throw away trailing '\n' */	/* returns 0 if eof is had immediately */{	int c;	uchar *s, *t; 	t = s = p;	while(((c = gch()) != 0) && c != '\n')		*t++ = c;	*t = 0;	if(c == 0 && s == t) return((uchar *)0);	prev = '\n';	pres = '\n';	return(s);} voidprinterr(char *type, char *fmt, va_list argl){	char buf[1024]; 	if(!eof)fprint(errorf,"%s:%d  ", yyfile, yyline);	fprint(errorf,"(%s) ", type);	vseprint(buf, buf+sizeof(buf), fmt, argl);	fprint(errorf, "%s\n", buf);}  voiderror(char *s,...){	va_list argl; 	va_start(argl, s);	printerr("Error", s, argl);	va_end(argl);# ifdef DEBUG	if(debug && sect != ENDSECTION) {		sect1dump();		sect2dump();	}# endif	if(# ifdef DEBUG		debug ||# endif		report == 1) statistics();	exits("error");	/* error return code */} voidwarning(char *s,...){	va_list argl; 	va_start(argl, s);	printerr("Warning", s, argl);	va_end(argl);	Bflush(&fout);} voidlgate(void){	int fd; 	if (lgatflg) return;	lgatflg=1;	if(foutopen == 0){		fd = create("lex.yy.c", OWRITE, 0666);		if(fd < 0)			error("Can't open lex.yy.c: %r");		Binit(&fout, fd, OWRITE);		foutopen = 1;		}	phead1();} voidcclinter(int sw){		/* sw = 1 ==> ccl */	int i, j, k;	int m;	if(!sw){		/* is NCCL */		for(i=1;i<NCH;i++)			symbol[i] ^= 1;			/* reverse value */	}	for(i=1;i<NCH;i++)		if(symbol[i]) break;	if(i >= NCH) return;	i = cindex[i];	/* see if ccl is already in our table */	j = 0;	if(i){		for(j=1;j<NCH;j++){			if((symbol[j] && cindex[j] != i) ||			   (!symbol[j] && cindex[j] == i)) break;		}	}	if(j >= NCH) return;		/* already in */	m = 0;	k = 0;	for(i=1;i<NCH;i++)		if(symbol[i]){			if(!cindex[i]){				cindex[i] = ccount;				symbol[i] = 0;				m = 1;			} else k = 1;		}			/* m == 1 implies last value of ccount has been used */	if(m)ccount++;	if(k == 0) return;	/* is now in as ccount wholly */	/* intersection must be computed */	for(i=1;i<NCH;i++){		if(symbol[i]){			m = 0;			j = cindex[i];	/* will be non-zero */			for(k=1;k<NCH;k++){				if(cindex[k] == j){					if(symbol[k]) symbol[k] = 0;					else {						cindex[k] = ccount;						m = 1;					}				}			}			if(m)ccount++;		}	}} intusescape(int c){	int d;	switch(c){	case 'n': c = '\n'; break;	case 'r': c = '\r'; break;	case 't': c = '\t'; break;	case 'b': c = '\b'; break;	case 'f': c = 014; break;		/* form feed for ascii */	case '0': case '1': case '2': case '3':	case '4': case '5': case '6': case '7':		c -= '0';		while('0' <= (d=gch()) && d <= '7'){			c = c * 8 + (d-'0');			if(!('0' <= peek && peek <= '7')) break;			}		break;	}	return(c);} intlookup(uchar *s, uchar **t){	int i;	i = 0;	while(*t){		if(strcmp((char *)s, *(char **)t) == 0)			return(i);		i++;		t++;	}	return(-1);} intcpyact(void){ /* copy C action to the next ; or closing } */	int brac, c, mth;	int savline, sw;	char *savfile; 	brac = 0;	sw = TRUE;	savline = 0;	savfile = "?"; while(!eof){	c = gch();swt:	switch( c ){ case '|':	if(brac == 0 && sw == TRUE){			if(peek == '|')gch();		/* eat up an extra '|' */			return(0);		}		break; case ';':		if( brac == 0 ){			Bputc(&fout, c);			Bputc(&fout, '\n');			return(1);		}		break; case '{':		brac++;		savline=yyline;		savfile=yyfile;		break; case '}':		brac--;		if( brac == 0 ){			Bputc(&fout, c);			Bputc(&fout, '\n');			return(1);		}		break; case '/':	/* look for comments */		Bputc(&fout, c);		c = gch();		if( c != '*' ) goto swt; 		/* it really is a comment */ 		Bputc(&fout, c);		savline=yyline;		savfile=yyfile;		while( c=gch() ){			if( c=='*' ){				Bputc(&fout, c);				if( (c=gch()) == '/' ) goto loop;			}			Bputc(&fout, c);		}		yyline=savline;		yyfile=savfile;		error( "EOF inside comment" ); case '\'':	/* character constant */		mth = '\'';		goto string; case '"':	/* character string */		mth = '"'; 	string: 		Bputc(&fout, c);		while( c=gch() ){			if( c=='\\' ){				Bputc(&fout, c);				c=gch();			}			else if( c==mth ) goto loop;			Bputc(&fout, c);			if (c == '\n') {				yyline--;				error( "Non-terminated string or character constant");			}		}		error( "EOF in string or character constant" ); case '\0':		yyline = savline;		yyfile = savfile;		error("Action does not terminate");default:		break;		/* usual character */		}loop:	if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;	Bputc(&fout, c);	}	error("Premature EOF");	return(0);} intgch(void){	int c;	prev = pres;	c = pres = peek;	peek = pushptr > pushc ? *--pushptr : Bgetc(fin);	if(peek == Beof && sargc > 1){		Bterm(fin);		yyfile = sargv[fptr++];		fin = Bopen(yyfile,OREAD);		if(fin == 0)			error("%s - cannot open file: %r",yyfile);		peek = Bgetc(fin);		sargc--;		sargv++;	}	if(c == Beof) {		eof = TRUE;		Bterm(fin);		fin = 0;		return(0);	}	if(c == '\n')yyline++;	return(c);} intmn2(int a, int d, uintptr c){	name[tptr] = a;	left[tptr] = d;	right[tptr] = c;	parent[tptr] = 0;	nullstr[tptr] = 0;	switch(a){	case RSTR:		parent[d] = tptr;		break;	case BAR:	case RNEWE:		if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE;		parent[d] = parent[c] = tptr;		break;	case RCAT:	case DIV:		if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE;		parent[d] = parent[c] = tptr;		break;	case RSCON:		parent[d] = tptr;		nullstr[tptr] = nullstr[d];		break;# ifdef DEBUG	default:		warning("bad switch mn2 %d %d",a,d);		break;# endif		}	if(tptr > treesize)		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));	return(tptr++);} intmnp(int a, void *p){	name[tptr] = a;	left[tptr] = 0;	parent[tptr] = 0;	nullstr[tptr] = 0;	ptr[tptr] = p;	switch(a){	case RCCL:	case RNCCL:		if(strlen(p) == 0) nullstr[tptr] = TRUE;		break;	default:		error("bad switch mnp %d %P", a, p);		break;	}	if(tptr > treesize)		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));	return(tptr++);} intmn1(int a, int d){	name[tptr] = a;	left[tptr] = d;	parent[tptr] = 0;	nullstr[tptr] = 0;	switch(a){	case STAR:	case QUEST:		nullstr[tptr] = TRUE;		parent[d] = tptr;		break;	case PLUS:	case CARAT:		nullstr[tptr] = nullstr[d];		parent[d] = tptr;		break;	case S2FINAL:		nullstr[tptr] = TRUE;		break;# ifdef DEBUG	case FINAL:	case S1FINAL:		break;	default:		warning("bad switch mn1 %d %d",a,d);		break;# endif	}	if(tptr > treesize)		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));	return(tptr++);} intmn0(int a){	name[tptr] = a;	parent[tptr] = 0;	nullstr[tptr] = 0;	if(a >= NCH) switch(a){	case RNULLS: nullstr[tptr] = TRUE; break;# ifdef DEBUG	default:		warning("bad switch mn0 %d",a);		break;# endif	}	if(tptr > treesize)		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));	return(tptr++);} voidmunputc(int p){	*pushptr++ = peek;		/* watch out for this */	peek = p;	if(pushptr >= pushc+TOKENSIZE)		error("Too many characters pushed");} voidmunputs(uchar *p){	int i,j;	*pushptr++ = peek;	peek = p[0];	i = strlen((char*)p);	for(j = i-1; j>=1; j--)		*pushptr++ = p[j];	if(pushptr >= pushc+TOKENSIZE)		error("Too many characters pushed");} intdupl(int n){	/* duplicate the subtree whose root is n, return ptr to it */	int i; 	i = name[n];	if(i < NCH) return(mn0(i));	switch(i){	case RNULLS:		return(mn0(i));	case RCCL: case RNCCL:		return(mnp(i,ptr[n]));	case FINAL: case S1FINAL: case S2FINAL:		return(mn1(i,left[n]));	case STAR: case QUEST: case PLUS: case CARAT:		return(mn1(i,dupl(left[n])));	case RSTR: case RSCON:		return(mn2(i,dupl(left[n]),right[n]));	case BAR: case RNEWE: case RCAT: case DIV:		return(mn2(i,dupl(left[n]),dupl(right[n])));# ifdef DEBUG	default:		warning("bad switch dupl %d",n);# endif	}	return(0);} # ifdef DEBUGvoidallprint(int c){	if(c < 0)		c += 256;	/* signed char */	switch(c){		case 014:			print("\\f");			charc++;			break;		case '\n':			print("\\n");			charc++;			break;		case '\t':			print("\\t");			charc++;			break;		case '\b':			print("\\b");			charc++;			break;		case ' ':

Lines 1–500 of 630.