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 void20 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 void32 error(char *s,...)33 {34 va_list argl;36 va_start(argl, s);37 printerr("Error", s, argl);38 va_end(argl);39 # ifdef DEBUG40 if(debug && sect != ENDSECTION) {41 sect1dump();42 sect2dump();43 }44 # endif45 if(46 # ifdef DEBUG47 debug ||48 # endif49 report == 1) statistics();50 exits("error"); /* error return code */51 }53 void54 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 void65 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 void82 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 }136 int137 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 }158 int159 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 }172 int173 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);190 }191 break;193 case ';':194 if( brac == 0 ){195 Bputc(&fout, c);196 Bputc(&fout, '\n');197 return(1);198 }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);212 }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;228 }229 Bputc(&fout, c);230 }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();248 }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");254 }255 }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 */263 }264 loop:265 if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;266 Bputc(&fout, c);267 }268 error("Premature EOF");269 return(0);270 }272 int273 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++;286 }287 if(c == Beof) {288 eof = TRUE;289 Bterm(fin);290 fin = 0;291 return(0);292 }293 if(c == '\n')yyline++;294 return(c);295 }297 int298 mn2(int a, int d, int c)299 {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 DEBUG324 default:325 warning("bad switch mn2 %d %d",a,d);326 break;327 # endif328 }329 if(tptr > treesize)330 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));331 return(tptr++);332 }334 int335 mnp(int a, void *p)336 {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;350 }351 if(tptr > treesize)352 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));353 return(tptr++);354 }356 int357 mn1(int a, int d)358 {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 DEBUG378 case FINAL:379 case S1FINAL:380 break;381 default:382 warning("bad switch mn1 %d %d",a,d);383 break;384 # endif385 }386 if(tptr > treesize)387 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));388 return(tptr++);389 }391 int392 mn0(int a)393 {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 DEBUG400 default:401 warning("bad switch mn0 %d",a);402 break;403 # endif404 }405 if(tptr > treesize)406 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));407 return(tptr++);408 }410 void411 munputc(int p)412 {413 *pushptr++ = peek; /* watch out for this */414 peek = p;415 if(pushptr >= pushc+TOKENSIZE)416 error("Too many characters pushed");417 }419 void420 munputs(uchar *p)421 {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");430 }432 int433 dupl(int n)434 {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 DEBUG454 default:455 warning("bad switch dupl %d",n);456 # endif457 }458 return(0);459 }461 # ifdef DEBUG462 void463 allprint(int c)464 {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 } else492 print("%c", c);493 break;494 }495 charc++;496 }498 void499 strpt(uchar *s)500 {501 charc = 0;502 while(*s){503 allprint(*s++);504 if(charc > LINESIZE){505 charc = 0;506 print("\n\t");507 }508 }509 }511 void512 sect1dump(void)513 {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]);522 }523 if(sname[0]){524 print("start names\n");525 i = -1;526 while(sname[++i])527 print("%s\n",sname[i]);528 }529 }531 void532 sect2dump(void)533 {534 print("Sect 2:\n");535 treedump();536 }538 void539 treedump(void)540 {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;609 }610 if(nullstr[t])print("\t(null poss.)");611 print("\n");612 }613 }614 # endif