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.
46 #define WSFMT(_fmt) _fmt
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
62 * XCU4: lower the precedence of $ and ^ to less than the or operator
67 %left CHAR CCL NCCL
'(' '.' STR NULLS
75 #define YYSTYPE union _yystype_
81 int peekon
= 0; /* need this to check if "^" came in a definition section */
90 static wchar_t L_PctUpT
[]= {'%', 'T', 0};
91 static wchar_t L_PctLoT
[]= {'%', 't', 0};
92 static wchar_t L_PctCbr
[]= {'%', '}', 0};
97 if
(debug
) sect2dump
();
101 lexinput: defns delim prods end
104 if
(!funcflag
)phead2
();
117 error("Illegal definition");
125 dp
+= slength
($2.cp
) + 1;
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 */
140 if
(sect
== DEFSECTION
&& debug
) sect1dump
();
146 ={ $$.i
= mn2
(RNEWE
,$1.i
,$2.i
);
154 i
= mn1
(S1FINAL
,casecount
);
155 else i
= mn1
(FINAL
,casecount
);
156 $$.i
= mn2
(RCAT
,$1.i
,i
);
158 if
((++casecount
)>NACTIONS
)
159 error("Too many (>%d) pattern-action rules.", NACTIONS
);
164 if
(debug
) sect2dump
();
169 error("Illegal rule");
174 ={ $$.i
= mn0
($1.i
); }
178 i
= mn0
((unsigned)(*p
++));
180 i
= mn2
(RSTR
,i
,(unsigned)(*p
++));
188 ={ $$.i
= mn1
(RCCL
,$1.i
); }
190 ={ $$.i
= mn1
(RNCCL
,$1.i
); }
192 ={ $$.i
= mn1
(STAR
,$1.i
); }
194 ={ $$.i
= mn1
(PLUS
,$1.i
); }
196 ={ $$.i
= mn1
(QUEST
,$1.i
); }
198 ={ $$.i
= mn2
(BAR
,$1.i
,$3.i
); }
200 ={ $$.i
= mn2
(RCAT
,$1.i
,$2.i
); }
203 j
= mn1
(S2FINAL
,-casecount
);
204 i
= mn2
(RCAT
,$1.i
,j
);
205 $$.i
= mn2
(DIV
,i
,$3.i
);
208 $$.i
= mn2
(RCAT
,$1.i
,$3.i
);
209 error("illegal extra slash");
213 | r ITER
',' ITER
'}'
220 error("iteration range must be positive");
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
++){
228 g
= mn2
(RCAT
,g
,dupl
($1.i
));
236 if
($2.i
< 0)error("can't have negative iteration");
237 else if
($2.i
== 0) $$.i
= mn0
(RNULLS
);
241 j
= mn2
(RCAT
,j
,dupl
($1.i
));
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 */
254 j
= mn2
(RCAT
,j
,dupl
($1.i
));
255 k
= mn1
(PLUS
,dupl
($1.i
));
256 $$.i
= mn2
(RCAT
,j
,k
);
260 ={ $$.i
= mn2
(RSCON
,$2.i
,(uintptr_t)$1.cp
); }
262 /* XCU4: add XSCON */
264 ={ $$.i
= mn2
(RXSCON
,$2.i
,(uintptr_t)$1.cp
); }
266 ={ $$.i
= mn1
(CARAT
,$2.i
); }
270 j
= mn1
(S2FINAL
,-casecount
);
271 k
= mn2
(RCAT
,$1.i
,j
);
274 else $$.i
= mn2
(RCAT
,$1.i
,i
);
280 ={ $$.i
= mn0
(RNULLS
); }
282 /* XCU4: add ARRAY and POINTER */
296 int lex_startcond_lookupval
;
300 static int sectbegin
;
301 static CHR token
[TOKENSIZE
];
303 int ccs
; /* Current CodeSet. */
305 int exclusive_flag
; /* XCU4: exclusive start flag */
311 if
(sect
== DEFSECTION
) { /* definitions section */
313 if
(prev
== '\n'){ /* next char is at beginning of line */
319 /*LINTED: E_BAD_PTR_CAST_ALIGN*/
320 if
(scomp
(p
, (CHR
*)"%%")) {
324 warning
("invalid string following %%%% be ignored");
329 if
(!ratfor
)(void) fprintf
(fout
,"# ");
330 (void) fprintf
(fout
,"define YYNEWLINE %d\n",ctable
['\n']);
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");
337 i
= treesize
*(sizeof
(*name
)+sizeof
(*left
)+
338 sizeof
(*right
)+sizeof
(*nullstr
)+sizeof
(*parent
))+ALITTLEEXTRA
;
339 c
= (int)myalloc
(i
,1);
341 error("Too little core for parse tree");
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
));
358 if
((*(p
+2) == 'o') ||
361 error("Too late for %%pointer");
362 while
(*p
&& !iswspace
(*p
))
367 /* has overridden number of positions */
370 if
(maxpos
<=0)error("illegal position number");
372 if
(debug
) (void) printf
("positions (%%p) now %d\n",maxpos
);
374 if
(report
== 2)report
= 1;
376 case
'n': case
'N': /* has overridden number of states */
379 if
(nstates
<=0)error("illegal state number");
381 if
(debug
)(void) printf
( " no. states (%%n) now %d\n",nstates
);
383 if
(report
== 2)report
= 1;
385 case
'e': case
'E': /* has overridden number of tree nodes */
387 treesize
= siconv
(p
);
388 if
(treesize
<=0)error("illegal number of parse tree nodes");
390 if
(debug
) (void) printf
("treesize (%%e) now %d\n",treesize
);
392 if
(report
== 2)report
= 1;
397 if
(outsize
<=0)error("illegal size of output array");
398 if
(report
==2) report
=1;
402 if
((*(p
+2) == 'r') ||
405 error("Too late for %%array");
406 while
(*p
&& !iswspace
(*p
))
411 /* has overridden number of transitions */
414 if
(ntrans
<=0)error("illegal translation number");
416 if
(debug
)(void) printf
("N. trans (%%a) now %d\n",ntrans
);
418 if
(report
== 2)report
= 1;
420 case
'k': case
'K': /* overriden packed char classes */
424 if
(pchlen
<=0)error("illegal number of packed character class");
426 if
(debug
) (void) printf
( "Size classes (%%k) now %d\n",pchlen
);
428 /*LINTED: E_BAD_PTR_CAST_ALIGN*/
429 pchar
=pcptr
=(CHR
*)myalloc
(pchlen
, sizeof
(*pchar
));
430 if
(report
==2) report
=1;
432 case
't': case
'T': /* character set specifier */
435 Character table (%t) is supported only in ASCII compatibility mode.\n");
437 if
(ZCH
< NCH
) ZCH
= NCH
;
438 if
(ZCH
> 2*NCH
) error("ch table needs redeclaration");
440 for
(i
= 0; i
<ZCH
; i
++)
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
);
447 while
(digit
(*p
)) p
++;
448 if
(!iswspace
(*p
)) error("bad translation format");
449 while
(iswspace
(*p
)) p
++;
453 if
(ctable
[(unsigned)c
]){
455 warning
("Character '%wc' used twice",c
);
458 error("Chararter %o used twice",c
);
460 else ctable
[(unsigned)c
] = n
;
466 char chused
[2*NCH
]; int kr
;
471 for
(kr
=i
=1; i
<NCH
; i
++)
474 while
(chused
[kr
] == 0)
487 error("Too late for language specifier");
492 while
(getl
(p
) && scomp
(p
, L_PctCbr
) != 0)
493 if
(p
[0]=='/' && p
[1]=='*')
496 (void) fprintf
(fout
,WSFMT
("%ws\n"),p
);
497 if
(p
[0] == '%') continue
;
498 if
(*p
) error("EOF before %%%%");
499 else
error("EOF before %%}");
502 case
'x': case
'X': /* XCU4: exclusive start conditions */
506 case
's': case
'S': /* start conditions */
511 while
(*p
&& !iswspace
(*p
) && ((*p
) != (wchar_t)',')) p
++;
514 while
(*p
&& (iswspace
(*p
) ||
((*p
) == (wchar_t)','))) p
++;
516 while
(*p
&& !iswspace
(*p
) && ((*p
) != (wchar_t)',')) {
518 error("None-ASCII characters in start condition.");
523 if
(*t
== 0) continue
;
525 if
(!ratfor
)(void) fprintf
(fout
,"# ");
526 (void) fprintf
(fout
,WSFMT
("define %ws %d\n"),t
,i
);
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");
540 error("Invalid request %s",p
);
542 } /* end of switch after seeing '%' */
544 case
' ': case
'\t': /* must be code */
546 if
( p
[1]=='/' && p
[2]=='*' ) cpycom
(p
);
547 else
(void) fprintf
(fout
, WSFMT
("%ws\n"),p
);
549 case
'/': /* look for comments */
551 if
((*(p
+1))=='*') cpycom
(p
);
553 default
: /* definition */
554 while
(*p
&& !iswspace
(*p
)) p
++;
560 yylval.cp
= (CHR
*)buf
;
562 warning
("Substitution strings may not begin with digits");
563 return
(freturn
(STR
));
565 } else
{ /* still sect 1, but prev != '\n' */
567 while
(*p
&& iswspace
(*p
)) p
++;
569 warning
("No translation given - null string assumed");
571 yylval.cp
= (CHR
*)token
;
573 return
(freturn
(STR
));
576 error("unexpected EOF before %%%%");
577 /* end of section one processing */
578 } else if
(sect
== RULESECTION
){ /* rules and actions */
581 static int first_test
=TRUE
, first_value
;
582 static int reverse
=FALSE
;
585 if
(n_error
)error_tail
();
588 if
(prev
== '\n') continue
;
593 if
(prev
== '\n') copy_line
= TRUE
;
594 if
(sectbegin
== TRUE
){
597 /*LINTED: E_EQUALITY_NOT_ASSIGNMENT*/
598 while
((c
=gch
()) && c
!= '\n');
601 if
(!funcflag
)phead2
();
603 if
(ratfor
)(void) fprintf
(fout
,"%d\n",30000+casecount
);
604 else
(void) fprintf
(fout
,"case %d:\n",casecount
);
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') {
616 if
((c
=gch
()) == '/') goto w_loop
;
619 error("EOF inside comment");
621 warning
("undefined string");
623 error("illegal extra \"}\"");
626 /* while ((c=gch())== ' ' || c == '\t') ; */
627 /* if (!space(c)) error("undefined action string"); */
628 if
(peek
== ' ' || peek
== '\t' || sectbegin
== TRUE
){
631 error("executable statements should occur right after %%%%");
638 if
(prev
!= '\n') goto character
;
639 if
(peek
== '{'){ /* included code */
641 while
(!eof
&& getl
(buf
) && scomp
(L_PctCbr
,buf
)!=0)
642 if
(buf
[0]=='/' && buf
[1]=='*')
645 (void) fprintf
(fout
,WSFMT
("%ws\n"),buf
);
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
++);
664 if
(peek
== '\n' || peek
== ' ' || peek
== '\t' || peek
== '|' || peek
== '/'){
670 if
(peekon
&& (prev
== '}')){
674 if
(prev
!= '\n' && scon
!= TRUE
) goto character
;
675 /* valid only at line begin */
684 error("illegal operator -- %c",c
);
699 case
'{': /* either iteration or definition */
700 if
(digit
(c
=gch
())){ /* iteration */
702 if
(prev
=='{') first_test
= TRUE
;
710 yylval.i
= siconv
(token
);
713 first_value
= yylval.i
;
715 if
(first_value
>yylval.i
)warning
("the values between braces are reversed");
721 else
{ /* definition */
726 error("definition too long");
730 i
= lookup
(token
,def
);
732 error("definition %ws not found",token
);
734 munput
('s',(CHR
*)(subs
[i
]));
739 case
'<': /* start condition ? */
740 if
(prev
!= '\n') /* not at line begin, not start */
745 if
(!isascii
(c
= gch
()))
746 error("Non-ASCII characters in start condition.");
747 while
(c
!= ',' && c
&& c
!= '>'){
750 error("string name too long");
751 if
(!isascii
(c
= gch
()))
752 error("None-ASCII characters in start condition.");
757 i
= lookup
(token
,sname
);
758 lex_startcond_lookupval
= i
;
762 error("undefined start condition %ws",token
);
767 } while
(c
&& c
!= '>');
769 /* check if previous value re-usable */
770 for
(xp
=slist
; xp
<t
; )
778 /* re-use previous pointer to string */
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
])
795 /*LINTED: E_EQUALITY_NOT_ASSIGNMENT*/
796 while
((c
=gch
()) && c
!= '"' && c
!= '\n'){
797 if
(c
== '\\') c
= usescape
(c
=gch
());
801 warning
("String too long");
808 warning
("Non-terminated string");
814 yylval.i
= (unsigned)token
[0];
818 yylval.cp
= (CHR
*)token
;
825 if
((c
= gch
()) == '^'){
831 while
(c
!= ']' && c
){
832 static int light
=TRUE
, ESCAPE
=FALSE
;
833 if
(c
== '-' && prev
== '^' && reverse
){
834 symbol
[(unsigned)c
] = 1;
839 c
= usescape
(c
=gch
());
842 if
(c
=='-' && !ESCAPE
&& prev
!='[' && peek
!=']'){
843 /* range specified */
853 Character range specified between different codesets.");
854 if
((unsigned)j
> (unsigned)k
) {
860 if
(!(('A'<=j
&& k
<='Z') ||
861 ('a'<=j
&& k
<='z') ||
863 warning
("Non-portable Character Class");
869 error("unmatched hyphen");
870 if
(symbol
[(unsigned)c
])warning
("\"%c\" redefined inside brackets",c
);
871 else symbol
[(unsigned)c
] = 1;
877 token
[i
++] = c
; /* Remember whatever.*/
883 /* try to pack ccl's */
887 while
(ccp
< ccptr
&& scomp
(token
, ccp
) != 0) ccp
++;
888 if
(ccp
< ccptr
) { /* found in ccl */
890 } else
{ /* not in ccl, add it */
893 ccptr
+= slength
(token
) + 1;
894 if
(ccptr
>= ccl
+CCLSIZE
)
895 error("Too many large character classes");
899 c
= usescape
(c
=gch
());
902 if
(iter
){ /* second part of an iteration */
904 if
('0' <= c
&& c
<= '9')
910 yylval.cp
= (CHR
*)token
;
913 remch
(token
[i
++] = gch
());
915 warning
("string too long");
920 if
(peek
== '?' || peek
== '*' || peek
== '+')
921 munput
('c',&token
[--i
]);
924 yylval.i
= (unsigned)(token
[0]);
930 yylval.i
= (unsigned)c
;
936 if
((x
== SCON
) ||
(x
== XSCON
))
948 (void) fprintf
(fout
,"\n/*this comes from section three - debug */\n");
951 if
(getl
(buf
) && !eof
) {
952 if
(sargv
[optind
] == NULL
)
953 (void) fprintf
(fout
, "\n# line %d\n", yyline
-1);
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
);
969 (void) printf
("now return ");
970 if
((unsigned)i
< NCH
) allprint
(i
);
971 else
(void) printf
("%d",i
);
972 (void) printf
(" yylval = ");
974 case STR
: case CCL
: case NCCL
:
981 (void) printf
("%d",yylval.i
);
984 (void) putchar
('\n');