hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

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