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