Presentation is loading. Please wait.

Presentation is loading. Please wait.

3. Annotating the Abstract Syntax Tree ― the Context From: Chapter 3, Modern Compiler Design, by Dick Grun et al.

Similar presentations


Presentation on theme: "3. Annotating the Abstract Syntax Tree ― the Context From: Chapter 3, Modern Compiler Design, by Dick Grun et al."— Presentation transcript:

1 3. Annotating the Abstract Syntax Tree ― the Context From: Chapter 3, Modern Compiler Design, by Dick Grun et al.

2 Annotating the AST`2 Background The lexical analyzer supplies the initial attributes of the terminals in the leaf nodes of the AST. Lexical analysis and parsing together perform the context-free processing of the source program. Context handling is required for two different purposes: –to check context condition imposed by the language specification and –to collect information for semantic processing.

3 Annotating the AST`3 3.1 Attribute grammars The computation required by context handling can be specified inside the CFG that is already being used for parsing; this results in an attribute grammar. The CFG is extended with two features: –For each grammar symbol, S, terminal or non-terminal, zero or more attributes are specified, each with a name and a type, like the fields in a record; these are formal attributes, since, like formal parameters, they consists of a name and a type only. Room for the actual attributes is allocated automatically in each node that is created for S in the AST. The attributes are used to hold information about the semantics attached to that specific node. All nodes in the AST correspond to the same grammar symbol S have the same formal attributes, but their values – the actual attributes – mat differ. ( Another feature is to be continued in the next page… )

4 Annotating the AST`4 3.1 Attribute grammars –With each production rule N  M 1 …M n, a set of computation rules are associated – the attribute evaluation rules – which express some of the attribute values of the LHS N and the members of the RHS M i in terms of other attribute values of these. These evaluation rules also check the context conditions and issue warning and error messages.

5 Annotating the AST`5 3.1 Attribute grammars Requirements to be fulfilled by the attributes: –The attributes of each grammar symbol N are divided into two groups: synthesis attributes and inherited attributes. –The evaluation rules for all production rules of N can count on the values of the inherited attributes of N to be set by the parent node, and have themselves the obligation to set synthesized attributes of N. The division of attributes into synthesized and inherited is not a logical necessity, but it is very useful and is an integral part of all theory about attribute grammars.

6 Annotating the AST`6 3.1 Attribute grammars It is the task of attribute grammar to activate the evaluation rules in such an order as to set all attribute values in a given AST, without using a value before it has been computed. The paradigm of the attribute evaluator is that of a data-flow machine: –A computation is performed only when all the values it depends on have been determined. –Initially, the only attributes that have values belong to the terminal symbols; theses are synthesized attributes and their values directly from the program text. –These synthesized attributes then become accessible to the evaluation rules of their parent nodes, where they allow further computation, both for the synthesized attributes of the parent and for the inherited values of the children of the parent. –The attribute evaluator continues to propagate the values until all attributes have obtained their values. This will happen eventually, provided there is no cycle in the computation.

7 Annotating the AST`7

8 8

9 9 3.1 Attribute grammars Detailed explanations required for Fig. 3.2 1. The execution order of the evaluation rules is not determined by their textual position but rather by the availability of their operands. 2.The non-terminal Defined_identifier is used rather than just Identifier. –An instance of the former only has its name; while –An instance of the latter has in addition to its name, scope information, type, kind, possibly a value, allocating information, etc. 3.The use of Checked type of Constant_definition(Expression.type) rather than just Expression.type.

10 Annotating the AST`10 3.1 Attribute grammars Disagreement on whether the start symbol and terminal symbols are different from other symbol with respect to attributes. –From the original theory as published by Knuth (1968), 1) the start symbol has no inherited attributes, and 2) the terminal symbols has no attributes at all. 1)The AST has a certain semantics, which would emerge as the synthesized attribute of the start symbol; and this semantics was independent of the environment, there was nothing to inherit. 2)Terminal symbols serve syntactic purpose most of the time and then have no semantics.

11 Annotating the AST`11 3.1 Attribute grammars Good reasons to allow both types of attributes to both 1) the start symbol and 2) terminal symbols 1)The start symbol may need inherited attributes to supply, for example, definitions from standard libraries, or details about the machine for which to generate code; and 2)Terminal symbols already have synthesized attributes in the form of their representation.

