You are on page 1of 13

Mid-ASSIGNMENT

Submitted to:
NAZIA ALFAZ
Assistant Professor
Department of CS
American International University- Bangladesh.

Submitted by:
ASHIKUR RAHAMAN JOY
Student ID: 19-41174-2
Course: Compiler Design.
Section: A
Department of CSE
American International University- Bangladesh.

Date of submission: 30/10/2021.


Answer to the Question No-2
Chapter-1 & 2
(Intro to Language Processors & Language Processing System)

Basic things of a Compiler


1. What is a Compiler?
A compiler is a program that reads a program written in one language and translates it
into another language.
2. Why do we need a compiler?
We need a compiler to execute the program. Because computer can't understand the
source code directly. It will understand only object level code.
Source codes are human readable format but the system cannot understand it.
So, the compiler is intermediate between human readable format and machine-readable
format.
3. Why study compilers?
✓ Machine Code Generation
✓ Format Converter
✓ Finite Automata
✓ Data Structures
✓ Computer Architectures
✓ Optimization Techniques

Language processors
There are some common language processors are:
1. Compiler
2. Interpreter
3. Preprocessor
4. Assembler
1. Compiler:

A compiler is a program that reads a program written in one language and translates it
into another language.

Human Readable Format Computer Understandable Forman

Programming Compiler Object


Language File

If the target program is an executable machine-language program, it can then be called by


the user to process inputs and produce outputs

Input Target Program Output

Fig: Running the target program.

Example:

X=a+b*10 Compiler MOV id3, R2


MUL #10.0,
R2
MOV id2, R1
ADD R2, R1
MOV R1, R1
2. Interpreter:
An interpreter is another common kind of language processor. Instead of producing a target
program as a translation, an interpreter appears to directly execute the operations specified
in the source program on inputs supplied by the user.

Source Program
Interpreter Output
Input

3. Preprocessor
Preprocessing performs (usually simple) operations on the source file(s) prior to
compilation.

4. Assembler
An Assembler is a translator that translates Assembly language to machine code. So, an
assembler is a type of a compiler and the source code is written in Assembly language.

Assembly Program Assembler Machine program

Differences between Compiler and Interpreter

Compiler Interpreter

Compiler takes whole program as input Interpreter takes single instruction as input

Intermediate Object code is generated No intermediate Object code is generated

Memory requirement more Memory requirement is less

Program need not be compiled every time Every time higher level program is converted
into lower level program

Programming languages like C, C++, Java use Programming languages like JavaScript,
compilers. Python, Ruby use interpreters.
Language Processing System
Answer to the Question No-3
The Phases of a Compiler
1. Lexical Analyzer:
The first phase of scanner works as a text scanner. This phase scans the source code as a
stream of characters and converts it into meaningful lexemes. Lexical analyzer represents
these lexemes in the form of tokens as:
p o s i t i o n = i n i t i a l + r a t e * 60

(i d , l ) (=) (id, 2) (+) (id, 3) (*) (60)

Lexical Errors: A lexical error is a mistake in a lexeme, for examples, typing tehn
instead of then, or missing off one of the quotes in a literal.

2. Syntax Analyzer:
The next phase is called the syntax analysis or parsing. It takes the token produced by
lexical analysis as input and generates a parse tree (or syntax tree). In this phase, token
arrangements are checked against the source code grammar, the parser checks if the
expression made by the tokens is syntactically correct.
Syntax Error: A grammatical error is a one that violates the (grammatical) rules of the
language, for example if x = 7 y := 4 (missing then).

3. Semantic Analyzer:
Semantic analysis checks whether the parse tree constructed follows the rules of
language. For example, assignment of values is between compatible data types, and
adding string to an integer. Also, the semantic analyzer keeps track of identifiers, their
types and expressions; whether identifiers are declared before use or not etc. The
semantic analyzer produces an annotated syntax tree as an output.

4. Intermediate Code Generator:


