lzz options filenames
Options begin with a dash (-); other arguments
are processed as filenames. Options can also be specified with
the environment variable LZZ_OPTIONS.
The options are:
The method the parser uses to recover from syntax errors is configured at runtime. The recover commands are specified with the
-i- Output inline function definitions to an inline file. The functions in this file will be inline if the macro
LZZ_ENABLE_INLINEis defined when you run your compiler.-t- Output function template definitions and class template static member object definitions to a template file. Use this option if you prefer to explicitly instantiate your templates.
-n- Output inline function template definitions to a template inline file. The functions in this file will be inline if the macro
LZZ_ENABLE_INLINEis defined when you run your compiler.-hx ext- Set the header file extension. The default is
h.-sx ext- Set the source file extension. The default is
cpp.-ix ext- Set the inline file extension. The default is
inl.-tx ext- Set the template file extension. The default is
tpl.-nx ext- Set the template inline file extension. The default is
tnl.-hl- Generate
#linedirectives in the header file.-sl- Generate
#linedirectives in the source file.-il- Generate
#linedirectives in the inline file.-tl- Generate
#linedirectives in the template file.-nl- Generate
#linedirectives in the template inline file.-hd- Write the header file only if it is different than the previous file.
-sd- Write the source file only if it is different than the previous file.
-id- Write the inline file only if it is different than the previous file.
-td- Write the template file only if it is different than the previous file.
-nd- Write the template inline file only if it is different than the previous file.
-c- Create the source file if the header file is created. Use this option if you want to make sure you header file is always self-contained.
-e- Preprocess all code. Normally code that is captured is not preprocessed, such as function bodies and template arguments. The code is copied verbatim to the appropriate output file. This option will preprocess this code, allowing the end delimiter to appear inside a macro. For example:
When preprocessing captured code the preprocessor behaves as a standard preprocessor.#define BEGIN void func () { #define END } BEGIN // stuff ... END#hdrand#enddirectives, for example, are not allowed, and the#includedirective has its standard meaning. The pragmapreprocess_blockallows you to explicitly set this option on or off within a file.-o- Set the output directory for created files. If this directory is different than the directory containing the input file you will likely also want to use the
-xoption.-x- Use absolute filenames in
#linedirectives.-d- Delete old files no longer created.
-I directory- Search directory for
#includeand#insertfiles. This option must be repeated to specify several directories. The directories are searched in the same order as the -I options are processed.
-D macro- Define a function or an object macro. Replacement text must follow the equals sign (
=). If the equals sign is not present then the macro is defined to1. Examples:-DSTR(X)=#X -D NULL_MACRO= -DDEBUG.
-a filename- Automatically
#includea file before the input file is opened. The files are included in the same order as the -a options are processed.
-p- Preprocess to standard output. Function bodies, expressions and template arguments are not preprocessed, unless the code originates from a macro; this code is represented as a
BLOCKtoken. No files are generated and no files are deleted.-P- Preprocess to standard output. All code in the file is preprocessed. No files are generated and no files are deleted.
-E- Preprocess to standard output. All code in the file, and all code in
#includefiles, is preprocessed. No files are generated and no files are deleted.-r commands- Set the syntax error recover commands. See below for the syntax of the commands. The commands can also be specified in the environment variable
LZZ_SYNTAX_RECOVER_COMMANDS; this environment variable is processed first.-v- Print the values of the above options.
-hr- Print the help text for the
-roption.-T- Print the token names usable in the
-roption.-ver- Print the version number.
-h-help- Print the usage and a brief description of the options.
-r option. The commands must be comma delimited. The
recover commands are:
Where
i:token- Insert a specific token.
i:[token,token,...]- Insert a specific sequence of tokens.
d- Delete one token.
d:max_num- Delete at most
max_numtokens.d:token- Delete a specific token.
r:token- Replace one token with a specific token.
r:token:max_num- Replace at most
max_numtokens with a specific token.r:token:token- Replace a specific token (the second) with a specific token (the first).
r:[token,token,...]- Replace one token with a specific sequence of tokens.
r:[token,token,...]:max_num- Replace at most
max_numtokens with a specific sequence of tokens.r:[token,token,...]:token- Replace a specific token with a specific sequence of tokens.
m- Move one token after one token to the right (swap token with next token).
m:max_move- Move one token after at most
max_movetokens to the right.m:max_move:max_num- Move at most
max_numtokens after at mostmax_movetokens to the right.
token is a token name. The
-T option prints the token names and their lexemes.
Token names are not case sensitive.
Lzz has a built-in, fully compatible, C++ preprocessor. However, during normal use:
-e option to preprocess all code. See above.)
#include files are processed.
C++ code is discarded. If you wish to include everything from
another file use #insert.
In earlier versions, a dollar sign ($) was used to
denote a directive. Lzz still accepts this use but may not in
the future.
Lzz recognizes the following directives:
#include- The argument, after macro substitution, must be a filename of the form
"filename"or<filename>. Only preprocessor directives in the named file are processed. If you always include the same file consider using the-aoption to automatically include the file.
#insert- Like
#includeexcept (Lzz) code is also processed.
#define#if#ifdef#ifndef#elif#else#endif#line#error- Same semantics as a standard C++ preprocessor.
#warning- The remaining characters on the line are printed to standard output.
#pragma- Lzz arguments optionally begin with
lzz. If this word is present then Lzz will issue a warning if the pragma is not recognized. The following arguments are recognized:
inl [on | off] [ext]- If on then create an inline file with optional file extension. This pragma should precede any
#inldirectives.
tpl [on | off] [ext]- If on then create an template file with optional file extension. This pragma should precede any
#tpldirectives.
tnl [on | off] [ext]- If on then create an template inline file with optional file extension. This pragma should precede any
#tnldirectives.
once- The enclosing file is not included again.
preprocess_block [on | off]- Preprocess all code. See the
-eoption above. If an argument is not givenonis assumed.
#hdr...#end- The delimited lines are copied verbatim to the header file.
#src...#end- The delimited lines are copied verbatim to the source file.
#inl...#end- The delimited lines are copied verbatim to the inline file, or to the header file if an inline file is not being created.
#tpl...#end- The delimited lines are copied verbatim to the template file, or to the header file if a template file is not being created.
#tnl...#end- The delimited lines are copied verbatim to the template inline file, or to the header file if a template inline file is not being created.
Restrictions:
All , characters must be enclosed in parenthesis.
Example:
enum { int I = (Q <int,char>::I), J }
Restrictions:
All , characters must be enclosed in parenthesis.
Example:
void f (int (* g) () = (h <int, int>)) { }
Restrictions:
AllExample:<and>characters not delimiting nested template arguments must be enclosed in parenthesis.
A <B <C>, (X < Y)>::D d;
Restrictions:
AllExample:,,<and>characters must be enclosed in parenthesis.
template <int (* g) () = (h <int, int>)> class A { }
Example:
int f (int (i), int (* g) (int j)) { }
f is a function taking two arguments: an int, and a
pointer to a function taking an int and returning an int.
Example:
A ()
try
: i (0)
{ }
catch (T t)
{ }
Example:
template <class T, int I, template <class R> class S>
class A
{ }
_dinit must precede the direct initializer.
Example:
A a1 ((X * Y), Z); A a2 _dinit (X * Y, Z);
Lzz recognizes all names, qualified and unqualified, with and without template arguments, including constructors, destructors, and operator and conversion function names.
Example:
template <class T>
class A
{
A () { }
~ A <T> () { }
(A) (A const & a);
B <int, R::S>::C c;
typename T::R const & operator + () const { }
operator class Z * () const { }
operator Z * () const { }
friend B::~ B ();
friend D::operator int * const () const;
friend B (::operator +) (B & b1, B & b2);
template <>
friend typename T::template S <int> T::template h <int> ();
}
Lzz recognizes the following C++ constructs:
- namespace definition
An unnamed namespace and all enclosed declarations are output to the source file. This rule overrides all others.
The name of a named namespace may be qualified.
is equivalent to:namespace A::B { typedef int I; }namespace A { namespace B { typedef int I; } }
- typedef
Typedefs are output to the header file.
- linkage specification
A linkage specification of the form
does not affect where the enclosed declarations are output; in this respect it is similar to a named namespace. A linkage specification of the formextern string-literal { declaration-seq }is treated as anextern string-literal declarationexternspecifier for the purpose of determining whether the contained declaration is a definition.
- using directive
- using declaration
Using directives and using declarations are output to the source file.
- object declaration
Object declarations are output to the header file. Note: an object declaration has either an
externspecifier or a linkage specification and does not have an initializer (otherwise it would be a definition).
- object definition
An object definition is output to the source file, and, if it is neither static, explicitly const, nor qualified, its declaration is output to the header file.
- enumeration
Enumerations are output to the header file.
- function declaration
- function template declaration
If a function declaration or a function template declaration is static, it is output to the source file; otherwise, it is output to the header file.
- function definition
If a function definition is static, it is output to the source file; otherwise, if the definition is inline:
If the definition is neither static nor inline, it is output to the source file, and, if not qualified, its declaration is output to the header file.
- if the option
-iis specified, it is output to the inline file, and, if not qualified, its declaration is output to the header file; otherwise,
- it is output to the header file.
- function template explicit specialization
If function template explicit specialization is static, it is output to the source file; otherwise, if the definition is inline:
If the definition is neither static nor inline, it is output to the source file, and its declaration is output to the header file.
- if the option
-iis specified, it is output to the inline file, and its declaration is output to the header file; otherwise,
- it is output to the header file.
- function template definition
If a function template definition is static, it is output to the source file; otherwise, if the definition is inline:
If the definition is neither static nor inline:
- if the option
-nis specified, it is output to the template inline file, and, if not qualified, its declaration is output to the header file; otherwise,
- it is output to the header file.
- if the option
-tis specified, it is output to the template file, and, if not qualified, its declaration is output to the header file; otherwise,
- it is output to the header file.
- class declaration
- class template declaration
Class declarations and class template declarations are output to the header file.
- class definition
- class template explicit specialization
Class definitions and class template explicit specializations are output to the header file. Member definitions are output accordingly:
- Static objects are defined in the source file.
- Function definitions, if inline:
- if the option
-iis specified, they are defined to the inline file; otherwise,- they are defined in the header file.
If not inline, they are defined in the source file.
- Function template definitions, if inline:
- if the option
-nis specified, they are defined to the template inline file; otherwise,- they are defined in the header file.
If not inline:
- if the option
-tis specified, they are defined to the template file; otherwise,- they are defined in the header file.
- Friend function definitions and friend function template definitions are defined inside the class definition.
A declarator cannot follow a class definition. That is, the following constructs are not supported:
typedef struct _A { int i; } A; struct B { int i; } b;A semi-colon thus is not necessary after the definition.
- class template definition
- class template partial specialization
Class template definitions and class template partial specializations are output to the header file. Member definitions are output accordingly:
- Static objects, if the option
-tis specified, are defined in the template file; otherwise, they are defined in the header file.- Function definitions and function template definitions, if inline:
- if the option
-nis specified, they are defined to the template inline file; otherwise,- they are defined in the header file.
If not inline, they are defined in the header file.
- Friend function definitions and friend function template definitions are defined inside the class definition.
- explicit template instantiation
Explicit template instantiations are output to the source file.
A lazy class is a shorthand notation for a class with a single constructor that only initializes base types and member variables. Here is an example:
class A (int i, int j = 0) : public Base (j)
{
int k = 0;
// ...
}
This is equivalent to the following Lzz code:
class A : public Base
{
int i;
int k;
// ...
public:
inline explicit A (int i, int j = 0)
: Base (j), i (i), k (0)
{
}
~ A ()
{
}
}
A lazy class is distinguished from an ordinary class by a parameter
list following the class name. This is the constructor parameter
list. It is also a list of the initial member objects of the class,
minus those that are passed to a base type. The parenthesized
expression list following a base type are the arguments passed to
the base type in the constructor's member initializer list. For
example, j above is passed to Base so it
does not become a member object of A. The
parenthesized expression list after a base type is optional; if it
is not present then the base type is not initialized in the
constructor's member initializer list.
Member objects declared in a lazy class (like k above)
can be initialized with an assignment or direct initializer. The
initializer becomes the member initializer for that variable.
Lazy classes are particularly useful when writing visitors. For example:
namespace
{
// get class base specifier list
struct GetBaseSpecList (BaseSpecPtrVector & base_spec_list)
: NodeVisitor
{
// base-spec -> obj-name
void visit (BaseSpec1Node & node) const
{
// ...
}
// base-spec -> VIRTUAL access-opt obj-name
void visit (BaseSpec2Node & node) const
{
// ...
}
// base-spec -> access virtual-opt obj-name
void visit (BaseSpec3Node & node) const
{
// ...
}
}
}
namespace gram
{
// get class base specifier list
void getBaseSpecList (basl::Nonterm & nonterm,
BaseSpecPtrVector & base_spec_list)
{
nonterm.accept (GetBaseSpecList (base_spec_list));
}
}
A lazy class can be defined anywhere a class can be defined. It can also be
defined as a template. For example:
template <class T = int>
class A (T * t)
{
// a nested lazy class template
template <template <class T> class S>
class B (S <int> const & s)
{
}
}
void Spud (int i, int j = 0; int k, int l = 0) const
: public Base (j)
{
}
This is equivalent to the following lazy class:
struct Spud (int i, int j = 0) : public Base (j)
{
void operator () (int k, int l = 0) const
{
}
}
A lazy functor is distinguished by the semicolon in the (otherwise)
function parameter list. The parameters before the semicolon are
the parameters to the constructor, and ones after are the parameters
to the operator() function. Any const
volatile specifiers after the parameter list apply to the
operator() function, not the constructor, and similarly
for any throw specification. Function specifiers can be applied to
the operator() function, as well as a function try
block. For example:
inline void Spud (int i, int j = 0; int k, int l = 0) const throw (A)
: public Base (j)
try
{
}
catch (...)
{
}
A functor can also be just declared. For example:
If a lazy functor is virtual, the generated class destructor is also virtual.virtual void Spud (int i, int j = 0; int k, int l = 0) const = 0 : Base (j);
A lazy functor can be declared or defined anywhere a class can be defined. It can also be declared or defined as a template. For example:
template <class T>
void Spud (int i, int j = 0; int k, int l = 0) const : public Base (j)
{
}
class A
{
template <class T>
virtual void Spud (int i, int j = 0; int k, int l = 0) const = 0
: public Base (j);
}