summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/flex.texi21
-rw-r--r--src/FlexLexer.h41
-rw-r--r--src/flex.skl123
3 files changed, 141 insertions, 44 deletions
diff --git a/doc/flex.texi b/doc/flex.texi
index c7edce6..9b7d83f 100644
--- a/doc/flex.texi
+++ b/doc/flex.texi
@@ -3764,8 +3764,7 @@ defaults to generating the scanner to the file @file{lex.yy.cc} instead
of @file{lex.yy.c}. The generated scanner includes the header file
@file{FlexLexer.h}, which defines the interface to two C++ classes.
-The first class,
-@code{FlexLexer},
+The first class in @file{FlexLexer.h}, @code{FlexLexer},
provides an abstract base class defining the general scanner class
interface. It provides the following member functions:
@@ -3799,10 +3798,10 @@ returns the current setting of the debugging flag.
Also provided are member functions equivalent to
@code{yy_switch_to_buffer()}, @code{yy_create_buffer()} (though the
-first argument is an @code{istream*} object pointer and not a
+first argument is an @code{istream&} object reference and not a
@code{FILE*)}, @code{yy_flush_buffer()}, @code{yy_delete_buffer()}, and
-@code{yyrestart()} (again, the first argument is a @code{istream*}
-object pointer).
+@code{yyrestart()} (again, the first argument is a @code{istream&}
+object reference).
@tindex yyFlexLexer (C++ only)
@tindex FlexLexer (C++ only)
@@ -3813,9 +3812,12 @@ additional member functions:
@table @code
@findex yyFlexLexer constructor (C++ only)
@item yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 )
+@item yyFlexLexer( istream& arg_yyin, ostream& arg_yyout )
constructs a @code{yyFlexLexer} object using the given streams for input
and output. If not specified, the streams default to @code{cin} and
-@code{cout}, respectively.
+@code{cout}, respectively. @code{yyFlexLexer} does not take ownership of
+its stream arguments. It's up to the user to ensure the streams pointed
+to remain alive at least as long as the @code{yyFlexLexer} instance.
@findex yylex (C++ version)
@item virtual int yylex()
@@ -3832,11 +3834,13 @@ instead of @code{yyFlexLexer}. In this case, rather than generating
@findex switch_streams (C++ only)
@item virtual void switch_streams(istream* new_in = 0, ostream* new_out = 0)
+@item virtual void switch_streams(istream& new_in, ostream& new_out)
reassigns @code{yyin} to @code{new_in} (if non-null) and @code{yyout} to
@code{new_out} (if non-null), deleting the previous input buffer if
@code{yyin} is reassigned.
@item int yylex( istream* new_in, ostream* new_out = 0 )
+@item int yylex( istream& new_in, ostream& new_out )
first switches the input streams via @code{switch_streams( new_in,
new_out )} and then returns the value of @code{yylex()}.
@end table
@@ -3893,7 +3897,7 @@ Here is an example of a simple C++ scanner:
int mylineno = 0;
%}
- %option noyywrap
+ %option noyywrap c++
string \"[^\n"]+\"
@@ -3938,6 +3942,9 @@ Here is an example of a simple C++ scanner:
%%
+ // This include is required if main() is an another source file.
+ //#include <FlexLexer.h>
+
int main( int /* argc */, char** /* argv */ )
{
FlexLexer* lexer = new yyFlexLexer;
diff --git a/src/FlexLexer.h b/src/FlexLexer.h
index bad4ce0..b725b1f 100644
--- a/src/FlexLexer.h
+++ b/src/FlexLexer.h
@@ -69,22 +69,33 @@ public:
yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
virtual struct yy_buffer_state*
yy_create_buffer( FLEX_STD istream* s, int size ) = 0;
+ virtual struct yy_buffer_state*
+ yy_create_buffer( FLEX_STD istream& s, int size ) = 0;
virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
- virtual void yyrestart( FLEX_STD istream* s ) = 0;
+ virtual void yyrestart( FLEX_STD istream* s ) = 0;
+ virtual void yyrestart( FLEX_STD istream& s ) = 0;
virtual int yylex() = 0;
// Call yylex with new input/output sources.
- int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 )
- {
+ int yylex( FLEX_STD istream& new_in, FLEX_STD ostream& new_out )
+ {
+ switch_streams( new_in, new_out );
+ return yylex();
+ }
+
+ int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0)
+ {
switch_streams( new_in, new_out );
return yylex();
- }
+ }
// Switch to new input/output streams. A nil stream pointer
// indicates "keep the current one".
- virtual void switch_streams( FLEX_STD istream* new_in = 0,
- FLEX_STD ostream* new_out = 0 ) = 0;
+ virtual void switch_streams( FLEX_STD istream* new_in,
+ FLEX_STD ostream* new_out ) = 0;
+ virtual void switch_streams( FLEX_STD istream& new_in,
+ FLEX_STD ostream& new_out ) = 0;
int lineno() const { return yylineno; }
@@ -113,20 +124,28 @@ class yyFlexLexer : public FlexLexer {
public:
// arg_yyin and arg_yyout default to the cin and cout, but we
// only make that assignment when initializing in yylex().
+ yyFlexLexer( FLEX_STD istream& arg_yyin, FLEX_STD ostream& arg_yyout );
yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 );
+private:
+ void ctor_common();
+
+public:
virtual ~yyFlexLexer();
void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
- struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size );
+ struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size );
+ struct yy_buffer_state* yy_create_buffer( FLEX_STD istream& s, int size );
void yy_delete_buffer( struct yy_buffer_state* b );
void yyrestart( FLEX_STD istream* s );
+ void yyrestart( FLEX_STD istream& s );
void yypush_buffer_state( struct yy_buffer_state* new_buffer );
void yypop_buffer_state();
virtual int yylex();
- virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 );
+ virtual void switch_streams( FLEX_STD istream& new_in, FLEX_STD ostream& new_out );
+ virtual void switch_streams( FLEX_STD istream* new_in = 0, FLEX_STD ostream* new_out = 0 );
virtual int yywrap();
protected:
@@ -138,7 +157,7 @@ protected:
int yyinput();
void yy_load_buffer_state();
- void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s );
+ void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream& s );
void yy_flush_buffer( struct yy_buffer_state* b );
int yy_start_stack_ptr;
@@ -153,8 +172,8 @@ protected:
yy_state_type yy_try_NUL_trans( yy_state_type current_state );
int yy_get_next_buffer();
- FLEX_STD istream* yyin; // input source for default LexerInput
- FLEX_STD ostream* yyout; // output sink for default LexerOutput
+ FLEX_STD istream yyin; // input source for default LexerInput
+ FLEX_STD ostream yyout; // output sink for default LexerOutput
// yy_hold_char holds the character lost when yytext is formed.
char yy_hold_char;
diff --git a/src/flex.skl b/src/flex.skl
index a1f6db6..73a0b9e 100644
--- a/src/flex.skl
+++ b/src/flex.skl
@@ -556,7 +556,7 @@ struct yy_buffer_state
%endif
%if-c++-only
- std::istream* yy_input_file;
+ std::streambuf* yy_input_file;
%endif
@@ -1338,7 +1338,7 @@ m4_ifdef( [[M4_YY_USES_REJECT]],
yyin = stdin;
%endif
%if-c++-only
- yyin = & std::cin;
+ yyin.rdbuf(std::cin.rdbuf());
%endif
if ( ! yyout )
@@ -1346,7 +1346,7 @@ m4_ifdef( [[M4_YY_USES_REJECT]],
yyout = stdout;
%endif
%if-c++-only
- yyout = & std::cout;
+ yyout.rdbuf(std::cout.rdbuf());
%endif
if ( ! YY_CURRENT_BUFFER ) {
@@ -1412,7 +1412,12 @@ do_action: /* This label is used only to access EOF actions. */
* back-up) that will match for the new input source.
*/
YY_G(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+%if-c-only
YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+%endif
+%if-c++-only
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin.rdbuf();
+%endif
YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
}
@@ -1525,11 +1530,29 @@ do_action: /* This label is used only to access EOF actions. */
%if-c++-only
%not-for-header
/* The contents of this function are C++ specific, so the YY_G macro is not used.
+ * This constructor simply maintains backward compatibility.
+ * DEPRECATED
+ */
+yyFlexLexer::yyFlexLexer( FLEX_STD istream* arg_yyin, FLEX_STD ostream* arg_yyout ):
+ yyin(arg_yyin ? arg_yyin->rdbuf() : std::cin.rdbuf()),
+ yyout(arg_yyout ? arg_yyout->rdbuf() : std::cout.rdbuf())
+{
+ ctor_common();
+}
+
+/* The contents of this function are C++ specific, so the YY_G macro is not used.
+ */
+yyFlexLexer::yyFlexLexer( std::istream& arg_yyin, std::ostream& arg_yyout ):
+ yyin(arg_yyin.rdbuf()),
+ yyout(arg_yyout.rdbuf())
+{
+ ctor_common();
+}
+
+/* The contents of this function are C++ specific, so the YY_G macro is not used.
*/
-yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout )
+void yyFlexLexer::ctor_common()
{
- yyin = arg_yyin;
- yyout = arg_yyout;
yy_c_buf_p = 0;
yy_init = 0;
yy_start = 0;
@@ -1572,16 +1595,29 @@ yyFlexLexer::~yyFlexLexer()
/* The contents of this function are C++ specific, so the YY_G macro is not used.
*/
+void yyFlexLexer::switch_streams( std::istream& new_in, std::ostream& new_out )
+{
+ // was if( new_in )
+ yy_delete_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG);
+ yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE M4_YY_CALL_LAST_ARG) M4_YY_CALL_LAST_ARG);
+
+ // was if( new_out )
+ yyout.rdbuf(new_out.rdbuf());
+}
+
+/* The contents of this function are C++ specific, so the YY_G macro is not used.
+ */
void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out )
{
- if ( new_in )
- {
- yy_delete_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG);
- yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE M4_YY_CALL_LAST_ARG) M4_YY_CALL_LAST_ARG);
- }
+ if( ! new_in ) {
+ new_in = &yyin;
+ }
- if ( new_out )
- yyout = new_out;
+ if ( ! new_out ) {
+ new_out = &yyout;
+ }
+
+ switch_streams(*new_in, *new_out);
}
#ifdef YY_INTERACTIVE
@@ -1590,33 +1626,33 @@ int yyFlexLexer::LexerInput( char* buf, int /* max_size */ )
int yyFlexLexer::LexerInput( char* buf, int max_size )
#endif
{
- if ( yyin->eof() || yyin->fail() )
+ if ( yyin.eof() || yyin.fail() )
return 0;
#ifdef YY_INTERACTIVE
- yyin->get( buf[0] );
+ yyin.get( buf[0] );
- if ( yyin->eof() )
+ if ( yyin.eof() )
return 0;
- if ( yyin->bad() )
+ if ( yyin.bad() )
return -1;
return 1;
#else
- (void) yyin->read( buf, max_size );
+ (void) yyin.read( buf, max_size );
- if ( yyin->bad() )
+ if ( yyin.bad() )
return -1;
else
- return yyin->gcount();
+ return yyin.gcount();
#endif
}
void yyFlexLexer::LexerOutput( const char* buf, int size )
{
- (void) yyout->write( buf, size );
+ (void) yyout.write( buf, size );
}
%ok-for-header
%endif
@@ -1973,7 +2009,7 @@ m4_ifdef( [[M4_YY_USE_LINENO]],
void yyrestart YYFARGS1( FILE *,input_file)
%endif
%if-c++-only
- void yyFlexLexer::yyrestart( std::istream* input_file )
+ void yyFlexLexer::yyrestart( std::istream& input_file )
%endif
{
M4_YY_DECL_GUTS_VAR();
@@ -1988,6 +2024,18 @@ m4_ifdef( [[M4_YY_USE_LINENO]],
yy_load_buffer_state( M4_YY_CALL_ONLY_ARG );
}
+%if-c++-only
+/** Delegate to the new version that takes an istream reference.
+ * @param input_file A readable stream.
+ * M4_YY_DOC_PARAM
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+void yyFlexLexer::yyrestart( std::istream* input_file )
+{
+ yyrestart( *input_file );
+}
+%endif
+
/** Switch to a different input buffer.
* @param new_buffer The new input buffer.
* M4_YY_DOC_PARAM
@@ -2040,7 +2088,12 @@ static void yy_load_buffer_state YYFARGS0(void)
M4_YY_DECL_GUTS_VAR();
YY_G(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
YY_G(yytext_ptr) = YY_G(yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+%if-c-only
yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+%endif
+%if-c++-only
+ yyin.rdbuf(YY_CURRENT_BUFFER_LVALUE->yy_input_file);
+%endif
YY_G(yy_hold_char) = *YY_G(yy_c_buf_p);
}
@@ -2054,7 +2107,7 @@ static void yy_load_buffer_state YYFARGS0(void)
YY_BUFFER_STATE yy_create_buffer YYFARGS2( FILE *,file, int ,size)
%endif
%if-c++-only
- YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size )
+ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream& file, int size )
%endif
{
YY_BUFFER_STATE b;
@@ -2080,6 +2133,19 @@ static void yy_load_buffer_state YYFARGS0(void)
return b;
}
+%if-c++-only
+/** Delegate creation of buffers to the new version that takes an istream reference.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * M4_YY_DOC_PARAM
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size )
+{
+ return yy_create_buffer( *file, size );
+}
+%endif
+
/** Destroy the buffer.
* @param b a buffer created with yy_create_buffer()
* M4_YY_DOC_PARAM
@@ -2114,7 +2180,7 @@ static void yy_load_buffer_state YYFARGS0(void)
static void yy_init_buffer YYFARGS2( YY_BUFFER_STATE ,b, FILE *,file)
%endif
%if-c++-only
- void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file )
+ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream& file )
%endif
{
@@ -2123,7 +2189,12 @@ static void yy_load_buffer_state YYFARGS0(void)
yy_flush_buffer( b M4_YY_CALL_LAST_ARG);
+%if-c-only
b->yy_input_file = file;
+%endif
+%if-c++-only
+ b->yy_input_file = file.rdbuf();
+%endif
b->yy_fill_buffer = 1;
/* If b is the current buffer, then yy_init_buffer was _probably_
@@ -2279,7 +2350,7 @@ void yyFlexLexer::yyensure_buffer_stack(void)
* scanner will even need a stack. We use 2 instead of 1 to avoid an
* immediate realloc on the next call.
*/
- num_to_alloc = 1;
+ num_to_alloc = 1; // After all that talk, this was set to 1 anyways...
YY_G(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
M4_YY_CALL_LAST_ARG);
@@ -2862,7 +2933,7 @@ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
}
%endif if-c-only
-
+%# Actually, that ended an if-rentrant section
%if-c-only
static int yy_init_globals YYFARGS0(void)