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]
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
43 * When lint is able to handle %ws, it would be appropriate
44 * to come back through and remove the use of this macro.
47 static const char *lint_ws_fmt
= "";
48 #define WSFMT(_fmt) lint_ws_fmt
50 #define WSFMT(_fmt) _fmt
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
63 %nonassoc ARRAY POINTER
67 * XCU4: lower the precedence of $ and ^ to less than the or operator
72 %left CHAR CCL NCCL
'(' '.' STR NULLS
80 #define YYSTYPE union _yystype_
86 int peekon
= 0; /* need this to check if "^" came in a definition section */
95 static wchar_t L_PctUpT
[]= {'%', 'T', 0};
96 static wchar_t L_PctLoT
[]= {'%', 't', 0};
97 static wchar_t L_PctCbr
[]= {'%', '}', 0};
102 if
(debug
) sect2dump
();
106 lexinput: defns delim prods end
109 if
(!funcflag
)phead2
();
122 error("Illegal definition");
130 dp
+= slength
($2.cp
) + 1;
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 */
145 if
(sect
== DEFSECTION
&& debug
) sect1dump
();
151 ={ $$.i
= mn2
(RNEWE
,$1.i
,$2.i
);
159 i
= mn1
(S1FINAL
,casecount
);
160 else i
= mn1
(FINAL
,casecount
);
161 $$.i
= mn2
(RCAT
,$1.i
,i
);
163 if
((++casecount
)>NACTIONS
)
164 error("Too many (>%d) pattern-action rules.", NACTIONS
);
169 if
(debug
) sect2dump
();
174 error("Illegal rule");
179 ={ $$.i
= mn0
($1.i
); }
183 i
= mn0
((unsigned)(*p
++));
185 i
= mn2
(RSTR
,i
,(unsigned)(*p
++));
193 ={ $$.i
= mn1
(RCCL
,$1.i
); }
195 ={ $$.i
= mn1
(RNCCL
,$1.i
); }
197 ={ $$.i
= mn1
(STAR
,$1.i
); }
199 ={ $$.i
= mn1
(PLUS
,$1.i
); }
201 ={ $$.i
= mn1
(QUEST
,$1.i
); }
203 ={ $$.i
= mn2
(BAR
,$1.i
,$3.i
); }
205 ={ $$.i
= mn2
(RCAT
,$1.i
,$2.i
); }
208 j
= mn1
(S2FINAL
,-casecount
);
209 i
= mn2
(RCAT
,$1.i
,j
);
210 $$.i
= mn2
(DIV
,i
,$3.i
);
213 $$.i
= mn2
(RCAT
,$1.i
,$3.i
);
214 error("illegal extra slash");
218 | r ITER
',' ITER
'}'
225 error("iteration range must be positive");
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
++){
233 g
= mn2
(RCAT
,g
,dupl
($1.i
));
241 if
($2.i
< 0)error("can't have negative iteration");
242 else if
($2.i
== 0) $$.i
= mn0
(RNULLS
);
246 j
= mn2
(RCAT
,j
,dupl
($1.i
));
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 */
259 j
= mn2
(RCAT
,j
,dupl
($1.i
));
260 k
= mn1
(PLUS
,dupl
($1.i
));
261 $$.i
= mn2
(RCAT
,j
,k
);
265 ={ $$.i
= mn2
(RSCON
,$2.i
,(uintptr_t)$1.cp
); }
267 /* XCU4: add XSCON */
269 ={ $$.i
= mn2
(RXSCON
,$2.i
,(uintptr_t)$1.cp
); }
271 ={ $$.i
= mn1
(CARAT
,$2.i
); }
275 j
= mn1
(S2FINAL
,-casecount
);
276 k
= mn2
(RCAT
,$1.i
,j
);
279 else $$.i
= mn2
(RCAT
,$1.i
,i
);
285 ={ $$.i
= mn0
(RNULLS
); }
287 /* XCU4: add ARRAY and POINTER */
301 int lex_startcond_lookupval
;
305 static int sectbegin
;
306 static CHR token
[TOKENSIZE
];
308 int ccs
; /* Current CodeSet. */
310 int exclusive_flag
; /* XCU4: exclusive start flag */
316 if
(sect
== DEFSECTION
) { /* definitions section */
318 if
(prev
== '\n'){ /* next char is at beginning of line */
324 /*LINTED: E_BAD_PTR_CAST_ALIGN*/
325 if
(scomp
(p
, (CHR
*)"%%")) {
329 warning
("invalid string following %%%% be ignored");
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");
338 i
= treesize
*(sizeof
(*name
)+sizeof
(*left
)+
339 sizeof
(*right
)+sizeof
(*nullstr
)+sizeof
(*parent
))+ALITTLEEXTRA
;
340 c
= (int)myalloc
(i
,1);
342 error("Too little core for parse tree");
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
));
359 if
((*(p
+2) == 'o') ||
362 error("Too late for %%pointer");
363 while
(*p
&& !iswspace
(*p
))
368 /* has overridden number of positions */
371 if
(maxpos
<=0)error("illegal position number");
373 if
(debug
) (void) printf
("positions (%%p) now %d\n",maxpos
);
375 if
(report
== 2)report
= 1;
377 case
'n': case
'N': /* has overridden number of states */
380 if
(nstates
<=0)error("illegal state number");
382 if
(debug
)(void) printf
( " no. states (%%n) now %d\n",nstates
);
384 if
(report
== 2)report
= 1;
386 case
'e': case
'E': /* has overridden number of tree nodes */
388 treesize
= siconv
(p
);
389 if
(treesize
<=0)error("illegal number of parse tree nodes");
391 if
(debug
) (void) printf
("treesize (%%e) now %d\n",treesize
);
393 if
(report
== 2)report
= 1;
398 if
(outsize
<=0)error("illegal size of output array");
399 if
(report
==2) report
=1;
403 if
((*(p
+2) == 'r') ||
406 error("Too late for %%array");
407 while
(*p
&& !iswspace
(*p
))
412 /* has overridden number of transitions */
415 if
(ntrans
<=0)error("illegal translation number");
417 if
(debug
)(void) printf
("N. trans (%%a) now %d\n",ntrans
);
419 if
(report
== 2)report
= 1;
421 case
'k': case
'K': /* overriden packed char classes */
425 if
(pchlen
<=0)error("illegal number of packed character class");
427 if
(debug
) (void) printf
( "Size classes (%%k) now %d\n",pchlen
);
429 /*LINTED: E_BAD_PTR_CAST_ALIGN*/
430 pchar
=pcptr
=(CHR
*)myalloc
(pchlen
, sizeof
(*pchar
));
431 if
(report
==2) report
=1;
433 case
't': case
'T': /* character set specifier */
436 Character table (%t) is supported only in ASCII compatibility mode.\n");
438 if
(ZCH
< NCH
) ZCH
= NCH
;
439 if
(ZCH
> 2*NCH
) error("ch table needs redeclaration");
441 for
(i
= 0; i
<ZCH
; i
++)
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
);
448 while
(digit
(*p
)) p
++;
449 if
(!iswspace
(*p
)) error("bad translation format");
450 while
(iswspace
(*p
)) p
++;
454 if
(ctable
[(unsigned)c
]){
456 warning
("Character '%wc' used twice",c
);
459 error("Chararter %o used twice",c
);
461 else ctable
[(unsigned)c
] = n
;
467 char chused
[2*NCH
]; int kr
;
472 for
(kr
=i
=1; i
<NCH
; i
++)
475 while
(chused
[kr
] == 0)
488 error("Too late for language specifier");
493 while
(getl
(p
) && scomp
(p
, L_PctCbr
) != 0)
494 if
(p
[0]=='/' && p
[1]=='*')
497 (void) fprintf
(fout
,WSFMT
("%ws\n"),p
);
498 if
(p
[0] == '%') continue
;
499 if
(*p
) error("EOF before %%%%");
500 else
error("EOF before %%}");
503 case
'x': case
'X': /* XCU4: exclusive start conditions */
507 case
's': case
'S': /* start conditions */
512 while
(*p
&& !iswspace
(*p
) && ((*p
) != (wchar_t)',')) p
++;
515 while
(*p
&& (iswspace
(*p
) ||
((*p
) == (wchar_t)','))) p
++;
517 while
(*p
&& !iswspace
(*p
) && ((*p
) != (wchar_t)',')) {
519 error("None-ASCII characters in start condition.");
524 if
(*t
== 0) continue
;
526 if
(!ratfor
)(void) fprintf
(fout
,"# ");
527 (void) fprintf
(fout
,WSFMT
("define %ws %d\n"),t
,i
);
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");
541 error("Invalid request %s",p
);
543 } /* end of switch after seeing '%' */
545 case
' ': case
'\t': /* must be code */
547 if
( p
[1]=='/' && p
[2]=='*' ) cpycom
(p
);
548 else
(void) fprintf
(fout
, WSFMT
("%ws\n"),p
);
550 case
'/': /* look for comments */
552 if
((*(p
+1))=='*') cpycom
(p
);
554 default
: /* definition */
555 while
(*p
&& !iswspace
(*p
)) p
++;
561 yylval.cp
= (CHR
*)buf
;
563 warning
("Substitution strings may not begin with digits");
564 return
(freturn
(STR
));
566 } else
{ /* still sect 1, but prev != '\n' */
568 while
(*p
&& iswspace
(*p
)) p
++;
570 warning
("No translation given - null string assumed");
572 yylval.cp
= (CHR
*)token
;
574 return
(freturn
(STR
));
577 error("unexpected EOF before %%%%");
578 /* end of section one processing */
579 } else if
(sect
== RULESECTION
){ /* rules and actions */
582 static int first_test
=TRUE
, first_value
;
583 static int reverse
=FALSE
;
586 if
(n_error
)error_tail
();
589 if
(prev
== '\n') continue
;
594 if
(prev
== '\n') copy_line
= TRUE
;
595 if
(sectbegin
== TRUE
){
598 /*LINTED: E_EQUALITY_NOT_ASSIGNMENT*/
599 while
((c
=gch
()) && c
!= '\n');
602 if
(!funcflag
)phead2
();
604 if
(ratfor
)(void) fprintf
(fout
,"%d\n",30000+casecount
);
605 else
(void) fprintf
(fout
,"case %d:\n",casecount
);
607 if
(ratfor
)(void) fprintf
(fout
,"goto 30997\n");
608 else
(void) fprintf
(fout
,"break;\n");
610 /*LINTED: E_EQUALITY_NOT_ASSIGNMENT*/
611 while
((c
=gch
()) && c
!= '\n') {
617 if
((c
=gch
()) == '/') goto w_loop
;
620 error("EOF inside comment");
622 warning
("undefined string");
624 error("illegal extra \"}\"");
627 /* while ((c=gch())== ' ' || c == '\t') ; */
628 /* if (!space(c)) error("undefined action string"); */
629 if
(peek
== ' ' || peek
== '\t' || sectbegin
== TRUE
){
632 error("executable statements should occur right after %%%%");
639 if
(prev
!= '\n') goto character
;
640 if
(peek
== '{'){ /* included code */
642 while
(!eof
&& getl
(buf
) && scomp
(L_PctCbr
,buf
)!=0)
643 if
(buf
[0]=='/' && buf
[1]=='*')
646 (void) fprintf
(fout
,WSFMT
("%ws\n"),buf
);
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
++);
665 if
(peek
== '\n' || peek
== ' ' || peek
== '\t' || peek
== '|' || peek
== '/'){
671 if
(peekon
&& (prev
== '}')){
675 if
(prev
!= '\n' && scon
!= TRUE
) goto character
;
676 /* valid only at line begin */
685 error("illegal operator -- %c",c
);
700 case
'{': /* either iteration or definition */
701 if
(digit
(c
=gch
())){ /* iteration */
703 if
(prev
=='{') first_test
= TRUE
;
711 yylval.i
= siconv
(token
);
714 first_value
= yylval.i
;
716 if
(first_value
>yylval.i
)warning
("the values between braces are reversed");
722 else
{ /* definition */
727 error("definition too long");
731 i
= lookup
(token
,def
);
733 error("definition %ws not found",token
);
735 munput
('s',(CHR
*)(subs
[i
]));
740 case
'<': /* start condition ? */
741 if
(prev
!= '\n') /* not at line begin, not start */
746 if
(!isascii
(c
= gch
()))
747 error("Non-ASCII characters in start condition.");
748 while
(c
!= ',' && c
&& c
!= '>'){
751 error("string name too long");
752 if
(!isascii
(c
= gch
()))
753 error("None-ASCII characters in start condition.");
758 i
= lookup
(token
,sname
);
759 lex_startcond_lookupval
= i
;
763 error("undefined start condition %ws",token
);
768 } while
(c
&& c
!= '>');
770 /* check if previous value re-usable */
771 for
(xp
=slist
; xp
<t
; )
779 /* re-use previous pointer to string */
783 if
(slptr
> slist
+STARTSIZE
) /* note not packed */
784 error("Too many start conditions used");
785 yylval.cp
= (CHR
*)t
;
787 /* XCU4: add XSCON */
789 if
(exclusive
[lex_startcond_lookupval
])
796 /*LINTED: E_EQUALITY_NOT_ASSIGNMENT*/
797 while
((c
=gch
()) && c
!= '"' && c
!= '\n'){
798 if
(c
== '\\') c
= usescape
(c
=gch
());
802 warning
("String too long");
809 warning
("Non-terminated string");
815 yylval.i
= (unsigned)token
[0];
819 yylval.cp
= (CHR
*)token
;
826 if
((c
= gch
()) == '^'){
832 while
(c
!= ']' && c
){
833 static int light
=TRUE
, ESCAPE
=FALSE
;
834 if
(c
== '-' && prev
== '^' && reverse
){
835 symbol
[(unsigned)c
] = 1;
840 c
= usescape
(c
=gch
());
843 if
(c
=='-' && !ESCAPE
&& prev
!='[' && peek
!=']'){
844 /* range specified */
854 Character range specified between different codesets.");
855 if
((unsigned)j
> (unsigned)k
) {
861 if
(!(('A'<=j
&& k
<='Z') ||
862 ('a'<=j
&& k
<='z') ||
864 warning
("Non-portable Character Class");
870 error("unmatched hyphen");
871 if
(symbol
[(unsigned)c
])warning
("\"%c\" redefined inside brackets",c
);
872 else symbol
[(unsigned)c
] = 1;
878 token
[i
++] = c
; /* Remember whatever.*/
884 /* try to pack ccl's */
888 while
(ccp
< ccptr
&& scomp
(token
, ccp
) != 0) ccp
++;
889 if
(ccp
< ccptr
) { /* found in ccl */
891 } else
{ /* not in ccl, add it */
894 ccptr
+= slength
(token
) + 1;
895 if
(ccptr
>= ccl
+CCLSIZE
)
896 error("Too many large character classes");
900 c
= usescape
(c
=gch
());
903 if
(iter
){ /* second part of an iteration */
905 if
('0' <= c
&& c
<= '9')
911 yylval.cp
= (CHR
*)token
;
914 remch
(token
[i
++] = gch
());
916 warning
("string too long");
921 if
(peek
== '?' || peek
== '*' || peek
== '+')
922 munput
('c',&token
[--i
]);
925 yylval.i
= (unsigned)(token
[0]);
931 yylval.i
= (unsigned)c
;
937 if
((x
== SCON
) ||
(x
== XSCON
))
949 (void) fprintf
(fout
,"\n/*this comes from section three - debug */\n");
952 if
(getl
(buf
) && !eof
) {
953 if
(sargv
[optind
] == NULL
)
954 (void) fprintf
(fout
, "\n# line %d\n", yyline
-1);
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
);
970 (void) printf
("now return ");
971 if
((unsigned)i
< NCH
) allprint
(i
);
972 else
(void) printf
("%d",i
);
973 (void) printf
(" yylval = ");
975 case STR
: case CCL
: case NCCL
:
982 (void) printf
("%d",yylval.i
);
985 (void) putchar
('\n');