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) 08/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 715