Presentation is loading. Please wait.

Presentation is loading. Please wait.

Bernd Fischer RW713: Compiler and Software Language Engineering.

Similar presentations


Presentation on theme: "Bernd Fischer RW713: Compiler and Software Language Engineering."— Presentation transcript:

1 Bernd Fischer bfischer@cs.sun.ac.za RW713: Compiler and Software Language Engineering

2 Contextual Analysis

3 Appel’s view of a compiler

4 Contextual Analysis “Semantic” Analysis is a misnomer –context-sensitive syntax Determine whether program is well-formed –scope rules(i.e., visibility) –type rules(i.e., compatibility) Two phases –name resolution- what does an identifier refer to? –type checking- can you do that with it?

5 Name Resolution Nested block structure  multiple scope levels Match identifier use with corresponding declaration: int i, j;... void f(int k) { char i;... for (int i = 0; i < 10; i++){... if (i > 5) {...} } i = “a”; }... j = i + 1;

6 Names vs. Symbols Operations on strings are expensive –comparison, hashing, … Instead: –enter all names into common area (lexeme pool) –can be done by lexer –work with symbols

7 Representing Symbols package Symbol; public class Symbol { private String name; private Symbol(String n) { name = n; } private static java.util.Dictionary pool = new java.util.Hashtable(); public String toString() { return name; } public static Symbol toSymbol(String n) { String u = n.intern(); Symbol s = (Symbol) pool.get(u); if (s == null) { s = new Symbol(u); pool.put(u,s); } return s; }

8 Symbol Tables Mapping symbols (identifiers) ↦ attributes –constant:type, value, … –variable:type, pointer to declaration, … –method:return and argument types, modifiers, … –class: pointer to (public) symbol table, … Also called environments = set of bindings Must cope with –nested scopes:block structure –parallel scopes:multiple name spaces Efficiency is important (but not paramount…) –lookup is most common operation

9 Symbol Table Interface public class Table { public Table(); public void put(Symbol key, Object value); public Object get(Symbol key); public void beginScope(); public void endScope(); public java.util.Enumeration keys(); }

10 Symbol Table Implementation Use hash table for efficiency –allow multiple entries with same key (external chaining) New binding for identifier x added to head of list for hash table bucket –“hides” earlier occurrences Uses auxiliary stack to implement “undo”: –beginScope() pushes marker onto stack –subsequent entries recorded on stack –endScope() pops symbols from stack, removes binding from table.

11 Hyperscope Standard Environment –standard collection of types, functions, etc. –can be used without declaration / import –e.g., built-in Pascal-functions, java.lang Initialize symbol table with these –at outermost scope level –watch for re-definitions (if required by language)

12 Multiple Name Spaces In many languages, a single symbol table is not sufficient: Solutions: –change symbol table type: Tag*Symbol public void put(Tag tbl, Symbol key, Object value); public Object get(Tag tbl, Symbol key); –separate tables for types and variables let type a = int var a : a = 5 var b : a = a in... end Type and variable declaration must be visible at same time!

13 Multiple Name Spaces (2) Modules/classes have separate name spaces –accessible by qualification / import –separate tables for each compilation unit class A { public static int x = 2; } class B { public static int x = A.x; } class Test { public static void main(String[] args) { System.out.println(""+(A.x + B.x)); }

14 Multiple Name Spaces (2) Modules/classes have separate name spaces –accessible by qualification / import –separate tables for each compilation unit Separate compilation requires persistent symbol tables –Modula-2:.sym -files –C: delayed to linker, no real error check

15 Type Checking Checking that identifiers are used correctly (i.e. in accordance with their [declared] type) Statically-typed languages –(Fortran, C), Ada, C++, Java, ML, Haskell,… –types always known at compile time Dynamically-typed languages –Lisp, Scheme, Smalltalk, Python, … –types determined at run time int x; void f() { f = x(2); }

16 Type Checking (2) Recursive walk over tree Uses current environment | AssignmentStmt | | Variable Expression –look up type of Variable –check and determine type of Expression –check for compatibility Compatibility rules –subtyping –coercion: insert operations to enforce compatibility

17 Type Checking Function Calls Type of greater is int x int  boolean To check applied occurrence: –look up greater in symbol table –check types of actual parameters match –result type of function (boolean) becomes result type of function call boolean greater (int x, int y){ return (x > y); }... if (greater(a, b)) {... }

18 Name-Binding Languages

19 Type Systems

20 Structural Operational Semantics

21 Reference Attribute Grammars

22 NaBL (Name Binding Language) domain-specific language to describe scope rules part of compiler-generation tool suite (Spoofax) compiled into name resolution algorithm semantics based on scope graphs

23 Definitions and References

24 Unique and Non-Unique Definitions

25 Namespaces

26 Scope

27 C# Namespaces are Scopes

28 Imports

29 Interaction with Type System (1)

30 Interaction with Type System (2)

31 Interaction with Type System (3)

32 NaBL use cases static checking editor services transformation refactoring code generation

33 NaBL use cases – reference resolution

34

35 NaBL use cases – code completion


Download ppt "Bernd Fischer RW713: Compiler and Software Language Engineering."

Similar presentations


Ads by Google