0% found this document useful (0 votes)
13 views48 pages

SDT 2025

The document discusses Syntax Directed Translation (SDT) and its role in semantic analysis, highlighting the limitations of context-free grammars (CFG) in representing certain language features. It explains the process of associating attributes with grammar symbols and the evaluation of semantic rules to generate code, perform semantic checks, and manage symbol tables. Additionally, it contrasts Syntax Directed Definitions (SDD) with SDT, detailing the concepts of synthesized and inherited attributes, and the evaluation strategies for implementing these definitions.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views48 pages

SDT 2025

The document discusses Syntax Directed Translation (SDT) and its role in semantic analysis, highlighting the limitations of context-free grammars (CFG) in representing certain language features. It explains the process of associating attributes with grammar symbols and the evaluation of semantic rules to generate code, perform semantic checks, and manage symbol tables. Additionally, it contrasts Syntax Directed Definitions (SDD) with SDT, detailing the concepts of synthesized and inherited attributes, and the evaluation strategies for implementing these definitions.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 48

22/04/25

Syntax Directed Translation

Beyond Syntax Analysis


— Syntax Analysis is not able to detect all kind of
program errors.
— Some features of language cannot be represented
using CFG
— Declaration of an identifier before its use.
— CFG cannot represent CSL and REL/RL like
— L= { anbmcndm | n,m >-1}

1
22/04/25

— Semantic Analysis computes additional information


related to the meaning of the program once the
syntactic structure is known.
— In typed languages as C, semantic analysis involves
adding information to the symbol table and
performing type checking.
— 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.

Syntax Directed Translation


— CFG + semantic rules à SDT
— computes additional information related to meaning of the program
once the syntactic structure is known.
E → E +T {print ’+’} // semantic action
F → id {print id.val}
— Process
— We associate Attributes to the grammar symbols representing the
language constructs.
— Values for attributes are computed by evaluating Semantic Rules
associated with grammar productions.
— Tasks accomplished by Evaluation of Semantic Rules–
— Generate Code;
— Print messages
— Insert information into the Symbol Table;
— Perform Semantic Check;
— Issue error messages;

2
22/04/25

Syntax directed translation


schemes
— An SDT is a Context Free grammar with program fragments
embedded within production bodies

— Those program fragments are called semantic actions

— They can appear at any position within production body

— 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

SDD vs SDT :- Two ways to add semantic actions


SDD-Syntax Directed Definitions SDT-Syntax Directed Translation
•Specifies the values of attributes by embeds program fragments (also called
associating semantic rules with the semantic actions) within production
productions. bodies.

easier to read can be more efficient

easy for specification. easy for implementation.

3
22/04/25

Syntax Directed Definitions


— Attributes are Portioned into 2 subsets
— Synthesized attributes
— Value of synthesized attribute at node N is defined only in terms of
attribute values of children of N and at N itself
Aà XY { A.s=X.s+ Y.s } à s in synthesized A
— useful in evaluating arithmetic expression like
a=x+y; X Y
— Inherited attributes
— Value of an inherited attribute at node N is defined only in terms of
attribute values at N’s parent, N itself and N’s siblings

AàXY { X.i =A.s} --à i is inherited attribute

Convenient for expressing dependence of programming language


construct eg int a,b,c;

An Example to illustrate working of SDD


SDD for desk calculator program
Production Semantic Rules
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

Val is integer value synthesized attribute associated with each non


terminal E, T and F.
Semantic rules for production for E, T and F compute value of attribute
val
Digit has synthesized attribute lexval
10

4
22/04/25

Synthesized Attributes

— SDD using synthesized attributes is known as S-attributed definition.


— Parse tree for S-attributed definition can be annotated by evaluating
semantic rules for attributes at each node bottom up from leaves to root

E T
T F

T F

Annotated parse tree for 3*5 + 4n

11

