diff -Nru flexc++-1.07.00/INSTALL.im flexc++-1.08.00/INSTALL.im --- flexc++-1.07.00/INSTALL.im 2013-06-20 12:39:17.000000000 +0000 +++ flexc++-1.08.00/INSTALL.im 2013-12-28 16:33:32.000000000 +0000 @@ -25,8 +25,9 @@ #define BINARY "/usr/bin/"${PROGRAM} // the full path of the final program -#define MAN "/usr/share/man/man1" - // the directory whre the manual page is stored +#define MAN "/usr/share/man" + // the directory below whre the manual pages are stored (below + // /man1, /man3 and /man7) #define MANUAL "/usr/share/doc/"${PROGRAM}"/manual" // the directory whre the manual page is stored diff -Nru flexc++-1.07.00/TODO flexc++-1.08.00/TODO --- flexc++-1.07.00/TODO 2013-06-20 11:16:27.000000000 +0000 +++ flexc++-1.08.00/TODO 2013-12-28 16:53:56.000000000 +0000 @@ -1,3 +1,2 @@ final %% should be recognized by the scanner as its end-line - ADD OPTION TO DISPLAY THE MATCHED RULE TO EXECUTE diff -Nru flexc++-1.07.00/VERSION flexc++-1.08.00/VERSION --- flexc++-1.07.00/VERSION 2013-08-11 08:14:54.000000000 +0000 +++ flexc++-1.08.00/VERSION 2013-12-28 16:42:10.000000000 +0000 @@ -1,2 +1,2 @@ -#define VERSION "1.07.00" +#define VERSION "1.08.00" #define YEARS "2008-2013" diff -Nru flexc++-1.07.00/changelog flexc++-1.08.00/changelog --- flexc++-1.07.00/changelog 2013-08-11 09:11:19.000000000 +0000 +++ flexc++-1.08.00/changelog 2013-12-28 16:46:39.000000000 +0000 @@ -1,3 +1,21 @@ +flexc++ (1.08.00) + + * Added the 'postCode' member to the interface of the class generated by + flexc++ + + * Added the strongly typed PostEnum__ enumeration to the scanner base class + generated by flexc++ + + * Added a chapter `Pre-loading input lines' to the manual + + * The single flexc++ man-page was split into several more specific + man-pages: + flexc++ -- general description, and features of flexc++ itself + flexc++input -- how to write flexc++'s input files + flexc++api -- description of the classes generated by flexc++ + + -- Frank B. Brokken Sat, 28 Dec 2013 17:41:52 +0100 + flexc++ (1.07.00) * --force-* options removed. Use 'rm ...' to remove files if necessary. diff -Nru flexc++-1.07.00/debian/changelog flexc++-1.08.00/debian/changelog --- flexc++-1.07.00/debian/changelog 2013-08-12 00:01:41.000000000 +0000 +++ flexc++-1.08.00/debian/changelog 2013-12-30 03:21:14.000000000 +0000 @@ -1,3 +1,11 @@ +flexc++ (1.08.00-1) unstable; urgency=low + + * New upstream release extends and reorganizes flexc++'s documentation + and adds a member to the Scanner class which is called after a regular + expression has been matched. + + -- Frank B. Brokken Sat, 28 Dec 2013 18:09:41 +0100 + flexc++ (1.07.00-2) unstable; urgency=low * Export CXX during the build. Together with the explicit dependency diff -Nru flexc++-1.07.00/debian/control flexc++-1.08.00/debian/control --- flexc++-1.07.00/debian/control 2013-08-12 00:01:41.000000000 +0000 +++ flexc++-1.08.00/debian/control 2013-12-30 03:21:14.000000000 +0000 @@ -5,10 +5,10 @@ Uploaders: George Danchev , tony mancill Build-Depends: debhelper (>= 9), libbobcat-dev (>= 3.12.00), - icmake (>= 7.19.0), g++-4.8, - yodl (>= 3.00.0), + icmake (>= 7.21.0), g++-4.8 (>= 4.8.2), + yodl (>= 3.03.0), hardening-wrapper, hardening-includes -Standards-Version: 3.9.4 +Standards-Version: 3.9.5 Homepage: http://flexcpp.sourceforge.net Vcs-Git: git://anonscm.debian.org/collab-maint/flexcpp.git Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/flexcpp.git diff -Nru flexc++-1.07.00/debian/rules flexc++-1.08.00/debian/rules --- flexc++-1.07.00/debian/rules 2013-08-12 00:01:41.000000000 +0000 +++ flexc++-1.08.00/debian/rules 2013-12-30 03:21:14.000000000 +0000 @@ -7,7 +7,7 @@ # Archive downloaded from https://www.icce.rug.nl/debian/flexc++ # file: flexc++_x.y.z.tar.gz -MD5TRUSTED := c0786ca4d2bf29a5259596345ed8b887 +MD5TRUSTED := 6578f810f54e18234556dab3112e4d84 # Uncomment this to turn on verbose mode. # export DH_VERBOSE=1 @@ -52,7 +52,7 @@ ./build install program debian/flexc++/usr/bin/flexc++ ./build install skel debian/flexc++/usr/share/flexc++ ./build install std debian/flexc++/usr/share/doc/flexc++ - ./build install man debian/flexc++/usr/share/man/man1 + ./build install man debian/flexc++/usr/share/man ./build install manual debian/flexc++/usr/share/doc/flexc++/manual binary-indep: diff -Nru flexc++-1.07.00/documentation/man/flexc++.yo flexc++-1.08.00/documentation/man/flexc++.yo --- flexc++-1.07.00/documentation/man/flexc++.yo 2013-08-05 19:48:06.000000000 +0000 +++ flexc++-1.08.00/documentation/man/flexc++.yo 2013-12-28 16:08:00.000000000 +0000 @@ -1,4 +1,4 @@ -NOUSERMACRO(lex setDebug) +NOUSERMACRO(lex setDebug postCode) includefile(../../release.yo) @@ -66,78 +66,106 @@ code generated by bf(flexc++) is pure bf(C++), allowing its users to apply all of the features offered by that language. - Below, the following sections may be consulted for specific details: + Not every aspect of flc() is covered by the man-pages. In addition to +what's summarized by the man-pages the flc() manual offers a chapter covering +pre-loading of input lines (allowing you to, e.g, display lines in which +errors are observed even though not all of the line's tokens have already been +scanned), as well as a chapter covering technical documentation about the +inner working of flc(). + + From version 0.92.00 Until version 1.07.00 flc() offered one big manual +page. The advantage of that being that you never had to look for which manual +page contained which information. At the same time, flc()'s man-page grew into +a huge man-page, in which it was hard to find your way. Starting with release +1.08.00 we reverted back to using multiple man-pages. The following index +relates manual pages to their specific contents: + +bf(This man-page) + + This man-page offers the following sections: + itemization( it() bf(1. QUICK START): a quick start overview about how to use flc(). it() bf(2. QUICK START: FLEXC++ and BISONC++): a quick start overview about how to use flc() in combination with bf(bisonc++)(1) it() bf(3. GENERATED FILES): files generated by flc() and their purposes it() bf(4. OPTIONS): options available for flc() - it() bf(5. INTERACTIVE SCANNERS): how to create an interactive scanner + ) - it() bf(6. SPECIFICATION FILE(S)): the format and contents of flc() input - files, specifying the Scanner's characteristics - it() bf(6.1. FILE SWITCHING): how to switch to another input specification - file - it() bf(6.2. DIRECTIVES): directives that can be used in input - specification files - it() bf(6.3. MINI SCANNERS): how to declare mini-scanners - it() bf(6.4. DEFINITIONS): how to define symbolic names for regular - expressions - it() bf(6.5. %% SEPARATOR): the separator between the input specification - sections - it() bf(6.6. REGULAR EXPRESSIONS): regular expressions supported by flc() - it() bf(6.7. SPECIFICATION EXAMPLE): an example of a specification file +The bf(flexc++api)(3) man-page: + + This man-page describes the classes generated by flc(), describing flc()'s +actions from the programmer's point of view. + + itemization( + it() bf(1. INTERACTIVE SCANNERS): how to create an interactive scanner - it() bf(7. THE CLASS INTERFACE: SCANNER.H): Constructors and members + it() bf(2. THE CLASS INTERFACE: SCANNER.H): Constructors and members of the scanner class generated by flc() - it() bf(7.1. NAMING CONVENTION): symbols defined by flc() in the scanner + it() bf(3. NAMING CONVENTION): symbols defined by flc() in the scanner class. - it() bf(7.2 CONSTRUCTORS): constructors defined in the scanner class. - it() bf(7.3 PUBLIC MEMBER FUNCTION): public member declared in the scanner + it() bf(4. CONSTRUCTORS): constructors defined in the scanner class. + it() bf(5. PUBLIC MEMBER FUNCTION): public member declared in the scanner class. - it() bf(7.4. PRIVATE MEMBER FUNCTIONS): private members declared in the + it() bf(6. PRIVATE MEMBER FUNCTIONS): private members declared in the scanner class. - it() bf(7.5. SCANNER CLASS HEADER EXAMPLE): an example of a generated + it() bf(7. SCANNER CLASS HEADER EXAMPLE): an example of a generated scanner class header - it() bf(8.1. THE SCANNER BASE CLASS): the scanner class is derived from a + it() bf(8. THE SCANNER BASE CLASS): the scanner class is derived from a base class. The base class is described in this section - it() bf(8.2. PUBLIC ENUMS AND -TYPES): enums and types declared by the + it() bf(9. PUBLIC ENUMS AND -TYPES): enums and types declared by the base class - it() bf(8.3. PROTECTED ENUMS AND -TYPES): enumerations and types used by + it() bf(10. PROTECTED ENUMS AND -TYPES): enumerations and types used by the scanner and scanner base classes - it() bf(8.4. NO PUBLIC CONSTRUCTORS): the scanner base class does not + it() bf(11. NO PUBLIC CONSTRUCTORS): the scanner base class does not offer public constructors. - it() bf(8.5. PUBLIC MEMBER FUNCTIONS): several members defined by the + it() bf(12. PUBLIC MEMBER FUNCTIONS): several members defined by the scanner base class have public access rights. - it() bf(8.6. PROTECTED CONSTRUCTORS): the base class can be constructed by + it() bf(13. PROTECTED CONSTRUCTORS): the base class can be constructed by a derived class. Usually this is the scanner class generated by flc(). - it() bf(8.7. PROTECTED MEMBER FUNCTIONS): this section covers the base + it() bf(14. PROTECTED MEMBER FUNCTIONS): this section covers the base class member functions that can only be used by scanner class or scanner base class members - it() bf(8.8. PROTECTED DATA MEMBERS): this section covers the base class + it() bf(15. PROTECTED DATA MEMBERS): this section covers the base class data members that can only be used by scanner class or scanner base class members - it() bf(8.9. FLEX++ TO FLEXC++ MEMBERS): a short overview of frequently + it() bf(16. FLEX++ TO FLEXC++ MEMBERS): a short overview of frequently used bf(flex)(1) members that received different names in flc(). - it() bf(9.1. THE CLASS INPUT): the scanner's job is completely decoupled + it() bf(17. THE CLASS INPUT): the scanner's job is completely decoupled from the actual input stream. The class tt(Input), nested within the scanner base class handles the communication with the input streams. The class tt(Input), is described in this section. - it() bf(9.2. CONSTRUCTORS): the class tt(Input) can easily be replaced by - another class. The constructor-requirements are described in this - section. - it() bf(9.3. REQUIRED PUBLIC MEMBER FUNCTIONS): this section covers the + it() bf(18. INPUT CONSTRUCTORS): the class tt(Input) can easily be + replaced by another class. The constructor-requirements are described + in this section. + it() bf(19. REQUIRED PUBLIC MEMBER FUNCTIONS): this section covers the required public members of a self-made tt(Input) class ) +The bf(flexc++input)(7) man-page: + + This man-page describes how flc()'s input file(s) should be organized. It +contains the following sections: + + itemization( + it() bf(1. SPECIFICATION FILE(S)): the format and contents of flc() input + files, specifying the Scanner's characteristics + it() bf(2. FILE SWITCHING): how to switch to another input specification + file + it() bf(3. DIRECTIVES): directives that can be used in input + specification files + it() bf(4. MINI SCANNERS): how to declare mini-scanners + it() bf(5. DEFINITIONS): how to define symbolic names for regular + expressions + it() bf(6. %% SEPARATOR): the separator between the input specification + sections + it() bf(7. REGULAR EXPRESSIONS): regular expressions supported by flc() + it() bf(8. SPECIFICATION EXAMPLE): an example of a specification file + ) + includefile(generic.yo) -includefile(rules.yo) -includefile(scanner.h.yo) -includefile(scannerbase.h.yo) -includefile(input.yo) manpagefiles() @@ -159,19 +187,11 @@ manpageseealso() - bf(bisonc++)(1) + bf(bisonc++)(1), bf(flexc++api)(3), bf(flexc++input)(7) manpagebugs() - itemization( - it() The priority of interval expressions (tt({...})) equals the priority -of other multiplicative operators (like tt(*)). - it() All tt(INITIAL) rules apply to inclusive mini scanners, also those -tt(INITIAL) rules that were explicitly associated with the tt(INITIAL) mini -scanner. - it() Generating interactive and non-interactive scanners (see section - 5. INTERACTIVE SCANNERS) cannot be mixed. - ) + None reported manpagesection(ABOUT flexc++) diff -Nru flexc++-1.07.00/documentation/man/flexc++api.yo flexc++-1.08.00/documentation/man/flexc++api.yo --- flexc++-1.07.00/documentation/man/flexc++api.yo 1970-01-01 00:00:00.000000000 +0000 +++ flexc++-1.08.00/documentation/man/flexc++api.yo 2013-12-28 16:25:27.000000000 +0000 @@ -0,0 +1,140 @@ +NOUSERMACRO(lex setDebug) + +includefile(../../release.yo) + +htmlbodyopt(text)(#27408B) +htmlbodyopt(bgcolor)(#FFFAF0) +whenhtml(mailto(Frank B. Brokken: f.b.brokken@rug.nl)) + +DEFINEMACRO(lsoption)(3)(\ + bf(--ARG1)=tt(ARG3) (bf(-ARG2))\ +) +DEFINEMACRO(laoption)(2)(\ + bf(--ARG1)=tt(ARG2)\ +) +DEFINEMACRO(loption)(1)(\ + bf(--ARG1)\ +) +DEFINEMACRO(soption)(1)(\ + bf(-ARG1)\ +) + +DEFINEMACRO(flc)(0)(bf(flexc++)) +DEFINEMACRO(Flc)(0)(bf(Flexc++)) +DEFINEMACRO(Cpp)(0)(bf(C++)) +DEFINEMACRO(prot)(0)(tt((prot))) + +DELETEMACRO(tt) +DEFINEMACRO(tt)(1)(em(ARG1)) +DEFINEMACRO(itt)(1)(it() tt(ARG1)) +DEFINEMACRO(itb)(1)(it() bf(ARG1)) + +NOUSERMACRO( FILE Input Scanner ScannerBase YYText accept back begin close +debug echo filename files get interactiveLine leave length less lineNr lineno +matched more name out popStream preCode print push pushStream reRead redo +scanner setFilename setMatched startCondition streamStack switchIstream +switchOstream switchStreams api postCode + ) + +COMMENT( man-request, section, date, distribution file, general name) +manpage(flexc++api)(3)(_CurYrs_)(flexc++._CurVers_.tar.gz) + (flexc++ API) + +COMMENT( man-request, larger title ) +manpagename(flexc++api) + (Application programmer's interface of flexc++ generated classes) + + +manpagedescription() + + Flc()(1) was designed after bf(flex)(1) and bf(flex++)(1). Like these +latter two programs flc() generates code performing pattern-matching on text, +possibly executing actions when certain em(regular expressions) are +recognized. + + Refer to bf(flexc++)(1) for a general overview. This manual page covers +the Application Programmer's Interface of classes generated by flc(), offering +the following sections: + + itemization( + it() bf(1. INTERACTIVE SCANNERS): how to create an interactive scanner + + it() bf(2. THE CLASS INTERFACE: SCANNER.H): Constructors and members + of the scanner class generated by flc() + it() bf(3. NAMING CONVENTION): symbols defined by flc() in the scanner + class. + it() bf(4. CONSTRUCTORS): constructors defined in the scanner class. + it() bf(5. PUBLIC MEMBER FUNCTION): public member declared in the scanner + class. + it() bf(6. PRIVATE MEMBER FUNCTIONS): private members declared in the + scanner class. + it() bf(7. SCANNER CLASS HEADER EXAMPLE): an example of a generated + scanner class header + + it() bf(8. THE SCANNER BASE CLASS): the scanner class is derived from a + base class. The base class is described in this section + it() bf(9. PUBLIC ENUMS AND -TYPES): enums and types declared by the + base class + it() bf(10. PROTECTED ENUMS AND -TYPES): enumerations and types used by + the scanner and scanner base classes + it() bf(11. NO PUBLIC CONSTRUCTORS): the scanner base class does not + offer public constructors. + it() bf(12. PUBLIC MEMBER FUNCTIONS): several members defined by the + scanner base class have public access rights. + it() bf(13. PROTECTED CONSTRUCTORS): the base class can be constructed by + a derived class. Usually this is the scanner class generated by flc(). + it() bf(14. PROTECTED MEMBER FUNCTIONS): this section covers the base + class member functions that can only be used by scanner class or + scanner base class members + it() bf(15. PROTECTED DATA MEMBERS): this section covers the base class + data members that can only be used by scanner class or scanner base + class members + it() bf(16. FLEX++ TO FLEXC++ MEMBERS): a short overview of frequently + used bf(flex)(1) members that received different names in flc(). + + it() bf(17. THE CLASS INPUT): the scanner's job is completely decoupled + from the actual input stream. The class tt(Input), nested within the + scanner base class handles the communication with the input + streams. The class tt(Input), is described in this section. + it() bf(18. INPUT CONSTRUCTORS): the class tt(Input) can easily be + replaced by another class. The constructor-requirements are described + in this section. + it() bf(19. REQUIRED PUBLIC MEMBER FUNCTIONS): this section covers the + required public members of a self-made tt(Input) class + ) + +includefile(interactive.yo) +includefile(scanner.h.yo) +includefile(scannerbase.h.yo) +includefile(input.yo) + +manpagefiles() + + Flc()'s default skeleton files are in tt(/usr/share/flexc++).nl() + By default, flc() generates the following files: + itemization( + itt(Scanner.h): the header file containing the scanner class's + interface. + itt(Scannerbase.h): the header file containing the interface of the + scanner class's base class. + itt(Scanner.ih): the internal header file that is meant to be included + by the scanner class's source files (e.g., it is included by + tt(lex.cc), see the next item's file), and that should contain all + declarations required for compiling the scanner class's sources. + itt(lex.cc): the source file implementing the scanner class member + function tt(lex) (and support functions), performing the lexical + scan. + ) + +manpageseealso() + + bf(flexc++)(1), bf(flexc++input)(7) + +manpagebugs() + + itemization( + it() Generating interactive and non-interactive scanners (see section + 1. INTERACTIVE SCANNERS) cannot be mixed. + ) + +includefile(include/trailer.yo) diff -Nru flexc++-1.07.00/documentation/man/flexc++input.yo flexc++-1.08.00/documentation/man/flexc++input.yo --- flexc++-1.07.00/documentation/man/flexc++input.yo 1970-01-01 00:00:00.000000000 +0000 +++ flexc++-1.08.00/documentation/man/flexc++input.yo 2013-12-28 16:11:28.000000000 +0000 @@ -0,0 +1,109 @@ +NOUSERMACRO(lex setDebug input) + +includefile(../../release.yo) + +htmlbodyopt(text)(#27408B) +htmlbodyopt(bgcolor)(#FFFAF0) +whenhtml(mailto(Frank B. Brokken: f.b.brokken@rug.nl)) + +DEFINEMACRO(lsoption)(3)(\ + bf(--ARG1)=tt(ARG3) (bf(-ARG2))\ +) +DEFINEMACRO(laoption)(2)(\ + bf(--ARG1)=tt(ARG2)\ +) +DEFINEMACRO(loption)(1)(\ + bf(--ARG1)\ +) +DEFINEMACRO(soption)(1)(\ + bf(-ARG1)\ +) + +DEFINEMACRO(flc)(0)(bf(flexc++)) +DEFINEMACRO(Flc)(0)(bf(Flexc++)) +DEFINEMACRO(Cpp)(0)(bf(C++)) +DEFINEMACRO(prot)(0)(tt((prot))) + +DELETEMACRO(tt) +DEFINEMACRO(tt)(1)(em(ARG1)) +DEFINEMACRO(itt)(1)(it() tt(ARG1)) +DEFINEMACRO(itb)(1)(it() bf(ARG1)) + +NOUSERMACRO( FILE Input Scanner ScannerBase YYText accept back begin close +debug echo filename files get interactiveLine leave length less lineNr lineno +matched more name out popStream preCode print push pushStream reRead redo +scanner setFilename setMatched startCondition streamStack switchIstream +switchOstream switchStreams + ) + +COMMENT( man-request, section, date, distribution file, general name) +manpage(flexc++input)(7)(_CurYrs_)(flexc++._CurVers_.tar.gz) + (flexc++ input file organization) + +COMMENT( man-request, larger title ) +manpagename(flexc++input)(Organization of flexc++'s input file(s)) + +manpagedescription() + + Flc()(1) was designed after bf(flex)(1) and bf(flex++)(1). Like these +latter two programs flc() generates code performing pattern-matching on text, +possibly executing actions when certain em(regular expressions) are +recognized. + + Refer to bf(flexc++)(1) for a general overview. This manual page describes +how flc()'s input file(s) should be organized. It contains the following +sections: + + itemization( + it() bf(1. SPECIFICATION FILE(S)): the format and contents of flc() input + files, specifying the Scanner's characteristics + it() bf(2. FILE SWITCHING): how to switch to another input specification + file + it() bf(3. DIRECTIVES): directives that can be used in input + specification files + it() bf(4. MINI SCANNERS): how to declare mini-scanners + it() bf(5. DEFINITIONS): how to define symbolic names for regular + expressions + it() bf(6. %% SEPARATOR): the separator between the input specification + sections + it() bf(7. REGULAR EXPRESSIONS): regular expressions supported by flc() + it() bf(8. SPECIFICATION EXAMPLE): an example of a specification file + ) + + +includefile(rules.yo) + +manpagefiles() + + Flc()'s default skeleton files are in tt(/usr/share/flexc++).nl() + By default, flc() generates the following files: + itemization( + itt(Scanner.h): the header file containing the scanner class's + interface. + itt(Scannerbase.h): the header file containing the interface of the + scanner class's base class. + itt(Scanner.ih): the internal header file that is meant to be included + by the scanner class's source files (e.g., it is included by + tt(lex.cc), see the next item's file), and that should contain all + declarations required for compiling the scanner class's sources. + itt(lex.cc): the source file implementing the scanner class member + function tt(lex) (and support functions), performing the lexical + scan. + ) + +manpageseealso() + + bf(flexc++)(1), bf(flexc++api)(3) + +manpagebugs() + + itemization( + it() The priority of interval expressions (tt({...})) equals the priority +of other multiplicative operators (like tt(*)). + it() All tt(INITIAL) rules apply to inclusive mini scanners, also those +tt(INITIAL) rules that were explicitly associated with the tt(INITIAL) mini +scanner. + ) + +includefile(include/trailer.yo) + diff -Nru flexc++-1.07.00/documentation/man/generic.yo flexc++-1.08.00/documentation/man/generic.yo --- flexc++-1.07.00/documentation/man/generic.yo 2013-06-20 19:50:36.000000000 +0000 +++ flexc++-1.08.00/documentation/man/generic.yo 2013-12-28 15:24:34.000000000 +0000 @@ -79,7 +79,7 @@ ) ) - manpagesection(QUICK START: FLEXC++ and BISONC++) + manpagesection(2. QUICK START: FLEXC++ and BISONC++) To interface flc() to the bf(bisonc++)(1) parser generator proceed as follows: itemization( @@ -202,80 +202,3 @@ 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; - } - } - } - ) - ) diff -Nru flexc++-1.07.00/documentation/man/input.yo flexc++-1.08.00/documentation/man/input.yo --- flexc++-1.07.00/documentation/man/input.yo 2013-06-20 14:16:39.000000000 +0000 +++ flexc++-1.08.00/documentation/man/input.yo 2013-12-28 16:18:30.000000000 +0000 @@ -1,5 +1,5 @@ -manpagesection(9.1 THE CLASS INPUT) +manpagesection(17. THE CLASS INPUT) Flc() generates a file tt(Scannerbase.h) defining the scanner class's base class, by default named tt(ScannerBase) (which is the name used in this @@ -45,7 +45,7 @@ compilation by a program maintenance utility. When the lexical scanner generated by flc() switches streams using the -tt(//include) directive (see section bf(6.1. FILE SWITCHING)) the input +tt(//include) directive (see also section bf(2. FILE SWITCHING)) the input stream that's currently processed is pushed on an tt(Input) stack maintained by tt(ScannerBase), and processing continues at the file named at the tt(//include) directive. Once the latter file has been processed, the @@ -54,7 +54,7 @@ `stack-able'. The required interface is designed to satisfy this requirement. -manpagesection(9.2. CONSTRUCTORS) +manpagesection(18. INPUT CONSTRUCTORS) itemization( itb(Input()) @@ -77,7 +77,7 @@ 1. ) -manpagesection(9.3. REQUIRED PUBLIC MEMBER FUNCTIONS) +manpagesection(19. REQUIRED PUBLIC MEMBER FUNCTIONS) itemization( itb(size_t get()) diff -Nru flexc++-1.07.00/documentation/man/interactive.yo flexc++-1.08.00/documentation/man/interactive.yo --- flexc++-1.07.00/documentation/man/interactive.yo 1970-01-01 00:00:00.000000000 +0000 +++ flexc++-1.08.00/documentation/man/interactive.yo 2013-12-28 15:31:42.000000000 +0000 @@ -0,0 +1,77 @@ +manpagesection(1. 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; + } + } + } + ) + ) + diff -Nru flexc++-1.07.00/documentation/man/rules.yo flexc++-1.08.00/documentation/man/rules.yo --- flexc++-1.07.00/documentation/man/rules.yo 2013-06-20 11:16:27.000000000 +0000 +++ flexc++-1.08.00/documentation/man/rules.yo 2013-12-28 16:21:50.000000000 +0000 @@ -1,4 +1,4 @@ -manpagesection(6. SPECIFICATION FILE(S)) +manpagesection(1. SPECIFICATION FILE(S)) Flc() expects an input file containing directives and the regular expressions that should be recognized by objects of the scanner class @@ -21,7 +21,7 @@ two consecutive slashes (tt(//)) start the comment, which continues up to the next newline character. -manpagesection(6.1. FILE SWITCHING) +manpagesection(2. FILE SWITCHING) Flc()'s input file may be split into multiple files. This allows for the definition of logically separate elements of the specifications in different @@ -42,7 +42,7 @@ the file that was initially specified when flc() was called indicates the end of flc()'s rules specification. -manpagesection(6.2. DIRECTIVES) +manpagesection(3. DIRECTIVES) The first section of flc()'s input file consists of directives. In addition it may associate regular expressions with symbolic names, allowing @@ -52,7 +52,7 @@ includefile(../manual/lexer/directives.yo) -manpagesection(6.3. MINI SCANNERS) +manpagesection(4. MINI SCANNERS) Mini scanners come in two flavors: inclusive mini scanners and exclusive mini scanners. The rules that apply to an inclusive mini scanner are the mini @@ -75,7 +75,7 @@ A flc() input file may contain multiple tt(%s) and tt(%x) specifications. -manpagesection(6.4. DEFINITIONS) +manpagesection(5. DEFINITIONS) Definitions are of the form verb( @@ -84,7 +84,7 @@ Each definition must be entered on a line of its own. Definitions associate identifiers with regular expressions, allowing the use of tt(${identifier}) as synonym for its regular expression in the rules section -of the flc() input file. One defined, the identifiers representing regular +of flc()'s input file. One defined, the identifiers representing regular expressions can also be used in subsequent definitions. Example: @@ -93,14 +93,14 @@ NAME {FIRST}[-A-Za-z0-9_]* ) -manpagesection(6.5. %% SEPARATOR) +manpagesection(6. %% SEPARATOR) Following directives and definitions a line merely containing two consecutive tt(%) characters is expected. Following this line the rules are defined. Rules consist of regular expressions which should be recognized, possibly followed by actions to be executed once a rule's regular expression has been matched. -manpagesection(6.6. REGULAR EXPRESSIONS) +manpagesection(7. REGULAR EXPRESSIONS) The regular expressions defined in flc()'s rules files are matched against the information passed to the scanner's tt(lex) function. @@ -308,7 +308,7 @@ at, respectively, the beginning and end of regular expressions. In all other cases they are treated as a normal characters. -manpagesection(6.7. SPECIFICATION EXAMPLE) +manpagesection(8. SPECIFICATION EXAMPLE) verb( %option debug diff -Nru flexc++-1.07.00/documentation/man/scanner.h.yo flexc++-1.08.00/documentation/man/scanner.h.yo --- flexc++-1.07.00/documentation/man/scanner.h.yo 2013-06-20 14:23:47.000000000 +0000 +++ flexc++-1.08.00/documentation/man/scanner.h.yo 2013-12-28 16:23:03.000000000 +0000 @@ -1,4 +1,4 @@ -manpagesection(7. THE CLASS INTERFACE: SCANNER.H) +manpagesection(2. THE CLASS INTERFACE: SCANNER.H) By default, flc() generates a file tt(Scanner.h) containing the initial interface of the scanner class performing the lexical scan according to the @@ -10,13 +10,13 @@ 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). +the scanner's base class (see this manpage's sections 8 through 16). bf(Many of the facilities offered by the scanner class are inherited from the tt(ScannerBase) base class. Additional facilities offered by the tt(Scanner) class. are covered below). -manpagesection(7.1. NAMING CONVENTION) +manpagesection(3. NAMING CONVENTION) All symbols that are required by the generated scanner class end in two consecutive underscore characters (e.g., tt(executeAction__)). These names @@ -30,7 +30,7 @@ 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) +manpagesection(4. CONSTRUCTORS) itemization( itb(explicit Scanner(std::istream &in = std::cin, @@ -52,7 +52,7 @@ bf(This constructor is not available with interactive scanners.) ) -manpagesection(7.3. PUBLIC MEMBER FUNCTIONS) +manpagesection(5. PUBLIC MEMBER FUNCTIONS) itemization( itb(int lex()) @@ -80,7 +80,7 @@ first having generated files implementing an interactive scanner. ) -manpagesection(7.4. PRIVATE MEMBER FUNCTIONS) +manpagesection(6. PRIVATE MEMBER FUNCTIONS) itemization( itb(int lex__()) @@ -116,6 +116,14 @@ } // while } ) + itb(void postCode(PostEnum__ type)) + By default this function has an empty, inline implementation in +tt(Scanner.h). It can safely be replaced by a user-defined +implementation. This function is called by tt(lex__), just after a rule has +been matched. Values of the tt(enum class PostEnum__) indicate the +characteristic of the matched rule. tt(PostEnum__) has four values: +tt(PostEnum__::END, PostEnum__::POP, PostEnum__::RETURN), and +tt(PostEnum__::WIP). Refer to section 10 for their meanings. itb(void print()) When the tt(--print-tokens) or tt(%print-tokens) directive is used this function is called to display, on the standard output stream, @@ -130,7 +138,7 @@ by an option controlled by the program using the scanner object. ) -manpagesection(7.5. SCANNER CLASS HEADER EXAMPLE) +manpagesection(7. SCANNER CLASS HEADER EXAMPLE) verb( #ifndef Scanner_H_INCLUDED_ diff -Nru flexc++-1.07.00/documentation/man/scannerbase.h.yo flexc++-1.08.00/documentation/man/scannerbase.h.yo --- flexc++-1.07.00/documentation/man/scannerbase.h.yo 2013-06-20 19:50:36.000000000 +0000 +++ flexc++-1.08.00/documentation/man/scannerbase.h.yo 2013-12-28 16:16:04.000000000 +0000 @@ -1,4 +1,4 @@ -manpagesection(8.1. THE SCANNER BASE CLASS) +manpagesection(8. THE SCANNER BASE CLASS) By default, flc() generates a file tt(Scannerbase.h) containing the interface of the base class of the scanner class also generated by flc(). The @@ -9,7 +9,7 @@ no user-serviceable or extensible parts. Rewriting can be prevented by specifying flc()'s tt(--no-baseclass-header) option). -manpagesection(8.2. PUBLIC ENUMS AND -TYPES) +manpagesection(9. PUBLIC ENUMS AND -TYPES) itemization( itb(enum class StartCondition__) @@ -23,22 +23,41 @@ ) ) -manpagesection(8.3. PROTECTED ENUMS AND -TYPES) +manpagesection(10. PROTECTED ENUMS AND -TYPES) itemization( itb(enum class ActionType__) This strongly typed enumeration is for internal use only. itb(enum Leave__) This enumeration is for internal use only. + itb(enum class PostEnum__) + Values of this strongly typed enumeration are passed to the scanner's + private member tt(postCode), indicating the scanner's action after + matching a rule. The values of this enumeration are: + + tt(PostEnum__::END): the function tt(lex__) immediately returns 0 + once tt(postCode) returns, indicating the end of the input was + reached; + + tt(PostEnum__::POP): the end of an input stream was reached, and + processing continues with the previously pushed input stream. In + this case the function tt(lex__) doesn't return, it simply + coontinues processing the previously pushed stream; + + tt(PostEnum__::RETURN): the function tt(lex__) immediately returns + once tt(postCode) returns, returning the next token; + + tt(PostEnum__::WIP): the function tt(lex__) has matched a + non-returning rule, and continues its rule-matching process. ) -manpagesection(8.4. NO PUBLIC CONSTRUCTORS) +manpagesection(11. NO PUBLIC CONSTRUCTORS) There are no public constructors. tt(ScannerBase) is a base class for the tt(Scanner) class generated by flc(). tt(ScannerBase) only offers protected constructors. -manpagesection(8.5. PUBLIC MEMBER FUNCTIONS) +manpagesection(12. PUBLIC MEMBER FUNCTIONS) itemization( itb(bool debug() const) @@ -118,7 +137,7 @@ ) -manpagesection(8.6. PROTECTED CONSTRUCTORS) +manpagesection(13. PROTECTED CONSTRUCTORS) itemization( itb(ScannerBase(std::string const &infilename, @@ -134,7 +153,7 @@ constructor's input stream and output streams. ) -manpagesection(8.7. PROTECTED MEMBER FUNCTIONS) +manpagesection(14. PROTECTED MEMBER FUNCTIONS) All member functions ending in two underscore characters are for internal use only and should not be called by user-defined members of the @@ -277,12 +296,12 @@ ) -manpagesection(8.8. PROTECTED DATA MEMBERS) +manpagesection(15. PROTECTED DATA MEMBERS) All protected data members are for internal use only, allowing tt(lex__) to access them. All of them end in two underscore characters. -manpagesection(8.9. FLEX++ TO FLEXC++ MEMBERS) +manpagesection(16. FLEX++ TO FLEXC++ MEMBERS) setmanalign(lcl) table(3)(lcl)( diff -Nru flexc++-1.07.00/documentation/manual/flexc++.yo flexc++-1.08.00/documentation/manual/flexc++.yo --- flexc++-1.07.00/documentation/manual/flexc++.yo 2013-06-20 11:16:27.000000000 +0000 +++ flexc++-1.08.00/documentation/manual/flexc++.yo 2013-12-21 16:24:30.000000000 +0000 @@ -91,13 +91,28 @@ sect(Handling input your own way) includefile(lexer/input) - lchapter(generated-files)(Generated files) includefile(files/intro) lsect(multiplestreams)(Multiple input streams) includefile(files/multiple) +chapter(Pre-loading input lines) +includefile(input/intro) + + sect(Using mini-scanners to pre-load input lines) + includefile(input/miniscanners) + + sect(Wrapping input streams) + includefile(input/wrapping) + + subsect(The class ScannerStreambuf) + includefile(input/scannerstreambuf) + + subsect(Illustration) + includefile(input/illustrationwrap) + + chapter(Technical documentation (PIPETHROUGH(date -R)())) includefile(technical/intro) Binary files /tmp/FGovgRufwA/flexc++-1.07.00/documentation/manual/images/inputwrapping.jpg and /tmp/4sdtQLmeqX/flexc++-1.08.00/documentation/manual/images/inputwrapping.jpg differ Binary files /tmp/FGovgRufwA/flexc++-1.07.00/documentation/manual/images/molds/inputwrapping.pdf and /tmp/4sdtQLmeqX/flexc++-1.08.00/documentation/manual/images/molds/inputwrapping.pdf differ diff -Nru flexc++-1.07.00/documentation/manual/input/illustrationwrap.yo flexc++-1.08.00/documentation/manual/input/illustrationwrap.yo --- flexc++-1.07.00/documentation/manual/input/illustrationwrap.yo 1970-01-01 00:00:00.000000000 +0000 +++ flexc++-1.08.00/documentation/manual/input/illustrationwrap.yo 2013-12-21 16:21:44.000000000 +0000 @@ -0,0 +1,28 @@ +Here is a set of lexer-rules which is used to illustrate the various +approaches with: + + verbinclude(scanner/lexer) + +Identifiers and numbers are returned as tokens, square brackets are returned +as tt(SIGNAL) tokens, indicating that we would like to see the lines and +columns in which they were found, white space characters are ignored, and +all other characters are returned as-is. + +The tt(main) function uses the tt(column) and tt(line) members, which were +added to the tt(class Scanner): + + verbinclude(scanner/main.cc) + +The tt(IStreambuf) wraps around tt(cin), and is passed to an tt(istream), +which in turn is passed to the tt(Scanner) object. When the scanner returns +tt(SIGNAL) tokens their lines, column indicators, line numbers and column +numbers are shown. + +Members like tt(switchStream) and tt(pushStream), expecting tt(std::istream) +references can also be used, if the actual input streams are wrapped in +tt(ScannerStreambuf) objects, which are passed to tt(istream) objects which +are, in turn, passed to tt(switchStream) and tt(pushStream). The members +expecting names of streams should of course not be used, since the scanner +creates plain tt(std::ifstream) objects for them. + + diff -Nru flexc++-1.07.00/documentation/manual/input/intro.yo flexc++-1.08.00/documentation/manual/input/intro.yo --- flexc++-1.07.00/documentation/manual/input/intro.yo 1970-01-01 00:00:00.000000000 +0000 +++ flexc++-1.08.00/documentation/manual/input/intro.yo 2013-12-21 16:21:44.000000000 +0000 @@ -0,0 +1,55 @@ +In some programs it may be desirable to have the currently scanned line +available, even though all its contents hasn't been read yet by flc(). + +E.g., when the tt(g++) compiler detects an error or warning it displays the +full line in which the error or warning condition arose, as well as a column +indicator indicating where the condition was observed (below, a condition +where the current input line should be displayed is simply called a +`condition'). + +Flc() could use one of the following approaches to provide the required +condition information: + itemization( + it() At each end of line flc() could store the current offset of the file + it is reading. Furthermore, each rule adds tt(length()) to a data + member keeping track of the length of the line read so far, making + this data member's value available through an accessor (e.g., + tt(column())). After each newline this data member is reset to zero. + + The code calling the scanner's tt(lex) member maintains a data + member holding the offset that was last returned by the scanner, as + well as a `condition vector' whose elements contain column numbers and + messages describing the nature of the conditions. + + When the code calling the scanner's tt(lex) member observes a + condition it compares the offset returned by the scanner to its + own offset data member. + + If the two offset values differ the source file's line that begins at + the code's offset data member is read, so this line + can be shown together with a column indicator and a message describing + the condition for each of the lements of the condition + vector. Following this, the condition vector is erased, and the + scanner provided offset is assigned to the code's own offset data + member. + + If the two offset values are equal the scanner's + tt(column) value and the nature of the condition are added to a + `condition vector'. + + This approach has the advantage of being relatively simple. A + disadvantage could be that it can only be used for seekable media, or + that the overhead of seeking and reading lines of the file that is + processed by flc() is considered impractical. + + The implementation of this approach is left as an exercise to the + reader. + + it() The scanner could read lines one at a time, followed by rereading the + line so that it can be broken down into tokens by the scanner. This + approach is discussed and implemented in the next section. + + it() Streams offering the contents and last-read column positions of the + currently scanned line could be passed to the scanner. This approach + is discussed and implemented in the final section of this chapter. + ) diff -Nru flexc++-1.07.00/documentation/manual/input/miniscanners.yo flexc++-1.08.00/documentation/manual/input/miniscanners.yo --- flexc++-1.07.00/documentation/manual/input/miniscanners.yo 1970-01-01 00:00:00.000000000 +0000 +++ flexc++-1.08.00/documentation/manual/input/miniscanners.yo 2013-12-21 16:23:31.000000000 +0000 @@ -0,0 +1,81 @@ +Since the scanner has full control over what happens before and after +determining the next token, the lexical scanner's rules can be designed so +that it always first reads a line, and then re-reads that line in another +mini-scanner. The tt(Scanner) object keeps the last-read line, a column +indicator, and a reset flag, which is initially set to tt(true) and also after +reading a newline. If the reset flag is true, the column indicator is set to +0, otherwise it is updated to the length of the currently matched text. Here +is the initial section of the class tt(Scanner), showing the new data members: + verb( + class Scanner: public ScannerBase + { + std::string d_storedLine; + size_t d_column = 0; + bool d_reset = true; + + public: + ... + }; + ) + +Of course, the lexer won't return for all matched text, but once a rule has +been matched the tt(posCode) member is called, so this function can update the +column and reset indicators: + + verb( + void Scanner::postCode(PostEnum__ type) + { + if (not d_reset) + d_column += length(); + else + { + d_reset = false; + d_column = 0; + } + } + ) + +The scanner's default rule (the tt(StartCondition__::INITIAL) scanner simply +reads the initial line, and then pushes the line back onto the scanner's +queue. A simple tt(.*) will ensure that all the line's characters are +read. Having matched a line it must still be broken down into tokens, for +which the tt(%x main) mini-scanner is used. The default (tt(INITIAL)) +scanner's rule looks like this: + + verb( + .* { + d_storedLine = matched(); + push(d_storedLine); + begin(StartCondition__::main); + d_reset = true; + } + ) + +Now that the line has been stored, it's time to obtain its tokens, which is +the responsibility of the tt(StartCondition__::main) mini scanner: + + verb( +
{ + [ \t]+ // skip white space chars. + [0-9]+ return NUMBER; + [[:alpha:]_][[:alpha:][:digit:]_]* return IDENTIFIER; + [][] return SIGNAL; + . return matched()[0]; + \n begin(StartCondition__::INITIAL); + } + ) + +Identifiers and numbers are returned as tokens, square brackets are returned +as tt(SIGNAL) tokens, indicating that we would like to see the lines and +columns in which they were found, white space characters are ignored, and +all other characters are returned as-is. + +Once a token is returned, tt(d_column) is updated to indicate the column +number of the last-matched character. To obtain the matched text's +initial column number, subtract tt(length() - 1). + +Here is a simple tt(main) function, reading its tt(cin) stream, and showing +lines, column indicators, line numbers, and column numbers of detected square +brackets: + + verbinclude(scanner/minimain.cc) diff -Nru flexc++-1.07.00/documentation/manual/input/scanner/lexer flexc++-1.08.00/documentation/manual/input/scanner/lexer --- flexc++-1.07.00/documentation/manual/input/scanner/lexer 1970-01-01 00:00:00.000000000 +0000 +++ flexc++-1.08.00/documentation/manual/input/scanner/lexer 2013-12-21 16:21:44.000000000 +0000 @@ -0,0 +1,13 @@ +%filenames scanner + +%% + +[ \t\n]+ // skip white space chars. +[0-9]+ return NUMBER; +[[:alpha:]_][[:alpha:][:digit:]_]* return IDENTIFIER; +[][] return SIGNAL; +. return matched()[0]; + + + + diff -Nru flexc++-1.07.00/documentation/manual/input/scanner/main.cc flexc++-1.08.00/documentation/manual/input/scanner/main.cc --- flexc++-1.07.00/documentation/manual/input/scanner/main.cc 1970-01-01 00:00:00.000000000 +0000 +++ flexc++-1.08.00/documentation/manual/input/scanner/main.cc 2013-12-21 16:21:44.000000000 +0000 @@ -0,0 +1,41 @@ +int main() +{ + ScannerStreambuf buf(cin); + istream in(&buf); + + string line; + + Scanner scanner(in); // define a Scanner object + + while (int token = scanner.lex()) // get all tokens + { + string const &text = scanner.matched(); + switch (token) + { + case IDENTIFIER: + cout << "identifier: " << text << '\n'; + break; + + case NUMBER: + cout << "number: " << text << '\n'; + break; + + case SIGNAL: + { + cout << + '\n' << + scanner.line() << + setw(scanner.column()) << '^' << "\n" + "Line " << scanner.lineNr() << ", column " << + scanner.column() << + ": saw `" << scanner.matched() << "'\n\n"; + } + break; + + default: + cout << "char. token: `" << text << "'\n"; + break; + } + } +} + diff -Nru flexc++-1.07.00/documentation/manual/input/scanner/minimain.cc flexc++-1.08.00/documentation/manual/input/scanner/minimain.cc --- flexc++-1.07.00/documentation/manual/input/scanner/minimain.cc 1970-01-01 00:00:00.000000000 +0000 +++ flexc++-1.08.00/documentation/manual/input/scanner/minimain.cc 2013-12-21 16:21:44.000000000 +0000 @@ -0,0 +1,42 @@ +#include +#include +#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 IDENTIFIER: + cout << "identifier: " << text << '\n'; + break; + + case NUMBER: + cout << "number: " << text << '\n'; + break; + + case SIGNAL: + { + cout << + '\n' << + scanner.line() << '\n' << + setw(scanner.column()) << '^' << "\n" + "Line " << scanner.lineNr() << ", column " << + scanner.column() << + ": saw `" << scanner.matched() << "'\n\n"; + } + break; + + default: + cout << "char. token: `" << text << "'\n"; + break; + } + } +} + diff -Nru flexc++-1.07.00/documentation/manual/input/scannerstreambuf.yo flexc++-1.08.00/documentation/manual/input/scannerstreambuf.yo --- flexc++-1.07.00/documentation/manual/input/scannerstreambuf.yo 1970-01-01 00:00:00.000000000 +0000 +++ flexc++-1.08.00/documentation/manual/input/scannerstreambuf.yo 2013-12-21 16:21:44.000000000 +0000 @@ -0,0 +1,64 @@ +The class tt(ScannerStreambuf) uses two data members (tt(d_line) and +tt(d_column)) to store, respectively, the line that's currently being scanned +and the column to where the scanning process has proceeded. In addition it +needs access to the actual input stream (in this example only one stream is +used, so a tt(std::istream &d_in) can be used; if stream-switching should be +supported then use a tt(std::istream *d_inPtr)), and it uses a one-character +buffer (there's no real need to use a bigger buffer, as the input stream may +already define its own buffer, and the scanner merely reads its input one +character at the time anyway (through tt(Input::get)). + +tt(ScannerStreambuf) only needs a very basic interface: + verb( + class ScannerStreambuf: public std::streambuf + { + std::istream &d_in; + std::string d_line; + size_t d_column = 0; + char d_ch; + + public: + ScannerStreambuf(std::istream &in); + + std::string const &line() const; + size_t column() const; + + private: + int underflow() override; + }; + ) + The members tt(line) and tt(column) are simple accessors, returning, +respectively tt(d_line) and tt(d_column). The constructor initializes tt(d_in) +and installs an empty buffer: + verb( + ScannerStreambuf::ScannerStreambuf(istream &in) + : + d_in(in) + { + setg(0, 0, 0); + } + ) + + The member tt(underflow) isn't complicated either: if all characters in +tt(d_line) have been processed (which is initially true) the next line is read +into tt(d_line), adding a newline character to tt(d_line). + + Then the next character in tt(d_line) is assigned to tt(d_ch), and the +input buffer is defined to point at tt(d_ch). Here is its implementation: + verb( + int ScannerStreambuf::underflow() + { + if (d_column == d_line.length()) + { + if (!getline(d_in, d_line)) + return EOF; + + d_column = 0; + d_line += '\n'; + } + d_ch = d_line[d_column++]; + setg(&d_ch, &d_ch, &d_ch + 1); + return *gptr(); + } + ) + diff -Nru flexc++-1.07.00/documentation/manual/input/wrapping.yo flexc++-1.08.00/documentation/manual/input/wrapping.yo --- flexc++-1.07.00/documentation/manual/input/wrapping.yo 1970-01-01 00:00:00.000000000 +0000 +++ flexc++-1.08.00/documentation/manual/input/wrapping.yo 2013-12-21 16:27:30.000000000 +0000 @@ -0,0 +1,62 @@ +Streams offering the contents and last-read column positions of the +currently scanned line could be passed to the scanner. The streams that are +processed by the scanner become em(wrapper streams) around the streams that +are actually processed by the scanner. + +This approach uses multiple inheritance to add tt(std::streambuf) and +tt(std::istream) facilities to the tt(class Scanner). However, these +facilities are for internal use only: they are merely used for wrapping the +tt(std::istream) that is actually passed to the scanner. + +Once the set of files have been generated from the rules file (e.g., +tt(lexer)) the file tt(Scanner.h) is available, and this file will be slightly +modified: we'll use triple inheritance for the tt(class Scanner): + + verb( +class Scanner: private ScannerStreambuf, private std::istream, + public ScannerBase + ) + +Only for the tt(ScannerBase) public inheritance is used: the initial two +classes are used to implement tt(Scanner) in terms of these classes. The class +tt(IStreambuf) is doing all the magic and is discussed below. The +tt(std::istream) base class receives tt(ScannerStreambuf)'s address, turning +tt(Scanner) objects into tt(std::istream) objects, but only so for the benefit +of the tt(Scanner) object itself. tt(ScannerBase), of course, is left +untouched. + +The class tt(ScannerStreambuf) maintains and offers the contents of the +currently scanned line and column numbers of returned characters. The +tt(Scanner)'s interface shares its members tt(line) and tt(column) to make +this information available to any class that may access the tt(Scanner) +object. To accomplish this the following declarations are added tt(Scanner)'s +public interface: + verb( + using ScannerStreambuf::line; + using ScannerStreambuf::column; + ) + +The member tt(explicit Scanner(std::istream &in = std::cin, std::ostream &out += std::cout)) now must make sure the tt(ScannerStreambuf) and tt(std::istream) +are properly initialized before the tt(ScannerBase) can be initialized. +the tt(ScannerStreambuf) is a wrapper around the actual tt(std::istream), and +it receives the initial stream from the constructor's arguments. This +completes the tt(ScannerStreambuf) construction, making tt(std::istream's +std::streambuffer) available. The interesting part comes next: now that the +tt(Scanner) is an tt(std::istream) it can simply be passed to tt(ScannerBase) +as the input file to be processed (cf. figure ref(inputwrapping)). + + figure(images/inputwrapping)(Scanner: triple inheritance)(inputwrapping) + +The code implementing this organization looks like this: + + verb( + Scanner::Scanner(std::istream &in, std::ostream &out) + : + ScannerStreambuf(cin), + istream(this), + ScannerBase(*this, cout) + {} + ) + + diff -Nru flexc++-1.07.00/documentation/manual/lexer/members.yo flexc++-1.08.00/documentation/manual/lexer/members.yo --- flexc++-1.07.00/documentation/manual/lexer/members.yo 2013-06-20 14:23:47.000000000 +0000 +++ flexc++-1.08.00/documentation/manual/lexer/members.yo 2013-12-21 16:23:03.000000000 +0000 @@ -1,3 +1,5 @@ +NOUSERMACRO(postCode) + The tt(Scanner) class offers the following members, which can be called from within actions (or by members called from those actions): @@ -74,6 +76,25 @@ } // while } ) + itb(void postCode(PostEnum__ type)) + By default this function has an empty, inline implementation in +tt(Scanner.h). It can safely be replaced by a user-defined +implementation. This function is called by tt(lex__), just after a rule has +been matched, where tt(PostEnum__)'s value indicates the characteristic of the +matched rule. tt(PostEnum__) has four values: + itemization( + itb(PostEnum__::END): the function tt(lex__) immediately returns 0 + once tt(postCode) returns, indicating the end of the input was + reached; + itb(PostEnum__::POP): the end of an input stream was reached, and + processing continues with the previously pushed input stream. In + this case the function tt(lex__) doesn't return, it simply + coontinues processing the previously pushed stream; + itb(PostEnum__::RETURN): the function tt(lex__) immediately returns + once tt(postCode) returns, returning the next token; + itb(PostEnum__::WIP): the function tt(lex__) has matched a + non-returning rule, and continues its rule-matching process. + ) itb(void push(size_t ch)) character tt(ch) is pushed back onto the input stream. I.e., it will be the character that is retrieved at the next attempt to obtain a diff -Nru flexc++-1.07.00/icmake/clean flexc++-1.08.00/icmake/clean --- flexc++-1.07.00/icmake/clean 2013-08-05 10:33:45.000000000 +0000 +++ flexc++-1.08.00/icmake/clean 2013-12-28 16:34:47.000000000 +0000 @@ -18,6 +18,7 @@ run("rm -rf " "man/*.1 " "man/*.3* " + "man/*.7* " "man/*.html " "manual/manual-stamp " "manual/*.html " diff -Nru flexc++-1.07.00/icmake/install flexc++-1.08.00/icmake/install --- flexc++-1.07.00/icmake/install 2013-06-20 12:39:17.000000000 +0000 +++ flexc++-1.08.00/icmake/install 2013-12-28 16:57:27.000000000 +0000 @@ -38,9 +38,19 @@ if (what == "man") { where = setWhere(where, MAN); + printf(" INSTALLING the manual pages below `", where, "'\n"); - printf(" INSTALLING the manual page at `", where, "'\n"); - run("gzip -9 < tmp/man/" PROGRAM ".1 > " + where + "/" PROGRAM ".1.gz"); + md(where + "/man1"); + run("gzip -9 -n < tmp/man/" PROGRAM ".1 > " + where + + "/man1/" PROGRAM ".1.gz"); + + md(where + "/man3"); + run("gzip -9 -n < tmp/man/" PROGRAM "api.3 > " + where + + "/man3/" PROGRAM "api.3.gz"); + + md(where + "/man7"); + run("gzip -9 -n < tmp/man/" PROGRAM "input.7 > " + where + + "/man7/" PROGRAM "input.7.gz"); exit(0); } @@ -58,10 +68,12 @@ where = setWhere(where, STD); printf(" INSTALLING the changelog at `", where, "\n"); - run("gzip -9 < changelog > " + where + "/changelog.gz"); + run("gzip -9 -n < changelog > " + where + "/changelog.gz"); - printf(" INSTALLING the html-manual page at `", where, "\n"); - run("cp tmp/manhtml/" PROGRAM "man.html " + where); + printf(" INSTALLING the html-manual pages at `", where, "\n"); + run("cp tmp/manhtml/" PROGRAM ".1.html " + where); + run("cp tmp/manhtml/" PROGRAM "api.3.html " + where); + run("cp tmp/manhtml/" PROGRAM "input.7.html " + where); exit(0); } diff -Nru flexc++-1.07.00/icmake/manpage flexc++-1.08.00/icmake/manpage --- flexc++-1.07.00/icmake/manpage 2013-08-05 19:36:57.000000000 +0000 +++ flexc++-1.08.00/icmake/manpage 2013-12-28 16:11:08.000000000 +0000 @@ -1,4 +1,14 @@ -#define MANPAGE "../../tmp/man/" ${PROGRAM} ".1" + +void _manpage(string dest, string manpage, string source) +{ + + if (source younger dest + manpage || "release.yo" younger dest + manpage) + { + run("yodl2man -o " + dest + manpage + " " + source); + run("yodl2html " + "-o ../../tmp/manhtml/" + manpage + ".html " + source); + } +} void manpage() { @@ -6,11 +16,10 @@ chdir("documentation/man"); - if (PROGRAM ".yo" younger MANPAGE || "release.yo" younger MANPAGE) - { - run("yodl2man -o " MANPAGE " " PROGRAM); - run("yodl2html " - "-o ../../tmp/manhtml/" PROGRAM "man.html " PROGRAM); - } + _manpage("../../tmp/man/", PROGRAM ".1", PROGRAM ".yo"); + _manpage("../../tmp/man/", PROGRAM "api.3", PROGRAM "api.yo"); + _manpage("../../tmp/man/", PROGRAM "input.7", PROGRAM "input.yo"); + + exit(0); } diff -Nru flexc++-1.07.00/skeletons/flexc++.cc flexc++-1.08.00/skeletons/flexc++.cc --- flexc++-1.07.00/skeletons/flexc++.cc 2013-06-20 14:16:39.000000000 +0000 +++ flexc++-1.08.00/skeletons/flexc++.cc 2013-12-06 20:24:33.000000000 +0000 @@ -379,6 +379,7 @@ if (return__()) { print(); + postCode(PostEnum__::RETURN); return d_token__; } break; @@ -395,10 +396,16 @@ case ActionType__::RETURN: $insert 16 debug "EOF_REACHED" if (!popStream()) - return 0; - continue; + { + postCode(PostEnum__::END); + return 0; + } + postCode(PostEnum__::POP); + continue; } // switch + postCode(PostEnum__::WIP); + reset__(); preCode(); } // while diff -Nru flexc++-1.07.00/skeletons/flexc++.h flexc++-1.08.00/skeletons/flexc++.h --- flexc++-1.07.00/skeletons/flexc++.h 2013-08-05 10:35:52.000000000 +0000 +++ flexc++-1.08.00/skeletons/flexc++.h 2013-12-03 10:47:50.000000000 +0000 @@ -16,6 +16,10 @@ void print(); void preCode(); // re-implement this function for code that must // be exec'ed before the patternmatching starts + + void postCode(PostEnum__ type); + // re-implement this function for code that must + // be exec'ed after the rules's actions. }; $insert scannerConstructors @@ -27,6 +31,11 @@ // optionally replace by your own code } +inline void \@::postCode(PostEnum__ type) +{ + // optionally replace by your own code +} + inline void \@::print() { print__(); diff -Nru flexc++-1.07.00/skeletons/flexc++base.h flexc++-1.08.00/skeletons/flexc++base.h --- flexc++-1.07.00/skeletons/flexc++base.h 2013-08-05 10:35:52.000000000 +0000 +++ flexc++-1.08.00/skeletons/flexc++base.h 2013-12-06 20:24:14.000000000 +0000 @@ -50,6 +50,15 @@ RETURN, // no further continuation, lex returns 0. }; + enum class PostEnum__ + { + END, // postCode called when lex__() ends + POP, // postCode called after switching files + RETURN, // postCode called when lex__() returns + WIP // postCode called when a non-returning rule + // was matched + }; + public: enum class StartCondition__ { $insert 8 startCondNames