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