Another example
S->xxw { print(10)}
/y { print(20) }
W-> Sz { printf(30)

Input string is :- xxxxyzz

Steps:
1. Build a parse tree for the input string
2. Traverse the tree, wherever we find a reduction, fire
the semantic rule associated with grammar.

12

5
22/04/25

Evaluation by Bottom-Up parser

O/P: 20 30 10 30 10
13

Evaluation by Top-down parser

1. Build parse tree for the given input


2. Assume sematic rules as part of production and add it to the tree
3. Go for traversal and execute semantic action as and when encountered

14

6
22/04/25

— Question: Try to change SDT and see How can you


print the post order traversal of input string it??
input :- 2+3 * 4
— 3-4 minutes:--

https://gateoverflow.in/270377/compiler-sdt-top-down-parsing

15

— Inherited Attributes
— Value at node in parse tree is defined in terms of attributes
at parent and/or siblings of that node.
— Convenient for expressing dependence of programming
language construct
AàXY { X.i =A.s, à i is inherited attribute ?? Why
X.inh = Y.in} à inh is inherited attribute?? Why
— Evaluation order:- cannot be evaluated by simple traversal
— Order of computation of inherited attributes of children are
important.
— Inherited attributes of children can depend from both left and right
siblings.
— Evaluated in depth first left to right manner( like preporder)

16

7
22/04/25

Inherited Attributes: Another Example

The following syntax-directed definition generates binary strings where (one of) the attributes gives
the number represented by the string. The non-terminals are B and D, the terminals are 0 and 1. The
symbol B stands for binary expansion and the symbol D stands for digit.

Find synthesized and inherited attributes?


17

Inherited Attributes: An Example


Example. Let us consider the syntax directed definition with both inherited
and synthesized attributes for the grammar for “type declarations”:

The non terminal T has a synthesized attribute, type, determined by the


tokens int/real in the corresponding production.
• The production D -> TL is associated with the semantic rule L.in := T.type
which set the inherited attribute L.in.
• Note: The production Là L1, id distinguishes the two occurrences of L.

18

8
22/04/25

Inherited Attributes: An Example (Cont.)


Synthesized attributes can be evaluated by a PostOrder traversal.
• Inherited attributes that do not depend from right children can be evaluated by a
depth first left-right/ PreOrder traversal.
• The annotated parse-tree for the input real id1, id2, id3 is:

T L

L1 , id3

L.in is then inherited top-down the tree by the other L-nodes.


• At each L-node the procedure addtype inserts into the symbol table the type of
the identifier.

19

Synthesized and inherited attributes properties


• Attribute Types: An individual attribute of a symbol cannot be both
synthesized and inherited. However, a single symbol in a grammar can have
some attributes that are synthesized and others that are inherited.
Evaluation: Attributes of symbols are evaluated by making passes over the
parse tree.
• Synthesized Attributes: They are computed in a bottom-up fashion,
starting from the leaf nodes and moving upwards towards the root of the
parse tree.
• The value of a synthesized attribute at a node is always determined by the
attribute values of its children.
• Leaf nodes (terminals) have synthesized attributes that are initialized by the
lexical analyzer, and these values cannot be modified later.
• Inherited Attributes: They flow down the parse tree, either from a parent
node to its children or between sibling nodes.
• The value of an inherited attribute at a node is determined by the attribute
values of its parent or its siblings.

20

9
22/04/25

Implementing Syntax Directed Definitions


Implementing a Syntax Directed Definition consists primarily in finding an order
for the evaluation of attributes
- Each attribute value must be available when a computation is performed.
- We impose certain restrictions on rules like don’t go too deep into tree,
localize the evaluations etc.

• Dependency Graphs are the most general technique used to evaluate syntax
directed definitions with both synthesized and inherited attributes.

• A Dependency Graph shows the interdependencies among the attributes of the


various nodes of a parse-tree.
– There is a node for each attribute;
– If attribute b depends on an attribute c there is a link from the node for c to
the node for b (b ß c).
• Dependency Rule: If an attribute b depends from an attribute c, then we
need to fire the semantic rule for c first and then the semantic rule for b.

21

Evaluation orders for SDD’s


— A dependency graph is used to determine the order of
computation of attributes
— Dependency graph
1. For each parse tree node, the parse tree has a node for
each attribute associated with that node
2. 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
3. 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.a to B.c
— Example!

22

10
22/04/25

Dependency graph
1. Create 3 nodes
2. Add edges from E1.val to
E.val and
3. From E2.val towards E.val

23

Evaluation Order
• The evaluation order of semantic rules depends from a Topological
Sort derived from the dependency graph.
• Topological Sort: Any ordering m1,m2, . . . ,mk such that if mi à mj is
a link in the dependency graph then mi < mj.
• Any topological sort of a dependency graph gives a valid order to
evaluate the semantic rules.

•The graph shown to the left has many valid topological sorts,
including:5, 7, 3, 11, 8, 2, 9, 10 (visual left-to-right, top-to-bottom)
•3, 5, 7, 8, 11, 2, 9, 10 (smallest-numbered available vertex first)
•5, 7, 3, 8, 11, 10, 9, 2 (fewest edges first)
•7, 5, 11, 3, 10, 8, 9, 2 (largest-numbered available vertex first)
•5, 7, 11, 2, 3, 8, 9, 10 (attempting top-to-bottom, left-to-right)
•3, 7, 8, 5, 11, 10, 2, 9 (arbitrary)

24

11
22/04/25

•Nodes in dependency graph are numbered


•There is edge to node 5 for L.in from node 4 for T.Type because of semantic rule
L.in := T.Type for production D-> TL
• Downward arrows into nodes 7 and 9 because of rule L1.in =L.in for production
L -> L1,id
•Rule addtype(id.entry,L.in) leads to creation of dummy attributes. (nodes 6,8,10)

25

Attribute Evaluation Strategy


— Construct the parse tree
— Construct the dependency graph
— Perform topological sort on the dependence graph and
obtain an evaluation order.
— Evaluate attributes according to this order using the
corresponding attribute evaluation rules attached to
respective productions.
— Multiple attributes at a node in the parse tree may result
in that node to be visited multiple number of times
— Each visit resulting in the evaluation of at least one
attribute.

26

12
22/04/25

Attribute Evaluation Algorithm

27

Implementing Attribute Evaluation:


General Remarks
• Attributes can be evaluated by building a dependency graph at
compile-time and then finding a topological sort.
• Disadvantages:-
1. This method fails if the dependency graph has a cycle: We need a test
for non-circularity;
2. This method is time consuming due to the construction of the
dependency graph.

• Alternative Approach.
Design the syntax directed definition in such a way that attributes can be
evaluated with a fixed order avoiding to build the dependency graph
(method followed by many compilers).

36

13
22/04/25

Strongly Non-Circular Syntax Directed


Definitions

• Strongly Non-Circular Syntax Directed Definitions. Formalisms


for which an attribute evaluation order can be fixed at compiler
construction time.

– They form a class that is less general than the class of non-circular
definitions.

– In the following we illustrate two kinds of strictly non-circular


definitions:

S-Attributed and L-Attributed Definitions.

37

S-Attributed definitions
— An SDD is S-attributed if every attribute is synthesized
— We can have a bottom –up/ post-order traversal of
parse-tree to evaluate attributes in S-attributed
definitions
A -> XYZ {A.S = X.S + Y.S}

postorder(N) {
for (each child C of N, from the left) postorder(C);
evaluate the attributes associated with node N;
}
— Semantic actions are Placed in RHS

38

14
22/04/25

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.
— More precisely, each attribute must be either
— Synthesized
— Inherited, but 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:
— Inherited attributes associated with the head A

— Either inherited or synthesized attributes associated with the occurrences of


symbols X1,X2,…,Xi-1 located to the left of Xi
Xi.i = X1.s+ X2.s+……..Xi-1.s
— Inherited or synthesized attributes associated with this occurrence of Xi itself,
but in such a way that there is no cycle in the graph
— Semantic actions are placed anywhere in RHS.
A → {Action1} B {Action2} C {Action3}
Action1: takes place before parsing of the input corresponding to the non-terminal B.
Action2: takes place after consuming the input for B, but before consuming the input for C.
Action3: takes place at the time of reduction of BC to A or after consuming the input corresponding to BC.
— evaluated by depth-first and left-to-right parsing manner.

39

Example
1. Find whether it is s/l attributed?

A -> XYZ {Y.S = A.I, Y.S = X.S, Y.S = Z.S}


not an L-attributed grammar since
Y.S = A.I and Y.S = X.S are allowed but
Y.S = Z.S violates the L-attributed SDT definition as attributed is inheriting the
value from its right sibling.

Example 2.
P1: S -> MN {S.val= M.val + N.val}
P2: M -> PQ {M.val = P.val * Q.val and P.val =Q.val}

Select the correct option.


A. Both P1 and P2 are S attributed.
B. P1 is S attributed and P2 is L-attributed.
The correct answer is option C as,
C. P1 is L attributed but P2 is not L-attributed. In P1, S is a synthesized attribute and in L-attribute definition
D. None of the above synthesized is allowed.
So P1 follows the L-attributed definition. But P2 doesn’t follow L-
attributed definition as P is depending on Q which is RHS to it.

40

15
22/04/25

Translation schemes
Translation Schemes are more implementation oriented than syntax directed
definitions since they indicate the order in which semantic rules and attributes are to
be evaluated.

We concentrate on s attributed grammars and 1-pass L-attributed grammars in which


attribute evaluation can be combined with LR, LL or recursive descent parsers.

implemen Synthesized Inherited


tation
Bottom up Cannot do it easily
parser While parsing in Procedure:-
bottom up manner - Convert l-attributed ( inherited) to s-attributed
- Introduce new non-terminal and move all rules to the
(1) right.
- Adding non-terminal will allocate space on value stack.
(4)
Top Down Why? Left recursion
parser Remove left recursion; Procedure:-
Convert s-attributed USE L-ATTRIBUTED DEFINITIONS AND
definition to l-attributed PLACE RULES IN PRODUCTION (2)
definition. (3)

41

1 B.U. evaluation of S-Attributed definitions

• Synthesized Attributes can be evaluated by a bottom-up parser as


the input is being analyzed avoiding the construction of a dependency
graph.

• The parser keeps the values of the synthesized attributes in its stack.
• Whenever a reduction A -> α is made, the attribute for A is computed
from the attributes of α which appear on the stack.

• Thus, a translator for an S-Attributed Definition can be simply


implemented by extending the stack of an LR-Parser.

42

16
22/04/25

Extending a Parser Stack


Extra fields are added to the stack to hold the values of synthesized
attributes.
• In the simple case of just one attribute per grammar symbol the stack
has two fields: state and val
• The current top of the stack is indicated by the
pointer top.
• During shift action both token and its value is
pushed on stack
• Synthesized attributes are computed just before
each reduction:
– Before the reduction A -> XYZ is made, the attribute
for A is computed: Before reduction :-
A.a := f (val[top], val[top − 1], val[top − 2]). Ntop= top-r+1. ( r=3)
= 3-3+1 =1
After reduction
Top=ntop

43

Extending a Parser Stack: Example


5 Top

- Top-1

3 Top-2

Print( E.val)

E.val = E1.val + T.val

E.val = T.val

T.val = T1.val * F.val

T.val = F.val

F.val = E.val

F.val = digit.lexval

Before reduction :-
Ntop= top-r+1. ( r=3)
= 3-3+1 = =1
After reduction
Top=ntop

44

17
22/04/25

Reduction at T*F
Rule is
Value[ntop]=val[top]*val[top-2]

Also r=3
Ntop= top-r+1
= 3-3+1
=1

45

(2) Top down parser and l-attribute evaluation


— Aà XYZ
X.i = f( A, Y,Z) but Y and Z will not be available since we are still expanding A.
— We therefore limit our inherited attribute to use left part of the production,
that helps to evaluate all attributes and dependence graph will not be
violated.
— i.e. X.i = f( A.i, X1……Xi-1)

PROCESS
— Semantic Actions are treated as terminal symbols: Annotated parse-trees contain
semantic actions as children of the node standing for the corresponding
production.
— Semantic Actions are enclosed between braces {} and are inserted within the
right-hand side of productions.
— Translation Schemes are useful to evaluate L-Attributed definitions at
parsing time (even if they are a general mechanism).

46

18
22/04/25

Design of Translation Schemes


• When designing a Translation Scheme we must be sure that an attribute value is available
when a semantic action is executed.
o When the semantic action involves only synthesized attributes: The action can
be put at the end of the production. As all attributed will be computed at this time
Example. The following Production and Semantic Rule:
T -> T1 * F T.val := T1.val * F.val
yield the translation scheme:
T -> T1 * F {T.val := T1.val * F.val}

Rules for Implementing L-Attributed SDD’s.


If we have an L-Attributed Syntax-Directed Definition we must enforce the following
restrictions:
1. An inherited attribute for a symbol in the right-hand side of a production must be computed
in an action before the symbol; i.e to the left of the Non terminal

2. A synthesized attribute for the non terminal on the left-hand side can only be computed when
all the attributes it references have been computed: The action is usually put at the end of the
production.

47

Translation Schemes
A Semantic definition scheme to map infix to postfix

E -à T R
R -à addop T R { print (addop) }. | epsilon.
T à num. { print (num) }

A CFG where actions occur within the rhs of production

A Translation scheme to map infix to postfix


E -à T R
R -à addop T { print (addop) }. R | epsilon
T à num. { print (num) }

Parse tree for 9. - 5. + 2

48

19
22/04/25

- Assume actions are terminal symbols


- Perform depth first traversal to obtain 9 5 – 2 +
- When designing translation scheme , ensure attribute value is avalialbel
when referred to
49

50

20
22/04/25

51

Translation Schemes: An Example (both


synthesized and inherited attributes)
• Consider the Translation Scheme for the L-Attributed Definition
for “type declarations”: ( Design appropriate Translation
scheme)

D ->T {L.in := T.type} L

T -> int {T.type :=integer}

T -> real {T.type :=real}

L -> {L1.in := L.in} L1, id {addtype(id.entry, L.in)}

L -> id {addtype(id.entry, L.in)}


52

21
22/04/25

Traversing the Parse Tree in depth-first order, we can evaluate the


attributes

53

2 problems solved
impleme Synthesized Inherited
ntation
Bottom up While parsing in Cannot do it easily
parser bottom up manner Procedure:-
- Convert l-attributed ( inherited) to s-attributed
(1) - Introduce new non-terminal and move all rules to
the right.
- Adding non-terminal will allocate space on value
stack. (4)
Top Down Why? Left recursion Procedure:-
parser Remove left recursion; USE L-ATTRIBUTED DEFINITIONS AND PLACE
Convert s-attributed RULES IN PRODUCTION
definition to l-
attributed definition (2)
(3)

54

22
22/04/25

(3) Top down translation of synthesized


attributes

— Problem:-
— Left recursion???
— Left part of tree will be built before right parse tree
— Evaluate all attributes on the left side of the tree and take
them to RHS
— General rule
— Remove Left Recursion
— Convert s-attribute rules to l-attributes since they evaluate
from left hand side.

55

Top Down Translation


Use Predictive parsing to implement L-attributed definitions
Eà E1 + T E.val := E1.val + T.val
Eà E1 - T E.val := E1.val T.val
EàT E.val =T.val
Tà (E ) T.val = E.val
T -à num T.val = num.lexval

Eliminate left recursion


E àT R
R à. + T R
Rà -TR
R à epsilon
T à ( E)
T à num
56

23
22/04/25

Parse trees for both Grammars


i/p: - 9 – 5 + 2

57

9–5+2

58

24
22/04/25

59

60

25
22/04/25

61

General Algorithm

62

26
22/04/25

3 problems solved
impleme Synthesized Inherited
ntation
Bottom up While parsing in Cannot do it easily
parser bottom up manner Procedure:-
- Convert l-attributed ( inherited) to s-attributed
(1) - Introduce new non-terminal and move all rules to
the right.
- Adding non-terminal will allocate space on value
stack. (4)
Top Down Why? Left recursion Procedure:-
parser Remove left recursion; USE L-ATTRIBUTED DEFINITIONS AND PLACE
Convert s-attributed RULES IN PRODUCTION
definition to l-
attributed definition (2)
(3)

63

4. Bottom-up evaluation of inherited


attributes
— Supposing we want to implement bottom up parsers for the
computation of inherited attributes
— Main Idea. Starting from a Translation Scheme (with
embedded actions) we introduce a transformation that
makes all the actions occur at the right ends of their
productions. i.e. convert l-attributed definitions to
synthesized attribute
— For each embedded semantic action we introduce a new
Marker (i.e., a non terminal, say M) with an empty
production (M -> ⍷);
— The semantic action is attached at the end of the production
M -> ⍷

64

27
22/04/25

-This example has no attribute that need to be evaluated


-We need to do more as attributes can be associated to this new non-
terminal rules
65

66

28
22/04/25

67

68

29
22/04/25

69

D ->T {L.in := T.type} L


T -> int {T.type :=integer}
T -> real {T.type :=real}
L -> {L1.in := L.in} L1, id {addtype(id.entry, L.in)}
L -> id {addtype(id.entry, L.in)}

The scheme works only if grammar allows position of attributes to be


predicted
70

30
22/04/25

— The scheme works only if grammar allows position of attributes


Markers make to be predicted
sure value
— Check the grammar below:- of A is immediately below
Stack1 Stack 2
C i.e predetermined
S à aAC {C.i = f(A.s) } location x C
x C Sà bA B C { C.i=f(A.s} B
A Càx { C.s= g(C.i)} A
a b
While reducing, by C->x on stack…we don’t know where is A at top-1 or top-2
Insert a marker M just before C in the second rule Stack-M
S à aAC {C.i = (A.s) } Stack1 x C
Sà bA B M C { M.i= A.s; C.i=M.s} A.s M
Càx { C.s= g(C.i)} x C B
M-> epsilon { M.s= M.i} A.s A A
a b

When production Mà epsilon is applied we have


M.s= M.i = A.s
Therefore value of C.i is always at top-1
71

72

31
22/04/25

Markers can also be used to simulate rules what are not copy rules

Stack1 Value

M1 -->E M1
Top. --> A A
a a

73

markers hold inherited attributes and grammar contain synthesized


attributes Eg M1 contains X1.i

74

32
22/04/25

2 cases:
1.Reduce by M
2.Reduce by non-Marker symbol:
1.We have to compute A.s note that
A.i is already computed and lives at position on stack just below
the position into which we insert A itself.

For eg:
- Compute inherited attribute associated with
X3.i. ( j=3)
- This shall be in M3
- Therefore it shall be calculated when M-
epsilon is reduced and M is pushed
- Refer to the drawn figure
75

Application of Syntax Directed Translation


— Type checking and intermediate code generation
(chapter 6)
— Construction of syntax trees
— Leaf nodes: Leaf(op,val)
— Interior node: Node(op,c1,c2,…,ck)
— Example:

Production Semantic Rules


1) E -> E1 + T E.node=new node(‘+’, E1.node,T.node)
2) E -> E1 - T E.node=new node(‘-’, E1.node,T.node)
3) E -> T E.node = T.node
4) T -> (E) T.node = E.node
5) T -> id T.node = new Leaf(id,id.entry)
6) T -> num T.node = new Leaf(num,num.val)
76

