xref: /plan9/sys/src/cmd/lex/parser.y (revision 169d3509e3830be480b499459c3245b23637fe07)
13e12c5d1SDavid du Colombier %token CHAR CCL NCCL STR DELIM SCON ITER NEWE NULLS
23e12c5d1SDavid du Colombier %left SCON '/' NEWE
33e12c5d1SDavid du Colombier %left '|'
43e12c5d1SDavid du Colombier %left '$' '^'
53e12c5d1SDavid du Colombier %left CHAR CCL NCCL '(' '.' STR NULLS
63e12c5d1SDavid du Colombier %left ITER
73e12c5d1SDavid du Colombier %left CAT
83e12c5d1SDavid du Colombier %left '*' '+' '?'
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier %{
113e12c5d1SDavid du Colombier # include "ldefs.h"
123e12c5d1SDavid du Colombier #define YYSTYPE union _yystype_
133e12c5d1SDavid du Colombier union _yystype_
143e12c5d1SDavid du Colombier {
153e12c5d1SDavid du Colombier 	int	i;
163e12c5d1SDavid du Colombier 	uchar	*cp;
173e12c5d1SDavid du Colombier };
183e12c5d1SDavid du Colombier %}
193e12c5d1SDavid du Colombier %%
203e12c5d1SDavid du Colombier %{
213e12c5d1SDavid du Colombier int i;
223e12c5d1SDavid du Colombier int j,k;
233e12c5d1SDavid du Colombier int g;
243e12c5d1SDavid du Colombier uchar *p;
253e12c5d1SDavid du Colombier %}
263e12c5d1SDavid du Colombier acc	:	lexinput
273e12c5d1SDavid du Colombier 	={
283e12c5d1SDavid du Colombier # ifdef DEBUG
293e12c5d1SDavid du Colombier 		if(debug) sect2dump();
303e12c5d1SDavid du Colombier # endif
313e12c5d1SDavid du Colombier 	}
323e12c5d1SDavid du Colombier 	;
333e12c5d1SDavid du Colombier lexinput:	defns delim prods end
343e12c5d1SDavid du Colombier 	|	defns delim end
353e12c5d1SDavid du Colombier 	={
363e12c5d1SDavid du Colombier 		if(!funcflag)phead2();
373e12c5d1SDavid du Colombier 		funcflag = TRUE;
383e12c5d1SDavid du Colombier 	}
393e12c5d1SDavid du Colombier 	| error
403e12c5d1SDavid du Colombier 	={
413e12c5d1SDavid du Colombier # ifdef DEBUG
423e12c5d1SDavid du Colombier 		if(debug) {
433e12c5d1SDavid du Colombier 			sect1dump();
443e12c5d1SDavid du Colombier 			sect2dump();
453e12c5d1SDavid du Colombier 			}
463e12c5d1SDavid du Colombier # endif
473e12c5d1SDavid du Colombier 		}
483e12c5d1SDavid du Colombier 	;
493e12c5d1SDavid du Colombier end:		delim | ;
503e12c5d1SDavid du Colombier defns:	defns STR STR
513e12c5d1SDavid du Colombier 	={	strcpy((char*)dp,(char*)$2.cp);
523e12c5d1SDavid du Colombier 		def[dptr] = dp;
533e12c5d1SDavid du Colombier 		dp += strlen((char*)$2.cp) + 1;
543e12c5d1SDavid du Colombier 		strcpy((char*)dp,(char*)$3.cp);
553e12c5d1SDavid du Colombier 		subs[dptr++] = dp;
563e12c5d1SDavid du Colombier 		if(dptr >= DEFSIZE)
573e12c5d1SDavid du Colombier 			error("Too many definitions");
583e12c5d1SDavid du Colombier 		dp += strlen((char*)$3.cp) + 1;
593e12c5d1SDavid du Colombier 		if(dp >= dchar+DEFCHAR)
603e12c5d1SDavid du Colombier 			error("Definitions too long");
613e12c5d1SDavid du Colombier 		subs[dptr]=def[dptr]=0;	/* for lookup - require ending null */
623e12c5d1SDavid du Colombier 	}
633e12c5d1SDavid du Colombier 	|
643e12c5d1SDavid du Colombier 	;
653e12c5d1SDavid du Colombier delim:	DELIM
663e12c5d1SDavid du Colombier 	={
673e12c5d1SDavid du Colombier # ifdef DEBUG
683e12c5d1SDavid du Colombier 		if(sect == DEFSECTION && debug) sect1dump();
693e12c5d1SDavid du Colombier # endif
703e12c5d1SDavid du Colombier 		sect++;
713e12c5d1SDavid du Colombier 		}
723e12c5d1SDavid du Colombier 	;
733e12c5d1SDavid du Colombier prods:	prods pr
743e12c5d1SDavid du Colombier 	={	$$.i = mn2(RNEWE,$1.i,$2.i);
753e12c5d1SDavid du Colombier 		}
763e12c5d1SDavid du Colombier 	|	pr
773e12c5d1SDavid du Colombier 	={	$$.i = $1.i;}
783e12c5d1SDavid du Colombier 	;
793e12c5d1SDavid du Colombier pr:	r NEWE
803e12c5d1SDavid du Colombier 	={
813e12c5d1SDavid du Colombier 		if(divflg == TRUE)
823e12c5d1SDavid du Colombier 			i = mn1(S1FINAL,casecount);
833e12c5d1SDavid du Colombier 		else i = mn1(FINAL,casecount);
843e12c5d1SDavid du Colombier 		$$.i = mn2(RCAT,$1.i,i);
853e12c5d1SDavid du Colombier 		divflg = FALSE;
863e12c5d1SDavid du Colombier 		casecount++;
873e12c5d1SDavid du Colombier 		}
883e12c5d1SDavid du Colombier 	| error NEWE
893e12c5d1SDavid du Colombier 	={
903e12c5d1SDavid du Colombier # ifdef DEBUG
913e12c5d1SDavid du Colombier 		if(debug) sect2dump();
923e12c5d1SDavid du Colombier # endif
933e12c5d1SDavid du Colombier 		}
943e12c5d1SDavid du Colombier r:	CHAR
953e12c5d1SDavid du Colombier 	={	$$.i = mn0($1.i); }
963e12c5d1SDavid du Colombier 	| STR
973e12c5d1SDavid du Colombier 	={
983e12c5d1SDavid du Colombier 		p = $1.cp;
993e12c5d1SDavid du Colombier 		i = mn0(*p++);
1003e12c5d1SDavid du Colombier 		while(*p)
1013e12c5d1SDavid du Colombier 			i = mn2(RSTR,i,*p++);
1023e12c5d1SDavid du Colombier 		$$.i = i;
1033e12c5d1SDavid du Colombier 		}
1043e12c5d1SDavid du Colombier 	| '.'
1053e12c5d1SDavid du Colombier 	={	symbol['\n'] = 0;
1063e12c5d1SDavid du Colombier 		if(psave == FALSE){
1073e12c5d1SDavid du Colombier 			p = ccptr;
1083e12c5d1SDavid du Colombier 			psave = ccptr;
1093e12c5d1SDavid du Colombier 			for(i=1;i<'\n';i++){
1103e12c5d1SDavid du Colombier 				symbol[i] = 1;
1113e12c5d1SDavid du Colombier 				*ccptr++ = i;
1123e12c5d1SDavid du Colombier 				}
1133e12c5d1SDavid du Colombier 			for(i='\n'+1;i<NCH;i++){
1143e12c5d1SDavid du Colombier 				symbol[i] = 1;
1153e12c5d1SDavid du Colombier 				*ccptr++ = i;
1163e12c5d1SDavid du Colombier 				}
1173e12c5d1SDavid du Colombier 			*ccptr++ = 0;
1183e12c5d1SDavid du Colombier 			if(ccptr > ccl+CCLSIZE)
1193e12c5d1SDavid du Colombier 				error("Too many large character classes");
1203e12c5d1SDavid du Colombier 			}
1213e12c5d1SDavid du Colombier 		else
1223e12c5d1SDavid du Colombier 			p = psave;
1231ed9a9d1SDavid du Colombier 		$$.i = mnp(RCCL, p);
1243e12c5d1SDavid du Colombier 		cclinter(1);
1253e12c5d1SDavid du Colombier 		}
1263e12c5d1SDavid du Colombier 	| CCL
12774f16c81SDavid du Colombier 	={	$$.i = mnp(RCCL,$1.cp); }
1283e12c5d1SDavid du Colombier 	| NCCL
12974f16c81SDavid du Colombier 	={	$$.i = mnp(RNCCL,$1.cp); }
1303e12c5d1SDavid du Colombier 	| r '*'
1313e12c5d1SDavid du Colombier 	={	$$.i = mn1(STAR,$1.i); }
1323e12c5d1SDavid du Colombier 	| r '+'
1333e12c5d1SDavid du Colombier 	={	$$.i = mn1(PLUS,$1.i); }
1343e12c5d1SDavid du Colombier 	| r '?'
1353e12c5d1SDavid du Colombier 	={	$$.i = mn1(QUEST,$1.i); }
1363e12c5d1SDavid du Colombier 	| r '|' r
1373e12c5d1SDavid du Colombier 	={	$$.i = mn2(BAR,$1.i,$3.i); }
1383e12c5d1SDavid du Colombier 	| r r %prec CAT
1393e12c5d1SDavid du Colombier 	={	$$.i = mn2(RCAT,$1.i,$2.i); }
1403e12c5d1SDavid du Colombier 	| r '/' r
1413e12c5d1SDavid du Colombier 	={	if(!divflg){
1423e12c5d1SDavid du Colombier 			j = mn1(S2FINAL,-casecount);
1433e12c5d1SDavid du Colombier 			i = mn2(RCAT,$1.i,j);
1443e12c5d1SDavid du Colombier 			$$.i = mn2(DIV,i,$3.i);
1453e12c5d1SDavid du Colombier 			}
1463e12c5d1SDavid du Colombier 		else {
1473e12c5d1SDavid du Colombier 			$$.i = mn2(RCAT,$1.i,$3.i);
1483e12c5d1SDavid du Colombier 			warning("Extra slash removed");
1493e12c5d1SDavid du Colombier 			}
1503e12c5d1SDavid du Colombier 		divflg = TRUE;
1513e12c5d1SDavid du Colombier 		}
1523e12c5d1SDavid du Colombier 	| r ITER ',' ITER '}'
1533e12c5d1SDavid du Colombier 	={	if($2.i > $4.i){
1543e12c5d1SDavid du Colombier 			i = $2.i;
1553e12c5d1SDavid du Colombier 			$2.i = $4.i;
1563e12c5d1SDavid du Colombier 			$4.i = i;
1573e12c5d1SDavid du Colombier 			}
1583e12c5d1SDavid du Colombier 		if($4.i <= 0)
1593e12c5d1SDavid du Colombier 			warning("Iteration range must be positive");
1603e12c5d1SDavid du Colombier 		else {
1613e12c5d1SDavid du Colombier 			j = $1.i;
1623e12c5d1SDavid du Colombier 			for(k = 2; k<=$2.i;k++)
1633e12c5d1SDavid du Colombier 				j = mn2(RCAT,j,dupl($1.i));
1643e12c5d1SDavid du Colombier 			for(i = $2.i+1; i<=$4.i; i++){
1653e12c5d1SDavid du Colombier 				g = dupl($1.i);
1663e12c5d1SDavid du Colombier 				for(k=2;k<=i;k++)
1673e12c5d1SDavid du Colombier 					g = mn2(RCAT,g,dupl($1.i));
1683e12c5d1SDavid du Colombier 				j = mn2(BAR,j,g);
1693e12c5d1SDavid du Colombier 				}
1703e12c5d1SDavid du Colombier 			$$.i = j;
1713e12c5d1SDavid du Colombier 			}
1723e12c5d1SDavid du Colombier 	}
1733e12c5d1SDavid du Colombier 	| r ITER '}'
1743e12c5d1SDavid du Colombier 	={
1753e12c5d1SDavid du Colombier 		if($2.i < 0)warning("Can't have negative iteration");
1763e12c5d1SDavid du Colombier 		else if($2.i == 0) $$.i = mn0(RNULLS);
1773e12c5d1SDavid du Colombier 		else {
1783e12c5d1SDavid du Colombier 			j = $1.i;
1793e12c5d1SDavid du Colombier 			for(k=2;k<=$2.i;k++)
1803e12c5d1SDavid du Colombier 				j = mn2(RCAT,j,dupl($1.i));
1813e12c5d1SDavid du Colombier 			$$.i = j;
1823e12c5d1SDavid du Colombier 			}
1833e12c5d1SDavid du Colombier 		}
1843e12c5d1SDavid du Colombier 	| r ITER ',' '}'
1853e12c5d1SDavid du Colombier 	={
1863e12c5d1SDavid du Colombier 				/* from n to infinity */
1873e12c5d1SDavid du Colombier 		if($2.i < 0)warning("Can't have negative iteration");
1883e12c5d1SDavid du Colombier 		else if($2.i == 0) $$.i = mn1(STAR,$1.i);
1893e12c5d1SDavid du Colombier 		else if($2.i == 1)$$.i = mn1(PLUS,$1.i);
1903e12c5d1SDavid du Colombier 		else {		/* >= 2 iterations minimum */
1913e12c5d1SDavid du Colombier 			j = $1.i;
1923e12c5d1SDavid du Colombier 			for(k=2;k<$2.i;k++)
1933e12c5d1SDavid du Colombier 				j = mn2(RCAT,j,dupl($1.i));
1943e12c5d1SDavid du Colombier 			k = mn1(PLUS,dupl($1.i));
1953e12c5d1SDavid du Colombier 			$$.i = mn2(RCAT,j,k);
1963e12c5d1SDavid du Colombier 			}
1973e12c5d1SDavid du Colombier 		}
1983e12c5d1SDavid du Colombier 	| SCON r
199*169d3509SDavid du Colombier 	={	$$.i = mn2(RSCON,$2.i,(uintptr)$1.cp); }
2003e12c5d1SDavid du Colombier 	| '^' r
2013e12c5d1SDavid du Colombier 	={	$$.i = mn1(CARAT,$2.i); }
2023e12c5d1SDavid du Colombier 	| r '$'
2033e12c5d1SDavid du Colombier 	={	i = mn0('\n');
2043e12c5d1SDavid du Colombier 		if(!divflg){
2053e12c5d1SDavid du Colombier 			j = mn1(S2FINAL,-casecount);
2063e12c5d1SDavid du Colombier 			k = mn2(RCAT,$1.i,j);
2073e12c5d1SDavid du Colombier 			$$.i = mn2(DIV,k,i);
2083e12c5d1SDavid du Colombier 			}
2093e12c5d1SDavid du Colombier 		else $$.i = mn2(RCAT,$1.i,i);
2103e12c5d1SDavid du Colombier 		divflg = TRUE;
2113e12c5d1SDavid du Colombier 		}
2123e12c5d1SDavid du Colombier 	| '(' r ')'
2133e12c5d1SDavid du Colombier 	={	$$.i = $2.i; }
2143e12c5d1SDavid du Colombier 	|	NULLS
2153e12c5d1SDavid du Colombier 	={	$$.i = mn0(RNULLS); }
2163e12c5d1SDavid du Colombier 	;
2173e12c5d1SDavid du Colombier %%
2183e12c5d1SDavid du Colombier int
2193e12c5d1SDavid du Colombier yylex(void)
2203e12c5d1SDavid du Colombier {
2213e12c5d1SDavid du Colombier 	uchar *p;
2223e12c5d1SDavid du Colombier 	int c, i;
2233e12c5d1SDavid du Colombier 	uchar  *t, *xp;
2243e12c5d1SDavid du Colombier 	int n, j, k, x;
2253e12c5d1SDavid du Colombier 	static int sectbegin;
2263e12c5d1SDavid du Colombier 	static uchar token[TOKENSIZE];
2273e12c5d1SDavid du Colombier 	static int iter;
2283e12c5d1SDavid du Colombier 
2293e12c5d1SDavid du Colombier # ifdef DEBUG
2303e12c5d1SDavid du Colombier 	yylval.i = 0;
23174f16c81SDavid du Colombier 	yylval.p = 0;
2323e12c5d1SDavid du Colombier # endif
2333e12c5d1SDavid du Colombier 
2343e12c5d1SDavid du Colombier 	if(sect == DEFSECTION) {		/* definitions section */
2353e12c5d1SDavid du Colombier 		while(!eof) {
2363e12c5d1SDavid du Colombier 			if(prev == '\n'){		/* next char is at beginning of line */
2373e12c5d1SDavid du Colombier 				getl(p=buf);
2383e12c5d1SDavid du Colombier 				switch(*p){
2393e12c5d1SDavid du Colombier 				case '%':
240219b2ee8SDavid du Colombier 					switch(*(p+1)){
2413e12c5d1SDavid du Colombier 					case '%':
2423e12c5d1SDavid du Colombier 						lgate();
243219b2ee8SDavid du Colombier 						Bprint(&fout,"#define YYNEWLINE %d\n",'\n');
244219b2ee8SDavid du Colombier 						Bprint(&fout,"yylex(void){\nint nstr; extern int yyprevious;\n");
2453e12c5d1SDavid du Colombier 						sectbegin = TRUE;
2463e12c5d1SDavid du Colombier 						i = treesize*(sizeof(*name)+sizeof(*left)+
2473e12c5d1SDavid du Colombier 							sizeof(*right)+sizeof(*nullstr)+sizeof(*parent))+ALITTLEEXTRA;
2483e12c5d1SDavid du Colombier 						p = myalloc(i,1);
2493e12c5d1SDavid du Colombier 						if(p == 0)
2503e12c5d1SDavid du Colombier 							error("Too little core for parse tree");
2513e12c5d1SDavid du Colombier 						free(p);
2523e12c5d1SDavid du Colombier 						name = myalloc(treesize,sizeof(*name));
2533e12c5d1SDavid du Colombier 						left = myalloc(treesize,sizeof(*left));
2543e12c5d1SDavid du Colombier 						right = myalloc(treesize,sizeof(*right));
2553e12c5d1SDavid du Colombier 						nullstr = myalloc(treesize,sizeof(*nullstr));
2563e12c5d1SDavid du Colombier 						parent = myalloc(treesize,sizeof(*parent));
2571ed9a9d1SDavid du Colombier 						ptr = myalloc(treesize,sizeof(*ptr));
2581ed9a9d1SDavid du Colombier 						if(name == 0 || left == 0 || right == 0 || parent == 0 || nullstr == 0 || ptr == 0)
2593e12c5d1SDavid du Colombier 							error("Too little core for parse tree");
2603e12c5d1SDavid du Colombier 						return(freturn(DELIM));
2613e12c5d1SDavid du Colombier 					case 'p': case 'P':	/* has overridden number of positions */
2623e12c5d1SDavid du Colombier 						while(*p && !isdigit(*p))p++;
2633e12c5d1SDavid du Colombier 						maxpos = atol((char*)p);
2643e12c5d1SDavid du Colombier # ifdef DEBUG
265219b2ee8SDavid du Colombier 						if (debug) print("positions (%%p) now %d\n",maxpos);
2663e12c5d1SDavid du Colombier # endif
2673e12c5d1SDavid du Colombier 						if(report == 2)report = 1;
2683e12c5d1SDavid du Colombier 						continue;
2693e12c5d1SDavid du Colombier 					case 'n': case 'N':	/* has overridden number of states */
2703e12c5d1SDavid du Colombier 						while(*p && !isdigit(*p))p++;
2713e12c5d1SDavid du Colombier 						nstates = atol((char*)p);
2723e12c5d1SDavid du Colombier # ifdef DEBUG
273219b2ee8SDavid du Colombier 						if(debug)print( " no. states (%%n) now %d\n",nstates);
2743e12c5d1SDavid du Colombier # endif
2753e12c5d1SDavid du Colombier 						if(report == 2)report = 1;
2763e12c5d1SDavid du Colombier 						continue;
2773e12c5d1SDavid du Colombier 					case 'e': case 'E':		/* has overridden number of tree nodes */
2783e12c5d1SDavid du Colombier 						while(*p && !isdigit(*p))p++;
2793e12c5d1SDavid du Colombier 						treesize = atol((char*)p);
2803e12c5d1SDavid du Colombier # ifdef DEBUG
281219b2ee8SDavid du Colombier 						if (debug) print("treesize (%%e) now %d\n",treesize);
2823e12c5d1SDavid du Colombier # endif
2833e12c5d1SDavid du Colombier 						if(report == 2)report = 1;
2843e12c5d1SDavid du Colombier 						continue;
2853e12c5d1SDavid du Colombier 					case 'o': case 'O':
2863e12c5d1SDavid du Colombier 						while (*p && !isdigit(*p))p++;
2873e12c5d1SDavid du Colombier 						outsize = atol((char*)p);
2883e12c5d1SDavid du Colombier 						if (report ==2) report=1;
2893e12c5d1SDavid du Colombier 						continue;
2903e12c5d1SDavid du Colombier 					case 'a': case 'A':		/* has overridden number of transitions */
2913e12c5d1SDavid du Colombier 						while(*p && !isdigit(*p))p++;
2923e12c5d1SDavid du Colombier 						if(report == 2)report = 1;
2933e12c5d1SDavid du Colombier 						ntrans = atol((char*)p);
2943e12c5d1SDavid du Colombier # ifdef DEBUG
295219b2ee8SDavid du Colombier 						if (debug)print("N. trans (%%a) now %d\n",ntrans);
2963e12c5d1SDavid du Colombier # endif
2973e12c5d1SDavid du Colombier 						continue;
2983e12c5d1SDavid du Colombier 					case 'k': case 'K': /* overriden packed char classes */
2993e12c5d1SDavid du Colombier 						while (*p && !isdigit(*p))p++;
3003e12c5d1SDavid du Colombier 						if (report==2) report=1;
3013e12c5d1SDavid du Colombier 						free(pchar);
3023e12c5d1SDavid du Colombier 						pchlen = atol((char*)p);
3033e12c5d1SDavid du Colombier # ifdef DEBUG
304219b2ee8SDavid du Colombier 						if (debug) print( "Size classes (%%k) now %d\n",pchlen);
3053e12c5d1SDavid du Colombier # endif
3063e12c5d1SDavid du Colombier 						pchar=pcptr=myalloc(pchlen, sizeof(*pchar));
3073e12c5d1SDavid du Colombier 						continue;
3083e12c5d1SDavid du Colombier 					case '{':
3093e12c5d1SDavid du Colombier 						lgate();
3103e12c5d1SDavid du Colombier 						while(getl(p) && strcmp((char*)p,"%}") != 0)
3117dd7cddfSDavid du Colombier 							Bprint(&fout, "%s\n",(char*)p);
3123e12c5d1SDavid du Colombier 						if(p[0] == '%') continue;
3133e12c5d1SDavid du Colombier 						error("Premature eof");
3143e12c5d1SDavid du Colombier 					case 's': case 'S':		/* start conditions */
3153e12c5d1SDavid du Colombier 						lgate();
3163e12c5d1SDavid du Colombier 						while(*p && strchr(" \t,", *p) == 0) p++;
3173e12c5d1SDavid du Colombier 						n = TRUE;
3183e12c5d1SDavid du Colombier 						while(n){
3193e12c5d1SDavid du Colombier 							while(*p && strchr(" \t,", *p)) p++;
3203e12c5d1SDavid du Colombier 							t = p;
3213e12c5d1SDavid du Colombier 							while(*p && strchr(" \t,", *p) == 0)p++;
3223e12c5d1SDavid du Colombier 							if(!*p) n = FALSE;
3233e12c5d1SDavid du Colombier 							*p++ = 0;
3243e12c5d1SDavid du Colombier 							if (*t == 0) continue;
3253e12c5d1SDavid du Colombier 							i = sptr*2;
3267dd7cddfSDavid du Colombier 							Bprint(&fout,"#define %s %d\n",(char*)t,i);
3273e12c5d1SDavid du Colombier 							strcpy((char*)sp, (char*)t);
3283e12c5d1SDavid du Colombier 							sname[sptr++] = sp;
3293e12c5d1SDavid du Colombier 							sname[sptr] = 0;	/* required by lookup */
3303e12c5d1SDavid du Colombier 							if(sptr >= STARTSIZE)
3313e12c5d1SDavid du Colombier 								error("Too many start conditions");
3323e12c5d1SDavid du Colombier 							sp += strlen((char*)sp) + 1;
3333e12c5d1SDavid du Colombier 							if(sp >= stchar+STARTCHAR)
3343e12c5d1SDavid du Colombier 								error("Start conditions too long");
3353e12c5d1SDavid du Colombier 						}
3363e12c5d1SDavid du Colombier 						continue;
3373e12c5d1SDavid du Colombier 					default:
3383e12c5d1SDavid du Colombier 						warning("Invalid request %s",p);
3393e12c5d1SDavid du Colombier 						continue;
3403e12c5d1SDavid du Colombier 					}	/* end of switch after seeing '%' */
3413e12c5d1SDavid du Colombier 				case ' ': case '\t':		/* must be code */
3423e12c5d1SDavid du Colombier 					lgate();
3437dd7cddfSDavid du Colombier 					Bprint(&fout, "%s\n",(char*)p);
3443e12c5d1SDavid du Colombier 					continue;
3453e12c5d1SDavid du Colombier 				default:		/* definition */
3463e12c5d1SDavid du Colombier 					while(*p && !isspace(*p)) p++;
3473e12c5d1SDavid du Colombier 					if(*p == 0)
3483e12c5d1SDavid du Colombier 						continue;
3493e12c5d1SDavid du Colombier 					prev = *p;
3503e12c5d1SDavid du Colombier 					*p = 0;
3513e12c5d1SDavid du Colombier 					bptr = p+1;
3523e12c5d1SDavid du Colombier 					yylval.cp = buf;
3533e12c5d1SDavid du Colombier 					if(isdigit(buf[0]))
3543e12c5d1SDavid du Colombier 						warning("Substitution strings may not begin with digits");
3553e12c5d1SDavid du Colombier 					return(freturn(STR));
3563e12c5d1SDavid du Colombier 				}
3573e12c5d1SDavid du Colombier 			}
3583e12c5d1SDavid du Colombier 			/* still sect 1, but prev != '\n' */
3593e12c5d1SDavid du Colombier 			else {
3603e12c5d1SDavid du Colombier 				p = bptr;
3613e12c5d1SDavid du Colombier 				while(*p && isspace(*p)) p++;
3623e12c5d1SDavid du Colombier 				if(*p == 0)
3633e12c5d1SDavid du Colombier 					warning("No translation given - null string assumed");
3643e12c5d1SDavid du Colombier 				strcpy((char*)token, (char*)p);
3653e12c5d1SDavid du Colombier 				yylval.cp = token;
3663e12c5d1SDavid du Colombier 				prev = '\n';
3673e12c5d1SDavid du Colombier 				return(freturn(STR));
3683e12c5d1SDavid du Colombier 			}
3693e12c5d1SDavid du Colombier 		}
3703e12c5d1SDavid du Colombier 		/* end of section one processing */
3713e12c5d1SDavid du Colombier 	} else if(sect == RULESECTION){		/* rules and actions */
3723e12c5d1SDavid du Colombier 		while(!eof){
3733e12c5d1SDavid du Colombier 			switch(c=gch()){
3743e12c5d1SDavid du Colombier 			case '\0':
3753e12c5d1SDavid du Colombier 				return(freturn(0));
3763e12c5d1SDavid du Colombier 			case '\n':
3773e12c5d1SDavid du Colombier 				if(prev == '\n') continue;
3783e12c5d1SDavid du Colombier 				x = NEWE;
3793e12c5d1SDavid du Colombier 				break;
3803e12c5d1SDavid du Colombier 			case ' ':
3813e12c5d1SDavid du Colombier 			case '\t':
3823e12c5d1SDavid du Colombier 				if(sectbegin == TRUE){
3833e12c5d1SDavid du Colombier 					cpyact();
3843e12c5d1SDavid du Colombier 					while((c=gch()) && c != '\n');
3853e12c5d1SDavid du Colombier 					continue;
3863e12c5d1SDavid du Colombier 				}
3873e12c5d1SDavid du Colombier 				if(!funcflag)phead2();
3883e12c5d1SDavid du Colombier 				funcflag = TRUE;
389219b2ee8SDavid du Colombier 				Bprint(&fout,"case %d:\n",casecount);
3903e12c5d1SDavid du Colombier 				if(cpyact())
391219b2ee8SDavid du Colombier 					Bprint(&fout,"break;\n");
3923e12c5d1SDavid du Colombier 				while((c=gch()) && c != '\n');
3933e12c5d1SDavid du Colombier 				if(peek == ' ' || peek == '\t' || sectbegin == TRUE){
3943e12c5d1SDavid du Colombier 					warning("Executable statements should occur right after %%");
3953e12c5d1SDavid du Colombier 					continue;
3963e12c5d1SDavid du Colombier 				}
3973e12c5d1SDavid du Colombier 				x = NEWE;
3983e12c5d1SDavid du Colombier 				break;
3993e12c5d1SDavid du Colombier 			case '%':
4003e12c5d1SDavid du Colombier 				if(prev != '\n') goto character;
4013e12c5d1SDavid du Colombier 				if(peek == '{'){	/* included code */
4023e12c5d1SDavid du Colombier 					getl(buf);
4033e12c5d1SDavid du Colombier 					while(!eof && getl(buf) && strcmp("%}",(char*)buf) != 0)
4047dd7cddfSDavid du Colombier 						Bprint(&fout,"%s\n",(char*)buf);
4053e12c5d1SDavid du Colombier 					continue;
4063e12c5d1SDavid du Colombier 				}
4073e12c5d1SDavid du Colombier 				if(peek == '%'){
408219b2ee8SDavid du Colombier 					gch();
409219b2ee8SDavid du Colombier 					gch();
4103e12c5d1SDavid du Colombier 					x = DELIM;
4113e12c5d1SDavid du Colombier 					break;
4123e12c5d1SDavid du Colombier 				}
4133e12c5d1SDavid du Colombier 				goto character;
4143e12c5d1SDavid du Colombier 			case '|':
4153e12c5d1SDavid du Colombier 				if(peek == ' ' || peek == '\t' || peek == '\n'){
416219b2ee8SDavid du Colombier 					Bprint(&fout,"%d\n",30000+casecount++);
4173e12c5d1SDavid du Colombier 					continue;
4183e12c5d1SDavid du Colombier 				}
4193e12c5d1SDavid du Colombier 				x = '|';
4203e12c5d1SDavid du Colombier 				break;
4213e12c5d1SDavid du Colombier 			case '$':
4223e12c5d1SDavid du Colombier 				if(peek == '\n' || peek == ' ' || peek == '\t' || peek == '|' || peek == '/'){
4233e12c5d1SDavid du Colombier 					x = c;
4243e12c5d1SDavid du Colombier 					break;
4253e12c5d1SDavid du Colombier 				}
4263e12c5d1SDavid du Colombier 				goto character;
4273e12c5d1SDavid du Colombier 			case '^':
4283e12c5d1SDavid du Colombier 				if(prev != '\n' && scon != TRUE) goto character;	/* valid only at line begin */
4293e12c5d1SDavid du Colombier 				x = c;
4303e12c5d1SDavid du Colombier 				break;
4313e12c5d1SDavid du Colombier 			case '?':
4323e12c5d1SDavid du Colombier 			case '+':
4333e12c5d1SDavid du Colombier 			case '.':
4343e12c5d1SDavid du Colombier 			case '*':
4353e12c5d1SDavid du Colombier 			case '(':
4363e12c5d1SDavid du Colombier 			case ')':
4373e12c5d1SDavid du Colombier 			case ',':
4383e12c5d1SDavid du Colombier 			case '/':
4393e12c5d1SDavid du Colombier 				x = c;
4403e12c5d1SDavid du Colombier 				break;
4413e12c5d1SDavid du Colombier 			case '}':
4423e12c5d1SDavid du Colombier 				iter = FALSE;
4433e12c5d1SDavid du Colombier 				x = c;
4443e12c5d1SDavid du Colombier 				break;
4453e12c5d1SDavid du Colombier 			case '{':	/* either iteration or definition */
4463e12c5d1SDavid du Colombier 				if(isdigit(c=gch())){	/* iteration */
4473e12c5d1SDavid du Colombier 					iter = TRUE;
4483e12c5d1SDavid du Colombier 				ieval:
4493e12c5d1SDavid du Colombier 					i = 0;
4503e12c5d1SDavid du Colombier 					while(isdigit(c)){
4513e12c5d1SDavid du Colombier 						token[i++] = c;
4523e12c5d1SDavid du Colombier 						c = gch();
4533e12c5d1SDavid du Colombier 					}
4543e12c5d1SDavid du Colombier 					token[i] = 0;
4553e12c5d1SDavid du Colombier 					yylval.i = atol((char*)token);
4563e12c5d1SDavid du Colombier 					munputc(c);
4573e12c5d1SDavid du Colombier 					x = ITER;
4583e12c5d1SDavid du Colombier 					break;
4593e12c5d1SDavid du Colombier 				} else {		/* definition */
4603e12c5d1SDavid du Colombier 					i = 0;
4613e12c5d1SDavid du Colombier 					while(c && c!='}'){
4623e12c5d1SDavid du Colombier 						token[i++] = c;
4633e12c5d1SDavid du Colombier 						c = gch();
4643e12c5d1SDavid du Colombier 					}
4653e12c5d1SDavid du Colombier 					token[i] = 0;
4663e12c5d1SDavid du Colombier 					i = lookup(token,def);
4673e12c5d1SDavid du Colombier 					if(i < 0)
4683e12c5d1SDavid du Colombier 						warning("Definition %s not found",token);
4693e12c5d1SDavid du Colombier 					else
4703e12c5d1SDavid du Colombier 						munputs(subs[i]);
4713e12c5d1SDavid du Colombier 					continue;
4723e12c5d1SDavid du Colombier 				}
4733e12c5d1SDavid du Colombier 			case '<':		/* start condition ? */
4743e12c5d1SDavid du Colombier 				if(prev != '\n')		/* not at line begin, not start */
4753e12c5d1SDavid du Colombier 					goto character;
4763e12c5d1SDavid du Colombier 				t = slptr;
4773e12c5d1SDavid du Colombier 				do {
4783e12c5d1SDavid du Colombier 					i = 0;
4793e12c5d1SDavid du Colombier 					c = gch();
4803e12c5d1SDavid du Colombier 					while(c != ',' && c && c != '>'){
4813e12c5d1SDavid du Colombier 						token[i++] = c;
4823e12c5d1SDavid du Colombier 						c = gch();
4833e12c5d1SDavid du Colombier 					}
4843e12c5d1SDavid du Colombier 					token[i] = 0;
4853e12c5d1SDavid du Colombier 					if(i == 0)
4863e12c5d1SDavid du Colombier 						goto character;
4873e12c5d1SDavid du Colombier 					i = lookup(token,sname);
4883e12c5d1SDavid du Colombier 					if(i < 0) {
4893e12c5d1SDavid du Colombier 						warning("Undefined start condition %s",token);
4903e12c5d1SDavid du Colombier 						continue;
4913e12c5d1SDavid du Colombier 					}
4923e12c5d1SDavid du Colombier 					*slptr++ = i+1;
4933e12c5d1SDavid du Colombier 				} while(c && c != '>');
4943e12c5d1SDavid du Colombier 				*slptr++ = 0;
4953e12c5d1SDavid du Colombier 				/* check if previous value re-usable */
4963e12c5d1SDavid du Colombier 				for (xp=slist; xp<t; ){
4973e12c5d1SDavid du Colombier 					if (strcmp((char*)xp, (char*)t)==0)
4983e12c5d1SDavid du Colombier 						break;
4993e12c5d1SDavid du Colombier 					while (*xp++);
5003e12c5d1SDavid du Colombier 				}
5013e12c5d1SDavid du Colombier 				if (xp<t){
5023e12c5d1SDavid du Colombier 					/* re-use previous pointer to string */
5033e12c5d1SDavid du Colombier 					slptr=t;
5043e12c5d1SDavid du Colombier 					t=xp;
5053e12c5d1SDavid du Colombier 				}
5063e12c5d1SDavid du Colombier 				if(slptr > slist+STARTSIZE)		/* note not packed ! */
5073e12c5d1SDavid du Colombier 					error("Too many start conditions used");
5083e12c5d1SDavid du Colombier 				yylval.cp = t;
5093e12c5d1SDavid du Colombier 				x = SCON;
5103e12c5d1SDavid du Colombier 				break;
5113e12c5d1SDavid du Colombier 			case '"':
5123e12c5d1SDavid du Colombier 				i = 0;
5133e12c5d1SDavid du Colombier 				while((c=gch()) && c != '"' && c != '\n'){
514219b2ee8SDavid du Colombier 					if(c == '\\') c = usescape(gch());
5153e12c5d1SDavid du Colombier 					token[i++] = c;
5163e12c5d1SDavid du Colombier 					if(i > TOKENSIZE){
5173e12c5d1SDavid du Colombier 						warning("String too long");
5183e12c5d1SDavid du Colombier 						i = TOKENSIZE-1;
5193e12c5d1SDavid du Colombier 						break;
5203e12c5d1SDavid du Colombier 					}
5213e12c5d1SDavid du Colombier 				}
5223e12c5d1SDavid du Colombier 				if(c == '\n') {
5233e12c5d1SDavid du Colombier 					yyline--;
5243e12c5d1SDavid du Colombier 					warning("Non-terminated string");
5253e12c5d1SDavid du Colombier 					yyline++;
5263e12c5d1SDavid du Colombier 				}
5273e12c5d1SDavid du Colombier 				token[i] = 0;
5283e12c5d1SDavid du Colombier 				if(i == 0)x = NULLS;
5293e12c5d1SDavid du Colombier 				else if(i == 1){
5303e12c5d1SDavid du Colombier 					yylval.i = token[0];
5313e12c5d1SDavid du Colombier 					x = CHAR;
5323e12c5d1SDavid du Colombier 				} else {
5333e12c5d1SDavid du Colombier 					yylval.cp = token;
5343e12c5d1SDavid du Colombier 					x = STR;
5353e12c5d1SDavid du Colombier 				}
5363e12c5d1SDavid du Colombier 				break;
5373e12c5d1SDavid du Colombier 			case '[':
5383e12c5d1SDavid du Colombier 				for(i=1;i<NCH;i++) symbol[i] = 0;
5393e12c5d1SDavid du Colombier 				x = CCL;
5403e12c5d1SDavid du Colombier 				if((c = gch()) == '^'){
5413e12c5d1SDavid du Colombier 					x = NCCL;
5423e12c5d1SDavid du Colombier 					c = gch();
5433e12c5d1SDavid du Colombier 				}
5443e12c5d1SDavid du Colombier 				while(c != ']' && c){
545219b2ee8SDavid du Colombier 					if(c == '\\') c = usescape(gch());
5463e12c5d1SDavid du Colombier 					symbol[c] = 1;
5473e12c5d1SDavid du Colombier 					j = c;
5483e12c5d1SDavid du Colombier 					if((c=gch()) == '-' && peek != ']'){		/* range specified */
5493e12c5d1SDavid du Colombier 						c = gch();
550219b2ee8SDavid du Colombier 						if(c == '\\') c = usescape(gch());
5513e12c5d1SDavid du Colombier 						k = c;
5523e12c5d1SDavid du Colombier 						if(j > k) {
5533e12c5d1SDavid du Colombier 							n = j;
5543e12c5d1SDavid du Colombier 							j = k;
5553e12c5d1SDavid du Colombier 							k = n;
5563e12c5d1SDavid du Colombier 						}
5573e12c5d1SDavid du Colombier 						if(!(('A' <= j && k <= 'Z') ||
5583e12c5d1SDavid du Colombier 						     ('a' <= j && k <= 'z') ||
5593e12c5d1SDavid du Colombier 						     ('0' <= j && k <= '9')))
5603e12c5d1SDavid du Colombier 							warning("Non-portable Character Class");
5613e12c5d1SDavid du Colombier 						for(n=j+1;n<=k;n++)
5623e12c5d1SDavid du Colombier 							symbol[n] = 1;		/* implementation dependent */
5633e12c5d1SDavid du Colombier 						c = gch();
5643e12c5d1SDavid du Colombier 					}
5653e12c5d1SDavid du Colombier 				}
5663e12c5d1SDavid du Colombier 				/* try to pack ccl's */
5673e12c5d1SDavid du Colombier 				i = 0;
5683e12c5d1SDavid du Colombier 				for(j=0;j<NCH;j++)
5693e12c5d1SDavid du Colombier 					if(symbol[j])token[i++] = j;
5703e12c5d1SDavid du Colombier 				token[i] = 0;
5713e12c5d1SDavid du Colombier 				p = ccl;
5723e12c5d1SDavid du Colombier 				while(p <ccptr && strcmp((char*)token,(char*)p) != 0)p++;
5733e12c5d1SDavid du Colombier 				if(p < ccptr)	/* found it */
5743e12c5d1SDavid du Colombier 					yylval.cp = p;
5753e12c5d1SDavid du Colombier 				else {
5763e12c5d1SDavid du Colombier 					yylval.cp = ccptr;
5773e12c5d1SDavid du Colombier 					strcpy((char*)ccptr,(char*)token);
5783e12c5d1SDavid du Colombier 					ccptr += strlen((char*)token) + 1;
5793e12c5d1SDavid du Colombier 					if(ccptr >= ccl+CCLSIZE)
5803e12c5d1SDavid du Colombier 						error("Too many large character classes");
5813e12c5d1SDavid du Colombier 				}
5823e12c5d1SDavid du Colombier 				cclinter(x==CCL);
5833e12c5d1SDavid du Colombier 				break;
5843e12c5d1SDavid du Colombier 			case '\\':
585219b2ee8SDavid du Colombier 				c = usescape(gch());
5863e12c5d1SDavid du Colombier 			default:
5873e12c5d1SDavid du Colombier 			character:
5883e12c5d1SDavid du Colombier 				if(iter){	/* second part of an iteration */
5893e12c5d1SDavid du Colombier 					iter = FALSE;
5903e12c5d1SDavid du Colombier 					if('0' <= c && c <= '9')
5913e12c5d1SDavid du Colombier 						goto ieval;
5923e12c5d1SDavid du Colombier 				}
5933e12c5d1SDavid du Colombier 				if(isalpha(peek)){
5943e12c5d1SDavid du Colombier 					i = 0;
5953e12c5d1SDavid du Colombier 					yylval.cp = token;
5963e12c5d1SDavid du Colombier 					token[i++] = c;
5973e12c5d1SDavid du Colombier 					while(isalpha(peek))
5983e12c5d1SDavid du Colombier 						token[i++] = gch();
5993e12c5d1SDavid du Colombier 					if(peek == '?' || peek == '*' || peek == '+')
6003e12c5d1SDavid du Colombier 						munputc(token[--i]);
6013e12c5d1SDavid du Colombier 					token[i] = 0;
6023e12c5d1SDavid du Colombier 					if(i == 1){
6033e12c5d1SDavid du Colombier 						yylval.i = token[0];
6043e12c5d1SDavid du Colombier 						x = CHAR;
6053e12c5d1SDavid du Colombier 					}
6063e12c5d1SDavid du Colombier 					else x = STR;
6073e12c5d1SDavid du Colombier 				} else {
6083e12c5d1SDavid du Colombier 					yylval.i = c;
6093e12c5d1SDavid du Colombier 					x = CHAR;
6103e12c5d1SDavid du Colombier 				}
6113e12c5d1SDavid du Colombier 			}
6123e12c5d1SDavid du Colombier 			scon = FALSE;
6133e12c5d1SDavid du Colombier 			if(x == SCON)scon = TRUE;
6143e12c5d1SDavid du Colombier 			sectbegin = FALSE;
6153e12c5d1SDavid du Colombier 			return(freturn(x));
6163e12c5d1SDavid du Colombier 		}
6173e12c5d1SDavid du Colombier 	}
6183e12c5d1SDavid du Colombier 	/* section three */
6193e12c5d1SDavid du Colombier 	ptail();
6203e12c5d1SDavid du Colombier # ifdef DEBUG
6213e12c5d1SDavid du Colombier 	if(debug)
622219b2ee8SDavid du Colombier 		Bprint(&fout,"\n/*this comes from section three - debug */\n");
6233e12c5d1SDavid du Colombier # endif
6243e12c5d1SDavid du Colombier 	while(getl(buf) && !eof)
6257dd7cddfSDavid du Colombier 		Bprint(&fout,"%s\n",(char*)buf);
6263e12c5d1SDavid du Colombier 	return(freturn(0));
6273e12c5d1SDavid du Colombier }
6283e12c5d1SDavid du Colombier /* end of yylex */
6293e12c5d1SDavid du Colombier # ifdef DEBUG
6303e12c5d1SDavid du Colombier int
freturn(int i)6313e12c5d1SDavid du Colombier freturn(int i)
6323e12c5d1SDavid du Colombier {
6333e12c5d1SDavid du Colombier 	if(yydebug) {
634219b2ee8SDavid du Colombier 		print("now return ");
6353e12c5d1SDavid du Colombier 		if(i < NCH) allprint(i);
636219b2ee8SDavid du Colombier 		else print("%d",i);
63739734e7eSDavid du Colombier 		print("   yylval = ");
6383e12c5d1SDavid du Colombier 		switch(i){
6393e12c5d1SDavid du Colombier 			case STR: case CCL: case NCCL:
6403e12c5d1SDavid du Colombier 				strpt(yylval.cp);
6413e12c5d1SDavid du Colombier 				break;
6423e12c5d1SDavid du Colombier 			case CHAR:
6433e12c5d1SDavid du Colombier 				allprint(yylval.i);
6443e12c5d1SDavid du Colombier 				break;
6453e12c5d1SDavid du Colombier 			default:
646219b2ee8SDavid du Colombier 				print("%d",yylval.i);
6473e12c5d1SDavid du Colombier 				break;
6483e12c5d1SDavid du Colombier 		}
649219b2ee8SDavid du Colombier 		print("\n");
6503e12c5d1SDavid du Colombier 	}
6513e12c5d1SDavid du Colombier 	return(i);
6523e12c5d1SDavid du Colombier }
6533e12c5d1SDavid du Colombier # endif
654