1 / 38

Compiler Construction Semantic Analysis II

Compiler Construction Semantic Analysis II. Ran Shaham and Ohad Shacham School of Computer Science Tel-Aviv University. PAs. PA2 Deadline extension Dec 29 Fix PA1 grader’s notes in your IC.lex PA1 Escape characters should stay as they are &lt;STRING&gt; <br> { str.append(“<br>”) }.

Télécharger la présentation

Compiler Construction Semantic Analysis II

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Compiler ConstructionSemantic Analysis II Ran Shaham and Ohad Shacham School of Computer Science Tel-Aviv University

  2. PAs • PA2 • Deadline extension Dec 29 • Fix PA1 grader’s notes in your IC.lex • PA1 • Escape characters should stay as they are • <STRING> \\n { str.append(“\n”) }

  3. x86 executable exe ICProgram ic IC compiler Compiler We saw: • Scope • Symbol tables LexicalAnalysis Syntax Analysis Parsing AST SymbolTableetc. Inter.Rep.(IR) CodeGeneration Today: • Type checking • Recap

  4. assigned type doesn’t match declared type relational operator applied to non-int type a is not a subtype of b argument list doesn’t match formal parameters Examples of type errors 1 < true int a; a = true; class A {…}class B extends A { void foo() { A a; B b; b = a; }} void foo(int x) { int x; foo(5,7);}

  5. Types • Type • Set of values computed during program execution • boolean = {true,false} • int = {-232,232} • void = {} • Type safety • Types usage adheres formally defined typing rules

  6. Type judgments • e : T • Formal notation for type judgments • e is a well-typed expression of type T • 2 : int • 2 * (3 + 4) : int • true : bool • “Hello” : string

  7. Type judgments • E e : T • Formal notation for type judgments • In the context E,e is a well-typed expression of T • b:bool, x:int  b:bool • x:int  1 + x < 4:bool • foo:int->string, x:int  foo(x) : string • Type context • set of type bindings id : T (symbol table)

  8. Typing rules Premise [Name] Conclusion Axioms [Name] Conclusion

  9. Typing rules for expressions E e1 : int E e2 : int [+] E e1+e2 : int AST leaves E true : bool E false : bool E int-literal : int E string-literal : string E  null : null E new T() : T

  10. Some IC expression rules 1 E  true : bool E  false : bool E int-literal : int E string-literal : string E  e1 : int E  e2 : int op  { +, -, /, *, %} E  e1 op e2 : int E  e1 : int E  e2 : int rop { <=,<, >, >=} E  e1 rop e2 : bool E  e1 : T E  e2 : T rop { ==,!=} E  e1 rop e2 : bool

  11. Some IC expression rules 2 E  e1 : bool E  e2 : bool lop  { &&,|| } E  e1 lop e2 : bool E  e1 : int E  e1 : bool E - e1 : int E ! e1 : bool E  e1 : T[] E  e1 : T[] E  e2 : int E  e1 : int E  e1[e2] : T E  e1.length : int E new T[e1] : T[] id : T  E E  id : T E new T() : T

  12. Type-checking algorithm • Construct types • Add basic types to type table • Traverse AST looking for user-defined types (classes,methods,arrays) and store in table • Bind all symbols to types • Traverse AST bottom-up (using visitor) • For each AST node find corresponding rule(there is only one for each kind of node) • Check if rule holds • Yes: assign type to node according to consequent • No: report error

  13. E  e1 : bool E  e2 : bool E  e1 lop e2 : bool lop  { &&,|| } E  e1 : bool E  e1 : int E  e2 : int E  !e1 : bool E  e1 rop e2 : bool rop  { <=,<, >, >=} E false : bool intLiteral intLiteral boolLiteral E int-literal : int val=false val=45 val=32 Algorithm example … BinopExpr : bool op=AND : bool : bool BinopExpr UnopExpr op=GT op=NEG : int : int : bool 45 > 32 && !false

  14. Type-checking visitor class TypeChecker implements PropagatingVisitor<Type,SymbolTable> { public Type visit(ArithBinopExp e, SymbolTable symtab) throws Exception { Type lType = e.left.accept(this, symtab); Type rType = e.right.accept(this, symtab); if (lType != TypeTable.intType()) throw new TypeError(“Expecting int type, found “ + lType.toString(), e.getLine); if (rType != TypeTable.intType) throw new TypeError(“Expecting int type, found “ + rType.toString(), e.getLine); // we only get here if no exceptions were thrown e.type = TypeTable.intType; } ...}

  15. E  e:bool E  S1 E S2 E  e:bool E  e:bool E  S E  S E if (e) S1 else S2 E while (e) S E if (e) S E break E continue Statement rules • Statements have type void • Judgments of the form E  S • In environment E, S is well-typed

  16. T subtype of T’ Checking return statements • Special entry {ret:Tr} represents return value • Add to symbol table when entering method • Lookup entry when hit return statement E  e:T ret:T’E T≤T’ ret:void  E E return e; E return;

  17. Subtyping • Inheritance induces subtyping relation • Type hierarchy is a tree • Subtyping rules: • Subtyping does not extend to array types • A subtype of B then A[] is not a subtype of B[]

  18. E  e : S S ≤ T E  e : T Type checking with subtyping • S ≤ T • S may be used whenever T is expected • An Expression E from type S also has type T

  19. IC rules with subtyping E  e1 : T1 E  e2 : T2 T1 ≤ T2 or T2 ≤ T1op {==,!=} E  e1 op e2 : bool

  20. Semantic analysis flow • Parsing and AST construction • Combine library AST with IC program AST • Construct and initialize global type table • Phase 1: Symbol table construction • Construct class hierarchy and check that hierarchy is a tree • Construct remaining symbol table hierarchy • Assign enclosing-scope for each AST node • Phase 2: Scope checking • Resolve names • Check scope rules using symbol table • Phase 3: Type checking • Assign type for each AST node • Phase 4: Remaining semantic checks

  21. Class hierarchy for types abstract class Type {...}class IntType extends Type {...}class BoolType extends Type {...}class ArrayType extends Type { Type elemType;}class MethodType extends Type { Type[] paramTypes; Type returnType; ... }class ClassType extends Type { ICClass classAST; ...}...

  22. Type comparison • Option 1: use a unique object for each distinct type • Resolve each type expression to same object • Use reference equality for comparison (==) • Option 2: implement a method t1.equals(t2) • Perform deep (structural) test • For object-oriented languages also need sub-typing: t1.subtypeof(t2)

  23. Type table implementation class TypeTable { // Maps element types to array types private Map<Type,ArrayType> uniqueArrayTypes; private Map<String,ClassType> uniqueClassTypes; public static Type boolType = new BoolType(); public static Type intType = new IntType(); ... // Returns unique array type object public static ArrayType arrayType(Type elemType) { if (uniqueArrayTypes.containsKey(elemType)) { // array type object already created – return it return uniqueArrayTypes.get(elemType); } else { // object doesn’t exist – create and return it ArrayType arrt = new ArrayType(elemType); uniqueArrayTypes.put(elemType,ArrayType); return arrt; } } ... }

  24. Recap

  25. Semantic analysis flow example class A { int x; int f(int x) { boolean y; ... }}class B extends A { boolean y; int t;}class C { A o; int z;}

  26. Parsing and AST construction AST Programfile = … class A { int x; int f(int x) { boolean y; ... }}class B extends A { boolean y; int t;}class C { A o; int z;} parser.parse() classes[2] classes[0] classes[1] … ICClassname = Bsuper = A ICClassname = C ICClassname = A fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … body parameters[0] DeclarationvarName = yinitExpr = nulltype = BoolType Paramname = xtype = IntType TypeTable IntTypeBoolTypeABCf : int->int… Table populated with user-defined types during parsing(or special AST pass)

  27. Defined types and type table abstract class Type { String name; boolean subtypeof(Type t) {...}}class IntType extends Type {...}class BoolType extends Type {...}class ArrayType extends Type { Type elemType;}class MethodType extends Type { Type[] paramTypes; Type returnType;}class ClassType extends Type { ICClass classAST;} class A { int x; int f(int x) { boolean y; ... }}class B extends A { boolean y; int t;}class C { A o; int z;} class TypeTable { public static Type boolType = new BoolType(); public static Type intType = new IntType(); ... public static ArrayType arrayType(Type elemType) {…} public static ClassType classType(String name, String super, ICClass ast) {…} public static MethodType methodType(String name,Type retType, Type[] paramTypes) {…}} TypeTable IntTypeBoolTypeABCf : int->int…

  28. Assigning types by declarations AST All type bindings available during parsing time Programfile = … classes[2] classes[0] classes[1] … ICClassname = Bsuper = A ICClassname = C ICClassname = A TypeTable type IntTypeBoolType ... fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … ClassTypename = C type body parameters[0] ClassTypename = B DeclarationvarName = yinitExpr = nulltype = BoolType type Paramname = xtype = IntType super ClassTypename = A type MethodTypename = fretTypeparamTypes

  29. Symbol tables Global symtab AST Programfile = … classes[2] classes[0] classes[1] … A symtab C symtab ICClassname = Bsuper = A ICClassname = C ICClassname = A fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … f symtab B symtab body parameters[0] DeclarationvarName = yinitExpr = nulltype = BoolType Paramname = xtype = IntType abstract class SymbolTable { private SymbolTable parent;}class ClassSymbolTable extends SymbolTable { Map<String,Symbol> methodEntries; Map<String,Symbol> fieldEntries; }class MethodSymbolTable extends SymbolTable { Map<String,Symbol> variableEntries;} abstract class Symbol { String name;}class VarSymbol extends Symbol {…} class LocalVarSymbol extends Symbol {…}class ParamSymbol extends Symbol {…}...

  30. Scope nesting in IC class GlobalSymbolTable extends SymbolTable {}class ClassSymbolTable extends SymbolTable {}class MethodSymbolTable extends SymbolTable {}class BlockSymbolTable extends SymbolTable {} Global names of all classes Class fields and methods Method formals + locals Block variables defined in block

  31. Symbol tables Global symtab AST Programfile = … classes[2] classes[0] classes[1] … A symtab C symtab ICClassname = Bsuper = A ICClassname = C ICClassname = A fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … f symtab B symtab body parameters[0] DeclarationvarName = yinitExpr = nulltype = BoolType Paramname = xtype = IntType this belongs to method scope … Locationname = xtype = ? ret can be used later for type-checking return statements

  32. Sym. tables phase 1 : construction Global symtab AST enclosingScope Programfile = … classes[2] classes[0] classes[1] … A symtab C symtab ICClassname = Bsuper = A ICClassname = C ICClassname = A fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … f symtab B symtab body parameters[0] DeclarationvarName = yinitExpr = nulltype = BoolType Paramname = xtype = IntType Build tables,Link each AST node to enclosing table … ? Locationname = xtype = ? symbol abstract class ASTNode { SymbolTable enclosingScope;} class TableBuildingVisitor implements Visitor { ...}

  33. Sym. tables phase 1 : construct Global symtab AST Programfile = … classes[2] classes[0] classes[1] … A symtab C symtab ICClassname = Bsuper = A ICClassname = C ICClassname = A fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … f symtab B symtab body parameters[0] DeclarationvarName = yinitExpr = nulltype = BoolType Paramname = xtype = IntType During this phase, add symbols from definitions, not uses, e.g., assignment to variable x … ? Locationname = xtype = ? symbol class TableBuildingVisitor implements Visitor { ...}

  34. Sym. tables phase 2 : resolve Global symtab AST Programfile = … classes[2] classes[0] classes[1] … A symtab C symtab ICClassname = Bsuper = A ICClassname = C ICClassname = A fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … f symtab B symtab body parameters[0] DeclarationvarName = yinitExpr = nulltype = BoolType Paramname = xtype = IntType Resolve each id to a symbol,e.g., in x=5 in foo, x is the formal parameter of f … Locationname = xtype=? symbol check scope rules:illegal symbol re-definitions,illegal shadowing,illegal use of undefined symbols... enclosingScope class SymResolvingVisitor implements Visitor { ...}

  35. Type-check AST AST Programfile = … TypeTable classes[2] IntTypeBoolType ... classes[0] classes[1] … ICClassname = Bsuper = A ICClassname = C ICClassname = A fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … body parameters[0] DeclarationvarName = yinitExpr = nulltype = BoolType Paramname = xtype = IntType Use type-rules to infer types for all AST expression nodes Check type rules for statements … Locationname = xtype = IntType class TypeCheckingVisitor implements Visitor { ...}

  36. Miscellaneous semantic checks AST Programfile = … classes[2] classes[0] classes[1] … ICClassname = Bsuper = A ICClassname = C ICClassname = A fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … body parameters[0] DeclarationvarName = yinitExpr = nulltype = BoolType Paramname = xtype = IntType Check remaining semantic checks: single main method, break/continue inside loops etc. … Locationname = xtype = IntType class SemanticChecker { ...}

  37. public Type visit(While whileStatement) { Type conditionType = whileStatement.getCondition().accept(this); whileStatement.setType(PrimitiveTypes.VOID); if (conditionType != PrimitiveTypes.BOOLEAN) Error ++loopDepth; whileStatement.getOperation().accept(this); --loopDepth; returnnull; }

  38. public Type visit(Break breakStatement) { if (loopDepth == 0) error; setType(PrimitiveTypes.VOID); returnnull; }

More Related