Next Previous Contents

3. Generated code

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++').

3.1 C Interface objects

C interface file of CS consists of the following definitions of generated type and functions:

  1. There is constant with nonterminal name and prefix `CSNT_' for each nonterminal. `CSNT' is abbreviation of code selector description nonterminal. The constants are defined as macros (with the aid of C preprocessor directive `#define'). The constants are used as parameter of functions `CS_it_is_axiom' and `CS_traverse_cover' (see below).
  2. Macro `CS_NODE' must represent type of node of low level internal representation. This macro can be redefined (only in a C declaration section which starts with `%import'). By default this macro is defined as follows:
               #define CS_NODE           struct IR_node_struct *
    
  3. Macro `CS_TYPE' defines type of terminal and nonterminal attributes. This macro can not be redefined if the corresponding code selector description has a construction `%union' which already describes terminal and nonterminal attribute types because in this case the default macro definition is absent. By default this macro is defined as follows:
               #define CS_TYPE           CS_node
    
  4. Type `CS_node' is defined as follows:
               typedef CS_NODE CS_node;
    
  5. Type `CS_cover' describes a minimal cost cover. The values of this types are created by function `CS_find_cover' and deleted by function `CS_delete_cover'.
  6. Function
            `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.
  7. Function
            `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.
  8. Function
            `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.
  9. Function
            `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.
  10. Function
            `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).
  11. Function
            `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.

3.2 C++ Interface objects

C++ interface file (see option -c++) of CS consists of the following definitions of generated type and functions:

  1. There is constant with nonterminal name and prefix `CSNT_' for each nonterminal. `CSNT' is abbreviation of code selector description nonterminal. The constants are defined as macros (with the aid of C preprocessor directive `#define'). The constants are used as parameter of functions `CS_it_is_axiom' and `CS_traverse_cover' (see below).
  2. Macro `CS_NODE' must represent type of node of low level internal representation. This macro can be redefined (only in a C declaration section which starts with `%import'). By default this macro is defined as follows:
               #define CS_NODE           struct IR_node_struct *
    
  3. Macro `CS_TYPE' defines type of terminal and nonterminal attributes. This macro can not be redefined if the corresponding code selector description has a construction `%union' which already describes terminal and nonterminal attribute types because in this case the default macro definition is absent. By default this macro is defined as follows:
               #define CS_TYPE           CS_node
    
  4. Type `CS_node' is defined as follows:
               typedef CS_NODE CS_node;
    
  5. Type `CS_cover' describes a minimal cost cover. It is pointer objects of a class. The class has not public constructors and desctructors. The class objects can be created only by function `CS_find_cover' and can be deleted by function `CS_traverse_cover'. This class has the following friend functions:
    1. Function
                  `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.
    2. Function
                  `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).
    3. Function
                  `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.
    This class has also the following class functions:
    1. Function
                  `int CS_it_is_axiom (int nonterminal)'
          
      
      returns 1 if there is a minimal cost cover for given nonterminal in given cover, 0 otherwise.
    2. Function
                  `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.
    3. Function
                  `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.

3.3 Implementation file macros

CS implementation file uses the following macros generated by NONA. These macros can be redefined (in any C/C++ declaration section).

  1. Macro `CS_OPERATION(node)' must return value defined by a constant which represents mode of the low level internal representation node (see description of construction `%term').
  2. Macros
            `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.
  3. Macros
            `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 *'.
  4. Macro `CS_ATTRIBUTE(node)' must return value of type `CS_TYPE'. This value is attribute of the terminal corresponding to given node of low level internal representation. This macro for given terminal may be evaluated several times because the terminal attribute can be in cost or constraint constructions. The value of the macro for the terminal must be l-value (variable in other words) when construction `%union' is present and given terminal is declared with type because in this case the operation `.' of C/C++ language is applyed to the macro value in order to get access to the terminal attribute.
  5. Macro `CS_ERROR(str)' is a reaction on fixing an error by tree pattern matcher. The macro argument is tree pattern matcher message about the error.
By default these macros are defined as follows:
    #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)

3.4 Storage management macros

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.

  1. Macros `CS_START_ALLOC()', `CS_FINISH_ALLOC()' are evaluated in functions correspondingly `CS_start' and `CS_finish' and are to be used to start and finish work with the storage manager.
  2. Macros `CS_ALLOC(ptr, size, ptr_type)', `CS_FREE(ptr, size)' allocate and free storage whose size is given as the second parameter. The first parameter serves to return pointer to memory being allocated or to point to memory being freed.
By default these macros are defined as follows:
    #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)


Next Previous Contents