**Branch :**Computer Science and Engineering

**Subject :**Compiler design

**Unit :**Syntax-directed Translation

## Control Flow

**Introduction**: The translation of statements such as if-else-statements and while-statements is tied to the translation of boolean expressions. In programming languages, boolean expressions are often used to

1. **Alter the flow of control**. Boolean expressions are used as conditional expressions in statements that alter the flow of control. The value of such boolean expressions is implicit in a position reached in a program. For example, in if (E) 5, the expression E must be true if statement S is reached.

2. **Compute logical values.** A boolean expression can represent true Or false as values. Such boolean expressions can be evaluated in analogy to arithmetic expressions using three-address instructions with logical operators.

The intended use of boolean expressions is determined by its syntactic context. For example, an expression following the keyword if is used to alter the flow of control, while an expression on the right side of an assignment is used to denote a logical value. Such syntactic contexts can be specified in a number of ways: we may use two different nonterminals, use inherited attributes, or set a flag during parsing. Alternatively we may build a syntax tree and invoke different procedures for the two different uses of boolean expressions.

This section concentrates on the use of boolean expressions to alter the flow of control. For clarity, we introduce a new nonterminal B for this purpose. In Section 6.6.6, we consider how a compiler can allow boolean expressions to represent logical values.

**Boolean Expressions: **Boolean expressions are composed of the boolean operators (which we denote&&, I I, and !, using the C convention for the operators AND, OR, and NOT,respectively) applied to elements that are boolean variables or relational expressions.Relational expressions are of the form E± rel E2, where Ex and

E2 are arithmetic expressions. In this section, we consider boolean expressions generated by the following grammar:

**B -> B I | B | B kk B | ! B | ( B ) \ E rel E | true | false**

We use the attribute rel. op to indicate which of the six comparison operators <, < = , =, ! =, >, or >= is represented by rel. As is customary, we assume that I I and &;& are left-associative, and that I I has lowest precedence, then &&, then !.

Given the expression Bi I I B2, if we determine that B\ is true, then we can conclude that the entire expression is true without having to evaluate B2. Similarly, given B\k,kB2, if Bi is false, then the entire expression is false.

The semantic definition of the programming language determines whether all parts of a boolean expression must be evaluated. If the language definition permits (or requires) portions of a boolean expression to go unevaluated, then the compiler can optimize the evaluation of boolean expressions by computing only enough of an expression to determine its value. Thus, in an expression such as B\ I I B2, neither B\ nor B2 is necessarily evaluated fully. If either B\ or B2 is an expression with side effects (e.g., it contains a function that changes a global variable), then an unexpected answer may be obtained.

**Short-Circuit Code: **In short-circuit (or jumping) code, the boolean operators &&, I I, and ! translate into jumps. The operators themselves do not appear in the code; instead, the value of a boolean expression is represented by a position in the code sequence.

**Example**: The statement

if ( x < 100 II x > 200 && x != y ) x = 0;

might be translated into the code of Fig. 6.34. In this translation, the Boolean expression is true if control reaches label L2. If the expression is false, control goes immediately to Lu skipping L2 and the assignment x = 0.