0% found this document useful (0 votes)
6 views15 pages

Compilier Construction 2 Paper Solution

The document provides comprehensive solutions for Compiler Construction Papers 1 and 2, covering definitions, grammar analysis, lexical analysis, and parsing techniques. It includes specific questions with detailed answers on topics such as cross-compilers, basic blocks, SLR and LALR parsing, and semantic rules for expressions. Additionally, it features code examples for Lex programs and recursive descent parsers.

Uploaded by

armanmohd50584
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views15 pages

Compilier Construction 2 Paper Solution

The document provides comprehensive solutions for Compiler Construction Papers 1 and 2, covering definitions, grammar analysis, lexical analysis, and parsing techniques. It includes specific questions with detailed answers on topics such as cross-compilers, basic blocks, SLR and LALR parsing, and semantic rules for expressions. Additionally, it features code examples for Lex programs and recursive descent parsers.

Uploaded by

armanmohd50584
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 15

Here is the comprehensive solution for Compiler Construction Paper-1 and Paper-2, solving them

entirely from the beginning with proper explanations and structure.

Compiler Construction Paper-1

Q1: Attempt all of the following for 1 mark each.

a) Define the term Handle.


A handle is a substring of a string that matches the right-hand side of a production and represents a
reducible portion in a rightmost derivation.

b) What is a cross-compiler?
A cross-compiler is a compiler that generates executable code for a platform different from the one
on which it is running.

c) Lex is a scanner provided by Linux operating system. Justify True/False.


True. Lex is a tool in Unix/Linux used for generating lexical analyzers.

d) List all phases of the compiler in sequence.

1. Lexical Analysis

2. Syntax Analysis

3. Semantic Analysis

4. Intermediate Code Generation

5. Code Optimization

6. Code Generation

e) What is a parser?
A parser is a component of the compiler that checks the syntax of a source code by analyzing token
sequences to produce a parse tree.

f) LALR is the best bottom-up parsing method. State and justify True/False.
True. LALR parsers are memory efficient and powerful enough to handle most practical grammars.

g) Define Basic Block.


A basic block is a sequence of consecutive instructions in a program with only one entry point and
one exit point.
h) What is the use of Display?
Display is used in block-structured languages to manage access to non-local variables efficiently.

i) List code optimization techniques.

1. Dead code elimination

2. Loop unrolling

3. Common subexpression elimination

4. Strength reduction

j) What is a sentinel?
A sentinel is a special value that indicates the end of a data structure or simplifies boundary
condition handling.

Q2: Attempt all of the following for 2 marks each.

a) Write a short note on S-attributed grammar.


S-attributed grammar is a type of attribute grammar where all attributes are synthesized. Attributes
depend only on child nodes and are evaluated in a bottom-up traversal of the parse tree.

b) Find FIRST and FOLLOW of the grammar:


Given grammar:

S → AB

A → BS | b | ε

B → bSB' | SB' | aB'

B' → SSB' | ε

Solution:

FIRST:

 FIRST(S) = FIRST(A) = FIRST(B) = {a, b, ε}

 FIRST(A) = {b, ε}

 FIRST(B) = {a, b}

FOLLOW:

 FOLLOW(S) = {$}

 FOLLOW(A) = FOLLOW(S) = {$}


 FOLLOW(B) = {a, b}

c) What are the basic and auxiliary tasks of a lexical analyzer?


Basic Tasks:

1. Break the input into tokens.

2. Ignore whitespace and comments.

Auxiliary Tasks:

1. Generate error messages for invalid tokens.

2. Create symbol tables for identifiers.

d) Explain the value number method to construct DAG with an example.


Value Number Method: Assign a unique value number to subexpressions. Use the value numbers to
identify and eliminate common subexpressions.

Example:
For (a + b) * (a + b),

1. Assign value v1 to (a + b).

2. Reuse v1 for both occurrences of (a + b) in the DAG.

e) Construct the local & non-local variable scope or accessibility table for the following blocks:

A: X, Y, Z

B: a

C: H, Z

D: i, j

Block Local Variables Non-Local Variables

A X, Y, Z None

B a X, Y, Z

C H, Z X, Y, a

D i, j X, Y, Z

Q3: Attempt all of the following for 4 marks each.

a) Check whether the following grammar is SLR or not.


