Title: CS571: Programming Languages
1CS571 Programming Languages
Semantic Elements I 10/15/2008
2Logistics
- Lecturer at a conference on the coming Wednesday.
No Class. - The coming Friday at graduate seminar, I will
talk about a project in the realm of multi-core
programming. - The Flex/Bison assignment will be due Sunday
night. - The next assignment will be given out Monday
morning. - Mid-term 2 will be soon! Stay tuned.
3A Review
Understanding Compilation Phases Backwards
4Phase of Compilation
Source program
Intermediate code generation
Lexical analysis
Parsing
Code optimizations
Semantic Analysis (e.g. type checking)
Final code generation
Target program
5Intermediate Code Generation
- loadint m
- loadimmed 0
- intequal
- jmpz .L1
- jmp .L2
- .L1
- . Code for S1
- jmp .L3
- .L2
- . Code for S2
- jmp .L3
- .L3
If-then-else
boolean
AST for S1
AST for S2
minteger
0integer
6Parsing
-
- include ltstdio.hgt
-
- token TOK_SEMICOLON TOK_ADD TOK_SUB TOK_MUL
TOK_DIV TOK_NUM TOK_PRINTLN - union
- int int_val
-
- type ltint_valgt expr TOK_NUM
- left TOK_ADD TOK_SUB
- left TOK_MUL TOK_DIV
7Parsing
- stmt
- stmt expr_stmt
-
- expr_stmt expr TOK_SEMICOLON
- TOK_PRINTLN expr TOK_SEMICOLON
- fprintf(stdout, "the value
is d\n", 2) -
- expr
- expr TOK_ADD expr
- 1 3
- expr TOK_SUB expr
- 1 - 3
- expr TOK_MUL expr
- 1 3
-
8Parsing
-
- int yyerror(char s)
- fprintf(stderr, syntax error")
- return 0
- int main()
-
- yyparse()
- return 0
9Lexing
-
- include ltstdio.hgt
- include "example.tab.h"
-
- digit (0-9)
-
- "println" return(TOK_PRINTLN)
- digit sscanf(yytext, "d",
(yylval.int_val)) - return TOK_NUM
- "" return(TOK_SEMICOLON)
- "" return(TOK_ADD)
- "-" return(TOK_SUB)
- "" return(TOK_MUL)
- "/" return(TOK_DIV)
- \n
- . printf("Invalid character 'c\n",
yytext0)
10What to Remember
- Different phases of compilation what the goal of
each phase is how they are connected with each
other. - Important concepts tokens, regular expressions,
context-free grammar, ambiguity, AST. - Learn to use Flex and Bison.
11What You Dont Have to Remember
- The details of constructing an FA.
- The details of constructing a shift-reduce parser
or a recursive descent parser. - The details of Flex and Bison specification
formats (You are fine as long as you can use them
with their manuals on your side.)
12Todays Topic I
Names, Attributes, and Bindings
13Names (Identifiers)
- Names in a programming language can be
- Variablese.g. int x 100
- Procedure namese.g. int fact (int n) .
- Constant namese.g. const int n 100
14Attributes
- Attributes are associated with names.
- Attributes describe the meaning or semantics of
names. - Examples
- For a variable value, data type, memory location
15Attributes (Cont.)
- For a function
- Number, names, types of its parameters
- Type of returned value
- Body of a function or method
- int fact (int n)
- 1 parameter with name n and type int
- Type of returned value int
- The body of the code in .
16Binding and Program Lifecycle
- Binding the process of associating an
attribute to - a name
- When does binding happen? Some time in the
program lifecycle
17Binding Time Pre-linking Binding
- Language Design Time (e.g. the meaning of char
in C, or let in Haskell, or class in Java) - Language Implementation Time (e.g. maximum
length of identifiers) - Compile Time (e.g. value of n in const int n 5)
18Binding Time Link-Time Binding
- A program is usually not complete until the
various modules are joined together by a linker - Compile different modules of a program at a
different time. - e.g. the body of function f in extern int f()
19Binding Time Load-Time Binding
- Refers to the point at which the operating system
loads the program into memory so that it can run. - e.g. the location of a global variable
20Static vs. Dynamic Binding
- Binding made prior to execution is called static
binding. - Binding made at run-time is called dynamic
binding. - Language design time
- Language implementation time
- Translation time (compile time)
- Link time
- Load time
- Execution time
Static binding
Dynamic binding
Early binding times are associated with greater
efficiency, while later binding times are
associated with greater flexibility
21Static vs. Dynamic Binding Example
- int x
- The type of x
- statically determined
- The value of x
- dynamically determined
- The location of x
- dynamically or statically (if x is a global
variable) determined
22Static vs. Dynamic Binding (Cont.)
- Languages differ substantially in which
attributes are bound statically and which are
bound dynamically. - Its a design choice that one can argue both
ways! - Functional languages have more dynamic binding
than imperative languages. - Interpreters have more dynamic binding than
compilers.
23Static vs. Dynamic Binding (Cont.)
- Value of an expression during execution or
during translation (constant expression). - Data type of an identifier translation time
(Java) or execution time (Smalltalk, Lisp). - Maximum number of digits in an integer language
definition time or language implementation time. - Location of a variable load or execution time.
- body of a function or method translation time or
link time or execution time (staged programming).
24Static vs. Dynamic Binding (Summary)
- Binding made prior to execution is called static
binding. - Binding made at run-time is called dynamic
binding. - Language definition time
- Language implementation time
- Translation time (compile time)
- Link time
- Load time
- Execution time
Static binding
Dynamic binding
25Todays Topic II
(Mostly) Static Elements
26Static Binding Construct Symbol Table
- A symbol table binds names to static attributes.
- It is typically constructed statically and used
by the compilers (i.e. when your program is up
and running, it does not exist any more.) - There are exceptions dynamic scoping.
- It is usually constructed at semantic analysis
phase, and used for type checking, scope control,
disambiguation, but can be constructed at the
stage of parsing as well. - Symbol tables are also important for modular
software development, used at linking time.
27Symbol Table Implementation
- Can be implemented using different data
structure, but typically a hash table. - Allows for efficient entry insertion, and name
lookup operations. - Things are a bit more than straightforward
because of scoping.
28Blocks and Scope
- int x /global/
- void p ()
- double r /the block of p/
-
- int x, y /nested block/
- x 2
- y 0
-
-
- Usually, a name refers to an entity within a
given context. - The context is specified by blocks
- Delimited by and in C, C, and Java
- Delimited by begin and end in Pascal, Algol
and Ada
29Scope
void p( ) int x void q( )
char x
- Scope region of the program to which a binding
is maintained (where is the name meaningful?). - Scope is typically indicated implicitly by the
position of the declaration in the code. - The same name may be involved in several
different declarations, each with a different
scope.
30Scope and Visibility
- Declarations in nested blocks take precedence
over previous declaration. - int x
- void p( )
- char x
- x a / assigns to char x /
-
- main ()
- x 2 / assigns to global x/
-
The global declaration of x is said to have a
scope hole inside p.
31Modeling Scopes In the Symbol Table
- Needs to remember the change of scopes.
- A scope stack that keeps track of the current
scope and its surrounding scopes. - The topmost element in the scope stack
corresponds to the current (i.e., innermost)
scope - The bottommost element corresponds to the
outermost (i.e., global) scope.
32Static (Lexical) vs. Dynamic Scoping
- Static/Lexical Scoping scope is managed
statically (prior to execution). - The scope of a binding is limited to the block in
which its declaration appears. - The bindings of local variables in C, C, Java
follow static scoping - Dynamic Scoping scope is managed directly during
execution (run-time). - The scope of a binding depends on the order in
which subroutines are called - The current binding for a given name is the one
encountered most recently during execution.
33Example
- Static/Lexical scoping the name y in function f
always refer to the global name y - Dynamic scoping
- If f is called from h, then y refers to the float
variable declared in h. - If f is called from g, then y refers to the
integer variable y defined in g
- float y 1.0
- void f()
- y 1
-
- void g()
- int y
- f()
-
- void h()
- float y 10.0
- f()
34Static Scoping
- On entry into a block, all declarations of that
block are processed and the corresponding
bindings are added to the symbol table. - On exit from the block, the bindings provided by
the declarations are removed, restoring any
previous bindings that may have existed. - We view symbol table schematically as collection
of names, each of which has a stack of
declarations associated with it.
35Static Scoping Example
(11) void q() (12) int y (13) (14)
(15) main() (6) char x (17) (18)
- (1) int x
- (2) char y
- (3) void p()
- (4) double x
- (5)
- (6) int y10
- (7)
- (8)
- (9)
- (10)
36Static Scoping Example
Symbol Table Structure at Line 5
37Static Scoping Example
Symbol Table Structure at Line 7
38Static Scoping Example
Symbol Table Structure at Line 10
39Static Scoping Example
Symbol Table Structure at Line 13
40Static Scoping Example
Symbol Table Structure at Line 14
41Symbol Table Structure at Line 17
42Dynamic Scoping
(10) void q() (11) int y 42 (12)
printf(d\n,x) (13) p() (14) (15)
main() (16) char x b (17) q() (18)
return 0 (19)
- (1) include ltstdio.hgt
- (2) int x 1
- (3) char y a
- (4) void p()
- (5) double x 2.5
- (6) printf(c\n,y)
- (7) int y10
- (8)
- (9)
43Dynamic Scoping
- Scope is managed during execution
- The scope of a binding depends on the order in
which subroutines are called - The current binding for a given name is the one
encountered most recently during execution.
44Dynamic Scoping
Symbol Table Structure at Line 17
45Dynamic Scoping
Symbol Table Structure at Line 12
46Dynamic Scoping
Symbol Table Structure at Line 6
47Pretending Java Supporting Both
- public class Scope
- public static int x 2 public static void
f() - System.out.println(x)
- public static void main(String
args) - int x 3 f()
- What will be printed out under
- Lexical scoping?
- Dynamic scoping?
2
3
48Dynamic Scoping Evaluated
- Almost all languages (C/C/Java/ML/Haskell) use
lexical scoping - With dynamic scoping, the meaning of a variable
cannot be known until execution time no static
type checking - Originally used in Lisp. Some languages still use
it VBScript, Javascript. - Even though symbol tables are mostly used at
compile time, they have to be preserved at run
time for languages with dynamic scoping.
49Todays Topic III
Run-time Semantics Variables,
Constants, Assignments
50Variables
- A variable is an object whose stored value can
change during execution.
Box-and-circle diagram
51Variables
- A variable is an object whose stored value can
change during execution. - Variables are associated with a location and
value. - The location is called l-value
- The value stored in this location is called
r-value
52L-value and R-value
- x y
- A name appearing on the left-hand side of an
assignment statement (x) must have an l-value. - A name appearing on the right-hand side must have
an r-value.
53L-Value Retrival in C
- int x
- x is the address of x and can be assigned to a
pointer - For example
- int x
- x 10
- x
54Constants
- A constant is an object whose value does not
change throughout its lifetime. - The semantics of constants
- Once the value is computed, it cannot change
- The location of the constant cannot be explicitly
referred to by a program
55Constants
- Compile-time Constant value is known at compile
time. - Can be used by a compiler to improve the
efficiency of a program - need not occupy memory. - Java static final int zero 0
- Load-time Constant
- Java now contains the date at the moment when
the program begins to run - static final Date now new Date()
- Dynamic Constant
- C const int d x1
56Assignment with Storage/Copy Semantics
- x y
- y is evaluated to a value which is then copied
into the location of x.
57Assignment with Pointer Semantics
- x y
- The location of x and y are simply shared.
- A future assignment to y may change the value of
x. - Used by Java for object assignment
- Used by C for pointer assignment
58Run-Time Environment
- The term environment usually refers to data
structures that are responsible for maintaining
variable bindings at run time. - Dont get too uptight with this term different
books might use it with different meanings. - The environment may be constructed statically (at
load time), dynamically (at execution time) or
mixture of the two. - Fortran complete static environment all
locations are bound statically. - LISP complete dynamic environment.
- C, C, Ada, Java mixture.