xref: /csrg-svn/old/lex/parser.y (revision 43618)
114492Ssam %token CHAR CCL NCCL STR DELIM SCON ITER NEWE NULLS
214492Ssam %left SCON '/' NEWE
314492Ssam %left '|'
414492Ssam %left '$' '^'
514492Ssam %left CHAR CCL NCCL '(' '.' STR NULLS
614492Ssam %left ITER
714492Ssam %left CAT
814492Ssam %left '*' '+' '?'
914492Ssam 
1014492Ssam %{
1114492Ssam #ifndef lint
12*43618Sbostic static char sccsid[] = "@(#)parser.y	4.3 (Berkeley) 06/24/90";
1314492Ssam #endif
1414492Ssam 
1514492Ssam # include "ldefs.c"
1614492Ssam %}
1714492Ssam %%
1814492Ssam %{
1914492Ssam int i;
2014492Ssam int j,k;
2114492Ssam int g;
2214492Ssam char *p;
2314492Ssam %}
2414492Ssam acc	:	lexinput
2514492Ssam 	={
2614492Ssam # ifdef DEBUG
2714492Ssam 		if(debug) sect2dump();
2814492Ssam # endif
2914492Ssam 	}
3014492Ssam 	;
3114492Ssam lexinput:	defns delim prods end
3214492Ssam 	|	defns delim end
3314492Ssam 	={
3414492Ssam 		if(!funcflag)phead2();
3514492Ssam 		funcflag = TRUE;
3614492Ssam 	}
3714492Ssam 	| error
3814492Ssam 	={
3914492Ssam # ifdef DEBUG
4014492Ssam 		if(debug) {
4114492Ssam 			sect1dump();
4214492Ssam 			sect2dump();
4314492Ssam 			}
4414492Ssam # endif
4514492Ssam 		}
4614492Ssam 	;
4714492Ssam end:		delim | ;
4814492Ssam defns:	defns STR STR
4914492Ssam 	={	scopy($2,dp);
5014492Ssam 		def[dptr] = dp;
5114492Ssam 		dp += slength($2) + 1;
5214492Ssam 		scopy($3,dp);
5314492Ssam 		subs[dptr++] = dp;
5414492Ssam 		if(dptr >= DEFSIZE)
5514492Ssam 			error("Too many definitions");
5614492Ssam 		dp += slength($3) + 1;
5714492Ssam 		if(dp >= dchar+DEFCHAR)
5814492Ssam 			error("Definitions too long");
5914492Ssam 		subs[dptr]=def[dptr]=0;	/* for lookup - require ending null */
6014492Ssam 	}
6114492Ssam 	|
6214492Ssam 	;
6314492Ssam delim:	DELIM
6414492Ssam 	={
6514492Ssam # ifdef DEBUG
6614492Ssam 		if(sect == DEFSECTION && debug) sect1dump();
6714492Ssam # endif
6814492Ssam 		sect++;
6914492Ssam 		}
7014492Ssam 	;
7114492Ssam prods:	prods pr
7214492Ssam 	={	$$ = mn2(RNEWE,$1,$2);
7314492Ssam 		}
7414492Ssam 	|	pr
7514492Ssam 	={	$$ = $1;}
7614492Ssam 	;
7714492Ssam pr:	r NEWE
7814492Ssam 	={
7914492Ssam 		if(divflg == TRUE)
8014492Ssam 			i = mn1(S1FINAL,casecount);
8114492Ssam 		else i = mn1(FINAL,casecount);
8214492Ssam 		$$ = mn2(RCAT,$1,i);
8314492Ssam 		divflg = FALSE;
8414492Ssam 		casecount++;
8514492Ssam 		}
8614492Ssam 	| error NEWE
8714492Ssam 	={
8814492Ssam # ifdef DEBUG
8914492Ssam 		if(debug) sect2dump();
9014492Ssam # endif
9114492Ssam 		}
9214492Ssam r:	CHAR
9314492Ssam 	={	$$ = mn0($1); }
9414492Ssam 	| STR
9514492Ssam 	={
9633344Sbostic 		p = (char *)$1;
9714492Ssam 		i = mn0(*p++);
9814492Ssam 		while(*p)
9914492Ssam 			i = mn2(RSTR,i,*p++);
10014492Ssam 		$$ = i;
10114492Ssam 		}
10214492Ssam 	| '.'
10314492Ssam 	={	symbol['\n'] = 0;
10414492Ssam 		if(psave == FALSE){
10514492Ssam 			p = ccptr;
10614492Ssam 			psave = ccptr;
10714492Ssam 			for(i=1;i<'\n';i++){
10814492Ssam 				symbol[i] = 1;
10914492Ssam 				*ccptr++ = i;
11014492Ssam 				}
11114492Ssam 			for(i='\n'+1;i<NCH;i++){
11214492Ssam 				symbol[i] = 1;
11314492Ssam 				*ccptr++ = i;
11414492Ssam 				}
11514492Ssam 			*ccptr++ = 0;
11614492Ssam 			if(ccptr > ccl+CCLSIZE)
11714492Ssam 				error("Too many large character classes");
11814492Ssam 			}
11914492Ssam 		else
12014492Ssam 			p = psave;
12114492Ssam 		$$ = mn1(RCCL,p);
12214492Ssam 		cclinter(1);
12314492Ssam 		}
12414492Ssam 	| CCL
12514492Ssam 	={	$$ = mn1(RCCL,$1); }
12614492Ssam 	| NCCL
12714492Ssam 	={	$$ = mn1(RNCCL,$1); }
12814492Ssam 	| r '*'
12914492Ssam 	={	$$ = mn1(STAR,$1); }
13014492Ssam 	| r '+'
13114492Ssam 	={	$$ = mn1(PLUS,$1); }
13214492Ssam 	| r '?'
13314492Ssam 	={	$$ = mn1(QUEST,$1); }
13414492Ssam 	| r '|' r
13514492Ssam 	={	$$ = mn2(BAR,$1,$3); }
13614492Ssam 	| r r %prec CAT
13714492Ssam 	={	$$ = mn2(RCAT,$1,$2); }
13814492Ssam 	| r '/' r
13914492Ssam 	={	if(!divflg){
14014492Ssam 			j = mn1(S2FINAL,-casecount);
14114492Ssam 			i = mn2(RCAT,$1,j);
14214492Ssam 			$$ = mn2(DIV,i,$3);
14314492Ssam 			}
14414492Ssam 		else {
14514492Ssam 			$$ = mn2(RCAT,$1,$3);
14614492Ssam 			warning("Extra slash removed");
14714492Ssam 			}
14814492Ssam 		divflg = TRUE;
14914492Ssam 		}
15014492Ssam 	| r ITER ',' ITER '}'
15114492Ssam 	={	if($2 > $4){
15214492Ssam 			i = $2;
15314492Ssam 			$2 = $4;
15414492Ssam 			$4 = i;
15514492Ssam 			}
15614492Ssam 		if($4 <= 0)
15714492Ssam 			warning("Iteration range must be positive");
15814492Ssam 		else {
15914492Ssam 			j = $1;
16014492Ssam 			for(k = 2; k<=$2;k++)
16114492Ssam 				j = mn2(RCAT,j,dupl($1));
16214492Ssam 			for(i = $2+1; i<=$4; i++){
16314492Ssam 				g = dupl($1);
16414492Ssam 				for(k=2;k<=i;k++)
16514492Ssam 					g = mn2(RCAT,g,dupl($1));
16614492Ssam 				j = mn2(BAR,j,g);
16714492Ssam 				}
16814492Ssam 			$$ = j;
16914492Ssam 			}
17014492Ssam 	}
17114492Ssam 	| r ITER '}'
17214492Ssam 	={
17314492Ssam 		if($2 < 0)warning("Can't have negative iteration");
17414492Ssam 		else if($2 == 0) $$ = mn0(RNULLS);
17514492Ssam 		else {
17614492Ssam 			j = $1;
17714492Ssam 			for(k=2;k<=$2;k++)
17814492Ssam 				j = mn2(RCAT,j,dupl($1));
17914492Ssam 			$$ = j;
18014492Ssam 			}
18114492Ssam 		}
18214492Ssam 	| r ITER ',' '}'
18314492Ssam 	={
18414492Ssam 				/* from n to infinity */
18514492Ssam 		if($2 < 0)warning("Can't have negative iteration");
18614492Ssam 		else if($2 == 0) $$ = mn1(STAR,$1);
18714492Ssam 		else if($2 == 1)$$ = mn1(PLUS,$1);
18814492Ssam 		else {		/* >= 2 iterations minimum */
18914492Ssam 			j = $1;
19014492Ssam 			for(k=2;k<$2;k++)
19114492Ssam 				j = mn2(RCAT,j,dupl($1));
19214492Ssam 			k = mn1(PLUS,dupl($1));
19314492Ssam 			$$ = mn2(RCAT,j,k);
19414492Ssam 			}
19514492Ssam 		}
19614492Ssam 	| SCON r
19714492Ssam 	={	$$ = mn2(RSCON,$2,$1); }
19814492Ssam 	| '^' r
19914492Ssam 	={	$$ = mn1(CARAT,$2); }
20014492Ssam 	| r '$'
20114492Ssam 	={	i = mn0('\n');
20214492Ssam 		if(!divflg){
20314492Ssam 			j = mn1(S2FINAL,-casecount);
20414492Ssam 			k = mn2(RCAT,$1,j);
20514492Ssam 			$$ = mn2(DIV,k,i);
20614492Ssam 			}
20714492Ssam 		else $$ = mn2(RCAT,$1,i);
20814492Ssam 		divflg = TRUE;
20914492Ssam 		}
21014492Ssam 	| '(' r ')'
21114492Ssam 	={	$$ = $2; }
21214492Ssam 	|	NULLS
21314492Ssam 	={	$$ = mn0(RNULLS); }
21414492Ssam 	;
21514492Ssam %%
21614492Ssam yylex(){
21714492Ssam 	register char *p;
21814492Ssam 	register int c, i;
21914492Ssam 	char  *t, *xp;
22014492Ssam 	int n, j, k, x;
22114492Ssam 	static int sectbegin;
22214492Ssam 	static char token[TOKENSIZE];
22314492Ssam 	static int iter;
22414492Ssam 
22514492Ssam # ifdef DEBUG
22614492Ssam 	yylval = 0;
22714492Ssam # endif
22814492Ssam 
22914492Ssam 	if(sect == DEFSECTION) {		/* definitions section */
23014492Ssam 		while(!eof) {
23114492Ssam 			if(prev == '\n'){		/* next char is at beginning of line */
23214492Ssam 				getl(p=buf);
23314492Ssam 				switch(*p){
23414492Ssam 				case '%':
23514492Ssam 					switch(c= *(p+1)){
23614492Ssam 					case '%':
23714492Ssam 						lgate();
23814492Ssam 						if(!ratfor)fprintf(fout,"# ");
23914492Ssam 						fprintf(fout,"define YYNEWLINE %d\n",ctable['\n']);
24014492Ssam 						if(!ratfor)fprintf(fout,"yylex(){\nint nstr; extern int yyprevious;\n");
24114492Ssam 						sectbegin = TRUE;
24214492Ssam 						i = treesize*(sizeof(*name)+sizeof(*left)+
24314492Ssam 							sizeof(*right)+sizeof(*nullstr)+sizeof(*parent))+ALITTLEEXTRA;
24433344Sbostic 						p = myalloc(i,1);
245*43618Sbostic 						if(p == 0)
24614492Ssam 							error("Too little core for parse tree");
247*43618Sbostic 						free(p);
24833344Sbostic 						name = (int *)myalloc(treesize,sizeof(*name));
24933344Sbostic 						left = (int *)myalloc(treesize,sizeof(*left));
25033344Sbostic 						right = (int *)myalloc(treesize,sizeof(*right));
25133344Sbostic 						nullstr = (char *)myalloc(treesize,sizeof(*nullstr));
25233344Sbostic 						parent = (int *)myalloc(treesize,sizeof(*parent));
25314492Ssam 						if(name == 0 || left == 0 || right == 0 || parent == 0 || nullstr == 0)
25414492Ssam 							error("Too little core for parse tree");
25514492Ssam 						return(freturn(DELIM));
25614492Ssam 					case 'p': case 'P':	/* has overridden number of positions */
25714492Ssam 						while(*p && !digit(*p))p++;
25814492Ssam 						maxpos = siconv(p);
25914492Ssam # ifdef DEBUG
26014492Ssam 						if (debug) printf("positions (%%p) now %d\n",maxpos);
26114492Ssam # endif
26214492Ssam 						if(report == 2)report = 1;
26314492Ssam 						continue;
26414492Ssam 					case 'n': case 'N':	/* has overridden number of states */
26514492Ssam 						while(*p && !digit(*p))p++;
26614492Ssam 						nstates = siconv(p);
26714492Ssam # ifdef DEBUG
26814492Ssam 						if(debug)printf( " no. states (%%n) now %d\n",nstates);
26914492Ssam # endif
27014492Ssam 						if(report == 2)report = 1;
27114492Ssam 						continue;
27214492Ssam 					case 'e': case 'E':		/* has overridden number of tree nodes */
27314492Ssam 						while(*p && !digit(*p))p++;
27414492Ssam 						treesize = siconv(p);
27514492Ssam # ifdef DEBUG
27614492Ssam 						if (debug) printf("treesize (%%e) now %d\n",treesize);
27714492Ssam # endif
27814492Ssam 						if(report == 2)report = 1;
27914492Ssam 						continue;
28014492Ssam 					case 'o': case 'O':
28114492Ssam 						while (*p && !digit(*p))p++;
28214492Ssam 						outsize = siconv(p);
28314492Ssam 						if (report ==2) report=1;
28414492Ssam 						continue;
28514492Ssam 					case 'a': case 'A':		/* has overridden number of transitions */
28614492Ssam 						while(*p && !digit(*p))p++;
28714492Ssam 						if(report == 2)report = 1;
28814492Ssam 						ntrans = siconv(p);
28914492Ssam # ifdef DEBUG
29014492Ssam 						if (debug)printf("N. trans (%%a) now %d\n",ntrans);
29114492Ssam # endif
29214492Ssam 						continue;
29314492Ssam 					case 'k': case 'K': /* overriden packed char classes */
29414492Ssam 						while (*p && !digit(*p))p++;
29514492Ssam 						if (report==2) report=1;
296*43618Sbostic 						free(pchar);
29714492Ssam 						pchlen = siconv(p);
29814492Ssam # ifdef DEBUG
29914492Ssam 						if (debug) printf( "Size classes (%%k) now %d\n",pchlen);
30014492Ssam # endif
30114492Ssam 						pchar=pcptr=myalloc(pchlen, sizeof(*pchar));
30214492Ssam 						continue;
30314492Ssam 					case 't': case 'T': 	/* character set specifier */
30414492Ssam 						ZCH = atoi(p+2);
30514492Ssam 						if (ZCH < NCH) ZCH = NCH;
30614492Ssam 						if (ZCH > 2*NCH) error("ch table needs redeclaration");
30714492Ssam 						chset = TRUE;
30814492Ssam 						for(i = 0; i<ZCH; i++)
30914492Ssam 							ctable[i] = 0;
31014492Ssam 						while(getl(p) && scomp(p,"%T") != 0 && scomp(p,"%t") != 0){
31114492Ssam 							if((n = siconv(p)) <= 0 || n > ZCH){
31214492Ssam 								warning("Character value %d out of range",n);
31314492Ssam 								continue;
31414492Ssam 								}
31514492Ssam 							while(!space(*p) && *p) p++;
31614492Ssam 							while(space(*p)) p++;
31714492Ssam 							t = p;
31814492Ssam 							while(*t){
31914492Ssam 								c = ctrans(&t);
32014492Ssam 								if(ctable[c]){
32114492Ssam 									if (printable(c))
32214492Ssam 										warning("Character '%c' used twice",c);
32314492Ssam 									else
32414492Ssam 										warning("Character %o used twice",c);
32514492Ssam 									}
32614492Ssam 								else ctable[c] = n;
32714492Ssam 								t++;
32814492Ssam 								}
32914492Ssam 							p = buf;
33014492Ssam 							}
33114492Ssam 						{
33214492Ssam 						char chused[2*NCH]; int kr;
33314492Ssam 						for(i=0; i<ZCH; i++)
33414492Ssam 							chused[i]=0;
33514492Ssam 						for(i=0; i<NCH; i++)
33614492Ssam 							chused[ctable[i]]=1;
33714492Ssam 						for(kr=i=1; i<NCH; i++)
33814492Ssam 							if (ctable[i]==0)
33914492Ssam 								{
34014492Ssam 								while (chused[kr] == 0)
34114492Ssam 									kr++;
34214492Ssam 								ctable[i]=kr;
34314492Ssam 								chused[kr]=1;
34414492Ssam 								}
34514492Ssam 						}
34614492Ssam 						lgate();
34714492Ssam 						continue;
34814492Ssam 					case 'r': case 'R':
34914492Ssam 						c = 'r';
35014492Ssam 					case 'c': case 'C':
35114492Ssam 						if(lgatflg)
35214492Ssam 							error("Too late for language specifier");
35314492Ssam 						ratfor = (c == 'r');
35414492Ssam 						continue;
35514492Ssam 					case '{':
35614492Ssam 						lgate();
35714492Ssam 						while(getl(p) && scomp(p,"%}") != 0)
35814492Ssam 							fprintf(fout, "%s\n",p);
35914492Ssam 						if(p[0] == '%') continue;
36014492Ssam 						error("Premature eof");
36114492Ssam 					case 's': case 'S':		/* start conditions */
36214492Ssam 						lgate();
36314492Ssam 						while(*p && index(*p," \t,") < 0) p++;
36414492Ssam 						n = TRUE;
36514492Ssam 						while(n){
36614492Ssam 							while(*p && index(*p," \t,") >= 0) p++;
36714492Ssam 							t = p;
36814492Ssam 							while(*p && index(*p," \t,") < 0)p++;
36914492Ssam 							if(!*p) n = FALSE;
37014492Ssam 							*p++ = 0;
37114492Ssam 							if (*t == 0) continue;
37214492Ssam 							i = sptr*2;
37314492Ssam 							if(!ratfor)fprintf(fout,"# ");
37414492Ssam 							fprintf(fout,"define %s %d\n",t,i);
37514492Ssam 							scopy(t,sp);
37614492Ssam 							sname[sptr++] = sp;
37714492Ssam 							sname[sptr] = 0;	/* required by lookup */
37814492Ssam 							if(sptr >= STARTSIZE)
37914492Ssam 								error("Too many start conditions");
38014492Ssam 							sp += slength(sp) + 1;
38114492Ssam 							if(sp >= schar+STARTCHAR)
38214492Ssam 								error("Start conditions too long");
38314492Ssam 							}
38414492Ssam 						continue;
38514492Ssam 					default:
38614492Ssam 						warning("Invalid request %s",p);
38714492Ssam 						continue;
38814492Ssam 						}	/* end of switch after seeing '%' */
38914492Ssam 				case ' ': case '\t':		/* must be code */
39014492Ssam 					lgate();
39114492Ssam 					fprintf(fout, "%s\n",p);
39214492Ssam 					continue;
39314492Ssam 				default:		/* definition */
39414492Ssam 					while(*p && !space(*p)) p++;
39514492Ssam 					if(*p == 0)
39614492Ssam 						continue;
39714492Ssam 					prev = *p;
39814492Ssam 					*p = 0;
39914492Ssam 					bptr = p+1;
40033344Sbostic 					yylval = (int)buf;
40114492Ssam 					if(digit(buf[0]))
40214492Ssam 						warning("Substitution strings may not begin with digits");
40314492Ssam 					return(freturn(STR));
40414492Ssam 					}
40514492Ssam 				}
40614492Ssam 			/* still sect 1, but prev != '\n' */
40714492Ssam 			else {
40814492Ssam 				p = bptr;
40914492Ssam 				while(*p && space(*p)) p++;
41014492Ssam 				if(*p == 0)
41114492Ssam 					warning("No translation given - null string assumed");
41214492Ssam 				scopy(p,token);
41333344Sbostic 				yylval = (int)token;
41414492Ssam 				prev = '\n';
41514492Ssam 				return(freturn(STR));
41614492Ssam 				}
41714492Ssam 			}
41814492Ssam 		/* end of section one processing */
41914492Ssam 		}
42014492Ssam 	else if(sect == RULESECTION){		/* rules and actions */
42114492Ssam 		while(!eof){
42214492Ssam 			switch(c=gch()){
42314492Ssam 			case '\0':
42414492Ssam 				return(freturn(0));
42514492Ssam 			case '\n':
42614492Ssam 				if(prev == '\n') continue;
42714492Ssam 				x = NEWE;
42814492Ssam 				break;
42914492Ssam 			case ' ':
43014492Ssam 			case '\t':
43114492Ssam 				if(sectbegin == TRUE){
43214492Ssam 					cpyact();
43314492Ssam 					while((c=gch()) && c != '\n');
43414492Ssam 					continue;
43514492Ssam 					}
43614492Ssam 				if(!funcflag)phead2();
43714492Ssam 				funcflag = TRUE;
43814492Ssam 				if(ratfor)fprintf(fout,"%d\n",30000+casecount);
43914492Ssam 				else fprintf(fout,"case %d:\n",casecount);
44014492Ssam 				if(cpyact()){
44114492Ssam 					if(ratfor)fprintf(fout,"goto 30997\n");
44214492Ssam 					else fprintf(fout,"break;\n");
44314492Ssam 					}
44414492Ssam 				while((c=gch()) && c != '\n');
44514492Ssam 				if(peek == ' ' || peek == '\t' || sectbegin == TRUE){
44614492Ssam 					warning("Executable statements should occur right after %%");
44714492Ssam 					continue;
44814492Ssam 					}
44914492Ssam 				x = NEWE;
45014492Ssam 				break;
45114492Ssam 			case '%':
45214492Ssam 				if(prev != '\n') goto character;
45314492Ssam 				if(peek == '{'){	/* included code */
45414492Ssam 					getl(buf);
45514492Ssam 					while(!eof && getl(buf) && scomp("%}",buf) != 0)
45614492Ssam 						fprintf(fout,"%s\n",buf);
45714492Ssam 					continue;
45814492Ssam 					}
45914492Ssam 				if(peek == '%'){
46014492Ssam 					c = gch();
46114492Ssam 					c = gch();
46214492Ssam 					x = DELIM;
46314492Ssam 					break;
46414492Ssam 					}
46514492Ssam 				goto character;
46614492Ssam 			case '|':
46714492Ssam 				if(peek == ' ' || peek == '\t' || peek == '\n'){
46814492Ssam 					if(ratfor)fprintf(fout,"%d\n",30000+casecount++);
46914492Ssam 					else fprintf(fout,"case %d:\n",casecount++);
47014492Ssam 					continue;
47114492Ssam 					}
47214492Ssam 				x = '|';
47314492Ssam 				break;
47414492Ssam 			case '$':
47514492Ssam 				if(peek == '\n' || peek == ' ' || peek == '\t' || peek == '|' || peek == '/'){
47614492Ssam 					x = c;
47714492Ssam 					break;
47814492Ssam 					}
47914492Ssam 				goto character;
48014492Ssam 			case '^':
48114492Ssam 				if(prev != '\n' && scon != TRUE) goto character;	/* valid only at line begin */
48214492Ssam 				x = c;
48314492Ssam 				break;
48414492Ssam 			case '?':
48514492Ssam 			case '+':
48614492Ssam 			case '.':
48714492Ssam 			case '*':
48814492Ssam 			case '(':
48914492Ssam 			case ')':
49014492Ssam 			case ',':
49114492Ssam 			case '/':
49214492Ssam 				x = c;
49314492Ssam 				break;
49414492Ssam 			case '}':
49514492Ssam 				iter = FALSE;
49614492Ssam 				x = c;
49714492Ssam 				break;
49814492Ssam 			case '{':	/* either iteration or definition */
49914492Ssam 				if(digit(c=gch())){	/* iteration */
50014492Ssam 					iter = TRUE;
50114492Ssam 				ieval:
50214492Ssam 					i = 0;
50314492Ssam 					while(digit(c)){
50414492Ssam 						token[i++] = c;
50514492Ssam 						c = gch();
50614492Ssam 						}
50714492Ssam 					token[i] = 0;
50814492Ssam 					yylval = siconv(token);
50914492Ssam 					munput('c',c);
51014492Ssam 					x = ITER;
51114492Ssam 					break;
51214492Ssam 					}
51314492Ssam 				else {		/* definition */
51414492Ssam 					i = 0;
51514492Ssam 					while(c && c!='}'){
51614492Ssam 						token[i++] = c;
51714492Ssam 						c = gch();
51814492Ssam 						}
51914492Ssam 					token[i] = 0;
52014492Ssam 					i = lookup(token,def);
52114492Ssam 					if(i < 0)
52214492Ssam 						warning("Definition %s not found",token);
52314492Ssam 					else
52414492Ssam 						munput('s',subs[i]);
52514492Ssam 					continue;
52614492Ssam 					}
52714492Ssam 			case '<':		/* start condition ? */
52814492Ssam 				if(prev != '\n')		/* not at line begin, not start */
52914492Ssam 					goto character;
53014492Ssam 				t = slptr;
53114492Ssam 				do {
53214492Ssam 					i = 0;
53314492Ssam 					c = gch();
53414492Ssam 					while(c != ',' && c && c != '>'){
53514492Ssam 						token[i++] = c;
53614492Ssam 						c = gch();
53714492Ssam 						}
53814492Ssam 					token[i] = 0;
53914492Ssam 					if(i == 0)
54014492Ssam 						goto character;
54114492Ssam 					i = lookup(token,sname);
54214492Ssam 					if(i < 0) {
54314492Ssam 						warning("Undefined start condition %s",token);
54414492Ssam 						continue;
54514492Ssam 						}
54614492Ssam 					*slptr++ = i+1;
54714492Ssam 					} while(c && c != '>');
54814492Ssam 				*slptr++ = 0;
54914492Ssam 				/* check if previous value re-usable */
55014492Ssam 				for (xp=slist; xp<t; )
55114492Ssam 					{
55214492Ssam 					if (strcmp(xp, t)==0)
55314492Ssam 						break;
55414492Ssam 					while (*xp++);
55514492Ssam 					}
55614492Ssam 				if (xp<t)
55714492Ssam 					{
55814492Ssam 					/* re-use previous pointer to string */
55914492Ssam 					slptr=t;
56014492Ssam 					t=xp;
56114492Ssam 					}
56214492Ssam 				if(slptr > slist+STARTSIZE)		/* note not packed ! */
56314492Ssam 					error("Too many start conditions used");
56433344Sbostic 				yylval = (int)t;
56514492Ssam 				x = SCON;
56614492Ssam 				break;
56714492Ssam 			case '"':
56814492Ssam 				i = 0;
56914492Ssam 				while((c=gch()) && c != '"' && c != '\n'){
57014492Ssam 					if(c == '\\') c = usescape(c=gch());
57114492Ssam 					token[i++] = c;
57214492Ssam 					if(i > TOKENSIZE){
57314492Ssam 						warning("String too long");
57414492Ssam 						i = TOKENSIZE-1;
57514492Ssam 						break;
57614492Ssam 						}
57714492Ssam 					}
57814492Ssam 				if(c == '\n') {
57914492Ssam 					yyline--;
58014492Ssam 					warning("Non-terminated string");
58114492Ssam 					yyline++;
58214492Ssam 					}
58314492Ssam 				token[i] = 0;
58414492Ssam 				if(i == 0)x = NULLS;
58514492Ssam 				else if(i == 1){
58614492Ssam 					yylval = token[0];
58714492Ssam 					x = CHAR;
58814492Ssam 					}
58914492Ssam 				else {
59033344Sbostic 					yylval = (int)token;
59114492Ssam 					x = STR;
59214492Ssam 					}
59314492Ssam 				break;
59414492Ssam 			case '[':
59514492Ssam 				for(i=1;i<NCH;i++) symbol[i] = 0;
59614492Ssam 				x = CCL;
59714492Ssam 				if((c = gch()) == '^'){
59814492Ssam 					x = NCCL;
59914492Ssam 					c = gch();
60014492Ssam 					}
60114492Ssam 				while(c != ']' && c){
60214492Ssam 					if(c == '\\') c = usescape(c=gch());
60314492Ssam 					symbol[c] = 1;
60414492Ssam 					j = c;
60514492Ssam 					if((c=gch()) == '-' && peek != ']'){		/* range specified */
60614492Ssam 						c = gch();
60714492Ssam 						if(c == '\\') c = usescape(c=gch());
60814492Ssam 						k = c;
60914492Ssam 						if(j > k) {
61014492Ssam 							n = j;
61114492Ssam 							j = k;
61214492Ssam 							k = n;
61314492Ssam 							}
61414492Ssam 						if(!(('A' <= j && k <= 'Z') ||
61514492Ssam 						     ('a' <= j && k <= 'z') ||
61614492Ssam 						     ('0' <= j && k <= '9')))
61714492Ssam 							warning("Non-portable Character Class");
61814492Ssam 						for(n=j+1;n<=k;n++)
61914492Ssam 							symbol[n] = 1;		/* implementation dependent */
62014492Ssam 						c = gch();
62114492Ssam 						}
62214492Ssam 					}
62314492Ssam 				/* try to pack ccl's */
62414492Ssam 				i = 0;
62514492Ssam 				for(j=0;j<NCH;j++)
62614492Ssam 					if(symbol[j])token[i++] = j;
62714492Ssam 				token[i] = 0;
62814492Ssam 				p = ccptr;
62914492Ssam 				if(optim){
63014492Ssam 					p = ccl;
63114492Ssam 					while(p <ccptr && scomp(token,p) != 0)p++;
63214492Ssam 					}
63314492Ssam 				if(p < ccptr)	/* found it */
63433344Sbostic 					yylval = (int)p;
63514492Ssam 				else {
63633344Sbostic 					yylval = (int)ccptr;
63714492Ssam 					scopy(token,ccptr);
63814492Ssam 					ccptr += slength(token) + 1;
63914492Ssam 					if(ccptr >= ccl+CCLSIZE)
64014492Ssam 						error("Too many large character classes");
64114492Ssam 					}
64214492Ssam 				cclinter(x==CCL);
64314492Ssam 				break;
64414492Ssam 			case '\\':
64514492Ssam 				c = usescape(c=gch());
64614492Ssam 			default:
64714492Ssam 			character:
64814492Ssam 				if(iter){	/* second part of an iteration */
64914492Ssam 					iter = FALSE;
65014492Ssam 					if('0' <= c && c <= '9')
65114492Ssam 						goto ieval;
65214492Ssam 					}
65314492Ssam 				if(alpha(peek)){
65414492Ssam 					i = 0;
65533344Sbostic 					yylval = (int)token;
65614492Ssam 					token[i++] = c;
65714492Ssam 					while(alpha(peek))
65814492Ssam 						token[i++] = gch();
65914492Ssam 					if(peek == '?' || peek == '*' || peek == '+')
66014492Ssam 						munput('c',token[--i]);
66114492Ssam 					token[i] = 0;
66214492Ssam 					if(i == 1){
66314492Ssam 						yylval = token[0];
66414492Ssam 						x = CHAR;
66514492Ssam 						}
66614492Ssam 					else x = STR;
66714492Ssam 					}
66814492Ssam 				else {
66914492Ssam 					yylval = c;
67014492Ssam 					x = CHAR;
67114492Ssam 					}
67214492Ssam 				}
67314492Ssam 			scon = FALSE;
67414492Ssam 			if(x == SCON)scon = TRUE;
67514492Ssam 			sectbegin = FALSE;
67614492Ssam 			return(freturn(x));
67714492Ssam 			}
67814492Ssam 		}
67914492Ssam 	/* section three */
68014492Ssam 	ptail();
68114492Ssam # ifdef DEBUG
68214492Ssam 	if(debug)
68314492Ssam 		fprintf(fout,"\n/*this comes from section three - debug */\n");
68414492Ssam # endif
68514492Ssam 	while(getl(buf) && !eof)
68614492Ssam 		fprintf(fout,"%s\n",buf);
68714492Ssam 	return(freturn(0));
68814492Ssam 	}
68914492Ssam /* end of yylex */
69014492Ssam # ifdef DEBUG
freturn(i)69114492Ssam freturn(i)
69214492Ssam   int i; {
69314492Ssam 	if(yydebug) {
69414492Ssam 		printf("now return ");
69514492Ssam 		if(i < NCH) allprint(i);
69614492Ssam 		else printf("%d",i);
69714492Ssam 		printf("   yylval = ");
69814492Ssam 		switch(i){
69914492Ssam 			case STR: case CCL: case NCCL:
70014492Ssam 				strpt(yylval);
70114492Ssam 				break;
70214492Ssam 			case CHAR:
70314492Ssam 				allprint(yylval);
70414492Ssam 				break;
70514492Ssam 			default:
70614492Ssam 				printf("%d",yylval);
70714492Ssam 				break;
70814492Ssam 			}
70914492Ssam 		putchar('\n');
71014492Ssam 		}
71114492Ssam 	return(i);
71214492Ssam 	}
71314492Ssam # endif
714