.TH "flexc++api" "3" "2008\-2023" "flexc++\&.2\&.14\&.00" "flexc++ API" .PP .SH "NAME" flexc++api \- Application programmer\(cq\&s interface of flexc++ generated classes .PP .SH "DESCRIPTION" .PP \fBFlexc++\fP(1) was designed after \fBflex\fP(1) and \fBflex++\fP(1)\&. Like these latter two programs \fBflexc++\fP generates code performing pattern\-matching on text, possibly executing actions when certain \fIregular expressions\fP are recognized\&. .PP Refer to \fBflexc++\fP(1) for a general overview\&. This manual page covers the Application Programmer\(cq\&s Interface of classes generated by \fBflexc++\fP, offering the following sections: .PP .IP o \fB1\&. INTERACTIVE SCANNERS\fP: how to create an interactive scanner .IP .IP o \fB2\&. THE CLASS INTERFACE: SCANNER\&.H\fP: Constructors and members of the scanner class generated by \fBflexc++\fP .IP o \fB3\&. NAMING CONVENTION\fP: symbols defined by \fBflexc++\fP in the scanner class\&. .IP o \fB4\&. CONSTRUCTORS\fP: constructors defined in the scanner class\&. .IP o \fB5\&. PUBLIC MEMBER FUNCTION\fP: public member declared in the scanner class\&. .IP o \fB6\&. PRIVATE MEMBER FUNCTIONS\fP: private members declared in the scanner class\&. .IP o \fB7\&. SCANNER CLASS HEADER EXAMPLE\fP: an example of a generated scanner class header .IP .IP o \fB8\&. THE SCANNER BASE CLASS\fP: the scanner class is derived from a base class\&. The base class is described in this section .IP o \fB9\&. PUBLIC ENUMS AND \-TYPES\fP: enums and types declared by the base class .IP o \fB10\&. PROTECTED ENUMS AND \-TYPES\fP: enumerations and types used by the scanner and scanner base classes .IP o \fB11\&. NO PUBLIC CONSTRUCTORS\fP: the scanner base class does not offer public constructors\&. .IP o \fB12\&. PUBLIC MEMBER FUNCTIONS\fP: several members defined by the scanner base class have public access rights\&. .IP o \fB13\&. PROTECTED CONSTRUCTORS\fP: the base class can be constructed by a derived class\&. Usually this is the scanner class generated by \fBflexc++\fP\&. .IP o \fB14\&. PROTECTED MEMBER FUNCTIONS\fP: this section covers the base class member functions that can only be used by scanner class or scanner base class members .IP o \fB15\&. PROTECTED DATA MEMBERS\fP: this section covers the base class data members that can only be used by scanner class or scanner base class members .IP o \fB16\&. FLEX++ TO FLEXC++ MEMBERS\fP: a short overview of frequently used \fBflex\fP(1) members that received different names in \fBflexc++\fP\&. .IP .IP o \fB17\&. THE CLASS INPUT\fP: the scanner\(cq\&s job is completely decoupled from the actual input stream\&. The class \fIInput\fP, nested within the scanner base class handles the communication with the input streams\&. The class \fIInput\fP, is described in this section\&. .IP o \fB18\&. INPUT CONSTRUCTORS\fP: the class \fIInput\fP can easily be replaced by another class\&. The constructor\-requirements are described in this section\&. .IP o \fB19\&. REQUIRED PUBLIC MEMBER FUNCTIONS\fP: this section covers the required public members of a self\-made \fIInput\fP class .PP .SH "UNDERSCORES" Starting with version 2\&.07\&.00 \fBflexc++\fP reserved identifiers no longer end in two underscore characters, but in one\&. This modification was necessary because according to the \fBC++\fP standard identifiers having two or more consecutive underscore characters are reserved by the language\&. In practice this could require some minor modifications of existing source files using \fBflexc++\fP\(cq\&s facilities, most likely limited to changing \fIStartCondition__\fP into \fIStartCondition_\fP and changing \fIPostEnum__\fP into \fIPostEnum_\fP\&. .PP The complete list of affected names is: .IP "Enums:" .RS ActionType_, Leave_, StartConditon_, PostEnum_; .RE .IP "Member functions:" .RS actionType_, continue_, echoCh_, echoFirst_, executeAction_, getRange_, get_, istreamName_, lex_, lop1_, lop2_, lop3_, lop4_, lopf_, matched_, noReturn_, print_, pushFront_, reset_, return_; .RE .IP "Protected data members:" .RS d_in_ d_token_ s_finIdx_, s_interactive_, s_maxSizeofStreamStack_, s_nRules_, s_rangeOfEOF_, s_ranges_, s_rf_\&. .RE .PP .SH "1\&. INTERACTIVE SCANNERS" .PP 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\&. \fBFlexc++\fP supports the \fI%interactive\fP directive), generating an interactive scanner\&. Here it is assumed that \fIScanner\fP is the name of the scanner class generated by \fBflexc++\fP\&. .PP \fBCaveat:\fP generating interactive and non\-interactive scanners should not be mixed as their class organizations fundamentally differ, and several of the Scanner class\(cq\&s members are only available in the non\-interactive scanner\&. As the \fIScanner\&.h\fP file contains the Scanner class\(cq\&s interface, which is normally left untouched by \fBflexc++\fP, \fBflexc++\fP cannot adapt the Scanner class when requested to change the interactivity of an existing Scanner class\&. Because of this support for the \fI\-\-interactive\fP option was discontinued at \fBflexc++\fP\(cq\&s 1\&.01\&.00 release\&. .PP The interactive scanner generated by \fBflexc++\fP has the following characteristics: .IP o The \fIScanner\fP class is derived privately from \fIstd::istringstream\fP and (as usual) publicly from \fIScannerBase\fP\&. .IP o The \fIistringstream\fP base class is constructed by its default constructor\&. .IP o The function \fIlex\fP\(cq\&s default implementation is removed from \fIScanner\&.h\fP and is implemented in the generated \fIlex\&.cc\fP source file\&. It performs the following tasks: .IP \- If the token returned by the scanner is not equal to 0 it is returned as then next token; .IP \- Otherwise the next line is retrieved from the input stream passed to the \fIScanner\fP\(cq\&s constructor (by default \fIstd::cin\fP)\&. If this fails, 0 is returned\&. .IP \- A \fI\(cq\&\en\(cq\&\fP character is appended to the just read line, and the scanner\(cq\&s \fIstd::istringstream\fP base class object is re\-initialized with that line; .IP \- The member \fIlex_\fP returns the next token\&. This implementation allows code calling \fIScanner::lex()\fP to conclude, as usual, that the input is exhausted when \fIlex\fP returns 0\&. .PP Here is an example of how such a scanner could be used: .nf // scanner generated using \(cq\&flexc++ lexer\(cq\& with lexer containing // the %interactive directive int main() { Scanner scanner; // by default: read from std::cin while (true) { cout << \(dq\&? \(dq\&; // prompt at each line while (true) // process all the line\(cq\&s tokens { int token = scanner\&.lex(); if (token == \(cq\&\en\(cq\&) // end of line: new prompt break; if (token == 0) // end of input: done return 0; // process other tokens cout << scanner\&.matched() << \(cq\&\en\(cq\&; if (scanner\&.matched()[0] == \(cq\&q\(cq\&) return 0; } } } .fi .PP .SH "2\&. THE CLASS INTERFACE: SCANNER\&.H" .PP By default, \fBflexc++\fP generates a file \fIScanner\&.h\fP containing the initial interface of the scanner class performing the lexical scan according to the specifications given in \fBflexc++\fP\(cq\&s input file\&. The name of the file that is generated can easily be changed using \fBflexc++\fP\(cq\&s \fI\-\-class\-header\fP option\&. In this man\-page we\(cq\&ll stick to using the default name\&. .PP The file \fIScanner\&.h\fP is generated only once, unless an explicit request is made to rewrite it (using \fBflexc++\fP\(cq\&s \fI\-\-force\-class\-header\fP option)\&. .PP The provided interface is very light\-weight, primarily offering a link to the scanner\(cq\&s base class (see this manpage\(cq\&s sections 8 through 16)\&. .PP \fBMany of the facilities offered by the scanner class are inherited from the \fIScannerBase\fP base class\&. Additional facilities offered by the \fIScanner\fP class\&. are covered below\fP\&. .PP .SH "3\&. NAMING CONVENTION" .PP All symbols that are required by the generated scanner class end in an underscore character (e\&.g\&., \fIexecuteAction_\fP)\&. These names should not be redefined\&. As they are part of the \fIScanner\fP and \fIScannerBase\fP class their scope is immediately clear and confusion with identically named identifiers elsewhere is unlikely\&. .PP Some member functions do not use the underscore convention\&. These are the scanner class\(cq\&s constructors, or names that are similar or equal to names that have historically been used (e\&.g\&., \fIlength\fP)\&. Also, some functions are offered offering hooks into the implementation (like \fIpreCode\fP)\&. The latter category of function also have names that don\(cq\&t end in underscores\&. .PP .SH "4\&. CONSTRUCTORS" .PP .IP o \fBexplicit Scanner(std::istream &in = std::cin, std::ostream &out = std::cout, bool keepCwd = true)\fP This constructor by default reads information from the standard input stream and writes to the standard output stream\&. When the \fIScanner\fP object goes out of scope the input and output files are closed\&. .IP By default (\fIkeepCwd == true\fP) the directory that was active when the scanner was constructed is made current again once the scanning process ends (i\&.e\&., when \fIlex_()\fP, see below, returns 0)\&. .IP When \fIkeepCwd == false\fP the scanner doesn\(cq\&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 \fIswitchStream()\fP, followed by full lexical scans of the switched\-to streams\&. .IP With interactive scanners input stream switching or stacking is not available; switching output streams, however, is\&. .IP .IP o \fBScanner(std::string const &infile, std::string const &outfile, bool keepCwd = true)\fP This constructor opens the input and output streams whose file names were specified\&. When the \fIScanner\fP object goes out of scope the input and output files are closed\&. If \fIoutfile == \(dq\&\-\(dq\&\fP then the standard output stream is used as the scanner\(cq\&s output medium; if \fIoutfile == \(dq\&\(dq\&\fP then the standard error stream is used as the scanner\(cq\&s output medium\&. .IP The parameter \fIkeepCwd\fP is used as with the previous constructor\&. .IP \fBThis constructor is not available with interactive scanners\&.\fP .PP .SH "5\&. PUBLIC MEMBER FUNCTIONS" .PP .IP o \fBint lex()\fP The \fIlex\fP 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 \fIint\fP representing the \fItoken\fP 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\&. \fILex\fP\(cq\&s default implementation merely calls \fIlex_\fP: .nf inline int Scanner::lex() { return lex_(); } .fi .IP \fBCaveat\fP: with interactive scanners the \fIlex\fP function is defined in the generated \fIlex\&.cc\fP file\&. Once \fBflexc++\fP has generated the scanner class header file this scanner class header file isn\(cq\&t automatically rewritten by \fBflexc++\fP\&. If, at some later stage, an interactive scanner must be generated, then the inline \fIlex\fP implementation must be removed `by hand\(cq\& from the scanner class header file\&. Likewise, a \fIlex\fP member implementation (like the above) must be provided `by hand\(cq\& if a non\-interactive scanner is required after first having generated files implementing an interactive scanner\&. .PP .SH "6\&. PRIVATE MEMBER FUNCTIONS" .PP .IP o \fBint lex_()\fP This function is used internally by \fIlex\fP and should not otherwise be used\&. .IP o \fBint executeAction_()\fP This function is used internally by \fIlex\fP and should not otherwise be used\&. .IP o \fBvoid preCode()\fP By default this function has an empty, inline implementation in \fIScanner\&.h\fP\&. It can safely be replaced by a user\-defined implementation\&. This function is called by \fIlex_\fP, just before it starts to match input characters against its rules: \fIpreCode\fP is called by \fIlex_\fP when \fIlex_\fP is called and also after having executed the actions of a rule which did not execute a \fIreturn\fP statement\&. The outline of \fIlex_\fP\(cq\&s implementation looks like this: .nf 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 } .fi .IP o \fBvoid postCode(PostEnum_ type)\fP By default this function has an empty, inline implementation in \fIScanner\&.h\fP\&. It can safely be replaced by a user\-defined implementation\&. This function is called by \fIlex_\fP, just after a rule has been matched\&. Values of the \fIenum class PostEnum_\fP indicate the characteristic of the matched rule\&. \fIPostEnum_\fP has four values: \fIPostEnum_::END, PostEnum_::POP, PostEnum_::RETURN\fP, and \fIPostEnum_::WIP\fP\&. Refer to section 10 for their meanings\&. .IP o \fBvoid print()\fP When the \fI\-\-print\-tokens\fP or \fI%print\-tokens\fP 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 \fBflexc++\fP\&. .IP Displaying is suppressed when the \fIlex\&.cc\fP file is (re)generated without using this directive\&. The function actually showing the tokens (\fIScannerBase::print_\fP) is called from \fIprint\fP, which is defined in\-line in \fIScanner\&.h\fP\&. Calling \fIScannerBase::print_\fP, therefore, can also easily be controlled by an option controlled by the program using the scanner object\&. .PP .SH "7\&. SCANNER CLASS HEADER EXAMPLE" .PP .nf #ifndef Scanner_H_INCLUDED_ #define Scanner_H_INCLUDED_ // $insert baseclass_h #include \(dq\&Scannerbase\&.h\(dq\& // $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\(cq\&ed before the patternmatching starts void postCode(PostEnum_ type); // re\-implement this function for code that must // be exec\(cq\&ed after the rules\(cq\&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_ .fi .PP .SH "8\&. THE SCANNER BASE CLASS" .PP By default, \fBflexc++\fP generates a file \fIScannerbase\&.h\fP containing the interface of the base class of the scanner class also generated by \fBflexc++\fP\&. The name of the file that is generated can easily be changed using \fBflexc++\fP\(cq\&s \fI\-\-baseclass\-header\fP option\&. In this man\-page we use the default name\&. .PP The file \fIScannerbase\&.h\fP is generated at each new \fBflexc++\fP run\&. It contains no user\-serviceable or extensible parts\&. Rewriting can be prevented by specifying \fBflexc++\fP\(cq\&s \fI\-\-no\-baseclass\-header\fP option)\&. .PP .SH "9\&. PUBLIC ENUMS AND \-TYPES" .PP .IP o \fBenum class StartCondition_\fP This strongly typed enumeration defines the names of the start conditions (i\&.e\&., mini scanners)\&. It at least contains \fIINITIAL\fP, but when the \fI%s\fP or \fI%x\fP directives were used it also contains the identifiers of the mini scanners declared by these directives\&. Since \fIStartCondition_\fP is a strongly typed enum its values must be preceded by its enum name\&. E\&.g\&., .nf begin(StartCondition_::INITIAL); .fi .PP .SH "10\&. PROTECTED ENUMS AND \-TYPES" .PP .IP o \fBenum class ActionType_\fP This strongly typed enumeration is for internal use only\&. .IP o \fBenum Leave_\fP This enumeration is for internal use only\&. .IP o \fBenum class PostEnum_\fP Values of this strongly typed enumeration are passed to the scanner\(cq\&s private member \fIpostCode\fP, indicating the scanner\(cq\&s action after matching a rule\&. The values of this enumeration are: .IP \fIPostEnum_::END\fP: the function \fIlex_\fP immediately returns 0 once \fIpostCode\fP returns, indicating the end of the input was reached; .IP \fIPostEnum_::POP\fP: the end of an input stream was reached, and processing continues with the previously pushed input stream\&. In this case the function \fIlex_\fP doesn\(cq\&t return, it simply coontinues processing the previously pushed stream; .IP \fIPostEnum_::RETURN\fP: the function \fIlex_\fP immediately returns once \fIpostCode\fP returns, returning the next token; .IP \fIPostEnum_::WIP\fP: the function \fIlex_\fP has matched a non\-returning rule, and continues its rule\-matching process\&. .PP .SH "11\&. NO PUBLIC CONSTRUCTORS" .PP There are no public constructors\&. \fIScannerBase\fP is a base class for the \fIScanner\fP class generated by \fBflexc++\fP\&. \fIScannerBase\fP only offers protected constructors\&. .PP .SH "12\&. PUBLIC MEMBER FUNCTIONS" .PP .IP o \fBstd::string const &cwd() const\fP return the working directory that was active when the \fIScanner\(cq\&s\fP constructor is called\&. It is also the program\(cq\&s current working directory after constructing a \fIScanner\fP object and when its \fIlex\fP member returns\&. .IP .IP o \fBbool debug() const\fP returns \fItrue\fP if \fI\-\-debug\fP or \fI%debug\fP was specified, otherwise \fIfalse\fP\&. .IP .IP o \fBbool interactiveLine()\fP this member is only available with interactive scanners\&. All remaining contents of the current interactive line buffer is discarded, and the interactive line buffer is filled with the contents of the next input line\&. This member can be used when a condition is encountered which invalidates the remaining contents of a line\&. Following a call to \fIinteractiveLine\fP the next token that is returned by the lexical scanner will be the first token on the next line\&. This member returns \fItrue\fP if the next line is available and \fIfalse\fP otherwise\&. .IP .IP o \fBstd::string const &filename() const\fP returns the name of the file currently processed by the scanner object\&. .IP .IP o \fBsize_t length() const\fP returns the length of the text that was matched by \fIlex\fP\&. With \fBflex++\fP this function was called \fIleng\fP\&. .IP .IP o \fBsize_t lineNr() const\fP returns the line number of the currently scanned line\&. This function is always available (note: \fBflex++\fP only offered a similar function (called \fIlineno\fP) after using the \fI%lineno\fP option)\&. .IP .IP o \fBstd::string const &matched() const\fP returns the text matched by \fIlex\fP (note: \fBflex++\fP offers a similar member called \fIYYText\fP)\&. .IP .IP o \fBvoid setDebug(bool onOff)\fP Switches on/off debugging output by providing the argument \fItrue\fP or \fIfalse\fP\&. Switching on debugging output only has visible effects if the \fIdebug\fP option was specified\&. .IP .IP o \fBvoid switchIstream(std::string const &infilename)\fP The currently processed input stream is closed, and processing continues at the stream whose name is specified as the function\(cq\&s argument\&. This is \fInot\fP a stack\-operation: after processing \fIinfilename\fP processing does not return to the original stream\&. .IP \fBThis member is not available with interactive scanners\&.\fP .IP .IP o \fBvoid switchOstream(std::ostream &out)\fP The currently processed output stream is closed, and new output is written to \fIout\fP\&. .IP .IP o \fBvoid switchOstream(std::string const &outfilename)\fP .IP The current output stream is closed, and output is written to \fIoutfilename\fP\&. If this file already exists, it is rewritten\&. .IP .IP o \fBvoid switchStreams(std::istream &in, std::ostream &out = std::cout)\fP The currently processed input and output streams are closed, and processing continues at \fIin\fP, writing output to \fIout\fP\&. This is \fInot\fP a stack\-operation: after processing \fIin\fP processing does not return to the original stream\&. .IP \fBThis member is not available with interactive scanners\&.\fP .IP .IP o \fBvoid switchStreams(std::string const &infilename, std::string const &outfilename)\fP The currently processed input and output streams are closed, and processing continues at the stream whose name is specified as the function\(cq\&s first argument, writing output to the file whose name is specified as the function\(cq\&s second argument\&. This latter file is rewritten\&. This is \fInot\fP a stack\-operation: after processing \fIinfilename\fP processing does not return to the original stream\&. If \fIoutfilename == \(dq\&\-\(dq\&\fP then the standard output stream is used as the scanner\(cq\&s output medium; if \fIoutfilename == \(dq\&\(dq\&\fP then the standard error stream is used as the scanner\(cq\&s output medium\&. .IP If \fIoutfilename == \(dq\&\-\(dq\&\fP then the standard output stream is used as the scanner\(cq\&s output medium; if \fIoutfilename == \(dq\&\(dq\&\fP then the standard error stream is used as the scanner\(cq\&s output medium\&. .IP \fBThis member is not available with interactive scanners\&.\fP .IP .SH "13\&. PROTECTED CONSTRUCTORS" .PP .IP o \fBScannerBase(std::string const &infilename, std::string const &outfilename, bool keepCwd = true)\fP The scanner object opens and reads \fIinfilename\fP and opens (rewrites) and writes \fIoutfilename\fP\&. It is called from the corresponding \fIScanner\fP constructor\&. .IP By default (\fIkeepCwd == true\fP) the directory that was active when \fIScannerBase\fP was constructed is made current again once the scanning process ends (i\&.e\&., when \fIScanner::lex_()\fP returns 0)\&. .IP When \fIkeepCwd == false\fP the scanner doesn\(cq\&t reset its working directory to the directory that was current when the \fIScannerBase\fP was constructed\&. This may be convenient in situations where a program repeatedly calls \fIswitchStream()\fP, followed by full lexical scans of the switched\-to streams\&. .IP \fBThis constructor is not available for interactive scanners\&.\fP .IP .IP o \fBScannerBase(std::istream &in, std::ostream &out, bool keepCwd = true)\fP The \fIin\fP and \fIout\fP parameters are, respectively, the derived class constructor\(cq\&s input stream and output streams\&. .IP The parameter \fIkeepCwd\fP is used as with the previous constructor\&. .PP .SH "14\&. PROTECTED MEMBER FUNCTIONS" .PP All member functions ending in an underscore character are for internal use only and should not be called by user\-defined members of the \fIScanner\fP class\&. .PP The following members, however, can safely be called by members of the generated \fIScanner\fP class: .PP .IP o \fBvoid accept(size_t nChars = 0)\fP \fIaccept(n)\fP returns all but the first `nChars\(cq\& characters of the current token back to the input stream, where they will be rescanned when the scanner looks for the next match\&. So, it matches `nChars\(cq\& of the characters in the input buffer, rescanning the rest\&. This function effectively sets \fIlength\fP\(cq\&s return value to \fInChars\fP (note: with \fBflex++\fP this function was called \fIless\fP); .IP .IP o \fBvoid begin(StartCondition_ startCondition)\fP activate the regular expression rules associated with \fIStartCondition_ startCondition\fP\&. As this enumeration is a strongly typed enum the \fIStartCondition_\fP scope must be specified as well\&. E\&.g\&., .nf begin(StartCondition_::INITIAL); .fi .IP .IP o \fBvoid echo() const\fP The currently matched text (i\&.e\&., the text returned by the member \fImatched\fP) is inserted into the scanner object\(cq\&s output stream; .IP .IP o \fBvoid leave(int retValue)\fP actions defined in the lexical scanner specification file may or may not return\&. This frequently results in complicated or overlong compound statements, blurring the readability of the specification file\&. By encapsulating the actions in a member function readability is enhanced\&. However, frequently a compound statement is still required, as in: .nf regex\-to\-match { if (int ret = memberFunction()) return ret; } .fi The member \fIleave\fP removes the need for constructions like the above\&. The member \fIleave\fP can be called from within member functions encapsulating actions performed when a regular expression has been matched\&. It ends \fIlex\fP, returning \fIretValue\fP to its caller\&. The above rule can now be written like this: .nf regex\-to\-match memberFunction(); .fi and \fImemberFunction\fP could be implemented as follows: .nf void memberFunction() { if (someCondition()) { // any action, e\&.g\&., // switch mini\-scanner begin(StartCondition_::INITIAL); leave(Parser::TOKENVALUE); // lex returns TOKENVALUE // this point is never reached } pushStream(d_matched); // switch to the next stream // lex continues } .fi The member \fIleave\fP should only (indirectly) be called (usually nested) from actions defined in the scanner\(cq\&s specification \fBs\fP; calling \fIleave\fP outside of this context results in undefined behavior\&. .IP .IP o \fBvoid more()\fP the matched text is kept and will be prefixed to the text that is matched at the next lexical scan; .IP .IP o \fBstd::ostream &out()\fP returns a reference to the scanner\(cq\&s output stream; .IP .IP o \fBbool popStream()\fP closes the currently processed input stream\&. If the stream stack (cf\&. the member \fIstreamStack()\fP) contains multiple elements then the most recently pushed element is removed and processing continues with the then final element of the \fIstreamStack\fP\&. If this switch was successfully performed \fItrue\fP is returned\&. If the stream stack contains only one element then all information has been processed and \fIfalse\fP is returned\&. This member is called automatically at the end of the currently processed input stream\&. After completely processing the initial input file the member \fIlex\fP returns 0\&. .IP When the \fI<>\fP pattern is used in the scanner\(cq\&s specification file \fIpopStream\fP is not automatically called\&. In that case it should explicitly be called in the \fI<>\fP pattern\(cq\&s action block, returning 0 when it returns \fIfalse\fP\&. E\&.g\&., .nf <> { if (not popStream()) return 0; cerr << \(dq\&WIP on \(dq\& << streamStack()\&.size() << \(dq\&file(s)\en\(dq\&; } .fi .IP .IP o \fBvoid push(size_t ch)\fP character \fIch\fP is pushed back onto the input stream\&. I\&.e\&., it will be the character that is retrieved at the next attempt to obtain a character from the input stream; .IP .IP o \fBvoid push(std::string const &txt)\fP the characters in the string \fItxt\fP are pushed back onto the input stream\&. I\&.e\&., they will be the characters that are retrieved at the next attempt to obtain characters from the input stream\&. The characters in \fItxt\fP are retrieved from the first character to the last\&. So if \fItxt == \(dq\&hello\(dq\&\fP then the \fI\(cq\&h\(cq\&\fP will be the character that\(cq\&s retrieved next, followed by \fI\(cq\&e\(cq\&\fP, etc, until \fI\(cq\&o\(cq\&\fP; .IP .IP o \fBvoid pushStream(std::istream &curStream)\fP this function pushes \fIcurStream\fP on the stream stack; .IP \fBThis member is not available with interactive scanners\&.\fP .IP .IP o \fBvoid pushStream(std::string const &curName)\fP same, but the stream \fIcurName\fP is opened first, and the resulting \fIistream\fP is pushed on the stream stack\&. If \fIcurName\fP does not exist a \fIstd::exception\fP is thrown\&. An exception is also thrown when the stream stack size exceeds (by default) 10 (the option \fImax\-depth\fP can be used to change the default)\&. .IP \fBThis member is not available with interactive scanners\&.\fP .IP .IP o \fBvoid redo(size_t nChars = 0)\fP this member acts like \fIaccept\fP but its argument counts backward from the end of the matched text\&. All but these \fInChars\fP characters are kept and the last \fInChar\fP characters are rescanned\&. This function effectively reduces \fIlength\fP\(cq\&s return value by \fInChars\fP; .IP .IP o \fBvoid setFilename(std::string const &name)\fP this function sets the name of the stream returned by \fIfilename\fP to \fIname\fP; .IP .IP o \fBvoid setMatched(std::string const &text)\fP this function stores \fItext\fP in the matched text buffer\&. Following a call to this function \fImatched\fP returns \fItext\fP\&. .IP .IP o \fBStartCondition_ startCondition() const\fP returns the currently active start condition (mini scanner); .IP .IP o \fBstd::vector const &streamStack() const\fP returns the vector of currently stacked input streams\&. Starting with \fBflexc++\fP version 2\&.08\&.00 the size and content of the information in this vector has been changed\&. Starting with version 2\&.08\&.00 its size is at least 1\&. Its size is incremented at every \fIpushStream\fP call, and decremented at every \fIpoStream\fP call\&. .IP The \fIStreamStruct\fP itself is a \fIstruct\fP having only one documented member: \fIstd::string const &pushedName\fP, containing the absolute pathname of the initial and pushed streams\&. .IP Internally, \fIstreamStack\fP vector is used as a stack\&. The pathname of the file that was specified at the scanner\(cq\&s construction time is found at index position 0, and pathname of the file that\(cq\&s currently being processed is found at \fIstreamStack()\&.back()\fP\&. Switching input streams changes the pathname at \fIstreamStack()\&.back()\fP, and if the pathname of a stream cannot be determined (which happens when constructing a scanner from or switching to a \fIstd::istream\fP) then the program\(cq\&s current working directory is not altered and \fIpushedName\fP contains \fI(istream)\fP\&. .IP \fBThis member is not available with interactive scanners\&.\fP .IP .SH "15\&. PROTECTED DATA MEMBERS" .PP All protected data members are for internal use only, allowing \fIlex_\fP to access them\&. All of them end in an underscore character\&. .PP .SH "16\&. FLEX++ TO FLEXC++ MEMBERS" .PP .TS tab(~); --- lcl --- lcl lcl lcl --- c. Flex++ (old)~~Flexc++ (new) \fIlineno()\fP~~\fIlineNr()\fP \fIYYText()\fP~~\fImatched()\fP \fIless()\fP~~\fIaccept()\fP .TE .PP .SH "17\&. THE CLASS INPUT" .PP \fBFlexc++\fP generates a file \fIScannerbase\&.h\fP defining the scanner class\(cq\&s base class, by default named \fIScannerBase\fP (which is the name used in this man\-page)\&. The base class \fIScannerBase\fP contains a nested class \fIInput\fP having this interface: .nf class Input { public: Input(); Input(std::istream *iStream, size_t lineNr = 1); size_t get(); size_t lineNr() const; size_t nPending() const; void setPending(size_t nPending); void reRead(size_t ch); void reRead(std::string const &str, size_t fmIdx); void close(); }; .fi The members of this class are all required and offer an implementation level between the operations of \fIScannerBase\fP and \fBflexc++\fP\(cq\&s actual input file that\(cq\&s being processed\&. .PP By default, \fBflexc++\fP provides the implementation of all of \fIInput\fP\(cq\&s required members\&. Therefore, in most situations this section of this man\-page can safely be ignored\&. .PP However, users may define and extend their own \fIInput\fP class, providing \fBflexc++\fP\(cq\&s base class with their own \fIInput\fP class\&. To do so \fBflexc++\fP\(cq\&s rules file must contain the following two directives: .nf %input\-inline = \(dq\&inline\(dq\& %input\-interface = \(dq\&interface\(dq\& %input\-implementation = \(dq\&sourcefile\(dq\& .fi Here, `\fIinline\fP\(cq\& is the name of a file containing the inline implementations of the class \fIInput\fP\(cq\&s member functions; `\fIinterface\fP\(cq\& is the name of a file containing the class \fIInput\fP\(cq\&s interface, while the non\-inline implementations of the class \fIInput\fP is provided in `\fIsourcefile\fP\(cq\&\&. .PP By default the class \fIInput\fP is defined in \fIScannerBase\(cq\&s\fP private section\&. When providing your own implementation the class \fIInput\fP is declared and defined in \fIScannerBase\(cq\&s\fP protected section so its members can also be accessed by the derived class \fIScanner\fP\&. Moreover, in that situation the (otherwise private) \fIScannerBase\fP data member \fIInput *d_input\fP is also declared in \fIScannerBase\(cq\&s\fP protected section\&. .PP In the default implementation of the class \fIInput\fP short, one\-line implementations of some of its members are defined \fIinline\fP below the interface of the class \fIScannerBase\fP in the generated \fIScannerBase\&.h\fP file\&. When providing your own implementation these members can also be defined \fIinline\fP by providing their implementations in a file (e\&.g\&., \fI\(dq\&inputinline\(dq\&\fP) which is specified by the \fI%input\-inline\fP directive\&. .PP When using the \fI%input\-inline\fP directive make sure that the defined members are specified as inline \fIInput::\fP class members inside the class \fIScannerBase\fP (using the actually used scanner class name)\&. E\&.g\&., if the default scanner class is used (see also the \fI%class\-name\fP directive), then the inline implementation of the member \fIInput::lineNr\fP could be .nf inline size_t ScannerBase::Line::lineNr() const { return d_lineNr; } .fi If, when using your self\-defined \fIInput\fP class, the default implementations of those \fIinline\fP members are not modified then use the default implementations by simply not specifying the \fI%input\-inline\fP directive\&. .PP Avoid using standard extensions for the files specified at the \fIinput\-implementation, input\-inline,\fP and \fIinput\-interface\fP directives to prevent confusing the compiler when using program maintenance utilities: the interface specifies the interface of the class \fIInput\fP, like the one shown aboove, and that interface is then inserted in \fIScannerBase\(cq\&s\fP class as a nested class\&. Putting these \fBs\fP in, e\&.g\&., a subdirectory \fIinput\fP of the scanner\(cq\&s directory, and then specifying, e\&.g\&., .nf %input\-interface = \(dq\&input/interface\(dq\& .fi nicely separates the interface and implementation of the scanner\-class from the user\-defined input class\&. .PP The file \fIsourcefile\fP specified at the \fI%input\-implementation\fP directive contains the standard (non\-inline) implementations of members of the user\-define \fIInput\fP class\&. .PP All member functions of the self\-defined class \fIInput\fP must be defined within the class \fIScannerBase\(cq\&s\fP class scope\&. E\&.g\&., an implementation of the member \fIInput::reRead(size_t ch)\fP would use the following mold: .nf void ScannerBase::Input::reRead(size_t ch) { \&.\&.\&.\&. your implementation here } .fi .PP When your user\-defined input class requires headers, which are not already provided by the class \fIScannerBase\fP (see the top lines of a generated \fIscannerbase\&.h\fP file for an overview of the already included header files) then provide the required \fI#include\fP specifications in the file specified at the \fI%baseclass\-preinclude\fP directive (or corresponding option)\&. The generated scanner itself is self\-supporting and doesn\(cq\&t need additional headers\&. .PP As an advice: when implementing your own \fIInput\fP class start out with the default class declaration and implementation as found in \fIScannerBase\&.h\fP and \fIlex\&.cc\fP, and modify that default class to the class you need\&. Note that the interface of your class \fIInput\fP must \fIat least\fP offer the same members and constructors of the default provided class \fIinput\fP, but it may define additional data members and/or member functions if required by your implementation (see also the following two section for descriptions of the class \fIInput\(cq\&s\fP constructors and required members\&. .PP When the lexical scanner generated by \fBflexc++\fP switches streams using the \fI//include\fP directive (see also section \fB2\&. FILE SWITCHING\fP) in the \fBflexc++input\fP(7) man page), then the input stream that\(cq\&s currently processed is pushed on an \fIInput\fP stack maintained by \fIScannerBase\fP, and processing continues at the file named at the \fI//include\fP directive\&. Once the latter file has been processed, the previously pushed stream is popped off the stack, and processing of the popped stream continues\&. This implies that \fIInput\fP objects must be `stack\-able\(cq\&\&. Its interface must always be designed in such a way that it satisfies this requirement\&. .PP .SH "18\&. INPUT CONSTRUCTORS" .PP .IP o \fBInput()\fP The default constructor is used by \fBScannerBase\fP to prepare the stack for \fIInput\fP objects\&. It must make sure that a default (empty) \fIInput\fP object is in a valid state and can be destroyed\&. It serves no further purpose\&. \fIInput\fP objects, however, must support the default (or overloaded) assignment operator\&. .IP o \fBInput(std::istream *iStream, size_t lineNr = 1)\fP This constructor receives a pointer to a dynamically allocated \fIistream\fP object\&. The \fIInput\fP constructor should preserve this pointer when the \fIInput\fP object is pushed on and popped off the stack\&. A \fIshared_ptr\fP probably comes in handy here\&. The \fIInput\fP object becomes the owner of the \fIistream\fP object, albeit that its destructor is \fInot\fP supposed to destroy the \fIistream\fP object\&. Destruction remains the responsibility of the \fIScannerBase\fP object, which calls the \fIInput::close\fP member (see below) when it\(cq\&s time to destroy (close) the stream\&. .IP The new input stream\(cq\&s line counter is set to \fIlineNr\fP, by default 1\&. .PP .SH "19\&. REQUIRED PUBLIC MEMBER FUNCTIONS" .PP .IP o \fBsize_t get()\fP returns the next character to be processed by the lexical scanner\&. Usually it will be the next character from the \fIistream\fP passed to the \fIInput\fP class at construction time\&. It is never called by the \fIScannerBase\fP object for \fIInput\fP objects defined using \fIInput\fP\(cq\&s default constructor\&. It should return 0x100 once \fIistream\fP\(cq\&s end\-of\-file has been reached\&. .IP o \fBsize_t lineNr() const\fP should return the (1\-based) number of the \fIistream\fP object passed to the \fIInput\fP object\&. At construction time the \fIistream\fP has just been opened and so at that point \fIlineNr\fP should return 1\&. .IP o \fBsize_t nPending() const\fP should return the number of pending characters (i\&.e\&., the number of characters which were passed back to the \fIInput\fP object using its \fIreRead\fP members which were not yet retrieved again by its \fIget\fP member)\&. .IP o \fBvoid setPending(size_t nPending)\fP should remove \fInPending\fP characters from the head of the \fIInput\fP object\(cq\&s pending input queue\&. The lexical scanner always passes the value received from \fInPending\fP to \fIsetPending\fP, without calling \fIget\fP in between\&. .IP o \fBvoid reRead(size_t ch)\fP if provided with a value smaller than 0x100 \fIch\fP should be pushed back onto the \fIistream\fP, where it becomes the character next to be returned\&. Physically the character doesn\(cq\&t have to be pushed back\&. The default implementation uses a \fIdeque\fP onto which the character is pushed\-front\&. Only when this \fIdeque\fP is exhausted characters are retrieved from the \fIInput\fP object\(cq\&s \fIistream\fP\&. .IP o \fBvoid reRead(std::string const &str, size_t fmIdx)\fP the characters in \fIstr\fP from \fIfmIdx\fP until the string\(cq\&s final character are pushed back onto the \fIistream\fP object so that the string\(cq\&s first character is retrieved first and the string\(cq\&s last character is retrieved last\&. .IP o \fBvoid close()\fP the \fIistream\fP object initially passed to the \fIInput\fP object is deleted by \fIclose\fP, thereby not only freeing the stream\(cq\&s memory, but also closing the stream if the stream in fact was an \fIifstream\fP\&. Note that the \fIInput\fP\(cq\&s destructor should \fInot\fP destroy the \fIInput\fP\(cq\&s \fIistream\fP object\&. .PP .SH "FILES" .PP \fBFlexc++\fP\(cq\&s default skeleton files are in \fI/usr/share/flexc++\fP\&. .br By default, \fBflexc++\fP generates the following files: .IP o \fIScanner\&.h\fP: the header file containing the scanner class\(cq\&s interface\&. .IP o \fIScannerbase\&.h\fP: the header file containing the interface of the scanner class\(cq\&s base class\&. .IP o \fIScanner\&.ih\fP: the internal header file that is meant to be included by the scanner class\(cq\&s source files (e\&.g\&., it is included by \fIlex\&.cc\fP, see the next item\(cq\&s file), and that should contain all declarations required for compiling the scanner class\(cq\&s sources\&. .IP o \fIlex\&.cc\fP: the source file implementing the scanner class member function \fIlex\fP (and support functions), performing the lexical scan\&. .PP .SH "SEE ALSO" .PP \fBflexc++\fP(1), \fBflexc++input\fP(7) .PP .SH "BUGS" .PP .IP o Generating interactive and non\-interactive scanners (see section 1\&. INTERACTIVE SCANNERS) cannot be mixed\&. .PP .SH "COPYRIGHT" This is free software, distributed under the terms of the GNU General Public License (GPL)\&. .PP .SH "AUTHOR" Frank B\&. Brokken (\fBf\&.b\&.brokken@rug\&.nl\fP), .br Jean\-Paul van Oosten (\fBj\&.p\&.van\&.oosten@rug\&.nl\fP), .br Richard Berendsen (\fBrichardberendsen@xs4all\&.nl\fP) (until 2010)\&. .br .PP