33
22/04/25

Syntax tree for L-attributed definition

Production Semantic Rules


1) E -> TE’ E.node=E’.syn
E’.inh=T.node
2) E’ -> + TE1’ E1’.inh=new node(‘+’, E’.inh,T.node)
E’.syn=E1’.syn
3) E’ -> -TE1’
E1’.inh=new node(‘+’, E’.inh,T.node)
4) E’ -> Î E’.syn=E1’.syn
E’.syn = E’.inh
5) T -> (E)
T.node = E.node
6) T -> id
7) T -> num T.node=new Leaf(id,id.entry)
T.node = new Leaf(num,num.val)

77

Intermediate code generation


— Intermediate code is the interface between front end
and back end in a compiler
— Ideally the details of source language are confined to
the front end and the details of target machines to the
back end (a m*n model)

Static Intermediate Code


Parser
Checker Code Generator Generator
Front end Back end
78

34
22/04/25

Graphical Representation of IC: Syntax Trees


— Abstract syntax tree is condensed form of parse tree
useful for representing language constructs.

Production and corresponding syntax tree

Syntax tree for previous parse tree


-Has less number of nodes

79

Construction of Syntax Trees


— Similar to translation of expression into postfix form.
— Construct subtrees for sub-expressions by creating node for
each operator and operand.
— Children of an operator node are roots of nodes representing
sub-expressions constituting operands of that operator.
— Each node has multiple fields with one field identifying
operator and remaining contain pointers to nodes for
operands.
— Following functions are used

