next up previous
Next: Design Pattern: Translator Up: The Translator Pattern Previous: The Translator Pattern

   
Introduction

Many operations on data structures can be viewed as homomorphisms, that is, as structure preserving mappings from one domain into another. For instance, compilers typically map the abstract syntax of the source language into a specific machine code language1. Other kinds of abstract interpretations (e.g., pretty-printing and type-checking) should be expressed as homomorphisms between source and target domain as well. The reason for this recommendation can be explained by means of an equation that holds, if a homomorphic relationship between two structures exists:

 \begin{displaymath}
\phi(op(a, b)) = op'(\phi(a), \phi(b))
\end{displaymath} (1)

An interpretation $\phi$ on an operation op (from a source domain) with subcomponents a and b is defined as a new operation op' (from a target domain) whose subcomponents are determined by again applying $\phi$ to aand b [15]. Applied to compilation this looks like:
compile(assign(lhs, rhs)) =
store(compile(lhs), compile(rhs))
First of all, the above equation depicts a general way of shifting the interpretation from operators down to operands. The strictly ``top-down'' recursive nature of this translation process should be recognizable for users of an object-oriented design. Furthermore, the right hand side of equation 1 has a structure that allows us to account for incremental modifications to the source structure. Consider a change made to the left-hand-side (lhs) of assign. There is no need to rebuild the whole result term. One simply has to apply compile to the changed lhs and plug the result into the first operand of store.

A homomorphic translation is allowed to perform a non-injective mapping, i.e., different elements of the source domain may be mapped onto the same element in the target domain. For instance, an initialization statement for a variable could be translated to a store instruction as well. In the target domain (machine language) there is no way to tell which type in the source domain caused the generation of a store (see section 2.7 Separation for further homomorphic simplifications).

Subsequently, we describe a general approach for homomorphic translations in the form of a design pattern [4]. The Translator pattern joins four aspects:

1.
Homomorphic translations
2.
Separation of translation and semantics
3.
Potential incremental translations
4.
External polymorphism.

The last point is of technical nature but will immediately be explained within the core pattern description as it substantially influences the pattern's structure. We already elaborated on point one, i.e., assigning a meaning to a recursive structure in terms of a similarly structured recursive meaning. Point two refers to the fact that this recursive meaning is represented by an explicit intermediate data structure. Thus, the final semantics of the translation is given by a function on the intermediate data structure. This aspect, as well as point three, will be discussed in the pattern's consequences (section 2.7).


next up previous
Next: Design Pattern: Translator Up: The Translator Pattern Previous: The Translator Pattern
Thomas Kuehne
1998-07-06