CD Unoit 3
CD Unoit 3
TECHNOLOGY
Unit-III
Syntax Directed Translation and Intermediate Code Generation
PART-A
The main idea behind generating three-address code during compilation is to create a simplified,
platform-independent representation of the source code. This simplification makes it easier for the compiler
to optimize and generate code for different computer architectures while also aiding in error detection and
debugging.
4. Translate the arithmetic expression a*-(b+c) into syntax tree and postfix notation.
5. What is the intermediate code representation for the expression a or b and not c?
t1=a or b
t2=not c
t3=t1 and t2
6. What are the various methods of implementing three address statements.
Quadruples: Use sets of four fields for operators, source operands, and a destination
variable.
Triples: Similar to quadruples but with an implicit destination determined by position.
Indirect Triples: Destination is represented as a reference to a memory location.
Each construct must have a clear and simple meaning such that optimizing transformations that
rewrite the IR can be easily specified and implemented.
9. Define backpatching
Backpatching is basically a process of fulfilling unspecified information. This information is of
labels. It basically uses the appropriate semantic actions during the process of code generation. It may
indicate the address of the Label in goto statements while producing TACs for the given expressions.
10. Mention the role of semantic analysis.
It uses syntax tree and symbol table to check whether the given program is semantically consistent
with language definition. It gathers type information and stores it in either syntax tree or symbol table.
This type information is subsequently used by compiler during intermediate-code generation.
PART-B
11. Discuss the various methods for translating the Boolean expression.
A Boolean Expression is an expression that evaluates to either true or false. We generally use Boolean
Expressions in conditional statements and loops in programming languages. It can be a simple Boolean
Variable or a combination of Boolean Variables, Constants, and Operators. Examples of Boolean Operators
include “and,” “or,” and “not
Methods to Translate Boolean Expressions
Numerical Representation
In Numerical Representation, we denote true by ‘1’ and false by ‘0’. The direction of evaluation of a
Boolean Expression is from left to right.
Let’s see some examples to understand Numerical Representation:
f1 : = NOT s
f2 : = q OR f1
f3 : = p AND f2
Let’s translate a < b into the three-address code sequence and start numbers at 50:
52: goto 54
53: t : = 1
54:
Now, translate a > b into the three-address code sequence and start numbers at 60:
{
E.place = newtemp();
E -> E1 OR E2
Emit(E.place ‘:=’ E1.place ‘OR’ E2.place)
}
{
E.place = newtemp();
E -> E1 AND E2
Emit(E.place ‘:=’ E1.place ‘AND’ E2.place)
}
{
E.place = newtemp();
E -> NOT E1
Emit(E.place ‘:=’ ‘NOT’ E1.place)
}
{
E -> (E1) E.place = E1.place
}
{
E.place ‘:=’ newtemp();
E -> true
Emit(E.place ‘:=’ ‘1’)
}
{
E.place ‘:=’ newtemp();
E -> false
Emit(E.place ‘:=’ ‘0’)
}
Flow-of-Control Statements
In this method, we translate the Boolean Expression into the three-address code in terms of if-then
statements, if-then-else statements, and while-do statements.
Here, Boolean Expressions are denoted by ‘E’ and the three-address statement is symbolically labelled.
These are some points you need to keep in mind while determining the Syntax-Directed Definition:
The Control will go to the E.true label, if the Expression ‘E’ will be true and the Control will go
to the E.false label, if the Expression ‘E’ will be false.
The label S.next is the first three-address instruction that needs to be executed after the S.code.
E.true : = newlabel;
E.false : = S.next;
S -> if E then S1
S1.next : = S.next;
S.code : = E.code || gen(E.true ‘:’) || S1.code
S.begin : = newlabel;
E.true : = newlabel;
E.false : = S.next;
S -> While E do S1
S1.next : = S.begin;
S.code : = gen(S.begin ‘:’) || E.code || gen(E.true ‘:’) || S1.code || gen(‘goto’
S.begin)
12. (i) Give the translating schemes for converting the assignment statements in to three address code
with example. Use the scheme for generating three address code for the assignment statement
s=a+b-c*d
Translation of Assignment Statements
In the syntax directed translation, assignment statement is mainly deals with expressions. The expression can
be of type real, integer, array and records.
Consider the grammar
1. S → id := E
2. E → E1 + E2
3. E → E1 * E2
4. E → (E1)
5. E → id
The translation scheme of above grammar is given below:
S → id :=E {p = look_up(id.name);
If p ≠ nil then
Emit (p = E.place)
Else
Error;
}
E → E1 + E2 {E.place = newtemp();
Emit (E.place = E1.place '+' E2.place)
}
7
E → E1 * E2 {E.place = newtemp();
Emit (E.place = E1.place '*' E2.place)
}
E → id {p = look_up(id.name);
If p ≠ nil then
Emit (p = E.place)
Else
Error;
}
13. What is a three address code ? What are its types ? How is it implemented? Write the intermediate
representation for the expression : (x + y) * (y + z) + (x + y + z)
Three address code is a type of intermediate code which is easy to generate and can be easily converted to
machine code. It makes use of at most three addresses and one operator to represent an expression and the
value computed at each instruction is stored in temporary variable generated by compiler. The compiler
decides the order of operation given by three address code.
Three address code is used in compiler applications:
Optimization: The three address code allows the compiler to analyze the code and perform optimizations
that can improve the performance of the generated code.
Code generation: . The three address code allows the compiler to generate code that is specific to the target
platform, while also ensuring that the generated code is correct and efficient.
Debugging: Since three address code is a low-level language, it is often easier to read and understand than
the final generated code. Developers can use the three address code to trace the execution of the program and
identify errors or issues that may be present.
Language translation: Three address code can also be used to translate code from one programming
language to another. By translating code to a common intermediate representation, it becomes easier to
translate the code to multiple target languages.
General representation –
a = b op c
Where a, b or c represents operands like names, constants or compiler generated temporaries and op
represents the operator
2. Triples – This representation doesn’t make use of extra temporary variable to represent a single operation
instead when a reference to another triple’s value is needed, a pointer to that triple is used. So, it consist of
only three fields namely op, arg1 and arg2.
Disadvantage –
Temporaries are implicit and difficult to rearrange code.
It is difficult to optimize because optimization involves moving intermediate code. When a triple
is moved, any other triple referring to it must be updated also. With help of pointer one can
directly access symbol table entry.
Example – Consider expression a = b * – c + b * – c
3. Indirect Triples – This representation makes use of pointer to the listing of all references to computations
which is made separately and stored. Its similar in utility as compared to quadruple representation but
requires less space than it. Temporaries are implicit and easier to rearrange code.
11
Question – Write quadruple, triples and indirect triples for following expression : (x + y) * (y + z) + (x + y +
z)
Explanation – The three address code is:
t1 = x + y
t2 = y + z
t3 = t1 * t2
t4 = t1 + z
t5 = t3 + t4
12
4. Construct a syntax directed translation scheme that translates arithmetic expressions form
infix to postfix notation. Using semantic attributes for each of the grammar symbols and
semantic rule, evaluate the input n3*4+5*2
13
5. Explain the process of generating the code for a Boolean expression in a single pass
Backpatching is basically a process of fulfilling unspecified information. This information is of labels. It
basically uses the appropriate semantic actions during the process of code generation. It may indicate the
address of the Label in goto statements while producing TACs for the given expressions. Here basically
two passes are used because assigning the positions of these label statements in one pass is quite
challenging. It can leave these addresses unidentified in the first pass and then populate them in the second
round. Backpatching is the process of filling up gaps in incomplete transformations and information.
Need for Backpatching:
Backpatching is mainly used for two purposes:
1. Boolean expression:
Boolean expressions are statements whose results can be either true or false. A boolean expression which
is named for mathematician George Boole is an expression that evaluates to either true or false. Let’s look
at some common language examples:
My favorite color is blue. → true
I am afraid of mathematics. → false
2 is greater than 5. → false
2. Flow of control statements:
The flow of control statements needs to be controlled during the execution of statements in a program. For
example:
14
Step 3: Now we will make the parse tree for the expression: