1 /* parse.y - parser for flex input */
3 %token CHAR NUMBER SECTEND SCDECL XSCDECL NAME PREVCCL EOF_OP
4 %token OPTION_OP OPT_OUTFILE OPT_PREFIX OPT_YYCLASS
6 %token CCE_ALNUM CCE_ALPHA CCE_BLANK CCE_CNTRL CCE_DIGIT CCE_GRAPH
7 %token CCE_LOWER CCE_PRINT CCE_PUNCT CCE_SPACE CCE_UPPER CCE_XDIGIT
11 * Copyright (c) 1990 The Regents of the University of California.
12 * All rights reserved.
14 * This code is derived from software contributed to Berkeley by
17 * The United States Government has rights in this work pursuant
18 * to contract no. DE-AC03-76SF00098 between the United States
19 * Department of Energy and the University of California.
21 * Redistribution and use in source and binary forms are permitted provided
22 * that: (1) source distributions retain this entire copyright notice and
23 * comment, and (2) distributions including binaries display the following
24 * acknowledgement: ``This product includes software developed by the
25 * University of California, Berkeley and its contributors'' in the
26 * documentation or other materials provided with the distribution and in
27 * all advertising materials mentioning features or use of this software.
28 * Neither the name of the University nor the names of its contributors may
29 * be used to endorse or promote products derived from this software without
30 * specific prior written permission.
31 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
32 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
33 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
36 /* $Header: /home/daffy/u0/vern/flex/RCS/parse.y,v 2.28 95/04/21 11:51:51 vern Exp $ */
37 /* $FreeBSD: src/usr.bin/lex/parse.y,v 1.3 1999/10/27 07:56:46 obrien Exp $ */
38 /* $DragonFly: src/usr.bin/lex/parse.y,v 1.3 2005/02/20 17:34:11 asmodai Exp $ */
41 /* Some versions of bison are broken in that they use alloca() but don't
42 * declare it properly. The following is the patented (just kidding!)
43 * #ifdef chud to fix the problem, courtesy of Francois Pinard.
48 /* The remainder of the alloca() cruft has to come after including flexdef.h,
49 * so HAVE_ALLOCA_H is (possibly) defined.
54 # define alloca __builtin_alloca
65 /* Bletch, ^^^^ that was ugly! */
68 int pat
, scnum
, eps
, headcnt
, trailcnt
, anyccl
, lastchar
, i
, rulelen
;
69 int trlcontxt
, xcluflg
, currccl
, cclsorted
, varlength
, variable_trail_rule
;
74 static int madeany
= false
; /* whether we've made the '.' character class */
75 int previous_continued_action
; /* whether the previous rule's action was '|' */
77 /* Expand a POSIX character class expression. */
78 #define CCL_EXPR(func) \
81 for
( c
= 0; c
< csize
; ++c
) \
82 if
( isascii
(c
) && func
(c
) ) \
83 ccladd
( currccl
, c
); \
86 /* While POSIX defines isblank(), it's not ANSI C. */
87 #define IS_BLANK(c) ((c) == ' ' || (c) == '\t')
89 /* On some over-ambitious machines, such as DEC Alpha's, the default
90 * token type is "long" instead of "int"; this leads to problems with
91 * declaring yylval in flexdef.h. But so far, all the yacc's I've seen
92 * wrap their definitions of YYSTYPE with "#ifndef YYSTYPE"'s, so the
93 * following should ensure that the default token type is "int".
100 goal
: initlex sect1 sect1end sect2 initforrule
101 { /* add default rule */
107 def_rule
= mkstate
( -pat
);
109 /* Remember the number of the default rule so we
110 * don't generate "can't match" warnings for it.
112 default_rule
= num_rules
;
114 finish_rule
( def_rule
, false
, 0, 0 );
116 for
( i
= 1; i
<= lastsc
; ++i
)
117 scset
[i
] = mkbranch
( scset
[i
], def_rule
);
121 "YY_FATAL_ERROR( \"flex scanner jammed\" )" );
123 add_action
( "ECHO" );
125 add_action
( ";\n\tYY_BREAK\n" );
130 { /* initialize for processing rules */
132 /* Create default DFA start condition. */
133 scinstal
( "INITIAL", false
);
137 sect1
: sect1 startconddecl namelist1
141 { synerr
( "unknown error processing section 1" ); }
147 scon_stk
= allocate_integer_array
( lastsc
+ 1 );
152 startconddecl
: SCDECL
159 namelist1
: namelist1 NAME
160 { scinstal
( nmstr
, xcluflg
); }
163 { scinstal
( nmstr
, xcluflg
); }
166 { synerr
( "bad start condition list" ); }
169 options
: OPTION_OP optionlist
172 optionlist
: optionlist option
176 option
: OPT_OUTFILE
'=' NAME
178 outfilename
= copy_string
( nmstr
);
181 | OPT_PREFIX
'=' NAME
182 { prefix
= copy_string
( nmstr
); }
183 | OPT_YYCLASS
'=' NAME
184 { yyclass
= copy_string
( nmstr
); }
187 sect2
: sect2 scon initforrule flexrule
'\n'
188 { scon_stk_ptr
= $2; }
189 | sect2 scon
'{' sect2
'}'
190 { scon_stk_ptr
= $2; }
196 /* Initialize for a parse of one rule. */
197 trlcontxt
= variable_trail_rule
= varlength
= false
;
198 trailcnt
= headcnt
= rulelen
= 0;
199 current_state_type
= STATE_NORMAL
;
200 previous_continued_action
= continued_action
;
210 finish_rule
( pat
, variable_trail_rule
,
213 if
( scon_stk_ptr
> 0 )
215 for
( i
= 1; i
<= scon_stk_ptr
; ++i
)
217 mkbranch
( scbol
[scon_stk
[i
]],
223 /* Add to all non-exclusive start conditions,
224 * including the default (0) start condition.
227 for
( i
= 1; i
<= lastsc
; ++i
)
229 scbol
[i
] = mkbranch
( scbol
[i
],
237 if
( performance_report
> 1 )
239 "'^' operator results in sub-optimal performance" );
246 finish_rule
( pat
, variable_trail_rule
,
249 if
( scon_stk_ptr
> 0 )
251 for
( i
= 1; i
<= scon_stk_ptr
; ++i
)
253 mkbranch
( scset
[scon_stk
[i
]],
259 for
( i
= 1; i
<= lastsc
; ++i
)
269 if
( scon_stk_ptr
> 0 )
274 /* This EOF applies to all start conditions
275 * which don't already have EOF actions.
277 for
( i
= 1; i
<= lastsc
; ++i
)
279 scon_stk
[++scon_stk_ptr
] = i
;
281 if
( scon_stk_ptr
== 0 )
283 "all start conditions already have <<EOF>> rules" );
291 { synerr
( "unrecognized rule" ); }
295 { $$
= scon_stk_ptr
; }
298 scon
: '<' scon_stk_ptr namelist2
'>'
305 for
( i
= 1; i
<= lastsc
; ++i
)
309 for
( j
= 1; j
<= scon_stk_ptr
; ++j
)
310 if
( scon_stk
[j
] == i
)
313 if
( j
> scon_stk_ptr
)
314 scon_stk
[++scon_stk_ptr
] = i
;
319 { $$
= scon_stk_ptr
; }
322 namelist2
: namelist2
',' sconname
327 { synerr
( "bad start condition list" ); }
332 if
( (scnum
= sclookup
( nmstr
)) == 0 )
333 format_pinpoint_message
(
334 "undeclared start condition %s",
338 for
( i
= 1; i
<= scon_stk_ptr
; ++i
)
339 if
( scon_stk
[i
] == scnum
)
342 "<%s> specified twice",
347 if
( i
> scon_stk_ptr
)
348 scon_stk
[++scon_stk_ptr
] = scnum
;
355 if
( transchar
[lastst
[$2]] != SYM_EPSILON
)
356 /* Provide final transition \now/ so it
357 * will be marked as a trailing context
360 $2 = link_machines
( $2,
361 mkstate
( SYM_EPSILON
) );
363 mark_beginning_as_normal
( $2 );
364 current_state_type
= STATE_NORMAL
;
366 if
( previous_continued_action
)
368 /* We need to treat this as variable trailing
369 * context so that the backup does not happen
370 * in the action but before the action switch
371 * statement. If the backup happens in the
372 * action, then the rules "falling into" this
373 * one's action will *also* do the backup,
376 if
( ! varlength || headcnt
!= 0 )
378 "trailing context made variable due to preceding '|' action" );
380 /* Mark as variable. */
385 if
( lex_compat ||
(varlength
&& headcnt
== 0) )
386 { /* variable trailing context rule */
387 /* Mark the first part of the rule as the
388 * accepting "head" part of a trailing
391 * By the way, we didn't do this at the
392 * beginning of this production because back
393 * then current_state_type was set up for a
394 * trail rule, and add_accept() can create
398 num_rules | YY_TRAILING_HEAD_MASK
);
399 variable_trail_rule
= true
;
405 $$
= link_machines
( $1, $2 );
409 { synerr
( "trailing context used twice" ); }
418 current_state_type
= STATE_TRAILING_CONTEXT
;
422 synerr
( "trailing context used twice" );
423 $$
= mkstate
( SYM_EPSILON
);
426 else if
( previous_continued_action
)
428 /* See the comment in the rule for "re2 re"
432 "trailing context made variable due to preceding '|' action" );
437 if
( lex_compat || varlength
)
439 /* Again, see the comment in the rule for
443 num_rules | YY_TRAILING_HEAD_MASK
);
444 variable_trail_rule
= true
;
449 eps
= mkstate
( SYM_EPSILON
);
450 $$
= link_machines
( $1,
451 link_machines
( eps
, mkstate
( '\n' ) ) );
460 if
( lex_compat ||
(varlength
&& headcnt
== 0) )
461 /* Both head and trail are
464 variable_trail_rule
= true
;
485 /* This rule is written separately so the
486 * reduction will occur before the trailing
491 synerr
( "trailing context used twice" );
496 /* We hope the trailing context is
505 current_state_type
= STATE_TRAILING_CONTEXT
;
510 series
: series singleton
512 /* This is where concatenation of adjacent patterns
515 $$
= link_machines
( $1, $2 );
522 singleton
: singleton
'*'
541 | singleton
'{' NUMBER
',' NUMBER
'}'
545 if
( $3 > $5 ||
$3 < 0 )
547 synerr
( "bad iteration values" );
557 "bad iteration values" );
562 mkrep
( $1, 1, $5 ) );
565 $$
= mkrep
( $1, $3, $5 );
569 | singleton
'{' NUMBER
',' '}'
575 synerr
( "iteration value must be positive" );
580 $$
= mkrep
( $1, $3, INFINITY
);
583 | singleton
'{' NUMBER
'}'
585 /* The singleton could be something like "(foo)",
586 * in which case we have no idea what its length
587 * is, so we punt here.
593 synerr
( "iteration value must be positive" );
598 $$
= link_machines
( $1,
599 copysingl
( $1, $3 - 1 ) );
606 /* Create the '.' character class. */
608 ccladd
( anyccl
, '\n' );
612 mkeccl
( ccltbl
+ cclmap
[anyccl
],
613 ccllen
[anyccl
], nextecm
,
614 ecgroup
, csize
, csize
);
621 $$
= mkstate
( -anyccl
);
627 /* Sort characters for fast searching. We
628 * use a shell sort since this list could
631 cshell
( ccltbl
+ cclmap
[$1], ccllen
[$1], true
);
634 mkeccl
( ccltbl
+ cclmap
[$1], ccllen
[$1],
635 nextecm
, ecgroup
, csize
, csize
);
659 if
( caseins
&& $1 >= 'A' && $1 <= 'Z' )
666 fullccl
: '[' ccl
']'
676 ccl
: ccl CHAR
'-' CHAR
680 if
( $2 >= 'A' && $2 <= 'Z' )
682 if
( $4 >= 'A' && $4 <= 'Z' )
687 synerr
( "negative range in character class" );
691 for
( i
= $2; i
<= $4; ++i
)
694 /* Keep track if this ccl is staying in
695 * alphabetical order.
697 cclsorted
= cclsorted
&& ($2 > lastchar
);
706 if
( caseins
&& $2 >= 'A' && $2 <= 'Z' )
710 cclsorted
= cclsorted
&& ($2 > lastchar
);
717 /* Too hard to properly maintain cclsorted. */
726 currccl
= $$
= cclinit
();
730 ccl_expr: CCE_ALNUM
{ CCL_EXPR
(isalnum
) }
731 | CCE_ALPHA
{ CCL_EXPR
(isalpha
) }
732 | CCE_BLANK
{ CCL_EXPR
(IS_BLANK
) }
733 | CCE_CNTRL
{ CCL_EXPR
(iscntrl
) }
734 | CCE_DIGIT
{ CCL_EXPR
(isdigit
) }
735 | CCE_GRAPH
{ CCL_EXPR
(isgraph
) }
736 | CCE_LOWER
{ CCL_EXPR
(islower
) }
737 | CCE_PRINT
{ CCL_EXPR
(isprint
) }
738 | CCE_PUNCT
{ CCL_EXPR
(ispunct
) }
739 | CCE_SPACE
{ CCL_EXPR
(isspace
) }
746 | CCE_XDIGIT
{ CCL_EXPR
(isxdigit
) }
751 if
( caseins
&& $2 >= 'A' && $2 <= 'Z' )
756 $$
= link_machines
( $1, mkstate
( $2 ) );
760 { $$
= mkstate
( SYM_EPSILON
); }
766 /* build_eof_action - build the "<<EOF>>" action for the active start
770 void build_eof_action
()
773 char action_text
[MAXLINE
];
775 for
( i
= 1; i
<= scon_stk_ptr
; ++i
)
777 if
( sceof
[scon_stk
[i
]] )
778 format_pinpoint_message
(
779 "multiple <<EOF>> rules for start condition %s",
780 scname
[scon_stk
[i
]] );
784 sceof
[scon_stk
[i
]] = true
;
785 sprintf
( action_text
, "case YY_STATE_EOF(%s):\n",
786 scname
[scon_stk
[i
]] );
787 add_action
( action_text
);
791 line_directive_out
( (FILE *) 0, 1 );
793 /* This isn't a normal rule after all - don't count it as
794 * such, so we don't have any holes in the rule numbering
795 * (which make generating "rule can never match" warnings
803 /* format_synerr - write out formatted syntax error */
805 void format_synerr
( msg
, arg
)
808 char errmsg
[MAXLINE
];
810 (void) sprintf
( errmsg
, msg
, arg
);
815 /* synerr - report a syntax error */
821 pinpoint_message
( str
);
825 /* format_warn - write out formatted warning */
827 void format_warn
( msg
, arg
)
830 char warn_msg
[MAXLINE
];
832 (void) sprintf
( warn_msg
, msg
, arg
);
837 /* warn - report a warning, unless -w was given */
842 line_warning
( str
, linenum
);
845 /* format_pinpoint_message - write out a message formatted with one string,
846 * pinpointing its location
849 void format_pinpoint_message
( msg
, arg
)
852 char errmsg
[MAXLINE
];
854 (void) sprintf
( errmsg
, msg
, arg
);
855 pinpoint_message
( errmsg
);
859 /* pinpoint_message - write out a message, pinpointing its location */
861 void pinpoint_message
( str
)
864 line_pinpoint
( str
, linenum
);
868 /* line_warning - report a warning at a given line, unless -w was given */
870 void line_warning
( str
, line
)
874 char warning
[MAXLINE
];
878 sprintf
( warning
, "warning, %s", str
);
879 line_pinpoint
( warning
, line
);
884 /* line_pinpoint - write out a message, pinpointing it at the given line */
886 void line_pinpoint
( str
, line
)
890 fprintf
( stderr
, "\"%s\", line %d: %s\n", infilename
, line
, str
);
894 /* yyerror - eat up an error message from the parser;
895 * currently, messages are ignore