0% found this document useful (0 votes)
36 views54 pages

CH3-1 and CH3-2

compiler design note

Uploaded by

kidanewoldhailu1
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)
36 views54 pages

CH3-1 and CH3-2

compiler design note

Uploaded by

kidanewoldhailu1
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/ 54

Syntax-Directed Translation

1
Introduction
 Attaching attributes to the variables of the context Free Grammar and defining semantic
action (meaning) of each production of grammar is called Syntax Directed Translation.

 Every non-terminal can get one or more than one attribute or sometimes 0 attribute
depending on the type of the attribute. The value of these attributes is evaluated by the
semantic rules associated with the production rule.

 In the semantic rule, attribute is VAL and an attribute may hold anything like a string, a
number, a memory location and a complex record.

 In Syntax directed translation, whenever a construct encounters in the programming


language then it is translated according to the semantic rules define in that particular
programming language.

2
Introduction
 E→E+T E.val := E.val + T.val, E.val is one of the attributes of E.

 We associate information with the programing language constructs by


attaching attributes to grammar symbols.

 Values of these attributes are evaluated by the semantic rules associated


with the production rules. So we can say that

Grammar + semantic rule = SDT (syntax directed translation)

3
Introduction
 Evaluation of these semantic rules:

 May generate Intermediate codes

 May put information into the Symbol table

 May perform type checking

 May issue error messages

 May perform some other activities.

 When we associate semantic rules with productions, we use two notations:

 Syntax-Directed Definitions (SDD)

 Translation Schemes (SDTS)

4
Introduction
 Syntax Directed Definitions
 Give high-level specifications for translations
 Hide many implementation details such as order of evaluation of semantic
actions.
 We associate a production rule with a set of sematic actions, and we do not
say when they will be evaluated.

 Translation Schemes
 Indicate the order of evaluation of semantic actions associated with a
production rule.
 In other words, translation schemes give a little bit information about
implementation details.

5
Introduction

 Conceptually with both the syntax directed definition


and translation scheme we
 Parse the input token stream
 Build the parse tree
 Traverse the tree to evaluate the semantic rules at the parse tree
nodes.
Input string → Parse Tree → Dependency graph → evaluation order
for semantic rules.
Conceptual view of syntax directed translation.

6
Syntax Directed Definition
 A SDD is a context free grammar with attributes and rules.
 Attributes are associated with grammar symbols and rules with productions.
 Attributes may be of many kinds: numbers, types, table references, strings, etc.

Synthesized attributes
 A synthesized attribute at node N is computed from the values of attributes at
the children in that node of the parse tree.
 A Synthesized attribute is an attribute of the non-terminal on the left-hand side
of a production.
Eg. let’s say A -> BC is a production of a grammar, and A’s attribute is dependent
on B’s attributes or C’s attributes then it will be synthesized attribute.

7
Syntax Directed Definition
Inherited attributes

 An inherited attribute at node N is defined only in terms of attribute values at N’s


parent, N itself and N’s siblings.

 An attribute of a nonterminal on the right-hand side of a production is called an


inherited attribute.

Eg. let’s say A -> BC is a production of a grammar and B’s attribute is dependent on
A’s attributes or C’s attributes then it will be inherited attribute.

Production semantic rules

E->E1+T E.code=E1.code||T.code||’+’

8
Syntax Directed Definition
 In a syntax-directed definition, each production A→ is associated
with a set of semantic rules of the form:

 b= f(c1,c2,…,cn) where f is a function and b can be on of the


followings.

 b is a Synthesized attribute of A and c1,c2,…,cn are attributes of the


grammar symbols in the production (A→). OR

 b is an Inherited attribute one of the grammar symbols in (on the


right side of the production), and c1,c2,…,cn are attributes of the
grammar symbols in the production(A→).

9
Syntax Directed Definition
 Syntax directed definition specifies the values of attributes by
associating semantic rules with the grammar productions.

 It is a CFG with attributes and rules together which are associated with
grammar symbols and productions respectively.

 The process of SDT is two-fold:


 Construction of syntax tree and
 Computing values of attributes at each node by visiting the nodes of syntax
tree.

10
Types of translation
 L-attributed translation
 It performs translation during parsing itself.
 No need of explicit tree construction.
 Semantic actions are placed anywhere in RHS.
 Uses both synthesized attributes and inherited attributes with a
restriction that inherited attribute can inherit values from left
siblings only,
 Attributes in L-attributed SDTs are evaluated by depth-first
traversal and left-to-right parsing manner.
11
Types of translation
 S-attributed translation
 ‘S’ represents synthesized.
 If an SDT uses only synthesized attributes, it is called as S-
attributed SDT.
 S-attributed SDTs are evaluated in bottom-up parsing, as the
values of the parent nodes depend upon the values of the
child nodes.
 Semantic actions are placed in rightmost place of RHS

12
Types of translation
L-attributed definition S-attributed definition

Uses synthesized & inherited


Uses synthesized attribute only.
attributes.

Semantic rule may be present in the Semantic rule is present at the right
middle also. end.
A → α {rule} β / A → {rule} α β A → α {rule}

Rules are evaluated in DFS from left Semantic rules are evaluated in
to right. (top down). bottom-up manner.

13
Types of translation
Note: Every S - attributed definition is L - attributed
definition but every L - attribute need not be S - attribute.

14
Evaluation Orders for SDD’s
 Dependency Graphs

 Ordering the Evaluation of Attributes

 S-Attributed Definitions

 L-Attributed Definitions

 Semantic Rules with Controlled Side Effects

15
Dependency graph
 While an annotated parse tree shows the values of attributes, a dependency graph helps
us determine how those values can be computed.

 A dependency graph depicts the flow of information among the attribute instances in a
particular parse tree.

 A dependency graph is used to determine the order of computation of attributes.

 It provides information about the order of evaluation of attributes with the help of
edges.

 An edge from the first node attribute to the second node attribute gives the information
that first node attribute evaluation is required for the evaluation of the second node
attribute.

16
Dependency graph
 Edges represent the semantic rules of the corresponding production.

 For each parse tree node, the parse tree has a node for each attribute
associated with that node

 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.

 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
17
Dependency Graph

1) L -> E
2) E -> E + T
3) E -> T
4) T -> T * F
5) T -> F
6) F -> (E)
7) F -> digit

18
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

 The attribute of the second node is dependent on the attribute of the


first node for further evaluation. This order of evaluation gives a linear
order called topological order.

 If there is any cycle in the graph, then there are no topological sorts;
that is, there is no way to evaluate the SDD on this parse tree.

19
S-Attributed Definitions
 When an SDD is S-attributed, we can evaluate its attributes in any
Bottom-up order of the nodes of the parse tree.

 It is simple to evaluate the attributes by performing a post-order


traversal of the parse tree and evaluating the attributes at a node N
when the traversal leaves N for the last time.

 S-attributed definitions can be implemented during bottom-up


parsing, since a bottom-up parse corresponds to a post order traversal.

 Specifically, post order corresponds exactly to the order in which an


LR parser reduces a production body to its head

20
Example of S-attributed SDD

Production Semantic Rules


1) L -> E n L.val = 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
1. Symbol E,T and F are associated with a synthesized attribute val.

2. The token digit has a synthesized attribute lexval(it is assumed that it is evaluated by the lexical
analyzer).

3. Terminals are assumed to have synthesized attributes only. Values for attributes of terminals are
usually supplied by the lexical analyzer.

4. The start symbol does not have any inherited attribute unless otherwise stated.

21
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
 Inherited or synthesized attributes associated with this occurrence of Xi itself, but in such a way
that there is no cycle in the graph

22
Example of L-attributed
Definition
➢ 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.(inherited)

23
Semantic Rules with
Controlled Side Effects
➢ With SDD's, we strike a balance between attribute grammars and translation schemes.

➢ Attribute grammars have no side effects and allow any evaluation order consistent with the
dependency graph.

➢ Translation schemes impose left-to-right evaluation and allow semantic actions to contain any
program fragment;

➢ We shall control side effects in SDD's in one of the following ways:


➢ Permit incidental side effects that do not constrain attribute evaluation. In other words, permit
side effects when attribute evaluation based on any topological sort of the dependency graph
produces a "correct" translation, where "correct" depends on the application.
➢ Constrain the allowable evaluation orders, so that the same translation is produced for any
allowable order. The constraints can be thought of as implicit edges added to the dependency
graph.

24
Evaluating Semantic rules
 Parse Tree methods
 At compile time evaluation order obtained from the topological sort of dependency graph.
 Fails if dependency graph has a cycle

 Rule Based Methods


 Semantic rules analyzed by hand or specialized tools at compiler construction time
 Order of evaluation of attributes associated with a production is pre-determined at
compiler construction time

 Oblivious Methods
 Evaluation order is chosen without considering the semantic rules.
 Restricts the class of syntax directed definitions that can be implemented.
 If translation takes place during parsing order of evaluation is forced by parsing method.

25
Syntax Directed Translation
Schemes
 A translation scheme is a context free grammar in which
 Attributes are associated with grammar symbols;
 Semantic actions are enclosed between braces{} and are inserted within the right-
hand side of production.

 Translation Schemes deal with both synthesized and inherited attributes.

 Semantic Actions are treated as terminal symbols: Annotated parse-trees


contain semantic actions as children of the node standing for the
corresponding production.

 Translation Schemes are useful to evaluate L-Attributed definitions at parsing


time (even if they are a general mechanism).

