.TH "flexc++api" "3" "2008\-2020" "flexc++\&.2\&.08\&.01\&.tar\&.gz" "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)\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 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)\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 \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 \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 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 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 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 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)\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 \fBThis member is not available for interactive scanners\&.\fP .IP .IP o \fBScannerBase(std::istream &in, std::ostream &out)\fP The \fIin\fP and \fIout\fP parameters are, respectively, the derived class constructor\(cq\&s input stream and output streams\&. .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 whose interface looks like this: .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 a level in 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 an implementation for 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 and provide \fBflexc++\fP\(cq\&s base class with that \fIInput\fP class\&. To do so \fBflexc++\fP\(cq\&s rules file must contain the following two directives: .nf %input\-implementation = \(dq\&sourcefile\(dq\& %input\-interface = \(dq\&interface\(dq\& .fi Here, \fIinterface\fP is the name of a file containing the class \fIInput\fP\(cq\&s interface\&. This interface is then inserted into \fIScannerBase\fP\(cq\&s interface instead of the default class \fIInput\fP\(cq\&s interface\&. This interface must \fIat least\fP offer the aforementioned members and constructors (their functions are described below)\&. The class may contain additional members if required by the user\-defined implementation\&. The implementation itself is expected in \fIsourcefile\fP\&. The contents of this file are inserted in the generated \fIlex\&.cc\fP file instead of \fIInput\fP\(cq\&s default implementation\&. The file \fIsourcefile\fP should probably not have a \fI\&.cc\fP extension to prevent its compilation by a program maintenance utility\&. .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\&\&. The required interface is designed to satisfy 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