dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / sgs / lex / common / parser.y
blob383e23505ce89825f60394497cef273bb8fe051f
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 */
33 #pragma ident "%Z%%M% %I% %E% SMI"
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.
43 * When lint is able to handle %ws, it would be appropriate
44 * to come back through and remove the use of this macro.
46 #define WSFMT(_fmt) _fmt
48 void yyerror(char *);
51 /* parser.y */
53 /* XCU4: add XSCON: %x exclusive start token */
54 /* XCU4: add ARRAY: %a yytext is char array */
55 /* XCU4: add POINTER: %p yytext is a pointer to char */
56 %token CHAR CCL NCCL STR DELIM SCON ITER NEWE NULLS XSCON ARRAY POINTER
58 %nonassoc ARRAY POINTER
59 %left XSCON SCON NEWE
60 %left '/'
62 * XCU4: lower the precedence of $ and ^ to less than the or operator
63 * per Spec. 1170
65 %left '$' '^'
66 %left '|'
67 %left CHAR CCL NCCL '(' '.' STR NULLS
68 %left ITER
69 %left CAT
70 %left '*' '+' '?'
73 #include "ldefs.h"
75 #define YYSTYPE union _yystype_
76 union _yystype_
78 int i;
79 CHR *cp;
81 int peekon = 0; /* need this to check if "^" came in a definition section */
86 int i;
87 int j,k;
88 int g;
89 CHR *p;
90 static wchar_t L_PctUpT[]= {'%', 'T', 0};
91 static wchar_t L_PctLoT[]= {'%', 't', 0};
92 static wchar_t L_PctCbr[]= {'%', '}', 0};
94 acc : lexinput
95 ={
96 # ifdef DEBUG
97 if(debug) sect2dump();
98 # endif
101 lexinput: defns delim prods end
102 | defns delim end
104 if(!funcflag)phead2();
105 funcflag = TRUE;
107 | error
109 # ifdef DEBUG
110 if(debug) {
111 sect1dump();
112 sect2dump();
114 # endif
115 fatal = 0;
116 n_error++;
117 error("Illegal definition");
118 fatal = 1;
121 end: delim | ;
122 defns: defns STR STR
123 ={ scopy($2.cp,dp);
124 def[dptr] = dp;
125 dp += slength($2.cp) + 1;
126 scopy($3.cp,dp);
127 subs[dptr++] = dp;
128 if(dptr >= DEFSIZE)
129 error("Too many definitions");
130 dp += slength($3.cp) + 1;
131 if(dp >= dchar+DEFCHAR)
132 error("Definitions too long");
133 subs[dptr]=def[dptr]=0; /* for lookup - require ending null */
137 delim: DELIM
139 # ifdef DEBUG
140 if(sect == DEFSECTION && debug) sect1dump();
141 # endif
142 sect++;
145 prods: prods pr
146 ={ $$.i = mn2(RNEWE,$1.i,$2.i);
148 | pr
149 ={ $$.i = $1.i;}
151 pr: r NEWE
153 if(divflg == TRUE)
154 i = mn1(S1FINAL,casecount);
155 else i = mn1(FINAL,casecount);
156 $$.i = mn2(RCAT,$1.i,i);
157 divflg = FALSE;
158 if((++casecount)>NACTIONS)
159 error("Too many (>%d) pattern-action rules.", NACTIONS);
161 | error NEWE
163 # ifdef DEBUG
164 if(debug) sect2dump();
165 # endif
166 fatal = 0;
167 yyline--;
168 n_error++;
169 error("Illegal rule");
170 fatal = 1;
171 yyline++;
173 r: CHAR
174 ={ $$.i = mn0($1.i); }
175 | STR
177 p = (CHR *)$1.cp;
178 i = mn0((unsigned)(*p++));
179 while(*p)
180 i = mn2(RSTR,i,(unsigned)(*p++));
181 $$.i = i;
183 | '.'
185 $$.i = mn0(DOT);
187 | CCL
188 ={ $$.i = mn1(RCCL,$1.i); }
189 | NCCL
190 ={ $$.i = mn1(RNCCL,$1.i); }
191 | r '*'
192 ={ $$.i = mn1(STAR,$1.i); }
193 | r '+'
194 ={ $$.i = mn1(PLUS,$1.i); }
195 | r '?'
196 ={ $$.i = mn1(QUEST,$1.i); }
197 | r '|' r
198 ={ $$.i = mn2(BAR,$1.i,$3.i); }
199 | r r %prec CAT
200 ={ $$.i = mn2(RCAT,$1.i,$2.i); }
201 | r '/' r
202 ={ if(!divflg){
203 j = mn1(S2FINAL,-casecount);
204 i = mn2(RCAT,$1.i,j);
205 $$.i = mn2(DIV,i,$3.i);
207 else {
208 $$.i = mn2(RCAT,$1.i,$3.i);
209 error("illegal extra slash");
211 divflg = TRUE;
213 | r ITER ',' ITER '}'
214 ={ if($2.i > $4.i){
215 i = $2.i;
216 $2.i = $4.i;
217 $4.i = i;
219 if($4.i <= 0)
220 error("iteration range must be positive");
221 else {
222 j = $1.i;
223 for(k = 2; k<=$2.i;k++)
224 j = mn2(RCAT,j,dupl($1.i));
225 for(i = $2.i+1; i<=$4.i; i++){
226 g = dupl($1.i);
227 for(k=2;k<=i;k++)
228 g = mn2(RCAT,g,dupl($1.i));
229 j = mn2(BAR,j,g);
231 $$.i = j;
234 | r ITER '}'
236 if($2.i < 0)error("can't have negative iteration");
237 else if($2.i == 0) $$.i = mn0(RNULLS);
238 else {
239 j = $1.i;
240 for(k=2;k<=$2.i;k++)
241 j = mn2(RCAT,j,dupl($1.i));
242 $$.i = j;
245 | r ITER ',' '}'
247 /* from n to infinity */
248 if($2.i < 0)error("can't have negative iteration");
249 else if($2.i == 0) $$.i = mn1(STAR,$1.i);
250 else if($2.i == 1)$$.i = mn1(PLUS,$1.i);
251 else { /* >= 2 iterations minimum */
252 j = $1.i;
253 for(k=2;k<$2.i;k++)
254 j = mn2(RCAT,j,dupl($1.i));
255 k = mn1(PLUS,dupl($1.i));
256 $$.i = mn2(RCAT,j,k);
259 | SCON r
260 ={ $$.i = mn2(RSCON,$2.i,(uintptr_t)$1.cp); }
262 /* XCU4: add XSCON */
263 | XSCON r
264 ={ $$.i = mn2(RXSCON,$2.i,(uintptr_t)$1.cp); }
265 | '^' r
266 ={ $$.i = mn1(CARAT,$2.i); }
267 | r '$'
268 ={ i = mn0('\n');
269 if(!divflg){
270 j = mn1(S2FINAL,-casecount);
271 k = mn2(RCAT,$1.i,j);
272 $$.i = mn2(DIV,k,i);
274 else $$.i = mn2(RCAT,$1.i,i);
275 divflg = TRUE;
277 | '(' r ')'
278 ={ $$.i = $2.i; }
279 | NULLS
280 ={ $$.i = mn0(RNULLS); }
282 /* XCU4: add ARRAY and POINTER */
283 | ARRAY
284 ={ isArray = 1; };
285 | POINTER
286 ={ isArray = 0; };
291 yylex(void)
293 CHR *p;
294 int i;
295 CHR *xp;
296 int lex_startcond_lookupval;
297 CHR *t, c;
298 int n, j = 0, k, x;
299 CHR ch;
300 static int sectbegin;
301 static CHR token[TOKENSIZE];
302 static int iter;
303 int ccs; /* Current CodeSet. */
304 CHR *ccp;
305 int exclusive_flag; /* XCU4: exclusive start flag */
307 # ifdef DEBUG
308 yylval.i = 0;
309 # endif
311 if(sect == DEFSECTION) { /* definitions section */
312 while(!eof) {
313 if(prev == '\n'){ /* next char is at beginning of line */
314 (void)getl(p=buf);
315 switch(*p){
316 case '%':
317 switch(c= *(p+1)){
318 case '%':
319 /*LINTED: E_BAD_PTR_CAST_ALIGN*/
320 if(scomp(p, (CHR *)"%%")) {
321 p++;
322 while(*(++p))
323 if(!space(*p)) {
324 warning("invalid string following %%%% be ignored");
325 break;
328 lgate();
329 if(!ratfor)(void) fprintf(fout,"# ");
330 (void) fprintf(fout,"define YYNEWLINE %d\n",ctable['\n']);
331 if(!ratfor) {
332 (void) fprintf(fout,"int yylex(){\nint nstr; extern int yyprevious;\n");
333 (void) fprintf(fout,"if (yyin == NULL) yyin = stdin;\n");
334 (void) fprintf(fout,"if (yyout == NULL) yyout = stdout;\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 default:
901 character:
902 if(iter){ /* second part of an iteration */
903 iter = FALSE;
904 if('0' <= c && c <= '9')
905 goto ieval;
907 remch(c);
908 if(alpha(peek)){
909 i = 0;
910 yylval.cp = (CHR *)token;
911 token[i++] = c;
912 while(alpha(peek)) {
913 remch(token[i++] = gch());
914 if(i >= TOKENSIZE) {
915 warning("string too long");
916 i = TOKENSIZE - 1;
917 break;
920 if(peek == '?' || peek == '*' || peek == '+')
921 munput('c',&token[--i]);
922 token[i] = 0;
923 if(i == 1){
924 yylval.i = (unsigned)(token[0]);
925 x = CHAR;
927 else x = STR;
929 else {
930 yylval.i = (unsigned)c;
931 x = CHAR;
934 scon = FALSE;
935 peekon = 0;
936 if((x == SCON) || (x == XSCON))
937 scon = TRUE;
938 sectbegin = FALSE;
939 return(freturn(x));
940 /* NOTREACHED */
943 /* section three */
944 lgate();
945 ptail();
946 # ifdef DEBUG
947 if(debug)
948 (void) fprintf(fout,"\n/*this comes from section three - debug */\n");
949 # endif
951 if(getl(buf) && !eof) {
952 if (sargv[optind] == NULL)
953 (void) fprintf(fout, "\n# line %d\n", yyline-1);
954 else
955 (void) fprintf(fout,
956 "\n# line %d \"%s\"\n", yyline-1, sargv[optind]);
957 (void) fprintf(fout,WSFMT("%ws\n"),buf);
958 while(getl(buf) && !eof)
959 (void) fprintf(fout,WSFMT("%ws\n"),buf);
962 return(freturn(0));
964 /* end of yylex */
965 # ifdef DEBUG
966 freturn(i)
967 int i; {
968 if(yydebug) {
969 (void) printf("now return ");
970 if((unsigned)i < NCH) allprint(i);
971 else (void) printf("%d",i);
972 (void) printf(" yylval = ");
973 switch(i){
974 case STR: case CCL: case NCCL:
975 strpt(yylval.cp);
976 break;
977 case CHAR:
978 allprint(yylval.i);
979 break;
980 default:
981 (void) printf("%d",yylval.i);
982 break;
984 (void) putchar('\n');
986 return(i);
988 # endif