80

35
22/04/25

Syntax tree

Syntax tree for a-4+c

Following sequence of function calls will make the syntax tree

81

Example

Parse tree shown in


dotted
100 200

800
300
Syntax tree for
a-4+c 100
200

82

36
22/04/25

Variants of syntax trees


— It is sometimes beneficial to crate a DAG instead of
tree for Expressions.
— This way we can easily show the common sub-
expressions and then use that knowledge during code
generation
— Example: a+a*(b-c)+(b-c)*d

+ *

*
d
a -

b c

83

Directed Acyclic Graph (DAG) for expressions


— Identifies common subexpressins in expression.
— Has node for every sub-expression of expression
— Interior node represnets an operator and its children
represent its operands.
— Node in DAG representing common sub-expression
has more than one “parent”; where as in syntax tree,
common sub-expression would be represented as
duplicate sub-tree
For expression
a + a * (b-c) + (b – c) * d

84

37
22/04/25

SDT for construction of dag


-Similar to constructing syntax tree with minor difference
-DAG is obtained if function for constructing node shall check whether identical
node exists
Eg mknode( op, left, right) will check for node labeled op and if it exists it will
return pointer to previously constructed node.
i/p:- a + a * (b-c) + (b – c) * d

85

Value-number method for constructing DAG’s

