xref: /csrg-svn/old/lex/parser.y (revision 14492)
1*14492Ssam %token CHAR CCL NCCL STR DELIM SCON ITER NEWE NULLS
2*14492Ssam %left SCON '/' NEWE
3*14492Ssam %left '|'
4*14492Ssam %left '$' '^'
5*14492Ssam %left CHAR CCL NCCL '(' '.' STR NULLS
6*14492Ssam %left ITER
7*14492Ssam %left CAT
8*14492Ssam %left '*' '+' '?'
9*14492Ssam 
10*14492Ssam %{
11*14492Ssam #ifndef lint
12*14492Ssam static char sccsid[] = "@(#)parser.y	4.1 (Berkeley) 08/11/83";
13*14492Ssam #endif
14*14492Ssam 
15*14492Ssam # include "ldefs.c"
16*14492Ssam %}
17*14492Ssam %%
18*14492Ssam %{
19*14492Ssam int i;
20*14492Ssam int j,k;
21*14492Ssam int g;
22*14492Ssam char *p;
23*14492Ssam %}
24*14492Ssam acc	:	lexinput
25*14492Ssam 	={
26*14492Ssam # ifdef DEBUG
27*14492Ssam 		if(debug) sect2dump();
28*14492Ssam # endif
29*14492Ssam 	}
30*14492Ssam 	;
31*14492Ssam lexinput:	defns delim prods end
32*14492Ssam 	|	defns delim end
33*14492Ssam 	={
34*14492Ssam 		if(!funcflag)phead2();
35*14492Ssam 		funcflag = TRUE;
36*14492Ssam 	}
37*14492Ssam 	| error
38*14492Ssam 	={
39*14492Ssam # ifdef DEBUG
40*14492Ssam 		if(debug) {
41*14492Ssam 			sect1dump();
42*14492Ssam 			sect2dump();
43*14492Ssam 			}
44*14492Ssam # endif
45*14492Ssam 		}
46*14492Ssam 	;
47*14492Ssam end:		delim | ;
48*14492Ssam defns:	defns STR STR
49*14492Ssam 	={	scopy($2,dp);
50*14492Ssam 		def[dptr] = dp;
51*14492Ssam 		dp += slength($2) + 1;
52*14492Ssam 		scopy($3,dp);
53*14492Ssam 		subs[dptr++] = dp;
54*14492Ssam 		if(dptr >= DEFSIZE)
55*14492Ssam 			error("Too many definitions");
56*14492Ssam 		dp += slength($3) + 1;
57*14492Ssam 		if(dp >= dchar+DEFCHAR)
58*14492Ssam 			error("Definitions too long");
59*14492Ssam 		subs[dptr]=def[dptr]=0;	/* for lookup - require ending null */
60*14492Ssam 	}
61*14492Ssam 	|
62*14492Ssam 	;
63*14492Ssam delim:	DELIM
64*14492Ssam 	={
65*14492Ssam # ifdef DEBUG
66*14492Ssam 		if(sect == DEFSECTION && debug) sect1dump();
67*14492Ssam # endif
68*14492Ssam 		sect++;
69*14492Ssam 		}
70*14492Ssam 	;
71*14492Ssam prods:	prods pr
72*14492Ssam 	={	$$ = mn2(RNEWE,$1,$2);
73*14492Ssam 		}
74*14492Ssam 	|	pr
75*14492Ssam 	={	$$ = $1;}
76*14492Ssam 	;
77*14492Ssam pr:	r NEWE
78*14492Ssam 	={
79*14492Ssam 		if(divflg == TRUE)
80*14492Ssam 			i = mn1(S1FINAL,casecount);
81*14492Ssam 		else i = mn1(FINAL,casecount);
82*14492Ssam 		$$ = mn2(RCAT,$1,i);
83*14492Ssam 		divflg = FALSE;
84*14492Ssam 		casecount++;
85*14492Ssam 		}
86*14492Ssam 	| error NEWE
87*14492Ssam 	={
88*14492Ssam # ifdef DEBUG
89*14492Ssam 		if(debug) sect2dump();
90*14492Ssam # endif
91*14492Ssam 		}
92*14492Ssam r:	CHAR
93*14492Ssam 	={	$$ = mn0($1); }
94*14492Ssam 	| STR
95*14492Ssam 	={
96*14492Ssam 		p = $1;
97*14492Ssam 		i = mn0(*p++);
98*14492Ssam 		while(*p)
99*14492Ssam 			i = mn2(RSTR,i,*p++);
100*14492Ssam 		$$ = i;
101*14492Ssam 		}
102*14492Ssam 	| '.'
103*14492Ssam 	={	symbol['\n'] = 0;
104*14492Ssam 		if(psave == FALSE){
105*14492Ssam 			p = ccptr;
106*14492Ssam 			psave = ccptr;
107*14492Ssam 			for(i=1;i<'\n';i++){
108*14492Ssam 				symbol[i] = 1;
109*14492Ssam 				*ccptr++ = i;
110*14492Ssam 				}
111*14492Ssam 			for(i='\n'+1;i<NCH;i++){
112*14492Ssam 				symbol[i] = 1;
113*14492Ssam 				*ccptr++ = i;
114*14492Ssam 				}
115*14492Ssam 			*ccptr++ = 0;
116*14492Ssam 			if(ccptr > ccl+CCLSIZE)
117*14492Ssam 				error("Too many large character classes");
118*14492Ssam 			}
119*14492Ssam 		else
120*14492Ssam 			p = psave;
121*14492Ssam 		$$ = mn1(RCCL,p);
122*14492Ssam 		cclinter(1);
123*14492Ssam 		}
124*14492Ssam 	| CCL
125*14492Ssam 	={	$$ = mn1(RCCL,$1); }
126*14492Ssam 	| NCCL
127*14492Ssam 	={	$$ = mn1(RNCCL,$1); }
128*14492Ssam 	| r '*'
129*14492Ssam 	={	$$ = mn1(STAR,$1); }
130*14492Ssam 	| r '+'
131*14492Ssam 	={	$$ = mn1(PLUS,$1); }
132*14492Ssam 	| r '?'
133*14492Ssam 	={	$$ = mn1(QUEST,$1); }
134*14492Ssam 	| r '|' r
135*14492Ssam 	={	$$ = mn2(BAR,$1,$3); }
136*14492Ssam 	| r r %prec CAT
137*14492Ssam 	={	$$ = mn2(RCAT,$1,$2); }
138*14492Ssam 	| r '/' r
139*14492Ssam 	={	if(!divflg){
140*14492Ssam 			j = mn1(S2FINAL,-casecount);
141*14492Ssam 			i = mn2(RCAT,$1,j);
142*14492Ssam 			$$ = mn2(DIV,i,$3);
143*14492Ssam 			}
144*14492Ssam 		else {
145*14492Ssam 			$$ = mn2(RCAT,$1,$3);
146*14492Ssam 			warning("Extra slash removed");
147*14492Ssam 			}
148*14492Ssam 		divflg = TRUE;
149*14492Ssam 		}
150*14492Ssam 	| r ITER ',' ITER '}'
151*14492Ssam 	={	if($2 > $4){
152*14492Ssam 			i = $2;
153*14492Ssam 			$2 = $4;
154*14492Ssam 			$4 = i;
155*14492Ssam 			}
156*14492Ssam 		if($4 <= 0)
157*14492Ssam 			warning("Iteration range must be positive");
158*14492Ssam 		else {
159*14492Ssam 			j = $1;
160*14492Ssam 			for(k = 2; k<=$2;k++)
161*14492Ssam 				j = mn2(RCAT,j,dupl($1));
162*14492Ssam 			for(i = $2+1; i<=$4; i++){
163*14492Ssam 				g = dupl($1);
164*14492Ssam 				for(k=2;k<=i;k++)
165*14492Ssam 					g = mn2(RCAT,g,dupl($1));
166*14492Ssam 				j = mn2(BAR,j,g);
167*14492Ssam 				}
168*14492Ssam 			$$ = j;
169*14492Ssam 			}
170*14492Ssam 	}
171*14492Ssam 	| r ITER '}'
172*14492Ssam 	={
173*14492Ssam 		if($2 < 0)warning("Can't have negative iteration");
174*14492Ssam 		else if($2 == 0) $$ = mn0(RNULLS);
175*14492Ssam 		else {
176*14492Ssam 			j = $1;
177*14492Ssam 			for(k=2;k<=$2;k++)
178*14492Ssam 				j = mn2(RCAT,j,dupl($1));
179*14492Ssam 			$$ = j;
180*14492Ssam 			}
181*14492Ssam 		}
182*14492Ssam 	| r ITER ',' '}'
183*14492Ssam 	={
184*14492Ssam 				/* from n to infinity */
185*14492Ssam 		if($2 < 0)warning("Can't have negative iteration");
186*14492Ssam 		else if($2 == 0) $$ = mn1(STAR,$1);
187*14492Ssam 		else if($2 == 1)$$ = mn1(PLUS,$1);
188*14492Ssam 		else {		/* >= 2 iterations minimum */
189*14492Ssam 			j = $1;
190*14492Ssam 			for(k=2;k<$2;k++)
191*14492Ssam 				j = mn2(RCAT,j,dupl($1));
192*14492Ssam 			k = mn1(PLUS,dupl($1));
193*14492Ssam 			$$ = mn2(RCAT,j,k);
194*14492Ssam 			}
195*14492Ssam 		}
196*14492Ssam 	| SCON r
197*14492Ssam 	={	$$ = mn2(RSCON,$2,$1); }
198*14492Ssam 	| '^' r
199*14492Ssam 	={	$$ = mn1(CARAT,$2); }
200*14492Ssam 	| r '$'
201*14492Ssam 	={	i = mn0('\n');
202*14492Ssam 		if(!divflg){
203*14492Ssam 			j = mn1(S2FINAL,-casecount);
204*14492Ssam 			k = mn2(RCAT,$1,j);
205*14492Ssam 			$$ = mn2(DIV,k,i);
206*14492Ssam 			}
207*14492Ssam 		else $$ = mn2(RCAT,$1,i);
208*14492Ssam 		divflg = TRUE;
209*14492Ssam 		}
210*14492Ssam 	| '(' r ')'
211*14492Ssam 	={	$$ = $2; }
212*14492Ssam 	|	NULLS
213*14492Ssam 	={	$$ = mn0(RNULLS); }
214*14492Ssam 	;
215*14492Ssam %%
216*14492Ssam yylex(){
217*14492Ssam 	register char *p;
218*14492Ssam 	register int c, i;
219*14492Ssam 	char  *t, *xp;
220*14492Ssam 	int n, j, k, x;
221*14492Ssam 	static int sectbegin;
222*14492Ssam 	static char token[TOKENSIZE];
223*14492Ssam 	static int iter;
224*14492Ssam 
225*14492Ssam # ifdef DEBUG
226*14492Ssam 	yylval = 0;
227*14492Ssam # endif
228*14492Ssam 
229*14492Ssam 	if(sect == DEFSECTION) {		/* definitions section */
230*14492Ssam 		while(!eof) {
231*14492Ssam 			if(prev == '\n'){		/* next char is at beginning of line */
232*14492Ssam 				getl(p=buf);
233*14492Ssam 				switch(*p){
234*14492Ssam 				case '%':
235*14492Ssam 					switch(c= *(p+1)){
236*14492Ssam 					case '%':
237*14492Ssam 						lgate();
238*14492Ssam 						if(!ratfor)fprintf(fout,"# ");
239*14492Ssam 						fprintf(fout,"define YYNEWLINE %d\n",ctable['\n']);
240*14492Ssam 						if(!ratfor)fprintf(fout,"yylex(){\nint nstr; extern int yyprevious;\n");
241*14492Ssam 						sectbegin = TRUE;
242*14492Ssam 						i = treesize*(sizeof(*name)+sizeof(*left)+
243*14492Ssam 							sizeof(*right)+sizeof(*nullstr)+sizeof(*parent))+ALITTLEEXTRA;
244*14492Ssam 						c = myalloc(i,1);
245*14492Ssam 						if(c == 0)
246*14492Ssam 							error("Too little core for parse tree");
247*14492Ssam 						p = c;
248*14492Ssam 						cfree(p,i,1);
249*14492Ssam 						name = myalloc(treesize,sizeof(*name));
250*14492Ssam 						left = myalloc(treesize,sizeof(*left));
251*14492Ssam 						right = myalloc(treesize,sizeof(*right));
252*14492Ssam 						nullstr = myalloc(treesize,sizeof(*nullstr));
253*14492Ssam 						parent = myalloc(treesize,sizeof(*parent));
254*14492Ssam 						if(name == 0 || left == 0 || right == 0 || parent == 0 || nullstr == 0)
255*14492Ssam 							error("Too little core for parse tree");
256*14492Ssam 						return(freturn(DELIM));
257*14492Ssam 					case 'p': case 'P':	/* has overridden number of positions */
258*14492Ssam 						while(*p && !digit(*p))p++;
259*14492Ssam 						maxpos = siconv(p);
260*14492Ssam # ifdef DEBUG
261*14492Ssam 						if (debug) printf("positions (%%p) now %d\n",maxpos);
262*14492Ssam # endif
263*14492Ssam 						if(report == 2)report = 1;
264*14492Ssam 						continue;
265*14492Ssam 					case 'n': case 'N':	/* has overridden number of states */
266*14492Ssam 						while(*p && !digit(*p))p++;
267*14492Ssam 						nstates = siconv(p);
268*14492Ssam # ifdef DEBUG
269*14492Ssam 						if(debug)printf( " no. states (%%n) now %d\n",nstates);
270*14492Ssam # endif
271*14492Ssam 						if(report == 2)report = 1;
272*14492Ssam 						continue;
273*14492Ssam 					case 'e': case 'E':		/* has overridden number of tree nodes */
274*14492Ssam 						while(*p && !digit(*p))p++;
275*14492Ssam 						treesize = siconv(p);
276*14492Ssam # ifdef DEBUG
277*14492Ssam 						if (debug) printf("treesize (%%e) now %d\n",treesize);
278*14492Ssam # endif
279*14492Ssam 						if(report == 2)report = 1;
280*14492Ssam 						continue;
281*14492Ssam 					case 'o': case 'O':
282*14492Ssam 						while (*p && !digit(*p))p++;
283*14492Ssam 						outsize = siconv(p);
284*14492Ssam 						if (report ==2) report=1;
285*14492Ssam 						continue;
286*14492Ssam 					case 'a': case 'A':		/* has overridden number of transitions */
287*14492Ssam 						while(*p && !digit(*p))p++;
288*14492Ssam 						if(report == 2)report = 1;
289*14492Ssam 						ntrans = siconv(p);
290*14492Ssam # ifdef DEBUG
291*14492Ssam 						if (debug)printf("N. trans (%%a) now %d\n",ntrans);
292*14492Ssam # endif
293*14492Ssam 						continue;
294*14492Ssam 					case 'k': case 'K': /* overriden packed char classes */
295*14492Ssam 						while (*p && !digit(*p))p++;
296*14492Ssam 						if (report==2) report=1;
297*14492Ssam 						cfree(pchar, pchlen, sizeof(*pchar));
298*14492Ssam 						pchlen = siconv(p);
299*14492Ssam # ifdef DEBUG
300*14492Ssam 						if (debug) printf( "Size classes (%%k) now %d\n",pchlen);
301*14492Ssam # endif
302*14492Ssam 						pchar=pcptr=myalloc(pchlen, sizeof(*pchar));
303*14492Ssam 						continue;
304*14492Ssam 					case 't': case 'T': 	/* character set specifier */
305*14492Ssam 						ZCH = atoi(p+2);
306*14492Ssam 						if (ZCH < NCH) ZCH = NCH;
307*14492Ssam 						if (ZCH > 2*NCH) error("ch table needs redeclaration");
308*14492Ssam 						chset = TRUE;
309*14492Ssam 						for(i = 0; i<ZCH; i++)
310*14492Ssam 							ctable[i] = 0;
311*14492Ssam 						while(getl(p) && scomp(p,"%T") != 0 && scomp(p,"%t") != 0){
312*14492Ssam 							if((n = siconv(p)) <= 0 || n > ZCH){
313*14492Ssam 								warning("Character value %d out of range",n);
314*14492Ssam 								continue;
315*14492Ssam 								}
316*14492Ssam 							while(!space(*p) && *p) p++;
317*14492Ssam 							while(space(*p)) p++;
318*14492Ssam 							t = p;
319*14492Ssam 							while(*t){
320*14492Ssam 								c = ctrans(&t);
321*14492Ssam 								if(ctable[c]){
322*14492Ssam 									if (printable(c))
323*14492Ssam 										warning("Character '%c' used twice",c);
324*14492Ssam 									else
325*14492Ssam 										warning("Character %o used twice",c);
326*14492Ssam 									}
327*14492Ssam 								else ctable[c] = n;
328*14492Ssam 								t++;
329*14492Ssam 								}
330*14492Ssam 							p = buf;
331*14492Ssam 							}
332*14492Ssam 						{
333*14492Ssam 						char chused[2*NCH]; int kr;
334*14492Ssam 						for(i=0; i<ZCH; i++)
335*14492Ssam 							chused[i]=0;
336*14492Ssam 						for(i=0; i<NCH; i++)
337*14492Ssam 							chused[ctable[i]]=1;
338*14492Ssam 						for(kr=i=1; i<NCH; i++)
339*14492Ssam 							if (ctable[i]==0)
340*14492Ssam 								{
341*14492Ssam 								while (chused[kr] == 0)
342*14492Ssam 									kr++;
343*14492Ssam 								ctable[i]=kr;
344*14492Ssam 								chused[kr]=1;
345*14492Ssam 								}
346*14492Ssam 						}
347*14492Ssam 						lgate();
348*14492Ssam 						continue;
349*14492Ssam 					case 'r': case 'R':
350*14492Ssam 						c = 'r';
351*14492Ssam 					case 'c': case 'C':
352*14492Ssam 						if(lgatflg)
353*14492Ssam 							error("Too late for language specifier");
354*14492Ssam 						ratfor = (c == 'r');
355*14492Ssam 						continue;
356*14492Ssam 					case '{':
357*14492Ssam 						lgate();
358*14492Ssam 						while(getl(p) && scomp(p,"%}") != 0)
359*14492Ssam 							fprintf(fout, "%s\n",p);
360*14492Ssam 						if(p[0] == '%') continue;
361*14492Ssam 						error("Premature eof");
362*14492Ssam 					case 's': case 'S':		/* start conditions */
363*14492Ssam 						lgate();
364*14492Ssam 						while(*p && index(*p," \t,") < 0) p++;
365*14492Ssam 						n = TRUE;
366*14492Ssam 						while(n){
367*14492Ssam 							while(*p && index(*p," \t,") >= 0) p++;
368*14492Ssam 							t = p;
369*14492Ssam 							while(*p && index(*p," \t,") < 0)p++;
370*14492Ssam 							if(!*p) n = FALSE;
371*14492Ssam 							*p++ = 0;
372*14492Ssam 							if (*t == 0) continue;
373*14492Ssam 							i = sptr*2;
374*14492Ssam 							if(!ratfor)fprintf(fout,"# ");
375*14492Ssam 							fprintf(fout,"define %s %d\n",t,i);
376*14492Ssam 							scopy(t,sp);
377*14492Ssam 							sname[sptr++] = sp;
378*14492Ssam 							sname[sptr] = 0;	/* required by lookup */
379*14492Ssam 							if(sptr >= STARTSIZE)
380*14492Ssam 								error("Too many start conditions");
381*14492Ssam 							sp += slength(sp) + 1;
382*14492Ssam 							if(sp >= schar+STARTCHAR)
383*14492Ssam 								error("Start conditions too long");
384*14492Ssam 							}
385*14492Ssam 						continue;
386*14492Ssam 					default:
387*14492Ssam 						warning("Invalid request %s",p);
388*14492Ssam 						continue;
389*14492Ssam 						}	/* end of switch after seeing '%' */
390*14492Ssam 				case ' ': case '\t':		/* must be code */
391*14492Ssam 					lgate();
392*14492Ssam 					fprintf(fout, "%s\n",p);
393*14492Ssam 					continue;
394*14492Ssam 				default:		/* definition */
395*14492Ssam 					while(*p && !space(*p)) p++;
396*14492Ssam 					if(*p == 0)
397*14492Ssam 						continue;
398*14492Ssam 					prev = *p;
399*14492Ssam 					*p = 0;
400*14492Ssam 					bptr = p+1;
401*14492Ssam 					yylval = buf;
402*14492Ssam 					if(digit(buf[0]))
403*14492Ssam 						warning("Substitution strings may not begin with digits");
404*14492Ssam 					return(freturn(STR));
405*14492Ssam 					}
406*14492Ssam 				}
407*14492Ssam 			/* still sect 1, but prev != '\n' */
408*14492Ssam 			else {
409*14492Ssam 				p = bptr;
410*14492Ssam 				while(*p && space(*p)) p++;
411*14492Ssam 				if(*p == 0)
412*14492Ssam 					warning("No translation given - null string assumed");
413*14492Ssam 				scopy(p,token);
414*14492Ssam 				yylval = token;
415*14492Ssam 				prev = '\n';
416*14492Ssam 				return(freturn(STR));
417*14492Ssam 				}
418*14492Ssam 			}
419*14492Ssam 		/* end of section one processing */
420*14492Ssam 		}
421*14492Ssam 	else if(sect == RULESECTION){		/* rules and actions */
422*14492Ssam 		while(!eof){
423*14492Ssam 			switch(c=gch()){
424*14492Ssam 			case '\0':
425*14492Ssam 				return(freturn(0));
426*14492Ssam 			case '\n':
427*14492Ssam 				if(prev == '\n') continue;
428*14492Ssam 				x = NEWE;
429*14492Ssam 				break;
430*14492Ssam 			case ' ':
431*14492Ssam 			case '\t':
432*14492Ssam 				if(sectbegin == TRUE){
433*14492Ssam 					cpyact();
434*14492Ssam 					while((c=gch()) && c != '\n');
435*14492Ssam 					continue;
436*14492Ssam 					}
437*14492Ssam 				if(!funcflag)phead2();
438*14492Ssam 				funcflag = TRUE;
439*14492Ssam 				if(ratfor)fprintf(fout,"%d\n",30000+casecount);
440*14492Ssam 				else fprintf(fout,"case %d:\n",casecount);
441*14492Ssam 				if(cpyact()){
442*14492Ssam 					if(ratfor)fprintf(fout,"goto 30997\n");
443*14492Ssam 					else fprintf(fout,"break;\n");
444*14492Ssam 					}
445*14492Ssam 				while((c=gch()) && c != '\n');
446*14492Ssam 				if(peek == ' ' || peek == '\t' || sectbegin == TRUE){
447*14492Ssam 					warning("Executable statements should occur right after %%");
448*14492Ssam 					continue;
449*14492Ssam 					}
450*14492Ssam 				x = NEWE;
451*14492Ssam 				break;
452*14492Ssam 			case '%':
453*14492Ssam 				if(prev != '\n') goto character;
454*14492Ssam 				if(peek == '{'){	/* included code */
455*14492Ssam 					getl(buf);
456*14492Ssam 					while(!eof && getl(buf) && scomp("%}",buf) != 0)
457*14492Ssam 						fprintf(fout,"%s\n",buf);
458*14492Ssam 					continue;
459*14492Ssam 					}
460*14492Ssam 				if(peek == '%'){
461*14492Ssam 					c = gch();
462*14492Ssam 					c = gch();
463*14492Ssam 					x = DELIM;
464*14492Ssam 					break;
465*14492Ssam 					}
466*14492Ssam 				goto character;
467*14492Ssam 			case '|':
468*14492Ssam 				if(peek == ' ' || peek == '\t' || peek == '\n'){
469*14492Ssam 					if(ratfor)fprintf(fout,"%d\n",30000+casecount++);
470*14492Ssam 					else fprintf(fout,"case %d:\n",casecount++);
471*14492Ssam 					continue;
472*14492Ssam 					}
473*14492Ssam 				x = '|';
474*14492Ssam 				break;
475*14492Ssam 			case '$':
476*14492Ssam 				if(peek == '\n' || peek == ' ' || peek == '\t' || peek == '|' || peek == '/'){
477*14492Ssam 					x = c;
478*14492Ssam 					break;
479*14492Ssam 					}
480*14492Ssam 				goto character;
481*14492Ssam 			case '^':
482*14492Ssam 				if(prev != '\n' && scon != TRUE) goto character;	/* valid only at line begin */
483*14492Ssam 				x = c;
484*14492Ssam 				break;
485*14492Ssam 			case '?':
486*14492Ssam 			case '+':
487*14492Ssam 			case '.':
488*14492Ssam 			case '*':
489*14492Ssam 			case '(':
490*14492Ssam 			case ')':
491*14492Ssam 			case ',':
492*14492Ssam 			case '/':
493*14492Ssam 				x = c;
494*14492Ssam 				break;
495*14492Ssam 			case '}':
496*14492Ssam 				iter = FALSE;
497*14492Ssam 				x = c;
498*14492Ssam 				break;
499*14492Ssam 			case '{':	/* either iteration or definition */
500*14492Ssam 				if(digit(c=gch())){	/* iteration */
501*14492Ssam 					iter = TRUE;
502*14492Ssam 				ieval:
503*14492Ssam 					i = 0;
504*14492Ssam 					while(digit(c)){
505*14492Ssam 						token[i++] = c;
506*14492Ssam 						c = gch();
507*14492Ssam 						}
508*14492Ssam 					token[i] = 0;
509*14492Ssam 					yylval = siconv(token);
510*14492Ssam 					munput('c',c);
511*14492Ssam 					x = ITER;
512*14492Ssam 					break;
513*14492Ssam 					}
514*14492Ssam 				else {		/* definition */
515*14492Ssam 					i = 0;
516*14492Ssam 					while(c && c!='}'){
517*14492Ssam 						token[i++] = c;
518*14492Ssam 						c = gch();
519*14492Ssam 						}
520*14492Ssam 					token[i] = 0;
521*14492Ssam 					i = lookup(token,def);
522*14492Ssam 					if(i < 0)
523*14492Ssam 						warning("Definition %s not found",token);
524*14492Ssam 					else
525*14492Ssam 						munput('s',subs[i]);
526*14492Ssam 					continue;
527*14492Ssam 					}
528*14492Ssam 			case '<':		/* start condition ? */
529*14492Ssam 				if(prev != '\n')		/* not at line begin, not start */
530*14492Ssam 					goto character;
531*14492Ssam 				t = slptr;
532*14492Ssam 				do {
533*14492Ssam 					i = 0;
534*14492Ssam 					c = gch();
535*14492Ssam 					while(c != ',' && c && c != '>'){
536*14492Ssam 						token[i++] = c;
537*14492Ssam 						c = gch();
538*14492Ssam 						}
539*14492Ssam 					token[i] = 0;
540*14492Ssam 					if(i == 0)
541*14492Ssam 						goto character;
542*14492Ssam 					i = lookup(token,sname);
543*14492Ssam 					if(i < 0) {
544*14492Ssam 						warning("Undefined start condition %s",token);
545*14492Ssam 						continue;
546*14492Ssam 						}
547*14492Ssam 					*slptr++ = i+1;
548*14492Ssam 					} while(c && c != '>');
549*14492Ssam 				*slptr++ = 0;
550*14492Ssam 				/* check if previous value re-usable */
551*14492Ssam 				for (xp=slist; xp<t; )
552*14492Ssam 					{
553*14492Ssam 					if (strcmp(xp, t)==0)
554*14492Ssam 						break;
555*14492Ssam 					while (*xp++);
556*14492Ssam 					}
557*14492Ssam 				if (xp<t)
558*14492Ssam 					{
559*14492Ssam 					/* re-use previous pointer to string */
560*14492Ssam 					slptr=t;
561*14492Ssam 					t=xp;
562*14492Ssam 					}
563*14492Ssam 				if(slptr > slist+STARTSIZE)		/* note not packed ! */
564*14492Ssam 					error("Too many start conditions used");
565*14492Ssam 				yylval = t;
566*14492Ssam 				x = SCON;
567*14492Ssam 				break;
568*14492Ssam 			case '"':
569*14492Ssam 				i = 0;
570*14492Ssam 				while((c=gch()) && c != '"' && c != '\n'){
571*14492Ssam 					if(c == '\\') c = usescape(c=gch());
572*14492Ssam 					token[i++] = c;
573*14492Ssam 					if(i > TOKENSIZE){
574*14492Ssam 						warning("String too long");
575*14492Ssam 						i = TOKENSIZE-1;
576*14492Ssam 						break;
577*14492Ssam 						}
578*14492Ssam 					}
579*14492Ssam 				if(c == '\n') {
580*14492Ssam 					yyline--;
581*14492Ssam 					warning("Non-terminated string");
582*14492Ssam 					yyline++;
583*14492Ssam 					}
584*14492Ssam 				token[i] = 0;
585*14492Ssam 				if(i == 0)x = NULLS;
586*14492Ssam 				else if(i == 1){
587*14492Ssam 					yylval = token[0];
588*14492Ssam 					x = CHAR;
589*14492Ssam 					}
590*14492Ssam 				else {
591*14492Ssam 					yylval = token;
592*14492Ssam 					x = STR;
593*14492Ssam 					}
594*14492Ssam 				break;
595*14492Ssam 			case '[':
596*14492Ssam 				for(i=1;i<NCH;i++) symbol[i] = 0;
597*14492Ssam 				x = CCL;
598*14492Ssam 				if((c = gch()) == '^'){
599*14492Ssam 					x = NCCL;
600*14492Ssam 					c = gch();
601*14492Ssam 					}
602*14492Ssam 				while(c != ']' && c){
603*14492Ssam 					if(c == '\\') c = usescape(c=gch());
604*14492Ssam 					symbol[c] = 1;
605*14492Ssam 					j = c;
606*14492Ssam 					if((c=gch()) == '-' && peek != ']'){		/* range specified */
607*14492Ssam 						c = gch();
608*14492Ssam 						if(c == '\\') c = usescape(c=gch());
609*14492Ssam 						k = c;
610*14492Ssam 						if(j > k) {
611*14492Ssam 							n = j;
612*14492Ssam 							j = k;
613*14492Ssam 							k = n;
614*14492Ssam 							}
615*14492Ssam 						if(!(('A' <= j && k <= 'Z') ||
616*14492Ssam 						     ('a' <= j && k <= 'z') ||
617*14492Ssam 						     ('0' <= j && k <= '9')))
618*14492Ssam 							warning("Non-portable Character Class");
619*14492Ssam 						for(n=j+1;n<=k;n++)
620*14492Ssam 							symbol[n] = 1;		/* implementation dependent */
621*14492Ssam 						c = gch();
622*14492Ssam 						}
623*14492Ssam 					}
624*14492Ssam 				/* try to pack ccl's */
625*14492Ssam 				i = 0;
626*14492Ssam 				for(j=0;j<NCH;j++)
627*14492Ssam 					if(symbol[j])token[i++] = j;
628*14492Ssam 				token[i] = 0;
629*14492Ssam 				p = ccptr;
630*14492Ssam 				if(optim){
631*14492Ssam 					p = ccl;
632*14492Ssam 					while(p <ccptr && scomp(token,p) != 0)p++;
633*14492Ssam 					}
634*14492Ssam 				if(p < ccptr)	/* found it */
635*14492Ssam 					yylval = p;
636*14492Ssam 				else {
637*14492Ssam 					yylval = ccptr;
638*14492Ssam 					scopy(token,ccptr);
639*14492Ssam 					ccptr += slength(token) + 1;
640*14492Ssam 					if(ccptr >= ccl+CCLSIZE)
641*14492Ssam 						error("Too many large character classes");
642*14492Ssam 					}
643*14492Ssam 				cclinter(x==CCL);
644*14492Ssam 				break;
645*14492Ssam 			case '\\':
646*14492Ssam 				c = usescape(c=gch());
647*14492Ssam 			default:
648*14492Ssam 			character:
649*14492Ssam 				if(iter){	/* second part of an iteration */
650*14492Ssam 					iter = FALSE;
651*14492Ssam 					if('0' <= c && c <= '9')
652*14492Ssam 						goto ieval;
653*14492Ssam 					}
654*14492Ssam 				if(alpha(peek)){
655*14492Ssam 					i = 0;
656*14492Ssam 					yylval = token;
657*14492Ssam 					token[i++] = c;
658*14492Ssam 					while(alpha(peek))
659*14492Ssam 						token[i++] = gch();
660*14492Ssam 					if(peek == '?' || peek == '*' || peek == '+')
661*14492Ssam 						munput('c',token[--i]);
662*14492Ssam 					token[i] = 0;
663*14492Ssam 					if(i == 1){
664*14492Ssam 						yylval = token[0];
665*14492Ssam 						x = CHAR;
666*14492Ssam 						}
667*14492Ssam 					else x = STR;
668*14492Ssam 					}
669*14492Ssam 				else {
670*14492Ssam 					yylval = c;
671*14492Ssam 					x = CHAR;
672*14492Ssam 					}
673*14492Ssam 				}
674*14492Ssam 			scon = FALSE;
675*14492Ssam 			if(x == SCON)scon = TRUE;
676*14492Ssam 			sectbegin = FALSE;
677*14492Ssam 			return(freturn(x));
678*14492Ssam 			}
679*14492Ssam 		}
680*14492Ssam 	/* section three */
681*14492Ssam 	ptail();
682*14492Ssam # ifdef DEBUG
683*14492Ssam 	if(debug)
684*14492Ssam 		fprintf(fout,"\n/*this comes from section three - debug */\n");
685*14492Ssam # endif
686*14492Ssam 	while(getl(buf) && !eof)
687*14492Ssam 		fprintf(fout,"%s\n",buf);
688*14492Ssam 	return(freturn(0));
689*14492Ssam 	}
690*14492Ssam /* end of yylex */
691*14492Ssam # ifdef DEBUG
692*14492Ssam freturn(i)
693*14492Ssam   int i; {
694*14492Ssam 	if(yydebug) {
695*14492Ssam 		printf("now return ");
696*14492Ssam 		if(i < NCH) allprint(i);
697*14492Ssam 		else printf("%d",i);
698*14492Ssam 		printf("   yylval = ");
699*14492Ssam 		switch(i){
700*14492Ssam 			case STR: case CCL: case NCCL:
701*14492Ssam 				strpt(yylval);
702*14492Ssam 				break;
703*14492Ssam 			case CHAR:
704*14492Ssam 				allprint(yylval);
705*14492Ssam 				break;
706*14492Ssam 			default:
707*14492Ssam 				printf("%d",yylval);
708*14492Ssam 				break;
709*14492Ssam 			}
710*14492Ssam 		putchar('\n');
711*14492Ssam 		}
712*14492Ssam 	return(i);
713*14492Ssam 	}
714*14492Ssam # endif
715