You are on page 1of 28

Compilers Lesson 5: semantic analysis

3rd year
Spring term

Alfonso Ortega: alfonso.ortega@uam.es


Enrique Alfonseca: enrique.alfonseca@uam.es

Semantic analysis Semantic analysis


Introduction: motivation Introduction: motivation
• Set of independent routines used by the morphological and syntactic analyser.
• The input is the parse tree, either fully built, or in construction, and these routines add <Program>
semantic error checking:
begin <declrcns> ; <sntncs> end
• They test type restrictions in expressions and assignations. int A
• They check other semantic limitations, e.g. declaration and initialisation of int <declrcn> <sntnc> ; <sntncs>
identifiers before their use, type correspondence, number of arguments in
function calls, etc. int
<type> <ids> <asignacion> <sntnc> ; <sntncs>
• We can image that, when the semantic analysis ends, the syntactic tree will have
some annotations about its semantics. int int int
• These annotations serve to: int <id> <id> := <expr> <asignacion> <sntnc>
• Determine the semantic correctness of the program.
A A <const.int> <id> := <expr> <salida>
• Prepare the next step: the code generation int int
100 A <expr> + <expr> output <expr>
int int int
<id> <id> <id>
int int int
A A A

3 4
Semantic analysis Semantic analysis
Introduction: Semantic analysis in 1-pass compilers Introduction: Semantic analysis in compilers with 2 o more passes

segment .data segment .data


_A dd 0 _A dd 0
(<palabra clave>,begin)
(<type>,int)(<id>,A)(<symbol>,;) Synt
segment .codigo
global _main
(<palabra clave>,begin)
(<type>,int)(<id>,A)(<symbol>,;)
Sem. segment .codigo
global _main

Ana.
_main: _main:
(<id>,A)(<symbolm>,:=)
(<cons int>,100)(<symbol>,;)
& push dword 100
pop eax
(<id>,A)(<symbolm>,:=)
(<cons int>,100)(<symbol>,;)
push dword 100
pop eax

Sem.
mov [_A], eax mov [_A], eax
(<id>,A)(<symbolm>,:=) (<id>,A)(<symbolm>,:=)
push dword [_A] push dword [_A]
(<id>,A)(<symbol>,+)(<id>,A)(<symbol>,;) (<id>,A)(<symbol>,+)(<id>,A)(<symbol>,;)
POP edx POP edx

anal.
(<palabra clave>,output)(<id>,A) (<palabra clave>,output)(<id>,A)
add eax,edx add eax,edx
Code
(palabra clave>,end) (palabra clave>,end)
push eax push eax

?
pop eax pop eax
mov [_A], eax mov [_A], eax
Morphosyntactic push dword [_A]
pop eax
Morphosyntactic Intermediate push dword [_A]
pop eax
Code generation,
analysis Code push eax
call imprime_integer
analysis file
push eax
optimisation, memory mngmt. call imprime_integer
add esp, 4 add esp, 4
call imprime_fin_linea call imprime_fin_linea
ret
5 ret
6

Semantic analysis Semantic analysis


Introduction: use of the stack Introduction: attributes
• The syntactic analyser is an “enriched variation” of a pushdown automata that • The procedure which is most widely used consists of adding, to each node in the
recognises the language studied. parse tree, the information about the semantics of the program that we are going to
• We have seen in detail how a stack is used in most kinds of analysers: LR(0), need.
SLR(1), LALR(1), LR(1), LL(1) and with precedence grammars. • This information is usually called attributes.
• The semantic analyser will also use a stack, called semantic stack, to store the • Along this lesson, we are going to formalise the idea of extending the grammar of the
“semantic annotations” for each of the syntactic elements analysed. language:
• The semantic stack can be the same as the syntactic stack. • Adding attributes to the symbols in the grammar.
• Providing methods for calculating the value of the attributes of a symbol, in
function of the attributes of other symbols.

7 8
Attributes: informal description Attributes: informal description
Examples Examples
• Consider the subset of the rules that describe the arithmetic expressions in the high- • Consider the following grammar for arithmetic expressions. Note that it is ambiguous,
level programming languages. so there may be conflicts in the design of some of the analysers, which might be
solved by assigning priorities to the operators.
GE={{+,*,(,),c,i}, {E},
• To treat correctly these expressions, most programming languages have ways to
{
specify:
E→E+E,
• The type of the result of the expressions (integer, real, etc.) E→E-E,
• The resulting value. E→-E,
E→E*E,
• In this way, each symbol can have a type and a value associated. E→E/E,
E→E^E,
• The following are some illustrative examples. E→(E),
E→i,
E→c,
},
E}
• We shall assume that:
• i refers to any identifier, and c refers to any numeric constant.
9 10

Attributes: informal description Attributes: informal description


Examples Examples
• Expression: (3+4)*5 indicates the work performed by the lexical analyser • Expression: (3+4)*5 indicates the work performed by the lexical analyser
E E

E E E E

E E

E E E E

c v:3 c c v:5
c c c v:4
t:i t:i t:i

( 3 + 4 ) * 5 ( 3 + 4 ) * 5

11 12
Attributes: informal description Attributes: informal description
Examples Examples
• Expression: (3+4)*5 indicates the work performed by the lexical analyser • Expression: (3+4)*5 indicates the work performed by the lexical analyser
E E

E E E E

v:7
E E
t:i

v:3 v:4 v:3 v:4


E E E E
t:i t:i t:i t:i

v:3 v:4 c v:5 v:3 v:4 c v:5