12 Annotating the AST`12 3.1 Attribute grammars Now we look into means of evaluating the attributes. Problem: –an infinite loop in the computation Normally it is the responsibility of the compiler writer not to write infinite loops, but –when one provides a high-level mechanism, one hopes to be able to give a bit more support. –There is indeed possibly an algorithm for loop detection in attribute grammars. To understand these algorithms, we need to understand the dependency graph.

13 Annotating the AST`13 3.1.1 Dependency graphs It is useful to depict the data flow in a node for a given production rule of non-terminal N by a simple diagram: dependency graph. –The inherited attributes of N are represented by named boxes on the left of the label and synthesized attributes by named boxed on the right. –The diagram consists of two levels, the top depicting the LHS of the grammar rule and the bottom the RHS. –Data flow is indicated by arrows leading from the source attributes to the destination attributes.

14 Annotating the AST`14

15 Annotating the AST`15

16 Annotating the AST`16 3.1.2 Attribute allocation To make the above approach work, we need a system that will –create the AST, –allocate space for the attributes in each node in the tree, –fill the attributes of terminals in the tree with values derived from the representations of the terminals, –execute evaluation rules of nodes to assign values to attributes until no new values can be assigned, and do this in the right order, so that no attribute value will be used before it is available and that each attribute will get a value once, –detect when it cannot do so. Such a system is called an attribute evaluator.

17 Annotating the AST`17

18 Annotating the AST`18 3.1.2 Attribute allocation The naive and most general way of implementing attribute evaluation is just to implement the data-flow machine. We use the following technique: –visit all nodes of the data-flow graph, –performing all possible assignments in each node when visiting it, and –repeat this process until all synthesized attributes of the root have been given a value. An assignment is possible when all attributes needed for the assignment have already given a value. –This algorithm looks wasteful of computer time, but good for educational purposes. 1.Algorithmically possible 2.Easy to implement 3.A good stepping stone to more realistic attribute evaluation

19 Annotating the AST`19 3.1.2 Attribute allocation The above method is an example of dynamic attribute evaluation, since the order in which the attributes are evaluated is determined dynamically, at the run time of compiler. This is opposed to static attribute evaluation, when the order in which the attributes are evaluated is fixed in advance during compiler evaluation.

20 Annotating the AST`20 3.1.2.1 A dynamic attribute evaluator The strength of attribute grammars lie in the fact that they transport information from anywhere in the parse tree to anywhere else, in a controlled way. We use a simple attribute grammar to demonstrate the attribute evaluator.

21 Annotating the AST`21

22 Annotating the AST`22

23 Annotating the AST`23 3.1.2.1 A dynamic attribute evaluator The attribute grammar code in Fig. 3.8 is very heavy and verbose. Practical attribute grammars have abbreviation techniques for these and other repetitive code structures. Digit_Seq(INH base, SYN value)  Digit_Seq(base, value) Digit(base, value) ATTRIBUTE RULES: SET value TO Digit_Seq.value * base + Digit.value; | Digit(base, value)

24 Annotating the AST`24 3.1.2.1 A dynamic attribute evaluator To implement the data-flow machine in the way explained above, we have to visit all nodes of the data dependency graph. Visiting all nodes of a graph usually requires some care to avoid infinite loops, but a simple solution is available in this case since the nodes are also linked in the parse tree, which is loop-free. By visiting all nodes in the parse tree we automatically visit all nodes in the data dependency graph, and we can visit all nodes in the parse tree by traversing it recursively.

25 Annotating the AST`25 3.1.2.1 A dynamic attribute evaluator Now the algorithm at each node is very simple: –try to perform all the assignments in the rules section of that node, –traverse the children, and –when returning from them again try to perform all the assignments in the rule section. The pre-visit assignments propagate inherited attribute values downwards; –the post-visit assignment harvest the synthesized attributes of the children and propagate them upwards.

26 Annotating the AST`26

27 Annotating the AST`27 Input: 567B Output: Evaluate for Number called Number.value = 375

28 Annotating the AST`28 Number value Digit_Seq value base Digit value base Base_Tag base Digit_Seq value base Digit value base Digit_Seq value base Digit value base B 7 6 7 1 1 1 1 2 2 2 2 3 3 3 3

29 Annotating the AST`29 3.1.3 Cycle handling To prevent the attribute evaluator from looping, cycle in the evaluation must be detected. Dynamic cycle detection –the cycle is detected during the evaluation of the attributes in an actual syntax tree; –it shows that there is a cycle in a particular tree. Static cycle detection –looks at the attribute grammar and from it deduces whether any tree that it produces can ever exhibit a cycle: it covers all trees.

30 Annotating the AST`30 3.1.3.1 Dynamic cycle detection A simple way to dynamically detect a cycle in the above data-flow implementation (but inelegant): –if the syntax tree has N attributes and more than N rounds are found to be required for obtaining an answer, there must be a cycle.

31 Annotating the AST`31 3.1.3.2 Static cycle detection First of all, we must know how such a cycle can exist at all. A cycle cannot originate directly from a dependency graph of a production rule P because

32 Annotating the AST`32 3.1.3.2 Static cycle detection For an attribute dependency cycle to exist, –the data flow has to leave the node, –pass through some part of the tree and return to the node, –perhaps repeat this process several times to different parts of the tree and then return to the attribute it started from.

33 Annotating the AST`33 3.1.3.2 Static cycle detection From Fig. 3.17, there are two kinds of dependencies between the attributes of a non-terminal N: –from inherited to synthesized (IS-dependency) –from synthesized to inherited (SI-dependency) The summary of the dependencies between the attributes of a non- terminal can be collected in an IS-SI graph.

34 Annotating the AST`34 3.1.3.2 Static cycle detection The IS-SI graphs are used to find cycles in the attribute dependencies of a grammar. Suppose we are given –the dependency graph for a production rule N  PQ and –the complete IS-SI graphs of children P and Q in it –then –we can obtain the IS-dependencies of N cause by N  PQ by adding the dependencies in the IS-SI graphs of P and Q to the dependency graph of N  PQ and taking the transitive closure of the dependencies.

35 Annotating the AST`35

36 Annotating the AST`36 3.1.3.2 Static cycle detection If we had all dependency graphs of all production rules in which N is a child, and –the complete IS-SI graphs of all the other non-terminals in those production rules, –we could in the same manner as above detect any cycle that runs through a tree of which N is a child, and –obtain all SI-graphs of N. Together this leads to the IS-SI graph of N and the detection of all cycles involving N.

37 Annotating the AST`37

38 Annotating the AST`38

39 Annotating the AST`39 3.1.3.2 Static cycle detection The data-flow technique described so far enables us to create very general attribute evaluators easily, and the circularity test shown here allows us to make sure that they will not loop. It is, however, felt that this full generality is not always necessary and that there is room for less general but much more efficient attribute evaluation methods. We will cover three levels of simplification: –multi-visit attribute grammars, –L-attributed grammars, and –S-attributed grammars.