Grammar:
S → bAB | aA

A → Ab | b

B → aB | a

Solution:

1. Compute FIRST and FOLLOW sets.

2. Construct the parsing table.

3. Check for shift/reduce or reduce/reduce conflicts.


Result: The grammar is SLR(1) as no conflicts exist in the parsing table.

b) Write a Lex program to find the sum of N numbers.

%{

#include<stdio.h>

int sum = 0, num;

%}

%%

[0-9]+ {

sscanf(yytext, "%d", &num);

sum += num;

\n {

printf("Sum: %d\n", sum);

sum = 0;

.;

%%

int main() {

printf("Enter numbers separated by spaces (newline to compute sum):\n");

yylex();

return 0;
}

int yywrap() {

return 1;

c) Write a Recursive Descent Parser (RDP) for the grammar:


Grammar:

S → aA | SbB

A → aA | bB

B→b

Solution:

#include<stdio.h>

#include<stdlib.h>

char *input;

void S(), A(), B();

void match(char c) {

if (*input == c)

input++;

else {

printf("Error: Unexpected character\n");

exit(1);

void S() {

if (*input == 'a') {

match('a');
A();

} else if (*input == 'S') {

S();

match('b');

B();

} else {

printf("Error in S\n");

exit(1);

void A() {

if (*input == 'a') {

match('a');

A();

} else if (*input == 'b') {

B();

void B() {

match('b');

int main() {

input = "aabb$";

S();

if (*input == '$')

printf("Parsing Successful\n");

else

printf("Error: Input not fully consumed\n");


return 0;

Continuing with Compiler Construction Paper-2, solving all the questions comprehensively:

Compiler Construction Paper-2

Q1: Attempt all of the following for 1 mark each.

a) Define cross-compiler.
A cross-compiler generates code for a platform different from the one it runs on.

b) State the advantages of Bootstrapping.

1. Simplifies the process of writing a compiler.

2. Allows a compiler to compile itself.

3. Facilitates the development of portable compilers.

c) What is sentinel?
A sentinel is a special value or symbol used to indicate the end of a data structure or simplify
boundary conditions in an algorithm.

d) State the use of function retract().


In Prolog, retract() is used to remove facts or rules from the knowledge base.

e) Name the types of LR parsers.

1. Simple LR (SLR)

2. Look-Ahead LR (LALR)

3. Canonical LR

f) What does the second 'L' stand for in LL(1) parser?


It stands for Lookahead, referring to the single token used to decide the parsing action.

g) What is the purpose of augmenting the grammar?


Augmenting the grammar ensures a unique starting symbol and helps define end conditions for
parsing.
h) Define synthesized attribute.
A synthesized attribute is calculated based on the values of its child nodes in the parse tree.

i) What is a basic block?


A basic block is a straight-line sequence of instructions with one entry and one exit point, with no
branches except at the end.

j) Define DAG.
A Directed Acyclic Graph (DAG) is used in code optimization to identify and eliminate redundant
computations.

Q2: Attempt all of the following for 2 marks each.

a) Construct the DAG for the expression: b * (a + c) + (a + c) * d.

/ \

* *

/\ /\

b ++ d

/\/\

a ca c

b) What are the basic and auxiliary tasks of a lexical analyzer?

Basic Tasks:

1. Tokenize input into lexemes.

2. Ignore whitespace and comments.

Auxiliary Tasks:

1. Generate error messages for invalid tokens.

2. Maintain a symbol table for identifiers.

c) Write any two limitations of top-down parsing.

1. Cannot handle left-recursive grammars directly.

2. Requires backtracking, which may be inefficient for ambiguous grammars.


d) Define S-attributed and L-attributed grammar.

 S-attributed Grammar: All attributes are synthesized.

 L-attributed Grammar: Allows both synthesized and inherited attributes, but inherited
attributes depend only on the parent and left siblings.

e) Differentiate between top-down parsing and bottom-up parsing.

Top-Down Parsing Bottom-Up Parsing

Starts with the start symbol. Starts with the input tokens.

Constructs parse tree from root. Constructs parse tree from leaves.

Requires LL(1) grammar. Requires LR(1) grammar.

Q3: Attempt all of the following for 4 marks each.

a) Check whether the grammar is SLR or not.


Grammar:

S → 0A2

