CS3833
Theory of Programming Languages
Week 06:
Semantic Analysis
1
Semantic Analysis
From Code Form To Program Meaning
Source Code
Compiler or Interpreter Interpre-
tation
Translation Execution
Target Code
2
Phases of Compilation
3
Specification of Programming Languages
• PLs require precise definitions
(i.e. no ambiguity)
– Language form (Syntax)
– Language meaning (Semantics)
• Consequently, PLs are specified
using formal notation:
– Formal syntax
» Tokens
» Grammar
– Formal semantics
» Attribute Grammars (static semantics)
» Dynamic Semantics
4
The Semantic Analyzer
• The principal job of the semantic
analyzer is to enforce static semantic
rules.
• In general, anything that requires the
compiler to compare things that are
separate by a long distance or to count
things ends up being a matter of
semantics.
• The semantic analyzer also commonly
constructs a syntax tree (usually
first), and much of the information it
gathers is needed by the code
generator.
5
Attribute
• Are detail related with grammar
symbol
• Are computed related with grammar
symbol
• Can be string, number, a type
• E.g
– [Link]=[Link]+[Link]
6
Attribute Grammars
• Context-Free Grammars (CFGs) are used to
specify the syntax of programming languages
– E.g. arithmetic expressions
• How do we tie these
rules to mathematical
concepts?
• Attribute grammars are
annotated CFGs in which
annotations are used to
establish meaning
relationships among
symbols
– Annotations are also 7
Attribute Grammars
Example
• Each grammar
symbols has a set
of attributes
– E.g. the value of E1
is the attribute
[Link]
• Each grammar rule
has a set of rules
over the symbol
attributes
– Copy rules
– Semantic Function
rules
» E.g. sum, quotient
8
Attribute Grammars
Example
• Syntax Directed Translation has
augmented rules to the grammar that
facilitate semantic analysis.
• SDT involves passing information bottom-
up and/or top-down the parse tree in form
of attributes attached to the nodes.
• Syntax-directed translation rules use 1)
lexical values of nodes, 2) constants & 3)
attributes associated with the non-
terminals in their definitions.
9
SDT
Applications
10
SDT
Applications
11
Attribute Grammars
Example
12
Attribute Grammars
Example
13
Evaluation of SDT
14
Parse Tree
Top-down VS bottom-up parse tree
Start from designing a parse tree
15
Top-down parse tree
16
Top-down parse tree
17
Bottom-up parse tree
18
Bottom-up parse tree
19
Evaluate Arithmetic Expression using
SDT
20
Evaluate Arithmetic Expression using
SDT
21
Example (Synthesized Attribute)
• The value of synthesized attribute at the node is
computed from the value attributes at the children of
that node in a parse tree.
• For example
22
Example (Synthesized Attribute)
• We will generate
– Syntax tree
– Parse tree
– Annotated tree
• Syntax Tree
– Lets drive 8+2*3
23
Parse Tree
24
Annotated Parse Tree
25
Annotated Parse Tree
26
Example (Inherited Attribute)
• The inherited attribute in which
the value at a node is defined in
term of attributes at the parent or
sibling of the node.
27
Types of SDT
• S-attributed SDT
– If an SDT uses only synthesized
attributes, it is called as S-
attributed SDT.
– These attributes are evaluated using S-
attributed SDTs that have their
semantic actions written after the
production (right hand side).
– The values of the parent nodes depend
upon the values of the child nodes.
28
Types of SDT
• L-attributed SDT
– This form of SDT uses both synthesized
and inherited attributes with
restriction of not taking values from
right siblings.
– For example: S → ABC
S can take values from A, B, and C
(synthesized). A can take values from S
only. B can take values from S and A. C
can get values from S, A, and B. No
non-terminal can get values from the
sibling to its right.
29
Types of SDT
30
Types of SDT
31
Types of SDT
32
Types of SDT
33
Types of SDT - Example
• Which of the following is TRUE?
– Both attributes are L-attributed
– Only Rule-1 is L-attributed
– Only Rule-2 is L-attributed
– Neither Rule-1 nor Rule-2 is L-
attributed
34
Attribute Flow
• Just as a context-free grammar does
not specify how it should be parsed,
an attribute grammar does not specify
the order in which attribute rules
should be invoked.
• Context-free grammars are not tied to
any specific parsing order
– E.g. Recursive descent, LR parsing
• Attribute grammars are not tied to an
specific evaluation order
– This evaluation is known as the annotation
or decoration of the parse tree
35
Attribute Flow
Example
• The figure shows
the result of
annotating the
parse tree for
(1+3)*2
• Each symbols has at most
one attribute shown in the
corresponding box
– Numerical value in this
example
– Operator symbols have no
value
• Arrows represent attribute
flow
36
Attribute Flow
Example
37
Attribute Flow
Synthetic and Inherited Attributes
• In the previous example, semantic
information is pass up the parse tree
– We call this type of attributes are called
synthetic attributes
– Attribute grammar with synthetic
attributes only are said to be S-
attributed
• Semantic information can also be
passed down the parse tree
– Using inherited attributes
– Attribute grammar with inherited
attributes only are said to be non-S-
attributed
38
Attribute Flow
Inherited Attributes
• L-attributed grammars, such as the one on the next slide, can
still be evaluated in a single left-to-right pass over the input.
• Each synthetic attribute of a LHS symbol (by definition of
synthetic)depends only on attributes of its RHS symbols.
• Each inherited attribute of a RHS symbol (by definition of L-
attributed) depends only on inherited attributes of the LHS
symbol or on synthetic or inherited attributes of symbols to its
left in the RHS.
• Top-down grammars generally require non-S-attributed flows
– The previous annotated grammar was an S-attributed LR(1)
– L-attributed grammars are the most general class of attribute
grammars that can be evaluated during an LL parse.
39
LL Grammar
40
Non-S-Attributed Grammars
Example
41
Syntax Tree
• There is considerable variety in the
extent to which parsing, semantic
analysis, and intermediate code generation
are interleaved.
• A one-pass compiler interleaves scanning,
parsing, semantic analysis, and code
generation in a single traversal of the
input.
• A common approach interleaves construction
of a syntax tree with parsing (eliminating
the need to build an explicit parse tree),
then follows with separate, sequential
phases for semantic analysis and code
generation.
42
Bottom-up Attribute Grammar to
Construct a Syntax Tree
43
Action Routines
• Automatic tools can construct a
parser for a given context-free
grammar
– E.g. yacc
• Automatic tools can construct a
semantic analyzer for an attribute
grammar
– An ad hoc techniques is to annotate the
grammar with executable rules
– These rules are known as action
routines
44
Action Rules for the Previous
LL(1) attribute grammar
E => T { [Link] := T.v } TT { E.v := TT.v }
TT => + T { [Link] := [Link] + T.v } TT { TT1.v := TT2.v }
TT => - T { [Link] := [Link] - T.v } TT { TT1.v := TT2.v }
TT => { TT.v := [Link] }
T => F { [Link] := F.v } FT { T.v := FT.v }
FT => * F { [Link] := [Link] * F.v } FT { FT1.v := FT2.v }
FT => / F { [Link] := [Link] / F.v } FT { FT1.v := FT2.v }
FT => { FT.v := [Link] }
F => - F { F1.v := - F2.v }
F => ( E ) { F.v := E.v }
F => const { F.v := C.v }
45
Action Rules
• The ease with which rules were incorporated
in the grammar is due to the fact that the
attribute grammar is L-attributed.
• The action rules for L-attributed grammars,
in which the attribute flow is depth-first
left-to-right, can be evaluated in the
order of the parse tree prediction for LL
grammars.
• Action rules for S-attributed grammars can
be incorporated at the end of the right-
hand sides of LR grammars. But, if action
rules are responsible for a significant
part of the semantic analysis, they will
need more contextual information to do
their job.
46
Static and Dynamic Semantics
• Attribute grammars add basic
semantic rules to the specification
of a language
– They specify static semantics
• But they are limited to the
semantic form that can be checked
at compile time
• Other semantic properties cannot be
checked at compile time
– They are described using dynamic
semantics
47
Dynamic Semantics
• Use to formally specify the behavior of
a programming language
– Semantic-based error detection
– Correctness proofs
• There is not a universally accepted
notation
– Operational semantics
» Executing statements that represent changes in
the state of a real or simulated machine
– Axiomatic semantics
» Using predicate calculus (pre and post-
conditions)
– Denotational semantics
» Using recursive function theory
48
Semantic Specification
• The most common way of specifying
the semantics of a language is
plain english
– [Link]
t_edition/html/[Link]#24588
• There is a lack of formal rigor in
the semantic specification of
programming languages
– Guess why
49