CD Unit 3 PDF
CD Unit 3 PDF
S-ATTRIBUTED DEFINITIONS
Definition. An S-Attributed Definition is a Syntax Directed Definition that uses
only synthesized attributes.
Evaluation Order. Semantic rules in a S-Attributed Definition can be evaluated
by a
bottom-up, or PostOrder, traversal of the parse-tree.
Example. The above arithmetic grammar is an example of an S-Attributed
Definition. The annotated parse-tree for the input 3*5+4n is:
L-attributed definition
Definition: A SDD its L-attributed if each inherited attribute of Xi in the RHS of A !
X1 :
:Xn depends only on
1. attributes of X1;X2; : : : ;Xi1 (symbols to the left of Xi in the RHS)
2. inherited attributes of A.
Top-Down Translation
Evaluation of the expression 9-5+2
Three address code in Compiler
Prerequisite –Intermediate Code Generation
Three address code is a type of intermediate code which is easy to generate and
can be easily converted to machine code. It makes use of at most three addresses
and one operator to represent an expression and the value computed at each
instruction is stored in temporary variable generated by compiler. The compiler
decides the order of operation given by three address code.
General representation –
a = b op c
Where a, b or c represents operands like names, constants or compiler generated
temporaries and op represents the operator
Example-1: Convert the expression a * – (b + c) into three address code.
2. Triples –
This representation doesn’t make use of extra temporary variable to represent a single
operation instead when a reference to another triple’s value is needed, a pointer to that
triple is used. So, it consist of only three fields namely op, arg1 and arg2.
Disadvantage –
Temporaries are implicit and difficult to rearrange code.
It is difficult to optimize because optimization involves moving intermediate code.
When a triple is moved, any other triple referring to it must be updated also. With
help of pointer one can directly access symbol table entry.
Example – Consider expression a = b * – c + b * – c
3. Indirect Triples –
This representation makes use of pointer to the listing of all references to computations
which is made separately and stored. Its similar in utility as compared to quadruple
representation but requires less space than it. Temporaries are implicit and easier to
rearrange code.
Example – Consider expression a = b * – c + b * – c
Question – Write quadruple, triples and indirect triples for following expression : (x + y)
* (y + z) + (x + y + z)
Explanation – The three address code is:
t1 = x + y
t2 = y + z
t3 = t1 * t2
t4 = t1 + z
t5 = t3 + t4
Types and Declarations
TYPE CHECKING
A compiler must check that the source program follows both syntactic
and semantic conventions of the source language.
This checking, called static checking, detects and reports programming
errors. Some examples of static checks:
1. Type checks – A compiler should report an error if an operator is applied to an
incompatible operand. Example: If an array variable and function variable
are added together.
2. Flow-of-control checks – Statements that cause flow of control to leave a
construct must have some place to which to transfer the flow of control.
Example: An error occurs when an enclosing statement, such as break, does
not exist in switch statement.
A type checker verifies that the type of a construct matches that expected by
its context.
Example: arithmetic operator mod in Pascal requires integer operands, so a
type checker verifies that the operands of mod have type integer.
Type information gathered by a type checker may be needed when code is
generated.
TYPE SYSTEMS
The design of a type checker for a language is based on information about the
syntactic constructs in the language, the notion of types, and the rules for
assigning types to language constructs.
For example : “ if both operands of the arithmetic operators of +,- and * are of
type integer, then the result is of type integer ”
Type Expressions
The type of a language construct will be denoted by a “type expression.”
A type expression is either a basic type or is formed by applying an
operator called a type constructor to other type expressions.
The sets of basic types and constructors depend on the language to be
checked.
The following are the definitions of type expressions:
1. Basic types such as boolean, char, integer, real are type expressions.
A special basic type, type_error , will signal an error during type checking;
void denoting “the absence of a value” allows statements to be checked.
2. Since type expressions may be named, a type name is a type expression.
3. A type constructor applied to type expressions is a type expression.
Constructors include:
Arrays : If T is a type expression then array (I,T) is a type expression
denoting the type of an array with elements of type T and index set I.
Products : If T1 and T2 are type expressions, then their Cartesian product
T1 X T2 is a type expression.
Records : The difference between a record and a product is that the fields of a
record have names. The record type constructor will be applied to a tuple
formed from field names and field types.
type row = record address: integer; lexeme: array[1..15] of char For example:
var table: array[1...101] of row;
declares the type name row representing the type expression record((address X
integer) X (lexeme X array(1..15,char))) and the variable table to be an array of
records of this type.
A Simple Language
Consider the following grammar:
P→D;E
D → D ; D | id : T
T → char | integer | array [ num ] of T | ↑ T
E → literal | num | id | E mod E | E [ E ] | E ↑
Translation scheme:
P→D;ED
→ D ;D
{ addtype (id.entry , T.type)} D
→ id : T
T → char { T.type : = char }
T → integer { T.type : = integer }
T → ↑ T1 { T.type : = pointer(T1.type) }
T → array [ num ] of T1 { T.type : = array ( 1… num.val , T1.type) }
In the above language,
→ There are two basic types : char and integer ;
→ type_error is used to signal errors;
→ the prefix operator ↑ builds a pointer type. Example , ↑ integer leads to the type
expression pointer ( integer ).
The postfix operator ↑ yields the object pointed to by its operand. The type of E ↑ is
the type t of the object pointed to by the pointer E.
3. While statement:
S → while E do S1 { S.type : = if E.type = boolean then S1.type
else type_error }
4. Sequence of statements:
S → S1 ; S2 { S.type : = if S1.type = void and S1.type = void
then void
else type_error }