A specification as described in the previous section is translated by code selector description translator (NONA) into code selector description (CS) interface and implementation files having the same names as one of specification file and correspondingly suffixes `.h' and `.c' for C or `.cpp' for C++ (see option `-c++').
C interface file of CS consists of the following definitions of generated type and functions:
#define CS_NODE struct IR_node_struct *
#define CS_TYPE CS_node
typedef CS_NODE CS_node;
`CS_cover CS_find_cover (CS_node node)'
makes the first bottom up pass on directed acyclic graph given
by its node and finds a minimal cost cover for each
nonterminal. The minimal cost cover is returned. If error
occurs during the pass then macro `CS_ERROR' (see below) is
evaluated. For example, the cause of error may be meeting
undeclared terminal code. During building cover, each
directed acyclic graph (DAG) node is visited only once.
`int CS_it_is_axiom (CS_cover cover, int nonterminal)'
returns 1 if there is a minimal cost cover for given
nonterminal in given cover, 0 otherwise.
`CS_TYPE CS_traverse_cover (CS_cover cover, int nonterminal)'
makes the second bottom up, left to right pass and fulfills
actions corresponding a minimal cost cover for given
nonterminal in cover found by call of function
`CS_find_cover'. A minimal cost cover for given nonterminal
must be in given cover before the function call. This
condition can be checked by function `CS_it_is_axiom'. The
function returns attribute of given nonterminal after
fulfilling the actions. Remember that action (and attribute
evaluation) associated with tree pattern is fulfilled only
once for each occurrence of the tree pattern in given cover of
a directed acyclic graph.
`void CS_delete_cover (CS_cover cover)'
frees memory allocated to `cover' which was to be created by
call of function `CS_find_cover'. Of course this cover can
not be used in function `CS_traverse_cover' after that. The
memory is freed in the reverse order therefore allocation
macros (see below) can use stack strategy of the memory
allocation.
`void CS_start (void)'
is to be called before any work with code selector
description. The function initiates code selector description
storage management (see below).
`void CS_finish (void)'
is to be last. The function finishes code selector description
storage management. Therefore only function `CS_start' can be
called after this function call.C++ interface file (see option -c++) of CS consists of the following definitions of generated type and functions:
#define CS_NODE struct IR_node_struct *
#define CS_TYPE CS_node
typedef CS_NODE CS_node;
`CS_cover CS_find_cover (CS_node node)'
makes the first bottom up pass on directed acyclic graph
given by its node and finds a minimal cost cover for each
nonterminal. The minimal cost cover is returned. If
error occurs during the pass then macro `CS_ERROR' (see
below) is evaluated. For example, the cause of error may
be meeting undeclared terminal code. During building
cover, each directed acyclic graph (DAG) node is visited
only once.
`void CS_start (void)'
is to be called before any work with code selector
description. The function initiates code selector
description storage management (see below).
`void CS_finish (void)'
is to be last. The function finishes code selector
description storage management. Therefore only function
`CS_start' can be called after this function call.
`int CS_it_is_axiom (int nonterminal)'
returns 1 if there is a minimal cost cover for given
nonterminal in given cover, 0 otherwise.
`CS_TYPE CS_traverse_cover (int nonterminal)'
makes the second bottom up, left to right pass and
fulfills actions corresponding a minimal cost cover for
given nonterminal in cover found by call of function
`CS_find_cover'. A minimal cost cover for given
nonterminal must be in given cover before the function
call. This condition can be checked by function
`CS_it_is_axiom'. The function returns attribute of given
nonterminal after fulfilling the actions. Remember that
action (and attribute evaluation) associated with tree
pattern is fulfilled only once for each occurrence of the
tree pattern in given cover of a directed acyclic graph.
`void CS_delete_cover (void)'
frees memory allocated to the cover which was to be
created by call of function `CS_find_cover'. Of course
the function `CS_traverse_cover' can not be used after
that (because the object is removed). The memory is freed
in the reverse order therefore allocation macros (see
below) can use stack strategy of the memory allocation.CS implementation file uses the following macros generated by NONA. These macros can be redefined (in any C/C++ declaration section).
`CS_OPERAND_1_OF_1(node)',
`CS_OPERAND_1_OF_2(node)',
`CS_OPERAND_2_OF_2(node)', and so on.
These macros define the structure of the low level internal
representation for which is needed to build minimal cost
cover. The structure must be a directed acyclic graph (DAG).
Macro of kind `CS_OPERAND_k_OF_n' defines k-th arc from the
DAG node given as the macro argument which has `n' such arcs.
Let us consider tree pattern
`integer_plus (register, const8)'
To access to children of node represented by terminal
`integer_plus' the macros `CS_OPERAND_1_OF_2' and
`CS_OPERAND_2_OF_2' will be used.
`CS_STATE(node)',
`CS_SET_STATE(node, state)'
define access to the a DAG node field. The field is used by
tree pattern matchers. The type of this field must be any
pointer type. Macro `CS_STATE' has one argument of type
`CS_node'. Macro `CS_SET_STATE' has two arguments of types
correspondingly `CS_node' and `void *'.
#define CS_OPERATION(node) IR_NODE_MODE (node)
#define CS_OPERAND_1_OF_1(node) IR_operand (node)
#define CS_OPERAND_1_OF_2(node) IR_operand_1 (node)
#define CS_OPERAND_2_OF_2(node) IR_operand_2 (node)
#define CS_OPERAND_1_OF_3(node) IR_operand_1 (node)
#define CS_OPERAND_2_OF_3(node) IR_operand_2 (node)
#define CS_OPERAND_3_OF_3(node) IR_operand_3 (node)
...
#define CS_STATE(node) IR_state (node)
#define CS_SET_STATE(node, state) IR_set_state (node, state)
#define CS_ATTRIBUTE(node) (node)
#define CS_ERROR(str) fprintf (stderr, "%s\012", str)
NONA completely automatically generates macros of storage management for the cover. Usually, the user does not have to care about it. The predefined storage management uses C standard functions for global storage with free lists. The user can create own storage manager by redefinition of one or more the following macros and placing them in a C declaration section. But the user should know that all functions generated by NONA believe that the storage can not change its place after the allocation.
#define CS_START_ALLOC()
#define CS_FINISH_ALLOC()
#define CS_ALLOC(ptr, size, ptr_type) \
((ptr) = (ptr_type) malloc (size))
#define CS_FREE(ptr, size) free (ptr)