To entry for i

i 10

-nodes are implemented as records stored in an array, as in Fig. above,


-In the figure, each record has a label field that determines the nature of
node.
-refer to a node by its index or position in the array
-The integer index of a node is often called a value number for historical
reasons. For example, using value numbers, we can say node 3 has Label
+, its left child is node 1 , and its right child is node 2,

86

38
22/04/25

Value-number method for constructing a


node in a dag
— Algorithm
— Search the array for a node M with label op, left child l
and right child r
— If there is such a node, return the value number M
— If not create in the array a new node N with label op, left
child l, and right child r and return its value
— An obvious way to determine if node m is already in
the array is to keep all previously created nodes on a
list and to check each node on the list to see if it has
the desired signature.
— We may use a hash table

87

Three address code


— Sequence of statement of general form A := B op C where A,B, C are
compiler defined variables or programmer defined names, op is operator.
— In a three address code there is at most one operator at the right side of an
instruction

— Example:

+
t1 = b – c
+ * t2 = a * t1
t3 = a + t2
* t4 = t1 * d
d
t5 = t3 + t4
a -

b c

88

39
22/04/25

— A Three address statement like A:= B op C puts B in ARG1,C


in ARG2 and A in result.
— Statement with unary operator are assumed not to use
ARG2
— Three Address Code for statement A := -B*(C+D)

