lex
member function
and its support functions. By default this file is named lex.cc
.
Scanner.h
. The scanner class itself is generated once and is
thereafter `owned' by the programmer, who may change it ad-lib. Newly
added members (data members, function members) will survive future flexc++ runs
as flexc++ will never rewrite an existing scanner class interface file, unless
explicitly ordered to do so.
Scannerbase.h
. At each new flexc++ run this file is rewritten unless flexc++
is explicitly ordered not to do so.
Scanner.ih
. This file, like the file containing the scanner class's
interface is never rewritten by flexc++ unless flexc++ is explicitly ordered to do
so.
The first file, lex.cc
contains lookup tables, the code to walk through
the lookup tables and the actions specified in the lexer file. Since the
lookup tables and actions (possibly) change every time flexc++ is called,
lex.cc
is rewritten at each new flexc++ run.
The file Scannerbase.h
contains the Scanner
's base class The
Scanner
class is derived from ScannerBase
. The Scannerbase.h
is
`owned' by flexc++, and flexc++ reqrites Scannerbase.h
at each new flexc++ run.
The other two files Scanner.h
and Scanner.ih
are created only once,
and can safely be edited by the programmer. The Scanner.h
header file
contains the final Scanner
class, to which new members may be added. These
members may be called from the actions defined in flexc++'s input file
(lexer
).
Finally, Scanner.ih
contains declarations which are used by the
implementations of the Scanner
members. One can place using
statements
here as well as includes which are only required by member implementations. In
a well-designed classq, source files defining new members of the class
Scanner
should only have to include Scanner.ih
.
#include
is defined
controlling stack-wise stream switching. Alternatively, direct switches to
other streams can be requested. Flexc++ offers both ways to switch streams.
#include
is
usually defined. When encountered, processing of the current stream is
suspended and the scanning process continues at the stream whose name is
specified at the #include
directive. When reaching a stream's end-of-file
the scanner switches back to the suspended input stream. In this case streams
are pushed on a stack when encountering a stream switching directive and
popped off the stack once the current file has completely been processed.
The members void pushStream(std::istream &curStream)
and void
pushStream(std::string const &curName)
are provided for stack-wise stream
switching. By default, at a stream's end-of-file the member bool
popStream()
is automatically called by flexc++, closing the currently processed
input stream and continuing the processing of the most recently stacked input
stream (removing it from the stack of streams). If this switch was
successfully performed true
is returned, otherwise (e.g., when the stream
stack is empty) false
is returned.
Returning to the previously stacked stream is handled automatically and
does not require the use of a <<EOF>>
rule. If an <<EOF>>
rule is
defined, however, previously pushed streams are not automatically
re-activated. In that case, returning to previously pushed streams is the
responsibility of the programmer.
When switching to another stream the line number counter and file name are reset to, respectively, 1 and the new file's name. When returning to a previously suspended (stacked) stream that stream's line number and file name are restored.
Direct, non-stack based stream switching can be realized by the void
switchStreams(std::string const &infilename), void switchStreams(std::string
const &infilename, std::string const &outfilename)
and void
switchStreams(std::istream &in, std::ostream &out)
members. Processing of the
current input file ends, and continues at the file or stream specified as
switchStream
's first argument.