1: #ifndef lint 2: static char sccsid[] = "@(#)sub1.c 4.2 (Berkeley) 2/21/85"; 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 = 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