40 Annotating the AST`40 3.1.4 Attribute allocation So far we have assumed that the attributes of a node are allocated in that node, like fields in a record. –For simple attributes  integers, pointers, etc.  this id satisfactory, but –for large values, e.g., the environment, this is clearly undesirable. The easiest solution to the environment problem –implementing the routine that updates the environments such that it delivers a pointer to the new environment. Another problem: –many attributes are just copies of other attributes on a higher or lower level in the syntax tree, and that –much information is replicated many times, requiring time for the copying and using up memory.

41 Annotating the AST`41 3.1.5 Multi-visit attribute grammars We have seen a solution to the cyclicity problem for attribute grammars, we turn to their efficiency problems. The dynamic evaluation of attributes exhibits some serious inefficiencies: –values must repeatedly be tested for availability; –the complicated flow of control causes much overhead; and –repeated traversals over the syntax tree may be needed to obtain all desired attribute values.

42 Annotating the AST`42 3.1.5.1 Multi-visits The above problems can be avoided by having a fixed evaluation sequence, –implemented as program code, –for each production rule of each non-terminal N; –this implements a form of static attribute evaluation. The task of such a code sequence is to evaluate the attributes of a node P, which represented production rule N→M 1 M 2 … The attribute values needed to do so can be obtained in two ways: –The code can visit a child C of P to obtain the values of some C’s synthesized attributes while supplying some of C’s inherited values to enable C to compute those synthesized attributes. –It can leave for the parent of P to obtain the values of some of P’s own inherited attributes while supplying some of P’s own synthesized attributes to enable the parent to compute those inherited attributes.

43 Annotating the AST`43 3.1.5.1 Multi-visits Since there is no point in computing an attribute before it is needed, the computation of the required attributes can be placed just before the point at which the flow of control leaves the node for the parent or for a child. So there are basically two kinds of visits: Supply a set of inherited attribute values to a child M i Visit M i Harvest a set of synthesized attribute values supplied by M i Supply a set of synthesized attribute values to parent Visit the parent Harvest a set of inherited attribute values supplied by the parent and This reduces the possibilities for the visiting code of a production rule N→M 1 M 2 …M n to the outline shown in Figure 3.24.

44 Annotating the AST`44

45 Annotating the AST`45 3.1.5.1 Multi-visits This scheme is called multi-visit attribute evaluation: –The flow of control pays multiple visit to each node according to a scheme fixed at compiler generation time. It can be implemented as a tree-walker, which executes the code sequentially and moves the flow of control to the children or the parent as indicated; –It will need a stack to leave to the correct position in the parent. Alternatively, and more usually, multi-visit attribute evaluation is implemented by recursive descent. –Each visit from the parent is then implemented as a separate routine, a visiting routine, which evaluates the appropriate attribute rules and calls the appropriate visit routine of the children. –The ‘leave to parent’ at the end of each visit is implemented as a return statement and the leave stack is accommodated in the return stack.

46 Annotating the AST`46

47 Annotating the AST`47 3.1.5.1 Multi-visits An important observation about the sets IN 1..n and SN 1..n –IN i is associated with the start of the i-th visit by the parent and SN i with the i-th leave to the parent. –The parent of the node N must of course adhere to this interface, but the parent does not know which production rule for N has produced the child it is about to visit. –So the set IN 1..n and SN 1..n must be the same for all production rules for N; they are a property of the non-terminal N rather than of each separate production rule for N. Similarly, all visiting routines for production rules in the grammar that contain non-terminal N in the RHS must call the visiting routines of N in the same order 1..n.

48 Annotating the AST`48 3.1.5.1 Multi-visits To obtain a multi-visit attribute evaluator, we will first show that once we know acceptable IN and SN sets for all non-terminals we can construct a multi-visit attribute evaluator, and we will then see how to obtain such sets.

49 Annotating the AST`49 3.1.5.2 Attribute partitionings The above outline of the multiple visit to a node for a production rule N→M 1 M 2 …partitions the attributes of N into a list of pairs of sets of attributes: (IN 1,SN 1 ), (IN 2,SN 2 ), …, (IN n,SN n ) for what is called an n- visit. –Visit i uses the attributes in IN i, which were set by the parent, visits some children some number of ties in some order, and returns after having set the attributes in SN i. –The sets IN 1..n must contain all inherited attributes of N, and SN 1..n all its synthesized attributes, since each attribute must in the end receives a value some way or another. None of the IN i and SN i can be empty, except IN 1 and perhaps SN n.

