CH3-1 and CH3-2
CH3-1 and CH3-2
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.
2
Introduction
E→E+T E.val := E.val + T.val, E.val is one of the attributes of E.
3
Introduction
Evaluation of these semantic rules:
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
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
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.
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:
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.
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
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
S-Attributed Definitions
L-Attributed Definitions
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.
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
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
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.
20
Example of S-attributed SDD
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
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;
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
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.
26
Syntax Directed Translation
Schemes
An SDT is a CFG with program fragments embedded within production
bodies
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.
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.
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.
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.
34
Type Systems
In a Safe Programming Language, it is not possible to write a
program that violates the basic structures of the language.
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
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;
37
Type Systems
Strongly typed languages enforce strict type rules, preventing
operations between incompatible types.
Examples:- include Java and Haskell.
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.
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
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
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 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.
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.
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)
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.
➢ Faster Execution
48
Disadvantages of Static Type
Checking
➢ Reduced Flexibility:- Static type checking can limit programmer
flexibility.
➢ Complex Error Messages: When type errors occur, static type checkers
often produce complex error messages..
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.
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.
➢ 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 more expensive.
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