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