Three-Address Code, Quadruples and Triples for GATE: Intermediate Code Generation Solved

Translate a repeated arithmetic expression into six TAC instructions, then align every instruction with its quadruple and triple representation.

KnowledgeGate Team

Exam prep & CS education

Updated 31 Aug 20265 min read

Intermediate-code questions usually ask you to translate an expression or count its instructions and temporaries. The arithmetic is simple, but representation details cause mistakes: a unary minus still needs an instruction, and a triple names results by position. An occurrence-by-occurrence translation maps each TAC instruction to one quadruple row and one triple row.

What three-address code means

Three-address code, or TAC, breaks a complex operation into simple statements. A typical binary instruction has one result and two operands:

x = y op z

That gives at most three addresses: x, y and z. It does not mean that every instruction must contain exactly three. A unary operation uses a result and one operand, while a copy has only a source and a destination.

Common TAC forms include:

x = y op z
x = op y
x = y
goto L
if x relop y goto L

Compilers also use forms for indexed arrays, addresses, pointers, parameters, calls and returns. The central rule for expression questions is that each TAC instruction performs at most one operator. The syntax tree fixes the evaluation dependencies before TAC is emitted; Parsing in Compiler Design: Top-Down and Bottom-Up Explained explains how that tree is built.

Worked three-address code

Translate this expression without first eliminating its repeated subexpression:

a = b * -c + b * -c

Both occurrences of unary -c and both multiplications are represented separately. A direct TAC sequence is:

t1 = -c
t2 = b * t1
t3 = -c
t4 = b * t3
t5 = t2 + t4
a = t5

Count the operations carefully:

  • two unary minus occurrences produce instructions 1 and 3

  • two multiplication occurrences produce instructions 2 and 4

  • one addition produces instruction 5

  • one final assignment produces instruction 6

The result is 6 TAC instructions and 5 temporaries. The final assignment is an instruction, but it stores into source variable a and creates no sixth temporary. An optimizer could later notice that b * -c repeats, but this unoptimized sequence preserves the expression tree occurrence by occurrence.

Quadruples name every result

A quadruple stores four fields:

(op, arg1, arg2, result)

For unary minus and assignment, the unused second argument is written _. The six TAC instructions become:

Index

op

arg1

arg2

result

0

minus

c

_

t1

1

*

b

t1

t2

2

minus

c

_

t3

3

*

b

t3

t4

4

+

t2

t4

t5

5

=

t5

_

a

Each intermediate result has an explicit name in the result field. If an optimizer moves a row while preserving its data dependencies, references such as t1 and t4 still name the same values. That explicit naming makes quadruples convenient for code movement, though each instruction carries a result field.

Triples name a result by its position

A triple stores only three fields:

(op, arg1, arg2)

There is no explicit result field. The value produced by row 0 is called (0), the value from row 1 is called (1), and so on. For assignment, this convention puts the source value in arg1 and the destination in arg2:

Index

op

arg1

arg2

0

minus

c

_

1

*

b

(0)

2

minus

c

_

3

*

b

(2)

4

+

(1)

(3)

5

=

(4)

a

Row 1 uses the value from row 0. Row 4 adds the results of rows 1 and 3. Row 5 copies row 4's result into a.

Triples save one field per row, but a position is now also a value's name. Moving an instruction changes its position and can force every reference to that position to be renumbered. Indirect triples address this weakness by maintaining a separate list of pointers to triple rows. The pointer order can change without moving or renumbering the triples themselves.

The expression a = b * -c + b * -c aligned across its six-row TAC, quadruple and triple representations in three columns.

Counting drills from the same expression

The unoptimized expression has five operator occurrences inside the right-hand expression: two unary minuses, two multiplications and one addition. Those create five intermediate computations and five temporaries. The assignment to a adds one more instruction but no temporary, giving 6 and 5 respectively.

For N represented instructions, a quadruple table has N result fields. A triple table omits those N fields and refers to intermediate results by row position instead. That is the direct space trade-off the examiner is testing.

Do not blindly equate the number of syntax-tree operators with the number of temporaries in every translation scheme. A direct store into the final target can avoid a new temporary, and a later optimization can remove repeated computations. State whether you are translating the original expression or optimized code before counting.

Grammar actions generate TAC during syntax-directed translation, before later passes optimize the representation without changing program meaning.

Traps and common GATE question forms

A unary minus is an operator, so t1 = -c consumes a complete TAC instruction. The final copy a = t5 is also an instruction even though it creates no temporary. These two facts explain many off-by-one answers.

Keep the field layouts distinct. A quadruple is (op, arg1, arg2, result). A triple is (op, arg1, arg2), with the row position serving as the missing result name. Triples cannot be freely reordered like quadruples because their back-references depend on row numbers.

Common stems ask for the TAC of an expression, the number of instructions or temporaries, the correct quadruple or triple table, or the representation most suitable for code movement.

For exact wording from a particular year, consult the paper and answer key on the official GATE portal of the organising IIT.

Short version and next step

TAC permits one operator per instruction. Quadruples store (op, arg1, arg2, result) and keep intermediate names stable when rows move. Triples store (op, arg1, arg2) and use row positions as names, so direct reordering requires renumbering. Indirect triples add a pointer layer.

Write all three forms for one expression with a unary operator and another with a repeated subexpression. Then practise the count-and-representation questions in GATE Guidance by Sanchit Sir, and use the GATE preparation category for the wider Compiler Design sequence.