Important Questions

CSC376 · Exam intelligence

Compiler Design and Construction important questions

From 6 past TU papers: which questions keep coming back, how much they carry, and what is most likely to show up next. Every question links to a model answer.

Most likely in the next examStatistical

Ranked by how often a topic is asked, its marks weight, and whether it is due after skipping the 2081.1 paper. No guarantees; study the whole syllabus.

1asked 10xavg 7 marks · LR parsing
Answer

Create the LR(1) parsing table for following grammar.S→AAS \rightarrow AAS→AAA→0AA \rightarrow 0AA→0AA→εA \rightarrow \varepsilonA→ε_[10]_

LR(1) Parsing Table for the Grammar

Step 1: EXTRACT - Given Data

Grammar: $$S \to AA$$ $$A \to 0A$$ $$A \to \varepsilon$$

  • Terminals: $${0, $}$$
  • Non-terminals: ${S, A}$
  • Marks: 10

Step 2: SOLVE

Augmented Grammar

$$ \begin{aligned} (0)\ & S' \to S\ (1)\ & S \to AA\ (2)\ & A \to 0A\ (3)\ & A \to \varepsilon \end{aligned} $$

Canonical LR(1) Item Sets

Closure rule: For $[B \to \alpha \bullet C\beta, a]$, add $[C \to \bullet \gamma, b]$ for each $b \in \text{FIRST}(\beta a)$.


