0% found this document useful (0 votes)
39 views5 pages

Lecture10 2x2

This document discusses static semantic analysis which is performed after parsing to detect errors and add type information. It covers typical tasks like type checking, scope rules, and handling classes and objects. Static semantic analysis takes the parse tree as input and produces a decorated tree with additional semantic information as output.

Uploaded by

mbilalarshad
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views5 pages

Lecture10 2x2

This document discusses static semantic analysis which is performed after parsing to detect errors and add type information. It covers typical tasks like type checking, scope rules, and handling classes and objects. Static semantic analysis takes the parse tree as input and produces a decorated tree with additional semantic information as output.

Uploaded by

mbilalarshad
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

Lecture 10: Static Semantics Overview1 Static vs.

Dynamic

• Lexical analysis • We use the term static to describe properties that the compiler can
determine without considering any particular execution.
– Produces tokens
– E.g., in
– Detects & eliminates illegal tokens
def f(x) : x + 1
• Parsing
Both uses of x refer to same variable
– Produces trees
• Dynamic properties are those that depend on particular executions
– Detects & eliminates ill-formed parse trees in general.
• Static semantic analysis ⇐= we are here – E.g., will x = x/y cause an arithmetic exception?
– Produces decorated tree with additional information attached • Actually, distinction is not that simple. E.g., after
– Detects & eliminates remaining static errors
x = 3
y = x + 2
compiler could deduce that x and y are integers.
• But languages often designed to require that we treat variables only
according to explicitly declared types, because deductions are dif-
ficult or impossible in general.
1
From material by R. Bodik and P. Hilfinger
Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 1 Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 2

Typical Tasks of the Semantic Analyzer Typical Semantic Errors: Java, C++

• Find the declaration that defines each identifier instance • Multiple declarations: a variable should be declared (in the same
region) at most once
• Determine the static types of expressions
• Perform re-organizations of the AST that were inconvenient in parser, • Undeclared variable: a variable should not be used without being
declared.
or required semantic information
• Detect errors and fix to allow further processing • Type mismatch: e.g., 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.

Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 3 Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 4
Output from Static Semantic Analysis Output from Static Semantic Analysis (II)

Input is AST; output is an annotated tree: identifiers decorated with • Analysis has added objects we’ll call symbol entries to hold informa-
declarations, other expressions with type information. tion about instances of identifiers.
x = 3 • In this example, #1: x, Any, 0 denotes an entry for something
def f (x): stmt list
named ‘x’ occurring at the outer lexical level (level 0) and having
return x+y static type Any.
y = 2 = def =
• For other expressions, we annotate with static type information.
x: #1 3: Int f: #2 id list return y: #4 2: Int

x: #3 +: Any

Id Type Nesting x: #3 y: #4
#1: x, Any, 0
#2: f, Any->Any, 0
#3: x, Any, 1
#4: y, Any, 0

Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 5 Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 6

Output from Static Semantic Analysis: Classes Scope Rules: Binding Names to Symbol Entries

• In Python (dynamically typed), can write • Scope of a declaration: section of text or program execution in
class A(object): which declaration applies
def f(self): return self.x • Declarative region: section of text or program execution that bounds
scopes of declarations (we’ll say “region” for short).
a1 = A(); a2 = A() # Create two As
a1.x = 3; print a1.x # OK • If scope of a declaration defined entirely according to its position
print a2.x # Error; there is no x in source text of a program, we say language is statically scoped.
so can’t say much about attributes (fields) of A. • If scope of a declaration depends on what statements get executed
• In Java, C, C++ (statically typed), analogous program is illegal, even during a particular run of the program, we say language has dynami-
without second print (the class definition itself is illegal). cally scoped.

• So in statically typed languages, symbol entries for classes would


contain dictionaries mapping attribute names to types.

Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 7 Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 8
Scope Rules: Name=⇒Declaration is Many-to-One Scope Rules: Nesting

• In most languages, can declare the same name multiple times, if its • Most statically scoped languages (including C, C++, Java) use:
declarations
Algol scope rule: Where multiple declarations might apply,
– occur in different declarative regions, or choose the one defined in the innermost (most deeply nested)
– involve different kinds of names. declarative region.
– Examples from Java?, C++? • Often expressed as “inner declarations hide outer ones.”
• Variations on this: Java disallows attempts to hide local variables
and parameters.

Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 9 Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 10

Scope Rules: Declarative Regions Scope Rules: Use Before Definition

• Languages differ in their definitions of declarative regions. • Languages have taken various decisions on where scopes start.
• In Java, variable declaration’s effect stops at the closing ‘}’, that • In Java, C++, scope of a member (field or method) includes the en-
is, each function body is a declarative region. tire class (textual uses may precede declaration).
• What others? • But scope of a local variable starts at its declaration.
• In Python, function header and body make up a declarative region, • As for non-member and class declarations in C++: must write
as does a lambda expression. But nothing smaller. Just one x in this
extern int f(int); // Forward declarations
program:
class C;
def f(x): int x = f(3) // Would be illegal w/o forward decls.
x = 3 void g(C* x) {
L = [x for x in xrange(0,10)] ...
}

int f (int x) { ... } // Full definitions


class C { ... }

Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 11 Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 12
Scope Rules: Overloading Dynamic Scoping

• In Java or C++ (not Python or C), can use the same name for more • Original Lisp, APL, Snobol use dynamic scoping, rather than static:
than one method, as long as the number or types of parameters are
Use of a variable refers to most recently executed, and
unique.
still active, declaration of that variable.
int add(int a, int b); float add(float a, float b);
• Makes static determination of declaration generally impossible.
• The declaration applies to the signature —name + argument types— • Example:
not just name.
void main() { f1(); f2(); }
• But return type not part of signature, so this won’t work: void f1() { int x = 10; g(); }
void f2() { String x = "hello"; f3();g(); }
int add (int a, int b); float add (int a, int b)
void f3() { double x = 30.5; }
• In Ada, it will, because the return type is part of signature. void g() { print(x); }

• With static scoping, illegal.


• With dynamic scoping, prints “10” and “hello”

Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 13 Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 14

Explicit vs. Implicit Declaration So How Do We Annotate with Declarations?

• Java, C++ require explicit declarations of things. • Idea is to recursively navigate the AST,
• C is lenient: if you write foo(3) with no declaration of foo in scope, – in effect executing the program in simplified fashion,
C will supply one. – extracting information that isn’t data dependent.
• Python implicitly declares variables you assign to in a function to be • You saw it in CS61A (sort of).
local variables.
• Fortran implicitly declares any variables you use, and gives them a
type depending on their first letter.
• But in all these cases, there is a declaration as far as the compiler
is concerned.

Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 15 Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 16
Environment Diagrams and Symbol Entries

• In Scheme, executing
(set! x 7)
(define (f x) (let ((y (+ x 39)) (+ x y)))
(f 3)

would eventually give this environment at (+ x y):

global x: 7 current
x: 3 y: 42
environment f: . . . environment

• Now abstract away values in favor of static type info:

#1. x: Any
#3. x: Any #4. y: Any
#2. f: Any→Any

• and voila! A data structure for mapping names to current declara-


tions: a block-structured symbol table.

Last modified: Mon Feb 23 14:39:08 2009 CS164: Lecture #10 17

You might also like