|
|
1.1 root 1: # include "ldefs.c"
2: char *
3: getl(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((char *)0);
14: prev = '\n';
15: pres = '\n';
16: return(s);
17: }
18: space(ch)
19: {
20: switch(ch)
21: {
22: case ' ':
23: case '\t':
24: case '\n':
25: return(1);
26: }
27: return(0);
28: }
29:
30: digit(c)
31: {
32: return(c>='0' && c <= '9');
33: }
34: error(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:
54: warning(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: }
64: index(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:
74: alpha(c)
75: int c; {
76: # ifdef ASCII
77: return('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z');
78: # endif
79: # ifdef EBCDIC
80: return(index(c,"abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") >= 0);
81: # endif
82: }
83: printable(c)
84: {
85: # ifdef ASCII
86: return( c>040 && c < 0177);
87: # endif
88: # ifdef EBCDIC
89: return(index(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,;:><+*)('&%!-=\"")>=0);
90: # endif
91: }
92: lgate()
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 */
107: scopy(s,t)
108: char *s, *t; {
109: register char *i;
110: i = t;
111: while(*i++ = *s++);
112: return;
113: }
114: siconv(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 */
132: slength(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 */
143: scomp(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: }
158: ctrans(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: }
184: cclinter(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: }
239: usescape(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: }
259: lookup(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: }
272: cpyact(){ /* 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:
279: while(!eof){
280: c = gch();
281: swt:
282: switch( c ){
283:
284: case '|': if(brac == 0 && sw == TRUE){
285: if(peek == '|')gch(); /* eat up an extra '|' */
286: return(0);
287: }
288: break;
289:
290: case ';':
291: if( brac == 0 ){
292: putc(c,fout);
293: putc('\n',fout);
294: return(1);
295: }
296: break;
297:
298: case '{':
299: brac++;
300: savline=yyline;
301: break;
302:
303: case '}':
304: brac--;
305: if( brac == 0 ){
306: putc(c,fout);
307: putc('\n',fout);
308: return(1);
309: }
310: break;
311:
312: case '/': /* 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:
331: case '\'': /* character constant */
332: mth = '\'';
333: goto string;
334:
335: case '"': /* 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:
356: case '\0':
357: yyline = savline;
358: error("Action does not terminate");
359: default:
360: break; /* usual character */
361: }
362: loop:
363: if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;
364: putc(c,fout);
365: }
366: error("Premature EOF");
367: }
368: gch(){
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: }
390: mn2(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: }
426: mn1(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: }
464: mn0(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: }
482: munput(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 = (int)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:
505: dupl(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
530: allprint(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: }
564: strpt(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: }
576: sect1dump(){
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: }
603: sect2dump(){
604: printf("Sect 2:\n");
605: treedump();
606: }
607: treedump()
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 = (char *)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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.