University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data...

12
—Spring 2005—54 CSc 520 Principles of Programming Languages 54: Semantics — Denotational Semantics — Static Semantics Christian Collberg [email protected] Department of Computer Science University of Arizona Copyright c 2005 Christian Collberg [1] 520—Spring 2005—54 Context-Sensitive Syntax We can use a denotational-semantic style to define the context-sensitive syntax (the context conditions, the static semantic rules) of the language. These are the rules that a compiler will typically check during the semantic analysis phase of compilation. [2] —Spring 2005—54 Pelican Context Conditions 1. The program name identifier lies in a scope outside the main block. 2. All identifiers that appear in a block must be declared in that block or in an enclosing block. 3. No identifier may be declared more than once at the top level of a block. 4. The identifier on the left side of an assignment command must be declared as a variable, and the expression on the right side must be of the same type. 5. An identifier occurring as an (integer) element must be an integer variable or an integer constant. 6. An identifier occurring as a Boolean element must be a Boolean variable or a Boolean constant. [3] 520—Spring 2005—54 Pelican Context Conditions. . . 7. An identifier occurring in a read command must be an integer variable. 8. An identifier used in a procedure call must be defined in a procedure declaration with the same (zero or one) number of parameters. 9. The identifier defined as the formal parameter in a procedure declaration is considered to belong to the top level declarations of the block that forms the body of the procedure. 10. The expression in a procedure call must match the type of the formal parameter in the procedure s declaration. [4]

Transcript of University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data...

Page 1: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

CSc 520

Principles of ProgrammingLanguages

54: Semantics — Denotational Semantics —Static Semantics

Christian Collberg

[email protected]

Department of Computer Science

University of Arizona

Copyright c© 2005 Christian Collberg[1] 520—Spring 2005—54

Context-Sensitive Syntax

We can use a denotational-semantic style to define thecontext-sensitive syntax (the context conditions, thestatic semantic rules) of the language.

These are the rules that a compiler will typically checkduring the semantic analysis phase of compilation.

[2]

520—Spring 2005—54

Pelican Context Conditions

1. The program name identifier lies in a scope outside themain block.

2. All identifiers that appear in a block must be declared inthat block or in an enclosing block.

3. No identifier may be declared more than once at the toplevel of a block.

4. The identifier on the left side of an assignmentcommand must be declared as a variable, and theexpression on the right side must be of the same type.

5. An identifier occurring as an (integer) element must bean integer variable or an integer constant.

6. An identifier occurring as a Boolean element must be aBoolean variable or a Boolean constant.

[3] 520—Spring 2005—54

Pelican Context Conditions. . .

7. An identifier occurring in a read command must be aninteger variable.

8. An identifier used in a procedure call must be defined ina procedure declaration with the same (zero or one)number of parameters.

9. The identifier defined as the formal parameter in aprocedure declaration is considered to belong to the toplevel declarations of the block that forms the body of theprocedure.

10. The expression in a procedure call must match the typeof the formal parameter in the procedure s declaration.

[4]

Page 2: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

The Static Semantics of Pelican

[5] 520—Spring 2005—54

Abstract Syntactic Domains

These are the abstract syntactic domains of Pelican:

P : Program

B: Block

C: Command

D: Declaration

T : Type

E: Expression

O: Operator

N : Numeral

I: Identifier

[6]

520—Spring 2005—54

Abstract Syntax of Pelican

Program ::= program identifieris Block end

Block ::= Declaration* begin Command end

Declaration ::= var Identifier: Type | const Identifier=Expression | procedure Identifieris Block | procedureIdentifier( identifier: Type ) is Block |

Type ::= integer | boolean

Command ::= . . . |declare BlockIdentifier |Identifier( Expression )

Expression ::= . . .

[7] 520—Spring 2005—54

Semantic Domains of Pelican

Environments map identifiers to types.

Sort represents all the different types an expression cantake on.

We distinguish between variables (IntVar,BoolVar) andconstants (Integer,Boolean).

Sort = {Integer, Boolean, IntVar, BoolVar, Program, unbound}

Boolean = {true, false}

Env = Identifier → Sort

[8]

Page 3: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

Semantic Functions of Pelican

We return true if a program satisfies all it staticsemantic constraints:

