Professional Documents
Culture Documents
Compiler Design KCS5
Compiler Design KCS5
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
Errors in structure
Missing operator
Misspelled keywords
Unbalanced parenthesis
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:
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:
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.