1: %token CHAR CCL NCCL STR DELIM SCON ITER NEWE NULLS 2: %left SCON '/' NEWE 3: %left '|' 4: %left '$' '^' 5: %left CHAR CCL NCCL '(' '.' STR NULLS 6: %left ITER 7: %left CAT 8: %left '*' '+' '?' 9: 10: %{ 11: #ifndef lint 12: static char sccsid[] = "@(#)parser.y 4.1 (Berkeley) 8/11/83"; 13: #endif 14: 15: # include "ldefs.c" 16: %} 17: %% 18: %{ 19: int i; 20: int j,k; 21: int g; 22: char *p; 23: %} 24: acc : lexinput 25: ={ 26: # ifdef DEBUG 27: if(debug) sect2dump(); 28: # endif 29: } 30: ; 31: lexinput: defns delim prods end 32: | defns delim end 33: ={ 34: if(!funcflag)phead2(); 35: funcflag = TRUE; 36: } 37: | error 38: ={ 39: # ifdef DEBUG 40: if(debug) { 41: sect1dump(); 42: sect2dump(); 43: } 44: # endif 45: } 46: ; 47: end: delim | ; 48: defns: defns STR STR 49: ={ scopy($2,dp); 50: def[dptr] = dp; 51: dp += slength($2) + 1; 52: scopy($3,dp); 53: subs[dptr++] = dp; 54: if(dptr >= DEFSIZE) 55: error("Too many definitions"); 56: dp += slength($3) + 1; 57: if(dp >= dchar+DEFCHAR) 58: error("Definitions too long"); 59: subs[dptr]=def[dptr]=0; /* for lookup - require ending null */ 60: } 61: | 62: ; 63: delim: DELIM 64: ={ 65: # ifdef DEBUG 66: if(sect == DEFSECTION && debug) sect1dump(); 67: # endif 68: sect++; 69: } 70: ; 71: prods: prods pr 72: ={ $$ = mn2(RNEWE,$1,$2); 73: } 74: | pr 75: ={ $$ = $1;} 76: ; 77: pr: r NEWE 78: ={ 79: if(divflg == TRUE) 80: i = mn1(S1FINAL,casecount); 81: else i = mn1(FINAL,casecount); 82: $$ = mn2(RCAT,$1,i); 83: divflg = FALSE; 84: casecount++; 85: } 86: | error NEWE 87: ={ 88: # ifdef DEBUG 89: if(debug) sect2dump(); 90: # endif 91: } 92: r: CHAR 93: ={ $$ = mn0($1); } 94: | STR 95: ={ 96: p = $1; 97: i = mn0(*p++); 98: while(*p) 99: i = mn2(RSTR,i,*p++); 100: $$ = i; 101: } 102: | '.' 103: ={ symbol['\n'] = 0; 104: if(psave == FALSE){ 105: p = ccptr; 106: psave = ccptr; 107: for(i=1;i<'\n';i++){ 108: symbol[i] = 1; 109: *ccptr++ = i; 110: } 111: for(i='\n'+1;i<NCH;i++){ 112: symbol[i] = 1; 113: *ccptr++ = i; 114: } 115: *ccptr++ = 0; 116: if(ccptr > ccl+CCLSIZE) 117: error("Too many large character classes"); 118: } 119: else 120: p = psave; 121: $$ = mn1(RCCL,p); 122: cclinter(1); 123: } 124: | CCL 125: ={ $$ = mn1(RCCL,$1); } 126: | NCCL 127: ={ $$ = mn1(RNCCL,$1); } 128: | r '*' 129: ={ $$ = mn1(STAR,$1); } 130: | r '+' 131: ={ $$ = mn1(PLUS,$1); } 132: | r '?' 133: ={ $$ = mn1(QUEST,$1); } 134: | r '|' r 135: ={ $$ = mn2(BAR,$1,$3); } 136: | r r %prec CAT 137: ={ $$ = mn2(RCAT,$1,$2); } 138: | r '/' r 139: ={ if(!divflg){ 140: j = mn1(S2FINAL,-casecount); 141: i = mn2(RCAT,$1,j); 142: $$ = mn2(DIV,i,$3); 143: } 144: else { 145: $$ = mn2(RCAT,$1,$3); 146: warning("Extra slash removed"); 147: } 148: divflg = TRUE; 149: } 150: | r ITER ',' ITER '}' 151: ={ if($2 > $4){ 152: i = $2; 153: $2 = $4; 154: $4 = i; 155: } 156: if($4 <= 0) 157: warning("Iteration range must be positive"); 158: else { 159: j = $1; 160: for(k = 2; k<=$2;k++) 161: j = mn2(RCAT,j,dupl($1)); 162: for(i = $2+1; i<=$4; i++){ 163: g = dupl($1); 164: for(k=2;k<=i;k++) 165: g = mn2(RCAT,g,dupl($1)); 166: j = mn2(BAR,j,g); 167: } 168: $$ = j; 169: } 170: } 171: | r ITER '}' 172: ={ 173: if($2 < 0)warning("Can't have negative iteration"); 174: else if($2 == 0) $$ = mn0(RNULLS); 175: else { 176: j = $1; 177: for(k=2;k<=$2;k++) 178: j = mn2(RCAT,j,dupl($1)); 179: $$ = j; 180: } 181: } 182: | r ITER ',' '}' 183: ={ 184: /* from n to infinity */ 185: if($2 < 0)warning("Can't have negative iteration"); 186: else if($2 == 0) $$ = mn1(STAR,$1); 187: else if($2 == 1)$$ = mn1(PLUS,$1); 188: else { /* >= 2 iterations minimum */ 189: j = $1; 190: for(k=2;k<$2;k++) 191: j = mn2(RCAT,j,dupl($1)); 192: k = mn1(PLUS,dupl($1)); 193: $$ = mn2(RCAT,j,k); 194: } 195: } 196: | SCON r 197: ={ $$ = mn2(RSCON,$2,$1); } 198: | '^' r 199: ={ $$ = mn1(CARAT,$2); } 200: | r '$' 201: ={ i = mn0('\n'); 202: if(!divflg){ 203: j = mn1(S2FINAL,-casecount); 204: k = mn2(RCAT,$1,j); 205: $$ = mn2(DIV,k,i); 206: } 207: else $$ = mn2(RCAT,$1,i); 208: divflg = TRUE; 209: } 210: | '(' r ')' 211: ={ $$ = $2; } 212: | NULLS 213: ={ $$ = mn0(RNULLS); } 214: ; 215: %% 216: yylex(){ 217: register char *p; 218: register int c, i; 219: char *t, *xp; 220: int n, j, k, x; 221: static int sectbegin; 222: static char token[TOKENSIZE]; 223: static int iter; 224: 225: # ifdef DEBUG 226: yylval = 0; 227: # endif 228: 229: if(sect == DEFSECTION) { /* definitions section */ 230: while(!eof) { 231: if(prev == '\n'){ /* next char is at beginning of line */ 232: getl(p=buf); 233: switch(*p){ 234: case '%': 235: switch(c= *(p+1)){ 236: case '%': 237: lgate(); 238: if(!ratfor)fprintf(fout,"# "); 239: fprintf(fout,"define YYNEWLINE %d\n",ctable['\n']); 240: if(!ratfor)fprintf(fout,"yylex(){\nint nstr; extern int yyprevious;\n"); 241: sectbegin = TRUE; 242: i = treesize*(sizeof(*name)+sizeof(*left)+ 243: sizeof(*right)+sizeof(*nullstr)+sizeof(*parent))+ALITTLEEXTRA; 244: c = myalloc(i,1); 245: if(c == 0) 246: error("Too little core for parse tree"); 247: p = c; 248: cfree(p,i,1); 249: name = myalloc(treesize,sizeof(*name)); 250: left = myalloc(treesize,sizeof(*left)); 251: right = myalloc(treesize,sizeof(*right)); 252: nullstr = myalloc(treesize,sizeof(*nullstr)); 253: parent = myalloc(treesize,sizeof(*parent)); 254: if(name == 0 || left == 0 || right == 0 || parent == 0 || nullstr == 0) 255: error("Too little core for parse tree"); 256: return(freturn(DELIM)); 257: case 'p': case 'P': /* has overridden number of positions */ 258: while(*p && !digit(*p))p++; 259: maxpos = siconv(p); 260: # ifdef DEBUG 261: if (debug) printf("positions (%%p) now %d\n",maxpos); 262: # endif 263: if(report == 2)report = 1; 264: continue; 265: case 'n': case 'N': /* has overridden number of states */ 266: while(*p && !digit(*p))p++; 267: nstates = siconv(p); 268: # ifdef DEBUG 269: if(debug)printf( " no. states (%%n) now %d\n",nstates); 270: # endif 271: if(report == 2)report = 1; 272: continue; 273: case 'e': case 'E': /* has overridden number of tree nodes */ 274: while(*p && !digit(*p))p++; 275: treesize = siconv(p); 276: # ifdef DEBUG 277: if (debug) printf("treesize (%%e) now %d\n",treesize); 278: # endif 279: if(report == 2)report = 1; 280: continue; 281: case 'o': case 'O': 282: while (*p && !digit(*p))p++; 283: outsize = siconv(p); 284: if (report ==2) report=1; 285: continue; 286: case 'a': case 'A': /* has overridden number of transitions */ 287: while(*p && !digit(*p))p++; 288: if(report == 2)report = 1; 289: ntrans = siconv(p); 290: # ifdef DEBUG 291: if (debug)printf("N. trans (%%a) now %d\n",ntrans); 292: # endif 293: continue; 294: case 'k': case 'K': /* overriden packed char classes */ 295: while (*p && !digit(*p))p++; 296: if (report==2) report=1; 297: cfree(pchar, pchlen, sizeof(*pchar)); 298: pchlen = siconv(p); 299: # ifdef DEBUG 300: if (debug) printf( "Size classes (%%k) now %d\n",pchlen); 301: # endif 302: pchar=pcptr=myalloc(pchlen, sizeof(*pchar)); 303: continue; 304: case 't': case 'T': /* character set specifier */ 305: ZCH = atoi(p+2); 306: if (ZCH < NCH) ZCH = NCH; 307: if (ZCH > 2*NCH) error("ch table needs redeclaration"); 308: chset = TRUE; 309: for(i = 0; i<ZCH; i++) 310: ctable[i] = 0; 311: while(getl(p) && scomp(p,"%T") != 0 && scomp(p,"%t") != 0){ 312: if((n = siconv(p)) <= 0 || n > ZCH){ 313: warning("Character value %d out of range",n); 314: continue; 315: } 316: while(!space(*p) && *p) p++; 317: while(space(*p)) p++; 318: t = p; 319: while(*t){ 320: c = ctrans(&t); 321: if(ctable[c]){ 322: if (printable(c)) 323: warning("Character '%c' used twice",c); 324: else 325: warning("Character %o used twice",c); 326: } 327: else ctable[c] = n; 328: t++; 329: } 330: p = buf; 331: } 332: { 333: char chused[2*NCH]; int kr; 334: for(i=0; i<ZCH; i++) 335: chused[i]=0; 336: for(i=0; i<NCH; i++) 337: chused[ctable[i]]=1; 338: for(kr=i=1; i<NCH; i++) 339: if (ctable[i]==0) 340: { 341: while (chused[kr] == 0) 342: kr++; 343: ctable[i]=kr; 344: chused[kr]=1; 345: } 346: } 347: lgate(); 348: continue; 349: case 'r': case 'R': 350: c = 'r'; 351: case 'c': case 'C': 352: if(lgatflg) 353: error("Too late for language specifier"); 354: ratfor = (c == 'r'); 355: continue; 356: case '{': 357: lgate(); 358: while(getl(p) && scomp(p,"%}") != 0) 359: fprintf(fout, "%s\n",p); 360: if(p[0] == '%') continue; 361: error("Premature eof"); 362: case 's': case 'S': /* start conditions */ 363: lgate(); 364: while(*p && index(*p," \t,") < 0) p++; 365: n = TRUE; 366: while(n){ 367: while(*p && index(*p," \t,") >= 0) p++; 368: t = p; 369: while(*p && index(*p," \t,") < 0)p++; 370: if(!*p) n = FALSE; 371: *p++ = 0; 372: if (*t == 0) continue; 373: i = sptr*2; 374: if(!ratfor)fprintf(fout,"# "); 375: fprintf(fout,"define %s %d\n",t,i); 376: scopy(t,sp); 377: sname[sptr++] = sp; 378: sname[sptr] = 0; /* required by lookup */ 379: if(sptr >= STARTSIZE) 380: error("Too many start conditions"); 381: sp += slength(sp) + 1; 382: if(sp >= schar+STARTCHAR) 383: error("Start conditions too long"); 384: } 385: continue; 386: default: 387: warning("Invalid request %s",p); 388: continue; 389: } /* end of switch after seeing '%' */ 390: case ' ': case '\t': /* must be code */ 391: lgate(); 392: fprintf(fout, "%s\n",p); 393: continue; 394: default: /* definition */ 395: while(*p && !space(*p)) p++; 396: if(*p == 0) 397: continue; 398: prev = *p; 399: *p = 0; 400: bptr = p+1; 401: yylval = buf; 402: if(digit(buf[0])) 403: warning("Substitution strings may not begin with digits"); 404: return(freturn(STR)); 405: } 406: } 407: /* still sect 1, but prev != '\n' */ 408: else { 409: p = bptr; 410: while(*p && space(*p)) p++; 411: if(*p == 0) 412: warning("No translation given - null string assumed"); 413: scopy(p,token); 414: yylval = token; 415: prev = '\n'; 416: return(freturn(STR)); 417: } 418: } 419: /* end of section one processing */ 420: } 421: else if(sect == RULESECTION){ /* rules and actions */ 422: while(!eof){ 423: switch(c=gch()){ 424: case '\0': 425: return(freturn(0)); 426: case '\n': 427: if(prev == '\n') continue; 428: x = NEWE; 429: break; 430: case ' ': 431: case '\t': 432: if(sectbegin == TRUE){ 433: cpyact(); 434: while((c=gch()) && c != '\n'); 435: continue; 436: } 437: if(!funcflag)phead2(); 438: funcflag = TRUE; 439: if(ratfor)fprintf(fout,"%d\n",30000+casecount); 440: else fprintf(fout,"case %d:\n",casecount); 441: if(cpyact()){ 442: if(ratfor)fprintf(fout,"goto 30997\n"); 443: else fprintf(fout,"break;\n"); 444: } 445: while((c=gch()) && c != '\n'); 446: if(peek == ' ' || peek == '\t' || sectbegin == TRUE){ 447: warning("Executable statements should occur right after %%"); 448: continue; 449: } 450: x = NEWE; 451: break; 452: case '%': 453: if(prev != '\n') goto character; 454: if(peek == '{'){ /* included code */ 455: getl(buf); 456: while(!eof && getl(buf) && scomp("%}",buf) != 0) 457: fprintf(fout,"%s\n",buf); 458: continue; 459: } 460: if(peek == '%'){ 461: c = gch(); 462: c = gch(); 463: x = DELIM; 464: break; 465: } 466: goto character; 467: case '|': 468: if(peek == ' ' || peek == '\t' || peek == '\n'){ 469: if(ratfor)fprintf(fout,"%d\n",30000+casecount++); 470: else fprintf(fout,"case %d:\n",casecount++); 471: continue; 472: } 473: x = '|'; 474: break; 475: case '$': 476: if(peek == '\n' || peek == ' ' || peek == '\t' || peek == '|' || peek == '/'){ 477: x = c; 478: break; 479: } 480: goto character; 481: case '^': 482: if(prev != '\n' && scon != TRUE) goto character; /* valid only at line begin */ 483: x = c; 484: break; 485: case '?': 486: case '+': 487: case '.': 488: case '*': 489: case '(': 490: case ')': 491: case ',': 492: case '/': 493: x = c; 494: break; 495: case '}': 496: iter = FALSE; 497: x = c; 498: break; 499: case '{': /* either iteration or definition */ 500: if(digit(c=gch())){ /* iteration */ 501: iter = TRUE; 502: ieval: 503: i = 0; 504: while(digit(c)){ 505: token[i++] = c; 506: c = gch(); 507: } 508: token[i] = 0; 509: yylval = siconv(token); 510: munput('c',c); 511: x = ITER; 512: break; 513: } 514: else { /* definition */ 515: i = 0; 516: while(c && c!='}'){ 517: token[i++] = c; 518: c = gch(); 519: } 520: token[i] = 0; 521: i = lookup(token,def); 522: if(i < 0) 523: warning("Definition %s not found",token); 524: else 525: munput('s',subs[i]); 526: continue; 527: } 528: case '<': /* start condition ? */ 529: if(prev != '\n') /* not at line begin, not start */ 530: goto character; 531: t = slptr; 532: do { 533: i = 0; 534: c = gch(); 535: while(c != ',' && c && c != '>'){ 536: token[i++] = c; 537: c = gch(); 538: } 539: token[i] = 0; 540: if(i == 0) 541: goto character; 542: i = lookup(token,sname); 543: if(i < 0) { 544: warning("Undefined start condition %s",token); 545: continue; 546: } 547: *slptr++ = i+1; 548: } while(c && c != '>'); 549: *slptr++ = 0; 550: /* check if previous value re-usable */ 551: for (xp=slist; xp<t; ) 552: { 553: if (strcmp(xp, t)==0) 554: break; 555: while (*xp++); 556: } 557: if (xp<t) 558: { 559: /* re-use previous pointer to string */ 560: slptr=t; 561: t=xp; 562: } 563: if(slptr > slist+STARTSIZE) /* note not packed ! */ 564: error("Too many start conditions used"); 565: yylval = t; 566: x = SCON; 567: break; 568: case '"': 569: i = 0; 570: while((c=gch()) && c != '"' && c != '\n'){ 571: if(c == '\\') c = usescape(c=gch()); 572: token[i++] = c; 573: if(i > TOKENSIZE){ 574: warning("String too long"); 575: i = TOKENSIZE-1; 576: break; 577: } 578: } 579: if(c == '\n') { 580: yyline--; 581: warning("Non-terminated string"); 582: yyline++; 583: } 584: token[i] = 0; 585: if(i == 0)x = NULLS; 586: else if(i == 1){ 587: yylval = token[0]; 588: x = CHAR; 589: } 590: else { 591: yylval = token; 592: x = STR; 593: } 594: break; 595: case '[': 596: for(i=1;i<NCH;i++) symbol[i] = 0; 597: x = CCL; 598: if((c = gch()) == '^'){ 599: x = NCCL; 600: c = gch(); 601: } 602: while(c != ']' && c){ 603: if(c == '\\') c = usescape(c=gch()); 604: symbol[c] = 1; 605: j = c; 606: if((c=gch()) == '-' && peek != ']'){ /* range specified */ 607: c = gch(); 608: if(c == '\\') c = usescape(c=gch()); 609: k = c; 610: if(j > k) { 611: n = j; 612: j = k; 613: k = n; 614: } 615: if(!(('A' <= j && k <= 'Z') || 616: ('a' <= j && k <= 'z') || 617: ('0' <= j && k <= '9'))) 618: warning("Non-portable Character Class"); 619: for(n=j+1;n<=k;n++) 620: symbol[n] = 1; /* implementation dependent */ 621: c = gch(); 622: } 623: } 624: /* try to pack ccl's */ 625: i = 0; 626: for(j=0;j<NCH;j++) 627: if(symbol[j])token[i++] = j; 628: token[i] = 0; 629: p = ccptr; 630: if(optim){ 631: p = ccl; 632: while(p <ccptr && scomp(token,p) != 0)p++; 633: } 634: if(p < ccptr) /* found it */ 635: yylval = p; 636: else { 637: yylval = ccptr; 638: scopy(token,ccptr); 639: ccptr += slength(token) + 1; 640: if(ccptr >= ccl+CCLSIZE) 641: error("Too many large character classes"); 642: } 643: cclinter(x==CCL); 644: break; 645: case '\\': 646: c = usescape(c=gch()); 647: default: 648: character: 649: if(iter){ /* second part of an iteration */ 650: iter = FALSE; 651: if('0' <= c && c <= '9') 652: goto ieval; 653: } 654: if(alpha(peek)){ 655: i = 0; 656: yylval = token; 657: token[i++] = c; 658: while(alpha(peek)) 659: token[i++] = gch(); 660: if(peek == '?' || peek == '*' || peek == '+') 661: munput('c',token[--i]); 662: token[i] = 0; 663: if(i == 1){ 664: yylval = token[0]; 665: x = CHAR; 666: } 667: else x = STR; 668: } 669: else { 670: yylval = c; 671: x = CHAR; 672: } 673: } 674: scon = FALSE; 675: if(x == SCON)scon = TRUE; 676: sectbegin = FALSE; 677: return(freturn(x)); 678: } 679: } 680: /* section three */ 681: ptail(); 682: # ifdef DEBUG 683: if(debug) 684: fprintf(fout,"\n/*this comes from section three - debug */\n"); 685: # endif 686: while(getl(buf) && !eof) 687: fprintf(fout,"%s\n",buf); 688: return(freturn(0)); 689: } 690: /* end of yylex */ 691: # ifdef DEBUG 692: freturn(i) 693: int i; { 694: if(yydebug) { 695: printf("now return "); 696: if(i < NCH) allprint(i); 697: else printf("%d",i); 698: printf(" yylval = "); 699: switch(i){ 700: case STR: case CCL: case NCCL: 701: strpt(yylval); 702: break; 703: case CHAR: 704: allprint(yylval); 705: break; 706: default: 707: printf("%d",yylval); 708: break; 709: } 710: putchar('\n'); 711: } 712: return(i); 713: } 714: # endif