Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 15 (Notes by P. N. Hilfinger and R. Bodik)

Similar presentations


Presentation on theme: "Lecture 15 (Notes by P. N. Hilfinger and R. Bodik)"— Presentation transcript:

1 Lecture 15 (Notes by P. N. Hilfinger and R. Bodik)
Static Semantics Lecture 15 (Notes by P. N. Hilfinger and R. Bodik) 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

2 Prof. Hilfinger, CS164 Lecture 15
Current Status Lexical analysis Produces tokens Detects & eliminates illegal tokens Parsing Produces trees Detects & eliminates ill-formed parse trees Static semantic analysis we are here Produces “decorated tree” with additional information attached Detects & eliminates remaining static errors 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

3 Prof. Hilfinger, CS164 Lecture 15
Static vs. Dynamic We use the term static to describe properties that the compiler can determine without considering any particular execution. E.g., in def f(x) : x + 1 Both uses of x refer to same variable Dynamic properties are those that depend on particular executions in general. E.g., will x = x/y cause an arithmetic exception. 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

4 Static vs. Dynamic, contd.
Actually, distinction is not that simple. E.g., after x = 3 y = x + 2 compiler could deduce that x and y are Ints But languages often designed to require that we treat variables only according to explicitly declared types, because deductions are difficult or impossible in general. 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

5 Typical Tasks of the Semantic Analyzer
Find the declaration that defines each identifier instance Determine the static types of expressions Perform re-organizations of the AST that were inconvenient in parser, or required semantic information Detect errors and fix to allow further processing 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

6 Typical Semantic Errors: Java, C++
Multiple declarations: a variable should be declared (in the same region) at most once Undeclared variable: a variable should not be used before being declared. Type mismatch: type of the left-hand side of an assignment should match the type of the right-hand side. Wrong arguments: methods should be called with the right number and types of arguments. Definite-assignment check (Java): conservative check that simple variables assigned to before use. 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

7 Output from Static Semantic Analysis
Input is AST; output is an annotated tree. x = 3 def f (x): return x+y y: Int y = 2 = def type_decl = x 3 f return y Int y 2 #1 #2 #4 #4 Int Int #1: x, Any, 0 #2: f, Any->Any, 0 #3: x, Any, 1 #4: y, Int, 0 x #3 + Any x #3 y #4 Ids decorated with declarations. Expressions annotated with (static) types. 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

8 Output from Static Semantic Analysis (II)
Analysis has added objects we’ll call “symbol entries” to hold information about instances of identifiers. In this example, #1: x, Any, 0 denotes an entry for something named x occurring at the outer lexical level (level 0) and having static type Any. For other expressions, we annotate with static type information. 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

9 Output from Static Semantic Analysis (III)
Symbol entries for classes (or modules, packages, namespaces and the like) must contain equivalent of a dictionary mapping names of members to symbol entries. So given an expression such as x.clear (), we find symbol entry for x find type (class) of x from its entry, and find clear in dictionary of entry associated with x’s type. 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

10 Binding names to symbol entries: Scoping
Scope of a declaration: section of text where it applies Declarative region: section of text that bounds scopes of declarations (we’ll say “region” for short) In most languages, the same name can be declared multiple times if its declarations occur in different declarative regions, and/or involve different kinds of names. 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

11 Prof. Hilfinger, CS164 Lecture 15
Scoping: example Java: can use same name for a class, field of the class, a method of the class, and a local variable of the method legal Java program: class Test { int Test; Test( ) { double Test; } } 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

12 Scoping: general rules
The scope rules of a language: determine which declaration of a named object corresponds to each use of the object. Scoping rules map uses of objects to their declarations (or symbol entries). C++ and Java use static scoping: mapping from uses to declarations is made at compile time. C++ uses “Algol scope rules” a use of variable x matches the declaration with the most closely enclosing scope. a deeply nested variable x hides x declared in an outer region. in Java: inner regions cannot define variables defined in outer regions 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

