manpagesection(7. 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.1 through 8.8).

    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(7.1. NAMING CONVENTION)

    All symbols that are required by the generated scanner class end in two
consecutive underscore characters (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(7.2 CONSTRUCTORS)

    itemization(
    itb(explicit Scanner(std::istream &in = std::cin, 
                    std::ostream &out = std::cout))
        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.
    
    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))
        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. 

    bf(This constructor is not available with interactive scanners.)
    )
    
manpagesection(7.3. 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(7.4. 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 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.5. SCANNER CLASS HEADER EXAMPLE)

        verb(
#ifndef Scanner_H_INCLUDED_
#define Scanner_H_INCLUDED_

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


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 preCode(); // re-implement this function for code to be
                        // exec'ed before the pattern matching starts
};

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

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__();
}

#endif // Scanner_H_INCLUDED_
        )

