Compiler Unit 3 & 4-1
Compiler Unit 3 & 4-1
UNIT-3
(Syntax-directed Translations)
Syntax-directed translation (SDT)
§ an extension of context-free grammar
(CFG) which acts as a notational
framework for the generation of
intermediate code.
§ It embeds program fragments (called
semantic actions) within the production
bodies.
§ For example,
2
Syntax-directed translation (SDT)
§ In SDT, by convention, we use curly
braces to enclose semantic actions.
§ In syntax-directed translation, we pass the
token stream as input, build the parse tree
for the input token stream, and then
evaluate the semantic rules at the nodes
of parse tree by traversing the parse tree.
3
Syntax-directed translation (SDT)
§ The evaluation of semantic rules by
syntax-directed translation may:
• generate an intermediate code
• save information in the symbol table
• perform semantic checking
• issue error messages, or
• perform some other activities.
4
Syntax-directed definition
§ It is a context-free grammar together with
attributes and rules.
§ Attributes are associated with grammar symbols
and rules are associated with productions.
§ X.a : denote the value of a at a particular parse-
tree node labeled X.
§ Attributes may be of any kind: numbers, types,
table references or strings.
§ Semantic rules are used to set up dependencies
between attributes that will be represented
by a graph. 5
Synthesized Attributes
§ A synthesized attribute for a non-terminal A at a
parse tree node I is defined by a semantic rule
associated with the production at I and the
production must have A as its head.
§ A synthesized attribute at node I has its value
defined only in terms of attribute values of its
child nodes and I itself.
6
Synthesized Attributes
§ For example, consider the grammar for a desk
calculator:
8
Synthesized Attributes
§ Since the entire attribute values of the symbols
as head are defined in terms of attributes at their
child nodes, it means all attributes involved are
synthesized attributes and the corresponding
SDD is known as S-attributed definition.
9
Inherited Attributes
§ An inherited attribute for a non-terminal A at a
parse tree node I is defined by a semantic rule
associated with the production at the parent of I,
and the production must have A as a symbol in
its body.
§ The value of an inherited attribute at node I can
only be defined in terms of attribute
values of I’s parents, I’s siblings, and I itself.
§ Inherited attributes are convenient for expressing
the dependency of a programming language
construct on the context on which it appears.
10
Inherited Attributes
§ An inherited attribute can be used to keep track
of whether an identifier appears on the left side
or right side of an assignment operator in order
to determine whether the address or the value of
the identifier is required.
§ For example, consider the following grammar:
11
Inherited Attributes
§ The syntax-directed definitions that use inherited
attributes can be written as:
12
Inherited Attributes
§ The syntax-directed definitions that use inherited
attributes can be written as:
14
Ordering the evaluation of attributes
§ If dependency graph has an edge from M to N
then M must be evaluated before the attribute of
N
§ Thus the only allowable orders of evaluation are
those sequence of nodes N1,N2,…,Nk such that
if there is an edge from Ni to Nj then i<j
§ Such an ordering is called a topological sort of a
graph
15
S-Attributed definitions
§ An SDD is S-attributed if every attribute is
synthesized
16
L-Attributed definitions
§ A SDD is L-Attributed if the edges in
dependency graph goes from Left to Right but
not from Right to Left.
17
L-Attributed definitions
§ If there is a production A->X1X2…Xn and there is
an inherited attribute Xi.a computed by a rule
associated with this production, then the rule may
only use:
1. Inherited attributes associated with the head
A
2. Either inherited or synthesized attributes
associated with the occurrences of symbols
X1,X2,…,Xi-1 located to the left of Xi
3. Inherited or synthesized attributes associated
with this occurrence of Xi itself, but in such a
way that there is no cycle in the graph.
18
Annotated Parse Tree
§ An annotated parse tree is a parse tree that
displays the values of the attributes at each
node.
§ It is used to visualize the SDD specified
translations.
§ To construct an annotated parse tree, first the
SDD rules are applied to construct a parse tree
and then the same SDD rules are applied to
evaluate the attributes at each node of the parse
tree.
19
Annotated Parse Tree
§ For example, an annotated parse tree for an
expression 3 + 5 * 2 by considering the following
productions and semantic rules:
20
Annotated Parse Tree
21
Types of Attributes
§ Inherited attributes: An
attribute is inherited at a
parse tree node if its
value is computed at a
parent or sibling node.
§ Synthesized attributes:
An attribute is
synthesized at a parse
tree node if its value is
computed at that node
or one of its children.
22
Dependency Graph
§ A dependency graph represents the flow of
information between the attribute instances in a
parse tree.
§ It is used to depict the interdependencies among
the inherited and synthesized attributes at
the nodes in a parse tree.
§ When the value of an attribute needs to compute
value of another attribute, then an edge from first
attribute instance to another is created to
indicate the dependency among the
attribute instances.
23
Dependency Graph
§ To construct a dependency graph for a parse
tree, we first make each semantic rule in the
form x: = f(y1,y2,y3,...,yk)
by introducing a dummy synthesized attribute x
for each semantic rule that consists of a
procedure call.
§ We then create a node for each attribute in the
graph and an edge from node y to the node x, if
attribute x depends on attribute y.
24
Dependency Graph Example
§ Construct a dependency graph for the input
string 7 + 8, by considering the following
grammar:
25
Dependency Graph Example
§ A synthesized attribute val is used for each of the
non-terminals A and B and a synthesized
attribute lexval is used for the terminal digit.
26
Dependency Graph Example
§ Syntax Directed Definition for the given grammar:
27
Dependency Graph Example
§ Annotated Parse Tree for 7 + 8:
28
Dependency Graph Example
§ We use this parse tree to construct a
dependency graph:
29
Symbol Tables
A symbol table is a major data structure used in a
compiler:
vAssociates attributes with identifiers used in a
program
vFor instance, a type attribute is usually associated
with each identifier
vA symbol table is a necessary component
Ø Definition (declaration) of identifiers appears once in a
program
Ø Use of identifiers may appear in many places of the
program text
30
Symbol Tables
• Identifiers and attributes are entered by the analysis
phases:
v When processing a definition (declaration) of
an identifier
v In simple languages with only global variables
and implicit declarations:
Ø The scanner can enter an identifier into a symbol
table if it is not already there
v In block-structured languages with scopes and
explicit declarations:
Ø The parser and/or semantic analyzer enter
identifiers and corresponding attributes
31
Symbol Tables
• Symbol table information is used by the analysis and
synthesis phases:
v To verify that used identifiers have been
defined (declared)
v To verify that expressions and assignments are
semantically correct - type checking
v To generate intermediate or target code
32
Symbol Table Interface
•The basic operations defined on a symbol table
include:
* allocate - to allocate a new empty symbol table
* free - to remove all entries and free the storage of a
symbol table
* insert - to insert a name in a symbol table and return a
pointer to its entry
* lookup - to search for a name and return a pointer to
its entry
* set_attribute - to associate an attribute with a given
entry
* get_attribute - to get an attribute associated with a
given entry
33
Basic Implementation Techniques
First consideration is how to insert and lookup names
34
Basic Implementation Techniques
Ordered List
vIf an array is sorted, it can be searched using
binary search - O(log2 n)
vInsertion into a sorted array is expensive -
O(n) on average
vUseful when set of names is known in
advance - table of reserved words
Binary Search Tree
vCan grow dynamically
vInsertion and lookup are O(log2 n) on average
35
Basic Implementation Techniques
Hash Tables and Hash Functions
vA hash table is an array with index range: 0 to TableSize –1
vMost commonly used data structure to implement symbol tables
vInsertion and lookup can be made very fast - 0(1)
vA hash function maps an identifier name into a table index
* A hash function, h(name), should depend solely on name
* h(name) should be computed quickly
*h should be uniform and randomizing in distributing names
* All table indices should be mapped with equal probability
* Similar names should not cluster to the same table index
36
Semantic analysis motivation
n Syntactically correct programs may still
contain errors
n Lexical analysis does not distinguish between
different variable names (same ID token)
n Syntax analysis does not correlate variable
declaration with variable use, does not keep
track of types
int a; int a;
a = “hello”; b = 1;
Assigning
undeclared
Assigning variable
wrong type 37
Goals of semantic analysis
n Check “correct” use of programming
constructs
n Provide information for subsequent phases
n Correctness specified by semantic rules
v Scope rules
v Type-checking rules
v Specific rules
38
Example of semantic rules
n A variable must be declared before used
n A variable should not be declared multiple times
n A variable should be initialized before used
n Non-void method should contain return statement
along all execution paths
n break/continue statements allowed only in loops
n this keyword cannot be used in static method
n main method should have specific signature
41
Scope Nesting
Scope nesting mirrored in hierarchy of symbol tables
42
Scope Example
class Foo {
int value;
int test() {
int b = 3; scope of
return value + b; local variable b
}
void setValue(int c) { scope of
value = c; field value
{ int d = c; scope of
c = c + d; local variable scope of formal
value = c; in statement parameter c scope of
} block d method test
}
}
…
(Foo)
Symbol Kind Type Properties
value field int …
test method -> int
setValue method int -> void
(Test) (setValue)
Symbol Kind Type Properties Symbol Kind Type Properties
b var int … c var int …
(block1)
Symbol Kind Type Properties
d var int …
44
Checking scope rules
(Foo)
Symbol Kind Type Properties
value field int …
test method -> int
setValue method int -> void
(Test) (setValue)
Symbol Kind Type Properties Symbol Kind Type Properties
b var int … c var int …
void setValue(int c) {
(block1)
value = c;
{ int d = c; lookup(value) Symbol Kind Type Properties
c = c + d; d var int …
value = c;
}
}
45
Catching semantic errors
Error !
(Foo)
Symbol Kind Type Properties
value field int …
test method -> int
setValue method int -> void
(Test) (setValue)
Symbol Kind Type Properties Symbol Kind Type Properties
b var int … c var int …
void setValue(int c)
{ (block1)
c = c + d;
myValue = c;
}
} 46
Symbol table construction
via AST traversal globals
Symbol kind
root
foo class
ClassDecl foo
name=foo Symbol kind
test method
setValue method
MethodDecl MethodDecl
name=test name=setValue test setValue
Symbol Symbol
b var c var
block1
VarDecl Stmt Stmt Block Symbol
id=b
d var