Title: Static Semantics
1Static Semantics
- Lecture 15
- (Notes by P. N. Hilfinger and R. Bodik)
2Current Status
- Lexical analysis
- Produces tokens
- Detects eliminates illegal tokens
- Parsing
- Produces trees
- Detects eliminates ill-formed parse trees
- Static semantic analysis ?we are here
- Produces decorated tree with additional
information attached - Detects eliminates remaining static errors
3Static vs. Dynamic
- We use the term static to describe properties
that the compiler can determine without
considering any particular execution. - E.g., in
- def f(x) x 1
- Both uses of x refer to same variable
- Dynamic properties are those that depend on
particular executions in general. E.g., will
x x/y cause an arithmetic exception.
4Static vs. Dynamic, contd.
- Actually, distinction is not that simple. E.g.,
after - x 3
- y x 2
- compiler could deduce that x and y are Ints
- But languages often designed to require that we
treat variables only according to explicitly
declared types, because deductions are difficult
or impossible in general.
5Typical Tasks of the Semantic Analyzer
- Find the declaration that defines each identifier
instance - Determine the static types of expressions
- Perform re-organizations of the AST that were
inconvenient in parser, or required semantic
information - Detect errors and fix to allow further processing
6Typical Semantic Errors Java, C
- Multiple declarations a variable should be
declared (in the same region) at most once - Undeclared variable a variable should not be
used before being declared. - Type mismatch type of the left-hand side of an
assignment should match the type of the
right-hand side. - Wrong arguments methods should be called with
the right number and types of arguments. - Definite-assignment check (Java) conservative
check that simple variables assigned to before
use.
7Output from Static Semantic Analysis
- Input is AST output is an annotated tree.
x 3 def f (x) return xy y Int y 2
?
def
type_decl
x
y
y
f
Int
3
2
return
?
1
2
4
4
Int
Int
1 x, Any, 0 2 f, Any-gtAny, 0 3 x, Any,
1 4 y, Int, 0
x
3
Any
y
x
3
4
Ids decorated with declarations.
Expressions annotated with (static) types.
8Output from Static Semantic Analysis (II)
- Analysis has added objects well call symbol
entries to hold information about instances of
identifiers. - In this example, 1 x, Any, 0 denotes an entry
for something named x occurring at the outer
lexical level (level 0) and having static type
Any. - For other expressions, we annotate with static
type information.
9Output from Static Semantic Analysis (III)
- Symbol entries for classes (or modules, packages,
namespaces and the like) must contain equivalent
of a dictionary mapping names of members to
symbol entries. - So given an expression such as x.clear (), we
- find symbol entry for x
- find type (class) of x from its entry, and
- find clear in dictionary of entry associated with
xs type.
10Binding names to symbol entries Scoping
- Scope of a declaration section of text where it
applies - Declarative region section of text that bounds
scopes of declarations (well say region for
short) - In most languages, the same name can be declared
multiple times - if its declarations occur in different
declarative regions, and/or - involve different kinds of names.
11Scoping example
- Java can use same name for
- a class,
- field of the class,
- a method of the class, and
- a local variable of the method
- legal Java program
- class Test
- int Test
- Test( ) double Test
-
12Scoping general rules
- The scope rules of a language
- determine which declaration of a named object
corresponds to each use of the object. - Scoping rules map uses of objects to their
declarations (or symbol entries). - C and Java use static scoping
- mapping from uses to declarations is made at
compile time. - C uses Algol scope rules
- a use of variable x matches the declaration with
the most closely enclosing scope. - a deeply nested variable x hides x declared in an
outer region. - in Java
- inner regions cannot define variables defined in
outer regions
13Scoping Options Declarative Regions
- In Java, each function has one or more
declarative regions - one for the function body,
- and possibly additional regions in the function
- for each for loop and
- each nested block (delimited by curly braces)
- In Pyth, each function has one per function
(possibly plus more for nested functions)
14Example (assume C rules)
- double y, k // y and k global variables
- void f(int y) // y also used as a parameter
- y k // Uses global k and parameter y
- int k 0 // k is now local variable
- while (k) // refers to 2nd decl
of k - int k 1 // another local var, in a
loop (not ok in Java) -
-
- the outermost region includes decls of "f, k
and y - function f itself has two (nested) regions
- The outer region for f includes parameter y and
local variable k . - The innermost region is for the body of the while
loop, and includes the variable k that is
initialized to 1.
global k hidden starting here
15Scoping Options overloading
- Java and C (but not in Pascal, C, or Pyth)
- can use the same name for more than one method
- as long as the number and/or types of parameters
are unique. - int add(int a, int b)
- float add(float a, float b)
16Scoping options Use before declaration?
- Can names be used before they are defined?
- Java, C a method or field name can be used
before the definition appears not true for a
variable, whose scope starts at its declaration - In Pyth, almost anything can be used before
declaration, where syntactically possible
17Scoping Options Dynamic scoping
- Not all languages use static scoping.
- Original Lisp, APL, and Snobol use dynamic
scoping. - Dynamic scoping
- A use of a variable that has no corresponding
declaration in the same function corresponds to
the declaration in the most-recently-called still
active function. - With this rule, difficult for compiler to
determine much about identifiers
18Example
- For example, consider the following code
- void main() f1() f2()
- void f1() int x 10 g()
- void f2() String x "hello" f3()g()
- void f3() double x 30.5
- void g() print(x)
- With static scoping, illegal.
- With dynamic scoping, prints 10 and hello
19So How do we Annotate with Declarations?
- Idea is to recursively navigate the AST, in
effect executing the program in simplified
fashion, extracting information that isnt data
dependent. - You saw it in CS61A (sort of).
20Environment Diagrams and Symbol Entries
- In Scheme, a program like
- (set! x 7)
- (define (f x) (let ((y ( x 39)) ( x y)))
- (f 3)
- when executed would eventually give you
something like this when computing ( x y)
X 7 f
y 42
current environment
x 3
global environment
21Environment Diagrams to Symbol Entries
- Abstracting from this particular execution,
X 7 f
y 42
current environment
x 3
we take away the values and replace with
static info
current environment
1. X Any 2. f Any-gtAny
4. y Any
3. x Any
and were left with symbol entries and a
data structure (a kind of symbol table) for
looking them up.
22Annotating Pyth with Symbol Entries
- Process requires several passes (traversals of
AST). A rough outline - Create symbol entries for all classes and record
in global environment, plus entries for all class
members stored in the classs entries. - For each declarative region,
- Create a new environment box for each declaration
immediately inside the region. - Use it to annotate all uses, and recursively do
step 2 for all inner declarative regions.
23Type Checking
- the job of the type-checking phase is to
- Determine the type of each expression in the
program - (each node in the AST that corresponds to an
expression) - Find type errors
- The type rules of a language define
- how to determine expression types, and
- what is considered to be an error.
- The type rules specify, for every operator
(including assignment), - what types the operands can have, and
- what is the type of the result.
24Type Errors
- The type checker must also
- find type errors having to do with the context of
expressions, - e.g., the context of some operators must be
boolean, - type errors having to do with method calls.
- Examples of the context errors
- the condition of an if not boolean (Java)
- type of returned value not functions return type
- Examples of method errors
- calling something that is not a method
- calling a method with the wrong number of
arguments - calling a method with arguments of the wrong
types