— T1 := -B
— T2 := C + D
— T3 := T1*T2
— A :=T3

89

Forms of three address instructions


— x = y op z
— x = op y
— x=y
— goto L
— if x goto L and if False x goto L
— if x relop y goto L
— Procedure calls using:
— param x
— call p,n
— y = call p,n
— x = y[i] and x[i] = y
— x = &y and x = *y and *x =y

90

40
22/04/25

Example
— do i = i+1; while (a[i] < v);

L: t1 = i + 1 100: t1 = i + 1
i = t1 101: i = t1
t2 = i * 8 102: t2 = i * 8
t3 = a[t2] 103: t3 = a[t2]
if t3 < v goto L 104: if t3 < v goto 100

Symbolic labels Position numbers

91

goto

92

41
22/04/25

— Implementation of Three Address Code


— Three address code is though to be an abstract specification
which can be implemented by number of ways by different
compilers.
— Quadruples
— Record structure with four fields, OP, ARG1, ARG2, RESULT.
— OP contains internal code for operators.
— Quadruples for statement A := -B*(C+D)
OP ARG1 ARG2 RESULT
(0) UMINUS B - T1 T1 := -B
T2 := C + D
(1) + C D T2
T3 := T1*T2
(2) * T1 T2 T3 A :=T3
(3) := T3 - A

