1 #ifndef lint 2 static char sccsid[] = "@(#)sub1.c 4.6 (Berkeley) 02/16/92"; 3 #endif 4 5 # include "ldefs.c" 6 # if __STDC__ 7 # include <stdarg.h> 8 # else 9 # include <varargs.h> 10 #endif 11 12 char * 13 getl(p) /* return next line of input, throw away trailing '\n' */ 14 /* returns 0 if eof is had immediately */ 15 char *p; 16 { 17 register int c; 18 register char *s, *t; 19 t = s = p; 20 while(((c = gch()) != 0) && c != '\n') 21 *t++ = c; 22 *t = 0; 23 if(c == 0 && s == t) return(0); 24 prev = '\n'; 25 pres = '\n'; 26 return(s); 27 } 28 space(ch) 29 { 30 switch(ch) 31 { 32 case ' ': 33 case '\t': 34 case '\n': 35 return(1); 36 } 37 return(0); 38 } 39 40 digit(c) 41 { 42 return(c>='0' && c <= '9'); 43 } 44 45 #if __STDC__ 46 error(char *s, ...) 47 #else 48 error(s, va_alist) 49 char *s; 50 va_dcl 51 #endif 52 { 53 va_list ap; 54 55 fprintf(errorf,"\"%s\", line %d: (Error) ", 56 fptr > 0 ? sargv[fptr] : "<stdin>", yyline); 57 #if __STDC__ 58 va_start(ap, s); 59 #else 60 va_start(ap); 61 #endif 62 vfprintf(errorf, s, ap); 63 va_end(ap); 64 putc('\n', errorf); 65 # ifdef DEBUG 66 if(debug && sect != ENDSECTION) { 67 sect1dump(); 68 sect2dump(); 69 } 70 # endif 71 if( 72 # ifdef DEBUG 73 debug || 74 # endif 75 report == 1) statistics(); 76 exit(1); /* error return code */ 77 } 78 79 #if __STDC__ 80 warning(char *s, ...) 81 #else 82 warning(s, va_alist) 83 char *s; 84 va_dcl 85 #endif 86 { 87 va_list ap; 88 89 fprintf(errorf,"\"%s\", line %d: (Warning) ", 90 fptr > 0 ? sargv[fptr] : "<stdin>", yyline); 91 #if __STDC__ 92 va_start(ap, s); 93 #else 94 va_start(ap); 95 #endif 96 vfprintf(errorf, s, ap); 97 va_end(ap); 98 putc('\n',errorf); 99 fflush(errorf); 100 fflush(fout); 101 fflush(stdout); 102 } 103 index(a,s) 104 char *s; 105 { 106 register int k; 107 for(k=0; s[k]; k++) 108 if (s[k]== a) 109 return(k); 110 return(-1); 111 } 112 113 alpha(c) 114 int c; { 115 # ifdef ASCII 116 return('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'); 117 # endif 118 # ifdef EBCDIC 119 return(index(c,"abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") >= 0); 120 # endif 121 } 122 printable(c) 123 { 124 # ifdef ASCII 125 return( c>040 && c < 0177); 126 # endif 127 # ifdef EBCDIC 128 return(index(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,;:><+*)('&%!-=\"")>=0); 129 # endif 130 } 131 lgate() 132 { 133 char fname[20]; 134 if (lgatflg) return; 135 lgatflg=1; 136 if(fout == NULL){ 137 sprintf(fname, "lex.yy.%c", ratfor ? 'r' : 'c' ); 138 fout = fopen(fname, "w"); 139 } 140 if(fout == NULL) error("Can't open %s",fname); 141 if(ratfor) fprintf( fout, "#\n"); 142 phead1(); 143 } 144 /* scopy(ptr to str, ptr to str) - copy first arg str to second */ 145 /* returns ptr to second arg */ 146 scopy(s,t) 147 char *s, *t; { 148 register char *i; 149 i = t; 150 while(*i++ = *s++); 151 return; 152 } 153 siconv(t) /* convert string t, return integer value */ 154 char *t; { 155 register int i,sw; 156 register char *s; 157 s = t; 158 while(!(('0' <= *s && *s <= '9') || *s == '-') && *s) s++; 159 sw = 0; 160 if(*s == '-'){ /* neg */ 161 sw = 1; 162 s++; 163 } 164 i = 0; 165 while('0' <= *s && *s <= '9') 166 i = i * 10 + (*(s++)-'0'); 167 return(sw ? -i : i); 168 } 169 /* slength(ptr to str) - return integer length of string arg */ 170 /* excludes '\0' terminator */ 171 slength(s) 172 char *s; { 173 register int n; 174 register char *t; 175 t = s; 176 for (n = 0; *t++; n++); 177 return(n); 178 } 179 /* scomp(x,y) - return -1 if x < y, 180 0 if x == y, 181 return 1 if x > y, all lexicographically */ 182 scomp(x,y) 183 char *x,*y; { 184 register char *a,*d; 185 a = x; 186 d = y; 187 while(*a || *d){ 188 if(*a > *d) 189 return(1); /* greater */ 190 if(*a < *d) 191 return(-1); /* less */ 192 a++; 193 d++; 194 } 195 return(0); /* equal */ 196 } 197 ctrans(ss) 198 char **ss; 199 { 200 register int c, k; 201 if ((c = **ss) != '\\') 202 return(c); 203 switch(c= *++*ss) 204 { 205 case 'n': c = '\n'; break; 206 case 't': c = '\t'; break; 207 case 'r': c = '\r'; break; 208 case 'b': c = '\b'; break; 209 case 'f': c = 014; break; /* form feed for ascii */ 210 case '\\': c = '\\'; break; 211 case '0': case '1': case '2': case '3': 212 case '4': case '5': case '6': case '7': 213 c -= '0'; 214 while ((k = *(*ss+1)) >= '0' && k <= '7') 215 { 216 c = c*8 + k - '0'; 217 (*ss)++; 218 } 219 break; 220 } 221 return(c); 222 } 223 cclinter(sw) 224 int sw; { 225 /* sw = 1 ==> ccl */ 226 register int i, j, k; 227 int m; 228 if(!sw){ /* is NCCL */ 229 for(i=1;i<NCH;i++) 230 symbol[i] ^= 1; /* reverse value */ 231 } 232 for(i=1;i<NCH;i++) 233 if(symbol[i]) break; 234 if(i >= NCH) return; 235 i = cindex[i]; 236 /* see if ccl is already in our table */ 237 j = 0; 238 if(i){ 239 for(j=1;j<NCH;j++){ 240 if((symbol[j] && cindex[j] != i) || 241 (!symbol[j] && cindex[j] == i)) break; 242 } 243 } 244 if(j >= NCH) return; /* already in */ 245 m = 0; 246 k = 0; 247 for(i=1;i<NCH;i++) 248 if(symbol[i]){ 249 if(!cindex[i]){ 250 cindex[i] = ccount; 251 symbol[i] = 0; 252 m = 1; 253 } 254 else k = 1; 255 } 256 /* m == 1 implies last value of ccount has been used */ 257 if(m)ccount++; 258 if(k == 0) return; /* is now in as ccount wholly */ 259 /* intersection must be computed */ 260 for(i=1;i<NCH;i++){ 261 if(symbol[i]){ 262 m = 0; 263 j = cindex[i]; /* will be non-zero */ 264 for(k=1;k<NCH;k++){ 265 if(cindex[k] == j){ 266 if(symbol[k]) symbol[k] = 0; 267 else { 268 cindex[k] = ccount; 269 m = 1; 270 } 271 } 272 } 273 if(m)ccount++; 274 } 275 } 276 return; 277 } 278 usescape(c) 279 int c; { 280 register char d; 281 switch(c){ 282 case 'n': c = '\n'; break; 283 case 'r': c = '\r'; break; 284 case 't': c = '\t'; break; 285 case 'b': c = '\b'; break; 286 case 'f': c = 014; break; /* form feed for ascii */ 287 case '0': case '1': case '2': case '3': 288 case '4': case '5': case '6': case '7': 289 c -= '0'; 290 while('0' <= (d=gch()) && d <= '7'){ 291 c = c * 8 + (d-'0'); 292 if(!('0' <= peek && peek <= '7')) break; 293 } 294 break; 295 } 296 return(c); 297 } 298 lookup(s,t) 299 char *s; 300 char **t; { 301 register int i; 302 i = 0; 303 while(*t){ 304 if(scomp(s,*t) == 0) 305 return(i); 306 i++; 307 t++; 308 } 309 return(-1); 310 } 311 cpyact(){ /* copy C action to the next ; or closing } */ 312 register int brac, c, mth; 313 int savline, sw; 314 315 brac = 0; 316 sw = TRUE; 317 318 while(!eof){ 319 c = gch(); 320 swt: 321 switch( c ){ 322 323 case '|': if(brac == 0 && sw == TRUE){ 324 if(peek == '|')gch(); /* eat up an extra '|' */ 325 return(0); 326 } 327 break; 328 329 case ';': 330 if( brac == 0 ){ 331 putc(c,fout); 332 putc('\n',fout); 333 return(1); 334 } 335 break; 336 337 case '{': 338 brac++; 339 savline=yyline; 340 break; 341 342 case '}': 343 brac--; 344 if( brac == 0 ){ 345 putc(c,fout); 346 putc('\n',fout); 347 return(1); 348 } 349 break; 350 351 case '/': /* look for comments */ 352 putc(c,fout); 353 c = gch(); 354 if( c != '*' ) goto swt; 355 356 /* it really is a comment */ 357 358 putc(c,fout); 359 savline=yyline; 360 while( c=gch() ){ 361 if( c=='*' ){ 362 putc(c,fout); 363 if( (c=gch()) == '/' ) goto loop; 364 } 365 putc(c,fout); 366 } 367 yyline=savline; 368 error( "EOF inside comment" ); 369 370 case '\'': /* character constant */ 371 mth = '\''; 372 goto string; 373 374 case '"': /* character string */ 375 mth = '"'; 376 377 string: 378 379 putc(c,fout); 380 while( c=gch() ){ 381 if( c=='\\' ){ 382 putc(c,fout); 383 c=gch(); 384 } 385 else if( c==mth ) goto loop; 386 putc(c,fout); 387 if (c == '\n') 388 { 389 yyline--; 390 error( "Non-terminated string or character constant"); 391 } 392 } 393 error( "EOF in string or character constant" ); 394 395 case '\0': 396 yyline = savline; 397 error("Action does not terminate"); 398 default: 399 break; /* usual character */ 400 } 401 loop: 402 if(c != ' ' && c != '\t' && c != '\n') sw = FALSE; 403 putc(c,fout); 404 } 405 error("Premature EOF"); 406 } 407 gch(){ 408 register int c; 409 static int hadeof; 410 411 if (hadeof) { 412 hadeof = 0; 413 yyline = 0; 414 } 415 prev = pres; 416 c = pres = peek; 417 peek = pushptr > pushc ? *--pushptr : getc(fin); 418 if(peek == EOF && sargc > 1){ 419 hadeof = 1; 420 fclose(fin); 421 fin = fopen(sargv[++fptr],"r"); 422 if(fin == NULL) { 423 yyline = 0; 424 error("Cannot open file %s",sargv[fptr]); 425 } 426 peek = getc(fin); 427 sargc--; 428 } 429 if(c == EOF) { 430 eof = TRUE; 431 fclose(fin); 432 return(0); 433 } 434 if(c == '\n')yyline++; 435 return(c); 436 } 437 mn2(a,d,c) 438 int a,d,c; 439 { 440 name[tptr] = a; 441 left[tptr] = d; 442 right[tptr] = c; 443 parent[tptr] = 0; 444 nullstr[tptr] = 0; 445 switch(a){ 446 case RSTR: 447 parent[d] = tptr; 448 break; 449 case BAR: 450 case RNEWE: 451 if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE; 452 parent[d] = parent[c] = tptr; 453 break; 454 case RCAT: 455 case DIV: 456 if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE; 457 parent[d] = parent[c] = tptr; 458 break; 459 case RSCON: 460 parent[d] = tptr; 461 nullstr[tptr] = nullstr[d]; 462 break; 463 # ifdef DEBUG 464 default: 465 warning("bad switch mn2 %d %d",a,d); 466 break; 467 # endif 468 } 469 if(tptr > treesize) 470 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":"")); 471 return(tptr++); 472 } 473 mn1(a,d) 474 int a,d; 475 { 476 name[tptr] = a; 477 left[tptr] = d; 478 parent[tptr] = 0; 479 nullstr[tptr] = 0; 480 switch(a){ 481 case RCCL: 482 case RNCCL: 483 if(slength(d) == 0) nullstr[tptr] = TRUE; 484 break; 485 case STAR: 486 case QUEST: 487 nullstr[tptr] = TRUE; 488 parent[d] = tptr; 489 break; 490 case PLUS: 491 case CARAT: 492 nullstr[tptr] = nullstr[d]; 493 parent[d] = tptr; 494 break; 495 case S2FINAL: 496 nullstr[tptr] = TRUE; 497 break; 498 # ifdef DEBUG 499 case FINAL: 500 case S1FINAL: 501 break; 502 default: 503 warning("bad switch mn1 %d %d",a,d); 504 break; 505 # endif 506 } 507 if(tptr > treesize) 508 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":"")); 509 return(tptr++); 510 } 511 mn0(a) 512 int a; 513 { 514 name[tptr] = a; 515 parent[tptr] = 0; 516 nullstr[tptr] = 0; 517 if(a >= NCH) switch(a){ 518 case RNULLS: nullstr[tptr] = TRUE; break; 519 # ifdef DEBUG 520 default: 521 warning("bad switch mn0 %d",a); 522 break; 523 # endif 524 } 525 if(tptr > treesize) 526 error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":"")); 527 return(tptr++); 528 } 529 munput(t,p) /* implementation dependent */ 530 char *p; 531 int t; { 532 register int i,j; 533 if(t == 'c'){ 534 *pushptr++ = peek; /* watch out for this */ 535 peek = (int)p; 536 } 537 else if(t == 's'){ 538 *pushptr++ = peek; 539 peek = p[0]; 540 i = slength(p); 541 for(j = i-1; j>=1; j--) 542 *pushptr++ = p[j]; 543 } 544 # ifdef DEBUG 545 else error("Unrecognized munput option %c",t); 546 # endif 547 if(pushptr >= pushc+TOKENSIZE) 548 error("Too many characters pushed"); 549 return; 550 } 551 552 dupl(n) 553 int n; { 554 /* duplicate the subtree whose root is n, return ptr to it */ 555 register int i; 556 i = name[n]; 557 if(i < NCH) return(mn0(i)); 558 switch(i){ 559 case RNULLS: 560 return(mn0(i)); 561 case RCCL: case RNCCL: case FINAL: case S1FINAL: case S2FINAL: 562 return(mn1(i,left[n])); 563 case STAR: case QUEST: case PLUS: case CARAT: 564 return(mn1(i,dupl(left[n]))); 565 case RSTR: case RSCON: 566 return(mn2(i,dupl(left[n]),right[n])); 567 case BAR: case RNEWE: case RCAT: case DIV: 568 return(mn2(i,dupl(left[n]),dupl(right[n]))); 569 # ifdef DEBUG 570 default: 571 warning("bad switch dupl %d",n); 572 # endif 573 } 574 return(0); 575 } 576 # ifdef DEBUG 577 allprint(c) 578 char c; { 579 switch(c){ 580 case 014: 581 printf("\\f"); 582 charc++; 583 break; 584 case '\n': 585 printf("\\n"); 586 charc++; 587 break; 588 case '\t': 589 printf("\\t"); 590 charc++; 591 break; 592 case '\b': 593 printf("\\b"); 594 charc++; 595 break; 596 case ' ': 597 printf("\\\bb"); 598 break; 599 default: 600 if(!printable(c)){ 601 printf("\\%-3o",c); 602 charc += 3; 603 } 604 else 605 putchar(c); 606 break; 607 } 608 charc++; 609 return; 610 } 611 strpt(s) 612 char *s; { 613 charc = 0; 614 while(*s){ 615 allprint(*s++); 616 if(charc > LINESIZE){ 617 charc = 0; 618 printf("\n\t"); 619 } 620 } 621 return; 622 } 623 sect1dump(){ 624 register int i; 625 printf("Sect 1:\n"); 626 if(def[0]){ 627 printf("str trans\n"); 628 i = -1; 629 while(def[++i]) 630 printf("%s\t%s\n",def[i],subs[i]); 631 } 632 if(sname[0]){ 633 printf("start names\n"); 634 i = -1; 635 while(sname[++i]) 636 printf("%s\n",sname[i]); 637 } 638 if(chset == TRUE){ 639 printf("char set changed\n"); 640 for(i=1;i<NCH;i++){ 641 if(i != ctable[i]){ 642 allprint(i); 643 putchar(' '); 644 printable(ctable[i]) ? putchar(ctable[i]) : printf("%d",ctable[i]); 645 putchar('\n'); 646 } 647 } 648 } 649 } 650 sect2dump(){ 651 printf("Sect 2:\n"); 652 treedump(); 653 } 654 treedump() 655 { 656 register int t; 657 register char *p; 658 printf("treedump %d nodes:\n",tptr); 659 for(t=0;t<tptr;t++){ 660 printf("%4d ",t); 661 parent[t] ? printf("p=%4d",parent[t]) : printf(" "); 662 printf(" "); 663 if(name[t] < NCH) { 664 allprint(name[t]); 665 } 666 else switch(name[t]){ 667 case RSTR: 668 printf("%d ",left[t]); 669 allprint(right[t]); 670 break; 671 case RCCL: 672 printf("ccl "); 673 strpt(left[t]); 674 break; 675 case RNCCL: 676 printf("nccl "); 677 strpt(left[t]); 678 break; 679 case DIV: 680 printf("/ %d %d",left[t],right[t]); 681 break; 682 case BAR: 683 printf("| %d %d",left[t],right[t]); 684 break; 685 case RCAT: 686 printf("cat %d %d",left[t],right[t]); 687 break; 688 case PLUS: 689 printf("+ %d",left[t]); 690 break; 691 case STAR: 692 printf("* %d",left[t]); 693 break; 694 case CARAT: 695 printf("^ %d",left[t]); 696 break; 697 case QUEST: 698 printf("? %d",left[t]); 699 break; 700 case RNULLS: 701 printf("nullstring"); 702 break; 703 case FINAL: 704 printf("final %d",left[t]); 705 break; 706 case S1FINAL: 707 printf("s1final %d",left[t]); 708 break; 709 case S2FINAL: 710 printf("s2final %d",left[t]); 711 break; 712 case RNEWE: 713 printf("new %d %d",left[t],right[t]); 714 break; 715 case RSCON: 716 p = right[t]; 717 printf("start %s",sname[*p++-1]); 718 while(*p) 719 printf(", %s",sname[*p++-1]); 720 printf(" %d",left[t]); 721 break; 722 default: 723 printf("unknown %d %d %d",name[t],left[t],right[t]); 724 break; 725 } 726 if(nullstr[t])printf("\t(null poss.)"); 727 putchar('\n'); 728 } 729 } 730 # endif 731