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