Presentation is loading. Please wait.

Presentation is loading. Please wait.

CPSC 388 – Compiler Design and Construction

Similar presentations

Presentation on theme: "CPSC 388 – Compiler Design and Construction"— Presentation transcript:

1 CPSC 388 – Compiler Design and Construction
Symbol Tables and Static Checking

2 Compiler Design Lexical Analyzer Syntax Analyzer (Scanner)
(Parser) Symantic Analyzer Intermediate Code Generator Symbol Table Optimizer Code Generator

3 Introduction Parser ensures proper syntax but cannot (or does not) check for: A variable should not be declared more than once in the same scope. A variable should not be used before being declared. The type of the left-hand side of an assignment should match the type of the right-hand side. Methods should be called with the right number and types of arguments.

4 Static Semantic Analyzer
Traverses the Abstract Syntax Tree: For each scope in the program: Process the declarations, adding new entries to the symbol table and reporting any variables that are multiply declared; process the statements, finding uses of undeclared variables, and updating the "ID" nodes of the abstract-syntax tree to point to the appropriate symbol-table entry. Process all of the statements in the program again, using the symbol-table information to determine the type of each expression, and finding type errors.

5 Symbol Table Holds names declared in a program:
Classes Fields Methods Variables Each name in Symbol Table has attributes: Kind of name Type Nesting level Location at runtime

6 Scoping Rules Say when a program is allowed to reuse a name
Match use of a name with the corresponding declaration

7 Reusing Names in Java? class Test { int Test; void Test( ) { … }
also reuse names for more than one method as long as the number and/or types of parameters are unique

8 Reusing Names in C/C++ void f(int k) {
int x = 0; /* x is declared here */ while (...) { int x = 1; /* another x is declared */ ... if (...) { float x = 5.5; /*another x */ }

9 Matching Uses to Declarations
Static Scoping Determination of match made at compile time Dynamic Scoping Determination of match made at runtime Java, C, and C++ use Static Scoping

10 C and C++ Scoping Rules “Most Closely Nested” rule Scoping Levels
A use of variable x matches the declaration in the most closely enclosing scope such that the declaration precedes the use. Scoping Levels One outermost scope includes function names and global variables Each Function has one (or more) scopes One scope for parameters and “top-level” declarations One scope for each block in the function C++ has a scope for each for loop, i.e. you can declare variables in for-loop header

11 You Try It (What reuses are allowed in Java?)
class animal { // methods void attack(int animal) { for (int animal=0; animal<10; animal++) { int attack; } int attack(int x) { for (int attack=0; attack<10; attack++) { int animal; void animal() { } // fields double attack;

12 You Try It Match uses to declarations (in C++)
int k=10, x=20; void foo(int k) { int a = x; int x = k; int b = x; while (...) { int x; if (x == k) { int k, y; k = y = x; } int x = y;

13 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.

14 Example Dynamic Scoping
void main() { f1(); f2(); } void f1() { int x = 10; g(); void f2() { String x = "hello"; f3(); void f3() { double x = 30.5; void g() { print(x); Output: “10 hello”

15 You Try It: What is Output?
void main() { int x = 0; f1(); g(); f2(); } void f1() { int x = 10; void f2() { int x = 20; void g() { print(x);

16 Using Names Before Defining (in Java)
class Test { void f() { val = 0; g(); x = 1; int x; } void g() {} int val; // field val has not yet been declared -- OK // method g has not yet been declared -- OK // variable x has not yet been declared -- ERROR!

17 Scoping in Our (C--) Language
uses static scoping requires that all names be declared before they are used does not allow multiple declarations of a name in the same scope (even for different kinds of names) does allow the same name to be declared in multiple nested scopes (but only once per scope) uses the same scope for a method's parameters and for the local variables declared at the beginning of the method

18 Symbol Table Given a declaration of a name, is there already a declaration of the same name in the current scope (i.e., is it multiply declared)? Given a use of a name, to which declaration does it correspond (using the "most closely nested" rule), or is it undeclared?

19 Symbol Table Operations
Look up a name in the current scope only (to check if it is multiply declared). Look up a name in the current and enclosing scopes (to check for a use of an undeclared name, and to link a use with the corresponding symbol-table entry). Insert a new name into the symbol table with its attributes. Do what must be done when a new scope is entered. Do what must be done when a scope is exited.

20 Symbol Table Entries in Table Use List of Hashtables Symbol Name Type
Nesting Level of declaration Use List of Hashtables Declarations In S Declarations made in scopes That enclose S

21 Example Symbol Table void f(int a, int b) { double x; while (...) {
int x, y; ... } void g() { f(); x: int, 3 y: int, 3 a: int, 2 b: int, 2 x: double, 2 f: (int, int), 1 g: (), 1

22 Operations Performed during Scope Analysis
On scope entry: increment the current level number and add a new empty hashtable to the front of the list. To process a declaration of x: look up x in the first table in the list. If it is there, then issue a "multiply declared variable" error; otherwise, add x to the first table in the list. To process a use of x: look up x starting in the first table in the list; if it is not there, then look up x in each successive table in the list. If it is not in any table then issue an "undeclared variable" error. On scope exit, remove the first table from the list and decrement the current level number.

23 Type Checking Determine the type of each expression in the program (each node in the AST that corresponds to an expression). Find type errors.

24 Type Rules specify, for every operator (including assignment), what types the operands can have, and what is the type of the result. Examples: Addition of int and double: result double (in java and C++) Assignment of double to int: C++ OK, Java error

25 Table of Operators and Types (in Java)
1st Operand 2nd Operand Result + int double = && boolean <

26 Context Method Call Type Errors
Context Type Errors the condition of an if statement the condition of a while loop the termination condition part of a for loop Method Call Type 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

Download ppt "CPSC 388 – Compiler Design and Construction"

Similar presentations

Ads by Google