Ognsemantic Analysis
Ognsemantic Analysis
Content influenced by many excellent references, see References slide for acknowledgements.
An Overview of Compilation
source program target program
intermediate code
semantic analyzer
generator
Beyond Scanning and Parsing
• A compiler must do more than just recognize whether a sentence
belongs to a programming language grammar
• An input program can be grammatically correct but may contain other errors
that prevent compilation
• Lexer and parser cannot catch all program errors
• Some language features cannot be modeled using context-free
grammar (CFG)
• Whether a variable has been declared before use?
• Parameter types and numbers match in the declaration and use of a function
• Types match on both sides of an assignment
Questions That Compiler Needs to Answer
• Has a variable been declared?
• What is the type and size of a variable?
• Is the variable scalar or an array?
• Is an array access A[i][j][k] consistent with the declaration?
• Does the name “x” correspond to a variable or a function?
Questions • If x is a function, how many arguments does it take?
• What kind of value, if any, does a function x return?
• Are all invocations of a function consistent with the
declaration?
• Track inheritance relationship
• Ensure that classes and its methods are not multiply defined
Semantic Analysis: Static Semantics
• Finding answers to these questions is part of the semantic analysis
phasen
• For example, ensure variable are declared before their uses and check that
each expression has a correct type
• These are static semantics of languages
Checking Dynamic Semantics
• Dynamic semantics of languages int dot_prod(int x[], int y[]) {
need to be checked at run time int d, i;
• Whether an overflow will occur d = 0;
during an arithmetic operation? for (i=0; i<10; i++)
• Whether array bounds will be d += x[i]*y[i];
exceeded during execution?
return d;
• Whether recursion will exceed stack
limits? }
10
SDD and SDT Scheme
SDD:
SDT:
F → id { print id.val } // semantic action
13
Syntax-Directed Definition
• A syntax-directed definition (SDD) is a context-free grammar with
rules and attributes
• A SDD specifies the values of attributes by associating semantic rules with the
grammar productions
Example
A → XYZW
Parent: A, Child: X, Y, Z, W
If parent is taking any value from child(s), then it is
synthesized.
If parent is giving any value or siblings are giving
any value, then it is inherited.
SDD: Synthesized Attributes
• SDD evaluates expressions terminated by an endmarker n.
• In the SDD, each of the non-terminals has a single synthesized attribute, called
val.
• The terminal digit has a synthesized attribute lexval, which is an integer value
returned by the lexical analyzer.
SDD: Synthesized Attributes
• Production 2: E → E1 + T, has one rule, which computes the val attribute for the
head E as the sum of the values at E1 and T.
• At any parse-tree node N labeled E, the value of val for E is the sum of the values
of val at the children of node N labeled E and T.
• An SDD that involves only synthesized attributes is called S-attributed; the SDD
below has this property.
Inherited Attributes
𝑋 𝑌 𝑋. 𝑥 𝑌. 𝑦
Example
• Whenever following production is used in a parse tree
E→ E1 + E2 E.val = E1.val + E2.val
we create a dependency graph
E.val
E1.val E2.val
33
Annotated Parse Tree
• A parse tree showing the
value(s) of its attribute(s) is
called an annotated parse
tree
Example Attribute Grammar
Draw Parse tree for 3 * 5 + 4 n
Parse tree for 3 * 5 + 4 n
E n
E + T
T F
T * digit
F
F digit
digit
Annotated Parse Tree
• A parse tree showing the
value(s) of its attribute(s) is
called an annotated parse
tree
Annotated Parse tree for 3 * 4 + 5 n
L Print 17
Val=17 E $
Val=12 E + T Val=5
Val=12 T F Val=5
Val=3 T * F Val=4 id
Val=3 F id
digit 21
Postfix Notation
• Postfix notation for an expression 𝐸 is defined inductively
• If 𝐸 is a variable or constant, then postfix notation is 𝐸
• If 𝐸 = 𝐸1op𝐸2 where op is any binary operator, then the postfix notation is
𝐸1′ 𝐸2′ op, where 𝐸1′ and 𝐸2′ are postfix notations for 𝐸1 and 𝐸2 respectively
• If 𝐸 = (𝐸1), then postfix notation for 𝐸1 is the notation for 𝐸
SDD for Infix to Postfix Translation
Production Semantic Rules
𝑒𝑥𝑝𝑟 → 𝑒𝑥𝑝𝑟1 + 𝑡𝑒𝑟𝑚 𝑒𝑥𝑝𝑟. 𝑐𝑜𝑑𝑒 = 𝑒𝑥𝑝𝑟1 . 𝑐𝑜𝑑𝑒||𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒||"+"
𝑒𝑥𝑝𝑟 → 𝑒𝑥𝑝𝑟1 − 𝑡𝑒𝑟𝑚 𝑒𝑥𝑝𝑟. 𝑐𝑜𝑑𝑒 = 𝑒𝑥𝑝𝑟1 . 𝑐𝑜𝑑𝑒||𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒||" − "
𝑒𝑥𝑝𝑟 → 𝑡𝑒𝑟𝑚 𝑒𝑥𝑝𝑟. 𝑐𝑜𝑑𝑒 = 𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒
𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒 = "0"
𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒 = "1"
𝑡𝑒𝑟𝑚 → 0 1 … | 9
…
𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒 = "9"
𝑒𝑥𝑝𝑟 Parse
9-5+2
Tree
𝑒𝑥𝑝𝑟 "+" 𝑡𝑒𝑟𝑚
"2"
𝑒𝑥𝑝𝑟 "−" 𝑡𝑒𝑟𝑚
𝑡𝑒𝑟𝑚 "5"
"9"
Annotated Parse Tree
𝑒𝑥𝑝𝑟. 𝑐𝑜𝑑𝑒 = "95 − 2 + "
"2"
𝑒𝑥𝑝𝑟. 𝑐𝑜𝑑𝑒 = "9" "−" 𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒 = "5"
"9"
Parse Tree and Annotated Parse Tree for 3 ∗ 5
Parse Tree and Annotated Parse Tree for 3 ∗ 5
𝑇
𝐹 𝑇′
digit
∗ 𝐹 𝑇1′
digit 𝜖
Parse Tree and Annotated Parse Tree for 3 ∗ 5
𝑇 𝑇. 𝑣𝑎𝑙 = 15
𝐹 𝑇′ 𝐹. 𝑣𝑎𝑙 = 3 𝑇 ′ . 𝑖𝑛ℎ = 3
𝑇 ′ . 𝑠𝑦𝑛 = 15
digit 𝜖
digit. 𝑙𝑒𝑥𝑣𝑎𝑙 = 5 𝜖
Parse Tree and Annotated Parse Tree for 3 ∗ 5
𝑇 𝑇. 𝑣𝑎𝑙 = 15
𝐹 𝑇′ 𝐹. 𝑣𝑎𝑙 = 3 𝑇 ′ . 𝑖𝑛ℎ = 3
𝑇 ′ . 𝑠𝑦𝑛 = 15
digit 𝜖
digit. 𝑙𝑒𝑥𝑣𝑎𝑙 = 5 𝜖
Another Example Parse Tree for “float 𝑥, 𝑦, 𝑧”?
𝐿 , id
𝑎𝑑𝑑𝑡𝑦𝑝𝑒() installs 𝐿. 𝑖𝑛 as the type of the symbol table object
pointed to by id. 𝑒𝑛𝑡𝑟𝑦
id
Annotated Parse Tree
𝐿.in= float , id
id
Abstract Syntax Tree (AST)
• Condensed form of a parse tree used for representing language
constructs
• ASTs do not check for string membership in the language for a grammar
• ASTs represent relationships between language constructs, do not bother
with derivations
if−then−else
𝑆 → if 𝑃 then 𝑆1else 𝑆2
P 𝑆1 𝑆2
𝐸𝑥𝑝𝑟 +
𝐸𝑥𝑝𝑟 + 𝑇𝑒𝑟𝑚
− name
𝐹𝑎𝑐𝑡𝑜𝑟 name
name
Creating an AST
• Following sequence of function calls create an AST for 𝑎 − 4 + 𝑐
2. 𝑝2 = new 𝐿𝑒𝑎𝑓(num, 4)
3. 𝑝3 = new 𝑁𝑜𝑑𝑒(“ − ”, 𝑝1, 𝑝2)
4. 𝑝4 = new 𝐿𝑒𝑎𝑓(id, 𝑒𝑛𝑡𝑟𝑦𝑐) − id
5. 𝑝5 = new 𝑁𝑜𝑑𝑒(“ + ”, 𝑝3, 𝑝4)
entry for 𝑐
id num 4
entry for 𝑎
S-Attributed Definition for Constructing
Syntax Trees
𝐸 𝑛𝑜𝑑𝑒 + 𝑇 𝑛𝑜𝑑𝑒
𝐸 𝑛𝑜𝑑𝑒 − 𝑇 𝑛𝑜𝑑𝑒 id
+
num
𝑇 𝑛𝑜𝑑𝑒 id
−
id entry for 𝑐
id
i num 4
d
entry for 𝑎
Bottom-up Evaluation of S-Attributed
Definitions
Input … … 𝑤 $
• Suppose 𝐴 → 𝑋𝑌𝑍, and
semantic rule is 𝐴. 𝑎 =
𝑓(𝑋. 𝑥, 𝑌. 𝑦, 𝑍. 𝑧)
𝑍. 𝑧 𝑍
LR Parsing
Program
• Can be computed during 𝑌. 𝑦 𝑌
bottom-up parsing
• On reduction, value of new 𝑋. 𝑥 𝑋
synthesized attribute 𝐴. 𝑎 is
computed from the attributes $ $
on the stack
• Extend stack to hold values Value State
stack stack
Example S-Attributed Definition
Bottom-up Evaluation of S-Attributed Definitions
Bottom-up Evaluation of S-Attributed Definitions
Value State Input Action
$ $ 3 ∗ 5 + 4$ Shift
$3 $digit ∗ 5 + 4$ Reduce by 𝐹 → digit
$3 $𝐹 ∗ 5 + 4$ Reduce by 𝑇 → 𝐹
$3 $𝑇 ∗ 5 + 4$ Shift
$3 $𝑇 ∗ 5 + 4$ Shift
$3 5 $𝑇 ∗ digit +4$ Reduce by 𝐹 → digit
$3 5 $𝑇 ∗ 𝐹 +4$ Reduce by 𝑇 → 𝑇 ∗ 𝐹
$15 $𝑇 +4$ Reduce by 𝐸 → 𝑇
$15 $𝐸 +4$ Shift
$15 $𝐸 + 4$ Shift
$15 4 $𝐸 + digit $ Reduce by 𝐹 → digit
$15 4 $𝐸 + 𝐹 $ Reduce by 𝑇 → 𝐹
$15 4 $𝐸 + 𝑇 $ Reduce by 𝐸 → 𝐸 + 𝑇
$19 $𝐸 $ …
SDT for Infix to Postfix Translation
SDD SDT
Production Semantic Rules Production Semantic Rules
𝑒𝑥𝑝𝑟 𝑒𝑥𝑝𝑟. 𝑐𝑜𝑑𝑒 = 𝑒𝑥𝑝𝑟 → 𝑒𝑥𝑝𝑟1 + 𝑡𝑒𝑟𝑚 { 𝑝𝑟𝑖𝑛𝑡 " + " }
→ 𝑒𝑥𝑝𝑟1 + 𝑡𝑒𝑟𝑚 𝑒𝑥𝑝𝑟1 . 𝑐𝑜𝑑𝑒||𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒||" + "
𝑒𝑥𝑝𝑟 → 𝑒𝑥𝑝𝑟1 − 𝑡𝑒𝑟𝑚 { 𝑝𝑟𝑖𝑛𝑡 " − " }
𝑒𝑥𝑝𝑟 𝑒𝑥𝑝𝑟. 𝑐𝑜𝑑𝑒 =
→ 𝑒𝑥𝑝𝑟1 − 𝑡𝑒𝑟𝑚 𝑒𝑥𝑝𝑟1 . 𝑐𝑜𝑑𝑒||𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒||" − " 𝑒𝑥𝑝𝑟 → 𝑡𝑒𝑟𝑚
𝑒𝑥𝑝𝑟 → 𝑡𝑒𝑟𝑚 𝑒𝑥𝑝𝑟. 𝑐𝑜𝑑𝑒 = 𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒 { 𝑝𝑟𝑖𝑛𝑡("0") }
𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒 = "0"
{ 𝑝𝑟𝑖𝑛𝑡("1") }
𝑡𝑒𝑟𝑚 → 0 1 … | 9
𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒 = "1" …
𝑡𝑒𝑟𝑚 → 0 1 … | 9 { 𝑝𝑟𝑖𝑛𝑡("9") }
…
𝑡𝑒𝑟𝑚. 𝑐𝑜𝑑𝑒 = "9"
SDT Actions
𝑒𝑥𝑝𝑟
SDT
Production Semantic Rules
𝑒𝑥𝑝𝑟 → 𝑒𝑥𝑝𝑟1 + 𝑡𝑒𝑟𝑚 { 𝑝𝑟𝑖𝑛𝑡 " + " }
𝑒𝑥𝑝𝑟 → 𝑒𝑥𝑝𝑟1 − 𝑡𝑒𝑟𝑚 { 𝑝𝑟𝑖𝑛𝑡 " − " }
𝑒𝑥𝑝𝑟 → 𝑡𝑒𝑟𝑚
{ 𝑝𝑟𝑖𝑛𝑡("0") }
{ 𝑝𝑟𝑖𝑛𝑡("1") }
𝑡𝑒𝑟𝑚 → 0 1 … | 9
…
{ 𝑝𝑟𝑖𝑛𝑡("9") }