— Contents of fields ARG1, ARG2 and RESULT can be


temporary names or pointers to symbol table entries for
names represented by these fields.

93

— Triples
— To avoid entering temporary names into symbol table, we
allow a statement computing temporary value to represent
that value.
— A structure of this sort with only three fields OP, ARG1 and
ARG2 where ARG1 and ARG2, the arguments of OP are
either pointers to symbol table or pointers to structure
itself.

OP ARG1 ARG2
(0) UMINUS B -
(1) + C D
(2) * (0) (1)
(3) := A (2)

94

42
22/04/25

— Indirect Triples
— Listing pointers to triples rather than listing triples
themselves

STATEMENT
(0) (14)
(1) (15) OP ARG1 ARG2
(2) (16)
(14) UMINUS B -
(3) (17)
(15) + C D
(16) * (14) (15)
(17) := A (16)

95

Comparison of representations
— Using Quadruple:
— On producing object code, each datum, temporary will be assigned memory
— Quadruples tend to clutter up symbol table with temp names.
— Quadruples make location for each temporary that can be immediately accessed via
symbol table
— In case of triples we have no idea unless we scan code, how many temporaries
are active simultaneously, or how many words must be allocated for
temporaries, therefore assignment of locations to temporaries is deferred to
code generation.
— Code motion: in quadruples, if we move statement computing A, statement
using A require no change ( used in optimization)
— In triples moving statement that defines temporary value requires to change
all pointers to that statement in ARG1 and Arg2 arrays.
— No problem in indirect triples, move statement requires reordering of
STATEMENT list. Can also save space as compared to quadruples if same temp
is used more than once.

