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