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

COMPILERS

1. Solution:
Given Grammar:

S_S#A/A

A_>A&B/B

B_>ID

Semantic Rules:

S _> S#A: Multiply the values of S and A.

S _> A: If there's no '#', then the value of S is the same as A.

A _> A&B: Add the values of A and B.

A _> B: If there's no '&', then the value of A is the same as B.

B _> ID: The value of B is the actual numeric value of the identifier (ID).

Parse Tree for the given expression:

S#A

/ \

S A

/ \

A B

/ \

B ID

/ \

1 0

Evaluation: Applying the semantic rules to find the value:S = S#A = S * A = B * A = 10


* A = 10 * (A&B) = 10 * B = 10 * ID = 10 * 3 = 30
2. Solution:
Given Grammar:

S_>AS{printf(1)}

S_>AB{printf(2)}

A_>a{printf(3)}

B_>bC{printf(4)}

B_>db{printf(5)}

C_>c{printf(6)}

Top-Down Parsing:

1. Top-Down Parsing Steps:


 Start with S and try to match the input "aadbc."
 Apply production rules based on the current non-terminal.
 Repeat until the entire input is matched.

2. Top-Down Parsing for "aadbc":


S _> AS
_> aAS
_> aaAS
_> aadBS
_> aadbCS
_> aadbcS{printf(1)}

Bottom-Up Parsing:

1. Bottom-Up Parsing Steps:


 Start with the input "aadbc."
 Apply reduction rules to group the input into non-terminals.
 Repeat until the start symbol is reached.

2. Bottom-Up Parsing for "aadbc":


aadbc
Aadc // Apply A _> a
AaBc // Apply A _> a
AaBC // Apply B _> bC
AaC // Apply B _> db
AaC{printf(4)} // Apply C _> c
AS{printf(2)}{printf(1)} // Apply S _> AB
3. SDT:
Syntax Directed Translation (SDT) is a technique used in the process of converting high-level
programming languages into machine code. It involves attaching specific actions to the
grammar rules of a programming language, which enables the automatic generation of
intermediate code or executable code from source code.

Types of SDT
1. S-attributed SDT :
 If an SDT uses only synthesized attributes, it is called as S-attributed SDT.
 S-attributed SDTs are evaluated in bottom-up parsing, as the values of the parent
nodes depend upon the values of the child nodes.
 Semantic actions are placed in rightmost place of RHS.

2. L-attributed SDT:
 If an SDT uses both synthesized attributes and inherited attributes with a restriction
that inherited attribute can inherit values from left siblings only, it is called as L-
attributed SDT.
 Attributes in L-attributed SDTs are evaluated by depth-first and left-to-right parsing
manner.
 Semantic actions are placed anywhere in RHS.

Advantages of Syntax Directed Translation:

 Ease of implementation
 Separation of concerns
 Efficient code generation

Disadvantages of Syntax Directed Translation:

 Limited expressiveness
 Inflexibility
 Limited error recovery
4. Type Checking:
Type checking is a crucial phase in the compilation process of a programming language. It
is the process of verifying and enforcing the consistency of types in a program according to
the language's type system rules. The primary goal of type checking is to ensure that
operations performed on variables and expressions are semantically valid and conform to
the intended usage of types.

Here are key aspects of type checking:


1. Verification of Compatibility:

Type checking ensures that operations and assignments involve compatible data types,
preventing mismatches such as adding a string to an integer.

2. Function Signature Matching:

Ensures that function calls match the expected function signatures in terms of the number
and types of arguments and the return type.

3. Array and Pointer Safety:

Prevents errors related to array bounds, illegal memory access, and pointer type mismatches
to enhance program security.

4. Static vs. Dynamic Typing:

In statically typed languages, type checking is performed at compile-time, catching errors


early. In dynamically typed languages, type checking occurs at runtime.

5. Overall Program Reliability:

Enhances program reliability by identifying type-related errors before program execution,


contributing to software quality and maintainability.
5. Intermediate code generation:
Intermediate code generation is a phase in the compilation process of a programming
language where a high-level source code is translated into an intermediate representation
that serves as a bridge between the source code and the target machine code. The main
purpose of generating intermediate code is to simplify the subsequent phases of the
compiler, such as optimization and code generation for the target machine.

Key aspects of intermediate code generation:


Abstraction from Source Code: Intermediate code serves as an abstract representation of
the high-level source code, capturing essential semantics while omitting low-level details.

Language-Independent Representation: Designed to be language-independent, allowing


for common optimization techniques to be applied across different high-level programming
languages.

Simplification for Code Generation: Breaks down complex language constructs into
simpler, more uniform operations, simplifying the subsequent phase of code generation for
the target machine.

Different Forms of Intermediate Code: Intermediate code can take various forms, such as
Three-Address Code (TAC) or Static Single Assignment (SSA) form, each suited for
different optimization strategies.

Facilitation of Optimization: Enables optimization techniques to be applied on the


intermediate code before translating it into the final target machine code, improving the
overall performance of the compiled program.

Three Address Code:


Three-Address Code (TAC) is a type of intermediate code representation used in compiler
design and optimization. It is named "three-address" because each statement in this code
typically involves at most three operands. The primary purpose of TAC is to simplify the
representation of complex expressions and control flow structures from the high-level
source code.

Key features of Three-Address Code:

 Operands and Operators


 Simplicity and Linearity
 Temporary Variables
 Basic Operations

You might also like