sub1.c (10164B)
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 vseprint(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 fin = 0; 291 return(0); 292 } 293 if(c == '\n')yyline++; 294 return(c); 295 } 296 297 int 298 mn2(int a, int d, uintptr 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 DEBUG 324 default: 325 warning("bad switch mn2 %d %d",a,d); 326 break; 327 # endif 328 } 329 if(tptr > treesize) 330 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":"")); 331 return(tptr++); 332 } 333 334 int 335 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 } 355 356 int 357 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 DEBUG 378 case FINAL: 379 case S1FINAL: 380 break; 381 default: 382 warning("bad switch mn1 %d %d",a,d); 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 int 392 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 DEBUG 400 default: 401 warning("bad switch mn0 %d",a); 402 break; 403 # endif 404 } 405 if(tptr > treesize) 406 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":"")); 407 return(tptr++); 408 } 409 410 void 411 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 } 418 419 void 420 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 } 431 432 int 433 dupl(int n) 434 { 435 /* duplicate the subtree whose root is n, return ptr to it */ 436 int i; 437 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 457 } 458 return(0); 459 } 460 461 # ifdef DEBUG 462 void 463 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 } else 492 print("%c", c); 493 break; 494 } 495 charc++; 496 } 497 498 void 499 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 } 510 511 void 512 sect1dump(void) 513 { 514 int i; 515 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 } 530 531 void 532 sect2dump(void) 533 { 534 print("Sect 2:\n"); 535 treedump(); 536 } 537 538 void 539 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