blob: 17ff05daa4b997971e7966d5194459c29bca77a2 [file] [log] [blame]
<!--
<!DOCTYPE DocBook>
< kimwitu++ part II: manual >
-->
<chapter><title>Definition of Phyla</title>
<sect1><title>Basic Definition</title>
<para>A phylum definition consists of two sides. The left-hand side
specifies the phylum name, the right-hand side, behind a colon, a set of
alternative operators, which are separated by bars. An operator is
followed by a matching pair of parentheses, which may enclose a list of
phyla as arguments. A nullary operator has an empty list.
Example <xref linkend="exa:phylumdef"/> presents a basic definition with
operators of different arity.
Before the semicolon closing the definition an attribute block may appear.
The definition of a phylum follows the general form:</para>
<informalexample>
<programlisting role="none">
<![CDATA[ phylum := phylum_name ":" operator { "|" operator } [ attributes ] ";"
operator := operator_name "(" [ phylum_name ] { " " phylum_name } ")"]]>
</programlisting>
</informalexample>
<para>For the names of phyla and operators, the same restrictions hold as
for &cpp; identifiers.
Multiple definitions of of a phylum with the same name are interpreted
as additional alternative branches of the first definition.</para>
<para>There are some simple predefined phyla:
<classname>integer</classname><indexterm significance="preferred"><primary>integer</primary></indexterm>, <classname>real</classname><indexterm significance="preferred"><primary>real</primary></indexterm>,
<classname>casestring</classname><indexterm significance="preferred"><primary>casestring</primary></indexterm>,
and <classname>nocasestring</classname><indexterm significance="preferred"><primary>nocasestring</primary></indexterm>, representing integer values,
real values, case sensitive
strings, and case insensitive strings respectively. Terms of these are not
created by calls of operators but of special generated functions:
<function>mkinteger()</function><indexterm><primary>mkinteger</primary></indexterm>,
<function>mkreal()</function><indexterm><primary>mkreal</primary></indexterm>,
<function>mkcasestring()</function><indexterm><primary>mkcasestring</primary></indexterm> and
<function>mknocasestring()</function><indexterm><primary>mknocasestring</primary></indexterm>.
</para>
<para>The phylum
<classname>abstract_phylum</classname> represents the direct base of all
phyla. Adding properties, like attributes or methods, to it makes them
available for all phyla. Other direct bases may be specified for a phylum
by using the keyword
<constant>%base</constant><indexterm significance="preferred"><primary>%base</primary></indexterm>.
One of them has to be derived from <classname>abstract_phylum</classname>,
not necessarily directly. Example <xref linkend="exa:base"/> makes phylum
<classname>math_expression</classname> to be derived from a phylum
<classname>expression</classname> and a user defined &cpp; class
<classname>counter_class</classname>. </para>
<example id="exa:phylumdef">
<title>Definition of a Phylum</title>
<programlisting>
<![CDATA[expression:
Plus ( expression expression )
| Neg ( expression )
| Null ( ) ;]]>
</programlisting>
</example>
<example id="exa:base">
<title>Changing base of a phylum</title>
<indexterm><primary>%base</primary></indexterm>
<programlisting>
<![CDATA[ %base math_expression : expression, counter_class;
%{ KC_TYPES_HEADER /* code redirection */
class counter_class {
...
};
%}]]>
</programlisting>
</example>
</sect1>
<sect1>
<title>List Phyla<indexterm id="idx:list_man" significance="preferred"
class="startofrange"><primary>list</primary></indexterm></title>
<indexterm><primary>phylum</primary><secondary>list</secondary><see>list</see></indexterm>
<para>A list phylum can be defined by using the basic form of phylum
definitions in a (right-) recursive way. The nullary operator constructs
a list which is empty, and the binary, a list which is concatenated of
a single list element and a list.
The other variant uses the predefined operator <constant>list</constant>
after which is specified the phylum of the list elements. The latter
notation is to prefer because it is concise and causes the generation of
additional list functions. That includes two operators which are named
according to the scheme which is used in the right-recursive definition
(prefixes <constant>Nil</constant> and
<constant>Const</constant>). Other names could be chosen as
well but this may cause some confusion. With either variants, a term is
created by calling one of the two operators.
The two definitions in example <xref linkend="exa:listdef"/> yield the
same list of elements of a phylum <classname>expression</classname>.
</para>
<example id="exa:listdef">
<title>Alternative Definitions of one List</title>
<programlisting>
<![CDATA[ expression_list:
Nilexpression_list ( )
| Consexpression_list ( expression expression_list )
;
expression_list: list expression;]]>
</programlisting>
</example>
<indexterm class="endofrange" startref="idx:list_man"/>
</sect1>
<sect1><title>Attributes of Phyla<indexterm significance="preferred" class="startofrange" id="idx:attributes"><primary>attributes</primary></indexterm></title>
<para>A phylum definition may have an attribute part attached which is
enclosed in braces. It contains declarations of attributes of phylum types
or other &cpp; types and optionally their initial value assignment. After
that arbitrary &cpp; code can follow again enclosed in braces. This is the
general form of the attribute part:</para>
<informalexample>
<programlisting role="none">
<![CDATA[ attributes := "{" {attr_type " " attr_name [ "=" init_value ] ";"} [ cpp_part ] "}"
cpp_part := "{" arbitrary_cpp_code "}"]]>
</programlisting>
</informalexample>
<para>In particular, the initialization of attributes can be done in the
&cpp; part too; though technically then it is not initialization, but
assignment. Attributes may also be defined outside the phylum
definition according to the general form beneath.</para>
<informalexample>
<programlisting role="none">
<![CDATA[ attributes := "%attr " attr_type phylum_name "::" attr_name ";"
members := "%member " attr_type phylum_name "::" attr_name ";"]]>
</programlisting>
</informalexample>
<para>Only attributes of phylum types can be defined with
<constant>%attr</constant><indexterm><primary>%attr</primary></indexterm>.
This is because they are considered part of the enclosing phylum by &kpp;.
When a term is written to a file using the CSGIO functions (see <xref
linkend="sec:csgiofuncs"/>), its
attributes are saved and can thus be restored.</para>
<para>Using the keyword
<constant>%member</constant><indexterm><primary>%member</primary></indexterm>
instead allows also &cpp; types to be used. The values of attributes
defined in this way will get lost when their term is written to a
file. Restoring a saved term will assign the initial values to all
<constant>%member</constant> attributes.</para>
<para>The &cpp; code is executed after the term creation and the attribute
initializations. Inside that code the newly created term can be referred
to as
<varname>$0</varname><indexterm><primary>$0</primary></indexterm>.
Attributes are accessed via the operator
<constant><![CDATA[->]]></constant>. Each predefined phylum has an
attribute which holds its value, which is <varname>value</varname> for
<classname>integer</classname><indexterm><primary>integer</primary></indexterm>
and
<classname>real</classname><indexterm><primary>real</primary></indexterm>,
and <varname>name</varname> for
<classname>casestring</classname><indexterm><primary>casestring</primary></indexterm>
and
<classname>nocasestring</classname><indexterm><primary>nocasestring</primary></indexterm>.
Example <xref linkend="exa:alter"/> shows three alternative ways to define
and initialize one attribute (of &cpp; type). </para>
<example id="exa:alter">
<title>Alternative Definitions of one Attribute</title>
<programlisting>
<![CDATA[ expression: Div ( expression expression )
{ bool is_valid = true; };
expression: Div ( expression expression )
{ bool is_valid;
{ $0 -> is_valid = true; } };
expression: Div ( expression expression );
%member bool expression::is_valid = true;]]>
</programlisting>
</example>
<indexterm class="endofrange" startref="idx:attributes"/>
</sect1>
<sect1><title>Supplemental Definitions</title>
<para>It is possible to supplement the classes which will be generated from
phylum definitions with additional methods. These are defined as usual but
have as qualifier the name of either a phylum or of an operator. Such a
method is known for all terms of the phylum or only for those constructed
by the specified operator. Predefined phyla can get additional methods
too. </para>
<example id="exa:methods">
<title>Additional Methods Definitions</title>
<programlisting>
<![CDATA[ bool aritherm::equals( aritherm a ) {...}
int Number::get_int( ) {...}
nocasestring casestring::convert_to_nocase( ) {...}]]>
</programlisting>
</example>
<para>It may appear desirable to initialize
attributes<indexterm> <primary>attributes</primary></indexterm> of a phylum
with non-default values immediately at term creation. This can be realized
by using the &kpp; keyword <constant>%ctor</constant><indexterm
significance="preferred"><primary>%ctor</primary></indexterm> to define
own constructors which will replace the default ones. Additional
constructors are possible for phyla as well as for operators, but not for
predefined phyla. </para>
<para>
If these constructors are defined to have arguments then of some points
are to take note. First, when used with operators the arguments will be
added to those in the operator definition. Second, since the default
constructors are replaced but relied on by some internal mechanism, the
user has to define new ones or alternatively just provide default values
for all new arguments. The latter may cause performance loss in the case
of many or non-simple arguments.</para>
<para>The keyword <constant>%dtor</constant><indexterm
significance="preferred"><primary>%dtor</primary></indexterm> allows
own destructor definitions for freeing memory of attributes or something
similar. It is applicable to phyla and operators but not to predefined
phyla.</para>
<example id="exa:cdtor">
<title>User provided Constructors and Destructors</title>
<programlisting>
<![CDATA[ %ctor simpleterm( int i ) {...}
%ctor simpleterm( ) {...}
%ctor Minus( bool neg = true ) {...}
// Minus now has 3 arguments, but the third is optional
%dtor virtual term( ) {...}]]>
</programlisting>
</example>
</sect1>
<sect1><title>Phylum Storage Options</title>
<indexterm><primary>storage options</primary><see>storage class</see></indexterm>
<indexterm id="idx:storage" class="startofrange"><primary>storage class</primary></indexterm>
<para>For every phylum a &cpp; class is generated, with one create-method for
every operator. A term is created by calling the appropriate method, which
returns a pointer to the object representing the term. As a default for
every such object a new cell is allocated in memory. But the user may
influence the memory management for optimization purposes. At phylum
definition time the phylum can be declared to use a special storage class.
There is one predefined storage class: <constant>uniq</constant><indexterm
significance="preferred" class="startofrange" id="uniq"><primary>uniq</primary></indexterm>.
It is allowed to specify <constant>!uniq</constant> what is the same as
specifying nothing and results in usage of the default storage.
Subphyla of a phylum with storage class can not use the default storage,
but
must be defined with a storage class too. The completed
general form of a phylum definition is the following one.</para>
<informalexample>
<programlisting role='none'>
<![CDATA[ phylum := phylum_name [ "{" storage_class "}" ] ":" operator
{ "|" operator } [ attributes ] ";"]]>
</programlisting>
</informalexample>
<example id="exa:storage">
<title>Phylum with Storage Class</title>
<programlisting>
<![CDATA[ aritherm {!uniq} : Plus ( aritherm aritherm );
simpleterm {uniq} : Number ( integer );]]>
</programlisting>
</example>
<para>The first phylum in example <xref linkend="exa:storage"/> declares
explicitly to use the default storage. All other phyla defined until now
got that implicitly. Memory of such terms can be freed individually,
terms of the second phylum can not. They are kept under
<constant>uniq</constant> storage. What does this mean?
Each storage class has a <indexterm><primary>hashtables</primary>
</indexterm> hashtable assigned. All terms
of phyla with that class are stored there. If a term is to be created the
create routine does conditionally allocate new storage. It
checks first whether there is already stored an object created with the
same arguments. If found true, the routine will return a pointer to that
object in memory. Such every term is created only once. All predefined
phyla, such as <classname>integer</classname>, are declared
<constant>uniq</constant><indexterm
significance="preferred" class="endofrange" startref="uniq"/>. So the
example has the effect that if two &simpleterm;s are created from the
same <constant>int</constant> value they will both point to the same
memory cell.</para>
<para>It is possible to define additional storage classes, which each get
their own table. Tables also can be explicitly created and assigned to
storage classes, as well as cleared or freed (see <xref
linkend="sec:hashtable"/>).
Example <xref linkend="exa:ownstorage"/> declares two additional storage
classes and defines two phyla using them.
</para>
<example id="exa:ownstorage">
<title>Storage Class Definition and Application</title>
<programlisting>
<![CDATA[ %storageclass table1 table2;
intermediate {table1}: Div ( aritherm aritherm );
final {table2}: Ident ( casestring );]]>
</programlisting>
</example>
<!-- Always move to end of enclosing chapter -->
<para><indexterm class="endofrange" startref="idx:storage"/></para>
</sect1>
</chapter>
<chapter><title>Processing phyla</title>
<sect1>
<title>Pattern Matching<indexterm
significance="preferred"><primary>patterns</primary></indexterm></title>
<para>Patterns make it easier to select terms and subterms and to
distinguish cases. They appear in rules for rewriting and unparsing and in
&with;- and &foreach;-statements. Here there are explained common features
while the slight differences will be mentioned in the appropriate place.
</para>
<para>The term &lsquo;pattern&rsquo; can be defined through induction.
Each of the following is a pattern in the context of &kpp;:
</para>
<orderedlist>
<listitem id="i:patternlit"><para>the literal of a predefined phylum or the
asterisk sign,</para></listitem>
<listitem><para>the phylum operator with zero or more patterns as arguments,</para>
</listitem>
<listitem><para>the assignment of a pattern to a variable, and</para>
</listitem>
<listitem id="i:patternenum"><para>the enumeration of patterns delimited by
commas.</para></listitem>
</orderedlist>
<para>Additionally some restrictions hold regarding the use of patterns. The
patterns of item <xref linkend="i:patternlit"/> are not allowed as the
outermost pattern, while these of item <xref linkend="i:patternenum"/>
are allowed only as the outermost pattern. The assignment of an asterisk
to a variable can be abbreviated by stating only the variable.</para>
<para>If more than one pattern matches a term, the most specific pattern is
chosen. If there is no most specific one, the first of the matches is
chosen. The matched term can be accessed
as <varname>$0</varname><indexterm><primary>$0</primary></indexterm>,
its first subterm<indexterm><primary>subterm</primary></indexterm> as
<varname>$1</varname>, the second as <varname>$2</varname> etc. (not in
rewrite rules). Table <xref linkend="tab:patterns"/> lists pattern
examples, which are in each group equally specific. &kpp; is
not yet able to decide between more
complex patterns (maybe partly overlapping each other) which to be most
specific, but chooses the first found.</para>
<table id="tab:patterns"><title>Pattern groups increasingly specific</title>
<tgroup cols='2' align='left' colsep='1' rowsep='1'>
<?latex-table-type tabularx?>
<?latex-table-option {\textwidth}?>
<?latex-table-head p{0.33\textwidth}X?>
<colspec colname='c1'/>
<colspec colname='c2'/>
<thead>
<row>
<entry>pattern</entry>
<entry>matches</entry>
</row>
</thead>
<tbody>
<row>
<entry><constant>*</constant></entry>
<entry>any term; not allowed as the outermost pattern.</entry>
</row>
<row>
<entry>&mdash;</entry>
<entry>&mdash;</entry>
</row>
<row>
<entry><constant>SimpleTerm</constant></entry>
<entry>term <constant>SimpleTerm</constant> with an unspecified
number of subterms; only allowed as the outermost pattern.</entry>
</row>
<row>
<entry><constant>SimpleTerm(*)</constant></entry>
<entry>term <constant>SimpleTerm</constant> with a subterm.</entry>
</row>
<row>
<entry><constant>a=SimpleTerm(b)</constant></entry>
<entry>term <constant>SimpleTerm</constant> with a subterm; the term
is assigned to a variable <varname>a</varname>, the subterm, to
<varname>b</varname>.</entry>
</row>
<row>
<entry><constant>Number(7)</constant></entry>
<entry>term <constant>Number</constant> with an
<classname>integer</classname> subterm of value the
<literal>7</literal>.</entry>
</row>
<row>
<entry><constant>SimpleTerm(*),Mul(b,b)</constant></entry>
<entry>either term <constant>SimpleTerm</constant> with a subterm or
term <constant>Mul</constant> with two subterms which are
structurally equal (the first of the two is assigned to
<varname>b</varname>).</entry>
</row>
<row>
<entry>&mdash;</entry>
<entry>&mdash;</entry>
</row>
<row>
<entry><constant>SimpleTerm(Number(*))</constant></entry>
<entry>term <constant>SimpleTerm</constant> with a subterm being a
<constant>Number</constant>.</entry>
</row>
<row>
<entry><constant>a=SimpleTerm(Number(b))</constant></entry>
<entry>term <constant>SimpleTerm</constant> with a subterm being a
<constant>Number</constant>; the term is
assigned to <varname>a</varname> and the sub-subterm to
<varname>b</varname>.</entry>
</row>
<row>
<entry>&mdash;</entry>
<entry>&mdash;</entry>
</row>
<row>
<entry><constant><![CDATA[SimpleTerm(Number(b))
provided (b->value!=0)]]></constant></entry>
<entry>term <constant>SimpleTerm</constant> with a subterm
being a <constant>Number</constant>, which is
assigned to <varname>b</varname>, but matches only if the
<classname>integer</classname> <varname>b</varname> is not zero.
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="sec:statements"><title>&kpp; Control Structures</title>
<para>&kpp; provides two control structures which help dealing with
terms: the
&with;<indexterm significance="preferred"><primary>&with;</primary></indexterm>-statement and the
&foreach;<indexterm significance="preferred"><primary>&foreach;</primary></indexterm>-statement. They appear in
different variants, fitting slightly different purposes. </para>
<sect2><title>Explicit
&with;<indexterm><primary>&with;</primary><secondary>explicit</secondary></indexterm></title>
<para>The &with;-statement is similar to a &cpp;
<constant>switch</constant>
and decides for a given term which alternative branch to choose. The
alternatives are patterns describing &kind;s of one phylum and have
assigned a &cpp; block, maybe an empty one.</para>
<para>The example <xref linkend="exa:withex"/> lists a code piece
containing an explicitly stated &with;. It decides whether the term
<varname>a</varname> is an identifier or a number and executes its code.
That term is accessable throughout the whole &with; body unless
an other term is assigned to the variable <varname>a</varname>, as it is
done in the second case. There, variable <varname>a</varname> gets
assigned the subterm of the <constant>Number</constant>.
The special pattern <constant>default</constant> matches when the
preceding patterns do not. Here this would never occur, because a
&simpleterm; is defined to be one of the two specified.
If no default case is specified and none of the patterns matches the
term a runtime exception is released (program execution aborted).
The pattern <constant>default</constant> is allowed in all
&with;-variants (implicit-, explicit-, and &foreach;-&with;).</para>
<example id="exa:withex">
<title>Explicit &with;</title>
<programlisting>
<![CDATA[ simpleterm a;
...
with( a ){
Ident( * ) : { $0 -> computable = false; }
c=Number( a ) : { c -> computable = true; c -> result = a -> value; }
default : { // never reached, because simpleterm has only
// the above two ]]>&kind;<![CDATA[s
}
}
]]>
</programlisting>
</example>
</sect2>
<sect2><title>Implicit
&with;<indexterm><primary>&with;</primary><secondary>implicit</secondary></indexterm></title>
<para>If a function is defined to have a phylum argument whose variable
name begins with a dollar sign, the function body is assumed to be
the body of an implicitly given &with;-statement. Example <xref
linkend="exa:withim"/> presents a function which returns
<literal>true</literal> if the given &aritherm;
matches one of
the specified patterns, that is represents an arithmetic term. If the
term has the &kind; <constant>SimpleTerm</constant>, the default case
would catch.</para>
<example id="exa:withim">
<title>Implicit &with;</title>
<programlisting>
<![CDATA[ bool is_arithmetic_term( aritherm $a ) {
Plus, Minus, Mul, Div: { return true; }
default: { return false; }
}
]]>
</programlisting>
</example>
</sect2>
<sect2><title>Simple &foreach;</title>
<para>The &foreach;-statement is a loop which runs over all elements of a
term which is a list phylum and executes at every run the code which is
specified in the statement body.</para>
<para>The &foreach; in example <xref linkend="exa:simpleforeach"/> counts
the appearances of arithmetic terms by calling the function
<function>is_arithmetic_term</function> for <varname>a</varname>
during each run. This variable holds the current list element.</para>
<example id="exa:simpleforeach">
<title>Simple foreach</title>
<programlisting>
<![CDATA[ int count = 0;
foreach( a; arithermlist A ) {
if( is_arithmetic_term( a ) ) count++;
}
]]>
</programlisting>
</example>
</sect2>
<sect2><title>&foreach;-&with;<indexterm><primary>&foreach;-&with;</primary></indexterm></title>
<para>This foreach variant also steps through a list, but performs a
&with; for every element. A dollar prefixed list variable is used
instead of a simple variable. The statement body contains patterns with
a &cpp; block assigned to each.
Example <xref linkend="exa:foreachwith"/>
demonstrates the usage. It counts the number of sums and differences
within the term list.</para>
<example id="exa:foreachwith">
<title>&foreach;-&with;</title>
<programlisting>
<![CDATA[ int num_plus = 0;
int num_minus = 0;
foreach( $a; arithermlist A ) {
Plus: { num_plus++; }
Minus: { num_minus++; }
}
]]>
</programlisting>
</example>
</sect2>
<sect2><title>&foreach; with Pattern</title>
<para>This third variant of &foreach; allows to specify a pattern instead
of
a list variable. The action is executed only for those list elements
which match the pattern. Thus it combines &foreach; and an implicit
&with; containing only one pattern of interest. Example <xref
linkend="exa:foreachpat"/> is similar to example <xref
linkend="exa:foreachwith"/> but it counts only the number of sums in the
list.</para>
<example id="exa:foreachpat">
<title>&foreach; with Pattern</title>
<programlisting>
<![CDATA[ int num_plus = 0;
foreach( Plus( *, * ); arithermlist A ) {
num_plus++;
}
]]>
</programlisting>
</example>
</sect2>
<sect2><title>Multiple Patterns<indexterm><primary>multiple
patterns</primary></indexterm></title>
<para>For every one of the preceding statements it is possible to specify
not only one but multiple variables or patterns respectively. Used with
&foreach;, multiple lists can be iterated over at one time. The
variables or patterns are separated by ampersand signs (&amp;), the list
specifications by commas. Used with &with;, multiple terms can be
checked at one time whether matching complex patterns. Here, the
variables are separated by commas.</para>
<para>The complex patterns are made up by concatenating
single patterns by ampersand signs
(&amp;)<indexterm><primary>&amp;</primary></indexterm>, where the first
pattern has to match the first term, the second the second term (and so
on) to have the complex pattern to match. A complex pattern can also be
a grouping of patterns, but then it must be enclosed in
parentheses.</para>
<para>Example <xref linkend="exa:multipat"/> shows a &with; over two
variables. The statement simply prints out whether the two terms have
the same &kind;.</para>
<example id="exa:multipat">
<title>Multiple Patterns in &with;</title>
<programlisting>
<![CDATA[ simpleterm a, b;
...
with ( a, b ) {
Number & Number: { std::cout << "numbers" << std::endl; }
Ident & Ident: { std::cout << "identifiers" << std::endl; }
Number & (Number, Ident): { std::cout << "first num" << std::endl; }
default: { std::cout << "first ident" << std::endl; }
}
]]>
</programlisting>
</example>
</sect2>
<sect2><title><constant>afterforeach</constant><indexterm><primary>afterforeach</primary></indexterm></title>
<para>When a &foreach; iterates over more than one list at one time, the
execution will stop if one of the lists reaches its end, while the others
may still contain elements. The
<constant>afterforeach</constant>-statement is useful
if it is desired to iterate further over the remainders of the lists. The
variables of the <constant>afterforeach</constant> refer to the list
remainders. Their phyla are already known
from the preceding &foreach;. The
code fragment in example <xref linkend="exa:afterfor"/> uses
&foreach;-&with; and
<constant>afterforeach</constant> to decide whether list
<varname>A</varname> is longer than list <varname>B</varname>, returning
<literal>true</literal> if it is.</para>
<example id="exa:afterfor">
<title><constant>afterforeach</constant> in Length Test</title>
<programlisting>
<![CDATA[ foreach( $a & $b; arithermlist A, arithermlist B ) {
default: { /* do nothing */ }
}
// at least one list ran out of elements
afterforeach( $a & $b ) {
Consarithermlist & Nilarithermlist: { return true;
/* A has elements, B doesn't */ }
default: { return false; }
}
]]>
</programlisting>
</example>
</sect2>
</sect1>
<sect1>
<title>Rewriting<indexterm
significance="preferred" id="idx:rewriting"
class="startofrange"><primary>rewriting</primary></indexterm></title>
<para>The process of rewriting transforms a term tree. The left-hand side of
each rewrite rule is a pattern specifying which term to substitute. The
right-hand side denotes the term to substitute by, which has to be of the
same phylum as the original one. This is done by calls of operators and
term returning functions. Variables from the left-hand side may be used.
Example <xref linkend="exa:rewrite2"/> simplifies terms by replacing every
sum of numbers by its evaluated result. A helper function is necessary
since it is not possible directly to use &cpp; operators in a
rewrite rule (except method calls, see <xref linkend="sec:restriction"/>). </para>
<example id="exa:rewrite2">
<title>Rewriting</title>
<programlisting>
<![CDATA[ Plus( SimpleTerm( Number( a ) ), SimpleTerm( Number( b ) ) ) ->
<: SimpleTerm( Number( plus( a, b ) ) ) >;
%{ KC_REWRITE /* code redirection */
integer plus( integer a, integer b ){
return mkinteger( a -> value + b -> value );
}
%}]]>
</programlisting>
</example>
<para>To allow rewriting to end, each rule has to replace the
term in question by one which is really simpler, reduced, or closer to a
normal form. Since rewriting searches depth first, the
subterms<indexterm><primary>subterm</primary></indexterm> are usually
already the result of a transformation.
Calling the
<function>rewrite</function><indexterm><primary>rewrite()</primary></indexterm> method of the root term
starts the transforming process for the tree. Choosing an arbitrary term
instead rewrites the subtree beneath. </para>
<indexterm class="endofrange" startref="idx:rewriting"/>
</sect1>
<sect1>
<title>Unparsing<indexterm class="startofrange" significance="preferred"
id="idx:unparsing"><primary>unparsing</primary></indexterm></title>
<para>The process of unparsing traverses a term tree and executes the
instructions for every term matching a pattern as specified in the unparse
rules. The left-hand side of a rule denotes a term pattern, the right-hand
side a list of unparse items which are evaluated for matching terms. The
various items allowed are listed below and appear all in example <xref
linkend="exa:unparseitems"/>, which is completely nonsensically.
</para>
<variablelist>
<varlistentry><term>string</term>
<listitem><para>Text strings in double quotes are delivered to the
printer unchanged.</para>
</listitem>
</varlistentry>
<varlistentry><term>variable</term>
<listitem><para>The term denoted by this term variable will be
unparsed by calling its <function>unparse</function>-method.</para>
</listitem>
</varlistentry>
<varlistentry><term>attribute</term>
<listitem><para>The
attribute<indexterm><primary>attributes</primary></indexterm> of
a term will be unparsed by calling
its
<function>unparse</function><indexterm><primary>unparse()</primary></indexterm>-method. If it is of non-phylum
type the user has to provide such a method.</para>
</listitem>
</varlistentry>
<varlistentry><term>&cpp; code</term>
<listitem><para>Inside a pair of braces arbitrary &cpp; code may be
placed. </para>
</listitem>
</varlistentry>
<varlistentry><term>escaped braces</term>
<listitem><para><indexterm><primary>${</primary></indexterm>
<indexterm><primary>$}</primary></indexterm>
If a non-matching brace is needed it has to be escaped by a dollar sign.
</para>
</listitem>
</varlistentry>
<varlistentry><term>variable with view</term>
<listitem><para>A view can be specified if a variable should be
unparsed under other than the current view (see <xref linkend="sec:viewclass"/>).
</para>
</listitem>
</varlistentry>
<varlistentry><term>unparse view variable definition</term>
<listitem><para>Variables of user defined unparse view classes can be
defined inside a rule (see <xref linkend="sec:viewclass"/>).
</para>
</listitem>
</varlistentry>
</variablelist>
<example id="exa:unparseitems">
<title>Unparse Items</title>
<programlisting>
<![CDATA[ Mul( a, b ) -> [: "zero"
a
b->result
{ if (a->value == 0) } ${
a:infix
$}
%uviewvar prefix p1;
a:p1
];]]>
</programlisting>
</example>
<para>For every operator, there is a default pattern which matches if
no other pattern does. Its associated rule unparses all subterms<indexterm><primary>subterm</primary></indexterm>.
The <function>unparse</function>-method
generated for every phylum can also be called explicitly. It has 3
arguments: the term to be unparsed, a printer and an
unparse view. The names <varname>kc_printer</varname><indexterm><primary>kc_printer</primary></indexterm> and
<varname>kc_current_view</varname><indexterm><primary>kc_current_view</primary></indexterm>
respectively refer to the printer and the view
which are currently in use.</para>
<sect2><title>Printer</title>
<indexterm id="idx:printer"
class="startofrange"><primary>printer</primary></indexterm>
<para>The user himself has to provide a printer function which satisfies
his needs. Usually it prints to the standard output or into some file,
and may take actions dependent on the view.
</para>
<informalexample>
<programlisting>
void printer( const char* the_string, uview the_view ) { ... };
</programlisting>
</informalexample>
<para>
Since several printer instances may be needed also a printer functor
can be
specified as the printer. The printer functor class must be derived
<constant>public</constant> from the class
<classname>printer_functor_class</classname>.</para>
<informalexample>
<programlisting>
%{ HEADER /* redirection since no class definitions allowed in .k */
class example_printer : public printer_functor_class {
public:
void operator( ) ( const char* the_string, uview the_view ) { ... };
}
%}
</programlisting>
</informalexample>
<!-- Always move to end of enclosing sect2 -->
<para><indexterm class="endofrange" startref="idx:printer"/></para>
</sect2>
<sect2><title>Language Options</title>
<indexterm><primary>language options</primary></indexterm>
<para>Often a term tree has to be pretty printed into different but
similar destination languages, which sometimes require only slightly
different output to be generated. To avoid whole rule sets to be
multiplied and to allow a more flexible choice concerning the
destination language, the concept of language options has been
introduced.
Every unparse item can be preceded by a language option, which is a
language name in angle brackets followed by a colon. That item will be
unparsed only if the language specified is active. Languages are
declared using the keyword
<constant>%language</constant><indexterm><primary>%language</primary></indexterm>
and they are set by
calling
<function>set_language(...)</function><indexterm><primary>set_language()</primary></indexterm>. The active language can
be checked by calling
<function>is_language(...)</function><indexterm><primary>is_language()</primary></indexterm>. The
language names must satisfy the requirements for &cpp; identifiers.
Example
<xref linkend="exa:langopt"/> demonstrates the application of language
options. </para>
<example id="exa:langopt"><title>Language Options</title>
<programlisting>
<![CDATA[ %language CPP, JAVA;
ClassDefinition( name, base_name, class_body ) ->
[: <JAVA>: "public " "class " name
<JAVA>: " extends " <CPP>: " : "
base_name " {\n" class_body "}"
<CPP>: ";"
"\n"
];
]]>
</programlisting>
</example>
<!-- Always move to end of enclosing sect1 -->
<para><indexterm class="endofrange" startref="idx:unparsing"/></para>
</sect2>
</sect1>
<sect1 id="sec:viewclass"><title>View
Classes<indexterm significance="preferred" class="startofrange"
id="idx:view_man"><primary>view</primary></indexterm></title>
<para>Rewriting and unparsing of each term is done under a certain view. The
view serves as a means to further differentiate between rules when
choosing one to apply. To be a match a rule must have the current view
to appear in its view list, which is the left part of the right-hand side
between the bracket and the colon. If no rule matches the rules with
empty list are considered. Below is shown the general form of rules with
views. </para>
<informalexample>
<programlisting>
<![CDATA[ rewrite_rule := pattern "->" "<" rview_list ":" {operator|function} ">;"
unparse_rule := pattern "->" "[" uview_list ":" unparse_items "];"]]>
</programlisting>
</informalexample>
<para>Views are declared by enumerating them after the keyword
<constant>%rview</constant><indexterm
significance="preferred"><primary>%rview</primary></indexterm> and
<constant>%uview</constant><indexterm
significance="preferred"><primary>%uview</primary></indexterm> for
rewriting and unparsing respectively, separated by a space or
a comma. These declarations enable &kpp; to check for view consistency,
although it is possible to leave them out entirely. But that
should be avoided, because then even simple misspellings in a view list
cause the implicit introduction of new views. One view is predefined for
rewriting and unparsing respectively,
<varname>base_rview</varname><indexterm
significance="preferred"><primary>base_rview</primary></indexterm> and
<varname>base_uview</varname><indexterm
significance="preferred"><primary>base_uview</primary></indexterm>,
which is implicitly included in the empty view list.</para>
<para>The view can be changed for a term by calling its
<function>rewrite/unparse</function><indexterm><primary>rewrite()</primary></indexterm>-method
with a new view argument. In unparse rules there the same can also
be achieved by appending a colon and a new view name to a variable unparse
item. Thus a whole subtree can be rewritten/unparsed under a different
view, or even multiple times under changing views. Changing views allows
to interlock several tasks on a certain subtree. </para>
<informalexample>
<programlisting>
<![CDATA[ %rview demo1 ;
Plus( a, SimpleTerm( Number( 0 ) ) ) -> <: a -> rewrite( demo1 ) >;
%uview demo2 ;
Plus( a, b ) -> [: a:demo2 { b->unparse( kc_printer, demo2 ); } ];
// both subterms of Plus are further unparsed under view demo2;]]>
</programlisting>
</informalexample>
<para><indexterm id="idx:viewclass"
class="startofrange"><primary>view</primary><secondary>class</secondary></indexterm>Every
view introduced by the user actually causes the generation of a view
class and one view variable of the same name. Since the user cannot
distinguish them, the generalizing term &lsquo;view&rsquo; is used.
For unparse views that may matter since the user can define his own
unparse view classes. These are declared by
enclosing the view name in parentheses. The user has
to provide a class <varname>view</varname><classname>_class</classname>
derived from a generated class
<varname>view</varname><classname>_baseclass</classname>. In particular,
that class may contain member variables to hold information persistent
over several rules. The base class provides an equality
operator (<function>==</function>) deciding whether two view variables
are of the same class and a
<function>name</function>-method returning the name of the view.</para>
<para>No global view variable of the same name is generated for a user
defined unparse view class. Variables of such a view are instantiated
inside of unparse rules by <constant>%uviewvar</constant><indexterm
significance="preferred"><primary>%uviewvar</primary></indexterm>
and may bear the same name as their class. They can be used
like the implicitly created view variables, but
additionally provide all features of their class. Example <xref
linkend="exa:uviewvar"/> shows the definition of an unparse view class and
demonstrates its usage.</para>
<example id="exa:uviewvar">
<title>User defined Unparse View Class</title>
<programlisting>
<![CDATA[ %uview ( number_count ) ;
%{ KC_UNPARSE /* code redirection to where it is needed */
class number_count_class : public number_count_baseclass {
public:
number_count_class() : counter( 0 ) { };
int counter;
};
%}
c=Plus, c=Minus, c=Mul, c=Div, c=SimpleTerm -> [:
%uviewvar number_count nc; // instantiate view variable
c:nc // and unparse c with it
{ std::cout << "Numbers counted: " << nc.counter << std::endl; }
];
Plus( a, b ), Minus( a, b ), Mul( a, b ), Div( a, b )
-> [ number_count: a b ];
SimpleTerm( a ) -> [ number_count: a ];
Number -> [ number_count: { kc_current_view.counter++; } ];
Ident -> [ number_count: ];]]>
</programlisting>
</example>
<para>View lists contain names of view classes, all other occurrences of
views actually are view variables. The scope of an unparse view variable
ends with its defining rule. Since its
name is not known inside other rules there it can be accessed only by
means of the name <varname>kc_current_view</varname><indexterm><primary>kc_current_view</primary></indexterm>, which always
refers to the view variable currently used. </para>
<indexterm class="endofrange" startref="idx:viewclass"/>
<indexterm class="endofrange" startref="idx:view_man"/>
</sect1>
<sect1 id="sec:restriction"><title>Restrictions on &cpp; in &kpp;</title>
<para>There are many places
in a <filename>.k</filename>-file where &cpp; code can be used. But for
some of them, the &kpp; processor allows only restricted use of &cpp;
constructs. These places are listed in the following along with the
restrictions they impose.</para>
<variablelist>
<varlistentry><term><filename>.k</filename>-file</term>
<listitem><para>Only function definitions are allowed. These
must have no types as arguments which have compound names
(for example no <constant>long int</constant>). &cpp;
comments<indexterm><primary>comments</primary></indexterm> are
allowed everywhere in <filename>.k</filename>-files.</para>
</listitem>
</varlistentry>
<varlistentry><term>&cpp; unparse item</term>
<listitem><para>Almost arbitrary &cpp; code is allowed, that is,
everything which is allowed inside a local &cpp; block. </para>
</listitem>
</varlistentry>
<varlistentry><term>rewrite rule</term>
<listitem><para>Only simple function calls are allowed, that is, calls
which have as arguments only term variables and term literals,
phylum operators and other simple function calls; in particular no
&cpp; operators, except access of member functions.</para>
</listitem>
</varlistentry>
<varlistentry><term>code redirection</term>
<listitem><para>Arbitrary &cpp; code is allowed, but it has to be pure
&cpp; since redirection code is not evaluated by &kpp;.</para>
</listitem>
</varlistentry>
</variablelist>
<para>There is a way to get around the restrictions of the &kpp; processor
using macros. A macro is defined inside a code redirection, which the
processor does not evaluate. Therefore it can
be as complex as necessary, while the macro call inside the rewrite rule
looks as simple as &kpp; wishes. Example
<xref linkend="exa:rewrite2"/> defines a function for addition, which can be
avoided when using a macro as in example <xref linkend="exa:macro"/>.
</para>
<example id="exa:macro">
<title>Macro Application in Rewriting</title>
<programlisting>
<![CDATA[ Plus( SimpleTerm( Number( a ) ), SimpleTerm( Number( b ) ) ) ->
<: SimpleTerm( Number( PLUS( a, b ) ) ) >;
%{ KC_REWRITE /* code redirection */
#define PLUS( a, b ) mkinteger( ( a ) -> value + ( b ) -> value )
%}]]>
</programlisting>
</example>
<para>Some generated functions return terms of the phylum
<classname>abstract_phylum</classname> which have to be cast to the
actual phylum. The &cpp; cast operators may be used also for phylum
conversion<indexterm><primary>phylum</primary><secondary>conversion</secondary></indexterm>
but &kpp; provides
<function>phylum_cast</function><indexterm><primary>phylum_cast</primary></indexterm>,
a cast operator for phyla, which is better to use. </para>
</sect1>
</chapter>
<chapter><title>Generated Code</title>
<para>From the &kpp; definitions, rules and &cpp; code pieces, several classes
and functions in pure &cpp; are generated and distributed over multiple
files. Compiled, they will perform the desired tree handling.
Additional code is needed to create the trees, probably created by scanner
and parser generators, for instance <application>Flex</application> and
&bison;.</para>
<sect1><title>Generated Classes and Types</title>
<para>The definition of phyla and operators result in generated &cpp;
classes.
But these should be of no further interest for the user since the phylum
names can be used in &cpp; code as if being pointer types of these
classes, the operators as if being &cpp; constructors.
Every phylum has a <constant>const</constant> counterpart of the same name
prefixed by <constant>c_</constant>, which is the only means to get a
<constant>const</constant> phylum variable. </para>
<para>Just for the sake of completeness, be it mentioned that every
phylum corresponds to a class
<classname>impl_</classname><varname>phylum</varname> and every
operator to a subclass
<classname>impl_</classname><varname>phylum</varname>_<varname>operator</varname>.
All the classes are derived from a common base class which can be referred
to as
<classname>abstract_phylum</classname>. By adding constructors, methods
or attributes to it, all phyla will be changed in that way.
</para>
<para>The interworking with &yacc;/&bison; requires a type
<classname>YYSTYPE</classname> which will be generated by &kpp; when the
option <constant>yystype</constant> is specified (see <xref linkend="sec:options"/>)</para>
<sect2><title>Smart-pointer<indexterm><primary>smart
pointer</primary></indexterm></title>
<para>Memory often leaks when phylum operators are used in expressions,
and that is sometimes hard to detect.
The option <constant>smart-pointer</constant> enables a smart memory
management which avoids unnecessary copying of terms and automatically
frees memory of unused terms. This is achieved
by using so called smart-pointers which do reference counting and
allow to free a term if it is no longer referenced.</para>
<para>An additional type is generated for every phylum with the suffix
<classname>_ptr</classname>. Variables of such types are unnecessary
ever to be freed. Avoid mixing them with variables of the usual types,
especially never assign between them, because that is likely to cause
memory access errors.
<!--(detailed description of implementation? TODO)--></para>
</sect2>
<sect2><title>Weak-pointer<indexterm><primary>weak
pointer</primary></indexterm></title>
<para>The option <constant>weak-pointer</constant> extends the
smart-pointer technique and supports a third
type for every phylum. It gets prefix <constant>weak_</constant> and
suffix <constant>_ptr</constant>. Weak-pointer variables of a term will
not contribute to the reference counting, such that the term already is
freed if merely weak-pointers reference it yet. That is why they are
only usefully employed in conjunction with smart-pointers.
In contrast to usual variables, weak-pointers have their own
reference counting, which allows to determine whether such a pointer
dangles, that is points to a term already freed and thus is no longer
valid.</para>
</sect2>
</sect1>
<sect1 id="sec:genfunc"><title>Generated Functions</title>
<para>&kpp; generates a number of functions which are available wherever
&cpp; code is allowed in <filename>.k</filename>-files. The table <xref
linkend="tab:functions"/> lists all these functions and the sections
which contain a more detailed description.</para>
<table id="tab:functions"><title>Generated Functions</title>
<?latex \hfill?>
<tgroup cols='2' align='left' colsep='1' rowsep='1'>
<?latex-table-option [t]?>
<thead>
<row>
<entry>function</entry>
<entry>see section</entry>
</row>
</thead>
<tbody>
<row>
<entry>append</entry>
<entry><xref linkend="sec:listfuncs"/></entry>
</row>
<row>
<entry>concat</entry>
<entry><xref linkend="sec:listfuncs"/></entry>
</row>
<row>
<entry>eq</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
<row>
<entry>CSGIOread</entry>
<entry><xref linkend="sec:csgiofuncs"/></entry>
</row>
<row>
<entry>CSGIOwrite</entry>
<entry><xref linkend="sec:csgiofuncs"/></entry>
</row>
<row>
<entry>filter</entry>
<entry><xref linkend="sec:listfuncs"/></entry>
</row>
<row>
<entry>fprint</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
<row>
<entry>fprintdot</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
<row>
<entry>fprintdotepilogue</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
<row>
<entry>fprintdotprologue</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
<row>
<entry>free</entry>
<entry><xref linkend="sec:memfuncs"/></entry>
</row>
<row>
<entry>freelist</entry>
<entry><xref linkend="sec:memfuncs"/></entry>
</row>
<row>
<entry>ht_create_simple</entry>
<entry><xref linkend="sec:memfuncs"/></entry>
</row>
<row>
<entry>ht_assign</entry>
<entry><xref linkend="sec:memfuncs"/></entry>
</row>
<row>
<entry>ht_assigned</entry>
<entry><xref linkend="sec:memfuncs"/></entry>
</row>
<row>
<entry>ht_clear</entry>
<entry><xref linkend="sec:memfuncs"/></entry>
</row>
<row>
<entry>ht_delete</entry>
<entry><xref linkend="sec:memfuncs"/></entry>
</row>
<row>
<entry>is_nil</entry>
<entry><xref linkend="sec:listfuncs"/></entry>
</row>
</tbody>
</tgroup>
<?latex \hfill?>
<tgroup cols='2' align='left' colsep='1' rowsep='1'>
<?latex-table-option [t]?>
<thead>
<row>
<entry>function</entry>
<entry>see section</entry>
</row>
</thead>
<tbody>
<row>
<entry>last</entry>
<entry><xref linkend="sec:listfuncs"/></entry>
</row>
<row>
<entry>length</entry>
<entry><xref linkend="sec:listfuncs"/></entry>
</row>
<row>
<entry>map</entry>
<entry><xref linkend="sec:listfuncs"/></entry>
</row>
<row>
<entry>merge</entry>
<entry><xref linkend="sec:listfuncs"/></entry>
</row>
<row>
<entry>mkcasestring</entry>
<entry><xref linkend="sec:creationfuncs"/></entry>
</row>
<row>
<entry>mkinteger</entry>
<entry><xref linkend="sec:creationfuncs"/></entry>
</row>
<row>
<entry>mknocasestring</entry>
<entry><xref linkend="sec:creationfuncs"/></entry>
</row>
<row>
<entry>mkreal</entry>
<entry><xref linkend="sec:creationfuncs"/></entry>
</row>
<row>
<entry>op_name</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
<row>
<entry>phylum_name</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
<row>
<entry>print</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
<row>
<entry>reduce</entry>
<entry><xref linkend="sec:listfuncs"/></entry>
</row>
<row>
<entry>reverse</entry>
<entry><xref linkend="sec:listfuncs"/></entry>
</row>
<row>
<entry>rewrite</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
<row>
<entry>set_subphylum</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
<row>
<entry>subphylum</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
<row>
<entry>unparse</entry>
<entry><xref linkend="sec:commonfuncs"/></entry>
</row>
</tbody>
</tgroup>
<?latex \hspace*{\fill}?>
</table>
<sect2 id="sec:commonfuncs"><title>Common Functions</title>
<para>Since <classname>abstract_phylum</classname> has an
<function>unparse</function>-method defined and all phyla are derived
from <classname>abstract_phylum</classname> all phyla have it. The same
is true for some other methods.</para>
<sect3><title>copy<indexterm><primary>copy()</primary></indexterm></title>
<informalexample>
<programlisting>
abstract_phylum copy( bool copy_attributes ) const;
</programlisting>
</informalexample>
<para>The method copies this term completely, including its subterms.
Since the result is always <classname>abstract_phylum</classname> it
has to be casted to the phylum of this term. If
<literal>true</literal> is specified as argument, the attributes are
copied too. But beware! Merely the addresses are copied if the
attributes are phyla or &cpp; pointers, that is, the new term
references the attributes of the old one. </para>
</sect3>
<sect3><title>eq<indexterm><primary>eq()</primary></indexterm></title>
<informalexample>
<programlisting>
bool eq( c_abstract_phylum c_p ) const;
</programlisting>
</informalexample>
<para>The method returns <literal>true</literal> if this term is
structurally equal to the argument, that is, both terms have
equal subtrees.</para>
</sect3>
<sect3><title>fprint<indexterm><primary>fprint()</primary></indexterm></title>
<informalexample>
<programlisting>
void fprint( FILE* file );
</programlisting>
</informalexample>
<para>The method prints a textual presentation of this term to
the specified file. This simple example produces the output
underneath. </para>
<programlisting>
simpleterm a_number = SimpleTerm( mkinteger( 23 ) );
a_number -> print( );
SimpleTerm(
Number(
23
)
)
</programlisting>
</sect3>
<sect3><title>fprintdot<indexterm><primary>fprintdot()</primary></indexterm></title>
<informalexample>
<programlisting>
void fprintdot( FILE *f,
const char *root_label_prefix,
const char *edge_label_prefix,
const char *edge_attributes,
bool print_node_labels,
bool use_context_when_sharing_leaves,
bool print_prologue_and_epilogue
) const;
</programlisting>
</informalexample>
<para>This function creates a representation of the term in a format
understood by the program <application>dot</application>, which is part
of the graphics package <application>graphviz</application> and draws
directed acyclic graphs in various output formats like PostScript or
GIF. The target of the operation is the file <varname>f</varname>, while
the other arguments control the details of the graphs appearence.
</para>
<variablelist>
<varlistentry><term>root_label_prefix</term>
<listitem><para>Adds a label to the graph denoting the root term.
The label has the name of the phylum of that term prefixed by
this string argument. </para>
</listitem>
</varlistentry>
<varlistentry><term>edge_label_prefix</term>
<listitem><para>Every edge in the graph is labelled with a number.
This string argument appears as the prefix of these labels.
</para>
</listitem>
</varlistentry>
<varlistentry><term>edge_attributes</term>
<listitem><para>For <application>dot</application>, the edges can
have attributes which specify additional features like font name
or edge colour (see <application>dot</application> manual for
attribute names and values). This string argument is a list of
attribute/value pairs
(<varname>attribute</varname>=<varname>value</varname>),
separated by commas.</para>
</listitem>
</varlistentry>
<varlistentry><term>print_node_labels</term>
<listitem><para>If this argument is set to <literal>true</literal>,
the names of the subterms phyla appear in the graph. Otherwise
they are suppressed and only the term names (operator names) are
printed.
</para>
</listitem>
</varlistentry>
<varlistentry><term>use_context_when_sharing_leaves</term>
<listitem><para>Terms which are shared in the tree usually appear
only once in the graph (terms of <constant>uniq</constant>
phyla). In particular, terms of predefined phyla are shared if
they are equal. They are always leaves since they have no
subphyla. If this argument is set to <literal>true</literal>,
the leaves appear shared in the graph only if they are subterms
of shared (<constant>uniq</constant>) terms.
</para>
</listitem>
</varlistentry>
<varlistentry><term>print_prologue_and_epilogue</term>
<listitem><para>This argument is usually set to
<literal>true</literal> since a certain prologue and epilogue
are necessary to frame the graph. This is set to
<literal>false</literal> if multiple graphs are to be grouped
into one figure. In that case the prologue function has to be
called explicitly, then some <function>fprintdot</function>
calls follow, and finally the epilogue call finishes the figure
creation. </para>
</listitem>
</varlistentry>
</variablelist>
<para>The following call of <function>fprintdot</function> writes a
a presentation of the term <varname>t</varname> to a file
<varname>exa</varname>. From that file <application>dot</application>
creates a graph like that in figure <xref linkend="fig:fprintdot"/>.</para>
<programlisting>
aterm t = Plus( SimpleTerm( Number( mkinteger( 7 ) ) ),
SimpleTerm( Number( mkinteger( 7 ) ) ) );
t -> fprintdot(exa, "root_", "edge", "style=dashed", true, false, true);
</programlisting>
<figure id="fig:fprintdot">
<title>Dot Created Graph of an Example Term</title>
<mediaobject><imageobject><imagedata
align="center" fileref="imagesgen/fprintdot.png" format="PNG"/>
</imageobject>
<imageobject><imagedata
align="center" fileref="imagesgen/fprintdot" format="TEX"/>
</imageobject>
</mediaobject>
</figure>
</sect3>
<sect3><title>fprintdotprologue<indexterm><primary>fprintdotprologue()</primary></indexterm></title>
<informalexample>
<programlisting>
void fprintdotprologue ( FILE *f );
</programlisting>
</informalexample>
<para>This function writes the prologue to <varname>f</varname>, which
is needed to set up <application>graphviz</application>.
Usually, when the figure contains only one graph, this function will
be called implicitly by <function>fprintdot</function>; call this
function when you set <varname>print_prologue_and_epilogue</varname>
to <literal>false</literal> in the function call above.
</para>
</sect3>
<sect3><title>fprintdotepilogue<indexterm><primary>fprintdotepilogue()</primary></indexterm></title>
<informalexample>
<programlisting>
void fprintdotepilogue ( FILE *f );
</programlisting>
</informalexample>
<para>This function writes the epilogue to <varname>f</varname>, which
is needed to finish the graph for <application>graphviz</application>.
Usually, when the figure contains only one graph, this function will
be called implicitly by <function>fprintdot</function>; call this
function when you set <varname>print_prologue_and_epilogue</varname>
to <literal>false</literal> in the function call above.
</para>
</sect3>
<sect3><title>op_name<indexterm><primary>op_name()</primary></indexterm></title>
<informalexample>
<programlisting>
const char* op_name( ) const;
</programlisting>
</informalexample>
<para>This function returns the name of the phylum operator which has
been used to create this term. </para>
</sect3>
<sect3><title>phylum_name<indexterm><primary>phylum_name()</primary></indexterm></title>
<informalexample>
<programlisting>
const char* phylum_name( ) const;
</programlisting>
</informalexample>
<para>This function returns the name of the phylum of this term. </para>
</sect3>
<sect3><title>print<indexterm><primary>print()</primary></indexterm></title>
<informalexample>
<programlisting>
void print( );
</programlisting>
</informalexample>
<para>This function prints a textual presentation of this term to the
standard output. It is similar to the output of
<function>fprint</function>.</para>
</sect3>
<sect3><title>set_subphylum<indexterm><primary>set_subphylum()</primary></indexterm></title>
<informalexample>
<programlisting>
void set_subphylum( int n, abstract_phylum p, bool=false );
</programlisting>
</informalexample>
<para>This function replaces the <varname>n</varname>th subterm of this term by term
<varname>p</varname>, which must be of a phylum castable to the phylum
of the appropriate subterm. Numbering starts with <literal>0</literal>.
</para>
</sect3>
<sect3><title>subphylum<indexterm><primary>subphylum()</primary></indexterm></title>
<informalexample>
<programlisting>
abstract_phylum subphylum( int n, bool=false ) const;
</programlisting>
</informalexample>
<para>This function returns the <varname>n</varname>th subterm of this
term. Numbering starts with <literal>0</literal>. </para>
</sect3>
<sect3><title>unparse<indexterm significance=
"preferred"><primary>unparse()</primary></indexterm></title>
<informalexample>
<programlisting>
void unparse( printer_functor pf, uview uv);
void unparse( printer_function opf, uview uv );
</programlisting>
</informalexample>
<para>This function starts unparsing for this term. It is recursively
called for every subterm. Unparsing is processed under the specified
unparse view, and the strings to output are delivered to the printer
functor or function respectively. </para>
</sect3>
<sect3><title>rewrite<indexterm><primary>rewrite()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ <actual phylum> rewrite( rview rv );
]]>
</programlisting>
</informalexample>
<para>This functions starts rewriting for this term. It returns a new term
of the actual phylum. Usually it is called at the root term whereupon
the entire tree is searched under the specified view. </para>
</sect3>
</sect2>
<sect2 id="sec:csgiofuncs"><title>CSGIO Functions</title>
<para>The generated files <filename>csgiok.h</filename> and
<filename>csgiok.cc</filename><indexterm><primary>csgiok.cc,h</primary></indexterm>
provide means to write terms to files and
to reconstruct terms from such files. Whole term trees thus can be saved
and exchanged between different applications. Reading and writing
is performed by two functions.</para>
<para>The format of the files has once been designed to be compatible to
the structure files of the commercial tool <application>Synthesizer
Generator</application>. The format written now by &kpp; is somewhat
extended so that they are not compatible any more, but old structure
files are expected to be still understood.</para>
<sect3><title>CSGIOwrite<indexterm><primary>CSGIOwrite()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ void CSGIOwrite( FILE *f ) const;
]]>
</programlisting>
</informalexample>
<para>The methods writes this term to <varname>f</varname>, that is, the
entire subterm tree. The
attributes are ignored except they are phyla which have been defined
using the keyword <constant>%member</constant>. </para>
</sect3>
<sect3><title>CSGIOread<indexterm><primary>CSGIOread()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ template<typename P> void
CSGIOread( FILE *f, P &p )
]]>
</programlisting>
</informalexample>
<para>The function reads from <varname>f</varname> the presentation of a
term. The term is constructed by successively calling the appropriate
operators of the subterms. The operators initialize the attributes
according to the phylum definition; except the
<constant>%member</constant>-attributes which get their values from
the saved term. The created term is assigned to <varname>p</varname>
which has to be a variable of the correct phylum.
</para>
</sect3>
</sect2>
<sect2 id="sec:creationfuncs"><title>Creation Functions</title>
<para>Terms of predefined phyla are created by functions.</para>
<sect3><title>mkcasestring<indexterm significance=
"preferred"><primary>mkcasestring()</primary></indexterm></title>
<informalexample>
<programlisting>
casestring mkcasestring( const char *str );
casestring mkcasestring( const char *str, unsigned int length );
</programlisting>
</informalexample>
<para>The function creates a term of the phylum
<classname>casestring</classname>
from the specified string. Upper and lower case characters are
distinguished. The second variant uses only the first
<varname>length</varname> characters of the specified string.
</para>
</sect3>
<sect3><title>mkinteger<indexterm significance=
"preferred"><primary>mkinteger()</primary></indexterm></title>
<informalexample>
<programlisting>
integer mkinteger( const INTEGER i );
</programlisting>
</informalexample>
<para>The function creates a term of the phylum
<classname>integer</classname>
from the specified value. <classname>INTEGER</classname> is a macro
which can be defined by the user as needed but defaults to
<classname>int</classname>. </para>
</sect3>
<sect3><title>mknocasestring<indexterm significance=
"preferred"><primary>mknocasestring()</primary></indexterm></title>
<informalexample>
<programlisting>
nocasestring mknocasestring( const char *str );
nocasestring mknocasestring( const char *str, unsigned int length );
</programlisting>
</informalexample>
<para>The function creates a term of the phylum
<classname>nocasestring</classname>
from the specified string. Upper and lower case characters are not
distinguished. The second variant uses only the first
<varname>length</varname> characters of the specified string. </para>
</sect3>
<sect3><title>mkreal<indexterm significance=
"preferred"><primary>mkreal()</primary></indexterm></title>
<informalexample>
<programlisting>
real mkreal( const REAL r );
</programlisting>
</informalexample>
<para>The function creates a term of the phylum
<classname>real</classname>
from the specified value. <classname>REAL</classname> is a macro
which can be defined by the user as needed but defaults to
<classname>double</classname>. </para>
</sect3>
</sect2>
<sect2 id="sec:memfuncs"><title>Memory Management Functions</title>
<para>When terms, once constructed, are no longer needed it is usually
reasonable to free the memory they allocate,
especially when dealing with large numbers of
terms.</para>
<para>The same does not hold not for the use of smart-pointers, because
these keep track of allocated memory by their own. Never apply
<function>free</function> or <function>freelist</function> to
smart-pointers. The
&cpp; <constant>delete</constant> should never be applied to
any term, since that would get around some &kpp; mechanisms. </para>
<sect3><title>free<indexterm><primary>free()</primary></indexterm></title>
<informalexample>
<programlisting>
void free( bool recursive=true );
</programlisting>
</informalexample>
<para>The method frees the memory allocated by this term and by
default it frees also the subterms recursively. When it is applied to
a list term, the whole list and all its elements are freed. The
non-recursive form only separates the list into its first element and
the remainder of the list. Terms of phyla under non-default storage
management can not be freed individually, calling
<function>free</function> on them has no effect.</para>
</sect3>
<sect3><title>freelist<indexterm><primary>freelist()</primary></indexterm></title>
<informalexample>
<programlisting>
void freelist( );
</programlisting>
</informalexample>
<para>The method frees the spine of this list term and leaves the list
elements untouched. </para>
</sect3>
<sect3 id="sec:hashtable">
<title>Hashtable Functions</title>
<indexterm significance="preferred"><primary>hashtables</primary></indexterm>
<para>The memory management of terms of storage class
<constant>uniq</constant><indexterm><primary>uniq</primary></indexterm>
or a user defined one can only be influenced by hashtable operations.
</para>
</sect3>
<sect3><title>ht_create_simple<indexterm><primary>ht_create_simple()</primary></indexterm></title>
<informalexample>
<programlisting>
hashtable_t ht_create_simple ( int size );
</programlisting>
</informalexample>
<para>The function creates a new hashtable and returns it. The current
implementation ignores the <varname>size</varname> argument.
</para>
</sect3>
<sect3><title>ht_assign<indexterm><primary>ht_assign()</primary></indexterm></title>
<informalexample>
<programlisting>
hashtable_t ht_assign ( hashtable_t ht, storageclass_t sc,
bool still_unique=false );
</programlisting>
</informalexample>
<para>The function assigns the hashtable <varname>ht</varname> to the
storage class <varname>sc</varname> and returns the hashtable which
has previously been assigned to <varname>sc</varname>. </para>
</sect3>
<sect3><title>ht_assigned<indexterm><primary>ht_assigned()</primary></indexterm></title>
<informalexample>
<programlisting>
hashtable_t ht_assigned ( storageclass_t sc );
</programlisting>
</informalexample>
<para>The function returns the hashtable which is assigned to the
storageclass <varname>sc</varname>. </para>
</sect3>
<sect3><title>ht_clear<indexterm><primary>ht_clear()</primary></indexterm></title>
<informalexample>
<programlisting>
void ht_clear ( hashtable_t ht );
</programlisting>
</informalexample>
<para>The function removes all entries from the hashtable
<varname>ht</varname>. </para>
</sect3>
<sect3><title>ht_delete<indexterm><primary>ht_delete()</primary></indexterm></title>
<informalexample>
<programlisting>
void ht_delete ( hashtable_t ht );
</programlisting>
</informalexample>
<para>The function deletes the hashtable <varname>ht</varname> entirely.
</para>
</sect3>
</sect2>
<sect2 id="sec:listfuncs"><title>List Functions<indexterm id="idx:listfunc"
class="startofrange"><primary>list</primary></indexterm></title>
<para>List phyla which have been defined using the
<constant>list</constant> keyword get some methods performing convenient
tasks. In the function signatures, the name
<classname><![CDATA[<phylum list>]]></classname> denotes the actual
list phylum, <constant><![CDATA[<phylum>]]></constant> denotes the
phylum of the list elements. </para>
<sect3><title>append<indexterm><primary>append()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ <phylum list> append( <phylum> p );]]>
</programlisting>
</informalexample>
<para>The method appends the specified term to this list and returns
the tail of the new list, <abbrev>ie.</abbrev> the sublist that has
<varname>p</varname> as its only element. This make appending several
elements in a row more efficient.
</para>
</sect3>
<sect3><title>concat<indexterm><primary>concat()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ friend <phylum list> concat( c_<phylum list> l1, c_<phylum list> l2 );]]>
</programlisting>
</informalexample>
<para>The function constructs a new list from the terms of
<varname>l1</varname> followed by the terms of <varname>l2</varname>
and returns that list.
</para>
</sect3>
<sect3><title>filter<indexterm><primary>filter()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ <phylum list> filter( bool (*fp) (<phylum>) );]]>
</programlisting>
</informalexample>
<para>The method constructs a new list from the terms of this
list for which the function <function>fp</function> yields
<literal>true</literal>.
</para>
</sect3>
<sect3><title>is_nil<indexterm><primary>is_nil()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ bool is_nil( ) const;]]>
</programlisting>
</informalexample>
<para>The method returns <literal>true</literal> if this list is empty.
</para>
</sect3>
<sect3><title>last<indexterm><primary>last()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ <phylum list> last( ) const;]]>
</programlisting>
</informalexample>
<para>The method returns the remainder of this list which contains only
one, the last, element. If this list is empty the empty list is
returned.
</para>
</sect3>
<sect3><title>length<indexterm><primary>length()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ int length( ) const;]]>
</programlisting>
</informalexample>
<para>The method returns the number of elements in this list.
</para>
</sect3>
<sect3><title>map<indexterm><primary>map()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ <phylum list> map( <phylum> (*fp) (<phylum>) );]]>
</programlisting>
</informalexample>
<para>The method constructs a new list containing the terms which are
returned by the <function>fp</function> which is called for every
element of this list. The new list is returned.
</para>
</sect3>
<sect3><title>merge<indexterm><primary>merge()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ <phylum list> merge( <phylum list> l, <phylum> (*fp) (<phylum>, <phylum>) );]]>
</programlisting>
</informalexample>
<para>The method constructs a new list containing the terms which are
returned by the <function>fp</function> which is called for every
element of this list taking the second argument from the specified
list. The new list is returned.
</para>
</sect3>
<sect3><title>reduce<indexterm><primary>reduce()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ <phylum> reduce( <phylum> p, <phylum> (*fp) (<phylum>, <phylum>) );]]>
</programlisting>
</informalexample>
<para>The method successively applies the function
<function>fp</function> to each element of this list and
<function>fp</function>s last result which initially is the term
<varname>p</varname>. The final result is returned.
</para>
</sect3>
<sect3><title>reverse<indexterm><primary>reverse()</primary></indexterm></title>
<informalexample>
<programlisting>
<![CDATA[ <phylum list> reverse( ) const;]]>
</programlisting>
</informalexample>
<para>The method constructs a new list which contains the elements of
this list in reverse order. The new list is returned.
<!-- Always move to end of enclosing sect2 -->
<indexterm class="endofrange" startref="idx:listfunc"/>
</para>
</sect3>
</sect2>
</sect1>
<sect1><title>Generated Files</title>
<para>The generated code is spread over several files. The table <xref
linkend="tab:filenames"/> lists these files and a description of their
contents.
Every file defines a macro symbol which can be used in preprocessor
instructions and in code redirections<indexterm><primary>redirection</primary></indexterm>.
These symbols are listed as well. From every &kpp; file
a &cpp; file and a header file are generated. The name
<varname>file</varname> in the table refers to such files.</para>
<table id="tab:filenames"><title>Generated files</title>
<tgroup cols='3' align='left' colsep='1' rowsep='1'>
<?latex-table-type tabularx?>
<?latex-table-option {\textwidth}?>
<?latex-table-head lp{0.4\textwidth}X?>
<colspec colname='c1'/>
<colspec colname='c2'/>
<colspec colname='c3'/>
<thead>
<row>
<entry>file</entry>
<entry>symbol</entry>
<entry>contents</entry>
</row>
</thead>
<tbody>
<row>
<entry><filename>csgiok.cc</filename><indexterm><primary>csgiok.cc,h</primary></indexterm></entry>
<entry>KC_CSGIO</entry>
<entry>functions for saving and restoring of terms</entry>
</row>
<row>
<entry><filename>csgiok.h</filename></entry>
<entry>KC_CSGIO_HEADER</entry>
<entry>some definitions for saving and restoring of terms</entry>
</row>
<row>
<entry><filename>k.cc</filename><indexterm><primary>k.cc,h</primary></indexterm></entry>
<entry>KC_TYPES</entry>
<entry>implementation of all classes generated from phylum definitions</entry>
</row>
<row>
<entry><filename>k.h</filename></entry>
<entry>KC_TYPES_HEADER</entry>
<entry>all class declarations generated from phylum definitions;
included by all implicitly generated files</entry>
</row>
<row>
<entry><filename>rk.cc</filename><indexterm><primary>rk.cc,h</primary></indexterm></entry>
<entry>KC_REWRITE</entry>
<entry>rewrite methods for all phyla</entry>
</row>
<row>
<entry><filename>rk.h</filename></entry>
<entry>KC_REWRITE_HEADER</entry>
<entry>rewrite view class definitions</entry>
</row>
<row>
<entry><filename>unpk.cc</filename><indexterm><primary>unpk.cc,h</primary></indexterm></entry>
<entry>KC_UNPARSE</entry>
<entry>unparse methods for all phyla</entry>
</row>
<row>
<entry><filename>unpk.h</filename></entry>
<entry>KC_UNPARSE_HEADER</entry>
<entry>unparse view class definitions</entry>
</row>
<row>
<entry><varname>file</varname><filename>.cc</filename></entry>
<entry>KC_FUNCTIONS_<varname>file</varname> or CODE</entry>
<entry>function definitions from <varname>file</varname><filename>.k</filename>-file</entry>
</row>
<row>
<entry><varname>file</varname><filename>.h</filename></entry>
<entry>KC_FUNCTIONS_<varname>file</varname>_HEADER or HEADER</entry>
<entry>declarations of functions from <varname>file</varname><filename>.k</filename>-file</entry>
</row>
</tbody>
</tgroup>
</table>
<sect2 id="sec:redirection"><title>Code Redirection<indexterm significance="preferred"><primary>redirection</primary></indexterm></title>
<para>A <filename>.k</filename>-file can contain pieces of arbitrary &cpp;
enclosed between a line
starting with
<constant>%{</constant><indexterm><primary>%{</primary></indexterm> and
one starting with
<constant>%}</constant><indexterm><primary>%}</primary></indexterm>.
Since it will not be
parsed by &kpp; but copied directly into generated code, it can not
contain special &kpp; constructs, but merely pure &cpp;. It will go to
the matching <filename>.cc</filename>-file, if no redirection is
specified. Giving a list of
file symbols after <constant>%{</constant> will copy the code each
of the specified files instead. The available redirection symbols
are listed in table <xref linkend="tab:filenames"/>.</para>
<informalexample>
<programlisting>
// this be a file example.k
%{
// everything between the brace lines will be copied to example.cc
%}
%{ HEADER KC_UNPARSE /* beware of //-comments here */
// everything between the brace lines will be copied to example.h and unpk.cc
%}
</programlisting>
</informalexample>
</sect2>
</sect1>
</chapter>
<chapter><title>Running &kpp;</title>
<para>The &kpp; processor is invoked with the command
<userinput>kc++</userinput>. It can be invoked on any number of
<filename>.k</filename>-files and will create a number of output files
as outlined above. A typical call looks like this:
</para>
<informalexample>
<userinput>kc++ abstr.k rpn.k main.k</userinput>
</informalexample>
<para>When used together with other tools (see
<xref linkend="sec:yacc"/>) a makefile is helpful.
Be aware, though, that every source file may influence every
generated file (because of the code redirections). Thus multiple destination
files depend on multiple source files. That means the makefile becomes more
complicated in order to handle these dependencies. That is why an example makefile
is provided in appendix (see <xref linkend="app:make"/>). It is sufficient
for the <acronym>RPN</acronym> example and
may easily be adapted for many more.</para>
<sect1
id="sec:options"><title>Options<indexterm id="idx:options"
class="startofrange"><primary>options</primary></indexterm></title>
<para>&kpp; recognizes a number of command line options which affect the
process of parsing and code generation, some rather drastically. Table
<xref linkend="tab:options"/> presents, in alphabetical order,
all available options and their explanation. In most environments, two
forms are provided, short and <acronym>GNU</acronym> style long options.
</para>
<para>Suppose you do not need CSGIO input/output, but want to interface with
your favourite compiler compiler, you might use:</para>
<informalexample>
<userinput>kc++ --no-csgio --yystype abstr.k rpn.k main.k</userinput>
</informalexample>
<para>Some vital options can be specified directly in &kpp; using the
keyword <constant>%option</constant>. Such specified options take higher
priority than command line options and thus override them.
Table <xref linkend="tab:vitaloptions"/> lists them in alphabetical order.
They behave like their command line counterparts.
A line like this could be specified in a &kpp; file:</para>
<informalexample>
<programlisting>
%option yystype smart-pointer
</programlisting>
</informalexample>
<table id="tab:options"><title>Command line options</title>
<tgroup cols='3' align='left' colsep='1' rowsep='1'>
<?latex-table-type tabularx?>
<?latex-table-option {\textwidth}?>
<?latex-table-head llX?>
<colspec colname='c1'/>
<colspec colname='c2'/>
<colspec colname='c3'/>
<thead>
<row>
<entry></entry>
<entry>option</entry>
<entry>explanation</entry>
</row>
</thead>
<tbody>
<!-- Kimwitu++ Features -->
<row>
<entry>–c</entry>
<entry>––no–csgio</entry>
<entry>do not generate phylum read/write functions
(<filename>csgiok.{h,cc}</filename>)
</entry>
</row>
<row>
<entry>–r</entry>
<entry>––no–rewrite</entry>
<entry>do not generate code for rewrite rules
(<filename>rk.{h,cc}</filename>)</entry>
</row>
<row>
<entry>–u</entry>
<entry>––no–unparse</entry>
<entry>do not generate code for unparse rules
(<filename>unpk.{h,cc}</filename>)</entry>
</row>
<row>
<entry>–d</entry>
<entry>––no–printdot</entry>
<entry>no fprintdot functions are generated</entry>
</row>
<row>
<entry>–t</entry>
<entry>––no–hashtables</entry>
<entry>do not generate code for hashtable operations
</entry>
</row>
<!-- C++ Compiler Options -->
<row>
<entry>–n</entry>
<entry>––covariant=C</entry>
<entry>use covariant return types: y|n|p (yes, no or generate both
and decide per preprocessor macro
<constant>NO_COVARIANT_RETURN</constant>)</entry>
</row>
<row>
<entry></entry>
<entry>––stdafx[=FILE]</entry>
<entry>generate include for Microsoft precompiled header files
(default <filename>stdafx.h</filename>)</entry>
</row>
<row>
<entry>–e</entry>
<entry>––dllexport=STRING</entry>
<entry>generates string between keyword class and the
class name of all operators and phyla</entry>
</row>
<row>
<entry>–m</entry>
<entry>––smart–pointer</entry>
<entry>generates code for smart pointers (reference counting)</entry>
</row>
<row>
<entry>–w</entry>
<entry>––weak–pointer</entry>
<entry>generates code for weak pointers (implies smart pointers)</entry>
</row>
<!-- Files -->
<row>
<entry>–s</entry>
<entry>––suffix=EXT</entry>
<entry>extension for generated source files (default
<filename>.cc</filename>)</entry>
</row>
<row>
<entry>–f</entry>
<entry>––file–prefix=PREF</entry>
<entry>prefix all generated files</entry>
</row>
<row>
<entry>–o</entry>
<entry>––overwrite</entry>
<entry>always write generated files even if not changed</entry>
</row>
<row>
<entry>–b</entry>
<entry>––yystype[=FILE]</entry>
<entry>generate file (default <filename>yystype.h</filename>)
containing <classname>YYSTYPE</classname>, for &yacc; and &bison;
</entry>
</row>
<row>
<entry>–y</entry>
<entry>––yxxunion</entry>
<entry>generate file <filename>yxx_union.h</filename>)
for use with for <application>Yacc++</application>.
</entry>
</row>
<!-- Advanced -->
<row>
<entry>–l</entry>
<entry>––no–linedirec</entry>
<entry>omit the line directives (<constant>#line</constant>)
altogether</entry>
</row>
<row>
<entry />
<entry>––comment–line</entry>
<entry>change line directives to mere comments</entry>
</row>
<row>
<entry />
<entry>––dir–line</entry>
<entry>prepends the current working directory to the file name
in line directives</entry>
</row>
<row>
<entry>–p</entry>
<entry>––pipe=CMD</entry>
<entry>process all files while piping them through CMD</entry>
</row>
<!-- Other -->
<row>
<entry>–M</entry>
<entry>––msg–format=PAT</entry>
<entry><?latex \raggedright ?>specifies format of (error) messages, PAT can contain:
<?latex \linebreak ?>
<userinput>%p</userinput> (program name),
<userinput>%s</userinput> (severity),
<userinput>%f</userinput> (file name),
<?latex \linebreak ?>
<userinput>%d</userinput> (current working directory),
<userinput>%l</userinput> (line number),
<userinput>%c</userinput> (column);
<?latex \linebreak ?>
the actual message is appended</entry>
</row>
<row>
<entry>–q</entry>
<entry>––quiet</entry>
<entry>quiet operation (is default)</entry>
</row>
<row>
<entry>–v</entry>
<entry>––verbose</entry>
<entry>print additional status information while processing</entry>
</row>
<row>
<entry>–h</entry>
<entry>––help</entry>
<entry>display the help and exit</entry>
</row>
<row>
<entry>–V</entry>
<entry>––version</entry>
<entry>output version information and exit</entry>
</row>
</tbody>
</tgroup>
</table>
<table id="tab:vitaloptions"><title>Built-in options</title>
<tgroup cols='1' align='left' colsep='1' rowsep='1'>
<?latex-table-type tabularx?>
<?latex-table-option {\textwidth}?>
<?latex-table-head X?>
<colspec colname='c1'/>
<tbody>
<row><entry>no–csgio</entry></row>
<row><entry>no–hashtables</entry></row>
<row><entry>no–printdot</entry></row>
<row><entry>no–rewrite</entry></row>
<row><entry>no–unparse</entry></row>
<row><entry>smart–pointer</entry></row>
<row><entry>weak–pointer</entry></row>
<row><entry>yystype</entry></row>
</tbody>
</tgroup>
</table>
<indexterm class="endofrange" startref="idx:options"/>
</sect1>
<sect1 id="sec:yacc"><title>&yacc;/&bison;</title>
<para>Interfacing with a compiler generator is useful when a tree should be
build from some kind of input. &kpp; provides the
<constant>yystype</constant>-option (see <xref linkend="sec:options"/>)
which causes the generation of a header file needed by &yacc; to
cooperate. For
every token found, the desired &kpp; operator is called to create a term.
If <application>lex/flex</application> is used too, &yacc; has to be
run with the option which causes the generation of an other header file
needed
by <application>lex/flex</application> (<userinput>–d</userinput>
for &bison;). Appropriate files for the example can be found in appendix
<xref linkend="app:rpn"/>. The makefile uses implicit rules for
<application>flex</application> and &bison;.</para>
</sect1>
</chapter>
<!-- vim:set sw=2 ts=8 tw=80: -->