0% found this document useful (0 votes)
10 views

Unit v Symantic Analysis

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

Unit v Symantic Analysis

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 45

Unit V : Semantic Analysis and Intermediate Code Generation

Course : Language Processor and Compiler Construction

Manisha Mali
[email protected]

BRACT’S, Vishwakarma Institute of Information Technology, Pune-48


(An Autonomous Institute affiliated to Savitribai Phule Pune University)
(NBA and NAAC accredited, ISO 9001:2015 certified)
Department of Computer Engineering
Contents
 Semantic Analysis
 Need, Syntax Directed Translation, Syntax Directed Definitions,
Translation of assignment Statements, iterative statements, Boolean
expressions, conditional statements, Type Checking and Type
conversion
 Intermediate Code Generation
 Postfix notation, Parse and syntax trees syntax trees, Three address
code, Quadruples and triples

2 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Contents
 Semantic Analysis
 Need, Syntax Directed Translation, Syntax Directed
Definitions, Translation of assignment Statements,
iterative statements, Boolean expressions,
conditional statements, Type Checking and Type
conversion
 Intermediate Code Generation
 Postfix notation, Parse and syntax trees syntax trees, Three address code, Quadruples and
triples

3 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Analysis Synthesis
of input program of output program

Compiler (front-end)
character
(back-end)

Phases and stream


Intermediate Code
Passes Lexical Analysis Generation

token intermediate
stream form

Syntactic Analysis Optimization

abstract intermediate
syntax tree form

Semantic Analysis Code Generation

annotated target
AST language

4 Manisha Mali
Semantic Analysis/Checking
Semantic analysis: the final part of the analysis half of compilation
 afterwards comes the synthesis half of compilation

Purposes:
 perform final checking of legality of input program, “missed” by lexical and
syntactic checking
 name resolution, type checking,break stmt in loop, ...
 “understand” program well enough to do synthesis
 Typical goal: relate assignments to & references of particular variable

5 Manisha Mali
Semantic Analysis
 Semantic analysis is applied by a compiler to discover the
meaning of a program by analyzing its parse tree or abstract
syntax tree.
 A program without grammatical errors may not always be
correct program.
 pos = init + rate * 60.0

 What if pos is a class while init and rate are integers?

 This kind of errors cannot be found by the parser


 Semantic analysis finds this type of error and ensure that the program
has a meaning.

6
Manisha Mali
Semantic Analysis
 Static semantic checks (done by the compiler) are performed at compile time
 Type checking
 Every variable is declared before used
 Identifiers are used in appropriate contexts
 Check subroutine call arguments
 Check labels
 Dynamic semantic checks are performed at run time, and the compiler produces code
that performs these checks
 Array subscript values are within bounds
int A[10]; for(i=0;i<20;i++) scanf(“%d”,&A[i]);
 Arithmetic errors, e.g. division by zero
 Pointers are not dereferenced unless pointing to valid object Int *a; float *a;
 A variable is used but hasn't been initialized
 int a, b, c ; c=a+b; printf(“%d”,c);
 When a check fails at run time, an exception is raised

7
Manisha Mali
Semantic Analysis and Strong Typing
 A language is strongly typed "if (type) errors are always detected"
 Errors are either detected at compile time or at run time
 Examples of such errors are listed on previous slide
 Languages that are strongly typed are Ada, Java, ML, Haskell
 Languages that are not strongly typed are Fortran, Pascal, C/C++,
Lisp
 Strong typing makes language safe and easier to use, but
potentially slower because of dynamic semantic checks
 In some languages, most (type) errors are detected late at run time
which is harmful to reliability e.g. early Basic, Lisp, Prolog, some
script languages

8
Manisha Mali
Semantic Analyzer
 A semantic analyzer checks the source program for semantic errors and
collects the type information for the code generation.
 Type-checking is an important part of semantic analyzer.
 Normally semantic information cannot be represented by a context-free
language used in syntax analyzers.
 Context-free grammars used in the syntax analysis are integrated with
attributes (semantic rules)
 the result is a syntax-directed translation,
 Attribute grammars
 Ex:
newval := oldval + 12

 The type of the identifier newval must match with type of the expression (oldval+12)

9 Manisha Mali
Type Checking
 A compiler has to do semantic checks in addition to syntactic checks.
 Semantic Checks
 Static – done during compilation
 Dynamic – done during run-time
 Type checking is one of these static checking operations.
 we may not do all type checking at compile-time.
 Some systems also use dynamic type checking too.
 A type system is a collection of rules for assigning type expressions to the parts of a
program.
 A type checker implements a type system.
 A sound type system eliminates run-time type checking for type errors.
 A programming language is strongly-typed
 In practice, some of type checking operations are done at run-time (so, most of
the programming languages are not strongly-typed).
 Ex: int x[100]; … x[i]  most of the compilers cannot guarantee that i will
