Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

COMPILER DESIGN SOLUTION(2020-21)

1.
a. .A parser generator is a program that takes as input a specification of a
syntax, and produces as output a procedure for recognizing that
language. Historically, they are also called compiler-compilers.
YACC (yet another compiler-compiler) is an LALR(1) (LookAhead,
Left-to-right, Rightmost derivation producer with 1 lookahead token)
parser generator. YACC was originally designed for being
complemented by Lex.

b. .
c. Follow(B) = {a,$}
d. .Shift Reduce parser attempts for the construction of parse in a
similar manner as done in bottom-up parsing i.e. the parse tree is
constructed from leaves(bottom) to the root(up). A more general form
of the shift-reduce parser is the LR parser.
e. .ab – cd + *ab -+
f. .In the analysis-synthesis model of a compiler, the front end of a
compiler translates a source program into an independent intermediate
code, then the back end of the compiler uses this intermediate code to
generate the target code (which can be understood by the machine).
g. .Control stack is a run time stack which is used to keep track of the
live procedure activations i.e. it is used to find out the procedures
whose execution have not been completed.
i. When it is called (activation begins) then the procedure name
will push on to the stack and when it returns (activation ends)
then it will popped.
ii. Activation record is used to manage the information needed by
a single execution of a procedure.
iii. An activation record is pushed into the stack when a procedure
is called and it is popped when the control returns to the caller
function.
h. Hashing is one of the searching techniques that uses a constant time.
The time complexity in hashing is O(1). Till now, we read the two
techniques for searching, i.e., linear search and binary search.
i. Expressions with constant operands can be evaluated at compile time,
thus improving run-time performance and reducing code size by
avoiding evaluation at compile-time. Example: In the code fragment
below, the expression (3 + 5) can be evaluated at compile time and
replaced with the constant 8.
j. 1 Input to the Code Generator
2 The Target Program
3 Instruction Selection
4 Register Allocation
5 Evaluation Order

2. .
a. .Lexical Analysis
This is the first step that works as an integration between the compiler and the
source language code. It reads the source code one character at a time and designs
a source code into a series of atomic units known as tokens.
In this phase, we will see how we can tokenize the expression.
A → Identifier: (id, 1)
= → Operator: Assignment
B → Identifier: (id, 2)
* → Operator: Multiplication
C → Identifier: (id, 3)
+ → Operator: Binary Addition
20 → Constant: Integer
The final expression is as follows −
id1=id2*id3+20
● Syntax Analysis
It is also known as the parser. It receives tokens as its input generated from the
previous phase (lexical analysis) and produces a hierarchical structure called
syntax tree or parse tree.
In this phase, it can check the syntax after tokenized the expression.
Syntax Analysis for the expression is as follows −

● Semantic Analysis
This phase makes the syntax tree input and determines the semantical accuracy of
the program. However, the tokens are accurate and syntactically right; they may be
precise, not semantically. Hence the semantic analyzer determines the semantics
(meaning) of the statements construct. In this phase, it can verify the type and
semantic action for the syntax tree.
● Intermediate Code Generation
This phase takes the syntactically and semantically correct form as input and
produces the same intermediate notation of the source code. In this phase, we will
provide a changed parse tree and as output after transforming into the Intermediate
program will create a three-address code.
T1=id2 * id3
T2=int to real (20)
T3=T1+T2
id1=T3
● Code Optimization
It is an optional phase. It converts the intermediate representation of the source
program into an efficient code. In this phase, it would look as an input will provide
three address code and as an output, and it will identify the optimized code.
T1=id2 * id3
id1=T1+ 20.0
● Code Generation
This is the final step of the compilation process. It converts optimized intermediate
code into Machine/Assembly code. It allocates memory locations for variables in
the program.
In the last phase, it can see how can modify the final expression into the assembly
program.
b.
c. .
d. .Lexical phase errors
These errors are detected during the lexical analysis phase. Typical lexical errors
are

● Exceeding length of identifier or numeric constants.


● Appearance of illegal characters
● Unmatched string
Syntactic phase errors
These errors are detected during syntax analysis phase. Typical syntax errors
are

Errors in structure
Missing operator
Misspelled keywords
Unbalanced parenthesis

e. Loop Optimization is the process of increasing execution speed and


