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