    manpagesection(1. QUICK START)

    A bare-bones, no-frills scanner is generated as follows:

    itemization(
    it() Create a file tt(lexer) defining the regular expressions to
recognize, and the tokens to return. Use token values exceeding 0xff if plain
ascii character values can also be used as token values. Example (assume
capitalized words are token-symbols defined in an enum defined by the scanner
class):
        verb(
%%
[ \t\n]+                            // skip white space chars.
[0-9]+                              return NUMBER;
[[:alpha:]_][[:alpha:][:digit:]_]*  return IDENTIFIER;
.                                   return matched()[0];
        )

    it() Execute:
        verb(
    flexc++ lexer
        )
    This generates four files):tt(Scanner.h, Scanner.ih, Scannerbase.h), and
tt(lex.cc) 

    it() Edit tt(Scanner.h), add the enum defining the token-symbols in
(usually) the public section of the class tt(Scanner). E.g.,
        verb(
class Scanner: public ScannerBase
{
    public:
        enum Tokens
        {
            IDENTIFIER = 0x100,
            NUMBER
        };
    // ... (etc, as generated by flexc++)
        )

    it() Create a file defining tt(int main), e.g.:
        verb(
#include <iostream>
#include "Scanner.h"

using namespace std;

int main()
{
    Scanner scanner;        // define a Scanner object

    while (int token = scanner.lex())   // get all tokens
    {
        string const &text = scanner.matched();
        switch (token)
        {
            case Scanner::IDENTIFIER:
                cout << "identifier: " << text << '\n';
            break;

            case Scanner::NUMBER:
                cout << "number: " << text << '\n';
            break;

            default:
                cout << "char. token: `" << text << "'\n";
            break;
        }
    }
}
        )
    it() Compile all tt(.cc) files:
        verb(
    g++ --std=c++11 *.cc
        )
    
    it() To `tokenize' tt(main.cc), execute:
        verb(
    a.out < main.cc
        )
    )

    manpagesection(QUICK START: FLEXC++ and BISONC++)

To interface flc() to the bf(bisonc++)(1) parser generator proceed as follows:
    itemization(
    it() Specify a grammar that can be processed by bf(bisonc++)(1). Assuming
that the scanner and parser are developed in, respectively, the
sub-directories tt(scanner) and tt(parser), then a simple grammar
specification that can be used with the scanner developed in the previous
section is, e.g., write the file tt(parser/grammar):
        verb(
%scanner                ../scanner/Scanner.h
%scanner-token-function d_scanner.lex()

%token IDENTIFIER NUMBER CHAR

%%

startrule:
    startrule tokenshow
|
    tokenshow
;

tokenshow:
    token
    {
        std::cout << "matched: " << d_scanner.matched() << '\n';
    }
;

token:
    IDENTIFIER
|
    NUMBER
|
    CHAR
;
    )
    it() Write a scanner specification file. E.g.,
    verb(
%%

[ \t\n]+                            // skip white space chars.
[0-9]+                              return Parser::NUMBER;
[[:alpha:]_][[:alpha:][:digit:]_]*  return Parser::IDENTIFIER;
.                                   return Parser::CHAR;
    )
    This causes the scanner to  return tt(Parser) tokens to the generated
parser. 

    it() Add the line
    verb(
#include "../parser/Parserbase.h"
    )
    to the file tt(scanner/Scanner.ih)

    it() Write a simple tt(main) function in the file tt(main.cc). E.g.,
    verb(
#include "parser/Parser.h"

int main(int argc, char **argv)
{
    Parser parser;

    parser.parse();
}
    )
    
    it() Generate a scanner in the tt(scanner) subdirectory:
    verb(
flexc++ lexer
    )
    
    it() Generate a parser in the tt(parser) subdirectory:
    verb(
bisonc++ grammar
    )
    
    it() Compile all sources:
    verb(
g++ --std=c++0x *.cc */*.cc
    )

    it() Execute the program, providing it some source file to be processed:
    verb(
a.out < main.cc
    )
        )

    manpagesection(3. GENERATED FILES)

Flc() generates four files from a well-formed input file:
    itemization(

    it() A file containing the implementation of the tt(lex) member function
and its support functions. By default this file is named tt(lex.cc).

    it() A file containing the scanner's class interface. By default this file
is named tt(Scanner.h). The scanner class itself is generated once and is
thereafter `owned' by the programmer, who may change it em(ad-lib). Newly
added members (data members, function members) will survive future flc() runs
as flc() will never rewrite an existing scanner class interface file, unless
explicitly ordered to do so. 

    it() A file containing the interface of the scanner class's em(base
class). The scanner class is publicly derived from this base class. It is used
to minimize the size of the scanner interface itself. The scanner base class
is `owned' by bf(flexc++) and should never be hand-modified. By
default the scanner's base class is provided in the file
tt(Scannerbase.h). At each new flc() run this file is rewritten unless flc()
is explicitly ordered em(not) to do so.

    it() A file containing the em(implementation header). This file should
contain includes and declarations that are only required when compiling the
members of the scanner class. By default this file is named
tt(Scanner.ih). This file, like the file containing the scanner class's
interface is never rewritten by flc() unless flc() is explicitly ordered to do
so.
    )

manpagesection(4. OPTIONS)

    includefile(../manual/intro/options)

manpagesection(5. INTERACTIVE SCANNERS)

An interactive scanner is characterized by the fact that scanning is postponed
until an end-of-line character has been received, followed by reading all
information on the line, read so far. Flc() supports the 
tt(%interactive) directive), generating an
interactive scanner. Here it is assumed that tt(Scanner) is the name of the
scanner class generated by flc().

bf(Caveat:) generating interactive and non-interactive scanners should not be
mixed as their class organizations fundamentally differ, and several of the
Scanner class's members are only available in the non-interactive scanner. As
the tt(Scanner.h) file contains the Scanner class's interface, which is
normally left untouched by flc(), flc() cannot adapt the Scanner class when
requested to change the interactivity of an existing Scanner class. Because of
this support for the tt(--interactive) option was discontinued at flc()'s
1.01.00 release.

The interactive scanner generated by flc() has the following characteristics:
    itemization(
    it() The tt(Scanner) class is derived privately from
        tt(std::istringstream) and (as usual) publicly from tt(ScannerBase).
    it() The tt(istringstream) base class is constructed by its default
        constructor. 
    it() The function tt(lex)'s default implementation is removed from
        tt(Scanner.h) and is implemented in the generated tt(lex.cc) source
        file. It performs the following tasks:

        - If the token returned by the scanner is not equal to 0 it is
            returned as then next token;

        - Otherwise the next line is retrieved from the input stream
            passed to the tt(Scanner)'s constructor (by default tt(std::cin)).
            If this fails, 0 is returned.

        - A tt('\n') character is appended to the just read line, and the
            scanner's tt(std::istringstream) base class object is
            re-initialized with that line;

        - The member tt(lex__) returns the next token.
    )
    This implementation allows code calling tt(Scanner::lex()) to conclude, as
usual, that the input is exhausted when tt(lex) returns 0.

Here is an example of how such a scanner could be used:
    itemization(
        verb(
    // scanner generated using 'flexc++ lexer' with lexer containing 
    // the %interactive directive
    int main()
    {
        Scanner scanner;        // by default: read from std::cin 
    
        while (true)
        {
            cout << "? ";       // prompt at each line

            while (true)        // process all the line's tokens
            {
                int token = scanner.lex();
    
                if (token == '\n')  // end of line: new prompt
                    break;
    
                if (token == 0)     // end of input: done
                    return 0;
    
                                    // process other tokens
                cout << scanner.matched() << '\n';
                if (scanner.matched()[0] == 'q')
                    return 0;
            }
        }
    }
        )
    )
