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