10 Manisha Mali
be between 0 and 99
Static Type Checking
Static checking examples:
 Type checks.
 Report an error if an operator is applied to an incompatible
operand
 int a; char c; a=c;
 Flow-of-control checks.
Statements that causes flow of control to leave a construct must
have some
 place to which to transfer the flow of control
 Uniqueness checks.
There are situations where an object must be defined exactly once.
 labels, identifiers
 Name-related checks.
Sometimes the same names may be appeared two or more times.
 Beginning and end of a construct
11 Manisha Mali
Type Expression
 The type of a language construct is denoted by a type expression.
 A type expression can be:
 A basic type
 a primitive data type such as integer, real, char, boolean, …
 type-error to signal a type error
 void : no type
 A type name
 a name can be used to denote a type expression.
 A type constructor applies to other type expressions.
 arrays: If T is a type expression, then array(I,T) is a type expression where I denotes
index range. Ex: array(0..99,int) , int a[100];
 products: If T1 and T2 are type expressions, then their Cartesian product T1 x T2 is a
type expression. Ex: int x int
 pointers: If T is a type expression, then pointer(T) is a type expression. Ex:
pointer(int), int A; int *A; float *A;

12 Manisha Mali
Type Expression
 functions: We may treat functions in a programming language as mapping from a domain type D to
a range type R. So, the type of a function can be denoted by the type expression D→R where D are
R type expressions. Ex: int→int represents the type of a function which takes an int value as
parameter, and its return type is also int.
 Function f(a,b: integer) :  integer
o Integer  integer → pointer(integer)
Ex. Function Declaration [int test (int, float, char)]
Function Definition [int test (int X, float Y, char Z)]
Function Call [int P = test(5, 3.7, ‘A’)]
 Records: The record type constructor will be applied to a tuple formed from field names and field
