From c504c9045f5ded20bc95d819d25c8ae4acc883b5 Mon Sep 17 00:00:00 2001 From: millaway Date: Wed, 17 Oct 2001 06:07:38 +0000 Subject: flex now generates header file upon request. --- flex.skl | 41 +++++++++++++++++++++++++++++++++-------- flexdef.h | 4 ++++ main.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- misc.c | 14 ++++++++++++++ parse.y | 4 +++- scan.l | 1 + 6 files changed, 105 insertions(+), 11 deletions(-) diff --git a/flex.skl b/flex.skl index a49f3ba..ba90d71 100644 --- a/flex.skl +++ b/flex.skl @@ -256,9 +256,11 @@ struct yy_buffer_state }; %- Standard (non-C++) definition +%c #ifndef YY_REENTRANT static YY_BUFFER_STATE yy_current_buffer = 0; #endif +%e %* /* We provide macros for accessing buffer states in case in the @@ -271,6 +273,7 @@ static YY_BUFFER_STATE yy_current_buffer = 0; %- Standard (non-C++) definition #ifndef YY_REENTRANT +%c /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; @@ -288,7 +291,7 @@ static int yy_start = 0; /* start state number */ * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; - +%e #endif /* end !YY_REENTRANT */ void yyrestart YY_PROTO(( FILE *input_file YY_LAST_ARG )); @@ -306,9 +309,11 @@ YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str YY_LAST_ARG )); YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len YY_LAST_ARG )); %* +%c static void *yy_flex_alloc YY_PROTO(( yy_size_t YY_LAST_ARG )); static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t YY_LAST_ARG )); static void yy_flex_free YY_PROTO(( void * YY_LAST_ARG )); +%e #define yy_new_buffer yy_create_buffer @@ -333,10 +338,12 @@ static void yy_flex_free YY_PROTO(( void * YY_LAST_ARG )); %% yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here %- Standard (non-C++) definition +%c static yy_state_type yy_get_previous_state YY_PROTO(( YY_ONLY_ARG )); static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state YY_LAST_ARG)); static int yy_get_next_buffer YY_PROTO(( YY_ONLY_ARG )); static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); +%e %* /* Done after the current pattern has been matched and before the @@ -344,16 +351,17 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); */ #define YY_DO_BEFORE_ACTION \ yytext_ptr = yy_bp; \ -%% code to fiddle yytext and yyleng for yymore() goes here +%% code to fiddle yytext and yyleng for yymore() goes here \ YY_G(yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ -%% code to copy yytext_ptr to yytext[] goes here, if %array +%% code to copy yytext_ptr to yytext[] goes here, if %array \ YY_G(yy_c_buf_p) = yy_cp; %* +%c %% data tables for the DFA and the user's section 1 definitions go here - +%e #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * @@ -406,7 +414,9 @@ struct yy_globals_t }; +%c static int yy_init_globals YY_PROTO(( void * )); +%e /* This must go here because YYSTYPE and YYLSTYPE are included * from bison output in section 1.*/ @@ -489,9 +499,11 @@ extern int yywrap YY_PROTO(( YY_ONLY_ARG )); #endif %- +%c #ifndef YY_NO_UNPUT static void yyunput YY_PROTO(( int c, char *buf_ptr YY_LAST_ARG)); #endif +%e %* #ifndef yytext_ptr @@ -504,19 +516,23 @@ static int yy_flex_strlen YY_PROTO(( yyconst char * YY_LAST_ARG)); #ifndef YY_NO_INPUT %- Standard (non-C++) definition +%c #ifdef __cplusplus static int yyinput YY_PROTO(( YY_ONLY_ARG )); #else static int input YY_PROTO(( YY_ONLY_ARG )); #endif +%e %* #endif #if YY_STACK_USED #ifndef YY_REENTRANT +%c static int yy_start_stack_ptr = 0; static int yy_start_stack_depth = 0; static int *yy_start_stack = 0; +%e #endif #ifndef YY_NO_PUSH_STATE static void yy_push_state YY_PROTO(( int new_state YY_LAST_ARG)); @@ -572,8 +588,8 @@ YY_MALLOC_DECL */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ -%% fread()/read() definition of YY_INPUT goes here unless we're doing C++ -%+ C++ definition +%% fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ +%+ C++ definition \ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); %* @@ -634,6 +650,9 @@ YY_MALLOC_DECL # endif #endif + +extern int yylex YY_PROTO( YY_LEX_ARGS ); + #define YY_DECL int yylex YY_LEX_ARGS %+ C++ definition #define YY_DECL int yyFlexLexer::yylex() @@ -654,6 +673,7 @@ YY_MALLOC_DECL %% YY_RULE_SETUP definition goes here +%c YY_DECL { register yy_state_type yy_current_state; @@ -859,8 +879,9 @@ do_action: /* This label is used only to access EOF actions. */ } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ - +%e %+ +%c yyFlexLexer::yyFlexLexer( FLEX_STD istream* arg_yyin, FLEX_STD ostream* arg_yyout ) { yyin = arg_yyin; @@ -943,6 +964,7 @@ void yyFlexLexer::LexerOutput( const char* buf, int size ) { (void) yyout->write( buf, size ); } +%e %* /* yy_get_next_buffer - try to read in a new buffer @@ -954,6 +976,7 @@ void yyFlexLexer::LexerOutput( const char* buf, int size ) */ %- +%c #ifdef YY_USE_PROTOS static int yy_get_next_buffer(YY_ONLY_ARG) #else @@ -1090,11 +1113,12 @@ int yyFlexLexer::yy_get_next_buffer() return ret_val; } - +%e /* yy_get_previous_state - get the state just before the EOB char was reached */ %- +%c #ifdef YY_USE_PROTOS static yy_state_type yy_get_previous_state(YY_ONLY_ARG) #else @@ -2074,3 +2098,4 @@ int main() return 0; } #endif +%e diff --git a/flexdef.h b/flexdef.h index 3f6770c..e046288 100644 --- a/flexdef.h +++ b/flexdef.h @@ -1046,4 +1046,8 @@ extern struct Buf* buf_strdefine PROTO((struct Buf* buf, const char* str, const /* buffer for #define's generated by user-options on cmd line. */ extern struct Buf userdef_buf; +/* For blocking out code from the header file. */ +#define OUT_BEGIN_CODE() out_str("#ifndef %sIN_HEADER\n",prefix) +#define OUT_END_CODE() out_str("#endif /* !%sIN_HEADER */\n",prefix); + #endif /* not defined FLEXDEF_H */ diff --git a/main.c b/main.c index 634b67e..4020305 100644 --- a/main.c +++ b/main.c @@ -295,7 +295,7 @@ void check_options() outfilename = outfile_path; } - prev_stdout = freopen( outfilename, "w", stdout ); + prev_stdout = freopen( outfilename, "w+", stdout ); if ( prev_stdout == NULL ) lerrsf( _( "could not create %s" ), outfilename ); @@ -395,9 +395,13 @@ void flexend( exit_status ) int exit_status; { - int tblsiz; + static int called_before = -1; /* prevent infinite recursion. */ + int tblsiz; int unlink(); + if( ++called_before ) + exit( exit_status ); + if ( skelfile != NULL ) { if ( ferror( skelfile ) ) @@ -409,6 +413,45 @@ int exit_status; skelname ); } + if ( headerfilename && exit_status == 0 && outfile_created && !ferror(stdout)) + { + /* Copy the file we just wrote to a header file. */ + #define COPY_SZ 512 + FILE *header_out; + char copybuf[COPY_SZ]; + int ncopy; + + /* rewind the outfile file. */ + fflush(stdout); + fseek(stdout, 0L, SEEK_SET); + + header_out = fopen(headerfilename, "w"); + if ( header_out == NULL) + lerrsf( _( "could not create %s"), headerfilename ); + + fprintf(header_out, + "#ifndef %sHEADER_H\n" + "#define %sHEADER_H 1\n" + "#define %sIN_HEADER 1\n", + prefix,prefix,prefix); + fflush(header_out); + + while((ncopy=fread(copybuf, 1, COPY_SZ, stdout)) > 0) + if ( fwrite(copybuf, 1, ncopy, header_out) <= 0) + break; + + fflush(header_out); + fprintf(header_out, + "\n" + "#undef %sIN_HEADER\n" + "#endif /* %sHEADER_H */\n", + prefix, prefix); + + if ( ferror( header_out ) ) + lerrsf( _( "error creating header file %s" ), headerfilename); + fclose(header_out); + } + if ( exit_status != 0 && outfile_created ) { if ( ferror( stdout ) ) @@ -424,6 +467,7 @@ int exit_status; outfilename ); } + if ( backing_up_report && backing_up_file ) { if ( num_backing_up == 0 ) @@ -1087,6 +1131,7 @@ _( "Variable trailing context rules entail a large performance penalty\n" ) ); else { + OUT_BEGIN_CODE(); /* In reentrant scanner, stdinit is handled in flex.skl. */ if ( do_stdinit ) { @@ -1117,6 +1162,7 @@ _( "Variable trailing context rules entail a large performance penalty\n" ) ); outn( yy_nostdinit ); outn( "#endif" ); } + OUT_END_CODE(); } if ( fullspd ) @@ -1133,7 +1179,9 @@ _( "Variable trailing context rules entail a large performance penalty\n" ) ); if ( do_yylineno && ! C_plus_plus && ! reentrant ) { outn( "extern int yylineno;" ); + OUT_BEGIN_CODE(); outn( "int yylineno = 1;" ); + OUT_END_CODE(); } if ( C_plus_plus ) diff --git a/misc.c b/misc.c index 3f320d9..dc5b6ef 100644 --- a/misc.c +++ b/misc.c @@ -794,6 +794,12 @@ void skelout() { /* copy from skel array */ if ( buf[0] == '%' ) { /* control line */ + /* print the control line as a comment. */ + if (buf[strlen(buf)-1]=='\\') + out_str("/* %s */\\\n", buf); + else + out_str("/* %s */\n", buf); + switch ( buf[1] ) { case '%': @@ -811,6 +817,14 @@ void skelout() do_copy = 1; break; + case 'c': + OUT_BEGIN_CODE(); + break; + + case 'e': + OUT_END_CODE(); + break; + default: flexfatal( _( "bad line in skeleton file" ) ); diff --git a/parse.y b/parse.y index 3a55691..26b646b 100644 --- a/parse.y +++ b/parse.y @@ -1,7 +1,7 @@ /* parse.y - parser for flex input */ %token CHAR NUMBER SECTEND SCDECL XSCDECL NAME PREVCCL EOF_OP -%token OPTION_OP OPT_OUTFILE OPT_PREFIX OPT_YYCLASS +%token OPTION_OP OPT_OUTFILE OPT_PREFIX OPT_YYCLASS OPT_HEADER %token CCE_ALNUM CCE_ALPHA CCE_BLANK CCE_CNTRL CCE_DIGIT CCE_GRAPH %token CCE_LOWER CCE_PRINT CCE_PUNCT CCE_SPACE CCE_UPPER CCE_XDIGIT @@ -196,6 +196,8 @@ option : OPT_OUTFILE '=' NAME { prefix = copy_string( nmstr ); } | OPT_YYCLASS '=' NAME { yyclass = copy_string( nmstr ); } + | OPT_HEADER '=' NAME + { headerfilename = copy_string( nmstr ); } ; sect2 : sect2 scon initforrule flexrule '\n' diff --git a/scan.l b/scan.l index 22b2e48..ac58aaf 100644 --- a/scan.l +++ b/scan.l @@ -301,6 +301,7 @@ LEXOPT [aceknopr] outfile return OPT_OUTFILE; prefix return OPT_PREFIX; yyclass return OPT_YYCLASS; + header return OPT_HEADER; \"[^"\n]*\" { strcpy( nmstr, yytext + 1 ); -- cgit v1.2.1