reducing the overheads associated with loops. It plays an important
role in improving cache performance and making effective use of
parallel processing capabilities. Most execution time of a scientific
program is spent on loops.
Loop Optimization Techniques:
Frequency Reduction (Code Motion):
In frequency reduction, the amount of code in loop is decreased. A
statement or expression, which can be moved outside the loop body
without affecting the semantics of the program, is moved outside the
loop.
Example:
Initial code:

while(i<100)
{
a = Sin(x)/Cos(x) + i;
i++;
}

Optimized code:

t = Sin(x)/Cos(x);
while(i<100)
{
a = t + i;
i++;
}
Loop Unrolling:
Loop unrolling is a loop transformation technique that helps to
optimize the execution time of a program. We basically remove or
reduce iterations. Loop unrolling increases the program’s speed by
eliminating loop control instruction and loop test instructions.
Example:
Initial code:

for (int i=0; i<5; i++)


printf("Pankaj\n");

Optimized code:

printf("Pankaj\n");
printf("Pankaj\n");
printf("Pankaj\n");
printf("Pankaj\n");
printf("Pankaj\n");
Loop Jamming:
Loop jamming is the combining the two or more loops in a single
loop. It reduces the time taken to compile the many number of loops.
Example:
Initial Code:

for(int i=0; i<5; i++)


a = i + 5;
for(int i=0; i<5; i++)
b = i + 10;

Optimized code:
for(int i=0; i<5; i++)
{
a = i + 5;
b = i + 10;
}

3. .
a. .(((aa+bb)*(ab+ba))*+((ab+ba)(aa+bb)*)*)
b.
First Leftmost derivation
E→E+E
→ id + E
→ id + E - E
→ id + id - E
→ id + id- id
Second Leftmost derivation
E→E-E
→E+E-E
→ id + E - E
→ id + id - E
→ id + id - id
i. .
ii. Cross compilers are programs that are capable of producing
executable code that can be run on a platform that is currently
not the resident platform for the compiler. They are commonly
used when a developer needs to use multiple platforms in order
to handle computing functions, such as in embedded systems
where each embedded computer within the system has a smaller
amount of resources. Using a cross compiler makes it possible
to overcome this lack of resources by creating an interrelated
execution between various components on the system.
One example of when a cross compiler might be used is when
microcontrollers are in use within a system. Generally, a
microcontroller does not contain a great deal of memory, so
when this program is used to handle the creation and issue of
execution of commands, less of the resources for the
microcontroller are tied up in administrative orders. This means
that they can be directed toward performing the task ordered by
the compiler.

4. .

a.

b.
5. .
6. .
a. Symbol Table is an important data structure created and maintained
by the compiler in order to keep track of semantics of variables i.e. it
stores information about the scope and binding information about
names, information about instances of various entities such as variable
and function names, classes, objects, etc.
It is built-in lexical and syntax analysis phases.
The information is collected by the analysis phases of the compiler and is
used by the synthesis phases of the compiler to generate code.
It is used by the compiler to achieve compile-time efficiency.
It is used by various phases of the compiler as follows:-
b. Lexical Analysis: Creates new table entries in the table, for example
like entries about tokens.
c. Syntax Analysis: Adds information regarding attribute type, scope,
dimension, line of reference, use, etc in the table.
d. Semantic Analysis: Uses available information in the table to check
for semantics i.e. to verify that expressions and assignments are
semantically correct(type checking) and update it accordingly.
e. Intermediate Code generation: Refers symbol table for knowing
how much and what type of run-time is allocated and table helps in
adding temporary variable information.
f. Code Optimization: Uses information present in the symbol table for
machine-dependent optimization.
g. Target Code generation: Generates code by using address
information of identifier present in the table.
Symbol Table entries – Each entry in the symbol table is associated
with attributes that support the compiler in different phases.

Items stored in Symbol table:


● Variable names and constants
● Procedure and function names
● Literal constants and strings
● Compiler generated temporaries
● Labels in source languages
Information used by the compiler from Symbol table:
Data type and name
Declaring procedures
Offset in storage
If structure or record then, a pointer to structure table.
For parameters, whether parameter passing by value or by reference
Number and type of arguments passed to function
Base Address

B. The scope of a variable x in the region of the program in which the


use of x refers to its declaration. One of the basic reasons for scoping
is to keep variables in different parts of the program distinct from one
another. Since there are only a small number of short variable names,
and programmers share habits about naming of variables (e.g., I for an
array index), in any program of moderate size the same variable name
will be used in multiple different scopes.
Scoping is generally divided into two classes:
1. Static Scoping
2. Dynamic Scoping

You might also like