c c c c
t:i t:i t:i t:i t:i t:i

( 3 + 4 ) * 5 ( 3 + 4 ) * 5

13 14

Attributes: informal description Attributes: informal description


Examples Examples
• Expression: (3+4)*5 indicates the work performed by the lexical analyser • Expression: (3+4)*5 indicates the work performed by the lexical analyser
E E
v:35
v:7 v:7
E E v:5 E t:i E v:5
t:i t:i t:i t:i

v:7 v:7
E E
t:i t:i

v:3 v:4 v:3 v:4


E E E E
t:i t:i t:i t:i

v:3 c c v:5 c v:5


c v:4 v:3 c c v:4
t:i t:i t:i t:i t:i t:i

( 3 + 4 ) * 5 ( 3 + 4 ) * 5

15 16
Attributes: informal description Attributes: informal description
Example 1: Conclusions Examples
• Observe that, in this case, if we want to obtain the correct value of the whole • Consider the rules for declaring variables:
expression, the “value” attribute should be propagated from the bottom up. GE={{int, real, i}, {D,T,L},
• From the point of view of the rules, {
• The information associated to the left-hand side of the rule is calculated from the D→TL
information associated to the symbols in the right-hand side of the rule. T→int
T→real
L→L,i
• For instance, in the following rule: L→i
E→E+E },
D}
• The semantics would be described from the following expression:
E→E+E and E.value = E.value+E.value
• We shall assume that:
• i refers to identifiers.
• D represents a declarative sentence (a declaration).
• In order to distinguish between the three symbols E in that rule, we can use sub-
indices i and d, as follows: • T indicates the type of the variables.
• L represents a list of comma-separated identifiers (,)
E→Ei+Ed and E.value = Ei.value + Ed.value

17 18

Attributes: informal description Attributes: informal description


Examples Examples
• In the following declaration: int var1, x, y • In the following declaration: int var1, x, y
D D

T L T t:i L

L L

L L

i i i i i i

int var1 , x , y int var1 , x , y

19 20
Attributes: informal description Attributes: informal description
Examples Examples
• In the following declaration: int var1, x, y • In the following declaration: int var1, x, y
D D
t:i t:i
T t:i L t:i T t:i L t:i

L t:i L

L L

v:0
i i i i i i
t:i

int var1 , x , y int var1 , x , y

21 22

Attributes: informal description Attributes: informal description


Examples Example 2: conclusions
• In the following declaration: int var1, x, y
• In this case, it seems reasonable that, when the parser finds the type (the reserved
D word int) then the type should propagate to all the identifiers in the list, and to the
t:i complete declarative sentence.
T t:i L t:i
• We can express this process in the following way:

t:i L D→TL and D.type = T.type; and L.type = D.type

t:i L

v:0 i v:0 i v:0


i
t:i t:i t:i

int var1 , x , y

23 24
Attributes: informal description Syntax-directed Definitions
Kinds of attributes, and attribute propagation Informal idea
• The previous examples have illustrated two kinds of attributes: • “Syntax-directed definitions” can be defined as:
• Synthesised attributes:
• Those used in the cases in which the attributes of the left-hand side are An extension of context-independent grammars, with the following additions
calculated in function of the attributes in the right-hand side. • The symbols (terminals and non-terminals) are extended with:
• An example is the value attribute in the example or arithmetic expressions: • Attributes, which will be used by the modules for semantic analyses
• E→Ei+Ed y E.value = Ei.value + Ed.value and code generation.
• Examples of these attributes:
• Inherited attributes: • The identifiers can be extended with their name, type and value.
• Those used in the cases in which the attributes of a symbol have to be • Constants and expressions can have a type and value associated.
calculated from the attributes of a sibling in the parse tree. • The rules are extended with:
• An example is the type attribute, in the second example: • Actions for manipulating those attributes.
• D→TL y D.type = T.type; y L.type = D.type • For instance, the rule that describes an expression can have the
semantic action that checks the correctness of the types of the sub-
• We shall call propagation to the process of calculating the value of the attributes of a expressions, and the resulting type of the operator, and the calculation
symbol in function of the values of the attributes of other symbols in the grammar. of the resulting value.

25 26

Syntax-directed Definitions Syntax-directed Definitions