types.
Type row = record
address : integer;
lexeme: array[1..15] of char
end;
Var table: array[1..101] of row;
Declares the type name row representing the type expression
record( (address  integer)  (lexeme  array(1..15,char) )
13 Manisha Mali
A Simple Type Checking System
P → D;E
D → D;D
D → id:T { addtype(id.entry,T.type) }
T → char { T.type=char }
T → int { T.type=int }
T → real { T.type=real }
T → ↑T1 { T.type=pointer(T1.type) }
T → array[intnum] of T1 { T.type=array(1..intnum.val,T1.type) }

Parts of translation scheme that saves the


type of an identifier

14 Manisha Mali
Type Checking of Expressions
E → id { E.type=lookup(id.entry) }
E → charliteral { E.type=char }
E → intliteral { E.type=int }
E → realliteral { E.type=real }

E → E1 + E2 { if (E1.type=int and E2.type=int) then E.type=int


else if (E1.type=int and E2.type=real) then E.type=real
else if (E1.type=real and E2.type=int) then E.type=real
else if (E1.type=real and E2.type=real) then E.type=real
else E.type=type-error }

E → E1 [E2] { if (E2.type=int and E1.type=array(s,t)) then E.type=t


else E.type=type-error }

E → E1 ↑ { if (E1.type=pointer(t)) then E.type= t else E.type=type-error }


15
Manisha Mali
Type Checking of Statements

S  id = E { if (id.type=E.type then S.type=void


else S.type=type-error }

S  if E then S1 { if (E.type=boolean then S.type=S1.type


else S.type=type-error }

S  while E do S1 { if (E.type=boolean then S.type=S1.type


else S.type=type-error }

16 Manisha Mali
Type Checking of Functions
E  E1 ( E2 ) { if (E2.type=s and E1.type=st) then E.type=t
else E.type=type-error }

Ex: int f(double x, char y) { ... }

f: double x char  int

argument types return type

function root (function f(real):real; x : real) : real

Root: (real  real)  real  real

17 Manisha Mali
Syntax-Directed Translation
1. Grammar symbols are associated with attributes to associate information with the
programming language constructs that they represent.

2. Values of these attributes are evaluated by the semantic rules associated with the
production rules.

3. Evaluation of these semantic rules:


 may generate intermediate codes
 may put information into the symbol table
 may perform type checking
 may issue error messages
 may perform some other activities
 in fact, they may perform almost any activities.

4. An attribute may hold almost any thing.


 a string, a number, a memory location, a complex record.
18 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20
Syntax-Directed Definitions and Translation
Schemes
1. When we associate semantic rules with productions, we use two notations:
 Syntax-Directed Definitions
 Translation Schemes

A. Syntax-Directed Definitions:
 give high-level specifications for translations
 hide many implementation details such as order of evaluation of semantic actions.
 We associate a production rule with a set of semantic actions, and we do not say
when they will be evaluated.

B. Translation Schemes:
 indicate the order of evaluation of semantic actions associated with a production
rule.
 In other words, translation schemes give a little bit information about
implementation details.

19 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Syntax-Directed Definitions
1. A syntax-directed definition is a generalization of a context-free
grammar in which:
 Each grammar symbol is associated with a set of attributes.
 This set of attributes for a grammar symbol is partitioned into two
subsets called
 synthesized and
 inherited attributes of that grammar symbol.
 Each production rule is associated with a set of semantic rules.
2. Semantic rules set up dependencies between attributes which can be
represented by a dependency graph.
3. This dependency graph determines the evaluation order of these
semantic rules.
4. Evaluation of a semantic rule defines the value of an attribute. But a
semantic rule may also have some side effects such as printing a value.
20 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20
Annotated Parse Tree
1. A parse tree showing the values of attributes at each node is
called an annotated parse tree.

2. The process of computing the attributes values at the nodes is


called annotating (or decorating) of the parse tree.

3. Of course, the order of these computations depends on the


dependency graph induced by the semantic rules.

21 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Syntax-Directed Definition
In a syntax-directed definition, each production A→α is associated
with a set of semantic rules of the form:
b=f(c1,c2,…,cn)
where f is a function and b can be one of the followings:

 b is a synthesized attribute of A and c1,c2,…,cn are attributes of the


grammar symbols in the production ( A→α ).
OR
 b is an inherited attribute one of the grammar symbols in α (on
the right side of the production), and c1,c2,…,cn are attributes of the
grammar symbols in the production ( A→α ).

22 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Attribute Grammar
 So, a semantic rule b=f(c1,c2,…,cn) indicates that the attribute b depends
on attributes c1,c2,…,cn.

 In a syntax-directed definition, a semantic rule may just evaluate


a value of an attribute or it may have some side effects such as printing
values.

 An attribute grammar is a syntax-directed definition in which the


functions in the semantic rules cannot have side effects (they can only
evaluate values of attributes).

23 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Syntax-Directed Definition – Example 1
Production
L → E return
E → E +T
E →T
T →T * F
T→F
F→(E)
F → digit

1. Symbols E, T, and F are associated with a synthesized attribute val.


2. The token digit has a synthesized attribute lexval (it is assumed that it is evaluated by
the lexical analyzer).

24 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Syntax-Directed Definition – Example 1
Production Semantic Rules
L → E return print(E.val)
E → E1 + T E.val = E1.val + T.val
E →T E.val = T.val
T → T1 * F T.val = T1.val * F.val
T→F T.val = F.val
F→(E) F.val = (E.val)
F → digit F.val = digit.lexval

1. Symbols E, T, and F are associated with a synthesized attribute val.


2. The token digit has a synthesized attribute lexval (it is assumed that it is evaluated by
the lexical analyzer).

25 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Annotated Parse Tree -- Example
Input: 5+3*4 L

E.Val return

E.Val + T.val

T.Val T.val * F.val

F.Val F.val digit.lexval

digit.lexval digit.lexval

26 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Annotated Parse Tree -- Example
Input: 5+3*4 L

E.Val return

E.Val + T.val

T.Val T.val * F.val

F.Val F.val digit.lexval=4

digit.lexval=5 digit.lexval=3

27 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Annotated Parse Tree -- Example
Input: 5+3*4 L

E.Val return

E.Val + T.val

T.Val T.val * F.val=4

F.Val=5 F.val=3 digit.lexval=4

digit.lexval=5 digit.lexval=3

28 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Annotated Parse Tree -- Example
Input: 5+3*4 L

E.Val return

E.Val + T.val

T.Val=5 T.val=3 * F.val=4

F.Val=5 F.val=3 digit.lexval=4

digit.lexval=5 digit.lexval=3

29 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Annotated Parse Tree -- Example
Input: 5+3*4 L

E.Val return

E.Val=5 + T.val=12

T.Val=5 T.val=3 * F.val=4

F.Val=5 F.val=3 digit.lexval=4

digit.lexval=5 digit.lexval=3

30 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Annotated Parse Tree -- Example
Input: 5+3*4 L

E.Val=17 return

E.Val=5 + T.val=12

T.Val=5 T.val=3 * F.val=4

F.Val=5 F.val=3 digit.lexval=4

digit.lexval=5 digit.lexval=3

31 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Annotated Parse Tree -- Example
Input: 5+3*4 L

E.val=17 return

E.val=5 + T.val=12

T.val=5 T.val=3 * F.val=4

F.val=5 F.val=3 digit.lexval=4

digit.lexval=5 digit.lexval=3

32 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Dependency Graph
Input: 5+3*4 L

E.val=17

E.val=5 T.val=12

T.val=5 T.val=3 F.val=4

F.val=5 F.val=3 digit.lexval=4

digit.lexval=5 digit.lexval=3

33 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Syntax-Directed Definition – Example 2
Input Expression : 23 * 5 + 4$
Production
S→E$
E → E+ E
E → E* E
E → (E)
E →I
I → I digit
I → digit
digit stands for any of the digits 0, 1, ….9

34 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Syntax-Directed Definition – Example 2

35 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Syntax-Directed Definition – Example 2
Input Expression : 23 * 5 + 4$

36 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Syntax-Directed Definition – Example3
Production Semantic Rules
E → E1 + T E.loc=newtemp(), E.code = E1.code || T.code || add E1.loc,T.loc,E.loc
E →T E.loc = T.loc, E.code=T.code
T → T1 * F T.loc=newtemp(), T.code = T1.code || F.code || mult T1.loc,F.loc,T.loc
T→F T.loc = F.loc, T.code=F.code
F→(E) F.loc = E.loc, F.code=E.code
F → id F.loc = id.name, F.code=“”

1. Symbols E, T, and F are associated with synthesized attributes loc and code.
2. The token id has a synthesized attribute name (it is assumed that it is evaluated by the lexical
analyzer).
3. It is assumed that || is the string concatenation operator.

37 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Syntax-Directed Definition – Inherited
Attributes
Production Semantic Rules
D →T L L.in = T.type
T → int T.type = integer
T → real T.type = real
L → L1 id L1.in = L.in, addtype(id.entry,L.in)
L → id addtype(id.entry,L.in)

1. Symbol T is associated with a synthesized attribute type.

2. Symbol L is associated with an inherited attribute in.

38 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


A Dependency Graph – Inherited
Attributes
Input: real p q

D L.in=real

T L T.type=real L1.in=real addtype(q,real)

real L1 id addtype(p,real) id.entry=q

id id.entry=p

parse tree dependency graph

39 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Syntax Trees
1. Decoupling Translation from Parsing-Trees.
2. Syntax-Tree: an intermediate representation of the compiler’s input.
3. Example Procedures:
mknode, mkleaf
4. Employment of the synthesized attribute nptr (pointer)

PRODUCTION SEMANTIC RULE


E  E1 + T E.nptr = mknode(“+”,E1.nptr ,T.nptr)
E  E1 - T E.nptr = mknode(“-”,E1.nptr ,T.nptr)
E T E.nptr = T.nptr
T  (E) T.nptr = E.nptr
T  id T.nptr = mkleaf(id, id.lexval)
T  num T.nptr = mkleaf(num, num.val)

40 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


Draw the Syntax Tree a-4+c

id

to entry for c
id num 4

to entry for a
41 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20
Syntax Dir. Definition for Assignment Statements
PRODUCTION Semantic Rule
S  id := E { S.nptr = mknode (‘assign’, mkleaf(id, id.entry), E.nptr) }

E  E1 + E2 {E.nptr = mknode(‘+’, E1.nptr,E2.nptr) }

E  E1 * E2 {E.nptr = mknode(‘*’, E1.nptr,E2.nptr) }

E  - E1 {E.nptr = mknode(‘uminus’,E1.nptr) }

E  ( E1 ) {E.nptr = E1.nptr }

E  id {E.nptr = mkleaf(id, id.entry) }


S-Attributed Definitions
1. Syntax-directed definitions are used to specify syntax-directed translations.

2. To create a translator for an arbitrary syntax-directed definition can be difficult.

3. We would like to evaluate the semantic rules during parsing (i.e. in a single pass, we will parse and
we will also evaluate semantic rules during the parsing).

4. We will look at two sub-classes of the syntax-directed definitions:


 S-Attributed Definitions: only synthesized attributes used in the
syntax-directed definitions.
 L-Attributed Definitions: in addition to synthesized attributes, we
may also use inherited attributes in a restricted fashion.
5. To implement S-Attributed Definitions and L-Attributed Definitions we can evaluate semantic rules
in a single pass during the parsing.

6. Implementations of S-attributed Definitions are a little bit easier than implementations of L-


Attributed Definitions

43 Manisha Mali, Dept. Computer Engg., VIIT 27-Oct-20


References
 D. M. Dhamdhere, Systems Programming and Operating Systems, Tata McGraw-Hill,
ISBN 13:978-0-07-463579-7, Second Revised Edition
 Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman, Compilers Principles, Techniques and

Engineering, VIIT , Pune-48


Manisha Mali, Department of Computer
Tools, Addison Wesley, ISBN:981–235–885 - 4, Low Price Edition
 J. J. Donovan, Systems Programming, McGraw-Hill, ISBN 13:978-0-07-460482-3,
Indian Edition

44
27-Oct-20
Manisha Mali, Dept. Computer Engg., VIIT
45

You might also like