Chapter 4
Chapter 4
By Birku L.
Introduction
Semantic analysis
Syntax-Directed Translation (SDT)
Syntax Directed Definitions
Synthesized attributes
Inherited attributes
Implementing Attribute
Dependency Graph
S-Attributed Definitions
L-Attributed Definitions
Translation Schemes
Introduction
Analysis of input program Synthesis of output program
(front-end) (back-end)
character
Character
stream
Intermediate Code Generation
Lexical Analysis
token
Token intermediate
Intermediate
stream form
abstract
Abstract intermediate
Intermediate
syntax tree form
annotated
Annotated target
Target
AST language
Introduction…
Program is lexically well-formed:
Identifiers have valid names.
Strings are properly terminated.
No stray/lost characters.
E.val=14 T.val=2
E.val=9 F.val=2
T.val=5
Note: all attributes
T.val=9 F.val=5 in this example
are of synthesized
F.val=9 attributes
9 + 5 + 2 n
20
Annotated Parse Tree Example
S-Attributed Definitions
An S-Attributed Definition is a SDD that uses only
Synthesized attributes
Evaluation Order:
Semantic rules in a S-Attributed Definition can be
evaluated by a bottom-up, or post-order traversal of the
parse-tree.
An S-attributed SDD can be implemented naturally in
conjunction with an LR parser.
Example – The arithmetic grammar on the above is an
example of an S-Attributed.
Compute the attribute
Compute the S attribute for the given production
by the following the sequence of steps .
The given string is 2+3*4
EE+T/T
TT*F/F
Fid
Inherited Attributes
Inherited Attributes are useful for expressing the dependence of
a construct on the context in which it appears.
It is always possible to rewrite a syntax directed definition to use
only synthesized attributes, but it is often more natural to use
both synthesized and inherited attributes.
Evaluation Order: Inherited attributes can be evaluated by a pre-
order traversal of the parse-tree, but
Unlike synthesized attributes, the order in which the inherited
attributes of the children are computed is important.
Inherited attributes of the children can depend from both left
and right siblings!
Dependency Graphs for
Attributed Parse Trees Direction of value
dependence
Synthesized A.a
attributes A.a= (X.x, Y.y)
X.x Y.y
A.a
A XY X.x= (A.a, Y.y)
X.x Y.y
Inherited A.a
attributes
X.x Y.y Y.y= (A.a, X.x)
25
Steps to compute L attribute
These are attributes which drive their value their parent
or siblings
To drive the L attribute from the given grammar we
must follow steps
Step 1 construct the SDD using semantic action
The annotated parser tree generated and attribute value
computed in top down manner
Top down approach
Left tree value obtained from child node
Value obtained from sibling node
Right tree value obtained from parent
Inherited Attributes: Example
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) }
E.val=17
E.val=5 T.val=12
digit.lexval=5 digit.lexval=3
id id.entry=p
⇓
E → E1+ T { E.val = E1.val + T.val } the
production of the corresponding translation scheme
A Translation Scheme Example
A simple translation scheme that converts infix
expressions to the corresponding postfix expressions.
E →T R
R → + T { print(“+”) } R1
R→
T → id { print(id.name) }
a+b+c ab+c+
infix expression postfix expression
A Translation Scheme Example (cont.)
E
T R
id{print(“a”)} + T {print(“+”)} R
id {print(“b”)} + T {print(“+”)} R
id {print(“c”)}
The depth first traversal of the parse tree (executing the semantic
actions in that order) will produce the postfix representation of the
infix expression.
Convert infix to post fix
SDT for converting infix to postfix expression
String 2+5*3 253*+
EE+T {printf(“+”);}
ET { }
TT*F {printf(“*”);}
TF { }
Fnum {printf(num.lval);}
Inherited Attributes in Translation Schemes
If a translation scheme has to contain both synthesized and
inherited attributes, we have to observe the following rules:
An inherited attribute of a symbol on the RHS of a
production must be computed in a semantic action before that
symbol.
A semantic action must not refer to a synthesized attribute of a
symbol to the right of that semantic action.
A synthesized attribute for the non-terminal on the left can
only be computed after all attributes it references have been
computed
With a L-attributed SDD, it is always possible to construct a
corresponding translation scheme which satisfies these three
conditions
Designing translation schemes
Type Checking