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