3. Semantic
Analysis
● Semantic Analysis computes additional information related to the
meaning of the program once the syntactic structure is known.
● In typed languages as C, semantic analysis involves adding
information to the symbol table and performing type checking.
● The information to be computed is beyond the capabilities
of standard parsing techniques, therefore it is not regarded as
syntax.
16. How previous
example?
● The values of lexval are presumed supplied by the lexical analyzer.
● Each of the nodes for the nonterminals has attribute val computed in a bottom-up
order, and we see the resulting values associated with each node.
● For instance, at the node with a child labeled *, after computing T .val = 3 and F.val = 5 at
its first and third children, we apply the rule that says T .val is the product of these two
values, or 15.
21. Construction of Syntax Tree ( S Attributed + Bottom
Up
)
( Built using
constructor)
How nodes are
constructed?
● Operand => Leaf Node
○ Leaf(operand,value)
● Operator => Interior node ( Built using
constructor)
○ Node(operator,left_child,right_child)
22. Constructing Syntax Tree for given expression and
grammar Expression : a-4+c
Step 1: Constructing Semantic
Rules
23. Step 2: Constructing parse tree using
bottom up
Step 3: Deciding steps in
construction
1
2
3
4
5
25. Three address
code ● Maximum three addresses in each
instruction
● Maximum one operator in RHS.
● It would be equivalent to syntax tree/
DAG.
Eg. a = b +
c
a= x+y+z if a>b then x=0 else
x=5
27. Instruction forms
1 Assignment (Binary/Unary) x=y+z
a=-b
2 Copy a=b
3 Jump => Unconditional
Conditional on true/false
Conditional on relational operator
goto L
if x goto L
ifFalse x goto
L
if x>y goto
L
4 Function Call count(a,b)
param a
param b
call
count,2
5 Indexed Copy x=y[i
]
x[i]=
z
6 Address and pointer x=
&t
m=*
p
38. Key
points
A quadruple has four fields, which we call op, arg 1, arg 2, and
result.
● A triple has only three fields, which we call op, arg 1, and arg 2.. Using triples, we refer to
the result of an operation x op y by its position, rather than by an explicit temporary
name.
● A benet of quadruples over triples can be seen in an optimizing compiler, where
instructions are often moved around.
● With quadruples, if we move an instruction that computes a temporary t, then the
instructions that use t require no change. With triples, the result of an operation is
referred to by its position, so moving an instruction may require us to change all
references to that result. This problem does not occur with indirect triples,
● Indirect triples consist of a listing of pointers to triples, rather than a listingof triples
themselves.
39. Examples 1
op arg1 arg2 res op arg1 arg2
3 address code Quadruples Triples
43. Type Checking Translation
● Type checking uses logical rules
to reason about the behavior of
a program at run time.
● It ensures that the types of the
operands match the type expected
● Determine storage needed for a
type of variable.
● Explicit type conversions
● Calculate address denoted by
array reference.
int a=4;
char b=”d”;
c =a+b;
44. Sl No Definition
1 Basic type expr - boolean, char, integer, float, and void
2 A type name is a type expression
3 Type expression can be formed by applying the array type constructor
to a
number and a type expression.
array(count,type)
4 A record is a data structure with named fields. A type expression can
be formed by applying the record type constructor to the field names
and their type.
5
6 If s and t are type expressions, then their Cartesian product sxt is a
1. Type Expressions - is either a basic type or is formed by applying
an operator called a type constructor to a type expression.
46. 3. Type Declarations
1. Nonterminal D generates a sequence of declarations.
2. Nonterminal T generates basic, array, or record types.
3. Nonterminal B generates one of the basic types int and float.
4. Nonterminal C, for component," generates strings of zero or more integers, each
integer surrounded by brackets.
5. A record type (the second production for T ) is a sequence of declarations for the fields of
the record, all surrounded by curly braces.
47. 4. Storage
Layout
● Datatype => Amount of storage required
● At compile time, we can use these amounts to assign each name a relative address.
● The type and relative address are saved in the symbol-table entry for the name.
● Data of varying length, such as strings, or data whose size cannot be determined until
run time, such as dynamic arrays, is handled by reserving a known fixed amount of
storage for a pointer to the data.
● The width of a type is the number of storage units needed for objects of that type.
48. 5. Sequences of
Declarations
● Languages such as C and Java allow all the declarations in a single procedure to be processed as
a group.
● The declarations may be distributed within a Java procedure, but they can still be processed
when the procedure is analyzed.
● Therefore, we can use a variable, say offset, to keep track of the next available relative
address.
● As each new name x is seen, x is entered into the symbol table with its relative address set to the
current value of offset, which is then incremented by the width of the type of x.
Create symbol
table entry
49. 6. Fields in Records and Classes
Record types can be added
using
50. Translation of Expressions
1. Operations within
Expressions
2. Incremental Translation
3. Addressing Array elements
4. Translation of Array
References
51. 1. Operations within expressions
● SDD attributes:
○ code - denote three address code
○ addr - address that will hold value of non-terminal
● Top - points to current symbol table
● top.get() - retrieves entry of parameter passed
● gen() - generate 3 address instruction , pass operator in
quotes
● new Temp() - Create distinct temp name
53. 2. Incremental Translation
● Code attributes can be long strings, so they are usually generated incrementally
● In the incremental approach, gen not only constructs a three-address instruction, it
appends the instruction to the sequence of instructions generated so far.
● The sequence may either be retained in memory for further processing, or it may be
output incrementally.
54. 3. Addressing Array Elements
12 18 24
0 1 2
Address Element Formula for
calculation:
59. Type Checking
1. Rules of type checking
2. Type conversions
3. Overloading of functions and operators
4. Type Inference and Polymorphic Functions
5. An algorithm for unification
60. What is type checking?
● assign a type expression to each component of the source program
● The compiler must then determine that these type expressions conform to a collection
of logical rules that is called the type system for the source language.
● It can be used to detect errors in the program.
● A sound type system eliminates the need for dynamic checking for type errors, because it
allows us to determine statically that these errors cannot occur when the target program
runs.
● type checking have been used to improve the security of systems that allow software
modules to be imported and executed
Example:
61. 1. Rules for Type Checking
(Synthesis/Inference)
Type Synthesis
● builds up the type of an expression from
the types of its subexpressions.
● It requires names to be declared
before they are used.
● Eg. Type of E1+E2 is determined from
types of E1 and E2.
Type Inference
● Determines the type of a
language construct from the
way it is used.
● Let null(x) be a function to check if
list is empty.
● Since null function applied on list, we
can say x is a list
62. 2. Type Conversions/ Type Casting
● Type casting is converting one datatype to some other data type. It is executed
using the
cast
operator.
● Explicit type conversion in C is when the datatype conversion is user-defined
according to
the program's needs. Explicit type conversion can easily change a particular data type
to a
different
one.
● Implicit type conversion is automatically done by the
program.
● Need
:
a = 5
b = 10.12
print(a+b
)
67. 4. Type Inference and Polymorphic Functions
● Type inference is useful for a language like ML which is strongly typed, but does not
require names to be declared before they are used. Type inference ensures that names are
used consistently.
● The term polymorphic refers to any code fragment that can be executed with
arguments of different types.
70. 5. Unification Algorithm
1. Unification is the problem of determining whether two
expressions s and t can be made identical by substituting
expressions for the variables in s and t.
2. Testing equality of expressions is a special case of unification; if s
and t have constants but no variables, then s and t unify if and only
if they are identical.
3. The unification algorithm in this section extends to graphs with
cycles, so it can be used to test structural equivalence of
circular types
4. Type variables are represented by leaves and type constructors
are represented by interior nodes.
5. Nodes are grouped into equivalence classes; if two nodes are in the
same equivalence class, then the type expressions they represent
must unify.