1*7e382390SJung-uk Kim /* parse.y - parser for flex input */
2*7e382390SJung-uk Kim
3*7e382390SJung-uk Kim %token CHAR NUMBER SECTEND SCDECL XSCDECL NAME PREVCCL EOF_OP
4*7e382390SJung-uk Kim %token TOK_OPTION TOK_OUTFILE TOK_PREFIX TOK_YYCLASS TOK_HEADER_FILE TOK_EXTRA_TYPE
5*7e382390SJung-uk Kim %token TOK_TABLES_FILE
6*7e382390SJung-uk Kim
7*7e382390SJung-uk Kim %token CCE_ALNUM CCE_ALPHA CCE_BLANK CCE_CNTRL CCE_DIGIT CCE_GRAPH
8*7e382390SJung-uk Kim %token CCE_LOWER CCE_PRINT CCE_PUNCT CCE_SPACE CCE_UPPER CCE_XDIGIT
9*7e382390SJung-uk Kim
10*7e382390SJung-uk Kim %token CCE_NEG_ALNUM CCE_NEG_ALPHA CCE_NEG_BLANK CCE_NEG_CNTRL CCE_NEG_DIGIT CCE_NEG_GRAPH
11*7e382390SJung-uk Kim %token CCE_NEG_LOWER CCE_NEG_PRINT CCE_NEG_PUNCT CCE_NEG_SPACE CCE_NEG_UPPER CCE_NEG_XDIGIT
12*7e382390SJung-uk Kim
13*7e382390SJung-uk Kim %left CCL_OP_DIFF CCL_OP_UNION
14*7e382390SJung-uk Kim
15*7e382390SJung-uk Kim /*
16*7e382390SJung-uk Kim *POSIX and AT&T lex place the
17*7e382390SJung-uk Kim * precedence of the repeat operator, {}, below that of concatenation.
18*7e382390SJung-uk Kim * Thus, ab{3} is ababab. Most other POSIX utilities use an Extended
19*7e382390SJung-uk Kim * Regular Expression (ERE) precedence that has the repeat operator
20*7e382390SJung-uk Kim * higher than concatenation. This causes ab{3} to yield abbb.
21*7e382390SJung-uk Kim *
22*7e382390SJung-uk Kim * In order to support the POSIX and AT&T precedence and the flex
23*7e382390SJung-uk Kim * precedence we define two token sets for the begin and end tokens of
24*7e382390SJung-uk Kim * the repeat operator, '{' and '}'. The lexical scanner chooses
25*7e382390SJung-uk Kim * which tokens to return based on whether posix_compat or lex_compat
26*7e382390SJung-uk Kim * are specified. Specifying either posix_compat or lex_compat will
27*7e382390SJung-uk Kim * cause flex to parse scanner files as per the AT&T and
28*7e382390SJung-uk Kim * POSIX-mandated behavior.
29*7e382390SJung-uk Kim */
30*7e382390SJung-uk Kim
31*7e382390SJung-uk Kim %token BEGIN_REPEAT_POSIX END_REPEAT_POSIX BEGIN_REPEAT_FLEX END_REPEAT_FLEX
32*7e382390SJung-uk Kim
33*7e382390SJung-uk Kim
34*7e382390SJung-uk Kim %{
35*7e382390SJung-uk Kim /* Copyright (c) 1990 The Regents of the University of California. */
36*7e382390SJung-uk Kim /* All rights reserved. */
37*7e382390SJung-uk Kim
38*7e382390SJung-uk Kim /* This code is derived from software contributed to Berkeley by */
39*7e382390SJung-uk Kim /* Vern Paxson. */
40*7e382390SJung-uk Kim
41*7e382390SJung-uk Kim /* The United States Government has rights in this work pursuant */
42*7e382390SJung-uk Kim /* to contract no. DE-AC03-76SF00098 between the United States */
43*7e382390SJung-uk Kim /* Department of Energy and the University of California. */
44*7e382390SJung-uk Kim
45*7e382390SJung-uk Kim /* This file is part of flex. */
46*7e382390SJung-uk Kim
47*7e382390SJung-uk Kim /* Redistribution and use in source and binary forms, with or without */
48*7e382390SJung-uk Kim /* modification, are permitted provided that the following conditions */
49*7e382390SJung-uk Kim /* are met: */
50*7e382390SJung-uk Kim
51*7e382390SJung-uk Kim /* 1. Redistributions of source code must retain the above copyright */
52*7e382390SJung-uk Kim /* notice, this list of conditions and the following disclaimer. */
53*7e382390SJung-uk Kim /* 2. Redistributions in binary form must reproduce the above copyright */
54*7e382390SJung-uk Kim /* notice, this list of conditions and the following disclaimer in the */
55*7e382390SJung-uk Kim /* documentation and/or other materials provided with the distribution. */
56*7e382390SJung-uk Kim
57*7e382390SJung-uk Kim /* Neither the name of the University nor the names of its contributors */
58*7e382390SJung-uk Kim /* may be used to endorse or promote products derived from this software */
59*7e382390SJung-uk Kim /* without specific prior written permission. */
60*7e382390SJung-uk Kim
61*7e382390SJung-uk Kim /* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
62*7e382390SJung-uk Kim /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
63*7e382390SJung-uk Kim /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
64*7e382390SJung-uk Kim /* PURPOSE. */
65*7e382390SJung-uk Kim
66*7e382390SJung-uk Kim #include "flexdef.h"
67*7e382390SJung-uk Kim #include "tables.h"
68*7e382390SJung-uk Kim
69*7e382390SJung-uk Kim int pat, scnum, eps, headcnt, trailcnt, lastchar, i, rulelen;
70*7e382390SJung-uk Kim int trlcontxt, xcluflg, currccl, cclsorted, varlength, variable_trail_rule;
71*7e382390SJung-uk Kim
72*7e382390SJung-uk Kim int *scon_stk;
73*7e382390SJung-uk Kim int scon_stk_ptr;
74*7e382390SJung-uk Kim
75*7e382390SJung-uk Kim static int madeany = false; /* whether we've made the '.' character class */
76*7e382390SJung-uk Kim static int ccldot, cclany;
77*7e382390SJung-uk Kim int previous_continued_action; /* whether the previous rule's action was '|' */
78*7e382390SJung-uk Kim
79*7e382390SJung-uk Kim #define format_warn3(fmt, a1, a2) \
80*7e382390SJung-uk Kim do{ \
81*7e382390SJung-uk Kim char fw3_msg[MAXLINE];\
82*7e382390SJung-uk Kim snprintf( fw3_msg, MAXLINE,(fmt), (a1), (a2) );\
83*7e382390SJung-uk Kim lwarn( fw3_msg );\
84*7e382390SJung-uk Kim }while(0)
85*7e382390SJung-uk Kim
86*7e382390SJung-uk Kim /* Expand a POSIX character class expression. */
87*7e382390SJung-uk Kim #define CCL_EXPR(func) \
88*7e382390SJung-uk Kim do{ \
89*7e382390SJung-uk Kim int c; \
90*7e382390SJung-uk Kim for ( c = 0; c < csize; ++c ) \
91*7e382390SJung-uk Kim if ( isascii(c) && func(c) ) \
92*7e382390SJung-uk Kim ccladd( currccl, c ); \
93*7e382390SJung-uk Kim }while(0)
94*7e382390SJung-uk Kim
95*7e382390SJung-uk Kim /* negated class */
96*7e382390SJung-uk Kim #define CCL_NEG_EXPR(func) \
97*7e382390SJung-uk Kim do{ \
98*7e382390SJung-uk Kim int c; \
99*7e382390SJung-uk Kim for ( c = 0; c < csize; ++c ) \
100*7e382390SJung-uk Kim if ( !func(c) ) \
101*7e382390SJung-uk Kim ccladd( currccl, c ); \
102*7e382390SJung-uk Kim }while(0)
103*7e382390SJung-uk Kim
104*7e382390SJung-uk Kim /* While POSIX defines isblank(), it's not ANSI C. */
105*7e382390SJung-uk Kim #define IS_BLANK(c) ((c) == ' ' || (c) == '\t')
106*7e382390SJung-uk Kim
107*7e382390SJung-uk Kim /* On some over-ambitious machines, such as DEC Alpha's, the default
108*7e382390SJung-uk Kim * token type is "long" instead of "int"; this leads to problems with
109*7e382390SJung-uk Kim * declaring yylval in flexdef.h. But so far, all the yacc's I've seen
110*7e382390SJung-uk Kim * wrap their definitions of YYSTYPE with "#ifndef YYSTYPE"'s, so the
111*7e382390SJung-uk Kim * following should ensure that the default token type is "int".
112*7e382390SJung-uk Kim */
113*7e382390SJung-uk Kim #define YYSTYPE int
114*7e382390SJung-uk Kim
115*7e382390SJung-uk Kim %}
116*7e382390SJung-uk Kim
117*7e382390SJung-uk Kim %%
118*7e382390SJung-uk Kim goal : initlex sect1 sect1end sect2 initforrule
119*7e382390SJung-uk Kim { /* add default rule */
120*7e382390SJung-uk Kim int def_rule;
121*7e382390SJung-uk Kim
122*7e382390SJung-uk Kim pat = cclinit();
123*7e382390SJung-uk Kim cclnegate( pat );
124*7e382390SJung-uk Kim
125*7e382390SJung-uk Kim def_rule = mkstate( -pat );
126*7e382390SJung-uk Kim
127*7e382390SJung-uk Kim /* Remember the number of the default rule so we
128*7e382390SJung-uk Kim * don't generate "can't match" warnings for it.
129*7e382390SJung-uk Kim */
130*7e382390SJung-uk Kim default_rule = num_rules;
131*7e382390SJung-uk Kim
132*7e382390SJung-uk Kim finish_rule( def_rule, false, 0, 0, 0);
133*7e382390SJung-uk Kim
134*7e382390SJung-uk Kim for ( i = 1; i <= lastsc; ++i )
135*7e382390SJung-uk Kim scset[i] = mkbranch( scset[i], def_rule );
136*7e382390SJung-uk Kim
137*7e382390SJung-uk Kim if ( spprdflt )
138*7e382390SJung-uk Kim add_action(
139*7e382390SJung-uk Kim "YY_FATAL_ERROR( \"flex scanner jammed\" )" );
140*7e382390SJung-uk Kim else
141*7e382390SJung-uk Kim add_action( "ECHO" );
142*7e382390SJung-uk Kim
143*7e382390SJung-uk Kim add_action( ";\n\tYY_BREAK]]\n" );
144*7e382390SJung-uk Kim }
145*7e382390SJung-uk Kim ;
146*7e382390SJung-uk Kim
147*7e382390SJung-uk Kim initlex :
148*7e382390SJung-uk Kim { /* initialize for processing rules */
149*7e382390SJung-uk Kim
150*7e382390SJung-uk Kim /* Create default DFA start condition. */
151*7e382390SJung-uk Kim scinstal( "INITIAL", false );
152*7e382390SJung-uk Kim }
153*7e382390SJung-uk Kim ;
154*7e382390SJung-uk Kim
155*7e382390SJung-uk Kim sect1 : sect1 startconddecl namelist1
156*7e382390SJung-uk Kim | sect1 options
157*7e382390SJung-uk Kim |
158*7e382390SJung-uk Kim | error
159*7e382390SJung-uk Kim { synerr( _("unknown error processing section 1") ); }
160*7e382390SJung-uk Kim ;
161*7e382390SJung-uk Kim
162*7e382390SJung-uk Kim sect1end : SECTEND
163*7e382390SJung-uk Kim {
164*7e382390SJung-uk Kim check_options();
165*7e382390SJung-uk Kim scon_stk = allocate_integer_array( lastsc + 1 );
166*7e382390SJung-uk Kim scon_stk_ptr = 0;
167*7e382390SJung-uk Kim }
168*7e382390SJung-uk Kim ;
169*7e382390SJung-uk Kim
170*7e382390SJung-uk Kim startconddecl : SCDECL
171*7e382390SJung-uk Kim { xcluflg = false; }
172*7e382390SJung-uk Kim
173*7e382390SJung-uk Kim | XSCDECL
174*7e382390SJung-uk Kim { xcluflg = true; }
175*7e382390SJung-uk Kim ;
176*7e382390SJung-uk Kim
177*7e382390SJung-uk Kim namelist1 : namelist1 NAME
178*7e382390SJung-uk Kim { scinstal( nmstr, xcluflg ); }
179*7e382390SJung-uk Kim
180*7e382390SJung-uk Kim | NAME
181*7e382390SJung-uk Kim { scinstal( nmstr, xcluflg ); }
182*7e382390SJung-uk Kim
183*7e382390SJung-uk Kim | error
184*7e382390SJung-uk Kim { synerr( _("bad start condition list") ); }
185*7e382390SJung-uk Kim ;
186*7e382390SJung-uk Kim
187*7e382390SJung-uk Kim options : TOK_OPTION optionlist
188*7e382390SJung-uk Kim ;
189*7e382390SJung-uk Kim
190*7e382390SJung-uk Kim optionlist : optionlist option
191*7e382390SJung-uk Kim |
192*7e382390SJung-uk Kim ;
193*7e382390SJung-uk Kim
194*7e382390SJung-uk Kim option : TOK_OUTFILE '=' NAME
195*7e382390SJung-uk Kim {
196*7e382390SJung-uk Kim outfilename = xstrdup(nmstr);
197*7e382390SJung-uk Kim did_outfilename = 1;
198*7e382390SJung-uk Kim }
199*7e382390SJung-uk Kim | TOK_EXTRA_TYPE '=' NAME
200*7e382390SJung-uk Kim { extra_type = xstrdup(nmstr); }
201*7e382390SJung-uk Kim | TOK_PREFIX '=' NAME
202*7e382390SJung-uk Kim { prefix = xstrdup(nmstr);
203*7e382390SJung-uk Kim if (strchr(prefix, '[') || strchr(prefix, ']'))
204*7e382390SJung-uk Kim flexerror(_("Prefix must not contain [ or ]")); }
205*7e382390SJung-uk Kim | TOK_YYCLASS '=' NAME
206*7e382390SJung-uk Kim { yyclass = xstrdup(nmstr); }
207*7e382390SJung-uk Kim | TOK_HEADER_FILE '=' NAME
208*7e382390SJung-uk Kim { headerfilename = xstrdup(nmstr); }
209*7e382390SJung-uk Kim | TOK_TABLES_FILE '=' NAME
210*7e382390SJung-uk Kim { tablesext = true; tablesfilename = xstrdup(nmstr); }
211*7e382390SJung-uk Kim ;
212*7e382390SJung-uk Kim
213*7e382390SJung-uk Kim sect2 : sect2 scon initforrule flexrule '\n'
214*7e382390SJung-uk Kim { scon_stk_ptr = $2; }
215*7e382390SJung-uk Kim | sect2 scon '{' sect2 '}'
216*7e382390SJung-uk Kim { scon_stk_ptr = $2; }
217*7e382390SJung-uk Kim |
218*7e382390SJung-uk Kim ;
219*7e382390SJung-uk Kim
220*7e382390SJung-uk Kim initforrule :
221*7e382390SJung-uk Kim {
222*7e382390SJung-uk Kim /* Initialize for a parse of one rule. */
223*7e382390SJung-uk Kim trlcontxt = variable_trail_rule = varlength = false;
224*7e382390SJung-uk Kim trailcnt = headcnt = rulelen = 0;
225*7e382390SJung-uk Kim current_state_type = STATE_NORMAL;
226*7e382390SJung-uk Kim previous_continued_action = continued_action;
227*7e382390SJung-uk Kim in_rule = true;
228*7e382390SJung-uk Kim
229*7e382390SJung-uk Kim new_rule();
230*7e382390SJung-uk Kim }
231*7e382390SJung-uk Kim ;
232*7e382390SJung-uk Kim
233*7e382390SJung-uk Kim flexrule : '^' rule
234*7e382390SJung-uk Kim {
235*7e382390SJung-uk Kim pat = $2;
236*7e382390SJung-uk Kim finish_rule( pat, variable_trail_rule,
237*7e382390SJung-uk Kim headcnt, trailcnt , previous_continued_action);
238*7e382390SJung-uk Kim
239*7e382390SJung-uk Kim if ( scon_stk_ptr > 0 )
240*7e382390SJung-uk Kim {
241*7e382390SJung-uk Kim for ( i = 1; i <= scon_stk_ptr; ++i )
242*7e382390SJung-uk Kim scbol[scon_stk[i]] =
243*7e382390SJung-uk Kim mkbranch( scbol[scon_stk[i]],
244*7e382390SJung-uk Kim pat );
245*7e382390SJung-uk Kim }
246*7e382390SJung-uk Kim
247*7e382390SJung-uk Kim else
248*7e382390SJung-uk Kim {
249*7e382390SJung-uk Kim /* Add to all non-exclusive start conditions,
250*7e382390SJung-uk Kim * including the default (0) start condition.
251*7e382390SJung-uk Kim */
252*7e382390SJung-uk Kim
253*7e382390SJung-uk Kim for ( i = 1; i <= lastsc; ++i )
254*7e382390SJung-uk Kim if ( ! scxclu[i] )
255*7e382390SJung-uk Kim scbol[i] = mkbranch( scbol[i],
256*7e382390SJung-uk Kim pat );
257*7e382390SJung-uk Kim }
258*7e382390SJung-uk Kim
259*7e382390SJung-uk Kim if ( ! bol_needed )
260*7e382390SJung-uk Kim {
261*7e382390SJung-uk Kim bol_needed = true;
262*7e382390SJung-uk Kim
263*7e382390SJung-uk Kim if ( performance_report > 1 )
264*7e382390SJung-uk Kim pinpoint_message(
265*7e382390SJung-uk Kim "'^' operator results in sub-optimal performance" );
266*7e382390SJung-uk Kim }
267*7e382390SJung-uk Kim }
268*7e382390SJung-uk Kim
269*7e382390SJung-uk Kim | rule
270*7e382390SJung-uk Kim {
271*7e382390SJung-uk Kim pat = $1;
272*7e382390SJung-uk Kim finish_rule( pat, variable_trail_rule,
273*7e382390SJung-uk Kim headcnt, trailcnt , previous_continued_action);
274*7e382390SJung-uk Kim
275*7e382390SJung-uk Kim if ( scon_stk_ptr > 0 )
276*7e382390SJung-uk Kim {
277*7e382390SJung-uk Kim for ( i = 1; i <= scon_stk_ptr; ++i )
278*7e382390SJung-uk Kim scset[scon_stk[i]] =
279*7e382390SJung-uk Kim mkbranch( scset[scon_stk[i]],
280*7e382390SJung-uk Kim pat );
281*7e382390SJung-uk Kim }
282*7e382390SJung-uk Kim
283*7e382390SJung-uk Kim else
284*7e382390SJung-uk Kim {
285*7e382390SJung-uk Kim for ( i = 1; i <= lastsc; ++i )
286*7e382390SJung-uk Kim if ( ! scxclu[i] )
287*7e382390SJung-uk Kim scset[i] =
288*7e382390SJung-uk Kim mkbranch( scset[i],
289*7e382390SJung-uk Kim pat );
290*7e382390SJung-uk Kim }
291*7e382390SJung-uk Kim }
292*7e382390SJung-uk Kim
293*7e382390SJung-uk Kim | EOF_OP
294*7e382390SJung-uk Kim {
295*7e382390SJung-uk Kim if ( scon_stk_ptr > 0 )
296*7e382390SJung-uk Kim build_eof_action();
297*7e382390SJung-uk Kim
298*7e382390SJung-uk Kim else
299*7e382390SJung-uk Kim {
300*7e382390SJung-uk Kim /* This EOF applies to all start conditions
301*7e382390SJung-uk Kim * which don't already have EOF actions.
302*7e382390SJung-uk Kim */
303*7e382390SJung-uk Kim for ( i = 1; i <= lastsc; ++i )
304*7e382390SJung-uk Kim if ( ! sceof[i] )
305*7e382390SJung-uk Kim scon_stk[++scon_stk_ptr] = i;
306*7e382390SJung-uk Kim
307*7e382390SJung-uk Kim if ( scon_stk_ptr == 0 )
308*7e382390SJung-uk Kim lwarn(
309*7e382390SJung-uk Kim "all start conditions already have <<EOF>> rules" );
310*7e382390SJung-uk Kim
311*7e382390SJung-uk Kim else
312*7e382390SJung-uk Kim build_eof_action();
313*7e382390SJung-uk Kim }
314*7e382390SJung-uk Kim }
315*7e382390SJung-uk Kim
316*7e382390SJung-uk Kim | error
317*7e382390SJung-uk Kim { synerr( _("unrecognized rule") ); }
318*7e382390SJung-uk Kim ;
319*7e382390SJung-uk Kim
320*7e382390SJung-uk Kim scon_stk_ptr :
321*7e382390SJung-uk Kim { $$ = scon_stk_ptr; }
322*7e382390SJung-uk Kim ;
323*7e382390SJung-uk Kim
324*7e382390SJung-uk Kim scon : '<' scon_stk_ptr namelist2 '>'
325*7e382390SJung-uk Kim { $$ = $2; }
326*7e382390SJung-uk Kim
327*7e382390SJung-uk Kim | '<' '*' '>'
328*7e382390SJung-uk Kim {
329*7e382390SJung-uk Kim $$ = scon_stk_ptr;
330*7e382390SJung-uk Kim
331*7e382390SJung-uk Kim for ( i = 1; i <= lastsc; ++i )
332*7e382390SJung-uk Kim {
333*7e382390SJung-uk Kim int j;
334*7e382390SJung-uk Kim
335*7e382390SJung-uk Kim for ( j = 1; j <= scon_stk_ptr; ++j )
336*7e382390SJung-uk Kim if ( scon_stk[j] == i )
337*7e382390SJung-uk Kim break;
338*7e382390SJung-uk Kim
339*7e382390SJung-uk Kim if ( j > scon_stk_ptr )
340*7e382390SJung-uk Kim scon_stk[++scon_stk_ptr] = i;
341*7e382390SJung-uk Kim }
342*7e382390SJung-uk Kim }
343*7e382390SJung-uk Kim
344*7e382390SJung-uk Kim |
345*7e382390SJung-uk Kim { $$ = scon_stk_ptr; }
346*7e382390SJung-uk Kim ;
347*7e382390SJung-uk Kim
348*7e382390SJung-uk Kim namelist2 : namelist2 ',' sconname
349*7e382390SJung-uk Kim
350*7e382390SJung-uk Kim | sconname
351*7e382390SJung-uk Kim
352*7e382390SJung-uk Kim | error
353*7e382390SJung-uk Kim { synerr( _("bad start condition list") ); }
354*7e382390SJung-uk Kim ;
355*7e382390SJung-uk Kim
356*7e382390SJung-uk Kim sconname : NAME
357*7e382390SJung-uk Kim {
358*7e382390SJung-uk Kim if ( (scnum = sclookup( nmstr )) == 0 )
359*7e382390SJung-uk Kim format_pinpoint_message(
360*7e382390SJung-uk Kim "undeclared start condition %s",
361*7e382390SJung-uk Kim nmstr );
362*7e382390SJung-uk Kim else
363*7e382390SJung-uk Kim {
364*7e382390SJung-uk Kim for ( i = 1; i <= scon_stk_ptr; ++i )
365*7e382390SJung-uk Kim if ( scon_stk[i] == scnum )
366*7e382390SJung-uk Kim {
367*7e382390SJung-uk Kim format_warn(
368*7e382390SJung-uk Kim "<%s> specified twice",
369*7e382390SJung-uk Kim scname[scnum] );
370*7e382390SJung-uk Kim break;
371*7e382390SJung-uk Kim }
372*7e382390SJung-uk Kim
373*7e382390SJung-uk Kim if ( i > scon_stk_ptr )
374*7e382390SJung-uk Kim scon_stk[++scon_stk_ptr] = scnum;
375*7e382390SJung-uk Kim }
376*7e382390SJung-uk Kim }
377*7e382390SJung-uk Kim ;
378*7e382390SJung-uk Kim
379*7e382390SJung-uk Kim rule : re2 re
380*7e382390SJung-uk Kim {
381*7e382390SJung-uk Kim if ( transchar[lastst[$2]] != SYM_EPSILON )
382*7e382390SJung-uk Kim /* Provide final transition \now/ so it
383*7e382390SJung-uk Kim * will be marked as a trailing context
384*7e382390SJung-uk Kim * state.
385*7e382390SJung-uk Kim */
386*7e382390SJung-uk Kim $2 = link_machines( $2,
387*7e382390SJung-uk Kim mkstate( SYM_EPSILON ) );
388*7e382390SJung-uk Kim
389*7e382390SJung-uk Kim mark_beginning_as_normal( $2 );
390*7e382390SJung-uk Kim current_state_type = STATE_NORMAL;
391*7e382390SJung-uk Kim
392*7e382390SJung-uk Kim if ( previous_continued_action )
393*7e382390SJung-uk Kim {
394*7e382390SJung-uk Kim /* We need to treat this as variable trailing
395*7e382390SJung-uk Kim * context so that the backup does not happen
396*7e382390SJung-uk Kim * in the action but before the action switch
397*7e382390SJung-uk Kim * statement. If the backup happens in the
398*7e382390SJung-uk Kim * action, then the rules "falling into" this
399*7e382390SJung-uk Kim * one's action will *also* do the backup,
400*7e382390SJung-uk Kim * erroneously.
401*7e382390SJung-uk Kim */
402*7e382390SJung-uk Kim if ( ! varlength || headcnt != 0 )
403*7e382390SJung-uk Kim lwarn(
404*7e382390SJung-uk Kim "trailing context made variable due to preceding '|' action" );
405*7e382390SJung-uk Kim
406*7e382390SJung-uk Kim /* Mark as variable. */
407*7e382390SJung-uk Kim varlength = true;
408*7e382390SJung-uk Kim headcnt = 0;
409*7e382390SJung-uk Kim
410*7e382390SJung-uk Kim }
411*7e382390SJung-uk Kim
412*7e382390SJung-uk Kim if ( lex_compat || (varlength && headcnt == 0) )
413*7e382390SJung-uk Kim { /* variable trailing context rule */
414*7e382390SJung-uk Kim /* Mark the first part of the rule as the
415*7e382390SJung-uk Kim * accepting "head" part of a trailing
416*7e382390SJung-uk Kim * context rule.
417*7e382390SJung-uk Kim *
418*7e382390SJung-uk Kim * By the way, we didn't do this at the
419*7e382390SJung-uk Kim * beginning of this production because back
420*7e382390SJung-uk Kim * then current_state_type was set up for a
421*7e382390SJung-uk Kim * trail rule, and add_accept() can create
422*7e382390SJung-uk Kim * a new state ...
423*7e382390SJung-uk Kim */
424*7e382390SJung-uk Kim add_accept( $1,
425*7e382390SJung-uk Kim num_rules | YY_TRAILING_HEAD_MASK );
426*7e382390SJung-uk Kim variable_trail_rule = true;
427*7e382390SJung-uk Kim }
428*7e382390SJung-uk Kim
429*7e382390SJung-uk Kim else
430*7e382390SJung-uk Kim trailcnt = rulelen;
431*7e382390SJung-uk Kim
432*7e382390SJung-uk Kim $$ = link_machines( $1, $2 );
433*7e382390SJung-uk Kim }
434*7e382390SJung-uk Kim
435*7e382390SJung-uk Kim | re2 re '$'
436*7e382390SJung-uk Kim { synerr( _("trailing context used twice") ); }
437*7e382390SJung-uk Kim
438*7e382390SJung-uk Kim | re '$'
439*7e382390SJung-uk Kim {
440*7e382390SJung-uk Kim headcnt = 0;
441*7e382390SJung-uk Kim trailcnt = 1;
442*7e382390SJung-uk Kim rulelen = 1;
443*7e382390SJung-uk Kim varlength = false;
444*7e382390SJung-uk Kim
445*7e382390SJung-uk Kim current_state_type = STATE_TRAILING_CONTEXT;
446*7e382390SJung-uk Kim
447*7e382390SJung-uk Kim if ( trlcontxt )
448*7e382390SJung-uk Kim {
449*7e382390SJung-uk Kim synerr( _("trailing context used twice") );
450*7e382390SJung-uk Kim $$ = mkstate( SYM_EPSILON );
451*7e382390SJung-uk Kim }
452*7e382390SJung-uk Kim
453*7e382390SJung-uk Kim else if ( previous_continued_action )
454*7e382390SJung-uk Kim {
455*7e382390SJung-uk Kim /* See the comment in the rule for "re2 re"
456*7e382390SJung-uk Kim * above.
457*7e382390SJung-uk Kim */
458*7e382390SJung-uk Kim lwarn(
459*7e382390SJung-uk Kim "trailing context made variable due to preceding '|' action" );
460*7e382390SJung-uk Kim
461*7e382390SJung-uk Kim varlength = true;
462*7e382390SJung-uk Kim }
463*7e382390SJung-uk Kim
464*7e382390SJung-uk Kim if ( lex_compat || varlength )
465*7e382390SJung-uk Kim {
466*7e382390SJung-uk Kim /* Again, see the comment in the rule for
467*7e382390SJung-uk Kim * "re2 re" above.
468*7e382390SJung-uk Kim */
469*7e382390SJung-uk Kim add_accept( $1,
470*7e382390SJung-uk Kim num_rules | YY_TRAILING_HEAD_MASK );
471*7e382390SJung-uk Kim variable_trail_rule = true;
472*7e382390SJung-uk Kim }
473*7e382390SJung-uk Kim
474*7e382390SJung-uk Kim trlcontxt = true;
475*7e382390SJung-uk Kim
476*7e382390SJung-uk Kim eps = mkstate( SYM_EPSILON );
477*7e382390SJung-uk Kim $$ = link_machines( $1,
478*7e382390SJung-uk Kim link_machines( eps, mkstate( '\n' ) ) );
479*7e382390SJung-uk Kim }
480*7e382390SJung-uk Kim
481*7e382390SJung-uk Kim | re
482*7e382390SJung-uk Kim {
483*7e382390SJung-uk Kim $$ = $1;
484*7e382390SJung-uk Kim
485*7e382390SJung-uk Kim if ( trlcontxt )
486*7e382390SJung-uk Kim {
487*7e382390SJung-uk Kim if ( lex_compat || (varlength && headcnt == 0) )
488*7e382390SJung-uk Kim /* Both head and trail are
489*7e382390SJung-uk Kim * variable-length.
490*7e382390SJung-uk Kim */
491*7e382390SJung-uk Kim variable_trail_rule = true;
492*7e382390SJung-uk Kim else
493*7e382390SJung-uk Kim trailcnt = rulelen;
494*7e382390SJung-uk Kim }
495*7e382390SJung-uk Kim }
496*7e382390SJung-uk Kim ;
497*7e382390SJung-uk Kim
498*7e382390SJung-uk Kim
499*7e382390SJung-uk Kim re : re '|' series
500*7e382390SJung-uk Kim {
501*7e382390SJung-uk Kim varlength = true;
502*7e382390SJung-uk Kim $$ = mkor( $1, $3 );
503*7e382390SJung-uk Kim }
504*7e382390SJung-uk Kim
505*7e382390SJung-uk Kim | series
506*7e382390SJung-uk Kim { $$ = $1; }
507*7e382390SJung-uk Kim ;
508*7e382390SJung-uk Kim
509*7e382390SJung-uk Kim
510*7e382390SJung-uk Kim re2 : re '/'
511*7e382390SJung-uk Kim {
512*7e382390SJung-uk Kim /* This rule is written separately so the
513*7e382390SJung-uk Kim * reduction will occur before the trailing
514*7e382390SJung-uk Kim * series is parsed.
515*7e382390SJung-uk Kim */
516*7e382390SJung-uk Kim
517*7e382390SJung-uk Kim if ( trlcontxt )
518*7e382390SJung-uk Kim synerr( _("trailing context used twice") );
519*7e382390SJung-uk Kim else
520*7e382390SJung-uk Kim trlcontxt = true;
521*7e382390SJung-uk Kim
522*7e382390SJung-uk Kim if ( varlength )
523*7e382390SJung-uk Kim /* We hope the trailing context is
524*7e382390SJung-uk Kim * fixed-length.
525*7e382390SJung-uk Kim */
526*7e382390SJung-uk Kim varlength = false;
527*7e382390SJung-uk Kim else
528*7e382390SJung-uk Kim headcnt = rulelen;
529*7e382390SJung-uk Kim
530*7e382390SJung-uk Kim rulelen = 0;
531*7e382390SJung-uk Kim
532*7e382390SJung-uk Kim current_state_type = STATE_TRAILING_CONTEXT;
533*7e382390SJung-uk Kim $$ = $1;
534*7e382390SJung-uk Kim }
535*7e382390SJung-uk Kim ;
536*7e382390SJung-uk Kim
537*7e382390SJung-uk Kim series : series singleton
538*7e382390SJung-uk Kim {
539*7e382390SJung-uk Kim /* This is where concatenation of adjacent patterns
540*7e382390SJung-uk Kim * gets done.
541*7e382390SJung-uk Kim */
542*7e382390SJung-uk Kim $$ = link_machines( $1, $2 );
543*7e382390SJung-uk Kim }
544*7e382390SJung-uk Kim
545*7e382390SJung-uk Kim | singleton
546*7e382390SJung-uk Kim { $$ = $1; }
547*7e382390SJung-uk Kim
548*7e382390SJung-uk Kim | series BEGIN_REPEAT_POSIX NUMBER ',' NUMBER END_REPEAT_POSIX
549*7e382390SJung-uk Kim {
550*7e382390SJung-uk Kim varlength = true;
551*7e382390SJung-uk Kim
552*7e382390SJung-uk Kim if ( $3 > $5 || $3 < 0 )
553*7e382390SJung-uk Kim {
554*7e382390SJung-uk Kim synerr( _("bad iteration values") );
555*7e382390SJung-uk Kim $$ = $1;
556*7e382390SJung-uk Kim }
557*7e382390SJung-uk Kim else
558*7e382390SJung-uk Kim {
559*7e382390SJung-uk Kim if ( $3 == 0 )
560*7e382390SJung-uk Kim {
561*7e382390SJung-uk Kim if ( $5 <= 0 )
562*7e382390SJung-uk Kim {
563*7e382390SJung-uk Kim synerr(
564*7e382390SJung-uk Kim _("bad iteration values") );
565*7e382390SJung-uk Kim $$ = $1;
566*7e382390SJung-uk Kim }
567*7e382390SJung-uk Kim else
568*7e382390SJung-uk Kim $$ = mkopt(
569*7e382390SJung-uk Kim mkrep( $1, 1, $5 ) );
570*7e382390SJung-uk Kim }
571*7e382390SJung-uk Kim else
572*7e382390SJung-uk Kim $$ = mkrep( $1, $3, $5 );
573*7e382390SJung-uk Kim }
574*7e382390SJung-uk Kim }
575*7e382390SJung-uk Kim
576*7e382390SJung-uk Kim | series BEGIN_REPEAT_POSIX NUMBER ',' END_REPEAT_POSIX
577*7e382390SJung-uk Kim {
578*7e382390SJung-uk Kim varlength = true;
579*7e382390SJung-uk Kim
580*7e382390SJung-uk Kim if ( $3 <= 0 )
581*7e382390SJung-uk Kim {
582*7e382390SJung-uk Kim synerr( _("iteration value must be positive") );
583*7e382390SJung-uk Kim $$ = $1;
584*7e382390SJung-uk Kim }
585*7e382390SJung-uk Kim
586*7e382390SJung-uk Kim else
587*7e382390SJung-uk Kim $$ = mkrep( $1, $3, INFINITE_REPEAT );
588*7e382390SJung-uk Kim }
589*7e382390SJung-uk Kim
590*7e382390SJung-uk Kim | series BEGIN_REPEAT_POSIX NUMBER END_REPEAT_POSIX
591*7e382390SJung-uk Kim {
592*7e382390SJung-uk Kim /* The series could be something like "(foo)",
593*7e382390SJung-uk Kim * in which case we have no idea what its length
594*7e382390SJung-uk Kim * is, so we punt here.
595*7e382390SJung-uk Kim */
596*7e382390SJung-uk Kim varlength = true;
597*7e382390SJung-uk Kim
598*7e382390SJung-uk Kim if ( $3 <= 0 )
599*7e382390SJung-uk Kim {
600*7e382390SJung-uk Kim synerr( _("iteration value must be positive")
601*7e382390SJung-uk Kim );
602*7e382390SJung-uk Kim $$ = $1;
603*7e382390SJung-uk Kim }
604*7e382390SJung-uk Kim
605*7e382390SJung-uk Kim else
606*7e382390SJung-uk Kim $$ = link_machines( $1,
607*7e382390SJung-uk Kim copysingl( $1, $3 - 1 ) );
608*7e382390SJung-uk Kim }
609*7e382390SJung-uk Kim
610*7e382390SJung-uk Kim ;
611*7e382390SJung-uk Kim
612*7e382390SJung-uk Kim singleton : singleton '*'
613*7e382390SJung-uk Kim {
614*7e382390SJung-uk Kim varlength = true;
615*7e382390SJung-uk Kim
616*7e382390SJung-uk Kim $$ = mkclos( $1 );
617*7e382390SJung-uk Kim }
618*7e382390SJung-uk Kim
619*7e382390SJung-uk Kim | singleton '+'
620*7e382390SJung-uk Kim {
621*7e382390SJung-uk Kim varlength = true;
622*7e382390SJung-uk Kim $$ = mkposcl( $1 );
623*7e382390SJung-uk Kim }
624*7e382390SJung-uk Kim
625*7e382390SJung-uk Kim | singleton '?'
626*7e382390SJung-uk Kim {
627*7e382390SJung-uk Kim varlength = true;
628*7e382390SJung-uk Kim $$ = mkopt( $1 );
629*7e382390SJung-uk Kim }
630*7e382390SJung-uk Kim
631*7e382390SJung-uk Kim | singleton BEGIN_REPEAT_FLEX NUMBER ',' NUMBER END_REPEAT_FLEX
632*7e382390SJung-uk Kim {
633*7e382390SJung-uk Kim varlength = true;
634*7e382390SJung-uk Kim
635*7e382390SJung-uk Kim if ( $3 > $5 || $3 < 0 )
636*7e382390SJung-uk Kim {
637*7e382390SJung-uk Kim synerr( _("bad iteration values") );
638*7e382390SJung-uk Kim $$ = $1;
639*7e382390SJung-uk Kim }
640*7e382390SJung-uk Kim else
641*7e382390SJung-uk Kim {
642*7e382390SJung-uk Kim if ( $3 == 0 )
643*7e382390SJung-uk Kim {
644*7e382390SJung-uk Kim if ( $5 <= 0 )
645*7e382390SJung-uk Kim {
646*7e382390SJung-uk Kim synerr(
647*7e382390SJung-uk Kim _("bad iteration values") );
648*7e382390SJung-uk Kim $$ = $1;
649*7e382390SJung-uk Kim }
650*7e382390SJung-uk Kim else
651*7e382390SJung-uk Kim $$ = mkopt(
652*7e382390SJung-uk Kim mkrep( $1, 1, $5 ) );
653*7e382390SJung-uk Kim }
654*7e382390SJung-uk Kim else
655*7e382390SJung-uk Kim $$ = mkrep( $1, $3, $5 );
656*7e382390SJung-uk Kim }
657*7e382390SJung-uk Kim }
658*7e382390SJung-uk Kim
659*7e382390SJung-uk Kim | singleton BEGIN_REPEAT_FLEX NUMBER ',' END_REPEAT_FLEX
660*7e382390SJung-uk Kim {
661*7e382390SJung-uk Kim varlength = true;
662*7e382390SJung-uk Kim
663*7e382390SJung-uk Kim if ( $3 <= 0 )
664*7e382390SJung-uk Kim {
665*7e382390SJung-uk Kim synerr( _("iteration value must be positive") );
666*7e382390SJung-uk Kim $$ = $1;
667*7e382390SJung-uk Kim }
668*7e382390SJung-uk Kim
669*7e382390SJung-uk Kim else
670*7e382390SJung-uk Kim $$ = mkrep( $1, $3, INFINITE_REPEAT );
671*7e382390SJung-uk Kim }
672*7e382390SJung-uk Kim
673*7e382390SJung-uk Kim | singleton BEGIN_REPEAT_FLEX NUMBER END_REPEAT_FLEX
674*7e382390SJung-uk Kim {
675*7e382390SJung-uk Kim /* The singleton could be something like "(foo)",
676*7e382390SJung-uk Kim * in which case we have no idea what its length
677*7e382390SJung-uk Kim * is, so we punt here.
678*7e382390SJung-uk Kim */
679*7e382390SJung-uk Kim varlength = true;
680*7e382390SJung-uk Kim
681*7e382390SJung-uk Kim if ( $3 <= 0 )
682*7e382390SJung-uk Kim {
683*7e382390SJung-uk Kim synerr( _("iteration value must be positive") );
684*7e382390SJung-uk Kim $$ = $1;
685*7e382390SJung-uk Kim }
686*7e382390SJung-uk Kim
687*7e382390SJung-uk Kim else
688*7e382390SJung-uk Kim $$ = link_machines( $1,
689*7e382390SJung-uk Kim copysingl( $1, $3 - 1 ) );
690*7e382390SJung-uk Kim }
691*7e382390SJung-uk Kim
692*7e382390SJung-uk Kim | '.'
693*7e382390SJung-uk Kim {
694*7e382390SJung-uk Kim if ( ! madeany )
695*7e382390SJung-uk Kim {
696*7e382390SJung-uk Kim /* Create the '.' character class. */
697*7e382390SJung-uk Kim ccldot = cclinit();
698*7e382390SJung-uk Kim ccladd( ccldot, '\n' );
699*7e382390SJung-uk Kim cclnegate( ccldot );
700*7e382390SJung-uk Kim
701*7e382390SJung-uk Kim if ( useecs )
702*7e382390SJung-uk Kim mkeccl( ccltbl + cclmap[ccldot],
703*7e382390SJung-uk Kim ccllen[ccldot], nextecm,
704*7e382390SJung-uk Kim ecgroup, csize, csize );
705*7e382390SJung-uk Kim
706*7e382390SJung-uk Kim /* Create the (?s:'.') character class. */
707*7e382390SJung-uk Kim cclany = cclinit();
708*7e382390SJung-uk Kim cclnegate( cclany );
709*7e382390SJung-uk Kim
710*7e382390SJung-uk Kim if ( useecs )
711*7e382390SJung-uk Kim mkeccl( ccltbl + cclmap[cclany],
712*7e382390SJung-uk Kim ccllen[cclany], nextecm,
713*7e382390SJung-uk Kim ecgroup, csize, csize );
714*7e382390SJung-uk Kim
715*7e382390SJung-uk Kim madeany = true;
716*7e382390SJung-uk Kim }
717*7e382390SJung-uk Kim
718*7e382390SJung-uk Kim ++rulelen;
719*7e382390SJung-uk Kim
720*7e382390SJung-uk Kim if (sf_dot_all())
721*7e382390SJung-uk Kim $$ = mkstate( -cclany );
722*7e382390SJung-uk Kim else
723*7e382390SJung-uk Kim $$ = mkstate( -ccldot );
724*7e382390SJung-uk Kim }
725*7e382390SJung-uk Kim
726*7e382390SJung-uk Kim | fullccl
727*7e382390SJung-uk Kim {
728*7e382390SJung-uk Kim /* Sort characters for fast searching.
729*7e382390SJung-uk Kim */
730*7e382390SJung-uk Kim qsort( ccltbl + cclmap[$1], (size_t) ccllen[$1], sizeof (*ccltbl), cclcmp );
731*7e382390SJung-uk Kim
732*7e382390SJung-uk Kim if ( useecs )
733*7e382390SJung-uk Kim mkeccl( ccltbl + cclmap[$1], ccllen[$1],
734*7e382390SJung-uk Kim nextecm, ecgroup, csize, csize );
735*7e382390SJung-uk Kim
736*7e382390SJung-uk Kim ++rulelen;
737*7e382390SJung-uk Kim
738*7e382390SJung-uk Kim if (ccl_has_nl[$1])
739*7e382390SJung-uk Kim rule_has_nl[num_rules] = true;
740*7e382390SJung-uk Kim
741*7e382390SJung-uk Kim $$ = mkstate( -$1 );
742*7e382390SJung-uk Kim }
743*7e382390SJung-uk Kim
744*7e382390SJung-uk Kim | PREVCCL
745*7e382390SJung-uk Kim {
746*7e382390SJung-uk Kim ++rulelen;
747*7e382390SJung-uk Kim
748*7e382390SJung-uk Kim if (ccl_has_nl[$1])
749*7e382390SJung-uk Kim rule_has_nl[num_rules] = true;
750*7e382390SJung-uk Kim
751*7e382390SJung-uk Kim $$ = mkstate( -$1 );
752*7e382390SJung-uk Kim }
753*7e382390SJung-uk Kim
754*7e382390SJung-uk Kim | '"' string '"'
755*7e382390SJung-uk Kim { $$ = $2; }
756*7e382390SJung-uk Kim
757*7e382390SJung-uk Kim | '(' re ')'
758*7e382390SJung-uk Kim { $$ = $2; }
759*7e382390SJung-uk Kim
760*7e382390SJung-uk Kim | CHAR
761*7e382390SJung-uk Kim {
762*7e382390SJung-uk Kim ++rulelen;
763*7e382390SJung-uk Kim
764*7e382390SJung-uk Kim if ($1 == nlch)
765*7e382390SJung-uk Kim rule_has_nl[num_rules] = true;
766*7e382390SJung-uk Kim
767*7e382390SJung-uk Kim if (sf_case_ins() && has_case($1))
768*7e382390SJung-uk Kim /* create an alternation, as in (a|A) */
769*7e382390SJung-uk Kim $$ = mkor (mkstate($1), mkstate(reverse_case($1)));
770*7e382390SJung-uk Kim else
771*7e382390SJung-uk Kim $$ = mkstate( $1 );
772*7e382390SJung-uk Kim }
773*7e382390SJung-uk Kim ;
774*7e382390SJung-uk Kim fullccl:
775*7e382390SJung-uk Kim fullccl CCL_OP_DIFF braceccl { $$ = ccl_set_diff ($1, $3); }
776*7e382390SJung-uk Kim | fullccl CCL_OP_UNION braceccl { $$ = ccl_set_union ($1, $3); }
777*7e382390SJung-uk Kim | braceccl
778*7e382390SJung-uk Kim ;
779*7e382390SJung-uk Kim
780*7e382390SJung-uk Kim braceccl:
781*7e382390SJung-uk Kim
782*7e382390SJung-uk Kim '[' ccl ']' { $$ = $2; }
783*7e382390SJung-uk Kim
784*7e382390SJung-uk Kim | '[' '^' ccl ']'
785*7e382390SJung-uk Kim {
786*7e382390SJung-uk Kim cclnegate( $3 );
787*7e382390SJung-uk Kim $$ = $3;
788*7e382390SJung-uk Kim }
789*7e382390SJung-uk Kim ;
790*7e382390SJung-uk Kim
791*7e382390SJung-uk Kim ccl : ccl CHAR '-' CHAR
792*7e382390SJung-uk Kim {
793*7e382390SJung-uk Kim
794*7e382390SJung-uk Kim if (sf_case_ins())
795*7e382390SJung-uk Kim {
796*7e382390SJung-uk Kim
797*7e382390SJung-uk Kim /* If one end of the range has case and the other
798*7e382390SJung-uk Kim * does not, or the cases are different, then we're not
799*7e382390SJung-uk Kim * sure what range the user is trying to express.
800*7e382390SJung-uk Kim * Examples: [@-z] or [S-t]
801*7e382390SJung-uk Kim */
802*7e382390SJung-uk Kim if (has_case ($2) != has_case ($4)
803*7e382390SJung-uk Kim || (has_case ($2) && (b_islower ($2) != b_islower ($4)))
804*7e382390SJung-uk Kim || (has_case ($2) && (b_isupper ($2) != b_isupper ($4))))
805*7e382390SJung-uk Kim format_warn3 (
806*7e382390SJung-uk Kim _("the character range [%c-%c] is ambiguous in a case-insensitive scanner"),
807*7e382390SJung-uk Kim $2, $4);
808*7e382390SJung-uk Kim
809*7e382390SJung-uk Kim /* If the range spans uppercase characters but not
810*7e382390SJung-uk Kim * lowercase (or vice-versa), then should we automatically
811*7e382390SJung-uk Kim * include lowercase characters in the range?
812*7e382390SJung-uk Kim * Example: [@-_] spans [a-z] but not [A-Z]
813*7e382390SJung-uk Kim */
814*7e382390SJung-uk Kim else if (!has_case ($2) && !has_case ($4) && !range_covers_case ($2, $4))
815*7e382390SJung-uk Kim format_warn3 (
816*7e382390SJung-uk Kim _("the character range [%c-%c] is ambiguous in a case-insensitive scanner"),
817*7e382390SJung-uk Kim $2, $4);
818*7e382390SJung-uk Kim }
819*7e382390SJung-uk Kim
820*7e382390SJung-uk Kim if ( $2 > $4 )
821*7e382390SJung-uk Kim synerr( _("negative range in character class") );
822*7e382390SJung-uk Kim
823*7e382390SJung-uk Kim else
824*7e382390SJung-uk Kim {
825*7e382390SJung-uk Kim for ( i = $2; i <= $4; ++i )
826*7e382390SJung-uk Kim ccladd( $1, i );
827*7e382390SJung-uk Kim
828*7e382390SJung-uk Kim /* Keep track if this ccl is staying in
829*7e382390SJung-uk Kim * alphabetical order.
830*7e382390SJung-uk Kim */
831*7e382390SJung-uk Kim cclsorted = cclsorted && ($2 > lastchar);
832*7e382390SJung-uk Kim lastchar = $4;
833*7e382390SJung-uk Kim
834*7e382390SJung-uk Kim /* Do it again for upper/lowercase */
835*7e382390SJung-uk Kim if (sf_case_ins() && has_case($2) && has_case($4)){
836*7e382390SJung-uk Kim $2 = reverse_case ($2);
837*7e382390SJung-uk Kim $4 = reverse_case ($4);
838*7e382390SJung-uk Kim
839*7e382390SJung-uk Kim for ( i = $2; i <= $4; ++i )
840*7e382390SJung-uk Kim ccladd( $1, i );
841*7e382390SJung-uk Kim
842*7e382390SJung-uk Kim cclsorted = cclsorted && ($2 > lastchar);
843*7e382390SJung-uk Kim lastchar = $4;
844*7e382390SJung-uk Kim }
845*7e382390SJung-uk Kim
846*7e382390SJung-uk Kim }
847*7e382390SJung-uk Kim
848*7e382390SJung-uk Kim $$ = $1;
849*7e382390SJung-uk Kim }
850*7e382390SJung-uk Kim
851*7e382390SJung-uk Kim | ccl CHAR
852*7e382390SJung-uk Kim {
853*7e382390SJung-uk Kim ccladd( $1, $2 );
854*7e382390SJung-uk Kim cclsorted = cclsorted && ($2 > lastchar);
855*7e382390SJung-uk Kim lastchar = $2;
856*7e382390SJung-uk Kim
857*7e382390SJung-uk Kim /* Do it again for upper/lowercase */
858*7e382390SJung-uk Kim if (sf_case_ins() && has_case($2)){
859*7e382390SJung-uk Kim $2 = reverse_case ($2);
860*7e382390SJung-uk Kim ccladd ($1, $2);
861*7e382390SJung-uk Kim
862*7e382390SJung-uk Kim cclsorted = cclsorted && ($2 > lastchar);
863*7e382390SJung-uk Kim lastchar = $2;
864*7e382390SJung-uk Kim }
865*7e382390SJung-uk Kim
866*7e382390SJung-uk Kim $$ = $1;
867*7e382390SJung-uk Kim }
868*7e382390SJung-uk Kim
869*7e382390SJung-uk Kim | ccl ccl_expr
870*7e382390SJung-uk Kim {
871*7e382390SJung-uk Kim /* Too hard to properly maintain cclsorted. */
872*7e382390SJung-uk Kim cclsorted = false;
873*7e382390SJung-uk Kim $$ = $1;
874*7e382390SJung-uk Kim }
875*7e382390SJung-uk Kim
876*7e382390SJung-uk Kim |
877*7e382390SJung-uk Kim {
878*7e382390SJung-uk Kim cclsorted = true;
879*7e382390SJung-uk Kim lastchar = 0;
880*7e382390SJung-uk Kim currccl = $$ = cclinit();
881*7e382390SJung-uk Kim }
882*7e382390SJung-uk Kim ;
883*7e382390SJung-uk Kim
884*7e382390SJung-uk Kim ccl_expr:
885*7e382390SJung-uk Kim CCE_ALNUM { CCL_EXPR(isalnum); }
886*7e382390SJung-uk Kim | CCE_ALPHA { CCL_EXPR(isalpha); }
887*7e382390SJung-uk Kim | CCE_BLANK { CCL_EXPR(IS_BLANK); }
888*7e382390SJung-uk Kim | CCE_CNTRL { CCL_EXPR(iscntrl); }
889*7e382390SJung-uk Kim | CCE_DIGIT { CCL_EXPR(isdigit); }
890*7e382390SJung-uk Kim | CCE_GRAPH { CCL_EXPR(isgraph); }
891*7e382390SJung-uk Kim | CCE_LOWER {
892*7e382390SJung-uk Kim CCL_EXPR(islower);
893*7e382390SJung-uk Kim if (sf_case_ins())
894*7e382390SJung-uk Kim CCL_EXPR(isupper);
895*7e382390SJung-uk Kim }
896*7e382390SJung-uk Kim | CCE_PRINT { CCL_EXPR(isprint); }
897*7e382390SJung-uk Kim | CCE_PUNCT { CCL_EXPR(ispunct); }
898*7e382390SJung-uk Kim | CCE_SPACE { CCL_EXPR(isspace); }
899*7e382390SJung-uk Kim | CCE_XDIGIT { CCL_EXPR(isxdigit); }
900*7e382390SJung-uk Kim | CCE_UPPER {
901*7e382390SJung-uk Kim CCL_EXPR(isupper);
902*7e382390SJung-uk Kim if (sf_case_ins())
903*7e382390SJung-uk Kim CCL_EXPR(islower);
904*7e382390SJung-uk Kim }
905*7e382390SJung-uk Kim
906*7e382390SJung-uk Kim | CCE_NEG_ALNUM { CCL_NEG_EXPR(isalnum); }
907*7e382390SJung-uk Kim | CCE_NEG_ALPHA { CCL_NEG_EXPR(isalpha); }
908*7e382390SJung-uk Kim | CCE_NEG_BLANK { CCL_NEG_EXPR(IS_BLANK); }
909*7e382390SJung-uk Kim | CCE_NEG_CNTRL { CCL_NEG_EXPR(iscntrl); }
910*7e382390SJung-uk Kim | CCE_NEG_DIGIT { CCL_NEG_EXPR(isdigit); }
911*7e382390SJung-uk Kim | CCE_NEG_GRAPH { CCL_NEG_EXPR(isgraph); }
912*7e382390SJung-uk Kim | CCE_NEG_PRINT { CCL_NEG_EXPR(isprint); }
913*7e382390SJung-uk Kim | CCE_NEG_PUNCT { CCL_NEG_EXPR(ispunct); }
914*7e382390SJung-uk Kim | CCE_NEG_SPACE { CCL_NEG_EXPR(isspace); }
915*7e382390SJung-uk Kim | CCE_NEG_XDIGIT { CCL_NEG_EXPR(isxdigit); }
916*7e382390SJung-uk Kim | CCE_NEG_LOWER {
917*7e382390SJung-uk Kim if ( sf_case_ins() )
918*7e382390SJung-uk Kim lwarn(_("[:^lower:] is ambiguous in case insensitive scanner"));
919*7e382390SJung-uk Kim else
920*7e382390SJung-uk Kim CCL_NEG_EXPR(islower);
921*7e382390SJung-uk Kim }
922*7e382390SJung-uk Kim | CCE_NEG_UPPER {
923*7e382390SJung-uk Kim if ( sf_case_ins() )
924*7e382390SJung-uk Kim lwarn(_("[:^upper:] ambiguous in case insensitive scanner"));
925*7e382390SJung-uk Kim else
926*7e382390SJung-uk Kim CCL_NEG_EXPR(isupper);
927*7e382390SJung-uk Kim }
928*7e382390SJung-uk Kim ;
929*7e382390SJung-uk Kim
930*7e382390SJung-uk Kim string : string CHAR
931*7e382390SJung-uk Kim {
932*7e382390SJung-uk Kim if ( $2 == nlch )
933*7e382390SJung-uk Kim rule_has_nl[num_rules] = true;
934*7e382390SJung-uk Kim
935*7e382390SJung-uk Kim ++rulelen;
936*7e382390SJung-uk Kim
937*7e382390SJung-uk Kim if (sf_case_ins() && has_case($2))
938*7e382390SJung-uk Kim $$ = mkor (mkstate($2), mkstate(reverse_case($2)));
939*7e382390SJung-uk Kim else
940*7e382390SJung-uk Kim $$ = mkstate ($2);
941*7e382390SJung-uk Kim
942*7e382390SJung-uk Kim $$ = link_machines( $1, $$);
943*7e382390SJung-uk Kim }
944*7e382390SJung-uk Kim
945*7e382390SJung-uk Kim |
946*7e382390SJung-uk Kim { $$ = mkstate( SYM_EPSILON ); }
947*7e382390SJung-uk Kim ;
948*7e382390SJung-uk Kim
949*7e382390SJung-uk Kim %%
950*7e382390SJung-uk Kim
951*7e382390SJung-uk Kim
952*7e382390SJung-uk Kim /* build_eof_action - build the "<<EOF>>" action for the active start
953*7e382390SJung-uk Kim * conditions
954*7e382390SJung-uk Kim */
955*7e382390SJung-uk Kim
956*7e382390SJung-uk Kim void build_eof_action(void)
957*7e382390SJung-uk Kim {
958*7e382390SJung-uk Kim int i;
959*7e382390SJung-uk Kim char action_text[MAXLINE];
960*7e382390SJung-uk Kim
961*7e382390SJung-uk Kim for ( i = 1; i <= scon_stk_ptr; ++i )
962*7e382390SJung-uk Kim {
963*7e382390SJung-uk Kim if ( sceof[scon_stk[i]] )
964*7e382390SJung-uk Kim format_pinpoint_message(
965*7e382390SJung-uk Kim "multiple <<EOF>> rules for start condition %s",
966*7e382390SJung-uk Kim scname[scon_stk[i]] );
967*7e382390SJung-uk Kim
968*7e382390SJung-uk Kim else
969*7e382390SJung-uk Kim {
970*7e382390SJung-uk Kim sceof[scon_stk[i]] = true;
971*7e382390SJung-uk Kim
972*7e382390SJung-uk Kim if (previous_continued_action /* && previous action was regular */)
973*7e382390SJung-uk Kim add_action("YY_RULE_SETUP\n");
974*7e382390SJung-uk Kim
975*7e382390SJung-uk Kim snprintf( action_text, sizeof(action_text), "case YY_STATE_EOF(%s):\n",
976*7e382390SJung-uk Kim scname[scon_stk[i]] );
977*7e382390SJung-uk Kim add_action( action_text );
978*7e382390SJung-uk Kim }
979*7e382390SJung-uk Kim }
980*7e382390SJung-uk Kim
981*7e382390SJung-uk Kim line_directive_out(NULL, 1);
982*7e382390SJung-uk Kim add_action("[[");
983*7e382390SJung-uk Kim
984*7e382390SJung-uk Kim /* This isn't a normal rule after all - don't count it as
985*7e382390SJung-uk Kim * such, so we don't have any holes in the rule numbering
986*7e382390SJung-uk Kim * (which make generating "rule can never match" warnings
987*7e382390SJung-uk Kim * more difficult.
988*7e382390SJung-uk Kim */
989*7e382390SJung-uk Kim --num_rules;
990*7e382390SJung-uk Kim ++num_eof_rules;
991*7e382390SJung-uk Kim }
992*7e382390SJung-uk Kim
993*7e382390SJung-uk Kim
994*7e382390SJung-uk Kim /* format_synerr - write out formatted syntax error */
995*7e382390SJung-uk Kim
format_synerr(const char * msg,const char arg[])996*7e382390SJung-uk Kim void format_synerr( const char *msg, const char arg[] )
997*7e382390SJung-uk Kim {
998*7e382390SJung-uk Kim char errmsg[MAXLINE];
999*7e382390SJung-uk Kim
1000*7e382390SJung-uk Kim (void) snprintf( errmsg, sizeof(errmsg), msg, arg );
1001*7e382390SJung-uk Kim synerr( errmsg );
1002*7e382390SJung-uk Kim }
1003*7e382390SJung-uk Kim
1004*7e382390SJung-uk Kim
1005*7e382390SJung-uk Kim /* synerr - report a syntax error */
1006*7e382390SJung-uk Kim
synerr(const char * str)1007*7e382390SJung-uk Kim void synerr( const char *str )
1008*7e382390SJung-uk Kim {
1009*7e382390SJung-uk Kim syntaxerror = true;
1010*7e382390SJung-uk Kim pinpoint_message( str );
1011*7e382390SJung-uk Kim }
1012*7e382390SJung-uk Kim
1013*7e382390SJung-uk Kim
1014*7e382390SJung-uk Kim /* format_warn - write out formatted warning */
1015*7e382390SJung-uk Kim
format_warn(const char * msg,const char arg[])1016*7e382390SJung-uk Kim void format_warn( const char *msg, const char arg[] )
1017*7e382390SJung-uk Kim {
1018*7e382390SJung-uk Kim char warn_msg[MAXLINE];
1019*7e382390SJung-uk Kim
1020*7e382390SJung-uk Kim snprintf( warn_msg, sizeof(warn_msg), msg, arg );
1021*7e382390SJung-uk Kim lwarn( warn_msg );
1022*7e382390SJung-uk Kim }
1023*7e382390SJung-uk Kim
1024*7e382390SJung-uk Kim
1025*7e382390SJung-uk Kim /* lwarn - report a warning, unless -w was given */
1026*7e382390SJung-uk Kim
lwarn(const char * str)1027*7e382390SJung-uk Kim void lwarn( const char *str )
1028*7e382390SJung-uk Kim {
1029*7e382390SJung-uk Kim line_warning( str, linenum );
1030*7e382390SJung-uk Kim }
1031*7e382390SJung-uk Kim
1032*7e382390SJung-uk Kim /* format_pinpoint_message - write out a message formatted with one string,
1033*7e382390SJung-uk Kim * pinpointing its location
1034*7e382390SJung-uk Kim */
1035*7e382390SJung-uk Kim
format_pinpoint_message(const char * msg,const char arg[])1036*7e382390SJung-uk Kim void format_pinpoint_message( const char *msg, const char arg[] )
1037*7e382390SJung-uk Kim {
1038*7e382390SJung-uk Kim char errmsg[MAXLINE];
1039*7e382390SJung-uk Kim
1040*7e382390SJung-uk Kim snprintf( errmsg, sizeof(errmsg), msg, arg );
1041*7e382390SJung-uk Kim pinpoint_message( errmsg );
1042*7e382390SJung-uk Kim }
1043*7e382390SJung-uk Kim
1044*7e382390SJung-uk Kim
1045*7e382390SJung-uk Kim /* pinpoint_message - write out a message, pinpointing its location */
1046*7e382390SJung-uk Kim
pinpoint_message(const char * str)1047*7e382390SJung-uk Kim void pinpoint_message( const char *str )
1048*7e382390SJung-uk Kim {
1049*7e382390SJung-uk Kim line_pinpoint( str, linenum );
1050*7e382390SJung-uk Kim }
1051*7e382390SJung-uk Kim
1052*7e382390SJung-uk Kim
1053*7e382390SJung-uk Kim /* line_warning - report a warning at a given line, unless -w was given */
1054*7e382390SJung-uk Kim
line_warning(const char * str,int line)1055*7e382390SJung-uk Kim void line_warning( const char *str, int line )
1056*7e382390SJung-uk Kim {
1057*7e382390SJung-uk Kim char warning[MAXLINE];
1058*7e382390SJung-uk Kim
1059*7e382390SJung-uk Kim if ( ! nowarn )
1060*7e382390SJung-uk Kim {
1061*7e382390SJung-uk Kim snprintf( warning, sizeof(warning), "warning, %s", str );
1062*7e382390SJung-uk Kim line_pinpoint( warning, line );
1063*7e382390SJung-uk Kim }
1064*7e382390SJung-uk Kim }
1065*7e382390SJung-uk Kim
1066*7e382390SJung-uk Kim
1067*7e382390SJung-uk Kim /* line_pinpoint - write out a message, pinpointing it at the given line */
1068*7e382390SJung-uk Kim
line_pinpoint(const char * str,int line)1069*7e382390SJung-uk Kim void line_pinpoint( const char *str, int line )
1070*7e382390SJung-uk Kim {
1071*7e382390SJung-uk Kim fprintf( stderr, "%s:%d: %s\n", infilename, line, str );
1072*7e382390SJung-uk Kim }
1073*7e382390SJung-uk Kim
1074*7e382390SJung-uk Kim
1075*7e382390SJung-uk Kim /* yyerror - eat up an error message from the parser;
1076*7e382390SJung-uk Kim * currently, messages are ignore
1077*7e382390SJung-uk Kim */
1078*7e382390SJung-uk Kim
yyerror(const char * msg)1079*7e382390SJung-uk Kim void yyerror( const char *msg )
1080*7e382390SJung-uk Kim {
1081*7e382390SJung-uk Kim (void)msg;
1082*7e382390SJung-uk Kim }
1083