1 # include "ldefs.h"
2 uchar *
getl(uchar * p)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;
8
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 }
18
19 void
printerr(char * type,char * fmt,va_list argl)20 printerr(char *type, char *fmt, va_list argl)
21 {
22 char buf[1024];
23
24 if(!eof)fprint(errorf,"%s:%d ", yyfile, yyline);
25 fprint(errorf,"(%s) ", type);
26 vseprint(buf, buf+sizeof(buf), fmt, argl);
27 fprint(errorf, "%s\n", buf);
28 }
29
30
31 void
error(char * s,...)32 error(char *s,...)
33 {
34 va_list argl;
35
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 }
52
53 void
warning(char * s,...)54 warning(char *s,...)
55 {
56 va_list argl;
57
58 va_start(argl, s);
59 printerr("Warning", s, argl);
60 va_end(argl);
61 Bflush(&fout);
62 }
63
64 void
lgate(void)65 lgate(void)
66 {
67 int fd;
68
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: %r");
75 Binit(&fout, fd, OWRITE);
76 foutopen = 1;
77 }
78 phead1();
79 }
80
81 void
cclinter(int sw)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;
101 }
102 }
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;
113 }
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;
128 }
129 }
130 }
131 if(m)ccount++;
132 }
133 }
134 }
135
136 int
usescape(int c)137 usescape(int c)
138 {
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;
152 }
153 break;
154 }
155 return(c);
156 }
157
158 int
lookup(uchar * s,uchar ** t)159 lookup(uchar *s, uchar **t)
160 {
161 int i;
162 i = 0;
163 while(*t){
164 if(strcmp((char *)s, *(char **)t) == 0)
165 return(i);
166 i++;
167 t++;
168 }
169 return(-1);
170 }
171
172 int
cpyact(void)173 cpyact(void)
174 { /* copy C action to the next ; or closing } */
175 int brac, c, mth;
176 int savline, sw;
177 char *savfile;
178
179 brac = 0;
180 sw = TRUE;
181 savline = 0;
182 savfile = "?";
183
184 while(!eof){
185 c = gch();
186 swt:
187 switch( c ){
188
189 case '|': if(brac == 0 && sw == TRUE){
190 if(peek == '|')gch(); /* eat up an extra '|' */
191 return(0);
192 }
193 break;
194
195 case ';':
196 if( brac == 0 ){
197 Bputc(&fout, c);
198 Bputc(&fout, '\n');
199 return(1);
200 }
201 break;
202
203 case '{':
204 brac++;
205 savline=yyline;
206 savfile=yyfile;
207 break;
208
209 case '}':
210 brac--;
211 if( brac == 0 ){
212 Bputc(&fout, c);
213 Bputc(&fout, '\n');
214 return(1);
215 }
216 break;
217
218 case '/': /* look for comments */
219 Bputc(&fout, c);
220 c = gch();
221 if( c != '*' ) goto swt;
222
223 /* it really is a comment */
224
225 Bputc(&fout, c);
226 savline=yyline;
227 savfile=yyfile;
228 while( c=gch() ){
229 if( c=='*' ){
230 Bputc(&fout, c);
231 if( (c=gch()) == '/' ) goto loop;
232 }
233 Bputc(&fout, c);
234 }
235 yyline=savline;
236 yyfile=savfile;
237 error( "EOF inside comment" );
238
239 case '\'': /* character constant */
240 mth = '\'';
241 goto string;
242
243 case '"': /* character string */
244 mth = '"';
245
246 string:
247
248 Bputc(&fout, c);
249 while( c=gch() ){
250 if( c=='\\' ){
251 Bputc(&fout, c);
252 c=gch();
253 }
254 else if( c==mth ) goto loop;
255 Bputc(&fout, c);
256 if (c == '\n') {
257 yyline--;
258 error( "Non-terminated string or character constant");
259 }
260 }
261 error( "EOF in string or character constant" );
262
263 case '\0':
264 yyline = savline;
265 yyfile = savfile;
266 error("Action does not terminate");
267 default:
268 break; /* usual character */
269 }
270 loop:
271 if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;
272 Bputc(&fout, c);
273 }
274 error("Premature EOF");
275 return(0);
276 }
277
278 int
gch(void)279 gch(void){
280 int c;
281 prev = pres;
282 c = pres = peek;
283 peek = pushptr > pushc ? *--pushptr : Bgetc(fin);
284 if(peek == Beof && sargc > 1){
285 Bterm(fin);
286 yyfile = sargv[fptr++];
287 fin = Bopen(yyfile,OREAD);
288 if(fin == 0)
289 error("%s - cannot open file: %r",yyfile);
290 peek = Bgetc(fin);
291 sargc--;
292 sargv++;
293 }
294 if(c == Beof) {
295 eof = TRUE;
296 Bterm(fin);
297 fin = 0;
298 return(0);
299 }
300 if(c == '\n')yyline++;
301 return(c);
302 }
303
304 int
mn2(int a,int d,uintptr c)305 mn2(int a, int d, uintptr c)
306 {
307 name[tptr] = a;
308 left[tptr] = d;
309 right[tptr] = c;
310 parent[tptr] = 0;
311 nullstr[tptr] = 0;
312 switch(a){
313 case RSTR:
314 parent[d] = tptr;
315 break;
316 case BAR:
317 case RNEWE:
318 if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE;
319 parent[d] = parent[c] = tptr;
320 break;
321 case RCAT:
322 case DIV:
323 if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE;
324 parent[d] = parent[c] = tptr;
325 break;
326 case RSCON:
327 parent[d] = tptr;
328 nullstr[tptr] = nullstr[d];
329 break;
330 # ifdef DEBUG
331 default:
332 warning("bad switch mn2 %d %d",a,d);
333 break;
334 # endif
335 }
336 if(tptr > treesize)
337 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
338 return(tptr++);
339 }
340
341 int
mnp(int a,void * p)342 mnp(int a, void *p)
343 {
344 name[tptr] = a;
345 left[tptr] = 0;
346 parent[tptr] = 0;
347 nullstr[tptr] = 0;
348 ptr[tptr] = p;
349 switch(a){
350 case RCCL:
351 case RNCCL:
352 if(strlen(p) == 0) nullstr[tptr] = TRUE;
353 break;
354 default:
355 error("bad switch mnp %d %P", a, p);
356 break;
357 }
358 if(tptr > treesize)
359 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
360 return(tptr++);
361 }
362
363 int
mn1(int a,int d)364 mn1(int a, int d)
365 {
366 name[tptr] = a;
367 left[tptr] = d;
368 parent[tptr] = 0;
369 nullstr[tptr] = 0;
370 switch(a){
371 case STAR:
372 case QUEST:
373 nullstr[tptr] = TRUE;
374 parent[d] = tptr;
375 break;
376 case PLUS:
377 case CARAT:
378 nullstr[tptr] = nullstr[d];
379 parent[d] = tptr;
380 break;
381 case S2FINAL:
382 nullstr[tptr] = TRUE;
383 break;
384 # ifdef DEBUG
385 case FINAL:
386 case S1FINAL:
387 break;
388 default:
389 warning("bad switch mn1 %d %d",a,d);
390 break;
391 # endif
392 }
393 if(tptr > treesize)
394 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
395 return(tptr++);
396 }
397
398 int
mn0(int a)399 mn0(int a)
400 {
401 name[tptr] = a;
402 parent[tptr] = 0;
403 nullstr[tptr] = 0;
404 if(a >= NCH) switch(a){
405 case RNULLS: nullstr[tptr] = TRUE; break;
406 # ifdef DEBUG
407 default:
408 warning("bad switch mn0 %d",a);
409 break;
410 # endif
411 }
412 if(tptr > treesize)
413 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
414 return(tptr++);
415 }
416
417 void
munputc(int p)418 munputc(int p)
419 {
420 *pushptr++ = peek; /* watch out for this */
421 peek = p;
422 if(pushptr >= pushc+TOKENSIZE)
423 error("Too many characters pushed");
424 }
425
426 void
munputs(uchar * p)427 munputs(uchar *p)
428 {
429 int i,j;
430 *pushptr++ = peek;
431 peek = p[0];
432 i = strlen((char*)p);
433 for(j = i-1; j>=1; j--)
434 *pushptr++ = p[j];
435 if(pushptr >= pushc+TOKENSIZE)
436 error("Too many characters pushed");
437 }
438
439 int
dupl(int n)440 dupl(int n)
441 {
442 /* duplicate the subtree whose root is n, return ptr to it */
443 int i;
444
445 i = name[n];
446 if(i < NCH) return(mn0(i));
447 switch(i){
448 case RNULLS:
449 return(mn0(i));
450 case RCCL: case RNCCL:
451 return(mnp(i,ptr[n]));
452 case FINAL: case S1FINAL: case S2FINAL:
453 return(mn1(i,left[n]));
454 case STAR: case QUEST: case PLUS: case CARAT:
455 return(mn1(i,dupl(left[n])));
456 case RSTR: case RSCON:
457 return(mn2(i,dupl(left[n]),right[n]));
458 case BAR: case RNEWE: case RCAT: case DIV:
459 return(mn2(i,dupl(left[n]),dupl(right[n])));
460 # ifdef DEBUG
461 default:
462 warning("bad switch dupl %d",n);
463 # endif
464 }
465 return(0);
466 }
467
468 # ifdef DEBUG
469 void
allprint(int c)470 allprint(int c)
471 {
472 if(c < 0)
473 c += 256; /* signed char */
474 switch(c){
475 case 014:
476 print("\\f");
477 charc++;
478 break;
479 case '\n':
480 print("\\n");
481 charc++;
482 break;
483 case '\t':
484 print("\\t");
485 charc++;
486 break;
487 case '\b':
488 print("\\b");
489 charc++;
490 break;
491 case ' ':
492 print("\\\bb");
493 break;
494 default:
495 if(!isprint(c)){
496 print("\\%-3o",c);
497 charc += 3;
498 } else
499 print("%c", c);
500 break;
501 }
502 charc++;
503 }
504
505 void
strpt(uchar * s)506 strpt(uchar *s)
507 {
508 charc = 0;
509 while(*s){
510 allprint(*s++);
511 if(charc > LINESIZE){
512 charc = 0;
513 print("\n\t");
514 }
515 }
516 }
517
518 void
sect1dump(void)519 sect1dump(void)
520 {
521 int i;
522
523 print("Sect 1:\n");
524 if(def[0]){
525 print("str trans\n");
526 i = -1;
527 while(def[++i])
528 print("%s\t%s\n",def[i],subs[i]);
529 }
530 if(sname[0]){
531 print("start names\n");
532 i = -1;
533 while(sname[++i])
534 print("%s\n",sname[i]);
535 }
536 }
537
538 void
sect2dump(void)539 sect2dump(void)
540 {
541 print("Sect 2:\n");
542 treedump();
543 }
544
545 void
treedump(void)546 treedump(void)
547 {
548 int t;
549 uchar *p;
550 print("treedump %d nodes:\n",tptr);
551 for(t=0;t<tptr;t++){
552 print("%4d ",t);
553 parent[t] ? print("p=%4d",parent[t]) : print(" ");
554 print(" ");
555 if(name[t] < NCH)
556 allprint(name[t]);
557 else switch(name[t]){
558 case RSTR:
559 print("%d ",left[t]);
560 allprint(right[t]);
561 break;
562 case RCCL:
563 print("ccl ");
564 allprint(ptr[t]);
565 break;
566 case RNCCL:
567 print("nccl ");
568 allprint(ptr[t]);
569 break;
570 case DIV:
571 print("/ %d %d",left[t],right[t]);
572 break;
573 case BAR:
574 print("| %d %d",left[t],right[t]);
575 break;
576 case RCAT:
577 print("cat %d %d",left[t],right[t]);
578 break;
579 case PLUS:
580 print("+ %d",left[t]);
581 break;
582 case STAR:
583 print("* %d",left[t]);
584 break;
585 case CARAT:
586 print("^ %d",left[t]);
587 break;
588 case QUEST:
589 print("? %d",left[t]);
590 break;
591 case RNULLS:
592 print("nullstring");
593 break;
594 case FINAL:
595 print("final %d",left[t]);
596 break;
597 case S1FINAL:
598 print("s1final %d",left[t]);
599 break;
600 case S2FINAL:
601 print("s2final %d",left[t]);
602 break;
603 case RNEWE:
604 print("new %d %d",left[t],right[t]);
605 break;
606 case RSCON:
607 p = (uchar *)right[t];
608 print("start %s",sname[*p++-1]);
609 while(*p)
610 print(", %s",sname[*p++-1]);
611 print(" %d",left[t]);
612 break;
613 default:
614 print("unknown %d %d %d",name[t],left[t],right[t]);
615 break;
616 }
617 if(nullstr[t])print("\t(null poss.)");
618 print("\n");
619 }
620 }
621 # endif
622