50 Annotating the AST`50 3.1.5.2 Attribute partitionings Given an acceptable partitioning (IN i,SN i ) i=1..n, it is relatively simple to generate the corresponding multi-visit attribute evaluator. We now consider –how this can be done, and –at the same time see what properties of an “acceptable” partitioning are.

51 Annotating the AST`51 3.1.5.2 Attribute partitionings The evaluator we are about to construct consists of a set of recursive routines. There are n routines for each production rule P N→M 1 M 2 …for non-terminal N, one for each of the n visits, with n determined by N. –So if there are p production rules for N, there will be a total of p  n visit routines for N. –Assuming that P is the k-th alternative of N, a possible name for the routine for the i-th visit to that alternative might be Visit_i to N alternative k.

52 Annotating the AST`52 3.1.5.2 Attribute partitionings Now discuss how we can determine which visit routines to call in which order inside a visiting routine Visit_i to N alternative k(), based on information gathered during the generation of the routines Visit_h to N() for 1  h  i, and knowledge of IN i. –We therefore skip the remaining details of Sections 3.1.5.2 and the whole Section of 3.1.5.3, but they can be found from pages 222 to 229. –We give the summary of the types of attribute grammars then.

53 Annotating the AST`53 3.1.5.2 Attribute partitionings

54 Annotating the AST`54 3.1.5.3 Ordered attribute grammars

55 Annotating the AST`55 3.1.6 Summary of the types of attribute grammars There are series of restrictions that reduce the most general attribute grammars to ordered attribute grammars. –They increase considerably the algorithmic tractability of the grammars but –Are almost no obstacles to the compiler writer who uses the attribute grammar The first restriction –All synthesized attributes of a production rule and all inherited attribute of its children must get values assigned to them in the production. The second restriction –No tree produced by the grammar may have a cycle in the attribute dependencies. –The test for this property is exponential time in the number of attributes in a non-terminal.

56 Annotating the AST`56 3.1.6 Summary of the types of attribute grammars The third restriction –The grammar is still non-cyclic even if a single IS-SI graph is used per non- terminal rather than an IS-SI graph set. –The test for this property is linear. The fourth restriction –The attributes can be evaluated using the fixed multi-visit scheme. –This leads to multi-visit attribute grammars. (3.1.5.1-2) –Such grammars have a partitioning for the attributes of each non-terminals. –Testing whether an attribute grammar is multi-visit is exponential in the total number of attributes. The fifth restriction –The partitioning is constructed heuristically using the late evaluation criterion. –This leads to ordered attribute grammar. (3.1.5.3) –The test is reduced to O(n 2 ) and O(n ln n).

57 Annotating the AST`57 3.1.6 Summary of the types of attribute grammars Two classes of attribute grammars resulting from far more serious restrictions –L-attributed grammars An inherited attribute of a child of a non-terminal N may depend only on –synthesized attributes of children to the left of it in the production rule of N and on –the inherited attributes of N itself. –S-attribute grammars Can not have inherited attributes at all.

58 Annotating the AST`58 3.2 Manual methods Although attribute grammars are the only means we have at the moment for generating context processing programs automatically, –the more advanced attribute evaluation techniques for them are still in their infancy, and –Much context processing programming is still done at a lower level, by writing code in a traditional language like C or C++. We will give two methods to collect context information from the AST –Symbolic interpretation –Data-flow equations Both start from the AST, –both require more flow-of-control information It is much more convenient to have the flow-of-control available at each node in the form of successor pointers –The control flow graph

59 Annotating the AST`59 3.2.1 Threading the AST The control flow graph can be constructed statically by threading the tree, as follows. –A threading routine exists for each node type; –The threading routine for a node type N gets a pointer to the node to be processed as a parameter, determines which production rule of N describes the node, and calls the threading routines of its children, in a recursive traversal of the AST. –Using this technique, the threading routine for a binary expression could be the following form: PROCEDURE Thread binary expression (Expr node pointer) Thread expression (Expr node pointer.left operand); Thread expression (Expr node pointer.right operand); //link this node to the dynamically last node SET Last node pointer.successor TO Expr node pointer; //make this node the new dynamically last node SET Last node pointer to Expr node pointer;

