2015
2015
b) Describe the various phases of compiler in detail. Trace the output of each phase for the
program segment position = initial + rate*60 where rate is real data type.
1. Lexical analysis: The first phase of a compiler is called lexical analysis or scanning. The lexical
analyzer reads the stream of characters making up the source program and groups the
characters into meaningful sequences called lexemes. For each lexeme, the lexical analyzer
produces as output a token that it passes on to the subsequent phase, syntax analysis. In the
token, the first component token-name is an abstract symbol that is used during syntax
analysis, and the second component attribute-value points to an entry in the symbol table for
this token.
The assignment statement, position = initial + rate * 60 can be represented as a sequence of
tokens after lexical analysis as
2. Syntax analysis: The second phase of the compiler is syntax analysis or parsing.
The parser uses
the rst components of the tokens produced by the lexical analyzer to creat
arguments of the operaThe second phase of the compiler is syntax analysis or parsing. The
parser uses the first components of the tokens produced by the lexical analyzer to create a
tree-like intermediate representation that depicts the grammatical structure of the token
stream. A typical representation is a syntax tree in which each interior node represents an
operation and the children of the node represent the arguments of the operation.
The syntax tree for the given statement can be represented as,
3. Semantic analysis: The semantic analyzer uses the syntax tree and the
information in the symbol
table to check the source program for semantic consistency with the languageA
semantic analyzer traverses the abstract syntax tree, checking that each node is appropriate for its
context, i.e., it checks for semantic errors. It outputs a refined abstract syntax tree.
temp1 = inttoreal(60)
id1 = temp3
5. Optimization:
An optimizer reviews the code, looking for ways to reduce the number of operations and
the memory requirements.
6. Code generation:
It produces either machine code for a specifific machine, or assembly code for a
specifific machine and assembler. If it produces assembly code, then an assembler is
used to produce the machine code.
The intermediate code may be translated into the assembly code as,
C) What are the functions performed when the preprocessor produce input to compilers?
Ans: The second phase of the compiler is syntax analysis or parsing.CFG is used in parsing for
figuring out how to derive the string of tokens obtained from the lexer from the start symbol of
the grammar, and if it cannot be derived from the start symbol of the grammar, then reporting
syntax errors within the string.
B) ans:Symbol-table entries are created and used during the analysis phase by the lexical
analyzer, the parser, and the semantic analyzer.In some cases, a lexical analyzer can create a
symbol-table entry as soon as it sees the characters that make up a lexeme. More often, the
lexical analyzer can only return to the parser a token, say id, along with a pointer to the lexeme.
Only the parser, however, can decide whether to use a previously created symbol-table entry or
create a new one for the identifier.
C)(+ er jaigai * dite hobe mone hoy)
Annotated parse tree for 95-2*(+ er jaigai * dite hobe mone hoy)
3. a)Why use regular expressions to define the lexical syntax of a language?
Ans:
Reasons :
Spaces.
B) ans:
Ans: . Yacc stands for ‘yet another compiler-compiler’. Yacc is available as a command
on the UNIX system, and has been used to help implement many production compilers.
4.
a) Give the comparison among parse tree, syntax tree and DAG. Draw the DAG for the
expression
a+a+(a+a+a+(a+a+a+a))
Like the syntax tree for an expression, a DAG has leaves corresponding to atomic operands and
interior nodes corresponding to operators. The dierence is that a node N in a DAG has more
than one parent if N represents a common subexpression; in a syntax tree, the tree for the
common subexpression would be replicated as many times as the subexpression appears in the
original expression. Thus, a DAG not only represents expressions more succinctly, it gives the
compiler important clues regarding the generation of efficient code to evaluate the expressions.
Fig: DAG for a+a+…
B) ans:
In other words, if A → α is a production, then A’s synthesized attributes are determined by the
attributes of the symbols in α.
An inherited attribute is a property of a symbol (node) that is determined by its parent node
and its siblings in the parse tree.
In other words, if β is symbol on the right side of the production A → αβλ, then β’s inherited
attributes are determined by the attributes of A and the other symbols in α and λ.
(example)
Ans: A dependency graph depicts the flow of information among the attribute instances
in a particular parse tree; an edge from one attribute instance to another means that the
value of the first is needed to compute the second. Edges express constraints implied by
the semantic rules.
In more detail:
B) ans:
a)The first “L" in LL(1) stands for scanning the input from left to right, the second “L" for
producing a leftmost derivation.
with backtracking, to go into an infinite loop. That is, when we try to expand
B)
C)
D)
7
a)
Fig: SDD
(3 er jaigai 8, 5 er jaigai 4 hbe)
Ans:
C)ans:
D)
8.a what do you mean by basic block and flow graph?
Ans: Basic blocks are maximal sequences of three-address instructions of the intermediate code
with the property that-
1. The flow of control can enter the e basic block through the first instruction in the block. That
is, there are no jumps into the middle of the block.
2. Control will leave the block without halting or branching, except possibly at the last
instruction in the block.
Flow graph:Flow graph represent the flow of control between the basic blocks. The nodes of
the flow graph are the basic blocks. There is an edge from block B to block C if and only if it is
possible for the first instruction in block C to immediately follow the last instruction in block
B.There are two ways that such an edge could be justified:
2. C immediately follows B in the original order of the three-address instructions and B does not
end in an unconditional jump.
B)
B. i. ans: Here, instructions 1, 3 and 13 are leaders.The basic block of each leader contains all
the instructions from itself until just before the next leader. Thus, the basic block of 1 consists
of instructions 1,2. The basic block of instruction 3 consists of instructions 3 through
12,inclusive. The basic block of 13 would consist of all instructions from 3 until just before the
next leader. The figure-1 shows the flow graph with basic block of instruction 1 and 3
Entry
B1 Prod := 0
i := 1
Arrow ta opposite
direction e hbe,
(3 to 12)
B2
Exit
ii. t1:=4*i t1:=4*i
t2:=a[t1] t2:=a[t1]
t3:=4*i t4:=b[t1]
t4:=b[t3] t5:=t2*t4
t5:=t2*t4 t6:=prod+t5
t6:=prod+t5 prod:=t6
prod:=t6 t7:=i+1
t7:=i+1 i:=t7
i:=t7 If i<=20 goto B2
If i<=20 goto B2
ii)Structure-Preserving Transformations:
The primary Structure-Preserving Transformation on basic blocks are:
Example:
a: =b+c
b: =a-d
c: =b+c
d: =a-d
The 2nd and 4th statements compute the same expression: b+c and a-d
a: = b+c
b: = a-d
c: = a
d: = b
It is possible that a large amount of dead (useless) code may exist in the program. This
might be especially caused when introducing variables and procedures as part of construction or
error-correction of a program - once declared and defined, one forgets to remove them in case
they serve no purpose. Eliminating these will definitely optimize the code.
• Two statements
t1:=b+c
t2:=x+y
can be interchanged or reordered in its computation in the basic block when value of t1 does not
affect the value of t2.
ii)There are a number of ways in which a compiler can improve a program without changing the
function it computes. These are called function-preserving transformation.
dead-code elimination, and constant folding are common examples of such transformation.
Common-subexpression elimination:
The assignments to t7 and t10 in Fig. (a) compute the common subexpressions 4*i and 4*j,
respectively. These steps have been eliminated in Fig. (b), which uses t6 instead of t7 and t8
instead of t10.
copy propagation:
The idea behind the copy-propagation transformation is to use v for u, wherever possible after
the copy statement u = v.
x = t3
a[t2] = t5
a[t4] = t3
goto B2
statements that compute values that never get used. For example:
Constant Folding: Deducing at compile time that the value of an expression is a constant and
using the constant instead is known as constant folding.