9032 sgs: this statement may fall through
[unleashed.git] / usr / src / cmd / sgs / lex / common / parser.y
blob9b1f173bf24052fe32949cb80eea26fcf46f787c
1 %{
2 /*
3 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
24 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 /* Copyright (c) 1988 AT&T */
29 /* All Rights Reserved */
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.
42 * When lint is able to handle %ws, it would be appropriate
43 * to come back through and remove the use of this macro.
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
52 void yyerror(char *);
55 /* parser.y */
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
62 %nonassoc ARRAY POINTER
63 %left XSCON SCON NEWE
64 %left '/'
66 * XCU4: lower the precedence of $ and ^ to less than the or operator
67 * per Spec. 1170
69 %left '$' '^'
70 %left '|'
71 %left CHAR CCL NCCL '(' '.' STR NULLS
72 %left ITER
73 %left CAT
74 %left '*' '+' '?'
77 #include "ldefs.h"
79 #define YYSTYPE union _yystype_
80 union _yystype_
82 int i;
83 CHR *cp;
85 int peekon = 0; /* need this to check if "^" came in a definition section */
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};
98 acc : lexinput
99 ={
100 # ifdef DEBUG
101 if(debug) sect2dump();
102 # endif
105 lexinput: defns delim prods end
106 | defns delim end
108 if(!funcflag)phead2();
109 funcflag = TRUE;
111 | error
113 # ifdef DEBUG
114 if(debug) {
115 sect1dump();
116 sect2dump();
118 # endif
119 fatal = 0;
120 n_error++;
121 error("Illegal definition");
122 fatal = 1;
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 */
141 delim: DELIM
143 # ifdef DEBUG
144 if(sect == DEFSECTION && debug) sect1dump();
145 # endif
146 sect++;
149 prods: prods pr
150 ={ $$.i = mn2(RNEWE,$1.i,$2.i);
152 | pr
153 ={ $$.i = $1.i;}
155 pr: r NEWE
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);
165 | error NEWE
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++;
177 r: CHAR
178 ={ $$.i = mn0($1.i); }
179 | STR
181 p = (CHR *)$1.cp;
182 i = mn0((unsigned)(*p++));
183 while(*p)
184 i = mn2(RSTR,i,(unsigned)(*p++));
185 $$.i = i;
187 | '.'
189 $$.i = mn0(DOT);
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);
211 else {
212 $$.i = mn2(RCAT,$1.i,$3.i);
213 error("illegal extra slash");
215 divflg = TRUE;
217 | r ITER ',' ITER '}'
218 ={ if($2.i > $4.i){
219 i = $2.i;
220 $2.i = $4.i;
221 $4.i = i;
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);
235 $$.i = j;
238 | r ITER '}'
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;
249 | r ITER ',' '}'
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);
263 | SCON r
264 ={ $$.i = mn2(RSCON,$2.i,(uintptr_t)$1.cp); }
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);
278 else $$.i = mn2(RCAT,$1.i,i);
279 divflg = TRUE;
281 | '(' r ')'
282 ={ $$.i = $2.i; }
283 | NULLS
284 ={ $$.i = mn0(RNULLS); }
286 /* XCU4: add ARRAY and POINTER */
287 | ARRAY
288 ={ isArray = 1; };
289 | POINTER
290 ={ isArray = 0; };
295 yylex(void)
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 */
311 # ifdef DEBUG
312 yylval.i = 0;
313 # endif
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;
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;
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;
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;
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);
457 else
458 error("Chararter %o used twice",c);
460 else ctable[(unsigned)c] = n;
461 t++;
463 p = buf;
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)
474 while (chused[kr] == 0)
475 kr++;
476 ctable[i]=kr;
477 chused[kr]=1;
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;
502 case 'x': case 'X': /* XCU4: exclusive start conditions */
503 exclusive_flag = 1;
504 goto start;
506 case 's': case 'S': /* start conditions */
507 exclusive_flag = 0;
508 start:
509 lgate();
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++;
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");
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));
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));
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;
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");
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();
619 error("EOF inside comment");
620 } else
621 warning("undefined string");
622 } else if (c=='}')
623 error("illegal extra \"}\"");
624 w_loop: ;
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;
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;
648 if(peek == '%'){
649 c = gch();
650 c = gch();
651 x = DELIM;
652 break;
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;
661 x = '|';
662 break;
663 case '$':
664 if(peek == '\n' || peek == ' ' || peek == '\t' || peek == '|' || peek == '/'){
665 x = c;
666 break;
668 goto character;
669 case '^':
670 if(peekon && (prev == '}')){
671 x = c;
672 break;
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;
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();
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;
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();
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;
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.");
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;
766 *slptr++ = i+1;
767 } while(c && c != '>');
768 *slptr++ = 0;
769 /* check if previous value re-usable */
770 for (xp=slist; xp<t; )
772 if (scomp(xp, t)==0)
773 break;
774 while (*xp++);
776 if (xp<t)
778 /* re-use previous pointer to string */
779 slptr=t;
780 t=xp;
782 if(slptr > slist+STARTSIZE) /* note not packed */
783 error("Too many start conditions used");
784 yylval.cp = (CHR *)t;
786 /* XCU4: add XSCON */
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;
806 if(c == '\n') {
807 yyline--;
808 warning("Non-terminated string");
809 yyline++;
811 token[i] = 0;
812 if(i == 0)x = NULLS;
813 else if(i == 1){
814 yylval.i = (unsigned)token[0];
815 x = CHAR;
817 else {
818 yylval.cp = (CHR *)token;
819 x = STR;
821 break;
822 case '[':
823 reverse = FALSE;
824 x = CCL;
825 if((c = gch()) == '^'){
826 x = NCCL;
827 reverse = TRUE;
828 c = gch();
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;
838 if(c == '\\') {
839 c = usescape(c=gch());
840 ESCAPE = TRUE;
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;
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;
873 ESCAPE = FALSE;
874 } else {
875 j = c;
876 remch(c);
877 token[i++] = c; /* Remember whatever.*/
878 light = TRUE;
879 ESCAPE = FALSE;
881 c = gch();
883 /* try to pack ccl's */
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");
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;
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;
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;
928 else x = STR;
930 else {
931 yylval.i = (unsigned)c;
932 x = CHAR;
935 scon = FALSE;
936 peekon = 0;
937 if((x == SCON) || (x == XSCON))
938 scon = TRUE;
939 sectbegin = FALSE;
940 return(freturn(x));
941 /* NOTREACHED */
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
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);
963 return(freturn(0));
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;
985 (void) putchar('\n');
987 return(i);
989 # endif