A → 1A1 | ε

Solution:

1. Compute FIRST and FOLLOW sets:

o FIRST(S) = {0}

o FOLLOW(S) = {$}

o FIRST(A) = {1, ε}

o FOLLOW(A) = {2, 1}

2. Construct LR(0) items and the parsing table.

3. Ensure no shift/reduce or reduce/reduce conflicts.

Conclusion: The grammar is SLR(1) as no conflicts exist in the parsing table.

b) Write a Lex program to find the sum of N numbers.

%{

#include<stdio.h>

int sum = 0, num;


%}

%%

[0-9]+ {

sscanf(yytext, "%d", &num);

sum += num;

\n {

printf("Sum: %d\n", sum);

sum = 0;

.;

%%

int main() {

printf("Enter numbers separated by spaces (newline to compute sum):\n");

yylex();

return 0;

int yywrap() {

return 1;

c) Write a Recursive Descent Parser (RDP) for the grammar:


Grammar:

S → aSa | sb | ss | b

Solution:

#include <stdio.h>

#include <stdlib.h>
char *input;

void S();

void match(char c) {

if (*input == c)

input++;

else {

printf("Error: Unexpected character\n");

exit(1);

void S() {

if (*input == 'a') {

match('a');

S();

match('a');

} else if (*input == 's') {

match('s');

if (*input == 'b') match('b');

else if (*input == 's') match('s');

} else if (*input == 'b') {

match('b');

} else {

printf("Error in S\n");

exit(1);

int main() {
input = "asa$";

S();

if (*input == '$')

printf("Parsing Successful\n");

else

printf("Error: Input not fully consumed\n");

return 0;

Q4: Attempt all of the following for 4 marks each.

a) Write the steps of creating a lexical analyzer using Lex. Explain the Lex library functions.

Steps:

1. Define patterns for tokens in the definitions section.

2. Write actions to execute upon recognizing patterns.

3. Compile the Lex program using lex and gcc.

4. Run the generated lexical analyzer.

Lex Functions:

1. yylex(): Begins scanning input.

2. yytext: Stores the matched lexeme.

3. yywrap(): Signals the end of input.

Remaining Solutions for Compiler Construction Paper-2

Q4b: Check whether the grammar is LALR(1) or not.

Grammar:

S → Aa | Ab | Bb | Ba

A→ε

B→ε

Solution:

1. Augment the grammar: Add S' → S.

2. Compute LR(1) items:

o Include lookahead symbols for each item.


3. Merge states with identical cores for LALR(1):

o Check if merging introduces shift/reduce or reduce/reduce conflicts.

Conclusion:
The grammar is LALR(1) because merging states does not introduce conflicts.

Q4c: For the input expression (2 + 3) * (3 + 4), design SDD and draw the annotated tree using the
given grammar.

Grammar:

L→E

E→E+T|T

T→T*F|F

F → (E) | digit

Semantic Rules:

 For E → E1 + T: E.val = E1.val + T.val

 For T → T1 * F: T.val = T1.val * F.val

 For F → digit: F.val = digit.val

 For F → (E): F.val = E.val

Annotated Tree:
For (2 + 3) * (3 + 4):

L.val = 35

E.val = 35

/\

E.val=5 T.val=7

| |

T.val=5 F.val=7

/\ /\

F.val=2 F.val=3

Result: The evaluated result of the expression is 35.

Q5: Attempt all of the following for 3 marks each.


Q5a: Consider the operator grammar

E → E + E | E * E | id

Construct the operator precedence relation table.

Symbol id + * ( ) $

id - >>- >>

+ < ><<>>

* < >><>>

( < <<<=-

) - >>- >>

$ < <<<- -

Q5b: Construct triple and indirect triple for the following string.

Expression: a + b + c + d + e ↑ f & x + b + c

Solution:

1. Triple Representation:

Index Operator Arg1 Arg2

1 + a b

2 + 1 c

3 + 2 d

4 + 3 e↑f

5 & 4 x

6 + 5 b+c

2. Indirect Triple Representation:

Index Statement Pointer

1 (+, a, b)

2 (+, 1, c)

3 (+, 2, d)

4 (+, 3, e ↑ f)

5 (&, 4, x)
Index Statement Pointer

6 (+, 5, b + c)

You might also like