Although flexc++ tries to be as compatible as possible with flex(1), there are some noteworthy differences. This chapter provides a quick overview for the users already familiar with flex.
Flexc++ does not support code blocks. Since flexc++ generates a class with
appropriate header files, initialization code can be activated bij flexc++'s
constructor, code to be executed when lex
is called can be placed in the
member lex
's body, just before calling lex_
, and Scanner::preCode
can be provided with any required pre-match code. See also generated
files 2.3 below.
Flexc++ also does not support a trailing `user code' section, where additional
code can be placed to be copied verbatim to the source file. Again, the
Scanner
class approach offers preferable means for adding user code to the
scanner.
Sections 2.1.1, 2.1.2 and 2.1.3 cover items which are no longer supported in flexc++, offering alternatives.
%top
block, copies code to top of yylex.cc.
- Purpose: Define macros or include files.
- Flexc++'s alternative: Include header files in Scanner.ih.
`%{ ... %}'
blocks copied verbatim to
yylex.cc
- Purpose: Can be used for helper code
- Flexc++'s alternative: Use member functions and/or data members of the
Scanner
class.
`/* ... */'
) is copied to yylex.cc
- Purpose: Commenting helper code.
- Flexc++'s alternative: Comment outside of actions is ignored, and is considered part of flexc++'s input file.
`%{ ... %}'
blocks before first rule copied
to the top of the function body of yylex.cc
- Purpose: Declare local variables for yylex().
- Flexc++'s alternative: Use data members to keep track of state, or if you want to execute some code everytime lex() is called, redefine lex() to do more than just call the generated function lex_().
`%{ ... %}'
blocks are copied
to the output, but meaning is ill-defined and compiler errors may
result.
- Purpose: POSIX compliance
- Flexc++'s alternative: A user code section is superfluous. User code should be provided as member functions.
- Purpose: defining companion routines
- Flexc++'s alternative: define member functions in scanner class
Another minor difference is that named patterns, defined in the definion section, cannot be used if they contain the lookahead operator (`/'). This is the result of the way name expansions are handled by flexc++. Flexc++ handles name expansions as a parenthesized regular expression (a group). Since groups may occur any number of times in a regular expression but a lookahead operator only once, the look-ahead operator is not accepted in a named pattern.
lex.yy.cc
, flexc++ generates several
files: several header files and a source file. By default flexc++ generates a
class header file (Scanner.h
), and internal header file (Scanner.ih
),
a base class header file (Scannerbase.h
), and the file lex.cc
containing the implementation of the required members of the class
Scanner
. Scannerbase.h
and lex.cc
should not be edited: they are
overwritten whenever flexc++ is invoked. The other files (Scanner.h
and
Scanner.ih
) are generated only once, and can thereafter be modified by the
user (e.g., to add members to the Scanner
class).
flex
. Cf. section 3.3 for
details.
yy
-prefix is no longer needed. In
addition, as flexc++ generates a scanner class, member functions rather than
macros can (should) be used. See the conversion table below.
flex | flexc++ | flexc++ alternative |
yylex() |
lex() |
|
YYText() |
matched() |
|
YYLeng() |
length() |
|
ECHO |
echo() |
|
yymore() |
more() |
|
yyless() |
redo() |
accept() |
BEGIN startcondition |
begin(StartCondition_::startcondition) |
|
YY_AT_BOL |
n.a. | |
yy_set_bol(at_bol) |
n.a. |
The member functions in the flexc++ column above are either members of
Scanner
or of its base class. Flexc++ does not use macros. All member
functions can be used from within actions or by other member functions.