$$I_0 = \text{Closure}([S' \to \bullet S, $])$$

  • $$[S' \to \bullet S, $]$$
  • $$[S \to \bullet AA, $]$$ (dot before $S$, FIRST($$$ $$) = $$$ $$)
  • Dot before first $A$; lookahead $=$ FIRST$$(A$) = {0, $}$$ (since $A \Rightarrow \varepsilon$):
    • $$[A \to \bullet 0A, 0/$]$$
    • $$[A \to \bullet, 0/$]$$

Transitions: $S \to I_1$, $A \to I_2$, $0 \to I_3$


$I_1 = \text{goto}(I_0, S)$

  • $$[S' \to S \bullet, $]$$ (Accept)

$I_2 = \text{goto}(I_0, A)$

  • $$[S \to A \bullet A, $]$$
  • Dot before second $A$; lookahead $=$ FIRST($$$ $$) $$= {$}$$:
    • $$[A \to \bullet 0A, $]$$
    • $$[A \to \bullet, $]$$

Transitions: $A \to I_4$, $0 \to I_5$


$I_3 = \text{goto}(I_0, 0)$

  • $$[A \to 0 \bullet A, 0/$]$$
  • Dot before $A$; lookahead $$= {0, $}$$:
    • $$[A \to \bullet 0A, 0/$]$$
    • $$[A \to \bullet, 0/$]$$

Transitions: $A \to I_6$, $0 \to I_3$ (self-loop, same item set)


$I_4 = \text{goto}(I_2, A)$

  • $$[S \to AA \bullet, $]$$ (reduce by rule 1)

$I_5 = \text{goto}(I_2, 0)$

  • $$[A \to 0 \bullet A, $]$$
  • $$[A \to \bullet 0A, $]$$
  • $$[A \to \bullet, $]$$

Transitions: $A \to I_7$, $0 \to I_5$ (self-loop)


$I_6 = \text{goto}(I_3, A)$

  • $$[A \to 0A \bullet, 0/$]$$ (reduce by rule 2)

$I_7 = \text{goto}(I_5, A)$

  • $$[A \to 0A \bullet, $]$$ (reduce by rule 2)

Reduce actions

  • $I_0$: $$[A \to \bullet, 0/$]$$ → reduce by rule 3 on $0$ and $$$ $$
  • $I_2$: $$[A \to \bullet, $]$$ → reduce by rule 3 on $$$ $$
  • $I_3$: $$[A \to \bullet, 0/$]$$ → reduce by rule 3 on $0$ and $$$ $$
  • $I_4$: reduce by rule 1 on $$$ $$
  • $I_5$: $$[A \to \bullet, $]$$ → reduce by rule 3 on $$$ $$
  • $I_6$: reduce by rule 2 on $0$ and $$$ $$
  • $I_7$: reduce by rule 2 on $$$ $$

Notation: $sn$ = shift and go to state $n$; $rn$ = reduce by production $n$; $acc$ = accept; blank = error.

LR(1) Parsing Table

StateAction 0Action $Goto SGoto A
0s3 / r3r312
1acc
2s5r34
3s3 / r3r36
4r1
5s5r37
6r2r2
7r2

Note on conflicts (States 0 and 3)

In states $I_0$ and $I_3$ the item $[A \to \bullet, 0]$ calls for reduce by rule 3 on input $0$, while the items $[A \to \bullet 0A, \dots]$ call for shift on $0$. This is a shift/reduce conflict on 0.

Resolving in favor of shift (standard convention, and required for this grammar to accept strings like $00$), the entries $s3$ / $s5$ are used on input $0$. With this resolution the parser works correctly. Strictly, the grammar is not LR(1) because of this genuine shift/reduce conflict in states 0 and 3, so I have shown both actions in those cells.

Final Result

The canonical collection has 8 states ($I_0$ through $I_7$), and the completed LR(1) table is as shown above, with shift/reduce conflicts on input 0 in states 0 and 3 (resolved by shift).

2asked 6xavg 6 marks · Top-down parsing
Answer

Compute the FIRST and FOLLOW of all the non-terminals in following grammar. S→ABS \rightarrow ABS→ABA→0A′∣1A′∣εA \rightarrow 0A' \mid 1A' \mid \varepsilonA→0A′∣1A′∣εA′→SSA′∣εA' \rightarrow SSA' \mid \varepsilonA′→SSA′∣εB→AS∣1B \rightarrow AS \mid 1B→AS∣1_[5]_

FIRST and FOLLOW Computation

Given data (Grammar)

$$S \rightarrow AB$$ $$A \rightarrow 0A' \mid 1A' \mid \varepsilon$$ $$A' \rightarrow SSA' \mid \varepsilon$$ $$B \rightarrow AS \mid 1$$

Non-terminals: $S, A, A', B$
Terminals: $0, 1$
Start symbol: $S$


Step 1: FIRST Sets

FIRST(A)

From $A \rightarrow 0A' \mid 1A' \mid \varepsilon$: $$FIRST(A) = {0, 1, \varepsilon}$$

FIRST(B)

From $B \rightarrow AS \mid 1$:

  • $B \rightarrow 1$ gives $1$
  • $B \rightarrow AS$: add $FIRST(A)\setminus{\varepsilon} = {0,1}$; since $\varepsilon \in FIRST(A)$, also add $FIRST(S)$.

Since $S$ cannot derive $\varepsilon$ (needs both $A$ and $B$ to vanish, but $B$ cannot), $FIRST(S)$ adds only ${0,1}$: $$FIRST(B) = {0, 1}$$

FIRST(S)

From $S \rightarrow AB$:

  • Add $FIRST(A)\setminus{\varepsilon} = {0,1}$
  • Since $\varepsilon \in FIRST(A)$, add $FIRST(B) = {0,1}$
  • $\varepsilon$ not added (B cannot derive $\varepsilon$) $$FIRST(S) = {0, 1}$$

FIRST(A')

From $A' \rightarrow SSA' \mid \varepsilon$:

  • $A' \rightarrow \varepsilon$ gives $\varepsilon$
  • $A' \rightarrow SSA'$: add $FIRST(S) = {0,1}$ $$FIRST(A') = {0, 1, \varepsilon}$$

Summary

Non-terminalFIRST
$S$${0, 1}$
$A$${0, 1, \varepsilon}$
$A'$${0, 1, \varepsilon}$
$B$${0, 1}$

Step 2: FOLLOW Sets

Rules: Start gets $$$ $$; for $X\to \alpha Y\beta$ add $FIRST(\beta)\setminus{\varepsilon}$ to $FOLLOW(Y)$; if $\varepsilon\in FIRST(\beta)$ or $\beta$ empty, add $FOLLOW(X)$ to $FOLLOW(Y)$.

FOLLOW(S)

  • Start symbol: add $$$ $$
  • $A' \rightarrow SSA'$:
    • First $S$ followed by $SA'$: add $FIRST(S)\setminus{\varepsilon}={0,1}$
    • Second $S$ followed by $A'$: add $FIRST(A')\setminus{\varepsilon}={0,1}$; since $\varepsilon\in FIRST(A')$, add $FOLLOW(A')$
  • $B \rightarrow AS$: $S$ at end, add $FOLLOW(B)$

$$FOLLOW(S) = {$, 0, 1} \cup FOLLOW(A') \cup FOLLOW(B)$$

FOLLOW(A)

  • $S \rightarrow AB$: $A$ followed by $B$, add $FIRST(B)\setminus{\varepsilon}={0,1}$; $\varepsilon\notin FIRST(B)$, no more.
  • $B \rightarrow AS$: $A$ followed by $S$, add $FIRST(S)\setminus{\varepsilon}={0,1}$; $\varepsilon\notin FIRST(S)$, no more. $$FOLLOW(A) = {0, 1}$$

FOLLOW(A')

  • $A \rightarrow 0A' \mid 1A'$: $A'$ at end, add $FOLLOW(A)={0,1}$
  • $A' \rightarrow SSA'$: $A'$ at end, add $FOLLOW(A')$ (itself, no new info) $$FOLLOW(A') = {0, 1}$$

FOLLOW(B)

  • $S \rightarrow AB$: $B$ at end, add $FOLLOW(S)$ $$FOLLOW(B) = FOLLOW(S)$$

Resolve FOLLOW(S) and FOLLOW(B)

$$FOLLOW(S) = {$, 0, 1} \cup FOLLOW(A') \cup FOLLOW(B)$$ $$= {$, 0, 1} \cup {0,1} \cup FOLLOW(B)$$

Since $FOLLOW(B) = FOLLOW(S)$, this is self-referential and adds nothing new: $$FOLLOW(S) = {$, 0, 1}$$ $$FOLLOW(B) = {$, 0, 1}$$


Final Answer

Non-terminalFIRSTFOLLOW
$S$${0, 1}$$${$, 0, 1}$$
$A$${0, 1, \varepsilon}$${0, 1}$
$A'$${0, 1, \varepsilon}$${0, 1}$
$B$${0, 1}$$${$, 0, 1}$$
3asked 4xavg 6 marks · due (skipped 2081.1) · Code Optimization
Answer

Why code optimization is needed? Describe any two techniques for loop optimization. [5]

Code optimization is the process of transforming a program to make it more efficient without changing its output or meaning. It is needed because: - Reduces space and increases speed: Optimization reduces the memory consumed by the progr...

4asked 4xavg 5 marks · due (skipped 2081.1) · Run-time storage management
Answer

How do you represent recursion in an activation tree? Generate the three-address code for the following instruction: [5]

STEP 1 - EXTRACT: Given Data

Part 1: Conceptual question about representing recursion in an activation tree. No numeric data.

Part 2: "Generate the three-address code for the following instruction."

Critical issue: The actual instruction/expression to be translated into three-address code is NOT provided in the question text. The statement ends with "the following instruction:" but no instruction, expression, or code fragment follows.

Therefore, the specific expression required for Part 2 is missing or unreadable, and three-address code cannot be generated for an expression that was not given. An expression such as a = b * c + b * d can only be treated as an illustration, not as the question's data.

I will fully answer Part 1 (conceptual, no data needed) and, for Part 2, explain the method and demonstrate it on a clearly-labelled illustrative example (marked as assumed, since the actual instruction is missing).


STEP 2 - SOLVE

Part 1: Representing Recursion in an Activation Tree

An activation tree shows the flow of control among procedure activations during a program's execution.

Properties:

  • Each node = one activation (one call) of a procedure.
  • The root = the activation of main.
  • Node for P is the parent of node for Q if control flows from P into Q (i.e., P calls Q).
  • Left-to-right ordering reflects the temporal order in which activations begin.

Recursion representation: When a procedure calls itself, the activation tree contains several distinct nodes bearing the same procedure name, arranged as a chain (or subtree) descending from the calling node. Each recursive call is a separate activation with its own activation record (own parameters, locals, return address) pushed onto the control stack.

Example: fact(n) computing $n!$

$$ \text{fact}(4) \rightarrow \text{fact}(3) \rightarrow \text{fact}(2) \rightarrow \text{fact}(1) $$

        fact(4)
           |
        fact(3)
           |
        fact(2)
           |
        fact(1)
  • Each node is a distinct activation even though the procedure name repeats.
  • At any moment, the runtime stack holds exactly the activation records lying on the path from the root to the currently active node.
  • On return, fact(1)'s record is popped, control resumes in fact(2), and so on.

Thus recursion = repeated nodes of the same procedure along a root-to-leaf path, each with its own activation record on the stack.


Part 2: Three-Address Code Generation

Missing data: The question says "Generate the three-address code for the following instruction:" but no instruction/expression was supplied in the given text. I cannot produce the intended answer without it. Below I state the method and demonstrate it on an assumed illustrative expression (clearly marked as not from the question).

Method (syntax-directed translation):

  • $E \rightarrow id$: E.place = id
  • $E \rightarrow E_1 * E_2$: emit t = E1.place * E2.place
  • $E \rightarrow E_1 + E_2$: emit t = E1.place + E2.place
  • $S \rightarrow id = E$: emit id = E.place

Assumed example (illustrative only): $a = b * c + b * d$

$$ \begin{aligned} t_1 &= b * c \ t_2 &= b * d \ t_3 &= t_1 + t_2 \ a &= t_3 \end{aligned} $$

Quadruple form $(op, arg_1, arg_2, result)$:

OpArg1Arg2Result
*bct1
*bdt2
+t1t2t3
=t3-a

Caveat: If the actual exam instruction differs (e.g., x = (a + b) * (c + d) or a control statement), the code must be regenerated from that expression. The above b*c+b*d result is not verifiable because the source instruction was absent from the given question.

5asked 3xavg 6 marks · due (skipped 2081.1) · Annotated Parse Tree
Answer

What is annotated parse tree? Define S-attributed grammar with an example. [5]

--- An annotated parse tree is a parse tree in which each node is labeled with its grammar symbol along with the values of its associated attributes. In Syntax-Directed Translation (SDT), semantic rules are used to compute attribute valu...

Most repeated questions

Topics asked at least twice, most-asked first.

asked 10xavg 7 marks · 2081.1, 2081, 2080, 2078, 2076...
Answer

Create the LR(1) parsing table for following grammar.S→AAS \rightarrow AAS→AAA→0AA \rightarrow 0AA→0AA→εA \rightarrow \varepsilonA→ε_[10]_

LR(1) Parsing Table for the Grammar

Step 1: EXTRACT - Given Data

Grammar: $$S \to AA$$ $$A \to 0A$$ $$A \to \varepsilon$$

  • Terminals: $${0, $}$$
  • Non-terminals: ${S, A}$
  • Marks: 10

Step 2: SOLVE

Augmented Grammar

$$ \begin{aligned} (0)\ & S' \to S\ (1)\ & S \to AA\ (2)\ & A \to 0A\ (3)\ & A \to \varepsilon \end{aligned} $$

Canonical LR(1) Item Sets

Closure rule: For $[B \to \alpha \bullet C\beta, a]$, add $[C \to \bullet \gamma, b]$ for each $b \in \text{FIRST}(\beta a)$.


$$I_0 = \text{Closure}([S' \to \bullet S, $])$$

  • $$[S' \to \bullet S, $]$$
  • $$[S \to \bullet AA, $]$$ (dot before $S$, FIRST($$$ $$) = $$$ $$)
  • Dot before first $A$; lookahead $=$ FIRST$$(A$) = {0, $}$$ (since $A \Rightarrow \varepsilon$):
    • $$[A \to \bullet 0A, 0/$]$$
    • $$[A \to \bullet, 0/$]$$

Transitions: $S \to I_1$, $A \to I_2$, $0 \to I_3$


$I_1 = \text{goto}(I_0, S)$

  • $$[S' \to S \bullet, $]$$ (Accept)

$I_2 = \text{goto}(I_0, A)$

  • $$[S \to A \bullet A, $]$$
  • Dot before second $A$; lookahead $=$ FIRST($$$ $$) $$= {$}$$:
    • $$[A \to \bullet 0A, $]$$
    • $$[A \to \bullet, $]$$

Transitions: $A \to I_4$, $0 \to I_5$


$I_3 = \text{goto}(I_0, 0)$

  • $$[A \to 0 \bullet A, 0/$]$$
  • Dot before $A$; lookahead $$= {0, $}$$:
    • $$[A \to \bullet 0A, 0/$]$$
    • $$[A \to \bullet, 0/$]$$

Transitions: $A \to I_6$, $0 \to I_3$ (self-loop, same item set)


$I_4 = \text{goto}(I_2, A)$

  • $$[S \to AA \bullet, $]$$ (reduce by rule 1)

$I_5 = \text{goto}(I_2, 0)$

  • $$[A \to 0 \bullet A, $]$$
  • $$[A \to \bullet 0A, $]$$
  • $$[A \to \bullet, $]$$

Transitions: $A \to I_7$, $0 \to I_5$ (self-loop)


$I_6 = \text{goto}(I_3, A)$

  • $$[A \to 0A \bullet, 0/$]$$ (reduce by rule 2)

$I_7 = \text{goto}(I_5, A)$

  • $$[A \to 0A \bullet, $]$$ (reduce by rule 2)

Reduce actions

  • $I_0$: $$[A \to \bullet, 0/$]$$ → reduce by rule 3 on $0$ and $$$ $$
  • $I_2$: $$[A \to \bullet, $]$$ → reduce by rule 3 on $$$ $$
  • $I_3$: $$[A \to \bullet, 0/$]$$ → reduce by rule 3 on $0$ and $$$ $$
  • $I_4$: reduce by rule 1 on $$$ $$
  • $I_5$: $$[A \to \bullet, $]$$ → reduce by rule 3 on $$$ $$
  • $I_6$: reduce by rule 2 on $0$ and $$$ $$
  • $I_7$: reduce by rule 2 on $$$ $$

Notation: $sn$ = shift and go to state $n$; $rn$ = reduce by production $n$; $acc$ = accept; blank = error.

LR(1) Parsing Table

StateAction 0Action $Goto SGoto A
0s3 / r3r312
1acc
2s5r34
3s3 / r3r36
4r1
5s5r37
6r2r2
7r2

Note on conflicts (States 0 and 3)

In states $I_0$ and $I_3$ the item $[A \to \bullet, 0]$ calls for reduce by rule 3 on input $0$, while the items $[A \to \bullet 0A, \dots]$ call for shift on $0$. This is a shift/reduce conflict on 0.

Resolving in favor of shift (standard convention, and required for this grammar to accept strings like $00$), the entries $s3$ / $s5$ are used on input $0$. With this resolution the parser works correctly. Strictly, the grammar is not LR(1) because of this genuine shift/reduce conflict in states 0 and 3, so I have shown both actions in those cells.

Final Result

The canonical collection has 8 states ($I_0$ through $I_7$), and the completed LR(1) table is as shown above, with shift/reduce conflicts on input 0 in states 0 and 3 (resolved by shift).

asked 6xavg 6 marks · 2081.1, 2081, 2080, 2075
Answer

Compute the FIRST and FOLLOW of all the non-terminals in following grammar. S→ABS \rightarrow ABS→ABA→0A′∣1A′∣εA \rightarrow 0A' \mid 1A' \mid \varepsilonA→0A′∣1A′∣εA′→SSA′∣εA' \rightarrow SSA' \mid \varepsilonA′→SSA′∣εB→AS∣1B \rightarrow AS \mid 1B→AS∣1_[5]_

FIRST and FOLLOW Computation

Given data (Grammar)

$$S \rightarrow AB$$ $$A \rightarrow 0A' \mid 1A' \mid \varepsilon$$ $$A' \rightarrow SSA' \mid \varepsilon$$ $$B \rightarrow AS \mid 1$$

Non-terminals: $S, A, A', B$
Terminals: $0, 1$
Start symbol: $S$


Step 1: FIRST Sets

FIRST(A)

From $A \rightarrow 0A' \mid 1A' \mid \varepsilon$: $$FIRST(A) = {0, 1, \varepsilon}$$

FIRST(B)

From $B \rightarrow AS \mid 1$:

  • $B \rightarrow 1$ gives $1$
  • $B \rightarrow AS$: add $FIRST(A)\setminus{\varepsilon} = {0,1}$; since $\varepsilon \in FIRST(A)$, also add $FIRST(S)$.

Since $S$ cannot derive $\varepsilon$ (needs both $A$ and $B$ to vanish, but $B$ cannot), $FIRST(S)$ adds only ${0,1}$: $$FIRST(B) = {0, 1}$$

FIRST(S)

From $S \rightarrow AB$:

  • Add $FIRST(A)\setminus{\varepsilon} = {0,1}$
  • Since $\varepsilon \in FIRST(A)$, add $FIRST(B) = {0,1}$
  • $\varepsilon$ not added (B cannot derive $\varepsilon$) $$FIRST(S) = {0, 1}$$

FIRST(A')

From $A' \rightarrow SSA' \mid \varepsilon$:

  • $A' \rightarrow \varepsilon$ gives $\varepsilon$
  • $A' \rightarrow SSA'$: add $FIRST(S) = {0,1}$ $$FIRST(A') = {0, 1, \varepsilon}$$

Summary

Non-terminalFIRST
$S$${0, 1}$
$A$${0, 1, \varepsilon}$
$A'$${0, 1, \varepsilon}$
$B$${0, 1}$

Step 2: FOLLOW Sets

Rules: Start gets $$$ $$; for $X\to \alpha Y\beta$ add $FIRST(\beta)\setminus{\varepsilon}$ to $FOLLOW(Y)$; if $\varepsilon\in FIRST(\beta)$ or $\beta$ empty, add $FOLLOW(X)$ to $FOLLOW(Y)$.

FOLLOW(S)

  • Start symbol: add $$$ $$
  • $A' \rightarrow SSA'$:
    • First $S$ followed by $SA'$: add $FIRST(S)\setminus{\varepsilon}={0,1}$
    • Second $S$ followed by $A'$: add $FIRST(A')\setminus{\varepsilon}={0,1}$; since $\varepsilon\in FIRST(A')$, add $FOLLOW(A')$
  • $B \rightarrow AS$: $S$ at end, add $FOLLOW(B)$

$$FOLLOW(S) = {$, 0, 1} \cup FOLLOW(A') \cup FOLLOW(B)$$

FOLLOW(A)

  • $S \rightarrow AB$: $A$ followed by $B$, add $FIRST(B)\setminus{\varepsilon}={0,1}$; $\varepsilon\notin FIRST(B)$, no more.
  • $B \rightarrow AS$: $A$ followed by $S$, add $FIRST(S)\setminus{\varepsilon}={0,1}$; $\varepsilon\notin FIRST(S)$, no more. $$FOLLOW(A) = {0, 1}$$

FOLLOW(A')

  • $A \rightarrow 0A' \mid 1A'$: $A'$ at end, add $FOLLOW(A)={0,1}$
  • $A' \rightarrow SSA'$: $A'$ at end, add $FOLLOW(A')$ (itself, no new info) $$FOLLOW(A') = {0, 1}$$

FOLLOW(B)

  • $S \rightarrow AB$: $B$ at end, add $FOLLOW(S)$ $$FOLLOW(B) = FOLLOW(S)$$

Resolve FOLLOW(S) and FOLLOW(B)

$$FOLLOW(S) = {$, 0, 1} \cup FOLLOW(A') \cup FOLLOW(B)$$ $$= {$, 0, 1} \cup {0,1} \cup FOLLOW(B)$$

Since $FOLLOW(B) = FOLLOW(S)$, this is self-referential and adds nothing new: $$FOLLOW(S) = {$, 0, 1}$$ $$FOLLOW(B) = {$, 0, 1}$$


Final Answer

Non-terminalFIRSTFOLLOW
$S$${0, 1}$$${$, 0, 1}$$
$A$${0, 1, \varepsilon}$${0, 1}$
$A'$${0, 1, \varepsilon}$${0, 1}$
$B$${0, 1}$$${$, 0, 1}$$
asked 4xavg 6 marks · 2080, 2078, 2076, 2075
Answer

Why code optimization is needed? Describe any two techniques for loop optimization. [5]

Code optimization is the process of transforming a program to make it more efficient without changing its output or meaning. It is needed because: - Reduces space and increases speed: Optimization reduces the memory consumed by the progr...

asked 4xavg 5 marks · 2081, 2080, 2078, 2075
Answer

How do you represent recursion in an activation tree? Generate the three-address code for the following instruction: [5]

STEP 1 - EXTRACT: Given Data

Part 1: Conceptual question about representing recursion in an activation tree. No numeric data.

Part 2: "Generate the three-address code for the following instruction."

Critical issue: The actual instruction/expression to be translated into three-address code is NOT provided in the question text. The statement ends with "the following instruction:" but no instruction, expression, or code fragment follows.

Therefore, the specific expression required for Part 2 is missing or unreadable, and three-address code cannot be generated for an expression that was not given. An expression such as a = b * c + b * d can only be treated as an illustration, not as the question's data.

I will fully answer Part 1 (conceptual, no data needed) and, for Part 2, explain the method and demonstrate it on a clearly-labelled illustrative example (marked as assumed, since the actual instruction is missing).


STEP 2 - SOLVE

Part 1: Representing Recursion in an Activation Tree

An activation tree shows the flow of control among procedure activations during a program's execution.

Properties:

  • Each node = one activation (one call) of a procedure.
  • The root = the activation of main.
  • Node for P is the parent of node for Q if control flows from P into Q (i.e., P calls Q).
  • Left-to-right ordering reflects the temporal order in which activations begin.

Recursion representation: When a procedure calls itself, the activation tree contains several distinct nodes bearing the same procedure name, arranged as a chain (or subtree) descending from the calling node. Each recursive call is a separate activation with its own activation record (own parameters, locals, return address) pushed onto the control stack.

Example: fact(n) computing $n!$

$$ \text{fact}(4) \rightarrow \text{fact}(3) \rightarrow \text{fact}(2) \rightarrow \text{fact}(1) $$

        fact(4)
           |
        fact(3)
           |
        fact(2)
           |
        fact(1)
  • Each node is a distinct activation even though the procedure name repeats.
  • At any moment, the runtime stack holds exactly the activation records lying on the path from the root to the currently active node.
  • On return, fact(1)'s record is popped, control resumes in fact(2), and so on.

Thus recursion = repeated nodes of the same procedure along a root-to-leaf path, each with its own activation record on the stack.


Part 2: Three-Address Code Generation

Missing data: The question says "Generate the three-address code for the following instruction:" but no instruction/expression was supplied in the given text. I cannot produce the intended answer without it. Below I state the method and demonstrate it on an assumed illustrative expression (clearly marked as not from the question).

Method (syntax-directed translation):

  • $E \rightarrow id$: E.place = id
  • $E \rightarrow E_1 * E_2$: emit t = E1.place * E2.place
  • $E \rightarrow E_1 + E_2$: emit t = E1.place + E2.place
  • $S \rightarrow id = E$: emit id = E.place

Assumed example (illustrative only): $a = b * c + b * d$

$$ \begin{aligned} t_1 &= b * c \ t_2 &= b * d \ t_3 &= t_1 + t_2 \ a &= t_3 \end{aligned} $$

Quadruple form $(op, arg_1, arg_2, result)$:

OpArg1Arg2Result
*bct1
*bdt2
+t1t2t3
=t3-a

Caveat: If the actual exam instruction differs (e.g., x = (a + b) * (c + d) or a control statement), the code must be regenerated from that expression. The above b*c+b*d result is not verifiable because the source instruction was absent from the given question.

asked 4xavg 7 marks · 2081.1, 2078, 2076, 2075
Answer

Define explicit and implicit type conversion. Why do we need to check type of the system? Justify with an example. [5]

Type Conversion and Type Checking

Explicit Type Conversion

Explicit type conversion (also called type casting) is a conversion that is manually performed by the programmer by writing a specific instruction in the source code. The programmer explicitly specifies the target type to which a value should be converted.

Example:

int a = 10;
float b = (float) a;   // programmer explicitly casts int to float

Implicit Type Conversion

Implicit type conversion (also called type coercion) is a conversion that is automatically performed by the compiler without any explicit instruction from the programmer. The compiler applies conversion rules defined by the type system when operands of different types are used together.

Example:

int a = 5;
float b = 3.2;
float c = a + b;   // compiler automatically converts 'a' to float

Here, the integer a is automatically promoted to float before the addition is performed.


Why Do We Need to Check the Type of a System?

The collection of different data types and their associated rules to assign types to programming language constructs is known as type systems. A type checker implements a type system.

Type checking is necessary for the following reasons:

1. Ensures Type Correctness

Type checking verifies that operations are applied to compatible types. Without it, meaningless operations (such as adding a string to an integer) could go undetected.

2. Prevents Runtime Errors

Catching type mismatches at compile time avoids unexpected crashes or incorrect results at runtime.

3. Enforces Language Rules

Type systems define informal rules such as:

"If both operands of addition are of type integer, then the result is of type integer."

The type checker enforces these rules consistently across the program.

4. Supports Semantic Correctness

Even if a program is syntactically correct, it may be semantically wrong due to type mismatches. Type checking adds a layer of semantic validation.


Justification with an Example

Consider the following expression:

int x = 5;
char ch = 'A';
int result = x + ch;

Without type checking: The compiler would not know whether adding an int and a char is valid, and the result type would be undefined or erroneous.

With type checking: The type checker applies the rule:

Operand 1Operand 2OperationResult Type
intchar+int (char is coerced to its ASCII integer value)

The type checker detects that char can be implicitly converted to int (ASCII value of 'A' = 65), so:

result = 5 + 65 = 70

This is a valid, well-typed expression. If instead we wrote:

int x = 5;
char *str = "hello";
int result = x + str;   // TYPE ERROR

The type checker would flag this as a type error because adding an integer and a string pointer violates the type rules, preventing a potential runtime crash.


Summary

FeatureExplicit ConversionImplicit Conversion
Initiated byProgrammerCompiler
Also known asType castingType coercion
RiskPossible data loss if misusedMay cause unintended behavior

Type checking is essential to ensure that every operation in a program is applied to operands of appropriate and compatible types, making programs safe, correct, and predictable.

asked 4xavg 6 marks · 2081.1, 2078, 2076, 2075
Answer

What are the roles of macros and preprocessor? Discuss about one pass and multi pass compiler. [5]

Roles of Macros and Preprocessor; One Pass vs Multi-Pass Compiler


1. Roles of Macros and Preprocessor

A preprocessor is a tool that processes the source code before it is passed to the compiler. It is generally considered a part of the compiler system and produces input for the compiler proper.

Key Functions of a Preprocessor:

i) Macro Processing: A preprocessor allows a user to define macros, which are shorthands for longer constructs. When the preprocessor encounters a macro call, it replaces it with the corresponding expanded code before compilation begins.

  • Example: #define MAX 100 replaces every occurrence of MAX with 100.

ii) File Inclusion: The preprocessor handles header file inclusion by inserting the content of specified files into the program text.

  • Example: #include <stdio.h> inserts the standard I/O header file.

iii) Rational Preprocessor: These preprocessors augment older languages with more modern flow-of-control and data structuring facilities, making legacy code more manageable.

iv) Language Extensions: These preprocessors attempt to add capabilities to the language by building in macro-like constructs, effectively extending what the base language can express.


2. One Pass vs Multi-Pass Compiler

One Pass Compiler:

A compiler in which all phases are combined and executed in a single pass over the source program.

Multi-Pass Compiler:

A compiler in which different phases are grouped into multiple passes, each pass reading the output of the previous one.


Comparison Table:

FeatureOne Pass CompilerMulti-Pass Compiler
StructureAll phases combined into one single passDifferent phases grouped into multiple passes
Intermediate RepresentationNot createdCreated between passes
SpeedFasterSlightly slower
Also CalledNarrow compilerWide compiler
Memory UsageRequires less memoryRequires more memory
ExamplePascal compilerC++ compiler

Summary:

  • A one pass compiler is simpler and faster but less flexible, as it cannot easily handle forward references.
  • A multi-pass compiler is more powerful and can perform better optimization since it has a complete view of the program through intermediate representations.
asked 3xavg 6 marks · 2080, 2076, 2075
Answer

What is annotated parse tree? Define S-attributed grammar with an example. [5]

--- An annotated parse tree is a parse tree in which each node is labeled with its grammar symbol along with the values of its associated attributes. In Syntax-Directed Translation (SDT), semantic rules are used to compute attribute valu...

asked 3xavg 5 marks · 2081, 2080, 2078
Answer

What types of information are stored in a symbol table? Discuss the activation record. [5]

A symbol table is a data structure used by compilers to hold information about source-program constructs. The information is collected incrementally by the analysis phases and used by the synthesis phases to generate target code. The fol...

asked 3xavg 7 marks · 2078, 2076, 2075
Answer

List out the tasks performed by Lexical Analyser. Define DFA. Convert the Regular Expression (a+b)∗a(a+b)(a+b)^*a(a+b)(a+b)∗a(a+b) to DFA directly.[10]

  • RE to convert (canonical/deduplicated form): $r = (a+b)^,a,(a+b)$ - Alphabet: $\Sigma = {a, b}$ - Marks: 10 Note: The question string repeats the pattern; the intended standard example is $(a+b)^a(a+b)$. --- 1. Scanning the source ...
asked 3xavg 6 marks · 2078, 2076, 2075
Answer

Explain about the factors affecting target code generation. [5]

Target code generation is the final phase of compilation that translates optimized intermediate code into machine-level instructions for a specific target machine. Several factors influence how efficient and correct the generated target ...

asked 3xavg 5 marks · 2081.1, 2081, 2078
Answer

Differentiate between synthesized and inherited attributes with example. [5]

Attributes of a node that are derived from its children nodes are called synthesized attributes. - Information flows bottom-up in the parse tree (from children to parent). - A node's attribute value is computed from the attribute values ...

asked 2xavg 8 marks · 2081, 2076
Answer

What are the significances of intermediate code? Differentiate between DAG and Syntax tree. Represent the instruction A = B + C - D * E + G using quadruple and triple.[10]

Intermediate Code, DAG vs Syntax Tree, and Quadruple/Triple Representation

Given Data (Extracted)

  • Task 1: Significances of intermediate code (conceptual)
  • Task 2: Differentiate DAG vs Syntax tree (conceptual)
  • Task 3: Expression to represent using quadruple and triple: $$A = B + C - D * E + G$$

Operator precedence assumption: * binds tighter than +/-; + and - are left-associative and equal precedence, evaluated left to right. So the expression parses as: $$A = ((B + C) - (D * E)) + G$$


1. Significances of Intermediate Code (3 marks)

Intermediate code (IC) is a machine-independent representation produced between the analysis (front end) and synthesis (back end) phases of a compiler.

SignificanceExplanation
Machine IndependenceIC is not tied to any target CPU, keeping the front end portable.
RetargetabilityOne front end can serve many target machines by swapping only the back-end code generator.
Enables OptimizationMachine-independent optimizations (common subexpression elimination, constant folding, dead-code removal) are applied conveniently on IC.
Front-end Reuse for Many LanguagesSeveral source-language front ends can share a single back end if they emit the same IC.
Modularity / Simpler Compiler DesignClean separation of phases eases development, debugging, and maintenance.
Aids Error/Type CheckingType mismatches and semantic issues can be handled while generating IC.

2. Difference Between DAG and Syntax Tree (3 marks)

FeatureSyntax TreeDAG (Directed Acyclic Graph)
DefinitionTree with operators at internal nodes and operands at leaves.Graph like a syntax tree but with common subexpressions shared as one node.
Common subexpressionsRepeated as separate subtrees.Shared using a single node.
Node parentsEach node has exactly one parent.A node may have multiple parents.
Space usageMore (duplication).Less (sharing).
Redundancy detectionDoes not expose redundant computation.Explicitly reveals repeated computations.
Typical useSemantic analysis, syntax-directed translation.Code optimization (common subexpression elimination).

Example: A + A * B

Syntax Tree (A duplicated):

      +
     / \
    A   *
       / \
      A   B

DAG (A shared):

      +
     / \
    |   *
     \ / \
      A   B

3. Quadruples and Triples for A = B + C - D * E + G (4 marks)

Three-Address Code

$$ \begin{aligned} t_1 &= B + C \ t_2 &= D * E \ t_3 &= t_1 - t_2 \ t_4 &= t_3 + G \ A &= t_4 \end{aligned} $$

Quadruple Representation: (op, arg1, arg2, result)

Indexoparg1arg2result
(0)+BC$t_1$
(1)*DE$t_2$
(2)-$t_1$$t_2$$t_3$
(3)+$t_3$G$t_4$
(4)=$t_4$-A

Triple Representation: (op, arg1, arg2) (result implied by position)

Indexoparg1arg2
(0)+BC
(1)*DE
(2)-(0)(1)
(3)+(2)G
(4)=A(3)

Quadruple vs Triple

QuadrupleTriple
ResultExplicit named temporaryImplicit (position index)
Fields43
Instruction reorderingEasyHard (position references break)
asked 2xavg 6 marks · 2080, 2075
Answer

What is three-address code? How high level code is converted to three address code? Illustrate with an example. [5]

Three-address code is an intermediate code representation where each instruction uses at most three addresses: two for operands and one for the result. Each instruction in three-address code is described as a 4-tuple: (operator, operand1...

asked 2xavg 5 marks · 2081, 2078
Answer

Compute the FIRST and FOLLOW of the non-terminals in the following grammar. S→(L)∣1S \rightarrow (L) \mid 1S→(L)∣1L→L;S∣εL \rightarrow L;S \mid \varepsilonL→L;S∣ε_[5]_

Grammar: $$S \rightarrow (L) \mid 1$$ $$L \rightarrow L,;,S \mid \varepsilon$$ - Non-terminals: $S$, $L$ - Terminals: $($, $)$, $1$, $;$ - Start symbol: $S$ --- FIRST(S): - $S \rightarrow (L)$ gives first symbol $($ - $S \rightarrow 1$...

asked 2xavg 6 marks · 2078, 2076
Answer

What are the disadvantages of shift reduce parsing. Perform shift reduce parsing of string w = (x-x). (x/x) for given grammar. E→E−E∣E/E∣(E)∣xE \rightarrow E-E | E/E |

(E) | xE→E−E∣E/E∣(E)∣x_[5]_

Grammar: $$E \rightarrow E - E \mid E / E \mid (E) \mid x$$ Input string: $w = (x-x).(x/x)$ Terminals visible in string: (, ), x, -, /, . Note on missing data: The grammar defines operators - and / only. The string contains a . (dot) ope...

Study every one of these with model answers, flashcards, and MCQs.

Open CSC376 study modes