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