26
Syntax Directed Translation
Schemes
 An SDT is a CFG 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.

27
Postfix Translation Schemes
 The syntax-directed translation which has its semantic actions at
the end of the production is called the postfix translation
scheme.

 This type of translation of SDT has its corresponding semantics


at the last in the RHS of the production.

 Example of Postfix SDT


 S ⇢ A#B{S.val = A.val * B.val}
 A ⇢B@1{A.val = B.val + 1}
 B ⇢num{B.val = num.lexval}

28
Example of postfix SDT
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;}

29
Type Systems
 The type system in a programming language manages how
types are declared, used, and handled.

 A type system is a logical system that assigns properties (types)


to various program structures (variables, expressions, functions,
etc.).

 It ensures correct usage of types by enforcing rules.

 Every programming language has a type system, which can vary


from one language to another.

30
Type Systems
 Most programming languages assign to every value (whether a literal,
constant, or variable) a type, which describes the interpretation of the data in
that variable.

 The type indicates whether the value is an integer, a floating point number, a
Boolean, a string, a pointer, or something else.

 The type system of a language serves several purposes.


 Correctness: A good type system can help to eliminate runtime errors by
flagging them at compile time instead.
 Performance : compiler can use type information to find the most efficient
implementation of a piece of code

31
Type Systems
 Maintainability: A well-designed type system can make code easier to
maintain. When you change the type of a variable, the compiler can check
to make sure that all of the places where that variable is used are still valid.
This can help to prevent bugs and regressions.
 Expressiveness: A program can be made more compact and expressive if
the language allows the programmer to leave out facts that can be inferred
from the type system.
 Documentation: The type system can act as a form of documentation for
your code. By looking at the types of variables and functions, you can get a
good understanding of what the code does.

32
Type Systems
 A programming language (and its type system) are commonly
classified on the following axes:
 Type-safe languages or Type-unsafe languages
 Statically typed or Dynamically typed
 Explicitly typed or Implicitly typed
 Strongly typed of weakly typed languages

33
Type Systems
 Unsafe Programming Language:- it is possible to write valid programs
that have wildly undefined behavior that violates the basic structure of the
program.

 Type-unsafe languages allow potentially unsafe operations.


int i;
int a[10];
for(i=0;i<100;i++) a[i] = i;

 It is syntactically legal and will compile, but is unsafe because it writes


data outside the bounds of the array a[].

34
Type Systems
 In a Safe Programming Language, it is not possible to write a
program that violates the basic structures of the language.

 Prevent type-related errors during compilation or execution.

 That is, no matter what input is given to a program written in a safe


language, it will always execute in a well defined way that preserves
the abstractions of the language.

 For example using “IndexOutOfRangeException:”

 Exception handler. Input validation.

35
Type Systems
 In a Statically Typed Language, all type checking is performed at compile
time, before the program runs.
 This means that the program can be translated into basic machine code without
retaining any of the type information, because all operations have been checked
and determined to be safe.
 Example:- Java, C++, and Swift

 In a Dynamically typed language, type information is available at runtime,


and stored in memory alongside the data that it describes.
 As the program executes, the safety of each operation is checked by comparing
the types of each operand.
 Example:- Python, JavaScript, and Ruby

36
Type Systems
 In an Explicitly typed language, the programmer is responsible for
indicating the types of variables and other items in the code explicitly.
 Developers specify types explicitly
 This requires more effort on the programmer’s part, but reduces the possibility
of unexpected errors. Ex. int x = 32.5;

 In an Implicitly typed language, the compiler will infer the type of


variables and expressions (to the degree possible) without explicit input
from the programmer.
 This allows for programs to be more compact, but can result in accidental
behavior.
 e.g., var y = "hello"; in C#

37
Type Systems
 Strongly typed languages enforce strict type rules, preventing
operations between incompatible types.
 Examples:- include Java and Haskell.

 Weakly typed languages allow more flexibility, often coercing types


implicitly.
 Examples include JavaScript and PHP1.

38
Type System
 To describe the type system of a language, we must explain its
 Atomic types,
 Its compound types, and
 The rules for assigning and converting between types.

 The Atomic types of a language are: These are the basic,


indivisible data types provided by the programming language.
They represent the simplest units of data that cannot be further
decomposed.:
 e.g. integers, floating point numbers, Boolean values, and so forth.

39
Type System
 The Compound types of a language:- These are more complex data
types constructed from atomic types or other compound types. They
allow for structuring and organizing data in more meaningful ways.
(functions, Arrays,…)

40
Type Systems
A Type system

 is a collection of rules for assigning type expressions to


the various parts of a program.

Note:
 A type checker implements a type system.
 The type systems are specified in a syntax-directed manner
 Different type systems may be used by different compilers or
processors of the same language

