modern compiler implementation in java semantic analysis chapter 5 cmsc 431 spring, 2003
TRANSCRIPT
Modern Compiler Implementation in Java
Semantic Analysis
Chapter 5CMSC 431
Spring, 2003
2
UMBC
Symbol Tables
• Symbol Tables Environments– Mapping IDs to Types and Locations– Definitions Insert in the table– Use Lookup ID
• Scope– Where the IDs are “visible”Ex: formal parameters, local variables in MiniJava
-> inside the method where defined
3
UMBC
Environments
• A set of bindings ( -> )Initial Env 0
Class C {
int a; int b; int c;
Env = 0 + {a -> int, b -> int, c -> int}
public void m() {
System.out.println(a+c);
int j = a+b;
Env = 1 + {j -> int}
String a = “hello”;
Env = 2 + {a -> String}
System.out.println(a);
4
UMBC
Environments (Cont’d)
Env = 2 + {a -> String}
System.out.println(a);
System.out.println(a);
System.out.println(a);
}
Env
}
Env
5
UMBC
Implementing Environments
• Functional Style– Keep previous env and create new one– When restored, discard new one and back to
old
• Imperative Style– Destructive update the env(symbol tables)– Undo : need “undo stack”
6
UMBC
Multiple Symbol Tables : ML-style
structure M = sturct
structure E = struct
val a = 5
end +
structure N = struct
val b = 10
val a = E.a + b
end +
structure D = struct
val d = E.a + N.a
end
End
Initial Env 0
= {a -> int}
= {E -> }
= {b -> int,a -> int}
= {N -> }
= {d -> int}
= {D -> }
=
7
UMBC
Multiple Symbol Tables : Java-style
Package M;
class E {
static int a = 5;
}
class N {
static int b = 10
static int a = E.a + b
}
class D {
static int d = E.a+ N.a
}
End
Initial Env 0
= {a -> int}
= {E -> }
= {b -> int,a -> int}
= {N -> }
= {d -> int}
= {D -> }
=
8
UMBCImplementation – Imperative Symbol Table
a
b
d
c
See Appel Program 5.2 (p106)
Update
Undo
’d
Using a Hash Table
9
UMBCImplementation – Functional Symbol Table
• Efficient Functional Approach’a
would return [a
• If implemented with a Hashtable would have to create O(n) buckets for each scope
• Is this a good idea?
10
UMBC
Implementation - Tree
dog 3
bat 1
dog 3
camel 2
emu 42
m1
m2
m1 = { bat |-> 1 , camel |-> 2, dog |-> 3 }
m2 = {m1 + emu |-> 42 }
How could this be implemented?
Want m2 from m1 in O(n)
11
UMBC
Symbols
• See Program 5.5 on pg109• Symbol Representation
– Comparing symbols for equality is fast.– Extracting an integer hash key is fast.– Comparing two symbols for “greater-than” is
fast.
• See Program 5.6 on P110 for implementation.
12
UMBC
Some sample program(I)
/** * The Table class is similar to java.util.Dictionary, * except that each key must be a Symbol and there is * a scope mechanism. */
public class Table {
private java.util.Dictionary dict = new java.util.Hashtable(); private Symbol top; private Binder marks;
public Table(){}
13
UMBC
Some sample program(II)
/** * Gets the object associated with the specified * symbol in the Table. */ public Object get(Symbol key) {
Binder e = (Binder)dict.get(key);if (e==null) return null;else return e.value;
}
/** * Puts the specified value into the Table, * bound to the specified Symbol. */ public void put(Symbol key, Object value) {
dict.put(key, new Binder(value, top, (Binder)dict.get(key)));
top = key; }
14
UMBC
Some sample program(III)
/** * Remembers the current state of the Table. */ public void beginScope() {marks = new Binder(null,top,marks); top=null;}
/** * Restores the table to what it was at the most recent * beginScope that has not already been ended. */ public void endScope() {
while (top!=null) { Binder e = (Binder)dict.get(top); if (e.tail!=null) dict.put(top,e.tail); else dict.remove(top); top = e.prevtop;}top=marks.prevtop;marks=marks.tail;
}
15
UMBC
Some sample program(IV)
package Symbol;
class Binder {
Object value;
Symbol prevtop;
Binder tail;
Binder(Object v, Symbol p, Binder t) {
value=v; prevtop=p; tail=t;
}
}
16
UMBC
Type-Checking in MiniJava
• Binding for type-checking in MiniJava– Variable and formal parameter
• Var name <-> type of variable
– Method• Method name <-> result type, parameters( including
position information), local variables
– Class• Class name <-> variables, method declaration, parent
class
17
UMBC
Symbol Table: example
See Figure 5.7 on page 111
• Primitive types– int -> IntegerType()– Boolean -> BooleanType()
• Other types– Int [] -> IntArrayType()– Class -> IdentifierType(String s)
18
UMBC
SymbolTable : Real Story
class SymbolTable { public SymbolTable(); public boolean addClass(String id, String parent); public Class getClass(String id); public boolean containsClass(String id); public Type getVarType(Method m, Class c, String
id); public Method getMethod(String id, String
classScope); public Type getMethodType(String id, String
classScope); public boolean compareTypes(Type t1, Type t2);}
19
UMBC
Be careful!
• getVarType(Method m, Class c, String id)– In c.m, find variable id– Local variable in method– Parameter in parameter list– Variable in the class– Variable in the parent class
• getMethod(), getMethodType()– May be defined in the parent Classes
• compareTypes()– Primitive types : int, boolean, IntArrayType– Subtype : IdentifierType
20
UMBC
SymbolTalbe : Class
class Class { public Class(String id, String parent); public String getId(); public Type type(); public boolean addMethod(String id, Type type); public Method getMethod(String id); public boolean containsMethod(String id); public boolean addVar(String id, Type type); public Variable getVar(String id); public boolean containsVar(String id); public String parent();}
21
UMBC
SymbolTable : Variable
class Variable{ public Variable(String id, Type type); public String id(); public Type type()}
22
UMBC
SymbolTable : Method
class Method { public Method(String id, Type type); public String getId(); public Type type(); public boolean addParam(String id, Type type); public Variable getParamAt(int i); public boolean getParam(String id); public boolean containsParam(String id); public boolean addVar(String id, Type type); public Variable getVar(String id); public boolean containsVar(String id);
23
UMBC
Type-Checking : Two Phase
• Build Symbol Table• Type-check statements and expressions
public class Main { public static void main(String [] args) { try { Program root = new MiniJavaParser(System.in).Goal();
BuildSymbolTableVisitor v1 = new BuildSymbolTableVisitor(); root.accept(v1);
root.accept(new TypeCheckVisitor(v1.getSymTab())); } catch (ParseException e) { System.out.println(e.toString()); } }}
24
UMBC
BuildSymbolTableVisitor();
• See Program 5.8 on Page 112
public class BuildSymbolTableVisitor extends TypeDepthFirstVisitor {
…. private Class currClass; private Method currMethod;…… // Type t; // Identifier i; public Type visit(VarDecl n) { Type t = n.t.accept(this); String id = n.i.toString();
25
UMBC
BuildSymbolTableVisitor(); - Cont’d
if (currMethod == null){ if (!currClass.addVar(id,t)){ System.out.println(id + "is already defined in "
+ currClass.getId()); System.exit(-1); }
} else { if (!currMethod.addVar(id,t)){ System.out.println(id + "is already defined in "
+ currClass.getId() + "." + currMethod.getId());
System.exit(-1); }
} return null;}
26
UMBCBuildSymbolTableVisitor() :TypeVisitor()
public Type visit(MainClass n); public Type visit(ClassDeclSimple n); public Type visit(ClassDeclExtends n); public Type visit(VarDecl n); public Type visit(MethodDecl n); public Type visit(Formal n); public Type visit(IntArrayType n); public Type visit(BooleanType n); public Type visit(IntegerType n); public Type visit(IdentifierType n);
27
UMBC
TypeCheckVisitor(SymbolTable);
• See Program 5.9 on page 113
package visitor;import syntaxtree.*;
public class TypeCheckVisitor extends DepthFirstVisitor {
static Class currClass; static Method currMethod; static SymbolTable symbolTable; public TypeCheckVisitor(SymbolTable s){
symbolTable = s; }
28
UMBCTypeCheckVisitor(SymbolTable); - Cont’d
// Identifier i;// Exp e;public void visit(Assign n) { Type t1 = symbolTable.getVarType(currMethod,currClass, n.i.toString()); Type t2 = n.e.accept(new TypeCheckExpVisitor() ); if (symbolTable.compareTypes(t1,t2)==false){
System.out.println("Type error in assignment to " +n.i.toString());
System.exit(0); }}
29
UMBC
TypeCheckExpVisitor()
package visitor;import syntaxtree.*;
public class TypeCheckExpVisitor extends TypeDepthFirstVisitor { // Exp e1,e2; public Type visit(Plus n) { if (! (n.e1.accept(this) instanceof IntegerType) ) { System.out.println("Left side of Plus must be of type
integer"); System.exit(-1); } if (! (n.e2.accept(this) instanceof IntegerType) ) { System.out.println("Right side of Plus must be of type
integer"); System.exit(-1); } return new IntegerType(); }
30
UMBC
TypeCheckVisitor : Visitor()
public void visit(MainClass n); public void visit(ClassDeclSimple n); public void visit(ClassDeclExtends n); public void visit(MethodDecl n); public void visit(If n); public void visit(While n); public void visit(Print n); public void visit(Assign n); public void visit(ArrayAssign n);
31
UMBC
TypeCheckExpVisitor() : TypeVisitor()
public Type visit(And n); public Type visit(LessThan n); public Type visit(Plus n); public Type visit(Minus n); public Type visit(Times n); public Type visit(ArrayLookup n); public Type visit(ArrayLength n); public Type visit(Call n); public Type visit(IntegerLiteral n); public Type visit(True n); public Type visit(False n); public Type visit(IdentifierExp n); public Type visit(This n); public Type visit(NewArray n); public Type visit(NewObject n); public Type visit(Not n);
32
UMBC
Overloading of Operators, ….
• When operators are overloaded, the compiler must explicitly generate the code for the type conversion.
• For an assignment statement, both sides have the same type. When we allow extension of classes, the right hand side is a subtype of lhs.
33
UMBC
Method Calls e.m(…)
• Lookup method in the SymbolTable to get parameter list and result type
• Find m in class e• The parameter types must be matched
against the actual arguments.• Result type becomes the type of the
method call as a whole.
• Etc, etc, …….
34
UMBC
Error Handling
• For a type error or an undeclared identifier, it should print an error message.
• And must go on…..
• Recovery from type errors?– Do as if it were correct.– Not a big deal in the examples we will examine
but the reality is bit more complicated.• What are some approaches the book mentions?
35
UMBC
References
• Modern Compiler Implementation in Java . 2nd Ed. A. Appel, Cambridge University Press, Chapter 5