60 Annotating the AST`60

61 Annotating the AST`61

62 Annotating the AST`62 3.2.1 Threading the AST A complication arises if the flow of control exits in more than one place from the tree below a node. –E.g., the if-statement –Problems and solutions The node corresponding to the run-time then/else decision has two successors rather than one. –Sol: Just storing two successor pointers in the if-node, make the if-node different from other nodes When we reach the node following the entire if-statement, its address must be recorded in the last nodes of both the then-part and the else-part. –Sol: Construct a special join node to merge the diverging flow of control Fig. 3-38:Sample threading routine for if-statement Figs.3.39 and 40: AST before and after threading

63 Annotating the AST`63

64 Annotating the AST`64

65 Annotating the AST`65 3.2.1 Threading the AST Threading the AST can also be expressed by means of an attribute grammar.

66 Annotating the AST`66 3.2.1 Threading the AST It is often useful to implement the control flow graph as a doubly- linked graph.

67 Annotating the AST`67 3.2.1 Threading the AST We have seen means to construct the complete control flow graph of a program, we are in a position to discuss two manual methods of context handling: –Symbolic interpretation, which tries too mimic the behavior of the program at run time in order to collect context information –Data-flow equations, which is semi-automated restricted form of symbolic interpretation.

68 Annotating the AST`68 3.2.2 Symbolic interpretation The run-time behavior of the code at each node is determined by values of the variables it finds at run time upon entering the code, and the behavior determines these values again upon leaving the node. Much contextual information about variables can be deduced statically by simulating this run-time process at compile time in a technique called symbolic interpretation or simulation on the stack. The technique of symbolic interpretation –A stack representation is attached to each arrow in the control flow graph. –It holds an entry for each identifier visible at that point in the program. –We are mostly interested in variables and constants. –The entry summarizes all compile-time information we have about the variable or the constant. –Such information could, for example, tell whether it has been initialized or not, or even what its value is. –The stack representation at the entry to a node and at its exit are connected by the semantics of that node.

69 Annotating the AST`69

70 Annotating the AST`70

71 Annotating the AST`71 3.2.2 Symbolic interpretation It will be clear that many properties can be propagated in this way through the control flow graph, and that the information obtained can be very useful both for doing context checks and for doing optimization. –In fact, this is how some implementation of the C context checking program lint operates. Using two variants of symbolic interpretation to check for uninitialized variables –Simple symbolic interpretation Works in one scan from routine entrance to routine exit Applies to structured programs and specific properties only –Full symbolic interpretation Works in the presence of any kind of flow of control and for wide range of properties.

72 Annotating the AST`72 3.2.2.1 Simple symbolic interpretation To check for the use of uninitialized variables using simple symbolic interpretation, we make a compile-time representation of the local stack of a routine and follow this representation through the entire routine. Such a representation can be implemented conveniently as a linked list of names and properties pairs, a ‘property list’. The list starts off as empty, or, –if there are parameters, Initialized for IN and INOUT parameters and Uninitialized for OUT parameters We maintain a return list, in which we combine the stack representation as found at return statements and routine exit. We then follow the arrows in the control flow graph, all the while updating our list. –The precise actions required at each node type depend on the semantics of the source language. –We therefore indicate them briefly.

73 Annotating the AST`73 3.2.2.1 Simple symbolic interpretation When a declaration is met –The declared name is added to the list, with the appropriate status, Initialized and Uninitialized. When the flow of control splits, e.g., if-statement –One copy of the original list is used to go through the then-part; –Another is for the then-part; and –Merging is made at the end-if node. –Merging is trivial, except that a variable obtained a value in one branch but not in the other. In this case: the status of the variable is made May be initialized. When an assignment is met –The destination variable is set to Initialized, after processing the source expression first, because ….

