004chapter 4 - Syntax Directed Translation
004chapter 4 - Syntax Directed Translation
Introduction
Semantic Analysis
The plain parse-tree constructed in that phase is generally of no use for a compiler,
The productions of CFG, which makes the rules of the language, do not accommodate
how to interpret them.
For example: E→E+T
The above CFG production has no semantic rule associated with it, and it cannot help in
making any sense of the production.
Semantic Analysis
Semantics of a language provide meaning to its constructs, like tokens and syntax structure.
Semantic Analysis judges whether the syntax structure constructed in the source program
derives any meaning or not.
For example: int a = “value”;
Should not issue an error in lexical and syntax analysis phase, as it is lexically and
structurally correct,
but it should generate a semantic error as the type of the assignment differs.
These rules are set by the grammar of the language and evaluated in semantic analysis.
In typed languages as C, the following tasks should be performed in semantic analysis:
adding information to the symbol table
performing type checking
Generate Code
Issue error messages.
Semantic Analysis….
The information to be computed is beyond the capabilities of standard parsing techniques,
therefore it is not regarded as syntax.
As for Lexical and Syntax analysis, also for Semantic Analysis we need both a
Representation Formalism and an Implementation Mechanism.
As representation formalism this lecture illustrates what are called Syntax Directed
Translations (SDT).
In SDT, along with the grammar we associate some informal notations and these
notations are called as semantic rules.
So we can say that:
• In SDT, every non-terminal can get one or more than one attribute or sometimes 0
attribute depending on the type of the attribute.
• The value of these attributes is evaluated by the semantic rules associated with the
grammar production rule.
• In the semantic rule, attribute is VAL and an attribute may hold anything like a
string, a number, a memory location and a complex record
The Principle of SDT states that:
the meaning of an input sentence is related to its syntactic structure, i.e., to its Parse-
Tree.
By SDT we indicate those formalisms for specifying translations for programming language
constructs guided by CFG.
Example
Production Semantic Rules
E→E+T E.val = E.val + T.val
E→T E.val = T.val
T→T*F T.val = T.val + F.val
T→F T.val = F.val
F → (F) F.val = F.val
F → num F.val = num.lexval
High-level specification hiding many implementation details (also called Attribute Grammars).
It is generalization of CFG in which each grammar production X –> a is associated with it a set of production
rules.
Attributes are associated with grammar symbols and
If X is a symbol and a is one of its attributes, then we write X.a to denote the value of a at a particular
parse-tree node labeled X.
• If curly braces occur as grammar symbols, we enclose them within single quotes, as in ' { ' and '}'.
• The position of a semantic action in a production body determines the order in which the action is executed.
ii. The annotated parse tree is generated and attribute values are computed in
bottom up manner.
TF {T.val=F.val}
Fdigit {F.val=digit.lexval}
Annotated parse tree: Example
• Let us assume an input string 4 * 5 + 6 for computing synthesized
attributes. The annotated parse tree for the input string is
Annotated parse tree: Example
description.
• For computation of attributes we start from leftmost bottom node.
• The rule F –> digit is used to reduce digit to F and the value of digit is obtained from lexical
analyzer which becomes value of F i.e. from semantic action F.val = digit.lexval.
• Hence, F.val = 4 and since T is parent node of F so, we get T.val = 4 from semantic action
T.val = F.val.
• Then, for T –> T1 * F production, the corresponding semantic action is T.val = T 1.val * F.val .
Hence, T.val = 4 * 5 = 20
• Similarly, combination of E1.val + T.val becomes E.val i.e. E.val = E 1.val + T.val = 26. Then,
the production S –> E is applied to reduce E.val = 26 and semantic action associated with it
prints the result E.val . Hence, the output will be 26.
SDD of a simple desk calculator: Example #2
Before we can evaluate an attribute at a node of a parse tree, we must evaluate all
the attributes upon which its value depends.
Cont’d
For example, if all attributes are synthesized, we must evaluate the val attributes at all of the
children of a node before we can evaluate the val attribute at the node itself.
With synthesized attributes, we can evaluate attributes in any bottom-up order, such as that
of a postorder traversal of the parse tree.
Example #2- shows an annotated parse tree for the input string
3 * 5 + 4 n, constructed using the grammar and rules .
The values of lexval are presumed supplied by the lexical analyzer.
Each of the nodes for the non-terminals 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.
Annotated parse tree for 3 * 5 + 4 n
b. inherited attribute
inherited attribute: Example 2
the following production, S → ABC
• Attribute for terminals have lexical values that are supplied by lexical analyzer.
• These are no semantic rules in the SDD itself for computing the values of an
attribute for a terminal.
Computation of Inherited Attributes –
• Construct the SDD using semantic actions.
• The annotated parse tree is generated and attribute values are computed in top down
manner.
Ex: Consider the The SDD for the above grammar can be written as follow
following grammar
S --> T L
T --> int
T --> float
T --> double
L --> L1, id
L --> id
Cont’d.
• Let us assume an input string int a, c for computing inherited attributes.
• The annotated parse tree for the input string is
Cont’d.
addtype(id.entry, L.in)
L → id addtype(id.entry, L.in)
"Dependency graphs" are a useful tool for determining an evaluation order for the
attribute instances in a given parse tree.
• Also used to represent the flow of information among the attributes in a parse tree.
• Dependency graph
– For each parse tree node, the parse tree has a node for each attribute associated
with that node.
– If a semantic rule defines the value of synthesized attribute A.b in terms of the
value of X.c then the dependency graph has an edge from X.c to A.b
– If a semantic rule defines the value of inherited attribute B.c in terms of the
value of X.a then the dependency graph has an edge from X.c to B.c
Dependency graph: Example #1
Dependency graph: Example #2
S-attributed vs L-attributed
The first, an S-attributed definition, is suitable for use during bottom-up parsing.
}
S-Attributed definitions can be implemented during bottom-up parsing without the need to
explicitly create parse trees
S-attributed Definitions
E.g. These attributes are evaluated using S-attributed that have their semantic actions
written after the production (right hand side).
In translation scheme, the semantic rules are embedded within the right side of the productions
Any SDT can be implemented by first building a parse tree and then performing the actions in a left-to-
right depth first order
Typically SDT’s are implemented during parsing without building a parse tree
Example
Production Semantic Rules
S→E$ { printE.VAL }
Simplest SDDs are those that we can parse the grammar bottom-up and
the SDD is s-attributed.
For such cases we can construct SDT where each action is placed at the
end of the production and is executed along with the reduction of the
body to the head of that production
SDT’s with all actions at the right ends of the production bodies are
called postfix SDT’s
Example1- Infix to Postfix translation scheme
Example #2: Postfix SDT
1) L → E n {print(E.val);}
2) E → E1 + T {E.val=E1.val+T.val;}
3) E → T {E.val = T.val;}
4) T → T1 * F {T.val=T1.val*F.val;}
5) T → F {T.val=F.val;}
6) F →(E) {F.val=E.val;}
7) F → digit {F.val=digit.lexval;}
Application of Syntax Directed Translation :
S → E$
E→E + E/ E*E/(E)/(I)
I → I/Idigit (Where I is a Integer)
Exercise #1
Q1. For the SDD of a simple desk calculator below,
a) (3 + 4 ) * ( 5 + 6 ) n .
b) 1 * 2 * 3 * (4 + 5) n.
c) (9 + 8 * (7 + 6 ) + 5) * 4 n .
End of chapter-Four!