standardize sccs keyword lines
[unix-history] / usr / src / old / lex / sub1.c
CommitLineData
90d00910
SL
1#ifndef lint
2static char sccsid[] = "@(#)sub1.c 4.1 (Berkeley) %G%";
3#endif
4
5# include "ldefs.c"
6char *
7getl(p) /* return next line of input, throw away trailing '\n' */
8 /* returns 0 if eof is had immediately */
9 char *p;
10 {
11 register int c;
12 register char *s, *t;
13 t = s = p;
14 while(((c = gch()) != 0) && c != '\n')
15 *t++ = c;
16 *t = 0;
17 if(c == 0 && s == t) return(0);
18 prev = '\n';
19 pres = '\n';
20 return(s);
21 }
22space(ch)
23 {
24 switch(ch)
25 {
26 case ' ':
27 case '\t':
28 case '\n':
29 return(1);
30 }
31 return(0);
32 }
33
34digit(c)
35{
36 return(c>='0' && c <= '9');
37}
38error(s,p,d)
39 {
40 if(!eof)fprintf(errorf,"%d: ",yyline);
41 fprintf(errorf,"(Error) ");
42 fprintf(errorf,s,p,d);
43 putc('\n',errorf);
44# ifdef DEBUG
45 if(debug && sect != ENDSECTION) {
46 sect1dump();
47 sect2dump();
48 }
49# endif
50 if(
51# ifdef DEBUG
52 debug ||
53# endif
54 report == 1) statistics();
55 exit(1); /* error return code */
56 }
57
58warning(s,p,d)
59 {
60 if(!eof)fprintf(errorf,"%d: ",yyline);
61 fprintf(errorf,"(Warning) ");
62 fprintf(errorf,s,p,d);
63 putc('\n',errorf);
64 fflush(errorf);
65 fflush(fout);
66 fflush(stdout);
67 }
68index(a,s)
69 char *s;
70{
71 register int k;
72 for(k=0; s[k]; k++)
73 if (s[k]== a)
74 return(k);
75 return(-1);
76 }
77
78alpha(c)
79 int c; {
80# ifdef ASCII
81return('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z');
82# endif
83# ifdef EBCDIC
84return(index(c,"abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") >= 0);
85# endif
86}
87printable(c)
88{
89# ifdef ASCII
90return( c>040 && c < 0177);
91# endif
92# ifdef EBCDIC
93return(index(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,;:><+*)('&%!-=\"")>=0);
94# endif
95}
96lgate()
97{
98 char fname[20];
99 if (lgatflg) return;
100 lgatflg=1;
101 if(fout == NULL){
102 sprintf(fname, "lex.yy.%c", ratfor ? 'r' : 'c' );
103 fout = fopen(fname, "w");
104 }
105 if(fout == NULL) error("Can't open %s",fname);
106 if(ratfor) fprintf( fout, "#\n");
107 phead1();
108 }
109/* scopy(ptr to str, ptr to str) - copy first arg str to second */
110/* returns ptr to second arg */
111scopy(s,t)
112 char *s, *t; {
113 register char *i;
114 i = t;
115 while(*i++ = *s++);
116 return;
117 }
118siconv(t) /* convert string t, return integer value */
119 char *t; {
120 register int i,sw;
121 register char *s;
122 s = t;
123 while(!(('0' <= *s && *s <= '9') || *s == '-') && *s) s++;
124 sw = 0;
125 if(*s == '-'){ /* neg */
126 sw = 1;
127 s++;
128 }
129 i = 0;
130 while('0' <= *s && *s <= '9')
131 i = i * 10 + (*(s++)-'0');
132 return(sw ? -i : i);
133 }
134/* slength(ptr to str) - return integer length of string arg */
135/* excludes '\0' terminator */
136slength(s)
137 char *s; {
138 register int n;
139 register char *t;
140 t = s;
141 for (n = 0; *t++; n++);
142 return(n);
143 }
144/* scomp(x,y) - return -1 if x < y,
145 0 if x == y,
146 return 1 if x > y, all lexicographically */
147scomp(x,y)
148 char *x,*y; {
149 register char *a,*d;
150 a = x;
151 d = y;
152 while(*a || *d){
153 if(*a > *d)
154 return(1); /* greater */
155 if(*a < *d)
156 return(-1); /* less */
157 a++;
158 d++;
159 }
160 return(0); /* equal */
161 }
162ctrans(ss)
163 char **ss;
164{
165 register int c, k;
166 if ((c = **ss) != '\\')
167 return(c);
168 switch(c= *++*ss)
169 {
170 case 'n': c = '\n'; break;
171 case 't': c = '\t'; break;
172 case 'r': c = '\r'; break;
173 case 'b': c = '\b'; break;
174 case 'f': c = 014; break; /* form feed for ascii */
175 case '\\': c = '\\'; break;
176 case '0': case '1': case '2': case '3':
177 case '4': case '5': case '6': case '7':
178 c -= '0';
179 while ((k = *(*ss+1)) >= '0' && k <= '7')
180 {
181 c = c*8 + k - '0';
182 (*ss)++;
183 }
184 break;
185 }
186 return(c);
187}
188cclinter(sw)
189 int sw; {
190 /* sw = 1 ==> ccl */
191 register int i, j, k;
192 int m;
193 if(!sw){ /* is NCCL */
194 for(i=1;i<NCH;i++)
195 symbol[i] ^= 1; /* reverse value */
196 }
197 for(i=1;i<NCH;i++)
198 if(symbol[i]) break;
199 if(i >= NCH) return;
200 i = cindex[i];
201 /* see if ccl is already in our table */
202 j = 0;
203 if(i){
204 for(j=1;j<NCH;j++){
205 if((symbol[j] && cindex[j] != i) ||
206 (!symbol[j] && cindex[j] == i)) break;
207 }
208 }
209 if(j >= NCH) return; /* already in */
210 m = 0;
211 k = 0;
212 for(i=1;i<NCH;i++)
213 if(symbol[i]){
214 if(!cindex[i]){
215 cindex[i] = ccount;
216 symbol[i] = 0;
217 m = 1;
218 }
219 else k = 1;
220 }
221 /* m == 1 implies last value of ccount has been used */
222 if(m)ccount++;
223 if(k == 0) return; /* is now in as ccount wholly */
224 /* intersection must be computed */
225 for(i=1;i<NCH;i++){
226 if(symbol[i]){
227 m = 0;
228 j = cindex[i]; /* will be non-zero */
229 for(k=1;k<NCH;k++){
230 if(cindex[k] == j){
231 if(symbol[k]) symbol[k] = 0;
232 else {
233 cindex[k] = ccount;
234 m = 1;
235 }
236 }
237 }
238 if(m)ccount++;
239 }
240 }
241 return;
242 }
243usescape(c)
244 int c; {
245 register char d;
246 switch(c){
247 case 'n': c = '\n'; break;
248 case 'r': c = '\r'; break;
249 case 't': c = '\t'; break;
250 case 'b': c = '\b'; break;
251 case 'f': c = 014; break; /* form feed for ascii */
252 case '0': case '1': case '2': case '3':
253 case '4': case '5': case '6': case '7':
254 c -= '0';
255 while('0' <= (d=gch()) && d <= '7'){
256 c = c * 8 + (d-'0');
257 if(!('0' <= peek && peek <= '7')) break;
258 }
259 break;
260 }
261 return(c);
262 }
263lookup(s,t)
264 char *s;
265 char **t; {
266 register int i;
267 i = 0;
268 while(*t){
269 if(scomp(s,*t) == 0)
270 return(i);
271 i++;
272 t++;
273 }
274 return(-1);
275 }
276cpyact(){ /* copy C action to the next ; or closing } */
277 register int brac, c, mth;
278 int savline, sw;
279
280 brac = 0;
281 sw = TRUE;
282
283while(!eof){
284 c = gch();
285swt:
286 switch( c ){
287
288case '|': if(brac == 0 && sw == TRUE){
289 if(peek == '|')gch(); /* eat up an extra '|' */
290 return(0);
291 }
292 break;
293
294case ';':
295 if( brac == 0 ){
296 putc(c,fout);
297 putc('\n',fout);
298 return(1);
299 }
300 break;
301
302case '{':
303 brac++;
304 savline=yyline;
305 break;
306
307case '}':
308 brac--;
309 if( brac == 0 ){
310 putc(c,fout);
311 putc('\n',fout);
312 return(1);
313 }
314 break;
315
316case '/': /* look for comments */
317 putc(c,fout);
318 c = gch();
319 if( c != '*' ) goto swt;
320
321 /* it really is a comment */
322
323 putc(c,fout);
324 savline=yyline;
325 while( c=gch() ){
326 if( c=='*' ){
327 putc(c,fout);
328 if( (c=gch()) == '/' ) goto loop;
329 }
330 putc(c,fout);
331 }
332 yyline=savline;
333 error( "EOF inside comment" );
334
335case '\'': /* character constant */
336 mth = '\'';
337 goto string;
338
339case '"': /* character string */
340 mth = '"';
341
342 string:
343
344 putc(c,fout);
345 while( c=gch() ){
346 if( c=='\\' ){
347 putc(c,fout);
348 c=gch();
349 }
350 else if( c==mth ) goto loop;
351 putc(c,fout);
352 if (c == '\n')
353 {
354 yyline--;
355 error( "Non-terminated string or character constant");
356 }
357 }
358 error( "EOF in string or character constant" );
359
360case '\0':
361 yyline = savline;
362 error("Action does not terminate");
363default:
364 break; /* usual character */
365 }
366loop:
367 if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;
368 putc(c,fout);
369 }
370error("Premature EOF");
371}
372gch(){
373 register int c;
374 prev = pres;
375 c = pres = peek;
376 peek = pushptr > pushc ? *--pushptr : getc(fin);
377 if(peek == EOF && sargc > 1){
378 fclose(fin);
379 fin = fopen(sargv[++fptr],"r");
380 if(fin == NULL)
381 error("Cannot open file %s",sargv[fptr]);
382 peek = getc(fin);
383 sargc--;
384 sargv++;
385 }
386 if(c == EOF) {
387 eof = TRUE;
388 fclose(fin);
389 return(0);
390 }
391 if(c == '\n')yyline++;
392 return(c);
393 }
394mn2(a,d,c)
395 int a,d,c;
396 {
397 name[tptr] = a;
398 left[tptr] = d;
399 right[tptr] = c;
400 parent[tptr] = 0;
401 nullstr[tptr] = 0;
402 switch(a){
403 case RSTR:
404 parent[d] = tptr;
405 break;
406 case BAR:
407 case RNEWE:
408 if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE;
409 parent[d] = parent[c] = tptr;
410 break;
411 case RCAT:
412 case DIV:
413 if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE;
414 parent[d] = parent[c] = tptr;
415 break;
416 case RSCON:
417 parent[d] = tptr;
418 nullstr[tptr] = nullstr[d];
419 break;
420# ifdef DEBUG
421 default:
422 warning("bad switch mn2 %d %d",a,d);
423 break;
424# endif
425 }
426 if(tptr > treesize)
427 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
428 return(tptr++);
429 }
430mn1(a,d)
431 int a,d;
432 {
433 name[tptr] = a;
434 left[tptr] = d;
435 parent[tptr] = 0;
436 nullstr[tptr] = 0;
437 switch(a){
438 case RCCL:
439 case RNCCL:
440 if(slength(d) == 0) nullstr[tptr] = TRUE;
441 break;
442 case STAR:
443 case QUEST:
444 nullstr[tptr] = TRUE;
445 parent[d] = tptr;
446 break;
447 case PLUS:
448 case CARAT:
449 nullstr[tptr] = nullstr[d];
450 parent[d] = tptr;
451 break;
452 case S2FINAL:
453 nullstr[tptr] = TRUE;
454 break;
455# ifdef DEBUG
456 case FINAL:
457 case S1FINAL:
458 break;
459 default:
460 warning("bad switch mn1 %d %d",a,d);
461 break;
462# endif
463 }
464 if(tptr > treesize)
465 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
466 return(tptr++);
467 }
468mn0(a)
469 int a;
470 {
471 name[tptr] = a;
472 parent[tptr] = 0;
473 nullstr[tptr] = 0;
474 if(a >= NCH) switch(a){
475 case RNULLS: nullstr[tptr] = TRUE; break;
476# ifdef DEBUG
477 default:
478 warning("bad switch mn0 %d",a);
479 break;
480# endif
481 }
482 if(tptr > treesize)
483 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
484 return(tptr++);
485 }
486munput(t,p) /* implementation dependent */
487 char *p;
488 int t; {
489 register int i,j;
490 if(t == 'c'){
491 *pushptr++ = peek; /* watch out for this */
492 peek = p;
493 }
494 else if(t == 's'){
495 *pushptr++ = peek;
496 peek = p[0];
497 i = slength(p);
498 for(j = i-1; j>=1; j--)
499 *pushptr++ = p[j];
500 }
501# ifdef DEBUG
502 else error("Unrecognized munput option %c",t);
503# endif
504 if(pushptr >= pushc+TOKENSIZE)
505 error("Too many characters pushed");
506 return;
507 }
508
509dupl(n)
510 int n; {
511 /* duplicate the subtree whose root is n, return ptr to it */
512 register int i;
513 i = name[n];
514 if(i < NCH) return(mn0(i));
515 switch(i){
516 case RNULLS:
517 return(mn0(i));
518 case RCCL: case RNCCL: case FINAL: case S1FINAL: case S2FINAL:
519 return(mn1(i,left[n]));
520 case STAR: case QUEST: case PLUS: case CARAT:
521 return(mn1(i,dupl(left[n])));
522 case RSTR: case RSCON:
523 return(mn2(i,dupl(left[n]),right[n]));
524 case BAR: case RNEWE: case RCAT: case DIV:
525 return(mn2(i,dupl(left[n]),dupl(right[n])));
526# ifdef DEBUG
527 default:
528 warning("bad switch dupl %d",n);
529# endif
530 }
531 return(0);
532 }
533# ifdef DEBUG
534allprint(c)
535 char c; {
536 switch(c){
537 case 014:
538 printf("\\f");
539 charc++;
540 break;
541 case '\n':
542 printf("\\n");
543 charc++;
544 break;
545 case '\t':
546 printf("\\t");
547 charc++;
548 break;
549 case '\b':
550 printf("\\b");
551 charc++;
552 break;
553 case ' ':
554 printf("\\\bb");
555 break;
556 default:
557 if(!printable(c)){
558 printf("\\%-3o",c);
559 charc =+ 3;
560 }
561 else
562 putchar(c);
563 break;
564 }
565 charc++;
566 return;
567 }
568strpt(s)
569 char *s; {
570 charc = 0;
571 while(*s){
572 allprint(*s++);
573 if(charc > LINESIZE){
574 charc = 0;
575 printf("\n\t");
576 }
577 }
578 return;
579 }
580sect1dump(){
581 register int i;
582 printf("Sect 1:\n");
583 if(def[0]){
584 printf("str trans\n");
585 i = -1;
586 while(def[++i])
587 printf("%s\t%s\n",def[i],subs[i]);
588 }
589 if(sname[0]){
590 printf("start names\n");
591 i = -1;
592 while(sname[++i])
593 printf("%s\n",sname[i]);
594 }
595 if(chset == TRUE){
596 printf("char set changed\n");
597 for(i=1;i<NCH;i++){
598 if(i != ctable[i]){
599 allprint(i);
600 putchar(' ');
601 printable(ctable[i]) ? putchar(ctable[i]) : printf("%d",ctable[i]);
602 putchar('\n');
603 }
604 }
605 }
606 }
607sect2dump(){
608 printf("Sect 2:\n");
609 treedump();
610 }
611treedump()
612 {
613 register int t;
614 register char *p;
615 printf("treedump %d nodes:\n",tptr);
616 for(t=0;t<tptr;t++){
617 printf("%4d ",t);
618 parent[t] ? printf("p=%4d",parent[t]) : printf(" ");
619 printf(" ");
620 if(name[t] < NCH) {
621 allprint(name[t]);
622 }
623 else switch(name[t]){
624 case RSTR:
625 printf("%d ",left[t]);
626 allprint(right[t]);
627 break;
628 case RCCL:
629 printf("ccl ");
630 strpt(left[t]);
631 break;
632 case RNCCL:
633 printf("nccl ");
634 strpt(left[t]);
635 break;
636 case DIV:
637 printf("/ %d %d",left[t],right[t]);
638 break;
639 case BAR:
640 printf("| %d %d",left[t],right[t]);
641 break;
642 case RCAT:
643 printf("cat %d %d",left[t],right[t]);
644 break;
645 case PLUS:
646 printf("+ %d",left[t]);
647 break;
648 case STAR:
649 printf("* %d",left[t]);
650 break;
651 case CARAT:
652 printf("^ %d",left[t]);
653 break;
654 case QUEST:
655 printf("? %d",left[t]);
656 break;
657 case RNULLS:
658 printf("nullstring");
659 break;
660 case FINAL:
661 printf("final %d",left[t]);
662 break;
663 case S1FINAL:
664 printf("s1final %d",left[t]);
665 break;
666 case S2FINAL:
667 printf("s2final %d",left[t]);
668 break;
669 case RNEWE:
670 printf("new %d %d",left[t],right[t]);
671 break;
672 case RSCON:
673 p = right[t];
674 printf("start %s",sname[*p++-1]);
675 while(*p)
676 printf(", %s",sname[*p++-1]);
677 printf(" %d",left[t]);
678 break;
679 default:
680 printf("unknown %d %d %d",name[t],left[t],right[t]);
681 break;
682 }
683 if(nullstr[t])printf("\t(null poss.)");
684 putchar('\n');
685 }
686 }
687# endif