In order to develop a fully functional C++ program, it is sometimes desirable to expand Flavor-defined classes with additional functionality. This can be easily done by deriving new classes from the ones defined in the Flavor source code. When only trivial modifications are needed, however, this may require more effort that necessary.
More importantly, it is sometimes desirable to intervene to the code generated by the
translator. A trivial example is to ensure that member variables are declared private
or protected, rather than the default of public used by the
translator. Other examples include constructors and destructors, in-line methods, etc.
More sophisticated cases involve intervention to the get() or put()
code produced by the translator.
In order to facilitate the highest possible level of integration between Flavor and the base language (C++ or Java), the translator supports verbatim code segments. In other words, segments that contain user code which will be ignored by the Flavor translator, but copied verbatim to the output file.
There are four different types of verbatim code segments, reflecting the different
program areas where such code should be copied: class declaration or global scope, put()
method, get() method, or both put() and get()
methods. Regardless of the type, verbatim code can appear wherever a regular Flavor
statement or declaration can appear. Also, it is copied to the output file at the exact
position where it appears.
In the following, in addition to describing the various types of verbatim code and its use, we also describe how to facilitate compilation and debugging of such code.
Declarative verbatim code is introduced with the delimiter %{ and ends
with the delimiter %}. Here are a few examples.
|
The declaration of the pointer p in file scope will be placed before the Example
class is declared. Similarly, the private keyword will be inserted before a
is declared. The translator outputs a public directive right at the beginning
of the class; as a result, any other directive inserted will override it. The dosomething()
method will be declared as protected since this is the directive that is
active when its declaration is encountered (it is the directive preceding the declaration
of b).
This verbatim code segment is enclosed in the delimiters %g{ and %g}.
All text contained between these two will be output at the exact same place in the put()
method only. Let's see an example.
|
Here the printf() statement will be inserted in the put()
method after the code for outputting a, but before the code for outputting b.
This allows the programmer very fine control, even inside the put()
method. For example, you could place at the top of the definition of a Flavor class a call
to a function that will transform its data and prepare them for output. This way, a single
call to the put() method will perform both perform the transformation
(encoding) and output the resulting bits (create the bitstream representation).
Similarly to the previous case, this verbatim code segment is enclosed in the
delimiters %p{ and %p}. All text contained between these two
will be output at the exact same place in the get() method only. Using our
previous example:
|
The printf() statement will be inserted in the get() method
after the code for outputting a (including any required code for tracing, if
requested), but before the code for outputting b.
For cases where the same code should be inserted in both the get() and the
put() method, the delimiters %*{ and %*} can be
used.
When verbatim code is used, the translator generates C++ preprocessor statements to indicate its position in the Flavor source code. This helps development environments that automatically position the programmer's editor to the source position where the error was detected. This information is also used by source code debuggers to position their source window to the right file and line.
In the case where you want compiler error messages to refer to the flavorc-generated
C++ file, or your debugger to use the flavorc-generated C++ file, you can
switch output of such line information off using the -l command
line option or the line pragma directive.