manpagesection(2. THE CLASS INTERFACE: SCANNER.H)

    By default, flc() generates a file tt(Scanner.h) containing the initial
interface of the scanner class performing the lexical scan according to the
specifications given in flc()'s input file. The name of the file that is
generated can easily be changed using flc()'s tt(--class-header)
option. In this man-page we'll stick to using the default name.

    The file tt(Scanner.h) is generated only once, unless an explicit request
is made to rewrite it (using flc()'s tt(--force-class-header) option).

    The provided interface is very light-weight, primarily offering a link to
the scanner's base class (see this manpage's sections 8 through 16).

    bf(Many of the facilities offered by the scanner class are inherited from
the tt(ScannerBase) base class. Additional facilities offered by the
tt(Scanner) class. are covered below).

manpagesection(3. NAMING CONVENTION)

    All symbols that are required by the generated scanner class end in an
underscore character (e.g., tt(executeAction_)). These names
should not be redefined. As they are part of the tt(Scanner) and
tt(ScannerBase) class their scope is immediately clear and confusion with
identically named identifiers elsewhere is unlikely.

    Some member functions do not use the underscore convention. These are the
scanner class's constructors, or names that are similar or equal to names that
have historically been used (e.g., tt(length)). Also, some functions are
offered offering hooks into the implementation (like tt(preCode)). The latter
category of function also have names that don't end in underscores.

manpagesection(4. CONSTRUCTORS)

    itemization(
    itb(explicit Scanner(std::istream &in = std::cin, 
                    std::ostream &out = std::cout, bool keepCwd = true))
        This constructor by default reads information from the standard input
stream and writes to the standard output stream. When the tt(Scanner) object
goes out of scope the input and output files are closed. 

    By default (tt(keepCwd == true)) the directory that was active when the
scanner was constructed is made current again once the scanning process ends
(i.e., when tt(lex_()), see below, returns 0).  

    When tt(keepCwd == false) the scanner doesn't reset its working directory
to the directory that was current when the scanner was constructed. This may
be convenient in situations where a program repeatedly calls
tt(switchStream()), followed by full lexical scans of the switched-to streams.
    
    With interactive scanners input stream switching or stacking is not
available; switching output streams, however, is.

    itb(Scanner(std::string const &infile, std::string const &outfile, 
                bool keepCwd = true))
        This constructor opens the input and output streams whose file names
were specified. When the tt(Scanner) object goes out of scope the input and
output files are closed. If tt(outfile == "-") then the standard output stream
is used as the scanner's output medium; if tt(outfile == "") then the standard
error stream is used as the scanner's output medium. 

    The parameter tt(keepCwd) is used as with the previous constructor.

    bf(This constructor is not available with interactive scanners.)
    )
    
manpagesection(5. PUBLIC MEMBER FUNCTIONS)

    itemization(
    itb(int lex())
        The tt(lex) function performs the lexical scanning of the input file
specified at construction time (but also see section 6.1. for information
about intermediate stream-switching facilities). It returns an tt(int)
representing the em(token) associated with the matched regular expression. The
returned value 0 indicates end-of-file. Considering its default
implementation, it could be redefined by the user. tt(Lex)'s default
implementation merely calls tt(lex_):
        verb(
inline int Scanner::lex()
{
    return lex_();
}
        )

    bf(Caveat): with interactive scanners the tt(lex) function is defined in
the generated tt(lex.cc) file. Once flc() has generated the scanner class
header file this scanner class header file isn't automatically rewritten by
flc(). If, at some later stage, an interactive scanner must be generated, then
the inline tt(lex) implementation must be removed `by hand' from the scanner
class header file. Likewise, a tt(lex) member implementation (like the above)
must be provided `by hand' if a non-interactive scanner is required after
first having generated files implementing an interactive scanner.
    )

manpagesection(6. PRIVATE MEMBER FUNCTIONS)

    itemization(
    itb(int lex_())
        This function is used internally by tt(lex) and should not otherwise
be used.
    itb(int executeAction_())
        This function is used internally by tt(lex) and should not otherwise
be used.
    itb(void preCode())
        By default this function has an empty, inline implementation in
tt(Scanner.h). It can safely be replaced by a user-defined
implementation. This function is called by tt(lex_), just before it starts to
match input characters against its rules: tt(preCode) is called by tt(lex_)
when tt(lex_) is called and also after having executed the actions of a rule
which did not execute a tt(return) statement. The outline of tt(lex_)'s
implementation looks like this:
        verb(
int Scanner::lex_()
{
    ...
    preCode();

    while (true)
    {
        size_t ch = get_();            // fetch next char
        ...
        switch (actionType_(range))    // determine the action
        {
            ... maybe return
        }
        ... no return, continue scanning
        preCode();
    } // while
}
        )
    itb(void postCode(PostEnum_ type))
        By default this function has an empty, inline implementation in
tt(Scanner.h). It can safely be replaced by a user-defined
implementation. This function is called by tt(lex_), just after a rule has
been matched. Values of the tt(enum class PostEnum_) indicate the
characteristic of the matched rule. tt(PostEnum_) has four values:
tt(PostEnum_::END, PostEnum_::POP, PostEnum_::RETURN), and
tt(PostEnum_::WIP). Refer to section 10 for their meanings.
   itb(void print())
           When the tt(--print-tokens) or tt(%print-tokens) directive is used
            this function is called to display, on the standard output stream,
            the tokens returned and text matched by the scanner generated by
            flc().

           Displaying is suppressed when the tt(lex.cc) file is (re)generated
            without using this directive. The function actually showing the
            tokens (tt(ScannerBase::print_)) is called from tt(print), which
            is defined in-line in tt(Scanner.h). Calling
            tt(ScannerBase::print_), therefore, can also easily be controlled
            by an option controlled by the program using the scanner object.
     )
    
manpagesection(7. SCANNER CLASS HEADER EXAMPLE)

        verb(
#ifndef Scanner_H_INCLUDED_
#define Scanner_H_INCLUDED_

// $insert baseclass_h
#include "Scannerbase.h"

// $insert classHead
class Scanner: public ScannerBase
{
    public:
        explicit Scanner(std::istream &in = std::cin,
                                std::ostream &out = std::cout);

        Scanner(std::string const &infile, std::string const &outfile);
        
        // $insert lexFunctionDecl
        int lex();

    private:
        int lex_();
        int executeAction_(size_t ruleNr);

        void print();
        void preCode();     // re-implement this function for code that must 
                            // be exec'ed before the patternmatching starts

        void postCode(PostEnum_ type);    
                            // re-implement this function for code that must 
                            // be exec'ed after the rules's actions.
};

// $insert scannerConstructors
inline Scanner::Scanner(std::istream &in, std::ostream &out)
:
    ScannerBase(in, out)
{}

inline Scanner::Scanner(std::string const &infile, std::string const &outfile)
:
    ScannerBase(infile, outfile)
{}

// $insert inlineLexFunction
inline int Scanner::lex()
{
    return lex_();
}

inline void Scanner::preCode() 
{
    // optionally replace by your own code
}

inline void Scanner::postCode(PostEnum_ type) 
{
    // optionally replace by your own code
}

inline void Scanner::print() 
{
    print_();
}

#endif // Scanner_H_INCLUDED_
        )