96

43
22/04/25

SDT to generate 3-address code


— S->id=E { gen(id.name=E.place);}
E:->E1+T { E.place=newTemp;
gen(E.place=E1.place+T.place)}
/T { E.place=T.place}
T-> T1*F {T.place=newTemp;
gen(T.place=T1.place*F.place);}
/F { T.place=F.place}
F->id { F.place=id.name;}

— Input is x=a+b*c
O/P:- t1=b*c
t2=a+t1
x=t2

97

— S->id=E { gen(id.name=E.place);}
E:->E1+T { E.place=newTemp;
gen(E.place=E1.place+T.place)}
/T { E.place=T.place}
T-> T1*F {T.place=newTemp;
gen(T.place=T1.place*F.place);}
/F { T.place=F.place}
F->id { F.place=id.name;}

S Input is x=a+b*c

O/P:- t1=b*c
id = E t2=a+t1
x=t2

E + T

T T * F
F F
id

id id

98

44
22/04/25

Type Checking
— Problem: Verify that a type of a construct matches
that expected by its context.
— Examples:
— mod requires integer operands (PASCAL)
— (dereferencing) – applied to a pointer
— a[i] – indexing applied to an array
— f(a1, a2, …, an) – function applied to correct
arguments
— Information gathered by a type checker:
— Needed during code generation.

99

Type Systems
A collection of rules for assigning type
expressions to the various parts of a program.
— Based on: Syntactic constructs, notion of a
type.
— Example: If both operators of “+”, “-”, “*” are
of type integer then so is the result.
— Type Checker: An implementation of a type
system.
n Syntax Directed.

— Sound Type System: eliminates the need for


checking type errors during run time.

100

45
22/04/25

101

102

46
22/04/25

Type Checking
— - Carried out in sematic phase
- Type checking information added with sematic rules
- Basic type checking is performed
- Extended to type checking of complex attributes

E à literal {E.type= char}


E à num {E.type= integer }
E à id {E.type= lookup(id.entry) }
E-> E1 mod E2 { if ((E1.type== integer ) && (E2.type == integer))
then E.type=int
else error }

103

SDT for type checking


E-> E1 + E2 { if ((E1.type==E2.type) && (E1.type == int))
then E.type=int
else error }

/ E1==E2 {
{ if ((E1.type==E2.type) && (E1.type == int/boolean))
then E.type=boolean
else error }}

/ (E1) { E.type = E1.type}


/ num { E.type =int}
/True { E.type =boolean
/False { E.type =boolean

Find the o/p when u process the


input :- (4+20) = =8

104

47
22/04/25

105

106

48

You might also like