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 /* $NetBSD: scan.l,v 1.12 2003/07/14 11:36:49 itojun Exp $ */
35 #define ACTION_ECHO add_action( yytext )
36 #define ACTION_IFDEF(def, should_define) \
38 if ( should_define ) \
39 action_define( def, 1 ); \
42 #define MARK_END_OF_PROLOG mark_prolog();
48 yylval = (unsigned char) yytext[0]; \
52 strlcpy(nmstr, yytext, sizeof(nmstr)); \
55 #define PUT_BACK_STRING(str, start) \
56 for ( i = strlen( str ) - 1; i >= start; --i ) \
59 #define CHECK_REJECT(str) \
60 if ( all_upper( str ) ) \
63 #define CHECK_YYMORE(str) \
64 if ( all_lower( str ) ) \
68 %option caseless nodefault outfile="scan.c" stack noyy_top_state
71 %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
72 %x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION
81 NAME ([[:alpha:]_][[:alnum:]_-]*)
82 NOT_NAME [^[:alpha:]_*\n]+
86 ESCSEQ (\\([^\n]|[0-7]{1,3}|x[[:xdigit:]]{1,2}))
88 FIRST_CCL_CHAR ([^\\\n]|{ESCSEQ})
89 CCL_CHAR ([^\\\n\]]|{ESCSEQ})
90 CCL_EXPR ("[:"[[:alpha:]]+":]")
95 static int bracelevel, didadef, indented_code;
96 static int doing_rule_action = false;
97 static int option_sense;
99 int doing_codeblock = false;
105 ^{WS} indented_code = true; BEGIN(CODEBLOCK);
106 ^"/*" ACTION_ECHO; yy_push_state( COMMENT );
107 ^#{OPTWS}line{WS} yy_push_state( LINEDIR );
108 ^"%s"{NAME}? return SCDECL;
109 ^"%x"{NAME}? return XSCDECL;
112 line_directive_out( (FILE *) 0, 1 );
113 indented_code = false;
123 line_directive_out( (FILE *) 0, 1 );
128 ^"%pointer".*{NL} yytext_is_array = false; ++linenum;
129 ^"%array".*{NL} yytext_is_array = true; ++linenum;
131 ^"%option" BEGIN(OPTION); return OPTION_OP;
133 ^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL} ++linenum; /* ignore */
134 ^"%"{LEXOPT}{WS}.*{NL} ++linenum; /* ignore */
136 ^"%"[^sxaceknopr{}].* synerr( _( "unrecognized '%' directive" ) );
139 strlcpy(nmstr, yytext, sizeof(nmstr));
145 ^{OPTWS}{NL} ++linenum; /* allows blank lines in section 1 */
146 {OPTWS}{NL} ACTION_ECHO; ++linenum; /* maybe end of comment line */
151 "*/" ACTION_ECHO; yy_pop_state();
154 [^*\n]*{NL} ++linenum; ACTION_ECHO;
159 [[:digit:]]+ linenum = myctoi( yytext );
162 flex_free( (void *) infilename );
163 infilename = copy_string( yytext + 1 );
164 infilename[strlen( infilename ) - 1] = '\0';
166 . /* ignore spurious characters */
170 ^"%}".*{NL} ++linenum; BEGIN(INITIAL);
172 {NAME}|{NOT_NAME}|. ACTION_ECHO;
184 {WS} /* separates name and definition */
187 strlcpy((char *)nmdef, yytext, sizeof(nmdef));
189 /* Skip trailing whitespace. */
190 for ( i = strlen( (char *) nmdef ) - 1;
191 i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t');
197 ndinstal(nmstr, nmdef);
203 synerr( _( "incomplete name definition" ) );
211 {NL} ++linenum; BEGIN(INITIAL);
212 {WS} option_sense = true;
216 no option_sense = ! option_sense;
218 7bit csize = option_sense ? 128 : 256;
219 8bit csize = option_sense ? 256 : 128;
221 align long_align = option_sense;
223 action_define( "YY_ALWAYS_INTERACTIVE", option_sense );
225 array yytext_is_array = option_sense;
226 backup backing_up_report = option_sense;
227 batch interactive = ! option_sense;
228 "c++" C_plus_plus = option_sense;
229 caseful|case-sensitive caseins = ! option_sense;
230 caseless|case-insensitive caseins = option_sense;
231 debug ddebug = option_sense;
232 default spprdflt = ! option_sense;
233 ecs useecs = option_sense;
235 useecs = usemecs = false;
236 use_read = fullspd = true;
239 useecs = usemecs = false;
240 use_read = fulltbl = true;
242 input ACTION_IFDEF("YY_NO_INPUT", ! option_sense);
243 interactive interactive = option_sense;
244 lex-compat lex_compat = option_sense;
246 action_define( "YY_MAIN", option_sense );
247 do_yywrap = ! option_sense;
249 meta-ecs usemecs = option_sense;
251 action_define( "YY_NEVER_INTERACTIVE", option_sense );
253 perf-report performance_report += option_sense ? 1 : -1;
254 pointer yytext_is_array = ! option_sense;
255 read use_read = option_sense;
256 reject reject_really_used = option_sense;
257 stack action_define( "YY_STACK_USED", option_sense );
258 stdinit do_stdinit = option_sense;
259 stdout use_stdout = option_sense;
260 unput ACTION_IFDEF("YY_NO_UNPUT", ! option_sense);
261 verbose printstats = option_sense;
262 warn nowarn = ! option_sense;
263 yylineno do_yylineno = option_sense;
264 yymore yymore_really_used = option_sense;
265 yywrap do_yywrap = option_sense;
267 yy_push_state ACTION_IFDEF("YY_NO_PUSH_STATE", ! option_sense);
268 yy_pop_state ACTION_IFDEF("YY_NO_POP_STATE", ! option_sense);
269 yy_top_state ACTION_IFDEF("YY_NO_TOP_STATE", ! option_sense);
271 yy_scan_buffer ACTION_IFDEF("YY_NO_SCAN_BUFFER", ! option_sense);
272 yy_scan_bytes ACTION_IFDEF("YY_NO_SCAN_BYTES", ! option_sense);
273 yy_scan_string ACTION_IFDEF("YY_NO_SCAN_STRING", ! option_sense);
275 outfile return OPT_OUTFILE;
276 prefix return OPT_PREFIX;
277 yyclass return OPT_YYCLASS;
280 strlcpy(nmstr, yytext + 1, sizeof(nmstr));
281 nmstr[strlen( nmstr ) - 1] = '\0';
285 (([a-mo-z]|n[a-np-z])[[:alpha:]\-+]*)|. {
286 format_synerr( _( "unrecognized %%option: %s" ),
292 <RECOVER>.*{NL} ++linenum; BEGIN(INITIAL);
296 ^"%{".* ++bracelevel; yyless( 2 ); /* eat only %{ */
297 ^"%}".* --bracelevel; yyless( 2 ); /* eat only %} */
299 ^{WS}.* ACTION_ECHO; /* indented code in prolog */
301 ^{NOT_WS}.* { /* non-indented code */
302 if ( bracelevel <= 0 )
303 { /* not in %{ ... %} */
304 yyless( 0 ); /* put it all back */
314 {NL} ++linenum; ACTION_ECHO;
319 yyterminate(); /* to stop the parser */
324 ^{OPTWS}{NL} ++linenum; /* allow blank lines in section 2 */
327 indented_code = false;
328 doing_codeblock = true;
330 BEGIN(PERCENT_BRACE_ACTION);
333 ^{OPTWS}"<" BEGIN(SC); return '<';
334 ^{OPTWS}"^" return '^';
335 \" BEGIN(QUOTE); return '"';
336 "{"/[[:digit:]] BEGIN(NUM); return '{';
337 "$"/([[:blank:]]|{NL}) return '$';
341 BEGIN(PERCENT_BRACE_ACTION);
345 doing_rule_action = true;
350 {WS}"|".*{NL} continued_action = true; ++linenum; return '\n';
353 yyless( yyleng - 2 ); /* put back '/', '*' */
355 continued_action = false;
359 ^{WS} /* allow indented rules */
362 /* This rule is separate from the one below because
363 * otherwise we get variable trailing context, so
364 * we can't build the scanner using -{f,F}.
367 continued_action = false;
372 doing_rule_action = true;
380 continued_action = false;
382 unput( '\n' ); /* so <ACTION> sees it */
386 doing_rule_action = true;
393 "<<EOF>>" return EOF_OP;
398 yyterminate(); /* to stop the parser */
401 "["({FIRST_CCL_CHAR}|{CCL_EXPR})({CCL_CHAR}|{CCL_EXPR})* {
404 strlcpy(nmstr, yytext, sizeof(nmstr));
406 /* Check to see if we've already encountered this
409 if ( (cclval = ccllookup( (Char *) nmstr )) != 0 )
411 if ( input() != ']' )
412 synerr( _( "bad character class" ) );
420 /* We fudge a bit. We know that this ccl will
421 * soon be numbered as lastccl + 1 by cclinit.
423 cclinstal( (Char *) nmstr, lastccl + 1 );
425 /* Push back everything but the leading bracket
426 * so the ccl can be rescanned.
436 register Char *nmdefptr;
438 strlcpy(nmstr, yytext + 1, sizeof(nmstr));
439 nmstr[yyleng - 2] = '\0'; /* chop trailing brace */
441 if ( (nmdefptr = ndlookup( nmstr )) == 0 )
443 _( "undefined definition {%s}" ),
447 { /* push back name surrounded by ()'s */
448 int len = strlen( (char *) nmdefptr );
450 if ( lex_compat || nmdefptr[0] == '^' ||
451 (len > 0 && nmdefptr[len - 1] == '$') )
452 { /* don't use ()'s after all */
453 PUT_BACK_STRING((char *) nmdefptr, 0);
455 if ( nmdefptr[0] == '^' )
462 PUT_BACK_STRING((char *) nmdefptr, 0);
468 [/|*+?.(){}] return (unsigned char) yytext[0];
474 [,*] return (unsigned char) yytext[0];
475 ">" BEGIN(SECT2); return '>';
476 ">"/^ BEGIN(CARETISBOL); return '>';
479 format_synerr( _( "bad <start condition>: %s" ),
484 <CARETISBOL>"^" BEGIN(SECT2); return '^';
489 \" BEGIN(SECT2); return '"';
492 synerr( _( "missing quote" ) );
501 "^"/[^-\]\n] BEGIN(CCL); return '^';
502 "^"/("-"|"]") return '^';
503 . BEGIN(CCL); RETURNCHAR;
507 -/[^\]\n] return '-';
509 "]" BEGIN(SECT2); return ']';
511 synerr( _( "bad character class" ) );
518 "[:alnum:]" BEGIN(CCL); return CCE_ALNUM;
519 "[:alpha:]" BEGIN(CCL); return CCE_ALPHA;
520 "[:blank:]" BEGIN(CCL); return CCE_BLANK;
521 "[:cntrl:]" BEGIN(CCL); return CCE_CNTRL;
522 "[:digit:]" BEGIN(CCL); return CCE_DIGIT;
523 "[:graph:]" BEGIN(CCL); return CCE_GRAPH;
524 "[:lower:]" BEGIN(CCL); return CCE_LOWER;
525 "[:print:]" BEGIN(CCL); return CCE_PRINT;
526 "[:punct:]" BEGIN(CCL); return CCE_PUNCT;
527 "[:space:]" BEGIN(CCL); return CCE_SPACE;
528 "[:upper:]" BEGIN(CCL); return CCE_UPPER;
529 "[:xdigit:]" BEGIN(CCL); return CCE_XDIGIT;
532 _( "bad character class expression: %s" ),
534 BEGIN(CCL); return CCE_ALNUM;
540 yylval = myctoi( yytext );
545 "}" BEGIN(SECT2); return '}';
548 synerr( _( "bad character inside {}'s" ) );
554 synerr( _( "missing }" ) );
562 <PERCENT_BRACE_ACTION>{
563 {OPTWS}"%}".* bracelevel = 0;
565 <ACTION>"/*" ACTION_ECHO; yy_push_state( COMMENT );
570 CHECK_REJECT(yytext);
574 CHECK_YYMORE(yytext);
578 {NAME}|{NOT_NAME}|. ACTION_ECHO;
582 if ( bracelevel == 0 ||
583 (doing_codeblock && indented_code) )
585 if ( doing_rule_action )
586 add_action( "\tYY_BREAK\n" );
588 doing_rule_action = doing_codeblock = false;
595 /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
597 "{" ACTION_ECHO; ++bracelevel;
598 "}" ACTION_ECHO; --bracelevel;
599 [^[:alpha:]_{}"'/\n]+ ACTION_ECHO;
601 "'"([^'\\\n]|\\.)*"'" ACTION_ECHO; /* character constant */
602 \" ACTION_ECHO; BEGIN(ACTION_STRING);
606 if ( bracelevel == 0 )
608 if ( doing_rule_action )
609 add_action( "\tYY_BREAK\n" );
611 doing_rule_action = false;
619 [^"\\\n]+ ACTION_ECHO;
621 {NL} ++linenum; ACTION_ECHO;
622 \" ACTION_ECHO; BEGIN(ACTION);
626 <COMMENT,ACTION,ACTION_STRING><<EOF>> {
627 synerr( _( "EOF encountered inside an action" ) );
632 <SECT2,QUOTE,FIRSTCCL,CCL>{ESCSEQ} {
633 yylval = myesc( (Char *) yytext );
635 if ( YY_START == FIRSTCCL )
644 <<EOF>> sectnum = 0; yyterminate();
647 <*>.|\n format_synerr( _( "bad character: %s" ), yytext );
654 if ( --num_input_files > 0 )
656 set_input_file( *++input_files );
665 /* set_input_file - open the given file (if NULL, stdin) for scanning */
667 void set_input_file( file )
670 if ( file && strcmp( file, "-" ) )
672 infilename = copy_string( file );
673 yyin = fopen( infilename, "r" );
676 lerrsf( _( "can't open %s" ), file );
682 infilename = copy_string( "<stdin>" );
689 /* Wrapper routines for accessing the scanner's malloc routines. */
691 void *flex_alloc( size )
694 return (void *) malloc( size );
697 void *flex_realloc( ptr, size )
701 return (void *) realloc( ptr, size );
704 void flex_free( ptr )