74 Annotating the AST`74 3.2.2.1 Simple symbolic interpretation When the value of a variable is used, usually in an expression, –Its status is checked An error message is given if it is not Initialized A warning message is given if it is May be initialized When a node describing a routine call is met –Need not do anything at all in principle –If it has IN and/or INOUT parameters, treat them as if they were used in an expression –If it has any IONOUT and OUT parameters, treat them as if they were used in an assignment When a for-statement is met

75 Annotating the AST`75

76 Annotating the AST`76 3.2.2.1 Simple symbolic interpretation When we find an exit-loop statement, … When we find a return statement, … When we reach the end node of a routine, … If the bounds in for-statement are constants, the loop will be performed at least once. –The merging of the original list and the exit list must not perform to avoid inappropriate messages. –The same applies to the infinite loops in C for(;;)… while(1)…

77 Annotating the AST`77 3.2.2.1 Simple symbolic interpretation Once we have a system of symbolic interpretation in place in our compiler, we can easily extend it to fit special requirements of and possibilities offered by the source language. 1.Do the same thing to see if a variable, constant, field selector, etc. is used at all. 2.Replace the status Initialized by the value, the range or even the set of values the variable may hold, a technique called constant propagation. Problem occurs when implementing constant propagation.

78 Annotating the AST`78 3.2.2.1 Simple symbolic interpretation Requirements for simple symbolic interpretation to work 1.The program must consist of flow-of-control structures with one entry point and one exit point only. 2.The value of the property must form a lattice, which means that the values can be ordered in a sequence 1.. n such that there is no operation that will transform j into i with i  j; we will write i  j for all i  j. 3.The result of merging two values must be at least as large as the smaller of the two. 4.An action taken on i in a given situation must make any action taken on j in that same situation superfluous, for i  j. Explanations of the requirements are given further in the following...

79 Annotating the AST`79 3.2.2.1 Simple symbolic interpretation The first requirement allows each control structure to be treated in isolation, –with the property being analyzed well-defined at the entry point of the structure and at its exit. The other three requirements allow us to ignore the jump back to the beginning of looping control structures. –We call the value of the property at the entrance of the loop body in and that at the exit is out. –Req. 2 guarantees that in  out. –Req. 3 guarantees that when we merge the out from the end of the first round through the loop back into in to obtain a value new at the start of a second round, then new  in. To take the second loop, we would undertake actions based on new. However, Req. 4 says that all these actions are superfluous. Explanations of the requirements are given further in the following...

80 Annotating the AST`80 3.2.2.1 Simple symbolic interpretation The initialization property with values 1 = Uninitialized, 2 = May be initialized, and 1 = Initialized, fulfills these requirements, since –the initialization status can only progress from left to right over these values and –the actions on Uninitialized (error message) render those on May be initialized superfluous (warning message), which again supersedes those on Initialized (none). If these four requirements are not fulfilled, it is necessary to perform full symbolic interpretation.

81 Annotating the AST`81 3.2.2.1 Full symbolic interpretation Goto statements can not be handled by simple symbolic interpretation, since they violate requirement 1. To handle goto statement need full symbolic interpretation. Full symbolic interpretation consists of performing the simple symbolic interpretation algorithm repeatedly until no more changes in the values of the properties occur, in closure algorithm fashion. For the remainder of Full symbolic interpretation see pp. 251-253.


Download ppt "3. Annotating the Abstract Syntax Tree ― the Context From: Chapter 3, Modern Compiler Design, by Dick Grun et al."

Similar presentations


Ads by Google