validate : Program → Boolean

To check a block we need access to an environmentcontaining declared identifiers:

examine : Block → Env → Boolean

The result of checking an expression is its type:

typify : Expression → Env → Sort

[9] 520—Spring 2005—54

Semantic Functions of Pelican. . .

To elaborate a declaration we need two environments:

elaborate : Declaration → (Env, Env) → (Env, Env)

1. The first environment lenv holds the identifiers localto the block. It is used to check for multiply declaredidentifiers.

2. The second environment env holds accumulateddeclarations.

Commands (statements) are checked given anenvironment of identifiers and their types:

check : Command → Env → Boolean

[10]

520—Spring 2005—54

Environment ADT

The environment is a structure that maps identifiers totheir types:

Example:

env = {c 7→ Integer, a 7→ IntVar}

emptyEnv : Env

extendEnv : Env × Identifier × Sort → Env

applyEnv : Env × Identifier → Sort

[11] 520—Spring 2005—54

Semantic Equations

[12]

Page 4: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

Programs

We validate the program (check its context conditions)by checking the main block B:

validate [[program I is B]] = examine [[B]] env

where env = extendEnv(e, I, Program)

where e = emptyEnv

lenv1 will contain all the identifiers declared in D. envcontains the identifiers inherited from enclosing blocks:

examine [[D begin C end]] env = check [[C]] env1

where (lenv1, env1) = elaborate [[D]] (e, env)

where e = emptyEnv

[13] 520—Spring 2005—54

Declarations

Sequences of declarations build up the environment:

elaborate [[ε]] (lenv, env) = (lenv, env)

elaborate [[D1 D2]] env = elaborate [[D2]] ◦ elaborate [[D1]]

Constant declarations add an entry id 7→ type to theenvironment, first checking for multiple declarations:

elaborate [[const I = E]](lenv, env) =

if applyEnv(lenv, I) == unbound then(l, e) else error

where t = typify [[E]] env

l = extendEnv(lenv, I, t)

e = extendEnv(env, I, t)

[14]

520—Spring 2005—54

Declarations. . .

Variable declarations add an entry id 7→ type to theenvironment, first checking for multiple declarations:

elaborate [[var I : T ]] (lenv, env) =

if applyEnv(lenv, I) == unbound then(l, e) else error

where t = type(T )

l = extendEnv(lenv, I, t)

e = extendEnv(env, I, t)

[15] 520—Spring 2005—54

Commands

A sequence of commands is OK, if each individualcommand is:

check [[C1; C2]] env = (check [[C1]] env) & (check [[C2]] env)

Note that both commands get the same environment.

The skip command is always OK:

check [[skip]] env = true

[16]

Page 5: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

Commands. . .

The assignment statement looks up the identifier in theenvironment and compares it to the type of the righthand side:

check [[I:= E]] env = (l = IntVar & r = Integer) |

(l = BoolVar & r = Boolean)

where l = applyEnv(env, I)

r = typify [[E]] env

Note that I cannot be an identifier declared to be aconstant.

[17] 520—Spring 2005—54

Commands. . .

If-statements:

check [[if E then C]] env = p &check [[C]]

where p = typify [[E]] env

If-then-else-statements:

check [[if E then C1 else C2]] env = p &check [[C1]] &check [[C2]]

where p = typify [[E]] env

Loops:

check [[while E do C]] env = p &check [[C]]

where p = typify [[E]] env[18]

520—Spring 2005—54

Commands. . .

Local scope:

check [[declare B]] env = examine [[B]] env

Input and Output:

check [[read I ]] env = applyEnv(I, env) = IntVar

check [[write E]] env = typify [[E]] env = Integer

[19] 520—Spring 2005—54

Expressions

typify [[I ]] env = if v ∈ {IntVar, Integer} then Integer

else if v ∈ {BoolVar, Boolean} then Boolean

else if v = unbound then error

where v = applyEnv(env, I)

We look up the identifier I in the current environment.

Integer variables and constants generate an Integersort, Boolean variables and constants generate aBoolean sort.

Undeclared identifiers generate an error.

[20]

Page 6: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

Expressions. . .

typify [[N ]] env = Integer

typify [[true]] env = Boolean

typify [[false]] env = Boolean

typify [[E1 + E2]] env = if m = n = Integer

then Integer

else error

where m = typify [[E1]] env

n = typify [[E2]] env

[21] 520—Spring 2005—54

Example

program p is

const m = 34; -- Point A

begin

declare -- Point B

var c : boolean; -- Point C

const c = m+21; -- Error

begin

write m+c;

end

end

At point A: env = {m 7→ Integer, p 7→ Program}, lenv = {m 7→ Integer}

At point B: env = {m 7→ Integer, p 7→ Program}, lenv = { }

At point C: env = {c 7→ BoolVar, m 7→ Integer, p 7→ Program},lenv = {c 7→ BoolVar}

[22]

520—Spring 2005—54

A Haskell Prototype

[23] 520—Spring 2005—54

Abstract Syntax

-- Abstract Syntax for storeable values:

type Num = Int

data Sort = IntType | BoolType | IntVar |

BoolVar | Routine | Unbound

type Identifier = String

type Env = [(Identifier,Sort)]

[24]

Page 7: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

Abstract Syntax

data Operator = Add | Sub | Mul | Minus | Div ...

data Expression = Id Identifier |

LitInt Num |

TrueVal |

FalseVal |

Unary Operator Expression |

Binary Expression Operator Expression

[25] 520—Spring 2005—54

Abstract Syntax

data Program = Program Identifier Block

data Block = Block Declaration Command

data Declaration =

VarDecl Identifier Sort |

DeclSeq Declaration Declaration |

NullDecl |

ConstDecl Identifier Expression |

ProcDecl0 Identifier Block |

ProcDecl1 Identifier Identifier Sort Block

[26]

520—Spring 2005—54

Abstract Syntax

data Command = Skip |

Assign Identifier Expression |

Read Identifier |

Write Expression |

IfThen Expression Command |

IfThenElse Expression Command Command |

While Expression Command |

Seq Command Command |

Declare Block |

Call0 Identifier |

Call1 Identifier Expression

[27] 520—Spring 2005—54

Environment

emptyEnv:: Env

emptyEnv = []

extendEnv:: Env -> Identifier -> Sort -> Env

extendEnv env id val = (id,val) : env

applyEnv:: Env -> Identifier -> Sort

applyEnv [] _ = Unbound

applyEnv ((s,sort):r) id

| s==id = sort

| otherwise = applyEnv r id

[28]

Page 8: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

Declarations

elaborate :: Declaration -> (Env,Env) -> (Env,Env)

elaborate NullDecl (lenv,env) = (lenv,env)

elaborate (DeclSeq d1 d2) (lenv,env) = (lenv2,env2)

where (lenv1,env1) = elaborate d1 (lenv,env)

(lenv2,env2) = elaborate d2 (lenv1,env1)

[29] 520—Spring 2005—54

Declarations

elaborate (VarDecl id typeid) (lenv,env) =

if (applyEnv lenv id) == Unbound then

(lenv1,env1)

else

error ("ERROR: Multiple declaration")

where lenv1 = extendEnv lenv id typev

env1 = extendEnv env id typev

typev = case typeid of

IntType -> IntVar

BoolType -> BoolVar

[30]

520—Spring 2005—54

Declarations

elaborate (ConstDecl id e) (lenv,env) =

if (applyEnv lenv id) == Unbound then

(lenv1,env1)

else

error ("ERROR: Multiple declaration")

where lenv1 = extendEnv lenv id (typify e env)

env1 = extendEnv env id (typify e env)

[31] 520—Spring 2005—54

Expressions

btype :: Sort -> Operator -> Sort -> Sort

btype IntType Add IntType = IntType

btype IntType Mul IntType = IntType

btype IntType Div IntType = IntType

btype IntType Sub IntType = IntType

btype BoolType And BoolType = BoolType

btype BoolType Or BoolType = BoolType

btype IntType Lt IntType = BoolType

btype IntType Gt IntType = BoolType

btype IntType Le IntType = BoolType

btype IntType Ge IntType = BoolType

btype IntType Eq IntType = BoolType

btype IntType Ne IntType = BoolType

btype a op b =

error ("ERROR: Type mismatch")

[32]

Page 9: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

Expressions

typify :: Expression -> Env -> Sort

typify (Id id) env = case (applyEnv env id) of

IntVar -> IntType

IntType -> IntType

BoolVar -> BoolType

BoolType -> BoolType

Routine -> Routine

Unbound -> error ("ERROR: Ident not declared")

[33] 520—Spring 2005—54

Expressions

typify (LitInt n) env = IntType

typify (TrueVal) env = BoolType

typify (FalseVal) env = BoolType

typify (Unary op r) env = utype op n

where n = typify r env

typify (Binary l op r) env = btype m op n

where m = typify l env

n = typify r env

[34]

520—Spring 2005—54

Commands

check :: Command -> Env -> Bool

check (Skip) env = True

check (Seq c1 c2) env = (check c1 env) && (check c2 env)

[35] 520—Spring 2005—54

Commands. . .

check (Assign id e) env =

if not v then

error ("ERROR: Variable expected")

else

if b then b

else error "ERROR: Assignment type error"

where l = applyEnv env id

r = typify e env

b = ((l==IntVar) && (r==IntType) ||

(l==BoolVar) && (r==BoolType))

v = (l==IntVar) || (l==BoolVar)

[36]

Page 10: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

Commands. . .

check (Read id) env =

if not v then

error ("ERROR: Variable expected")

else

if l==IntVar then True

else error "ERROR: Read type error"

where l = applyEnv env id

v = (l==IntVar) || (l==BoolVar)

check (Write e) env =

if r==IntType then True

else error "ERROR: Write type error"

where r = typify e env

[37] 520—Spring 2005—54

Commands. . .

check (IfThen b c) env = if p then check c env

else error "ERROR: Boolean type expected."

where p = (typify b env)==BoolType

check (IfThenElse b c1 c2) env = if p

then (check c1 env) && (check c2 env)

else error "ERROR: Boolean type expected"

where p = (typify b env)==BoolType

check (While b c) env = if p then check c env

else error "ERROR: Boolean type expected."

where p = (typify b env)==BoolType

[38]

520—Spring 2005—54

Programs

validate :: Program -> Bool

validate (Program id b) = examine b (env)

where env = extendEnv emptyEnv id Routine

-- Note: "seq" is necessary to force elaboration

-- (avoid laziness) even when the new environment

-- is not needed.

examine :: Block -> Env -> Bool

examine (Block decl cmd) env = seq env1 (check cmd env1)

where env1 = snd (elaborate decl (emptyEnv,env))

[39] 520—Spring 2005—54

Examples

> validate (Program "h"

(Block

(VarDecl "s" IntType)

(Assign "s" (LitInt 5))))

True

> validate (Program "h"

(Block

(VarDecl "s" IntType)

(Assign "s" (TrueVal))))

Program error: ERROR: Assignment type error

[40]

Page 11: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

Examples. . .

> validate (Program "h"

(Block

NullDecl

(Assign "s" (LitInt 5))))

Program error: ERROR: Variable expected

[41] 520—Spring 2005—54

Examples. . .

> validate (Program "h"

(Block

(VarDecl "x" BoolType)

(Declare

(Block

(VarDecl "y" BoolType)

(Declare

(Block

(VarDecl "x" IntType)

(Assign "s" (LitInt 99))

) ) ) ) )

)

Program error: ERROR: Variable expected

[42]

520—Spring 2005—54

Examples. . .

> validate (Program "h"

(Block (

DeclSeq

(VarDecl "s" BoolType)

(VarDecl "s" IntType))

Skip))

Program error: ERROR: Multiple declaration

[43] 520—Spring 2005—54

Readings and References

Read pp. 323–328, in Chapter 9 of Syntax andSemantics of Programming Languages, by KenSlonneger and Barry Kurtz,http://www.cs.uiowa.edu/˜slonnegr/plf/Book.

[44]

Page 12: University of Arizonacollberg/Teaching/520/... · 520—Spring 2005—54 Abstract Syntax data Command = Skip | Assign Identifier Expression | Read Identifier | Write Expression |

520—Spring 2005—54

Acknowledgments

Much of the material in this lecture on DenotationalSemantics is taken from the book Syntax andSemantics of Programming Languages, by KenSlonneger and Barry Kurtz,http://www.cs.uiowa.edu/˜slonnegr/plf/Book.

[45]