After semantic analysis the compiler generates an intermediate code of the source code
for the target machine. It represents a program for some abstract machine. It is in between
the high-level language and the machine language. This intermediate code should be
generated in such a way that it makes it easier to be translated into the target machine
code.

5. Code Optimizer:
The next phase does code optimization of the intermediate code. Optimization can be
assumed as something that removes unnecessary code lines, and arranges the sequence of
statements in order to speed up the program execution without wasting resources (CPU,
memory).
6. Code Generator:
In this phase, the code generator takes the optimized representation of the intermediate
code and maps it to the target machine language. The code generator translates the
intermediate code into a sequence of (generally) re-locatable machine code. Sequence of
instructions of machine code performs the task as the intermediate code would do.
The Phases of a Compiler

position := initial + rate * 60

Lexical Analyzer

(id1) (:= ) (id2) (+) (id3) (*) (60)

Syntax Analyzer

:=
id1 +
id2 *
id3 60

Semantic Analyzer
:=
id1 +
id2 *
id3 inttofloat
60

Intermediate Analyzer
temp1 := inttofloat(60)
temp2 := id3 * temp1
temp3 := id2 + temp2
id1 := temp3

Code Optimizer

temp1 := id3 * 60.0


id1 := id2 + temp1

Code Generator
MOVF R2,id3
MULF R2,#60.0
MOVF R1,id2
ADDF R1, R2
MOVF id1,R1
Answer to the Question No-4
1.
Variables = {E,F,T}
Terminals = {4,2,3}
Production/Rules = E → E + T | E - T | T
T→T*F|F
F→a|4|2|3
Start Variable = {E}
String: 4+2*3
Derivation : E->E+T
->T+T
->F+T
->4+T
->4+T*F
->4+F*F
->4+2*F
->4+2*3

2.
String: aabbb
Variables = {S, A, B}
Terminals = {a, b}
Production/Rules = S → AB
A → aA | A
B → bB| b
Start Variable = {S}
Derivation : S->AB
->aAB
->aaB
->aabB
->aabbB
->aabbb
3.
String: abaca
Variables = {S}
Terminals = {a,b,c}
Production/Rules = S → SbS | ScS | a

Start Variable = {S}

Derivation : S->SbS
->abS
->abScS
->abacS
->abaca

Derivation : S->ScS
->SbScS
->abScS
->abacS
->abaca
4.
String: abaca
Variables = {S}
Terminals = {a,b,c}

Production/Rules = A → AA | (A) | a

Start Variable = {A}

Derivation : A->AA
->AAA
->aAA
->aAAA
->a(A)AA
->a(a)AA
->a(a)aA
->a(a)aa

Derivation : S->A
->AA
->aA
->aAA
->aAAA
->a(A)AA
->a(a)AA
->a(a)aA
->a(a)aa
Answer to the Question No-5
Production Semantic Rule

expr → expr + term expr.t := ‘+’ || expr.t || term.t


expr → expr – term expr.t := ’-’ ||expr.t || term.t
expr → term expr.t := term.t
term → 0 term.t := ‘0’
term → 1 term.t := ‘1’
…. ….
term → 9 term.t := ‘9’

Input string: M+N*O


Prefix: *+MNO
Derivation: Expr->expr * term
->expr + term * term
->term + term * term
->M + term * term
->M + N * term
->M + N * O
Given context free grammar to convert an expression from infix to prefix the annotated parse
trees:
expr.t = *+MNO

expr.t = +MN * term.t = O

expr.t = M + term.t = N O

term.t = M N

M
Fig: Annotated Parse Trees
Production Semantic Action

expr → expr + term {print (‘+’)}


expr → expr – term {print (‘-’)}
expr → term {print ( )}
term → 0 {print (‘0’)}
term → 1 {print (‘1’)}
…. ….
term → 9 {print (‘9’)}

expr
{print (‘*’)}
expr * term
{print (‘+’)}

expr + expr O {print (‘O’)}

term term

M {print (‘M’)} N {print (‘N’)}


Fig: Semantic Action

You might also like