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; 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 20 printerr(char *type, char *fmt, va_list argl) 21 { 22 char buf[1024]; 23 24 if(!eof)fprint(errorf,"%d: ",yyline); 25 fprint(errorf,"(%s) ", type); 26 doprint(buf, buf+sizeof(buf), fmt, argl); 27 fprint(errorf, "%s\n", buf); 28 } 29 30 31 void 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 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 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"); 75 Binit(&fout, fd, OWRITE); 76 foutopen = 1; 77 } 78 phead1(); 79 } 80 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; 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 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 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 173 cpyact(void) 174 { /* copy C action to the next ; or closing } */ 175 int brac, c, mth; 176 int savline, sw; 177 178 brac = 0; 179 sw = TRUE; 180 savline = 0; 181 182 while(!eof){ 183 c = gch(); 184 swt: 185 switch( c ){ 186 187 case '|': if(brac == 0 && sw == TRUE){ 188 if(peek == '|')gch(); /* eat up an extra '|' */ 189 return(0); 190 } 191 break; 192 193 case ';': 194 if( brac == 0 ){ 195 Bputc(&fout, c); 196 Bputc(&fout, '\n'); 197 return(1); 198 } 199 break; 200 201 case '{': 202 brac++; 203 savline=yyline; 204 break; 205 206 case '}': 207 brac--; 208 if( brac == 0 ){ 209 Bputc(&fout, c); 210 Bputc(&fout, '\n'); 211 return(1); 212 } 213 break; 214 215 case '/': /* look for comments */ 216 Bputc(&fout, c); 217 c = gch(); 218 if( c != '*' ) goto swt; 219 220 /* it really is a comment */ 221 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" ); 233 234 case '\'': /* character constant */ 235 mth = '\''; 236 goto string; 237 238 case '"': /* character string */ 239 mth = '"'; 240 241 string: 242 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" ); 257 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 } 271 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++; 286 } 287 if(c == Beof) { 288 eof = TRUE; 289 Bterm(fin); 290 return(0); 291 } 292 if(c == '\n')yyline++; 293 return(c); 294 } 295 296 int 297 mn2(int a, int d, int c) 298 { 299 name[tptr] = a; 300 left[tptr] = d; 301 right[tptr] = c; 302 parent[tptr] = 0; 303 nullstr[tptr] = 0; 304 switch(a){ 305 case RSTR: 306 parent[d] = tptr; 307 break; 308 case BAR: 309 case RNEWE: 310 if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE; 311 parent[d] = parent[c] = tptr; 312 break; 313 case RCAT: 314 case DIV: 315 if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE; 316 parent[d] = parent[c] = tptr; 317 break; 318 case RSCON: 319 parent[d] = tptr; 320 nullstr[tptr] = nullstr[d]; 321 break; 322 # ifdef DEBUG 323 default: 324 warning("bad switch mn2 %d %d",a,d); 325 break; 326 # endif 327 } 328 if(tptr > treesize) 329 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":"")); 330 return(tptr++); 331 } 332 333 int 334 mn1(int a, int d) 335 { 336 name[tptr] = a; 337 left[tptr] = d; 338 parent[tptr] = 0; 339 nullstr[tptr] = 0; 340 switch(a){ 341 case RCCL: 342 case RNCCL: 343 if(strlen((char *)d) == 0) nullstr[tptr] = TRUE; 344 break; 345 case STAR: 346 case QUEST: 347 nullstr[tptr] = TRUE; 348 parent[d] = tptr; 349 break; 350 case PLUS: 351 case CARAT: 352 nullstr[tptr] = nullstr[d]; 353 parent[d] = tptr; 354 break; 355 case S2FINAL: 356 nullstr[tptr] = TRUE; 357 break; 358 # ifdef DEBUG 359 case FINAL: 360 case S1FINAL: 361 break; 362 default: 363 warning("bad switch mn1 %d %d",a,d); 364 break; 365 # endif 366 } 367 if(tptr > treesize) 368 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":"")); 369 return(tptr++); 370 } 371 372 int 373 mn0(int a) 374 { 375 name[tptr] = a; 376 parent[tptr] = 0; 377 nullstr[tptr] = 0; 378 if(a >= NCH) switch(a){ 379 case RNULLS: nullstr[tptr] = TRUE; break; 380 # ifdef DEBUG 381 default: 382 warning("bad switch mn0 %d",a); 383 break; 384 # endif 385 } 386 if(tptr > treesize) 387 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":"")); 388 return(tptr++); 389 } 390 391 void 392 munputc(int p) 393 { 394 *pushptr++ = peek; /* watch out for this */ 395 peek = p; 396 if(pushptr >= pushc+TOKENSIZE) 397 error("Too many characters pushed"); 398 } 399 400 void 401 munputs(uchar *p) 402 { 403 int i,j; 404 *pushptr++ = peek; 405 peek = p[0]; 406 i = strlen((char*)p); 407 for(j = i-1; j>=1; j--) 408 *pushptr++ = p[j]; 409 if(pushptr >= pushc+TOKENSIZE) 410 error("Too many characters pushed"); 411 } 412 413 int 414 dupl(int n) 415 { 416 /* duplicate the subtree whose root is n, return ptr to it */ 417 int i; 418 419 i = name[n]; 420 if(i < NCH) return(mn0(i)); 421 switch(i){ 422 case RNULLS: 423 return(mn0(i)); 424 case RCCL: case RNCCL: case FINAL: case S1FINAL: case S2FINAL: 425 return(mn1(i,left[n])); 426 case STAR: case QUEST: case PLUS: case CARAT: 427 return(mn1(i,dupl(left[n]))); 428 case RSTR: case RSCON: 429 return(mn2(i,dupl(left[n]),right[n])); 430 case BAR: case RNEWE: case RCAT: case DIV: 431 return(mn2(i,dupl(left[n]),dupl(right[n]))); 432 # ifdef DEBUG 433 default: 434 warning("bad switch dupl %d",n); 435 # endif 436 } 437 return(0); 438 } 439 440 # ifdef DEBUG 441 void 442 allprint(int c) 443 { 444 switch(c){ 445 case 014: 446 print("\\f"); 447 charc++; 448 break; 449 case '\n': 450 print("\\n"); 451 charc++; 452 break; 453 case '\t': 454 print("\\t"); 455 charc++; 456 break; 457 case '\b': 458 print("\\b"); 459 charc++; 460 break; 461 case ' ': 462 print("\\\bb"); 463 break; 464 default: 465 if(!isprint(c)){ 466 print("\\%-3o",c); 467 charc += 3; 468 } else 469 print("%c", c); 470 break; 471 } 472 charc++; 473 } 474 475 void 476 strpt(uchar *s) 477 { 478 charc = 0; 479 while(*s){ 480 allprint(*s++); 481 if(charc > LINESIZE){ 482 charc = 0; 483 print("\n\t"); 484 } 485 } 486 } 487 488 void 489 sect1dump(void) 490 { 491 int i; 492 493 print("Sect 1:\n"); 494 if(def[0]){ 495 print("str trans\n"); 496 i = -1; 497 while(def[++i]) 498 print("%s\t%s\n",def[i],subs[i]); 499 } 500 if(sname[0]){ 501 print("start names\n"); 502 i = -1; 503 while(sname[++i]) 504 print("%s\n",sname[i]); 505 } 506 } 507 508 void 509 sect2dump(void) 510 { 511 print("Sect 2:\n"); 512 treedump(); 513 } 514 515 void 516 treedump(void) 517 { 518 int t; 519 uchar *p; 520 print("treedump %d nodes:\n",tptr); 521 for(t=0;t<tptr;t++){ 522 print("%4d ",t); 523 parent[t] ? print("p=%4d",parent[t]) : print(" "); 524 print(" "); 525 if(name[t] < NCH) 526 allprint(name[t]); 527 else switch(name[t]){ 528 case RSTR: 529 print("%d ",left[t]); 530 allprint(right[t]); 531 break; 532 case RCCL: 533 print("ccl "); 534 strpt(left[t]); 535 break; 536 case RNCCL: 537 print("nccl "); 538 strpt(left[t]); 539 break; 540 case DIV: 541 print("/ %d %d",left[t],right[t]); 542 break; 543 case BAR: 544 print("| %d %d",left[t],right[t]); 545 break; 546 case RCAT: 547 print("cat %d %d",left[t],right[t]); 548 break; 549 case PLUS: 550 print("+ %d",left[t]); 551 break; 552 case STAR: 553 print("* %d",left[t]); 554 break; 555 case CARAT: 556 print("^ %d",left[t]); 557 break; 558 case QUEST: 559 print("? %d",left[t]); 560 break; 561 case RNULLS: 562 print("nullstring"); 563 break; 564 case FINAL: 565 print("final %d",left[t]); 566 break; 567 case S1FINAL: 568 print("s1final %d",left[t]); 569 break; 570 case S2FINAL: 571 print("s2final %d",left[t]); 572 break; 573 case RNEWE: 574 print("new %d %d",left[t],right[t]); 575 break; 576 case RSCON: 577 p = (uchar *)right[t]; 578 print("start %s",sname[*p++-1]); 579 while(*p) 580 print(", %s",sname[*p++-1]); 581 print(" %d",left[t]); 582 break; 583 default: 584 print("unknown %d %d %d",name[t],left[t],right[t]); 585 break; 586 } 587 if(nullstr[t])print("\t(null poss.)"); 588 print("\n"); 589 } 590 } 591 # endif 592