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