Informal idea Informal idea
• In other words, • Each rule has a set of semantic actions that indicate how we can calculate the
• Each symbol has a list of attributes associated. These will be the semantic semantic values of the non-terminal symbols.
values for the symbol. • Each semantic action can be represented as an “assignation statement”, in
• In the example of arithmetic expressions, the following would be the which the attribute of the non-terminal symbol at the left-hand side of the
extended alphabets with attributes. rule is assigned the result of an expression (or a function call), whose
{+,*,(,),c{value,type},i{value,type}}, {E{value,type}} arguments are the attributes of the symbols at the right-hand side of the rule.
• In the example of the declaration of variables, the alphabets of terminals and • We can represent that each symbol has associated a structure with different
non-terminals are: fields, like a struct in C. So, we can refer to the attribute”attr” of the symbol
“A” as “A.attr”.
{{int{type}, real{type}, i{type}}, {D{type},T{type},L{type}}
• We are going to assume that the terminal symbols only have the attributes
calculated by the morphological analyser.
• These attributes are usually called synthesised attributes.

27 28
Syntax-directed Definitions Syntax-directed Definitions
Informal idea Informal idea
• The following is the example with arithmetic expressions: • The following is the example with the declarations of variables:
GE={{+,*,(,),c{value,type}(1),i{value,type}(1)}, {E{value,type}}, GE={ {{int{type}, real{type}, i{type}}(1),
{ {D{type},T{type},L{type}},
E→Ei+Ed {E.value:= Ei.value+Ed.value, E.type:= Ei.type(2)}, {
E→Ei-Ed {E.value:= Ei.value-Ed.value, E.type:= Ei.type(2)}, D→TL {L.type:=T.type},
E→-Ed, {E.value:= -Ed.value, E.type:= Ed.type}, T→int {T.type:=integer},
E→E*E {E.value:= Ei.value*Ed.value, E.type:= Ei.type(2)}, T→real {T.type:=real},
E→Ei/Ed, {E.value:= Ei.value/Ed.value, E.type:= Ei.type(3)} L→Ld,i {Ld.type:=L.type},
E→Ei^Ed {E.value:= Ei.value^Ed.value, E.type:= Ei.type(3)},
L→i
E→(Ed) {E.value:= Ed.value, E.type:= Ei.type},
},
E→i {E.value:= i.value, E.type:= i.type},
D}
E→c {E.value:= c.value, E.type:= c.type}
• (1) Values provided by the morphological analyser
},
E}
• (1) These values are provided by the morphological analyser
• (2) We can place here the type checks.
• (3) We can place here type checks, and additional error detections, such as making

sure that the second argument of the division is not 0.

29 30

Syntax-directed Definitions Syntax-directed Definitions


Informal idea Informal idea
• We can also add semantic actions with a different effect to that of calculating • Imagine that the action of inserting an identifier in the symbols table is
the values of other semantic attributes. performed by the following function:
• Whenever this is needed, it can be implemented as creating a new attribute add_type(SymbolsTable* pT, Identifier i, Type type)
(fictitious or nameless) for a symbol, which will not be assigned any value by
the function associated. • Where:
• In this last example, we might add a new action to modify the symbols • pT is a pointer to the symbols table.
table when we are determining the type of an identifier. • i is the token returned by the morphological analyser.
GE={ {{int{type}, real{type}, i{type}}(1),
GE={ {{int{type}, real{type}, i{type}}(1), {D{type},T{type},L{type}},
{D{type},T{type},L{type}}, {
{
D→TL {L.type:=T.type},
D→TL {L.type:=T.type},
T→int {T.type:=integer},
T→int {T.type:=integer},
T→real {T.type:=real},
T→real {T.type:=real},
L→Ld,i {Ld.type:=L.type}, L→Ld,i {Ld.type:=L.type,add_type(&Table,i,L.type)},
L→i L→i {add_type(&Table,i,L.type)}
}, },
D} D}

31 32
Syntax-directed Definitions Syntax-directed Definitions
Examples Examples
• Let us consider now a slightly more complicated grammar, which includes the ones that we • The following is the analyses of int var1, x, y x:=(3+4)*5
have studied until now. This grammar will allow us to declare identifiers, and to assign them the
result of expressions: P
GE={{int{type}, real{type}, i{type,value}, +, *, (, )},
{D{type},T{type},L{type},E{value,type},A{type},P},
A
{ P→DA, A→i:=E {“i∈SymTab”∧E.type=i.type⇒A.type:=i.type} D TS
E
D→TL {L.type:=T.type},
T→int {T.type:=integer}, E E
T L
T→real {T.type:=real},
L→Ld,i {Ld.type:=L.type,add_type(&T,i,L.type)},
L→i {add_type(&T,i,L.type)},
L E
E→Ei+Ed {E.value:= Ei.value+Ed.value, E.type:= Ei.type},
E→Ei-Ed {E.value:= Ei.value-Ed.value, E.type:= Ei.type},
E→-Ed, {E.value:= -Ed.value, E.type:= Ed.type}, L E E
E→E*E {E.value:= Ei.value*Ed.value, E.type:= Ei.type},
E→Ei/Ed, {E.value:= Ei.value/Ed.value, E.type:= Ei.type}
E→Ei^Ed {E.value:= Ei.value^Ed.value, E.type:= Ei.type}, c
i i i i c c
E→(Ed) {E.value:= Ed.value, E.type:= Ei.type},
E→i {E.value:= i.value, E.type:= i.type},
int var1 , x , y x := ( 3 + 4 ) * 5
E→c {E.value:= c.value, E.type:= c.type}},
P}
33 34

Syntax-directed Definitions Syntax-directed Definitions


Examples Examples

P P

A A
D TS D TS
E t:i E

T t:i L E E T t:i L t:i E E

L E L E

L E E L E E

c c
i i i i c c i i i i c c

int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

35 36
Syntax-directed Definitions Syntax-directed Definitions
Examples Examples

P P

A A
D TS D TS
t:i E t:i E
y(int) y(int)
T t:i L t:i E E T t:i L t:i E E
x(int)

var1(int)
t:i L E t:i L E

L t:i L
E E E E

v:0 c v:0 v:0 v:0 c


i i i i c c i i i i c c
t:i t:i t:i t:i

int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

37 38

Syntax-directed Definitions Syntax-directed Definitions


Examples Examples

P P

A A
D TS D TS
t:i E t:i E
y(int) y(int)
T t:i L t:i E E T t:i L t:i E E
x(int) x(int)

var1(int) var1(int)
t:i L E t:i L E

t:i L t:i L
E E E E

v:0 v:0 v:0 v:0 c v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i

int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

39 40
Syntax-directed Definitions Syntax-directed Definitions
Examples Examples

P P

A A
D TS D TS
t:i E t:i E
y(int) y(int)
T t:i L t:i E E T t:i L t:i E E
x(int) x(int)

var1(int) var1(int)
v:7
t:i L E t:i L E
t:i

t:i L v:3 v:4 t:i L v:3 v:4


E E E E
t:i t:i t:i t:i

v:0 v:0 v:0 v:0 v:3 v:4 c v:5 v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i

int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

41 42

Syntax-directed Definitions Syntax-directed Definitions


Examples Examples

P P

A A
D TS D TS
t:i E t:i E
y(int) y(int) v:35
v:7 v:7
T t:i L t:i E E v:5 T t:i L t:i E t:i E v:5
x(int) t:i t:i x(int) t:i t:i

var1(int) var1(int)
v:7 v:7
t:i L E t:i L E
t:i t:i

t:i L v:3 v:4 t:i L v:3 v:4


E E E E
t:i t:i t:i t:i

v:0 v:0 v:0 v:0 v:3 v:4 c v:5 v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i

int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

43 44
Syntax-directed Definitions Syntax-directed Definitions
Examples Conclusions
• The propagation of attributes is like adding annotations to the nodes in the syntactic
parse tree.
P
• This formalism makes it easy to determine the order in which we need to perform the
A
semantic actions to obtain the correct result.
D TS t:i
E
• However, in real situations, we may not have the parse tree, and it is not always
t:i
y(int) v:35
adequate to generate it completely before starting annotating it.
T t:i L t:i
x(int)
E
v:7
t:i
t:i E v:5
t:i
• We need to decide, therefore:
• How to determine the order in which the tree nodes will be visited so we
var1(int) can calculate all the semantic values correctly.
v:7
t:i L E
t:i • How to perform the semantic actions in the nodes during the syntactic
analysis, to obtain an adequate compiler with respect to power and efficiency.
t:i L v:3 v:4
t:i
E E
t:i • We shall see that some attributes are more suitable for top-down analysis,
and others for bottom-up analysis.

v:0 v:0 v:0 v:0 v:3 v:4 c v:5


i i i i c c
t:i t:i t:i t:i t:i t:i t:i

int var1 , x , y x := ( 3 + 4 ) * 5

45 46

Attribute Grammars Attribute Grammars


Formal definition Introduction to the most general technique
• An attributes grammar is a syntax-directed definition, in which the semantic actions • The most general techniques used for semantic analyses with attributes grammar is
do not have side effects. They can only be used to calculate the values of attributes. the following:
• Actions such as introducing an identifier in the symbols table would not be 1. To determine the dependences between some attributes and the others, by
allowed. studying the semantic rules.
2. To build the parse tree.
• The sides effects could be treated by creating fictitious attributes. 3. To determine an order between the nodes (by annotating the tree with a
• From now, we are going to use, indistinctly, the terms attributes grammar, and numeric sequence). It will be the correct ordering for calculating the semantic
syntax-directed definitions. attributes.
4. To establish a path along the tree that respects the previous ordering, and to
apply it.
5. The result of the evaluation of the semantic actions in the previous ordering will
be the correct semantic analysis of the program.

47 48
Attribute Grammars Attribute Grammars
Introduction to the most general technique Examples: steps 2 and 3
1. To determine the dependences between some attributes and the others, by studying • We can annotate a path in the parse tree:
the semantic rules. E
• The following approach will be followed: v:35
v:7
1. For every semantic action, E t:i E v:5
t:i t:i
2. If the action is of the following type
b:= f(c1,...,cn)
v:7
We shall say that b depends on c1,...,cn E
t:i
• At the end, we shall have all the semantic dependences calculated, between all
the attributes. v:3 v:4
E E
t:i t:i
2. Next, the parse tree is built.
v:3 v:4 c v:5
3. The following are possible orderings for the parse trees seen in the previous t:i
c c
t:i t:i
examples.
1
( 3 + 4 ) * 5

49 50

Attribute Grammars Attribute Grammars


Examples: steps 2 and 3 Examples: steps 2 and 3

E E
v:35 v:35
v:7 v:7
E t:i E v:5 E t:i E v:5
t:i t:i t:i t:i

v:7 v:7
E E
t:i t:i

v:3 v:4 v:3 v:4


2 t:i E E
t:i 2 t:i E E
t:i

v:3 c c v:5 c v:5


c v:4 v:3 c c v:4
t:i t:i t:i t:i t:i t:i
1 1 3
( 3 + 4 ) * 5 ( 3 + 4 ) * 5

51 52
Attribute Grammars Attribute Grammars
Examples: steps 2 and 3 Examples: steps 2 and 3

E E
v:35 v:35
v:7 v:7
E t:i E v:5 E t:i E v:5
t:i t:i t:i t:i

E
v:7
E
v:7 5
t:i t:i

v:3 v:4 v:3 v:4


2 t:i E E
t:i 4 2 t:i E E
t:i 4

v:3 v:4 c v:5 v:3 v:4 c v:5


c c c c
t:i t:i t:i t:i t:i t:i
1 3 1 3
( 3 + 4 ) * 5 ( 3 + 4 ) * 5

53 54

Attribute Grammars Attribute Grammars


Examples: steps 2 and 3 Examples: steps 2 and 3

E E
v:35 v:35
E
v:7 6 t:i E v:5 E
v:7 6 t:i E v:5
t:i t:i t:i t:i

E
v:7 5 E
v:7 5
t:i t:i

v:3 v:4 v:3 v:4


2 t:i E E
t:i 4 2 t:i E E
t:i 4

v:3 c c v:5 c v:5


c v:4 v:3 c c v:4
t:i t:i t:i t:i t:i t:i
1 3 1 3 7
( 3 + 4 ) * 5 ( 3 + 4 ) * 5

55 56
Attribute Grammars Attribute Grammars
Examples: steps 2 and 3 Examples: steps 2 and 3

E E
v:35 v:35
9
E
v:7 6 t:i E v:5 8 E
v:7 6 t:i E v:5 8
t:i t:i t:i t:i

E
v:7 5 E
v:7 5
t:i t:i

v:3 v:4 v:3 v:4


2 t:i E E
t:i 4 2 t:i E E
t:i 4

v:3 v:4 c v:5 v:3 v:4 c v:5


c c c c
t:i t:i t:i t:i t:i t:i
1 3 7 1 3 7
( 3 + 4 ) * 5 ( 3 + 4 ) * 5

57 58

Attribute Grammars Attribute Grammars


Examples: steps 2 and 3 Examples: steps 2 and 3
• The same for the declaration:
D D
t:i t:i
2
T t:i L t:i T t:i L t:i

1 1
t:i L t:i L

t:i L t:i L

v:0 i v:0 i v:0 v:0 i v:0 i v:0


i i
t:i t:i t:i t:i t:i t:i

int var1 , x , y int var1 , x , y

59 60
Attribute Grammars Attribute Grammars
Examples: steps 2 and 3 Examples: steps 2 and 3

D D
t:i
2 t:i
2
T t:i L t:i T t:i L t:i

1 3 1 3
t:i L t:i L
4
t:i L t:i L

v:0 v:0 v:0 v:0 v:0 v:0


i i i i i i
t:i t:i t:i t:i t:i t:i

int var1 , x , y int var1 , x , y

61 62

Attribute Grammars Attribute Grammars


Examples: steps 2 and 3 Examples: steps 2 and 3

D D
t:i
2 t:i
2
T t:i L t:i T t:i L t:i

1 3 1 3
t:i L t:i L
4 4
t:i L t:i L
5 5

v:0 i v:0 i v:0 v:0 i v:0 i v:0


i i
t:i t:i t:i t:i t:i t:i
6
int var1 , x , y int var1 , x , y

63 64
Attribute Grammars Attribute Grammars
Examples: steps 2 and 3 Examples: steps 2 and 3

D D
t:i
2 t:i
2
T t:i L t:i T t:i L t:i

1 3 1 3
t:i L t:i L
4 4
t:i L t:i L
5 5

v:0 v:0 v:0 v:0 v:0 v:0


i i i i i i
t:i t:i t:i t:i t:i t:i
6 7 6 7 8
int var1 , x , y int var1 , x , y

65 66

Attribute Grammars Attribute Grammars


Examples: steps 2 and 3 Examples: steps 2 and 3
• And for the final example:

P P

A A
D TS t:i D TS t:i
t:i E t:i 2 E
v:35 v:35
v:7 v:7
T t:i L t:i E t:i E v:5 T t:i L t:i E t:i E v:5
t:i t:i t:i t:i
1 1
v:7 v:7
t:i L E t:i L E
t:i t:i

t:i L v:3 v:4 t:i L v:3 v:4


E E E E
t:i t:i t:i t:i

v:0 v:0 v:0 v:0 v:3 v:4 c v:5 v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i

int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

67 68
Attribute Grammars Attribute Grammars
Examples: steps 2 and 3 Examples: steps 2 and 3

P P

A A
D TS t:i D TS t:i
t:i 2 E t:i 2 E
v:35 v:35
v:7 v:7
T t:i L t:i E t:i E v:5 T t:i L t:i E t:i E v:5
t:i t:i t:i t:i
1 3 1 3
v:7 4 v:7
t:i L E t:i L E
t:i t:i

t:i L v:3 v:4 t:i L v:3 v:4


E E E E
t:i t:i t:i t:i

v:0 v:0 v:0 v:0 v:3 v:4 c v:5 v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i

int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

69 70

Attribute Grammars Attribute Grammars


Examples: steps 2 and 3 Examples: steps 2 and 3

P P

A A
D TS t:i D TS t:i
t:i 2 E t:i 2 E
v:35 v:35
v:7 v:7
T t:i L t:i E t:i E v:5 T t:i L t:i E t:i E v:5
t:i t:i t:i t:i
1 3 1 3
4 v:7 4 var1(int)
v:7
t:i L E t:i L E
t:i t:i
5 5
t:i L v:3 v:4 t:i L v:3 v:4
E E E E
t:i t:i t:i t:i

v:0 v:0 v:0 v:0 v:3 v:4 c v:5 v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i
6
int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

71 72
Attribute Grammars Attribute Grammars
Examples: steps 2 and 3 Examples: steps 2 and 3

P P

A A
D TS t:i D TS t:i
t:i 2 E t:i 2 y(int)
E
v:35 v:35
v:7 v:7
T t:i L t:i E t:i E v:5 T t:i L t:i E t:i E v:5
x(int) t:i t:i x(int) t:i t:i
1 3 1 3
4 var1(int)
v:7 4 var1(int)
v:7
t:i L E t:i L E
t:i t:i
5 5
t:i L v:3 v:4 t:i L v:3 v:4
E E E E
t:i t:i t:i t:i

v:0 v:0 v:0 v:0 v:3 v:4 c v:5 v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i
6 7 6 7 8
int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

73 74

Attribute Grammars Attribute Grammars


Examples: steps 2 and 3 Examples: steps 2 and 3

P P

A A
D TS t:i D TS t:i
t:i 2 y(int)
E t:i 2 y(int)
E
v:35 v:35
v:7 v:7
T t:i L t:i E t:i E v:5 T t:i L t:i E t:i E v:5
x(int) t:i t:i x(int) t:i t:i
1 3 1 3
4 var1(int)
v:7 4 var1(int)
v:7
t:i L E t:i L E
t:i t:i
5 5
t:i L v:3 v:4 t:i L v:3 v:4
E E E E
t:i t:i t:i t:i

v:0 v:0 v:0 v:0 v:3 v:4 c v:5 v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i
6 7 8 9 6 7 8 9 10
int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

75 76
Attribute Grammars Attribute Grammars
Examples: steps 2 and 3 Examples: steps 2 and 3

P P

A A
D TS t:i D TS t:i
t:i 2 y(int)
E t:i 2 y(int)
E
v:35 v:35
v:7 v:7
T t:i L t:i E t:i E v:5 T t:i L t:i E t:i E v:5
x(int) t:i t:i x(int) t:i t:i
1 3 1 3
4 var1(int)
v:7 4 var1(int)
v:7
t:i L E t:i L E
t:i t:i
5 5
t:i L v:3 v:4 t:i L v:3 v:4
E E E E
t:i t:i t:i t:i
11 11
v:0 v:0 v:0 v:0 v:3 v:4 c v:5 v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i
6 7 8 9 10 6 7 8 9 10 12
int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

77 78

Attribute Grammars Attribute Grammars


Examples: steps 2 and 3 Examples: steps 2 and 3

P P

A A
D TS t:i D TS t:i
t:i 2 y(int)
E t:i 2 y(int)
E
v:35 v:35
v:7 v:7
T t:i L t:i E t:i E v:5 T t:i L t:i E t:i E v:5
x(int) t:i t:i x(int) t:i t:i
1 3 1 3
4 var1(int)
v:7 4 var1(int)
v:7
t:i L E t:i L E
t:i t:i
5 5 14
t:i L v:3 v:4 t:i L v:3 v:4
E E E E
t:i t:i t:i t:i
11 13 11 13
v:0 v:0 v:0 v:0 v:3 v:4 c v:5 v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i
6 7 8 9 10 12 6 7 8 9 10 12
int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

79 80
Attribute Grammars Attribute Grammars
Examples: steps 2 and 3 Examples: steps 2 and 3

P P

A A
D TS t:i D TS t:i
t:i 2 y(int)
E t:i 2 y(int)
E
v:35 v:35
v:7 v:7
T t:i L t:i E t:i E v:5 T t:i L t:i E t:i E v:5
x(int) t:i t:i x(int) t:i t:i
1 3 15 1 3 15
4 var1(int)
v:7 4 var1(int)
v:7
t:i L E t:i L E
t:i t:i
5 14 5 14
t:i L v:3 v:4 t:i L v:3 v:4
E E E E
t:i t:i t:i t:i
11 13 11 13
v:0 v:0 v:0 v:0 v:3 v:4 c v:5 v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i
6 7 8 9 10 12 6 7 8 9 10 12 16
int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

81 82

Attribute Grammars Attribute Grammars


Examples: steps 2 and 3 Examples: steps 2 and 3

P P

A A
D TS t:i D TS t:i
t:i 2 y(int)
E t:i 2 y(int)
E
v:35 v:35
v:7 v:7
T t:i L t:i E t:i E v:5 T t:i L t:i E t:i E v:5
x(int) t:i t:i x(int) t:i t:i
1 3 15 1 3 15 18
17 17
4 var1(int)
v:7 4 var1(int)
v:7
t:i L E t:i L E
t:i t:i
5 14 5 14
t:i L v:3 v:4 t:i L v:3 v:4
E E E E
t:i t:i t:i t:i
11 13 11 13
v:0 v:0 v:0 v:0 v:3 v:4 c v:5 v:0 v:0 v:0 v:0 v:3 v:4 c v:5
i i i i c c i i i i c c
t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i t:i
6 7 8 9 10 12 16 6 7 8 9 10 12 16
int var1 , x , y x := ( 3 + 4 ) * 5 int var1 , x , y x := ( 3 + 4 ) * 5

83 84
Attribute Grammars Attribute Grammars
Examples: steps 2 and 3 Introduction to the more general technique
3. The third step, that we have seen with some examples, can be formalised:
P
1. For each semantic action that is a side effect:
g(a1,...,am)
A 1. We create a new attribute a’
D TS t:i
2 E 2. We assume that the semantic action is really:
t:i
y(int) 19
v:35 a’:=g(a1,...,am)
v:7
T t:i L t:i E t:i E v:5
3
x(int) t:i
18
t:i 2. We construct a dependency graph with the following algorithm:
1 15 17
4 var1(int) graph BuildDependencyGraph
v:7
t:i L E (tree as, attributes_grammar ga){
t:i
5 14 node n; semantic_attribute a; semantic_action acc;
t:i L v:3 v:4 graph gd = empty_graph;
E E
t:i t:i “For each node (n) in the parse tree as”
11 13 “For each attribute (a) of symbol n”
v:3 v:4 c v:5 AddNode( new_node(a), gd);
v:0 v:0 v:0 v:0
i i i i c c “For each node (n) in the parse_tree as”
t:i t:i t:i t:i t:i t:i t:i
6 7 8 9 10 12 16 “For each action (acc=b:=f(c1,...,ck)) of n”
int var1 , x , y x := ( 3 + 4 ) * 5 “For i from 1 to k” AddEdge(new_edge(ci,b),gd);

85 86

Attribute Grammars Attribute Grammars


Introduction to the more general technique Examples: Conclusions
3. (cont.) It is very important to mention the possibility of having cycles in the • We can observe, that, depending on the semantic rules, the type of path along the
dependency graph. In this case, we shall say that the syntax-directed definition is tree can be very different.
circular. • Remember the order of appearance of the nodes in the tree using the different
• Circularity is a problem in the design of the grammar: some attributes methods that we have studied, both top-down and bottom-up.
depend on others, which themselves depend on the first ones. • The combination of the syntactic and the semantic analysis will be easier if we can
• They provoke a very small performance, so it is advisable to re-design the express the semantic information using a set of attributes and rules which is
grammar if it has this problem. compatible with the ordering in which the syntactic analyser builds the tree.
4. To establish a path along the tree that respects the previous ordering, and to apply
it. • The following are two possibilities:
• In the examples, the order marked in green would determine the path to follow. • Syntax-directed definitions with synthesised attributes.
5. The result of the evaluation of the semantic actions in the previous ordering will be • Syntax-directed definitions with left attributes.
the correct semantic analysis of the program.
• It is possible to check, in the examples, that the interpretation obtained is
correct.

87 88
Syntax-Directed Definitions with Synthesised Attributes Syntax-Directed Definitions with Left Attributes
Introduction and example Introduction
• These are compatible with bottom-up analysis: • Depth-first analysis:
• The utility of these kinds of definitions is their compatibility with the order in • Many techniques of syntactic analysis perform a depth-first analysis.
which the nodes are created, in the parse tree, in bottom-up analysis. • It has the following characteristics:
• The syntax-directed definitions with synthesised attributes: • The children of a node are visited from left to right.
• are those that do not use inherited attributes, i.e. all the attributes are calculated • When all the children of a node have been processed, the parent node is
for the parent nodes from their children. processed.
• Syntax-directed definitions with left attributes:
• Are compatible with depth-first analysis.
• The example of arithmetic expressions is an example of this kind of grammar. • We can consider them as the most general class of syntax-directed definitions.
• Remember that the evaluation ordering of the attributes is exactly the same as • They allow us to perform the semantic analyses before creating explicitly the
the order in which the rules are reduced in a bottom-up analyser. whole parse tree.
• They include all the definitions directed by LL(1) grammars.
• They can also be used with bottom-up parsers.

89 90

Syntax-Directed Definitions with Left Attributes Syntax-Directed Definitions with Left Attributes
Definition Observation: attributes synthesized from the left
• Syntax-directed definitions with left attributes: • Because syntax-directed definitions with left-attributes only establish conditions on
• They are syntax-directed definitions, which establish the following conditions for the inherited attributes, we can say that
the attributes inherited by a non-terminal symbol, Xj, at the right-hand side of a • Any syntax-directed definition with synthesised attributes is included in the set of
rule: definitions allowed here.
A→X1X2...Xn
• These attributes can only depend on:
• The attributes of the left siblings.
X1, X2,..., Xj-1
• The attributes of the parent node A

91 92
Attributes Propagation and Syntax Analysis Attributes Propagation and Syntax Analysis
Introduction With bottom-up analysis
• We have seen the most general method, which requires that we have the whole • As already mentioned, the semantic actions in grammars with synthesised attributes
parse tree already built before we attempt the semantic analysis. are compatible with bottom-up analysis.

• We are also interested in performing the semantic analysis at the same time as the • When a rule is reduced, we shall have to execute the semantic actions associated to
syntactic. that rule.

• The following are some possibilities.

93 94

Attributes Propagation and Bottom-Up Syntax Analysis Attributes Propagation and Bottom-Up Syntax Analysis
Example: evaluation of arithmetic expressions Generación de la representación sufija asociada al programa
• In this grammar, the only semantic value is v which represents the value of the expression: • Se puede comprobar que las nexts acciones semánticas
GE={{+,*,-,/,(,),c{v},i{v}}, {E{v}, T{v}, F{v}},
E→E+T
{
E→Ed+T {E.v=Ed.v+T.v}
E→E-T
E→Ed-T {E.v=Ed.v-T.v} E→T
E→T {E.v=T.v} T→T*F
T→Td*F {T.v=Td.v*F.v} T→T/F F.v=5
T→Td/F {T.v=Td.v/F.v}
T→F
T→F {T.v=F.v}
F→i {F.v=i.v} F→i
F→c {F.v=c.v} F→(E)
F→(E) {F.v=E.v} F→-F
F→-Fd {F.v=-Fd.v}
},}
• Imagine that, before this expression a*(b+c/a), we have the following code:
a:=5;
b:=3;
c:=10;
• We can evaluate the expression and calculate the correct value (25)by propagating the
attributes simultaneously with the parsing a*(b+c/a)

95 96
Attributes Propagation and Bottom-Up Syntax Analysis Attributes Propagation and Bottom-Up Syntax Analysis
Generación de la representación sufija asociada al programa Generación de la representación sufija asociada al programa
• Se puede comprobar que las nexts acciones semánticas • Se puede comprobar que las nexts acciones semánticas
E→E+T E→E+T
E→E-T E→E-T
E→T E→T
T→T*F T→T*F
T→T/F F.v=5 T→T/F F.v=5
T→F T→F
F→i F→i
F→(E) F→(E)
F→-F F→-F

F.v=3 F.v=3 F.v=10

97 98

Attributes Propagation and Bottom-Up Syntax Analysis Attributes Propagation and Bottom-Up Syntax Analysis
Generación de la representación sufija asociada al programa Generación de la representación sufija asociada al programa
• Se puede comprobar que las nexts acciones semánticas • Se puede comprobar que las nexts acciones semánticas
E→E+T E→E+T
E→E-T E→E-T
E→T E→T
T→T*F T→T*F
T→T/F F.v=5 T→T/F F.v=5
T→F T→F
F→i F→i T.v=2=(10/5)
F→(E) F→(E)
F.v=5 F.v=5
F→-F F→-F

F.v=3 F.v=10 F.v=3 F.v=10

99 100
Attributes Propagation and Bottom-Up Syntax Analysis Attributes Propagation and Bottom-Up Syntax Analysis
Generación de la representación sufija asociada al programa Generación de la representación sufija asociada al programa
• Se puede comprobar que las nexts acciones semánticas • Se puede comprobar que las nexts acciones semánticas
E→E+T E→E+T T.v=25=5*5
E→E-T E→E-T
E→T E→T
T→T*F T→T*F
T→T/F F.v=5 E.v=5=3+2 T→T/F F.v=5 E.v=5=3+2
T→F T→F
F→i T.v=2=(10/5) F→i T.v=2=(10/5)
F→(E) F→(E)
F.v=5 F.v=5
F→-F F→-F

F.v=3 F.v=10 F.v=3 F.v=10

101 102

Attributes Propagation and Bottom-Up Syntax Analysis Attributes Propagation and Bottom-Up Syntax Analysis
Generación de la representación sufija asociada al programa Extensions: propagating some inherited attributes
E.v=25
• Se puede comprobar que las nexts acciones semánticas • If we use a stack for the semantic values, or we store them in the stack used by the
E→E+T T.v=25=5*5 syntactic analyser, then, when we propagate an inherited value, we can have in the
E→E-T stack, below it, the values on which it depends.
E→T • In these cases, by accessing the stack, it will be possible to propagate inherited
values (e.g. sibling’s attributes).
T→T*F
T→T/F F.v=5 E.v=5=3+2 • Other possibility will be to modify the grammar, so this information will be synthesised
rather than inherited.
T→F
T.v=2=(10/5)
• The detailed description of these options is outside the scope of this course.
F→i
F→(E)
F.v=5
F→-F

F.v=3 F.v=10

103 104
Attributes Propagation and Bottom-Up Syntax Analysis Attributes Propagation and Bottom-Up Syntax Analysis
Extensions: actions between the symbols at the right-hand side Extensions: actions between the symbols at the right-hand side
• Grammar to assign expressions to identifiers, to calculate the value and check the types. • Grammar for conditional statements:
GA={{:=,+,c{v,t},i{v,t}}, {A{v,t}, E{v,t}, F{v}}, GA={{if, then, else}, {E, Instr},
{ {
A→i{“Check that i has been declared”} Instr→if E {Action2} then Instr {Action1}
:= <Exp> Instr→if E {Action2} then Instr else {Action3} Instr
{“Type compatibility: (i.t) and (E.t)”; {Action1}
i.v = E.v } },}
E→E’+T
{“Type compatibility: (E’.t) and (T.t)”;
E.t=type_sum(E’.t,T.t);(*)E.v=E’.v+T.v}
E→T {E.t=T.t; E.v=T.v}
T→i {“Check that i has been declared”;
T.t=i.t; T.v=i.v}
T→c {T.t=c.t; T.v=c.v}
},}

105 106

Attributes Propagation and Bottom-Up Syntax Analysis Attributes Propagation and Bottom-Up Syntax Analysis
Extensions: actions between the symbols at the right-hand side Extensions: actions between the symbols at the right-hand side
• In bottom-up analysers, the semantic actions are only executed when the rule is • The previous technique is used by some automatic generators of parsers.
reduced. • The designer of the grammar can use the same procedure.
• Therefore, the actions should all be at the end of the right-hand sides of the rules.
• A possibility is to add markers for semantic actions, which are symbols which just • In the second example:
generate the empty word, (M→λ) but that execute an action before disappearing.
• This technique is applied in the first example above, in the first rule. The actions that
are not problematic are abbreviated as {} )
GA={{if, then, else}, {E, E1, Else, Instr},
GA={{:=,+,c{v,t},i{v,t}}, {A{v,t}, E{v,t}, F{v}, M},
{
{
Instr→if E1 then Instr {Action1}
A→i M := <Exp> {}
Instr→if E1 then Instr Else Instr {Action1}
M→λ {“Check that the identifier was declared”}
E1→E {Action2}
E→E’+T {}
Else→else {Action3}
E→T {}
},}
T→i {}
T→c {}
},}

107 108
Attributes Propagation and Bottom-Up Syntax Analysis Attributes Propagation and Top-Down Syntax Analysis
Extensions: actions between the symbols at the right-hand side With top-down analysers
• It is easy to see that the new grammars are equivalent to the previous ones. • We have already mentioned that the semantic actions in left-attribute grammars
are compatible with LL(1) grammars.
• However, take care with this technique, because too many rules to the empty word • In the case of top-down analyses, it is not relevant the position of the semantic
may start provoking conflicts in the analysis matrix. actions in the right-hand sides of the rules.
• The semantic actions can be considered as additional symbols.

• If it is possible to transform a grammar into LL(1) form, together with the semantic
actions, then the generation of a syntax/semantic analyser is very easy.

• This lesson will show later a variation of the recursive top-down LL(1) analyser with
some semantic actions added.

109 110

You might also like