41
The purpose of Types
 To define what the program should do.
 e.g. read an array of integers and return a double

 To guarantee that the program is meaningful.


 That it does not add a string to an integer
 That variables are declared before they are used

 To document the programmer's intentions.


 Better than comments, which are not checked by the compiler

 To optimize the use of hardware.


 Reserve the minimal amount of memory, but not more
 Use the most appropriate machine instructions

42
Type Checking
 Type checking is the process of verifying and enforcing constraints of types in
values.

 Check that the source program follows both the syntactic and semantic
conventions.

 It should also check the type rules of the language.

 It checks the type of objects and reports a type error in the case of a violation,
and incorrect types are corrected.

 The type checker is a module of a compiler and its task is type checking.

 This allows for the detection of errors at compile-time, instead of at runtime.

43
Type Checking
 The type-checker determines whether these values are used appropriately or
not.

44
Type Checking
➢ Conversion from one type to another type is known as
Coercion.
➢ Implicit if it is to be done automatically by the compiler.

➢ Explicit if the programmer writes something to do the Conversion.

➢ There are two kinds of Type Checking:


➢ Static Type Checking.

➢ Dynamic Type Checking.

45
Type Checking
➢ Static Checking
➢ Is defined as type checking performed at compile time.
➢ It checks the type variables at compile time, which means the type of
the variable is known at the compile time. (include C, C++, java)

Examples of static check


➢ Type checks (incompatible operand)
➢ Flow-of-control checks (break statement)
➢ Uniqueness checks (uniquely declared identifier)
➢ Name-related checks

46
Static Checking
➢ Type checks: A compiler should report an error if an operator is applied to an incompatible
operand.

➢ Flow-of-control checks: runtime errors related to control flow constructs like loops,
conditionals, and jumps..
➢ For example, branching to non-existent labels.

➢ Uniqueness checks: Objects should be defined only once. This is true in many
languages. you can't declare a variable with the same name twice within the same
scope.

➢ Name-related checks: Sometimes, the same name must appear two or more times.
➢ For example, in Ada the name of a block must appear both at the beginning of the block
and at the end.
47
Advantage of Static Type
Checking
➢ The early detection of errors at compile time.

➢ Checking All Execution Paths: it ensures consistency across different


branches and scenarios, reducing the chances of runtime surprises.

➢ No Runtime Type Tags:- There is no requirement of type tags on data


objects at runtime.

➢ Storage Efficiency: It knows the exact types of variables and can


allocate memory accordingly, resulting in better storage efficiency.

➢ Faster Execution

48
Disadvantages of Static Type
Checking
➢ Reduced Flexibility:- Static type checking can limit programmer
flexibility.

➢ In languages without declarations, there is no static type checking is


possible.

➢ Complex Error Messages: When type errors occur, static type checkers
often produce complex error messages..

➢ Static type checking is complex when a language enables a memory cell


to save values of multiple types at various times during execution.

➢ Difficulty with Self-Describing Types

49
Dynamic Type Checking
➢ Dynamic type Checking
➢ Dynamic Type Checking is defined as the type checking being done
at run time.
➢ In Dynamic Type Checking, types are associated with values, not variables.

➢ Dynamic typing is more flexible.

➢ Include Javascript, python, php

50
Advantage of Dynamic Type
Checking
➢ Flexibility in Program Design: allow you to change the type of a variable during
program execution..

➢ No Requirement for Declarations: You don’t need to explicitly declare the data type of
a variable. The type is determined at runtime based on the assigned value.

➢ Ease of Prototyping and Iteration:.

➢ Dynamic type checking can find many errors that cannot be identified by static type
checking.

➢ Compact Programs:- This can improve code readability and reduce verbosity

➢ In most languages, static type checking is not possible for some language constructs in
certain cases but the same purpose can be achieved by dynamic type checking.
51
Disadvantage of Dynamic
Type Checking
➢ It takes up more space involves inserting extra code into the program to
detect impending errors.

➢ Programs are difficult to debug as all possible execution paths are not
explored during program testing.

➢ It takes more time which reduces the speed of executing the operation.

➢ It is less efficient than static type checking.

➢ It is more expensive.

➢ Properties that depend on values computed at runtime are rarely checked.

52
Different type Checkers
➢ We can classify checkers in terms of what they return:
➢ A Rude Checker, which only says True or False, and may
even crash (for instance, when variable lookup just gives an
error is the variable is not found).
➢ An Error-reporting Checker, which returns OK or a message
saying where the error is.
➢ An Annotating Checker, which returns a syntax tree
annotated with more type information.

53
Type Checker
 Depending on language, the type checker can prevent
 Application of a function to wrong number of arguments,
 Application of integer functions to floats,
 Use of undeclared variables in expressions,
 Functions that do not return values,
 Division by zero
 Array indices out of bounds,
 Nonterminating recursion,
 Sorting algorithms that don't sort...

54

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy