Upload
brett-nicholson
View
221
Download
1
Tags:
Embed Size (px)
Citation preview
1
Mooly Sagiv and Greta YorshSchool of Computer Science
Tel-Aviv University
[email protected]://www.cs.tau.ac.il/~gretay
Modern Compiler Design
T7 – Symbol Tables and Scoping Rules
3
Today
Goals: Semantic checks - scoping rules Symbol tables
Next week Type checking
COOL
code
txt
Executable
code
exeLexicalAnalysi
s
Syntax Analysi
s
Parsing
AST Symbol
Tableetc.
Inter.Rep.
(IR)
Code
Gen.
4
Cool Semantic Analysis ?
1. All identifiers are declared2. Types3. Inheritance relations4. Classes defined only once5. Methods in a class defined only once6. Reserved identifiers are not misused7. Number of arguments (in call) matches the
number of formals (in declaration) and the corresponding types
8. …
5
Semantic Analysis
Checking for “correct meaning” Warn about dubious meaning
Long-distance and deep relations Lexer and parser are only short-distance
Implemented using AST traversals
6
Scope of an identifier
The part of the program in which the identifier is accessible or visible
An identifier may have restricted scopeSame identifier may refer to different things
in different parts of the programDifferent scopes for same name don’t
overlapNot all kinds of identifiers follow the most-
closely nested rule
7
Scopesclass Foo { value : Int 39; test() : Int { let b:Int 3 in value + b }; setValue(c:Int):Int {{ value c; let d:Int c in { c c + d; value c; }; }};};
public class Bar { value:Int 42; setValue(int c):Int {
value c; }}
scope of value
scope of b
scope of c
scope of c
scope of value
scope of d
8
Where do identifiers come from ?
(How do we introduce identifier bindings in Cool ?)
Let expressionsFormal parametersAttribute definitionsCase expressions
Class declarations (class names)Method declarations (method names)
(object ids)
9
Scope rules
Match identifier declarations with uses
Why ? for type checking…
Let y : String “abc” in y + 3
Static scope - depends only on the program text, not runtime behavior
11
Scope of Class Definitions
Cannot be nestedGlobally visibleClass name can be used before it is definedClass Foo {
… let y : Bar in …
}
Class Bar {
…
}
12
Scope of Attributes
Global within the class in which they are defined
Can be used before defined in the class
Class Foo {
f() : Int { a };
a : Int 0;
}
13
Scope of Methods
Method need not be defined in the class in which it is used, but in some parent class
Overriding - methods may be redefinedclass A {
foo():Int { …};
};
class B inherits A { };
class C { b : B new B;
bar():Int{ b.foo() };
};
14
Scope of Methods
Overriding - methods may be redefinedclass A {
foo():Int { …};
};
class B inherits A {
foo():Int {…};
};
class C { b : B new B;
bar():Int{ b.foo() };
};
15
Some Cool Scope Rules
local variable declared before useattributes need not be declared before usevariables cannot be defined multiple times
in same scope, but can be redefined in nested scopesclass A {
x : String “a”;
foo(x : Int, x : String): SELF_TYPE{ x };
};
it is allowed to shadow method parameters
16
What is Symbol Table ?
Scopes implemented using symbol tables
Data-structure for “look-up” key – identifier value – type of identifier, other semantic
properties
17
Symbol Table - 1st Attempt
Symbol Kind Type Properties
a var Int …
b var Int …
test method -> Int …
class Test { a: Int 39; test(): Int { let b:Int 3 in a + b };};
18
Symbol Table - 1st Attempt
Symbol Kind Type Properties
a var Int …
b var Int …
test method -> Int …
a var String …
class Test { a: Int 39; test(): Int { let a: String “hello”,
b:Int 3 in b };};
19
Implementing Scopes
Let x : Int 0 in e
before processing e add definition of x to current definitions override any other definition of x
after processing e remove definition of x restore old definition of x
20
Symbol Table – 2nd Attempt
class Foo { value : Int 39; test(b:Int) : Int { value + b }; setValue(c:Int):Int {{ value c; let d:Int c in { c c + d; value c; }; }};};
21
Symbol Table – 2nd Attempt
Symbol Kind Type Properties
value var Int …
test method
-> Int
setValue
method
Int -> Int
Symbol Kind Type Properties
b var Int …
Symbol Kind Type Properties
c var Int …
Symbol Kind Type Properties
d var Int …
(Foo)
(test) (setValue)
(setValue-block)…
22
Symbol Table Lookup
Symbol Kind Type Properties
value var int …
test method
-> int
setValue
method
int -> int
Symbol Kind Type Properties
b var int …
Symbol Kind Type Properties
c var int …
Symbol Kind Type Properties
d var int …
(Foo)
(Test) (setValue)
(setValue-block)
setValue(c:Int):Int {{ value c; let d :Int c in { c c + d; value c; }; }};
Lookup(value)
23
Symbol Table Lookup
Symbol Kind Type Properties
value var int …
test method
-> int
setValue
method
int -> int
Symbol Kind Type Properties
b var int …
Symbol Kind Type Properties
c var int …
Symbol Kind Type Properties
d var int …
(Foo)
(Test) (setValue)
(setValue-block)
Lookup(myValue)
Error !
setValue(c:Int):Int {{ value c; let d :Int c in { c c + d; myValue c; }; }};
24
Symbol Table Construction
class Foo { value : Int 39; test(b:Int) : Int { value + b; }; setValue(c:Int):Int {{ value c; let d:Int c in { c c + d; value c; }; }};};
Method
Expr
Method
Class
root
name=Foo
name=setValuename=test
Expr Let
Expr ExprExpr
id=d
(some details omitted)
25
class
Symbol Table Construction via AST Traversal
Method
Expr
Method
Class
root
name=Foo
name=setValuename=test
Expr Let
Expr ExprExpr
(some details omitted)
Symbol
kind
globals
Symbol kind
Foo
Symbol
test
Symbol
setValue
Foo
test methodsetValue method
b var c var
Symbol
Let
d varid=d
26
class
Symbol Table Construction via AST Traversal
Method
Expr
Method
Class
root
name=Foo
name=setValuename=test
Expr Let
Expr ExprExpr
(some details omitted)
Symbol
kind
globals
Symbol kind
Foo
Symbol
test
Symbol
setValue
Foo
test methodsetValue method
b var c var
Symbol
Let
d varid=d
27
Implementation
SymbolTable.java symbol table - stack of scopes scope – hash table <key, value> key is AbstractSymbol value is Object
generic – do we need store and lookup in other cases ?
SymtabExample.java
28
Our Implementation Support
enterScope() start a new nested scope
lookup(x) finds current x (or null)
addId(x) adds a symbol x to the table
probe(x) true if x defined in current scope
exitScope() exit current scope
29
Your Implementation Should …
Symbol table key should combine id and kind separating table in advance according to kinds
method, attribute/local variable bindings, classes
implement using 2-level maps (kind->id->value)
implement this using key objects ( (kind,id)->value) )
30
Symbol Tables (cont’d)
class A {
foo() {
bar();
}
bar() {
…
}
}
Program
root
Class
id=A
Method
id=foo
Method
id=bar
dispatch
id=bar()
class
Symbol
kind
globals
Symbol kind
A
A
foo methodbar method
Undefined identifier bar()
31
Symbol Tables - Naïve solution
Building visitor Propagates (at least) a reference to the symbol table of the
current scope In some cases have to use type information (inherits)
Checking visitor On visit to node – perform check using symbol tables
Resolve identifiers Try to find symbol in table hierarchy In some cases have to use global type table and type
information You may postpone these checks
32
Symbol Tables – less naïve solution
Use forward referencesAnd/or construct some of the symbol table
during parsing
33
Symbol Tables (cont’d)
class A {
foo() {
bar();
}
bar() {
…
}
}
Program
root
Class
id=A
Method
id=foo
Method
id=bar
Dispatch
id=bar()
class
Symbol
kind
globals
Symbol kind FREF
A
A
foo methodbar method true
34
Forward References
Optimistically assume that symbol will be eventually defined
Update symbol table when symbol defined Remove forward-reference marker
But check correctness when exiting scope No forward references should exist at exit
35
Passes
Can we check class names using symbol table? No.
Can we check class names in one pass ? No.
Semantic analysis requires multiple passes probably more than 2 for Cool
pass 1: gather all class namespass 2: do the checking
36
Inheritance Graph
A node in the inheritance graph for each class
Parent and children in the inheritance graph
Predefined classes: Object, IO, Int, etc. Int, String, Bool can’t be inherited Is the class reachable/unreachable from the
Object class via the "inherits from" relation?
A type checking environment
37
Check Inheritance Graph
Local properties base class is defined base class can be inherited from do not require traversing inheritance graph
Global properties find all classes reachable from root class Object check that it really is a tree (no cycles)
38
Major Semantic Tasks
initially the symbol table mapping class names to inheritance graph nodes is empty
construct inheritance graph predefined classes user-defined classes
check inheritance graph build symbol tables of features for each
class check for Main class and main method type check all expressions