1 /* scan.l - scanner for flex input */
5 * Copyright (c) 1990 The Regents of the University of California.
8 * This code is derived from software contributed to Berkeley by
11 * The United States Government has rights in this work pursuant
12 * to contract no. DE-AC03-76SF00098 between the United States
13 * Department of Energy and the University of California.
15 * Redistribution and use in source and binary forms are permitted provided
16 * that: (1) source distributions retain this entire copyright notice and
17 * comment, and (2) distributions including binaries display the following
18 * acknowledgement: ``This product includes software developed by the
19 * University of California, Berkeley and its contributors'' in the
20 * documentation or other materials provided with the distribution and in
21 * all advertising materials mentioning features or use of this software.
22 * Neither the name of the University nor the names of its contributors may
23 * be used to endorse or promote products derived from this software without
24 * specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
26 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 /* $Header: /home/daffy/u0/vern/flex/RCS/scan.l,v 2.56 95/04/24 12:17:19 vern Exp $ */
31 /* $FreeBSD: src/usr.bin/lex/scan.l,v 1.5 1999/10/27 07:56:46 obrien Exp $ */
32 /* $DragonFly: src/usr.bin/lex/scan.l,v 1.2 2003/06/17 04:29:28 dillon Exp $ */
37 #define ACTION_ECHO add_action( yytext )
38 #define ACTION_IFDEF(def, should_define) \
40 if ( should_define ) \
41 action_define( def, 1 ); \
44 #define MARK_END_OF_PROLOG mark_prolog();
50 yylval = (unsigned char) yytext[0]; \
54 strcpy( nmstr, yytext ); \
57 #define PUT_BACK_STRING(str, start) \
58 for ( i = strlen( str ) - 1; i >= start; --i ) \
61 #define CHECK_REJECT(str) \
62 if ( all_upper( str ) ) \
65 #define CHECK_YYMORE(str) \
66 if ( all_lower( str ) ) \
70 %option caseless nodefault outfile="scan.c" stack noyy_top_state
73 %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
74 %x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION
83 NAME ([[:alpha:]_][[:alnum:]_-]*)
84 NOT_NAME [^[:alpha:]_*\n]+
88 ESCSEQ (\\([^\n]|[0-7]{1,3}|x[[:xdigit:]]{1,2}))
90 FIRST_CCL_CHAR ([^\\\n]|{ESCSEQ})
91 CCL_CHAR ([^\\\n\]]|{ESCSEQ})
92 CCL_EXPR ("[:"[[:alpha:]]+":]")
97 static int bracelevel, didadef, indented_code;
98 static int doing_rule_action = false;
99 static int option_sense;
101 int doing_codeblock = false;
103 Char nmdef[MAXLINE], myesc();
107 ^{WS} indented_code = true; BEGIN(CODEBLOCK);
108 ^"/*" ACTION_ECHO; yy_push_state( COMMENT );
109 ^#{OPTWS}line{WS} yy_push_state( LINEDIR );
110 ^"%s"{NAME}? return SCDECL;
111 ^"%x"{NAME}? return XSCDECL;
114 line_directive_out( (FILE *) 0, 1 );
115 indented_code = false;
125 line_directive_out( (FILE *) 0, 1 );
130 ^"%pointer".*{NL} yytext_is_array = false; ++linenum;
131 ^"%array".*{NL} yytext_is_array = true; ++linenum;
133 ^"%option" BEGIN(OPTION); return OPTION_OP;
135 ^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL} ++linenum; /* ignore */
136 ^"%"{LEXOPT}{WS}.*{NL} ++linenum; /* ignore */
138 ^"%"[^sxaceknopr{}].* synerr( _( "unrecognized '%' directive" ) );
141 strcpy( nmstr, yytext );
147 ^{OPTWS}{NL} ++linenum; /* allows blank lines in section 1 */
148 {OPTWS}{NL} ACTION_ECHO; ++linenum; /* maybe end of comment line */
153 "*/" ACTION_ECHO; yy_pop_state();
156 [^*\n]*{NL} ++linenum; ACTION_ECHO;
161 [[:digit:]]+ linenum = myctoi( yytext );
164 flex_free( (void *) infilename );
165 infilename = copy_string( yytext + 1 );
166 infilename[strlen( infilename ) - 1] = '\0';
168 . /* ignore spurious characters */
172 ^"%}".*{NL} ++linenum; BEGIN(INITIAL);
174 {NAME}|{NOT_NAME}|. ACTION_ECHO;
186 {WS} /* separates name and definition */
189 strcpy( (char *) nmdef, yytext );
191 /* Skip trailing whitespace. */
192 for ( i = strlen( (char *) nmdef ) - 1;
193 i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t');
199 ndinstal( nmstr, nmdef );
205 synerr( _( "incomplete name definition" ) );
213 {NL} ++linenum; BEGIN(INITIAL);
214 {WS} option_sense = true;
218 no option_sense = ! option_sense;
220 7bit csize = option_sense ? 128 : 256;
221 8bit csize = option_sense ? 256 : 128;
223 align long_align = option_sense;
225 action_define( "YY_ALWAYS_INTERACTIVE", option_sense );
227 array yytext_is_array = option_sense;
228 backup backing_up_report = option_sense;
229 batch interactive = ! option_sense;
230 "c++" C_plus_plus = option_sense;
231 caseful|case-sensitive caseins = ! option_sense;
232 caseless|case-insensitive caseins = option_sense;
233 debug ddebug = option_sense;
234 default spprdflt = ! option_sense;
235 ecs useecs = option_sense;
237 useecs = usemecs = false;
238 use_read = fullspd = true;
241 useecs = usemecs = false;
242 use_read = fulltbl = true;
244 input ACTION_IFDEF("YY_NO_INPUT", ! option_sense);
245 interactive interactive = option_sense;
246 lex-compat lex_compat = option_sense;
248 action_define( "YY_MAIN", option_sense );
249 do_yywrap = ! option_sense;
251 meta-ecs usemecs = option_sense;
253 action_define( "YY_NEVER_INTERACTIVE", option_sense );
255 perf-report performance_report += option_sense ? 1 : -1;
256 pointer yytext_is_array = ! option_sense;
257 read use_read = option_sense;
258 reject reject_really_used = option_sense;
259 stack action_define( "YY_STACK_USED", option_sense );
260 stdinit do_stdinit = option_sense;
261 stdout use_stdout = option_sense;
262 unput ACTION_IFDEF("YY_NO_UNPUT", ! option_sense);
263 verbose printstats = option_sense;
264 warn nowarn = ! option_sense;
265 yylineno do_yylineno = option_sense;
266 yymore yymore_really_used = option_sense;
267 yywrap do_yywrap = option_sense;
269 yy_push_state ACTION_IFDEF("YY_NO_PUSH_STATE", ! option_sense);
270 yy_pop_state ACTION_IFDEF("YY_NO_POP_STATE", ! option_sense);
271 yy_top_state ACTION_IFDEF("YY_NO_TOP_STATE", ! option_sense);
273 yy_scan_buffer ACTION_IFDEF("YY_NO_SCAN_BUFFER", ! option_sense);
274 yy_scan_bytes ACTION_IFDEF("YY_NO_SCAN_BYTES", ! option_sense);
275 yy_scan_string ACTION_IFDEF("YY_NO_SCAN_STRING", ! option_sense);
277 outfile return OPT_OUTFILE;
278 prefix return OPT_PREFIX;
279 yyclass return OPT_YYCLASS;
282 strcpy( nmstr, yytext + 1 );
283 nmstr[strlen( nmstr ) - 1] = '\0';
287 (([a-mo-z]|n[a-np-z])[[:alpha:]\-+]*)|. {
288 format_synerr( _( "unrecognized %%option: %s" ),
294 <RECOVER>.*{NL} ++linenum; BEGIN(INITIAL);
298 ^"%{".* ++bracelevel; yyless( 2 ); /* eat only %{ */
299 ^"%}".* --bracelevel; yyless( 2 ); /* eat only %} */
301 ^{WS}.* ACTION_ECHO; /* indented code in prolog */
303 ^{NOT_WS}.* { /* non-indented code */
304 if ( bracelevel <= 0 )
305 { /* not in %{ ... %} */
306 yyless( 0 ); /* put it all back */
316 {NL} ++linenum; ACTION_ECHO;
321 yyterminate(); /* to stop the parser */
326 ^{OPTWS}{NL} ++linenum; /* allow blank lines in section 2 */
329 indented_code = false;
330 doing_codeblock = true;
332 BEGIN(PERCENT_BRACE_ACTION);
335 ^{OPTWS}"<" BEGIN(SC); return '<';
336 ^{OPTWS}"^" return '^';
337 \" BEGIN(QUOTE); return '"';
338 "{"/[[:digit:]] BEGIN(NUM); return '{';
339 "$"/([[:blank:]]|{NL}) return '$';
343 BEGIN(PERCENT_BRACE_ACTION);
347 doing_rule_action = true;
352 {WS}"|".*{NL} continued_action = true; ++linenum; return '\n';
355 yyless( yyleng - 2 ); /* put back '/', '*' */
357 continued_action = false;
361 ^{WS} /* allow indented rules */
364 /* This rule is separate from the one below because
365 * otherwise we get variable trailing context, so
366 * we can't build the scanner using -{f,F}.
369 continued_action = false;
374 doing_rule_action = true;
382 continued_action = false;
384 unput( '\n' ); /* so <ACTION> sees it */
388 doing_rule_action = true;
395 "<<EOF>>" return EOF_OP;
400 yyterminate(); /* to stop the parser */
403 "["({FIRST_CCL_CHAR}|{CCL_EXPR})({CCL_CHAR}|{CCL_EXPR})* {
406 strcpy( nmstr, yytext );
408 /* Check to see if we've already encountered this
411 if ( (cclval = ccllookup( (Char *) nmstr )) != 0 )
413 if ( input() != ']' )
414 synerr( _( "bad character class" ) );
422 /* We fudge a bit. We know that this ccl will
423 * soon be numbered as lastccl + 1 by cclinit.
425 cclinstal( (Char *) nmstr, lastccl + 1 );
427 /* Push back everything but the leading bracket
428 * so the ccl can be rescanned.
438 register Char *nmdefptr;
441 strcpy( nmstr, yytext + 1 );
442 nmstr[yyleng - 2] = '\0'; /* chop trailing brace */
444 if ( (nmdefptr = ndlookup( nmstr )) == 0 )
446 _( "undefined definition {%s}" ),
450 { /* push back name surrounded by ()'s */
451 int len = strlen( (char *) nmdefptr );
453 if ( lex_compat || nmdefptr[0] == '^' ||
454 (len > 0 && nmdefptr[len - 1] == '$') )
455 { /* don't use ()'s after all */
456 PUT_BACK_STRING((char *) nmdefptr, 0);
458 if ( nmdefptr[0] == '^' )
465 PUT_BACK_STRING((char *) nmdefptr, 0);
471 [/|*+?.(){}] return (unsigned char) yytext[0];
477 [,*] return (unsigned char) yytext[0];
478 ">" BEGIN(SECT2); return '>';
479 ">"/^ BEGIN(CARETISBOL); return '>';
482 format_synerr( _( "bad <start condition>: %s" ),
487 <CARETISBOL>"^" BEGIN(SECT2); return '^';
492 \" BEGIN(SECT2); return '"';
495 synerr( _( "missing quote" ) );
504 "^"/[^-\]\n] BEGIN(CCL); return '^';
505 "^"/("-"|"]") return '^';
506 . BEGIN(CCL); RETURNCHAR;
510 -/[^\]\n] return '-';
512 "]" BEGIN(SECT2); return ']';
514 synerr( _( "bad character class" ) );
521 "[:alnum:]" BEGIN(CCL); return CCE_ALNUM;
522 "[:alpha:]" BEGIN(CCL); return CCE_ALPHA;
523 "[:blank:]" BEGIN(CCL); return CCE_BLANK;
524 "[:cntrl:]" BEGIN(CCL); return CCE_CNTRL;
525 "[:digit:]" BEGIN(CCL); return CCE_DIGIT;
526 "[:graph:]" BEGIN(CCL); return CCE_GRAPH;
527 "[:lower:]" BEGIN(CCL); return CCE_LOWER;
528 "[:print:]" BEGIN(CCL); return CCE_PRINT;
529 "[:punct:]" BEGIN(CCL); return CCE_PUNCT;
530 "[:space:]" BEGIN(CCL); return CCE_SPACE;
531 "[:upper:]" BEGIN(CCL); return CCE_UPPER;
532 "[:xdigit:]" BEGIN(CCL); return CCE_XDIGIT;
535 _( "bad character class expression: %s" ),
537 BEGIN(CCL); return CCE_ALNUM;
543 yylval = myctoi( yytext );
548 "}" BEGIN(SECT2); return '}';
551 synerr( _( "bad character inside {}'s" ) );
557 synerr( _( "missing }" ) );
565 <PERCENT_BRACE_ACTION>{
566 {OPTWS}"%}".* bracelevel = 0;
568 <ACTION>"/*" ACTION_ECHO; yy_push_state( COMMENT );
573 CHECK_REJECT(yytext);
577 CHECK_YYMORE(yytext);
581 {NAME}|{NOT_NAME}|. ACTION_ECHO;
585 if ( bracelevel == 0 ||
586 (doing_codeblock && indented_code) )
588 if ( doing_rule_action )
589 add_action( "\tYY_BREAK\n" );
591 doing_rule_action = doing_codeblock = false;
598 /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
600 "{" ACTION_ECHO; ++bracelevel;
601 "}" ACTION_ECHO; --bracelevel;
602 [^[:alpha:]_{}"'/\n]+ ACTION_ECHO;
604 "'"([^'\\\n]|\\.)*"'" ACTION_ECHO; /* character constant */
605 \" ACTION_ECHO; BEGIN(ACTION_STRING);
609 if ( bracelevel == 0 )
611 if ( doing_rule_action )
612 add_action( "\tYY_BREAK\n" );
614 doing_rule_action = false;
622 [^"\\\n]+ ACTION_ECHO;
624 {NL} ++linenum; ACTION_ECHO;
625 \" ACTION_ECHO; BEGIN(ACTION);
629 <COMMENT,ACTION,ACTION_STRING><<EOF>> {
630 synerr( _( "EOF encountered inside an action" ) );
635 <SECT2,QUOTE,FIRSTCCL,CCL>{ESCSEQ} {
636 yylval = myesc( (Char *) yytext );
638 if ( YY_START == FIRSTCCL )
647 <<EOF>> sectnum = 0; yyterminate();
650 <*>.|\n format_synerr( _( "bad character: %s" ), yytext );
657 if ( --num_input_files > 0 )
659 set_input_file( *++input_files );
668 /* set_input_file - open the given file (if NULL, stdin) for scanning */
670 void set_input_file( file )
673 if ( file && strcmp( file, "-" ) )
675 infilename = copy_string( file );
676 yyin = fopen( infilename, "r" );
679 lerrsf( _( "can't open %s" ), file );
685 infilename = copy_string( "<stdin>" );
692 /* Wrapper routines for accessing the scanner's malloc routines. */
694 void *flex_alloc( size )
697 return (void *) malloc( size );
700 void *flex_realloc( ptr, size )
704 return (void *) realloc( ptr, size );
707 void flex_free( ptr )