Assighnment-4 Compiler Design
Assighnment-4 Compiler Design
MANDATORY QUESTIONS
QUESTION-1:
ANSWER:
➢ It is used in compiler design and plays a crucial role in the process of transforming the
source code of a programming language into an intermediate or target language.
3.Tree Traversal:
- SDTS often involves the construction and traversal of abstract syntax trees (ASTs) derived
from the source code. The semantic actions associated with the grammar rules are executed as
the tree is traversed, allowing for the generation of intermediate code or other representations.
4.Code Generation and Optimization:
- The semantic actions specified in the SDTS are instrumental in generating target code or an
intermediate representation. Additionally, optimization strategies can be applied during this
translation process to improve the efficiency and performance of the resulting code.
ANSWER:
QUESTION-3
What are the advantages of SDT? Give SDT to translate a*- (b + c) into syntax tree.
ANSWER:
2.Separation of Concerns:
- SDTs enable the separation of syntax and semantics, making it easier to modify or extend
the translation process without affecting the entire compiler. This modular approach enhances
maintainability and facilitates the addition of new features.
3.Ease of Implementation:
- Implementing a compiler or translator becomes more straightforward with the use of SDTs.
The direct association of semantic actions with grammar rules simplifies the task of generating
intermediate code or performing other translation tasks.
4.Consistency:
- SDTs ensure consistency between the syntax and semantics of a programming language. By
explicitly defining the translation rules, errors and inconsistencies can be detected early in the
development process.
6.Error Handling:
- SDTs can be designed to include error-handling mechanisms. Semantic actions associated
with error detection and recovery can be incorporated into the translation process, improving
the robustness of the compiler.
7.Intermediate Representation:
- SDTs play a key role in generating intermediate representations (such as abstract syntax trees)
that serve as a bridge between the source and target languages. This abstraction simplifies
subsequent phases of the compilation process.
ANSWER:
Intermediate Code
➢ Intermediate code is an abstraction used in compiler design to represent the high-level
source code in a form that is closer to the machine code but is still independent of the
target machine architecture.
➢ It serves as an intermediate representation between the source code and the target code
generated by a compiler.
2.Polish Notation
3.Three-address code
1.Abstract syntax tree- The natural hierarchical structure is represented by syntax trees.
The code being generated as Intermediate should be such that the remaining processing of
subsequent phase should be easy. Consider the input string. x= -a*b+-a*b
2.Polish Notation- Basically the linearization of syntax tree is polish notation in this
representation, the operator can be easily associated with the corresponding operands
this is the most natural way of representation in expression evaluation.
➢ The polish notation is also called prefix notation where the operator occurs first and then
operands are arranged.
➢ Ex- Construct the syntax free & postfix notation for the following expression .
(a+(b*c))^d-e/(f+g)
3.THREE ADDRESS CODE- In three-address code there are atmost three address are used to
represent any statement. The general form of three- address code representation is
a:=b operator c
Where a, b, c are operands that can be named, constants, compiler generated variable. The
operators can be fixed or floating point arithmetic operator logical operator.
For Ex-Consider the statement a = b+c+d, the three address code for it is as follows -
a=b+c+d t₁=b+c
t2=t₁+d
a=t2
QUESTION-5
Write quadruple, triple and indirect triple for the following expressions: (x + y)*(y + z)+
(x+y+z).
ANSWER:
QUESTION-8
Write the translation procedure for control statement and switch statement
ANSWER:
if (condition) {
// Code for true branch
} else {
// Code for false branch
}
1.Translation Procedure:
- Evaluate the condition.
- If the condition is true, execute the code for the true branch; otherwise, execute the
code for the false branch.
Three-Address Code (Example):
- Assuming the condition is represented by `cond`, and the true and false branches are
represented by `true_code` and `false_code` respectively:
t1 = evaluate(cond)
if t1 goto L1
goto L2
L1: true_code
goto L3
L2: false_code
L3:
- In this example, `L1`, `L2`, and `L3` are labels representing different points in the
code. The `goto` statements transfer control based on the evaluation of the condition.
switch (expression) {
case constant1:
// Code for case 1
break;
case constant2:
// Code for case 2
break;
//... other cases...
default:
// Code for the default case
}
```
Translation Procedure:
- Evaluate the expression.
- Compare the expression value with each constant in the `case` statements.
- If a match is found, execute the corresponding code and break out of the `switch`. If
no match is found, execute the code for the `default` case.
QUESTION-9
ANSWER:
Postfix translation, also known as postfix notation or Reverse Polish Notation (RPN),
is a way of representing mathematical expressions where the operators follow their
operands. In postfix notation, there are no parentheses, and the order of operations is
determined solely by the position of the operators.
The process of postfix translation involves converting an infix expression (the standard
mathematical notation with operators placed between operands) into postfix notation.
This translation is useful for simplifying expression evaluation, especially in computer
programs and calculators.
3.Handle parentheses:
- If an opening parenthesis is encountered, push it onto the stack.
- If a closing parenthesis is encountered, pop operators from the stack and add them to
the output until an opening parenthesis is encountered. Pop and discard the opening
parenthesis.
4.After processing the entire expression, pop any remaining operators from the stack and
add them to the output.
The resulting postfix expression is a b c * + d e / f + -.
➢ The resulting value on the stack is the final result of the expression.
➢ The postfix notation allows for a straightforward evaluation of expressions
without the need for complex parsing rules.
QUESTION-10
Translate the following expression into quadruple, triple and indirect triple: -(a +b) * (c
+ d) – (a + b + c)
QUESTION-11
ANSWER:
QUESTION-12
ANSWER:
➢ It is used in compiler design and plays a crucial role in the process of transforming the
source code of a programming language into an intermediate or target language.
For this, Our task is to convert it into a program that implement the input/output
mapping.
Syntax Analysis is not sufficient, the language required something more beyond it.
Hence, Semantic analysis is done to Handle issues beyond it.
The static analysis can be used by Syntax Directed Definition (SDD) and the
process of executing the code fragment from the SDD is called syntax directed
translation, which is known as syntax directed translation Scheme (SDTS).
2.Intermediate Code
➢ Intermediate code is an abstraction used in compiler design to represent the high-level
source code in a form that is closer to the machine code but is still independent of the
target machine architecture.
➢ It serves as an intermediate representation between the source code and the target code
generated by a compiler.
b. Polish Notation
c. Three-address code
3. Backpatching:
4.Syntax tree:
A syntax tree, also known as a parse tree or concrete syntax tree, is a hierarchical tree-
like data structure that represents the syntactic structure of a source code or expression
according to the rules of a formal grammar. In the context of compiler design and
programming languages, syntax trees are commonly used to depict the hierarchical
structure of program statements.Here are key points defining a syntax tree:
i. Representation of Syntax:
- A syntax tree represents the grammatical structure of a program or expression,
illustrating how different components (tokens, operators, and operands) are
hierarchically related based on the language's syntax rules.
ii. Hierarchical Structure:
- The tree has a hierarchical structure where each node corresponds to a syntactic
element, and the relationships between nodes indicate how these elements are combined
to form larger constructs.
iii. Nodes and Edges:
- Nodes in the tree represent different syntactic elements, such as expressions,
statements, operators, or operands. Edges between nodes represent the syntactic
relationships between these elements.
iv. Root Node:
- The root of the syntax tree corresponds to the entire program or expression. It is the
highest-level construct that encompasses all other syntactic elements.
v. Internal Nodes:
- Internal nodes represent non-terminal symbols in the grammar and correspond to
higher-level constructs in the program or expression.
vi. Leaf Nodes:
- Leaf nodes represent terminal symbols in the grammar, such as identifiers, constants,
or keywords. They are the basic building blocks of the syntax tree.
vii. Branching Structure:
- The branching structure of the tree reflects the nested and hierarchical nature of the
syntactic constructs. Nodes with children represent compound constructs, while nodes
with no children (leaf nodes) represent atomic elements.
Example:
For the expression `a + (b * c)`, the syntax tree might look like:
+
/\
a *
/\
b c
➢ The construction and traversal of syntax trees are integral parts of the parsing
phase in compiler design.
5. Parse tree:
A parse tree, also known as a derivation tree or concrete syntax tree, is a graphical
representation of the syntactic structure of a source code according to the rules of a
formal grammar. In the context of compiler design and programming languages, parse
trees are constructed during the parsing phase of compilation to illustrate how the source
code is derived from the grammar rules.
1.Representation of Derivation:
- A parse tree represents the derivation of the source code from the production rules of
a formal grammar. It visually shows how the input string is decomposed into smaller
syntactic units until reaching the terminal symbols.
2.Hierarchical Structure:
- Like a syntax tree, a parse tree has a hierarchical structure. Each level of the tree
corresponds to a step in the derivation process, starting from the start symbol of the
grammar and progressing to the input string.
4.Root Node:
- The root of the parse tree corresponds to the start symbol of the grammar. It
represents the entire input string being parsed.
5.Internal Nodes:
- Internal nodes represent non-terminal symbols in the grammar. They correspond to
the application of production rules and the creation of new syntactic units.
6.Leaf Nodes:
- Leaf nodes represent terminal symbols in the grammar. They correspond to actual
tokens or lexemes in the input string.
7.Branching Structure:
- The branching structure of the tree reflects the application of different production
rules during the parsing process. Each branch represents a specific alternative in the
grammar.
Example:
- For a simple arithmetic expression like `2 + 3 * 4`, the parse tree might look like:
+
/\
2 *
/\
3 4
Parse trees are useful in understanding the syntactic structure of a program and in
debugging the parsing process.
QUESTION-13
ANSWER: