• No results found

Flow Graph Construction

4.6 Program Graphs

4.6.2 Flow Graph Construction

Although in this chapter, the focus is on defining the actual execution semantics, we will briefly give some insight in how pgs are constructed from fasgs by applying the rules in taal-flow (recall Fig. 4.1), and discuss some of the important characteristics of this process. First we describe the general principle on which this process is based, after which we will discuss some actual rules. An overview of all the flow graph construction rules is given in Appendix C.

Eventually, the control flow semantics of all flow elements must have been constructed. The generation of control flow graphs can be done in a top-down or

bottom-up fashion with respect to the abstract syntax graph. We have specified

the graph production rules to generate control flow in a top-down fashion. This makes the specification of the rules simpler and results in more intuitive rules, for reasons that are similar to why we have chosen to have a separate control flow generation phase.

Flow graphs are constructed at three distinct contexts, as discussed above. Constructing flow graphs in a top-down fashion is achieved by specifying that every flow element triggers the construction of the flow semantics of its sub-flow elements, starting from the context nodes. The actual “trigger” is represented by a special edge labelled flowIn. In some cases, for example for the WhileStat, we need an intermediate flow element which serves as a temporary bridge be- tween syntax elements for which insufficient information is locally available to determine the correct flow of control. Such a temporary bridge is formed by a node labelled FlowTmp. When also specifying the structure of flow graphs dur- ing construction, the meta-model from Fig. 4.10 should be extended with the above mentioned elements, as shown in Fig. 4.14. In the following paragraphs we will briefly discuss some flow graph construction rules.

Chapter 4. Semantics Through Graph Transformations

FlowElement

FlowTmp

-flowIn 0..1

Figure 4.14: Extension to the meta-model from Fig. 4.10

Program. The construction of the Program flow graph starts with application of the rule depicted in Fig. 4.15(a). This rule specifies that if the only Pro- gram-node of a Taal program has no outgoing flowIn-edge and no outgoing flowNext-edge, the flow graph construction process has not yet started nor fin- ished, respectively. In that case, the top-down flow graph construction process is started by creating a flowIn-edge to the ExpStat reached by the startExp-edge, and a flowNext-edge in the reverse direction. The created flowIn-edge now trig- gers the rule that defines the control flow semantics of the ExpStat. This rule is depicted in Fig. 4.15(b). This rule also clearly indicates how flow graphs are constructed using a top-down approach.

(a) Program. (b) ExpStat.

Figure 4.15: Flow graph construction rules (part I).

Object Types. The flow graph of an ObjectType consists of the attribute decla- rations and their initial expressions. When an ObjectType is instantiated, the order in which its attributes are initialized reflects the order in which they ap- pear in the original program. The rule that initializes the flow graph creation of an ObjectType-instance, depicted in Fig. 4.16(a), is very similar to the one for a

4.6 Program Graphs

Program-instance. An application of the ObjectType-rule triggers the creation of the control flow semantics of an attribute declaration attached to the matched ObjectType-instance, as represented by a VarDecl-instance. Again, the rule for VarDeclflow elements, depicted in Fig. 4.16(b), obeys the top-down approach by “passing through” the flowIn-edge to the Expression representing the initial ex- pression of this attribute declaration. Note that this rule explicitly requires the existence of an initial expression for every declared attribute. The rule shown in Fig. 4.16(c) specifies that for LiteralExp-instances, the flow graph construction process terminates, since these are considered the leaves in the syntax graph with respect to the control flow semantics of Taal. That is, when constructing the control flow semantics of a LiteralExp-instance, the flowIn-edge is replaced by a flowNext-edge and no new flowIn-edge is created.

(a) ObjectType. (b) VarDecl. (c) LiteralExp.

Figure 4.16: Flow graph construction rules (part II).

While Statement. In order to give some insight in how we deal with cases in which the flow of control may branch, we discuss the rule that defines the con- trol flow semantics of the WhileStat. The rule is depicted in Fig. 4.17. Before the WhileStat itself will be simulated, its condition must first be evaluated. A straightforward way to achieve this would be to redirect the flowIn-edge to the Expression pointed to by the condition-edge. The problem now arises that the condition must also be reevaluated whenever the body of the WhileStat has been executed. Solving this in the usual way would mean to also create a flowIn-edge from the body-Statement of the WhileStat to its condition. This would then result in the conditional Expression having two incoming flowIn- edges. However, a flow element with two incoming flowIn-edges gives rise to two matching of the corresponding flow graph construction rule. To ensure that the conditional expression has exactly one incoming flowIn-edge, we in- troduce a temporary FlowTmp node. The syntax elements after which control should flow to the Expression, now first point to the FlowTmp node with usual

Chapter 4. Semantics Through Graph Transformations

flowNext-edges. As soon as the outgoing flowIn-edge of the FlowTmp nodes has been replaced by a flowNext-edge, the FlowTmp node will be merged with its flowNext-successor, thereby ensuring that all its incoming successor-edges point to the proper syntax element. A similar issue arises for the body of the While- Stat. When the condition of the WhileStat evaluates to true, control must flow along the flowTrue-edge, triggering the simulation of the body of the WhileStat. Triggering the flow graph construction of the body of the WhileStat, however, requires corresponding Statement to have an incoming flowIn-edge. Again, we introduce a FlowTmp node as temporary bridge between the flowTrue-edge that will eventually point to the first syntax element of the body and the flowIn-edge that triggers the body’s flow graph construction process. Finally, note that the flowNext-edge from the WhileStat to its “next” flow element is replaced by a flowFalse-edge.

