Blob


1 # include "ldefs.h"
2 uchar *
3 getl(uchar *p) /* return next line of input, throw away trailing '\n' */
4 /* returns 0 if eof is had immediately */
5 {
6 int c;
7 uchar *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((uchar *)0);
14 prev = '\n';
15 pres = '\n';
16 return(s);
17 }
19 void
20 printerr(char *type, char *fmt, va_list argl)
21 {
22 char buf[1024];
24 if(!eof)fprint(errorf,"%d: ",yyline);
25 fprint(errorf,"(%s) ", type);
26 vseprint(buf, buf+sizeof(buf), fmt, argl);
27 fprint(errorf, "%s\n", buf);
28 }
31 void
32 error(char *s,...)
33 {
34 va_list argl;
36 va_start(argl, s);
37 printerr("Error", s, argl);
38 va_end(argl);
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 exits("error"); /* error return code */
51 }
53 void
54 warning(char *s,...)
55 {
56 va_list argl;
58 va_start(argl, s);
59 printerr("Warning", s, argl);
60 va_end(argl);
61 Bflush(&fout);
62 }
64 void
65 lgate(void)
66 {
67 int fd;
69 if (lgatflg) return;
70 lgatflg=1;
71 if(foutopen == 0){
72 fd = create("lex.yy.c", OWRITE, 0666);
73 if(fd < 0)
74 error("Can't open lex.yy.c");
75 Binit(&fout, fd, OWRITE);
76 foutopen = 1;
77 }
78 phead1();
79 }
81 void
82 cclinter(int sw)
83 {
84 /* sw = 1 ==> ccl */
85 int i, j, k;
86 int m;
87 if(!sw){ /* is NCCL */
88 for(i=1;i<NCH;i++)
89 symbol[i] ^= 1; /* reverse value */
90 }
91 for(i=1;i<NCH;i++)
92 if(symbol[i]) break;
93 if(i >= NCH) return;
94 i = cindex[i];
95 /* see if ccl is already in our table */
96 j = 0;
97 if(i){
98 for(j=1;j<NCH;j++){
99 if((symbol[j] && cindex[j] != i) ||
100 (!symbol[j] && cindex[j] == i)) break;
103 if(j >= NCH) return; /* already in */
104 m = 0;
105 k = 0;
106 for(i=1;i<NCH;i++)
107 if(symbol[i]){
108 if(!cindex[i]){
109 cindex[i] = ccount;
110 symbol[i] = 0;
111 m = 1;
112 } else k = 1;
114 /* m == 1 implies last value of ccount has been used */
115 if(m)ccount++;
116 if(k == 0) return; /* is now in as ccount wholly */
117 /* intersection must be computed */
118 for(i=1;i<NCH;i++){
119 if(symbol[i]){
120 m = 0;
121 j = cindex[i]; /* will be non-zero */
122 for(k=1;k<NCH;k++){
123 if(cindex[k] == j){
124 if(symbol[k]) symbol[k] = 0;
125 else {
126 cindex[k] = ccount;
127 m = 1;
131 if(m)ccount++;
136 int
137 usescape(int c)
139 int d;
140 switch(c){
141 case 'n': c = '\n'; break;
142 case 'r': c = '\r'; break;
143 case 't': c = '\t'; break;
144 case 'b': c = '\b'; break;
145 case 'f': c = 014; break; /* form feed for ascii */
146 case '0': case '1': case '2': case '3':
147 case '4': case '5': case '6': case '7':
148 c -= '0';
149 while('0' <= (d=gch()) && d <= '7'){
150 c = c * 8 + (d-'0');
151 if(!('0' <= peek && peek <= '7')) break;
153 break;
155 return(c);
158 int
159 lookup(uchar *s, uchar **t)
161 int i;
162 i = 0;
163 while(*t){
164 if(strcmp((char *)s, *(char **)t) == 0)
165 return(i);
166 i++;
167 t++;
169 return(-1);
172 int
173 cpyact(void)
174 { /* copy C action to the next ; or closing } */
175 int brac, c, mth;
176 int savline, sw;
178 brac = 0;
179 sw = TRUE;
180 savline = 0;
182 while(!eof){
183 c = gch();
184 swt:
185 switch( c ){
187 case '|': if(brac == 0 && sw == TRUE){
188 if(peek == '|')gch(); /* eat up an extra '|' */
189 return(0);
191 break;
193 case ';':
194 if( brac == 0 ){
195 Bputc(&fout, c);
196 Bputc(&fout, '\n');
197 return(1);
199 break;
201 case '{':
202 brac++;
203 savline=yyline;
204 break;
206 case '}':
207 brac--;
208 if( brac == 0 ){
209 Bputc(&fout, c);
210 Bputc(&fout, '\n');
211 return(1);
213 break;
215 case '/': /* look for comments */
216 Bputc(&fout, c);
217 c = gch();
218 if( c != '*' ) goto swt;
220 /* it really is a comment */
222 Bputc(&fout, c);
223 savline=yyline;
224 while( c=gch() ){
225 if( c=='*' ){
226 Bputc(&fout, c);
227 if( (c=gch()) == '/' ) goto loop;
229 Bputc(&fout, c);
231 yyline=savline;
232 error( "EOF inside comment" );
234 case '\'': /* character constant */
235 mth = '\'';
236 goto string;
238 case '"': /* character string */
239 mth = '"';
241 string:
243 Bputc(&fout, c);
244 while( c=gch() ){
245 if( c=='\\' ){
246 Bputc(&fout, c);
247 c=gch();
249 else if( c==mth ) goto loop;
250 Bputc(&fout, c);
251 if (c == '\n') {
252 yyline--;
253 error( "Non-terminated string or character constant");
256 error( "EOF in string or character constant" );
258 case '\0':
259 yyline = savline;
260 error("Action does not terminate");
261 default:
262 break; /* usual character */
264 loop:
265 if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;
266 Bputc(&fout, c);
268 error("Premature EOF");
269 return(0);
272 int
273 gch(void){
274 int c;
275 prev = pres;
276 c = pres = peek;
277 peek = pushptr > pushc ? *--pushptr : Bgetc(fin);
278 if(peek == Beof && sargc > 1){
279 Bterm(fin);
280 fin = Bopen(sargv[fptr++],OREAD);
281 if(fin == 0)
282 error("Cannot open file %s",sargv[fptr-1]);
283 peek = Bgetc(fin);
284 sargc--;
285 sargv++;
287 if(c == Beof) {
288 eof = TRUE;
289 Bterm(fin);
290 fin = 0;
291 return(0);
293 if(c == '\n')yyline++;
294 return(c);
297 int
298 mn2(int a, int d, int c)
300 name[tptr] = a;
301 left[tptr] = d;
302 right[tptr] = c;
303 parent[tptr] = 0;
304 nullstr[tptr] = 0;
305 switch(a){
306 case RSTR:
307 parent[d] = tptr;
308 break;
309 case BAR:
310 case RNEWE:
311 if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE;
312 parent[d] = parent[c] = tptr;
313 break;
314 case RCAT:
315 case DIV:
316 if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE;
317 parent[d] = parent[c] = tptr;
318 break;
319 case RSCON:
320 parent[d] = tptr;
321 nullstr[tptr] = nullstr[d];
322 break;
323 # ifdef DEBUG
324 default:
325 warning("bad switch mn2 %d %d",a,d);
326 break;
327 # endif
329 if(tptr > treesize)
330 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
331 return(tptr++);
334 int
335 mnp(int a, void *p)
337 name[tptr] = a;
338 left[tptr] = 0;
339 parent[tptr] = 0;
340 nullstr[tptr] = 0;
341 ptr[tptr] = p;
342 switch(a){
343 case RCCL:
344 case RNCCL:
345 if(strlen(p) == 0) nullstr[tptr] = TRUE;
346 break;
347 default:
348 error("bad switch mnp %d %P", a, p);
349 break;
351 if(tptr > treesize)
352 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
353 return(tptr++);
356 int
357 mn1(int a, int d)
359 name[tptr] = a;
360 left[tptr] = d;
361 parent[tptr] = 0;
362 nullstr[tptr] = 0;
363 switch(a){
364 case STAR:
365 case QUEST:
366 nullstr[tptr] = TRUE;
367 parent[d] = tptr;
368 break;
369 case PLUS:
370 case CARAT:
371 nullstr[tptr] = nullstr[d];
372 parent[d] = tptr;
373 break;
374 case S2FINAL:
375 nullstr[tptr] = TRUE;
376 break;
377 # ifdef DEBUG
378 case FINAL:
379 case S1FINAL:
380 break;
381 default:
382 warning("bad switch mn1 %d %d",a,d);
383 break;
384 # endif
386 if(tptr > treesize)
387 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
388 return(tptr++);
391 int
392 mn0(int a)
394 name[tptr] = a;
395 parent[tptr] = 0;
396 nullstr[tptr] = 0;
397 if(a >= NCH) switch(a){
398 case RNULLS: nullstr[tptr] = TRUE; break;
399 # ifdef DEBUG
400 default:
401 warning("bad switch mn0 %d",a);
402 break;
403 # endif
405 if(tptr > treesize)
406 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
407 return(tptr++);
410 void
411 munputc(int p)
413 *pushptr++ = peek; /* watch out for this */
414 peek = p;
415 if(pushptr >= pushc+TOKENSIZE)
416 error("Too many characters pushed");
419 void
420 munputs(uchar *p)
422 int i,j;
423 *pushptr++ = peek;
424 peek = p[0];
425 i = strlen((char*)p);
426 for(j = i-1; j>=1; j--)
427 *pushptr++ = p[j];
428 if(pushptr >= pushc+TOKENSIZE)
429 error("Too many characters pushed");
432 int
433 dupl(int n)
435 /* duplicate the subtree whose root is n, return ptr to it */
436 int i;
438 i = name[n];
439 if(i < NCH) return(mn0(i));
440 switch(i){
441 case RNULLS:
442 return(mn0(i));
443 case RCCL: case RNCCL:
444 return(mnp(i,ptr[n]));
445 case FINAL: case S1FINAL: case S2FINAL:
446 return(mn1(i,left[n]));
447 case STAR: case QUEST: case PLUS: case CARAT:
448 return(mn1(i,dupl(left[n])));
449 case RSTR: case RSCON:
450 return(mn2(i,dupl(left[n]),right[n]));
451 case BAR: case RNEWE: case RCAT: case DIV:
452 return(mn2(i,dupl(left[n]),dupl(right[n])));
453 # ifdef DEBUG
454 default:
455 warning("bad switch dupl %d",n);
456 # endif
458 return(0);
461 # ifdef DEBUG
462 void
463 allprint(int c)
465 if(c < 0)
466 c += 256; /* signed char */
467 switch(c){
468 case 014:
469 print("\\f");
470 charc++;
471 break;
472 case '\n':
473 print("\\n");
474 charc++;
475 break;
476 case '\t':
477 print("\\t");
478 charc++;
479 break;
480 case '\b':
481 print("\\b");
482 charc++;
483 break;
484 case ' ':
485 print("\\\bb");
486 break;
487 default:
488 if(!isprint(c)){
489 print("\\%-3o",c);
490 charc += 3;
491 } else
492 print("%c", c);
493 break;
495 charc++;
498 void
499 strpt(uchar *s)
501 charc = 0;
502 while(*s){
503 allprint(*s++);
504 if(charc > LINESIZE){
505 charc = 0;
506 print("\n\t");
511 void
512 sect1dump(void)
514 int i;
516 print("Sect 1:\n");
517 if(def[0]){
518 print("str trans\n");
519 i = -1;
520 while(def[++i])
521 print("%s\t%s\n",def[i],subs[i]);
523 if(sname[0]){
524 print("start names\n");
525 i = -1;
526 while(sname[++i])
527 print("%s\n",sname[i]);
531 void
532 sect2dump(void)
534 print("Sect 2:\n");
535 treedump();
538 void
539 treedump(void)
541 int t;
542 uchar *p;
543 print("treedump %d nodes:\n",tptr);
544 for(t=0;t<tptr;t++){
545 print("%4d ",t);
546 parent[t] ? print("p=%4d",parent[t]) : print(" ");
547 print(" ");
548 if(name[t] < NCH)
549 allprint(name[t]);
550 else switch(name[t]){
551 case RSTR:
552 print("%d ",left[t]);
553 allprint(right[t]);
554 break;
555 case RCCL:
556 print("ccl ");
557 allprint(ptr[t]);
558 break;
559 case RNCCL:
560 print("nccl ");
561 allprint(ptr[t]);
562 break;
563 case DIV:
564 print("/ %d %d",left[t],right[t]);
565 break;
566 case BAR:
567 print("| %d %d",left[t],right[t]);
568 break;
569 case RCAT:
570 print("cat %d %d",left[t],right[t]);
571 break;
572 case PLUS:
573 print("+ %d",left[t]);
574 break;
575 case STAR:
576 print("* %d",left[t]);
577 break;
578 case CARAT:
579 print("^ %d",left[t]);
580 break;
581 case QUEST:
582 print("? %d",left[t]);
583 break;
584 case RNULLS:
585 print("nullstring");
586 break;
587 case FINAL:
588 print("final %d",left[t]);
589 break;
590 case S1FINAL:
591 print("s1final %d",left[t]);
592 break;
593 case S2FINAL:
594 print("s2final %d",left[t]);
595 break;
596 case RNEWE:
597 print("new %d %d",left[t],right[t]);
598 break;
599 case RSCON:
600 p = (uchar *)right[t];
601 print("start %s",sname[*p++-1]);
602 while(*p)
603 print(", %s",sname[*p++-1]);
604 print(" %d",left[t]);
605 break;
606 default:
607 print("unknown %d %d %d",name[t],left[t],right[t]);
608 break;
610 if(nullstr[t])print("\t(null poss.)");
611 print("\n");
614 # endif