1 %{ 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 %} 23 /* 24 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* Copyright (c) 1988 AT&T */ 29 /* All Rights Reserved */ 30 31 32 %{ 33 #pragma ident "%Z%%M% %I% %E% SMI" 34 35 void yyerror(char *); 36 37 %} 38 /* parser.y */ 39 40 /* XCU4: add XSCON: %x exclusive start token */ 41 /* XCU4: add ARRAY: %a yytext is char array */ 42 /* XCU4: add POINTER: %p yytext is a pointer to char */ 43 %token CHAR CCL NCCL STR DELIM SCON ITER NEWE NULLS XSCON ARRAY POINTER 44 45 %nonassoc ARRAY POINTER 46 %left XSCON SCON NEWE 47 %left '/' 48 /* 49 * XCU4: lower the precedence of $ and ^ to less than the or operator 50 * per Spec. 1170 51 */ 52 %left '$' '^' 53 %left '|' 54 %left CHAR CCL NCCL '(' '.' STR NULLS 55 %left ITER 56 %left CAT 57 %left '*' '+' '?' 58 59 %{ 60 #include "ldefs.h" 61 62 #define YYSTYPE union _yystype_ 63 union _yystype_ 64 { 65 int i; 66 CHR *cp; 67 }; 68 int peekon = 0; /* need this to check if "^" came in a definition section */ 69 70 %} 71 %% 72 %{ 73 int i; 74 int j,k; 75 int g; 76 CHR *p; 77 static wchar_t L_PctUpT[]= {'%', 'T', 0}; 78 static wchar_t L_PctLoT[]= {'%', 't', 0}; 79 static wchar_t L_PctCbr[]= {'%', '}', 0}; 80 %} 81 acc : lexinput 82 ={ 83 # ifdef DEBUG 84 if(debug) sect2dump(); 85 # endif 86 } 87 ; 88 lexinput: defns delim prods end 89 | defns delim end 90 ={ 91 if(!funcflag)phead2(); 92 funcflag = TRUE; 93 } 94 | error 95 ={ 96 # ifdef DEBUG 97 if(debug) { 98 sect1dump(); 99 sect2dump(); 100 } 101 # endif 102 fatal = 0; 103 n_error++; 104 error("Illegal definition"); 105 fatal = 1; 106 } 107 ; 108 end: delim | ; 109 defns: defns STR STR 110 ={ scopy($2.cp,dp); 111 def[dptr] = dp; 112 dp += slength($2.cp) + 1; 113 scopy($3.cp,dp); 114 subs[dptr++] = dp; 115 if(dptr >= DEFSIZE) 116 error("Too many definitions"); 117 dp += slength($3.cp) + 1; 118 if(dp >= dchar+DEFCHAR) 119 error("Definitions too long"); 120 subs[dptr]=def[dptr]=0; /* for lookup - require ending null */ 121 } 122 | 123 ; 124 delim: DELIM 125 ={ 126 # ifdef DEBUG 127 if(sect == DEFSECTION && debug) sect1dump(); 128 # endif 129 sect++; 130 } 131 ; 132 prods: prods pr 133 ={ $$.i = mn2(RNEWE,$1.i,$2.i); 134 } 135 | pr 136 ={ $$.i = $1.i;} 137 ; 138 pr: r NEWE 139 ={ 140 if(divflg == TRUE) 141 i = mn1(S1FINAL,casecount); 142 else i = mn1(FINAL,casecount); 143 $$.i = mn2(RCAT,$1.i,i); 144 divflg = FALSE; 145 if((++casecount)>NACTIONS) 146 error("Too many (>%d) pattern-action rules.", NACTIONS); 147 } 148 | error NEWE 149 ={ 150 # ifdef DEBUG 151 if(debug) sect2dump(); 152 # endif 153 fatal = 0; 154 yyline--; 155 n_error++; 156 error("Illegal rule"); 157 fatal = 1; 158 yyline++; 159 } 160 r: CHAR 161 ={ $$.i = mn0($1.i); } 162 | STR 163 ={ 164 p = (CHR *)$1.cp; 165 i = mn0((unsigned)(*p++)); 166 while(*p) 167 i = mn2(RSTR,i,(unsigned)(*p++)); 168 $$.i = i; 169 } 170 | '.' 171 ={ 172 $$.i = mn0(DOT); 173 } 174 | CCL 175 ={ $$.i = mn1(RCCL,$1.i); } 176 | NCCL 177 ={ $$.i = mn1(RNCCL,$1.i); } 178 | r '*' 179 ={ $$.i = mn1(STAR,$1.i); } 180 | r '+' 181 ={ $$.i = mn1(PLUS,$1.i); } 182 | r '?' 183 ={ $$.i = mn1(QUEST,$1.i); } 184 | r '|' r 185 ={ $$.i = mn2(BAR,$1.i,$3.i); } 186 | r r %prec CAT 187 ={ $$.i = mn2(RCAT,$1.i,$2.i); } 188 | r '/' r 189 ={ if(!divflg){ 190 j = mn1(S2FINAL,-casecount); 191 i = mn2(RCAT,$1.i,j); 192 $$.i = mn2(DIV,i,$3.i); 193 } 194 else { 195 $$.i = mn2(RCAT,$1.i,$3.i); 196 error("illegal extra slash"); 197 } 198 divflg = TRUE; 199 } 200 | r ITER ',' ITER '}' 201 ={ if($2.i > $4.i){ 202 i = $2.i; 203 $2.i = $4.i; 204 $4.i = i; 205 } 206 if($4.i <= 0) 207 error("iteration range must be positive"); 208 else { 209 j = $1.i; 210 for(k = 2; k<=$2.i;k++) 211 j = mn2(RCAT,j,dupl($1.i)); 212 for(i = $2.i+1; i<=$4.i; i++){ 213 g = dupl($1.i); 214 for(k=2;k<=i;k++) 215 g = mn2(RCAT,g,dupl($1.i)); 216 j = mn2(BAR,j,g); 217 } 218 $$.i = j; 219 } 220 } 221 | r ITER '}' 222 ={ 223 if($2.i < 0)error("can't have negative iteration"); 224 else if($2.i == 0) $$.i = mn0(RNULLS); 225 else { 226 j = $1.i; 227 for(k=2;k<=$2.i;k++) 228 j = mn2(RCAT,j,dupl($1.i)); 229 $$.i = j; 230 } 231 } 232 | r ITER ',' '}' 233 ={ 234 /* from n to infinity */ 235 if($2.i < 0)error("can't have negative iteration"); 236 else if($2.i == 0) $$.i = mn1(STAR,$1.i); 237 else if($2.i == 1)$$.i = mn1(PLUS,$1.i); 238 else { /* >= 2 iterations minimum */ 239 j = $1.i; 240 for(k=2;k<$2.i;k++) 241 j = mn2(RCAT,j,dupl($1.i)); 242 k = mn1(PLUS,dupl($1.i)); 243 $$.i = mn2(RCAT,j,k); 244 } 245 } 246 | SCON r 247 ={ $$.i = mn2(RSCON,$2.i,(uintptr_t)$1.cp); } 248 249 /* XCU4: add XSCON */ 250 | XSCON r 251 ={ $$.i = mn2(RXSCON,$2.i,(uintptr_t)$1.cp); } 252 | '^' r 253 ={ $$.i = mn1(CARAT,$2.i); } 254 | r '$' 255 ={ i = mn0('\n'); 256 if(!divflg){ 257 j = mn1(S2FINAL,-casecount); 258 k = mn2(RCAT,$1.i,j); 259 $$.i = mn2(DIV,k,i); 260 } 261 else $$.i = mn2(RCAT,$1.i,i); 262 divflg = TRUE; 263 } 264 | '(' r ')' 265 ={ $$.i = $2.i; } 266 | NULLS 267 ={ $$.i = mn0(RNULLS); } 268 269 /* XCU4: add ARRAY and POINTER */ 270 | ARRAY 271 ={ isArray = 1; }; 272 | POINTER 273 ={ isArray = 0; }; 274 ; 275 276 %% 277 int 278 yylex(void) 279 { 280 CHR *p; 281 int i; 282 CHR *xp; 283 int lex_startcond_lookupval; 284 CHR *t, c; 285 int n, j = 0, k, x; 286 CHR ch; 287 static int sectbegin; 288 static CHR token[TOKENSIZE]; 289 static int iter; 290 int ccs; /* Current CodeSet. */ 291 CHR *ccp; 292 int exclusive_flag; /* XCU4: exclusive start flag */ 293 294 # ifdef DEBUG 295 yylval.i = 0; 296 # endif 297 298 if(sect == DEFSECTION) { /* definitions section */ 299 while(!eof) { 300 if(prev == '\n'){ /* next char is at beginning of line */ 301 (void)getl(p=buf); 302 switch(*p){ 303 case '%': 304 switch(c= *(p+1)){ 305 case '%': 306 if(scomp(p, (CHR *)"%%")) { 307 p++; 308 while(*(++p)) 309 if(!space(*p)) { 310 warning("invalid string following %%%% be ignored"); 311 break; 312 } 313 } 314 lgate(); 315 if(!ratfor)(void) fprintf(fout,"# "); 316 (void) fprintf(fout,"define YYNEWLINE %d\n",ctable['\n']); 317 if(!ratfor)(void) fprintf(fout,"int yylex(){\nint nstr; extern int yyprevious;\n"); 318 sectbegin = TRUE; 319 i = treesize*(sizeof(*name)+sizeof(*left)+ 320 sizeof(*right)+sizeof(*nullstr)+sizeof(*parent))+ALITTLEEXTRA; 321 c = (int)myalloc(i,1); 322 if(c == 0) 323 error("Too little core for parse tree"); 324 p = (CHR *)c; 325 free(p); 326 name = (int *)myalloc(treesize,sizeof(*name)); 327 left = (int *)myalloc(treesize,sizeof(*left)); 328 right = (int *)myalloc(treesize,sizeof(*right)); 329 nullstr = myalloc(treesize,sizeof(*nullstr)); 330 parent = (int *)myalloc(treesize,sizeof(*parent)); 331 if(name == 0 || left == 0 || right == 0 || parent == 0 || nullstr == 0) 332 error("Too little core for parse tree"); 333 return(freturn(DELIM)); 334 case 'p': case 'P': 335 /* %p or %pointer */ 336 if ((*(p+2) == 'o') || 337 (*(p+2) == 'O')) { 338 if(lgatflg) 339 error("Too late for %%pointer"); 340 while(*p && !iswspace(*p)) 341 p++; 342 isArray = 0; 343 continue; 344 } 345 /* has overridden number of positions */ 346 p += 2; 347 maxpos = siconv(p); 348 if (maxpos<=0)error("illegal position number"); 349 # ifdef DEBUG 350 if (debug) (void) printf("positions (%%p) now %d\n",maxpos); 351 # endif 352 if(report == 2)report = 1; 353 continue; 354 case 'n': case 'N': /* has overridden number of states */ 355 p += 2; 356 nstates = siconv(p); 357 if(nstates<=0)error("illegal state number"); 358 # ifdef DEBUG 359 if(debug)(void) printf( " no. states (%%n) now %d\n",nstates); 360 # endif 361 if(report == 2)report = 1; 362 continue; 363 case 'e': case 'E': /* has overridden number of tree nodes */ 364 p += 2; 365 treesize = siconv(p); 366 if(treesize<=0)error("illegal number of parse tree nodes"); 367 # ifdef DEBUG 368 if (debug) (void) printf("treesize (%%e) now %d\n",treesize); 369 # endif 370 if(report == 2)report = 1; 371 continue; 372 case 'o': case 'O': 373 p += 2; 374 outsize = siconv(p); 375 if(outsize<=0)error("illegal size of output array"); 376 if (report ==2) report=1; 377 continue; 378 case 'a': case 'A': 379 /* %a or %array */ 380 if ((*(p+2) == 'r') || 381 (*(p+2) == 'R')) { 382 if(lgatflg) 383 error("Too late for %%array"); 384 while(*p && !iswspace(*p)) 385 p++; 386 isArray = 1; 387 continue; 388 } 389 /* has overridden number of transitions */ 390 p += 2; 391 ntrans = siconv(p); 392 if(ntrans<=0)error("illegal translation number"); 393 # ifdef DEBUG 394 if (debug)(void) printf("N. trans (%%a) now %d\n",ntrans); 395 # endif 396 if(report == 2)report = 1; 397 continue; 398 case 'k': case 'K': /* overriden packed char classes */ 399 p += 2; 400 free(pchar); 401 pchlen = siconv(p); 402 if(pchlen<=0)error("illegal number of packed character class"); 403 # ifdef DEBUG 404 if (debug) (void) printf( "Size classes (%%k) now %d\n",pchlen); 405 # endif 406 pchar=pcptr=(CHR *)myalloc(pchlen, sizeof(*pchar)); 407 if (report==2) report=1; 408 continue; 409 case 't': case 'T': /* character set specifier */ 410 if(handleeuc) 411 error("\ 412 Character table (%t) is supported only in ASCII compatibility mode.\n"); 413 ZCH = watoi(p+2); 414 if (ZCH < NCH) ZCH = NCH; 415 if (ZCH > 2*NCH) error("ch table needs redeclaration"); 416 chset = TRUE; 417 for(i = 0; i<ZCH; i++) 418 ctable[i] = 0; 419 while(getl(p) && scomp(p,L_PctUpT) != 0 && scomp(p,L_PctLoT) != 0){ 420 if((n = siconv(p)) <= 0 || n > ZCH){ 421 error("Character value %d out of range",n); 422 continue; 423 } 424 while(digit(*p)) p++; 425 if(!iswspace(*p)) error("bad translation format"); 426 while(iswspace(*p)) p++; 427 t = p; 428 while(*t){ 429 c = ctrans(&t); 430 if(ctable[(unsigned)c]){ 431 if (iswprint(c)) 432 warning("Character '%wc' used twice",c); 433 434 else 435 error("Chararter %o used twice",c); 436 } 437 else ctable[(unsigned)c] = n; 438 t++; 439 } 440 p = buf; 441 } 442 { 443 char chused[2*NCH]; int kr; 444 for(i=0; i<ZCH; i++) 445 chused[i]=0; 446 for(i=0; i<NCH; i++) 447 chused[ctable[i]]=1; 448 for(kr=i=1; i<NCH; i++) 449 if (ctable[i]==0) 450 { 451 while (chused[kr] == 0) 452 kr++; 453 ctable[i]=kr; 454 chused[kr]=1; 455 } 456 } 457 lgate(); 458 continue; 459 case 'r': case 'R': 460 c = 'r'; 461 /* FALLTHRU */ 462 case 'c': case 'C': 463 if(lgatflg) 464 error("Too late for language specifier"); 465 ratfor = (c == 'r'); 466 continue; 467 case '{': 468 lgate(); 469 while(getl(p) && scomp(p, L_PctCbr) != 0) 470 if(p[0]=='/' && p[1]=='*') 471 cpycom(p); 472 else 473 (void) fprintf(fout,"%ws\n",p); 474 if(p[0] == '%') continue; 475 if (*p) error("EOF before %%%%"); 476 else error("EOF before %%}"); 477 break; 478 479 case 'x': case 'X': /* XCU4: exclusive start conditions */ 480 exclusive_flag = 1; 481 goto start; 482 483 case 's': case 'S': /* start conditions */ 484 exclusive_flag = 0; 485 start: 486 lgate(); 487 488 while(*p && !iswspace(*p) && ((*p) != (wchar_t)',')) p++; 489 n = TRUE; 490 while(n){ 491 while(*p && (iswspace(*p) || ((*p) == (wchar_t)','))) p++; 492 t = p; 493 while(*p && !iswspace(*p) && ((*p) != (wchar_t)',')) { 494 if(!isascii(*p)) 495 error("None-ASCII characters in start condition."); 496 p++; 497 } 498 if(!*p) n = FALSE; 499 *p++ = 0; 500 if (*t == 0) continue; 501 i = sptr*2; 502 if(!ratfor)(void) fprintf(fout,"# "); 503 fprintf(fout,"define %ws %d\n",t,i); 504 scopy(t,sp); 505 sname[sptr] = sp; 506 /* XCU4: save exclusive flag with start name */ 507 exclusive[sptr++] = exclusive_flag; 508 sname[sptr] = 0; /* required by lookup */ 509 if(sptr >= STARTSIZE) 510 error("Too many start conditions"); 511 sp += slength(sp) + 1; 512 if(sp >= schar+STARTCHAR) 513 error("Start conditions too long"); 514 } 515 continue; 516 default: 517 error("Invalid request %s",p); 518 continue; 519 } /* end of switch after seeing '%' */ 520 break; 521 case ' ': case '\t': /* must be code */ 522 lgate(); 523 if( p[1]=='/' && p[2]=='*' ) cpycom(p); 524 else (void) fprintf(fout, "%ws\n",p); 525 continue; 526 case '/': /* look for comments */ 527 lgate(); 528 if((*(p+1))=='*') cpycom(p); 529 /* FALLTHRU */ 530 default: /* definition */ 531 while(*p && !iswspace(*p)) p++; 532 if(*p == 0) 533 continue; 534 prev = *p; 535 *p = 0; 536 bptr = p+1; 537 yylval.cp = (CHR *)buf; 538 if(digit(buf[0])) 539 warning("Substitution strings may not begin with digits"); 540 return(freturn(STR)); 541 } 542 } else { /* still sect 1, but prev != '\n' */ 543 p = bptr; 544 while(*p && iswspace(*p)) p++; 545 if(*p == 0) 546 warning("No translation given - null string assumed"); 547 scopy(p,token); 548 yylval.cp = (CHR *)token; 549 prev = '\n'; 550 return(freturn(STR)); 551 } 552 } 553 error("unexpected EOF before %%%%"); 554 /* end of section one processing */ 555 } else if(sect == RULESECTION){ /* rules and actions */ 556 lgate(); 557 while(!eof){ 558 static int first_test=TRUE, first_value; 559 static int reverse=FALSE; 560 switch(c=gch()){ 561 case '\0': 562 if(n_error)error_tail(); 563 return(freturn(0)); 564 case '\n': 565 if(prev == '\n') continue; 566 x = NEWE; 567 break; 568 case ' ': 569 case '\t': 570 if(prev == '\n') copy_line = TRUE; 571 if(sectbegin == TRUE){ 572 (void)cpyact(); 573 copy_line = FALSE; 574 while((c=gch()) && c != '\n'); 575 continue; 576 } 577 if(!funcflag)phead2(); 578 funcflag = TRUE; 579 if(ratfor)(void) fprintf(fout,"%d\n",30000+casecount); 580 else (void) fprintf(fout,"case %d:\n",casecount); 581 if(cpyact()){ 582 if(ratfor)(void) fprintf(fout,"goto 30997\n"); 583 else (void) fprintf(fout,"break;\n"); 584 } 585 while((c=gch()) && c != '\n') { 586 if (c=='/') { 587 if((c=gch())=='*') { 588 c=gch(); 589 while(c !=EOF) { 590 while (c=='*') 591 if ((c=gch()) == '/') goto w_loop; 592 c = gch(); 593 } 594 error("EOF inside comment"); 595 } else 596 warning("undefined string"); 597 } else if (c=='}') 598 error("illegal extra \"}\""); 599 w_loop: ; 600 } 601 /* while ((c=gch())== ' ' || c == '\t') ; */ 602 /* if (!space(c)) error("undefined action string"); */ 603 if(peek == ' ' || peek == '\t' || sectbegin == TRUE){ 604 fatal = 0; 605 n_error++; 606 error("executable statements should occur right after %%%%"); 607 fatal = 1; 608 continue; 609 } 610 x = NEWE; 611 break; 612 case '%': 613 if(prev != '\n') goto character; 614 if(peek == '{'){ /* included code */ 615 (void)getl(buf); 616 while(!eof&& getl(buf) && scomp(L_PctCbr,buf)!=0) 617 if(buf[0]=='/' && buf[1]=='*') 618 cpycom(buf); 619 else 620 (void) fprintf(fout,"%ws\n",buf); 621 continue; 622 } 623 if(peek == '%'){ 624 c = gch(); 625 c = gch(); 626 x = DELIM; 627 break; 628 } 629 goto character; 630 case '|': 631 if(peek == ' ' || peek == '\t' || peek == '\n'){ 632 if(ratfor)(void) fprintf(fout,"%d\n",30000+casecount++); 633 else (void) fprintf(fout,"case %d:\n",casecount++); 634 continue; 635 } 636 x = '|'; 637 break; 638 case '$': 639 if(peek == '\n' || peek == ' ' || peek == '\t' || peek == '|' || peek == '/'){ 640 x = c; 641 break; 642 } 643 goto character; 644 case '^': 645 if(peekon && (prev == '}')){ 646 x = c; 647 break; 648 } 649 if(prev != '\n' && scon != TRUE) goto character; 650 /* valid only at line begin */ 651 x = c; 652 break; 653 case '?': 654 case '+': 655 case '*': 656 if(prev == '\n' ) { 657 fatal = 0; 658 n_error++; 659 error("illegal operator -- %c",c); 660 fatal = 1; 661 } 662 /* FALLTHRU */ 663 case '.': 664 case '(': 665 case ')': 666 case ',': 667 case '/': 668 x = c; 669 break; 670 case '}': 671 iter = FALSE; 672 x = c; 673 break; 674 case '{': /* either iteration or definition */ 675 if(digit(c=gch())){ /* iteration */ 676 iter = TRUE; 677 if(prev=='{') first_test = TRUE; 678 ieval: 679 i = 0; 680 while(digit(c)){ 681 token[i++] = c; 682 c = gch(); 683 } 684 token[i] = 0; 685 yylval.i = siconv(token); 686 if(first_test) { 687 first_test = FALSE; 688 first_value = yylval.i; 689 } else 690 if(first_value>yylval.i)warning("the values between braces are reversed"); 691 ch = c; 692 munput('c',&ch); 693 x = ITER; 694 break; 695 } 696 else { /* definition */ 697 i = 0; 698 while(c && c!='}'){ 699 token[i++] = c; 700 if(i >= TOKENSIZE) 701 error("definition too long"); 702 c = gch(); 703 } 704 token[i] = 0; 705 i = lookup(token,def); 706 if(i < 0) 707 error("definition %ws not found",token); 708 else 709 munput('s',(CHR *)(subs[i])); 710 if (peek == '^') 711 peekon = 1; 712 continue; 713 } 714 case '<': /* start condition ? */ 715 if(prev != '\n') /* not at line begin, not start */ 716 goto character; 717 t = slptr; 718 do { 719 i = 0; 720 if(!isascii(c = gch())) 721 error("Non-ASCII characters in start condition."); 722 while(c != ',' && c && c != '>'){ 723 token[i++] = c; 724 if(i >= TOKENSIZE) 725 error("string name too long"); 726 if(!isascii(c = gch())) 727 error("None-ASCII characters in start condition."); 728 } 729 token[i] = 0; 730 if(i == 0) 731 goto character; 732 i = lookup(token,sname); 733 lex_startcond_lookupval = i; 734 if(i < 0) { 735 fatal = 0; 736 n_error++; 737 error("undefined start condition %ws",token); 738 fatal = 1; 739 continue; 740 } 741 *slptr++ = i+1; 742 } while(c && c != '>'); 743 *slptr++ = 0; 744 /* check if previous value re-usable */ 745 for (xp=slist; xp<t; ) 746 { 747 if (scomp(xp, t)==0) 748 break; 749 while (*xp++); 750 } 751 if (xp<t) 752 { 753 /* re-use previous pointer to string */ 754 slptr=t; 755 t=xp; 756 } 757 if(slptr > slist+STARTSIZE) /* note not packed */ 758 error("Too many start conditions used"); 759 yylval.cp = (CHR *)t; 760 761 /* XCU4: add XSCON */ 762 763 if (exclusive[lex_startcond_lookupval]) 764 x = XSCON; 765 else 766 x = SCON; 767 break; 768 case '"': 769 i = 0; 770 while((c=gch()) && c != '"' && c != '\n'){ 771 if(c == '\\') c = usescape(c=gch()); 772 remch(c); 773 token[i++] = c; 774 if(i >= TOKENSIZE){ 775 warning("String too long"); 776 i = TOKENSIZE-1; 777 break; 778 } 779 } 780 if(c == '\n') { 781 yyline--; 782 warning("Non-terminated string"); 783 yyline++; 784 } 785 token[i] = 0; 786 if(i == 0)x = NULLS; 787 else if(i == 1){ 788 yylval.i = (unsigned)token[0]; 789 x = CHAR; 790 } 791 else { 792 yylval.cp = (CHR *)token; 793 x = STR; 794 } 795 break; 796 case '[': 797 reverse = FALSE; 798 x = CCL; 799 if((c = gch()) == '^'){ 800 x = NCCL; 801 reverse = TRUE; 802 c = gch(); 803 } 804 i = 0; 805 while(c != ']' && c){ 806 static int light=TRUE, ESCAPE=FALSE; 807 if(c == '-' && prev == '^' && reverse){ 808 symbol[(unsigned)c] = 1; 809 c = gch(); 810 continue; 811 } 812 if(c == '\\') { 813 c = usescape(c=gch()); 814 ESCAPE = TRUE; 815 } 816 if(c=='-' && !ESCAPE && prev!='[' && peek!=']'){ 817 /* range specified */ 818 if (light) { 819 c = gch(); 820 if(c == '\\') 821 c=usescape(c=gch()); 822 remch(c); 823 k = c; 824 ccs=wcsetno(k); 825 if(wcsetno(j)!=ccs) 826 error("\ 827 Character range specified between different codesets."); 828 if((unsigned)j > (unsigned)k) { 829 n = j; 830 j = k; 831 k = n; 832 } 833 if(!handleeuc) 834 if(!(('A'<=j && k<='Z') || 835 ('a'<=j && k<='z') || 836 ('0'<=j && k<='9'))) 837 warning("Non-portable Character Class"); 838 token[i++] = RANGE; 839 token[i++] = j; 840 token[i++] = k; 841 light = FALSE; 842 } else { 843 error("unmatched hyphen"); 844 if(symbol[(unsigned)c])warning("\"%c\" redefined inside brackets",c); 845 else symbol[(unsigned)c] = 1; 846 } 847 ESCAPE = FALSE; 848 } else { 849 j = c; 850 remch(c); 851 token[i++] = c; /* Remember whatever.*/ 852 light = TRUE; 853 ESCAPE = FALSE; 854 } 855 c = gch(); 856 } 857 /* try to pack ccl's */ 858 859 token[i] = 0; 860 ccp = ccl; 861 while (ccp < ccptr && scomp(token, ccp) != 0) ccp++; 862 if (ccp < ccptr) { /* found in ccl */ 863 yylval.cp = ccp; 864 } else { /* not in ccl, add it */ 865 scopy(token,ccptr); 866 yylval.cp = ccptr; 867 ccptr += slength(token) + 1; 868 if(ccptr >= ccl+CCLSIZE) 869 error("Too many large character classes"); 870 } 871 break; 872 case '\\': 873 c = usescape(c=gch()); 874 default: 875 character: 876 if(iter){ /* second part of an iteration */ 877 iter = FALSE; 878 if('0' <= c && c <= '9') 879 goto ieval; 880 } 881 remch(c); 882 if(alpha(peek)){ 883 i = 0; 884 yylval.cp = (CHR *)token; 885 token[i++] = c; 886 while(alpha(peek)) { 887 remch(token[i++] = gch()); 888 if(i >= TOKENSIZE) { 889 warning("string too long"); 890 i = TOKENSIZE - 1; 891 break; 892 } 893 } 894 if(peek == '?' || peek == '*' || peek == '+') 895 munput('c',&token[--i]); 896 token[i] = 0; 897 if(i == 1){ 898 yylval.i = (unsigned)(token[0]); 899 x = CHAR; 900 } 901 else x = STR; 902 } 903 else { 904 yylval.i = (unsigned)c; 905 x = CHAR; 906 } 907 } 908 scon = FALSE; 909 peekon = 0; 910 if((x == SCON) || (x == XSCON)) 911 scon = TRUE; 912 sectbegin = FALSE; 913 return(freturn(x)); 914 /* NOTREACHED */ 915 } 916 } 917 /* section three */ 918 lgate(); 919 ptail(); 920 # ifdef DEBUG 921 if(debug) 922 (void) fprintf(fout,"\n/*this comes from section three - debug */\n"); 923 # endif 924 925 if(getl(buf) && !eof) { 926 if (sargv[optind] == NULL) 927 (void) fprintf(fout, "\n# line %d\n", yyline-1); 928 else 929 (void) fprintf(fout, 930 "\n# line %d \"%s\"\n", yyline-1, sargv[optind]); 931 (void) fprintf(fout,"%ws\n",buf); 932 while(getl(buf) && !eof) 933 (void) fprintf(fout,"%ws\n",buf); 934 } 935 936 return(freturn(0)); 937 } 938 /* end of yylex */ 939 # ifdef DEBUG 940 freturn(i) 941 int i; { 942 if(yydebug) { 943 (void) printf("now return "); 944 if((unsigned)i < NCH) allprint(i); 945 else (void) printf("%d",i); 946 (void) printf(" yylval = "); 947 switch(i){ 948 case STR: case CCL: case NCCL: 949 strpt(yylval.cp); 950 break; 951 case CHAR: 952 allprint(yylval.i); 953 break; 954 default: 955 (void) printf("%d",yylval.i); 956 break; 957 } 958 (void) putchar('\n'); 959 } 960 return(i); 961 } 962 # endif 963