Figure 4.17: Flow graph construction rules (part III).

Connectedness of Flow Graphs

Although one possibly expects that program execution is modelled by one sin- gle flow graph, a PG contains several flow graphs at the different contexts. The different flow graphs are not directly connected to each other. They will be se- mantically connected to each other when simulating the program. For instance, the Program flow graph is connected to an ObjectType flow graph by executing a CreateExp expression; the Program flow graph will also be connected to an OperImplflow graph, when a specific operation of the instantiated ObjectType is called. OperImpl flow graphs can also be connected to each other. This occurs when one OperImpl flow graph contains a method call to another operation (po- tentially to itself in a recursive fashion). The connection between flow graphs will be discussed in more detail in Section 4.7.3.

4.6 Program Graphs

Confluence and Termination

We have specified a set of flow graph construction rules, in the sequel referred to as taal-flow, that properly enriches the fasg of any Taal program with flow graphs, thus resulting in a Program Graph (pg). Since each Taal pro- gram should correspond to exactly one pg, we must guarantee that the graph production system consisting of the the set taal-flow and an arbitrary fasg

terminates and is confluent.

Essentially, in MDA [143] terminology, the transformation of an fasg of a Taalprogram into the corresponding pg can be interpreted as a model trans-

formation. Typically, a model transformation is defined by specifying how every

language construct in the source language translates to a language construct in the target language. When all instances of the source language constructs have been properly translated, the model transformation has finished and the result is often a unique model of the target language.

Although we have not formally proven termination and confluence of taal- flow(when applied to an arbitrary fasg), we will now intuitively discuss why we are confident that this is indeed the case. Let us first get convinced of the fact that taal-flow is confluent. If we can prove that every pair of simul- taneous rule applications, i.e., rule applications sharing their host graph, are

local confluent, we may conclude (global) confluence of the whole graph trans-

formation system, due to standard theory on rewrite systems (see, e.g., [173]). As mentioned above, flow graphs are constructed at different contexts. More importantly, those individual flow graphs are mutually disconnected. From this we may conclude that the construction of the individual flow graphs are inde- pendent of each other. That is, any pair of rule applications involved in the construction of distinct flow graphs are local confluent. The next step is to consider rule applications that together construct a single flow graph. Due to the fact that flow graphs are constructed in a top-down fashion, the number of flowIn-edges typically determine the number of rule applications. Initially, there are no flowIn-edges. The rules for each of the context nodes introduce flowIn- edges. Most of the rules “pass through” this trigger down the syntax graph, thereby triggering a single successive rule application. Examples of this have been shown in Fig. 4.15(b) and Fig. 4.16(b). The control flow semantics of some Taalfeatures, however, are slightly more complex since such features consists of multiple sub-components. An example of such a feature is the WhileStat of which the flow graph construction rule has been shown in Fig. 4.17. An ap- plication of this rule introduces two flowIn-edges, one for each sub-component, namely its condition and its body. Since both sub-components correspond to

Chapter 4. Semantics Through Graph Transformations

syntactically disjoint parts of the program (and therefore involve disjoint parts of the fasg), the rule applications that construct the sub-flow graphs for the WhileStat’s condition and body are independent. Summarizing, since all pairs of simultaneous applications of rules in taal-flow are local confluent, we may conclude that any graph transformation system in which taal-flow is applied to an arbitrary fasg, is confluent.

Argumenting why applying taal-flow to an arbitrary fasg terminates, is a bit more straightforward. There are at least two ways to do this. Since the flow graph construction process propagates in a top-down fashion with respect to the syntax graph, the process has finished if all the leaves of the syntax graph have been processed. The fact that every Taal program is represented by a finite fasg then indicates that the flow graph construction process terminates somewhen. Alternatively, we could keep track of the number, say n, of syntax elements that have not yet been processed. Obviously, from the start all syntax elements (which are finitely many, suppose N ) still have to be processed, i.e., n = N . When n = 0, all syntax elements have been processed and the flow graph construction has finished. Since every application of a rule in taal-flow construct the local flow graph for the syntax element under transformation, in the target state the value of n has decreased by one. We may therefore conclude that it takes finitely many steps to fully construct all flow graphs and thus the corresponding pg. Stated differently, the pg construction process terminates.

4.6.3

The Flower and Vase Example

Applying taal-flow to the graph representing the fasg of the example from Listing 4.2 produces a graph transition system in which every path ends in the same final state (due to the fact that taal-flow is confluent and terminates), which represents the graph modelling the pg. Since the rule applications cre- ating flow graph elements for different flow graphs do not interfere with each other, they can be interleaved in any possible order. As mentioned above, they constitute a globally confluent graph transition system, which intuitively means that all paths will finally reach the same state, which in our case happens to be a final state in which no rule is applicable anymore. This state represent the pg of the program to be simulated. Due to taal-flow being confluent it suffices to execute only a single sequence instead of generating the entire graph transition system.

Fig. 4.18 again shows the fasg of the Flower type declaration with additional control flow edges that have been created during the control flow construction process (compare with Fig. 4.9). In this figure we can clearly see that during