13 Scoping Options: Declarative Regions
In Java, each function has one or more declarative regions: one for the function body, and possibly additional regions in the function for each for loop and each nested block (delimited by curly braces) In Pyth, each function has one per function (possibly plus more for nested functions) 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

14 Example (assume C++ rules)
double y, k; // y and k global variables void f(int y) { // y also used as a parameter y = k; // Uses global k and parameter y int k = 0; // k is now local variable while (k) { // refers to 2nd decl of k int k = 1; // another local var, in a loop (not ok in Java) } the outermost region includes decls of "f”, “k” and “y” function f itself has two (nested) regions: The outer region for f includes parameter y and local variable k . The innermost region is for the body of the while loop, and includes the variable k that is initialized to 1. global k hidden starting here 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

15 Scoping Options: overloading
Java and C++ (but not in Pascal, C, or Pyth): can use the same name for more than one method as long as the number and/or types of parameters are unique. int add(int a, int b); float add(float a, float b); 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

16 Scoping options: Use before declaration?
Can names be used before they are defined? Java, C++: a method or field name can be used before the definition appears; not true for a variable, whose scope starts at its declaration In Pyth, almost anything can be used before declaration, where syntactically possible 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

17 Scoping Options: Dynamic scoping
Not all languages use static scoping. Original Lisp, APL, and Snobol use dynamic scoping. 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. With this rule, difficult for compiler to determine much about identifiers 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

18 Prof. Hilfinger, CS164 Lecture 15
Example For example, consider the following code: void main() { f1(); f2(); } void f1() { int x = 10; g(); } void f2() { String x = "hello"; f3();g(); } void f3() { double x = 30.5; } void g() { print(x); } With static scoping, illegal. With dynamic scoping, prints 10 and hello 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

19 So How do we Annotate with Declarations?
Idea is to recursively navigate the AST, in effect executing the program in simplified fashion, extracting information that isn’t data dependent. You saw it in CS61A (sort of). 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

20 Environment Diagrams and Symbol Entries
In Scheme, a program like (set! x 7) (define (f x) (let ((y (+ x 39)) (+ x y))) (f 3) when executed would eventually give you something like this when computing (+ x y) X: 7 f: … y: 42 current environment x: 3 global environment 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

21 Environment Diagrams to Symbol Entries
Abstracting from this particular execution, X: 7 f: … y: 42 current environment x: 3 we take away the values and replace with static info: current environment #1. X: Any #2. f: Any->Any #4. y: Any #3. x: Any … and we’re left with symbol entries and a data structure (a kind of symbol table) for looking them up. 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

22 Annotating Pyth with Symbol Entries
Process requires several passes (traversals of AST). A rough outline: Create symbol entries for all classes and record in global environment, plus entries for all class members stored in the class’s entries. For each declarative region, Create a new environment box for each declaration immediately inside the region. Use it to annotate all uses, and recursively do step 2 for all inner declarative regions. 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

23 Prof. Hilfinger, CS164 Lecture 15
Type Checking the job of the type-checking phase is to: Determine the type of each expression in the program (each node in the AST that corresponds to an expression) Find type errors The type rules of a language define how to determine expression types, and what is considered to be an error. The type rules specify, for every operator (including assignment), what types the operands can have, and what is the type of the result. 11/29/2018 Prof. Hilfinger, CS164 Lecture 15

24 Prof. Hilfinger, CS164 Lecture 15
Type Errors The type checker must also find type errors having to do with the context of expressions, e.g., the context of some operators must be boolean, type errors having to do with method calls. Examples of the context errors: the condition of an if not boolean (Java) type of returned value not function’s return type Examples of method 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 11/29/2018 Prof. Hilfinger, CS164 Lecture 15


Download ppt "Lecture 15 (Notes by P. N. Hilfinger and R. Bodik)"

Similar presentations


Ads by Google