Download presentation
Presentation is loading. Please wait.
Published byAlberta Poole Modified over 8 years ago
1
Compiler Design Lecture 10 Semantic Analysis
2
int aintegers int a[2][3]array(2, array(3, integer)) int f(int, float, char) int x float x char int Int f()void int void f(int)int void bool aboolean char __int8 short __int16 int and long __int32
3
Declarations Simple grammar for declarations
4
SDD for Assigning Basic and Array Types addType is used to assign type to identifiers added by the Lexer
5
Assigning Basic Types int T.t = integer.b = integer B C int C.t = integer.t = integer
6
Assigning Array Types int [2][3] T.t = integer.b = integer B C [ num ] C int C [ num ] .b = integer C.t = array( 2, ????????????? ) C.t = array( 3, ?????? ) C.t = integer.t = array( 2, array( 3, integer) ) integer array( 3, integer) ?
7
Checking for Unique Identifier Names Check if the id has already assigned a type in the same scope i.e. it’s already declared error int x; int x; D T id ; D{ t = lookup ( id.lexeme); if t = unbound then addType ( id.entry, T.t) else error( ‘identifier already defined’) } semantic action
8
Semantic Actions Syntax-directed translation scheme embeds program fragments called semantic actions within production bodies, as in E -+ El +T { print ' + I } By convention, semantic actions are enclosed within curly braces. (If curly braces occur as grammar symbols, we enclose them within single quotes, as in ‘{‘ and ‘ } '. The position of a semantic action in a production body determines the order in which the action is executed. In the previous production, the action occurs at the end, after all the grammar symbols; in general, semantic actions may occur at any position in a production body.
9
Small Example Language First-order functional language with recursive definition
10
Small Example Language (cont) Examples bool equals( int a, int b) = a = b int add( int a, int b) = a + b int equals (int a, int b) = if a = b then 0 else 1
11
The symbol table is implemented as a list with the following operations: empty: An empty symbol table is an empty list. binding: A new binding (name/object pair) is added to the front of the list. lookup: The list is searched until a matching name is found. The object paired with the name is then returned. If the end of the list is reached, an indication that this happened is returned instead. This indication can be made by raising an exception or by letting the lookup function return a type that can hold both objects and error indications, i.e., a sum-type. enter: The old list is remembered, i.e., a reference is made to it. exit: The old list is recalled, i.e., the above reference is used. Small Example Language (cont)
12
For terminals (variable names and numeric constants) with attributes, we assume that there are predefined functions for extracting these. Hence, id has an associated function name, that extracts the name of the identifier. Similarly, num has a function value, that returns the value of the number. For each nonterminal, we define one or more functions that take an abstract syntax subtree and inherited attributes as arguments and return the synthesised attributes. Small Example Language (cont)
13
Type Checking Expressions S ::= id = Exp int x; x = y; error: undefined identifier A new look for SDD
14
Type Checking Expressions (cont)
15
Grammar rule: Exps Exp, Exps | Exp Example: int f1(bool y) = let x = 3 in y+ f2( x, y) Type of f2 is: (int, bool) int Exps Exp, Exps id x id y.type = bool.type = [bool].type = int.type = [int, bool] Exp ] [
16
Expression Type Checking (cont) ProductionSemantic Rule When to assign Exp.hasAddress = true? In case of Exp id Also, Exp Exp [Exp] And so on … according to the language semantics Exp Exp 1 [Exp 2 ] Exp * Exp 1 Exp & Exp 1 e.g. &X &(X+Y) &3 if Exp 1.type = array(x, t) and if Exp 1.type = pointer(t) e.g. X[ Y[2] ] X[2][3] Exp.type = pointer(Exp 1.type) then Exp.type = t else error() Exp 2.type = integer then Exp.type = t else error() if Exp 1.hasAddress = true then else error() but what if the id is constant? since an array element has an address
17
Type Checking of Statements ProductionSemantic Rule P Decl Stmts if Decl.type = void then P.type = Stmts.type else error() Stmts Stmt; Stmts 1 if Stmt.type = void then Stmts.type = Stmts 1.type Stmts Stmt; Stmts.type = Stmt.type Stmt id = Exp if id.type = Exp.type then Stmt.type = void else error() What if id.type is array? Stmt if (Exp) Stmt 1 Stmt while (Exp) Stmt 1 if Exp.type = bool then Stmt.type = Stmt 1.type else error() Stmt ‘{‘ Stmts ‘}’ Stmt.type = Stmts.type
18
Function Declaration Grammar Function int add( int a, int b) = a + b int add( int a, int b) = a + b+c (Error) int add( int a, int b) = a = b (Error) int add( int a, int b, int a) = a + b (Error)
19
Function Declaration Checking Check Fun returns no information, it just checks for internal errors.
20
Function Declaration Checking (cont) e.g. int f(int x, bool y) TypeIds => int x, bool y Their should be a symbol table contains x and y with their types TypeIds TypeId, TypeIds.type = (y, bool).vtable = ((y, bool)).type = (x, int).vtable = ((y, bool), (x, int)) TypeId Int id x bool id y lookup( vtable, x) = unbound
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.