0% found this document useful (0 votes)
6 views

[CPL'25] Semantics

The document outlines the concepts of programming languages, focusing on semantics, attributes, binding, and the symbol table. It discusses the challenges of specifying semantics compared to syntax and introduces various methods for defining semantics, including informal descriptions and formal definitions. Additionally, it covers the importance of declarations, blocks, scope, and the structure of the symbol table in managing bindings during program execution.

Uploaded by

johnashraf712
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)
6 views

[CPL'25] Semantics

The document outlines the concepts of programming languages, focusing on semantics, attributes, binding, and the symbol table. It discusses the challenges of specifying semantics compared to syntax and introduces various methods for defining semantics, including informal descriptions and formal definitions. Additionally, it covers the importance of declarations, blocks, scope, and the structure of the symbol table in managing bindings during program execution.

Uploaded by

johnashraf712
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/ 106

CSCE 3104

• Dr. Maryam Nabil


Concepts of • [email protected]

Programming
Languages
2/28/2025 Partial credit: Dr. Sherif Aly 1
Progress Map

Attributes, Binding, and


Semantic Functions
The Symbol Table
and Environment
Declarations, Blocks,
and Scope

3. Syntax
4. Semantics

Concepts of PL 5. Data Types

5. Exception
2. Language Handling
Design Principles 6. Procedures
1. Introduction
and 2
2/28/2025 Environments
Semantics
Contents
• Attributes, Binding, and Semantic Functions
• Declarations, Blocks, and Scope
• The Symbol Table
• Name Resolutions and Overloading
• Allocation, Lifetime, and Environment
Introduction
• Specifying the semantics of a programming
language is more difficult than specifying
syntax.
• There are several ways to specify
semantics:
1. Language reference manual:
• Most common, clear but lacks precision.

5
Introduction
2. Defining Translator:
• Questions about a language can be answered
by experiment
• Drawbacks:
• Questions about program behavior cannot be
answered in advance—we must execute a program
to discover what it does.
• Bugs and machine dependencies in the translator
become parts of the language semantics, possibly
unintentionally.
• The translator may not be portable to all machines
and may not be generally available.
6
Introduction
3. Formal Definition:
• Formal, mathematical methods are precise, but
they are also complex and abstract, and require
study to understand.
• Different formal methods are available, with
the choice of method depending on its
intended use.
• Perhaps the best formal method to use for the
description of the translation and execution of
programs is denotational semantics, which
describes semantics using a series of functions.
7
Introduction
• We will specify semantics by using a hybrid of
the type of informal description you might
find in a manual combined with the simplified
functions used in denotational descriptions.
• We will provide abstractions of the operations
that occur during the translation and
execution of programs in general, whatever
the language, but we will concentrate on the
details of Algol-like languages, such as C, C++,
Java, Pascal, and Ada.

8
Attributes,
Binding, and
Semantic
Functions
2/28/2025 9
Attributes, Binding, and Semantic
Functions
Attributes:
• Names, or identifiers are used to denote language
entities or constructs.
• Attributes are the properties of language entities,
especially identifiers.

10
Attributes, Binding, and Semantic
Functions
Attribute Examples:
• Value of expressions: Any storable quantities such as
integers, reals, array values.
• Locations: Addresses in memory.
• Data type of an identifier.
• Maximum number of digits in an integer.
• Code body for a function or method.

11
Attributes, Binding, and Semantic
Functions
Attribute Examples:
• const int n = 5;
• Associates to identifier n the attribute integer
constant, and the value 5
• int x;
• Associates to identifier x the attribute integer.
• int *x;
• Associates to identifier x the attribute integer
pointer.
12
Attributes, Binding, and Semantic
Functions
Binding:
• Declarations (definitions) bind attributes to an
identifier.
• Binding Is the process of associating an attribute to
a name (identifier).

13
Attributes, Binding, and Semantic
Functions
Binding:
• Binding times are classified into two general
categories:
• Static: occurs prior to execution.
• Dynamic: occurs during execution.

14
Attributes, Binding, and Semantic
Functions
Binding:
• An attribute that is bound statically is called a static
attribute.
• An attribute that is bound dynamically is called a
dynamic attribute.

15
Attributes, Binding, and Semantic
Functions
Binding:
• Binding times can depend on the translator itself.
• Compilers perform many bindings statically.
• Interpreters perform many bindings dynamically.

16
Attributes, Binding, and Semantic
Functions
Binding:
• Some attributes can be bound both dynamically and
statically depending on the translator used.
• To make the issue of binding independent of
translators, we refer to:
The binding time of an attribute is the earliest time
that the language rules permit the attribute to be
bound.

17
Attributes, Binding, and Semantic
Functions
Binding:
• Example: An attribute that could be statically bound,
but is actually bound dynamically is still referred to
as a static attribute.

18
Attributes, Binding, and Semantic
Functions
Binding Example:
• int x;
• The type int is statically bound to identifier x.
• x = 2;
• The value 2 is dynamically bound to identifier x,
when the statement is actually executed.

19
Attributes, Binding, and Semantic
Functions
Binding:
• Binding Times Sub-Classification:
• Binding times can be further refined into
subcategories of dynamic and static binding.

20
Attributes, Binding, and Semantic
Functions
Binding:
• Examples of possible binding times:
• Language definition time. (static)
• Language implementation time. (static)
• Translation time (compile time). (static)
• Link time. (static)
• Load time. (static)
• Execution time (run-time). (dynamic)
• Further sub-classifications of dynamic binding
• Example: on entry or exist from a procedure or program.
21
Attributes, Binding, and Semantic
Functions
Binding:
• Examples of possible binding times:
• 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 and language implementation time.

22
Attributes, Binding, and Semantic
Functions
Binding:
• Examples of possible binding times:
• Predefined identifiers such as boolean, char: language
definition time.
• Location of a variable: load or execution time.
• Code body of a function or method: translation time or
link time or execution time.

23
Attributes, Binding, and Semantic
Functions
Binding:
• Bindings must be maintained by a translator so that
appropriate meanings are given to names during
translation and execution.
• A translator does this by creating a data structure to
maintain this information.
• We can think of it abstractly as a function that
expresses the binding of attributes to names.
• This function is a fundamental part of language
semantics, and is called the symbol table.
24
Attributes, Binding, and Semantic
Functions
Binding:
• A dictionary or table is used to maintain the
identifier/attribute bindings.
• It can be maintained either during translation or
execution or both. (Pre-translation entities are
entered into the initial or default table.)
• During translation this table is called the symbol
table.
• During execution this table is called the
environment.
25
Attributes, Binding, and Semantic
Functions
Binding:
• Formally, we can think of the symbol table and
environment as functions.
• If the symbol table and environment are maintained
separately (compiler): The following binding information
is maintained:
SymbolTable: Names → Static Attributes
Environment: Names → Locations Memory:
The binding of
Locations → Values
locations to
values is called
memory 26
Attributes, Binding, and Semantic
Functions
Binding:
• If the symbol table and environment are maintained
together (interpreter):
Environment: Names → Attributes (including locations and
values)

27
Declarations,
Blocks, and Scope

2/28/2025 28
Declarations, Blocks, and Scope
Declarations
• Declarations are a principal method for establishing
bindings.
• Bindings can be determined by a declaration either
• Implicitly or
• Explicitly.

29
Declarations, Blocks, and Scope
Declarations
• Example: int x
• Establishes an explicit binding of identifier x with the
type int.
• The exact location of x during execution is implicitly
bound.
• The value of x is implicitly 0 or undefined.
• Example: int x=0
• explicitly binds the initial value of x to 0.

30
Declarations, Blocks, and Scope
Declarations
• Example:
• FORTRAN does not require variable
declarations for simple variables!
• All variables not explicitly declared are
assumed to be integer if their names begin
with “I”, “J”, “K”, “L”, “M”, or “N”
• And are real otherwise.

31
Declarations, Blocks, and Scope
Declarations
• Example:
• Other languages with implicit declarations are
like:
• APL
• SNOBOL
• A declaration may fail to fully specify all
necessary attributes—a supplemental
declaration is then necessary elsewhere.
32
Declarations, Blocks, and Scope
Declarations
• In C and C++, declarations that bind ALL potential
attributes are called definitions.
• Example: int x=0;
• Declarations that only PARTIALLY specify
attributes are called declarations.
• Example: function prototype double f(int x);
• It does not specify the code to implement
function f.
33
Declarations, Blocks, and Scope
Scope
• The scope of a declaration is the region of the
program to which the bindings established by the
declaration apply. (If individual bindings apply
over different regions: scope of a binding.)
• Scope is typically indicated implicitly by the
position of the declaration in the code, though
keywords can modify it.

34
Declarations, Blocks, and Scope
Blocks
• In a block-structured language, the scope is
typically the code from the end of the
declaration to the end of the "block"
• Example of blocks: indicated by braces {…} in C
and Java in which the declaration occurs.
• Scope can extend backwards to the beginning of
the block in certain cases (class declarations in
Java and C++, top- level declarations in Scheme).
35
Declarations, Blocks, and Scope
Blocks
Syntactic block
• Example in C: marker in C,
C++ and Java

36
Declarations, Blocks, and Scope
Blocks
Begin and end
• Example in C: are the block
markers in Ada

37
Declarations, Blocks, and Scope
Blocks
• Lexical (Static) Scope:
• In block structure languages, blocks can be
nested.
• The scope of a binding is:
• Limited to the block in which its associated
declaration appears
• But is visible to other blocks contained within it
i.e. global to all nested scopes within it.
• This is called lexical scope.
38
Declarations, Blocks, and Scope
Blocks
• Lexical (Static) Scope:
• The symbol table processes the declarations
statically (prior to execution).
• This is the case if the symbol table is managed
by a compiler.
• Static scoping is the standard for most
programming languages, including C.

39
Declarations, Blocks, and Scope
Blocks
• Dynamic scope:
• If the symbol table is managed the same way,
but during execution.
• Declarations are processed as they are
encountered along an execution path through
the program.

40
Declarations, Blocks, and Scope
Blocks
• Scope holes:
Although there is a global x, this
• Example in C: declaration of x inside function p
masks the global declaration.
This creates a scope hole!
You can still access the global x, but
using special mechanisms

41
The Symbol Table

2/28/2025 42
The Symbol Table
• The symbol table is like a variable dictionary
• Must support:
• Insertion.
• Lookup.
• Deletion.
• Contains names with associated attributes
representing the bindings in declarations.

43
The Symbol Table
• A symbol can be maintained by any number of data
structures to allow for efficient access and
maintenance.
• Hash tables, trees, and lists are some data structures
used.

44
The Symbol Table
• A language with block structure requires that
declarations be processed in a stack-like fashion.
• On entry into a block:
• All declarations of that block are processed
• The corresponding bindings are added to the
symbol table.

45
The Symbol Table
• Example:
• Observe the corresponding
code in C.
• Functions p, q, main exist
• Three different declarations
of x occur.
• Three different declarations
of y occur.
• We need to know what the
symbol table looks like using
a lexical (static) scope.

46
The Symbol Table

47
The Symbol Table

48
The Symbol Table

49
The Symbol Table

50
The Symbol Table

51
The Symbol Table

52
The Symbol Table
• What if dynamic scoping was used now as opposed
to static scoping?

• What would the behavior of the symbol table be?

53
The Symbol Table
int x = 1;
char y = ‘a’;

void p(void){
double x = 2.5;
printf(“%c\n”, y);
{ int y[10];

}
}

void q(void){ Dynamic scoping will now be used.


int y = 42;
printf(“%d\n”, x); The symbol table is constructed dynamically as
p(); execution proceeds.
}
Execution will begin at main
main (){
char x = ‘b’;
q(); All global declarations are processed before main
return 0; begins, main must know about all declarations before it.
}

54
The Symbol Table

55
The Symbol Table

56
The Symbol Table

57
The Symbol Table

◼ Using static scoping (the


standard for most languages,
including C), The output of
this program is?

58
The Symbol Table
◼ Using static scoping (the
standard for most languages,
including C), The output of
this program is:
◼ 1
◼ a
◼ Since the printf statements
refer to the global x and y,
irrespective of the execution
path!

59
The Symbol Table
◼ Using dynamic scoping, the
output differs depending on
the execution path !!!
◼ When this printf is reached,
the latest value of x is a
character ‘b’.
◼ Since the printf is trying to
print a decimal format (%d),
the decimal value of ‘b’ is
printed!!!
◼ The output is 92 here !!!!
60
The Symbol Table
Dynamic scoping is very problematic and
unnatural to the idea of blocks.

Static scoping is the standard for most


languages.

However, dynamic scoping is a possible option for highly dynamic,


interpreted languages

61
The Symbol Table
◼ No language specification will dictate what
the symbol table structure looks like.

◼ Any structure that provides the appropriate


properties will do.

◼ What if we create the symbol table as a stack


for each scope as follows:

62
The Symbol Table

63
The Symbol Table

64
Name
Resolutions and
Overloading
2/28/2025 65
Name Resolutions and Overloading
◼ To what extent can the same name be used to
refer to different things in a program?

66
Name Resolutions and Overloading
◼ Consider the + operator, it can at least be
used for:
◼ Integer addition
◼ Floating point addition

◼ The + operator is said to be overloaded.

67
Name Resolutions and Overloading
◼ Overloading:
◼ Is a property of symbol tables that allows
them to successfully handle declarations
that use the same name within the same
scope.
◼ Overload Resolution:
◼ It is the job of the symbol table to pick the
correct choice from among the declarations
for the same name in the same scope.

68
Name Resolutions and Overloading
◼ The symbol table performs overload
resolution by using extra information, typically
the data type of each declaration, which it
compares to the probable type at the use site,
picking the best match.

◼ If it cannot successfully do this, a static


semantic error occurs.

69
Name Resolutions and Overloading
◼ Overloading typically applies only to functions
or methods.
◼ Example of overloaded functions:
◼ Max (int, int);
◼ Max (float, float);
◼ Max (double, double);
◼ Resolution is usually made based not only on
the name of the function, but also on:
◼ The number of parameters.
◼ The parameter types.
70
Name Resolutions and Overloading
◼ What if we have the following:
◼ Max (int, int)
◼ Max (float, float)
◼ We perform the following function call:
◼ Max (2.5, 3) (float and an int)
◼ Which of the above two functions will be
called?
◼ We are encountered with an ambiguity.
Different programming language will resolve
differently.
71
Name Resolutions and Overloading
◼ Automatic conversions such as in C++ and
Java significantly complicate the process of
overload resolution.
◼ Java has a more restrictive type conversion
policy.
◼ Ada does not allow automatic conversions.

72
Name Resolutions and Overloading
◼ Overloading is made difficult by weak typing,
particularly automatic conversions.
◼ ML as an Example:
◼ ML has partially specified types, overload
resolution becomes even more difficult,
which is why ML disallows it.
◼ Scheme as an Example:
◼ Scheme disallows overloading for a
different reason: there are no types on
which to base overload resolution, even
during execution. 73
Name Resolutions and Overloading
◼ Overload resolution:
◼ We indicated before overload resolution for
functions is usually done using:
◼ The number of parameters.
◼ The parameter types.
◼ To resolve overloads, other programming
languages such as ADA also use:
◼ Return types
◼ Names of parameters in a definition !

74
Allocation,
Lifetime, and
Environment
2/28/2025 75
Allocation, Lifetime, and Environment
• Can be constructed entirely statically (Fortran):

• All vars and functions have fixed locations for the


duration of execution.
• Can also be entirely dynamic: functional languages
• Scheme
• ML
• Most language use a mix: C, C++, Java, Ada.

76
Allocation, Lifetime, and Environment
• Consists of three components:
❑ A fixed area for static (global) allocation
❑ A stack area for LIFO allocation (usually
the processor stack)
❑ A "heap" area for on-demand dynamic
allocation (with or without garbage collection)

77
Allocation, Lifetime, and Environment

78
Allocation, Lifetime, and Environment
◼ The Runtime Stack is used for:

❑ Procedure, function, and method calls.

❑ Temporaries (temporary results that cannot be stored in


registers).

❑ Local variables.

79
Allocation, Lifetime, and Environment
• Example of stack-based allocation:
A: { int x;
char y;

B: { double x;
int a;
} /* end B */

C: { char y;
int b;

D: { int x;
double y;
} /* end D */

} /* end C */

} /* end A */

80
Allocation, Lifetime, and Environment

81
Allocation, Lifetime, and Environment

82
Allocation, Lifetime, and Environment
◼ An alternative to stack-based allocation is a float
local space:

❑ All local variables are allocated at once,


irrespective nesting.

❑ Wastes space.

83
Allocation, Lifetime, and Environment
◼ Even with the flat memory approach, the primary
structure of the stack is still the call structure.
◼ A complete record of a call on the stack is called
an activation record or frame, and the stack is
referred to as the call stack.

84
Allocation, Lifetime, and Environment
◼ Java promotes a flat space by forbidding nested
re-declarations.
◼ This is not an essential property:
◼ A symbol table can easily distinguish nested
declarations as A.x, A.y, A.B.x, A.B.a, etc.

85
Allocation, Lifetime, and Environment

86
Allocation, Lifetime, and Environment
◼ Heap Allocation:
◼ In C, C++, Java, heap allocation requires the
use of the operation: new
◼ Any kind of data in C/C++ can be allocated on
the heap. In Java, only objects can be
allocated on the heap.
◼ Even with heap allocation in C/C++ and Java,
the stack is used to represent calls.

87
Allocation, Lifetime, and Environment
◼ Heap Allocation:
◼ In C/C++, de-allocation is usually done
manually.
◼ Usually tedious, and prone to errors.
◼ Java uses an automated memory anagement
mechanism and performs automated memory
de- allocation.
◼ Has its serious drawbacks also!

88
Allocation, Lifetime, and Environment
◼ Heap Allocation:
◼ In functional languages (Scheme, ML) heap
allocation is performed automatically, and
virtually everything, including function calls,
are allocated on the heap.
◼ Functional languages also use garbage
collection, since de-allocation is automatic
as well.
◼ C and C++ still lack garbage collectors,
although lots of research has been made to
make garbage collection efficient.
89
Allocation, Lifetime, and Environment
◼ Lifetime (Extent):
◼ The lifetime of a program entity is the
duration of its allocation in the environment.
◼ Allocation is static when the lifetime is the
duration of the entire program execution.
◼ E.g. global variables, statically declared
variables.

90
Allocation, Lifetime, and Environment
◼ Lifetime (Extent):
◼ Is lifetime identical to scope? NO

◼ Lifetime is related to but not identical to scope.


◼ With scope holes, lifetime can extend to
regions of the program where the program
entity is not accessible.
◼ It is possible for scope to exceed lifetime when
a language allows locations to be manipulated
directly (e.g. manual de- allocation).
◼ Exteremely dangerous!

91
Allocation, Lifetime, and Environment
◼ Variables and Constants:
◼ A variable is an object whose stored value
can change during execution.
◼ A constant is an object whose value does not
change throughout its lifetime.
◼ Constants are often confused with literals:
constants have names, literals do not.
◼ E.g. ‘a’, 1

92
Allocation, Lifetime, and Environment
◼ Variables and Constants:
◼ A schematic representation of a variable can
be drawn as follows:

◼ Each variable has a value stored in a given


location in memory.

93
Allocation, Lifetime, and Environment
◼ Variables and Constants:
◼ If we want to concentrate only on the location
and value, the schematic can be as follows:

94
Allocation, Lifetime, and Environment
◼ Variables and Constants:
◼ Since a variable has both a location and
value, we can refer to:
◼ The location as: r-value
◼ The value as: l-value
◼ Let’s view some examples on the usage of the
assignment operator.
◼ Using the assignment operator does NOT
always mean copying values!

95
Allocation, Lifetime, and Environment
◼ Variables and Constants:

◼ The principal way a variable changes its value


is through an assignment statement.
◼ x=y

96
Allocation, Lifetime, and Environment
◼ Variables and Constants:
◼ However, some programming languages
explicitly distinguish between the value and the
location of a variable.
◼ In ML, variables are thought of as locations, or
references to values.
◼ If x is an integer variable in ML, then its type is
a “reference to integer”.
◼ To obtain its value, we must write !x.
◼ This dereferences x to produce its value.
◼ To increment x, we must say x = !x + 1
◼ To assign the value of variable y to x, we must
97
write x:= !y
Allocation, Lifetime, and Environment
◼ Variables and Constants:
◼ In C:
◼ int x
◼ Is a variable called x, of type int.
◼ To obtain the location of variable x:
◼ &x (Address of x)
◼ int * x
◼ Is a variable called x of type pointer to int.
◼ Saying *x refers to the value of the location
stored in x.

98
Allocation, Lifetime, and Environment
◼ Variables and Constants:
◼ In other languages, simply saying x = y
assigns the location of y to the location of x.
◼ In conclusion, be careful, you must understand
the semantic of the assignment operator in any
programming language.

99
Allocation, Lifetime, and Environment
◼ Variables and Constants:
◼ Constants may be:
◼ compile-time static (may not ever be
allocated)
◼ load-time static
◼ dynamic

10
0
Allocation, Lifetime, and Environment
◼ Variables and Constants:
◼ Compile-time constant in Java:
◼ static final int zero = 0;

◼ Load-time constant in Java:


◼ static final Date now = new Date();

◼ Dynamic constant in Java:


◼ Any non-static final assigned in a
constructor.

10
1
Allocation, Lifetime, and Environment
◼ Aliases, Dangling References, and Garbage:
◼ Alias:
◼ When the same object is bound to two
different names at the same time. This is
fairly common with Java objects.

10
2
Allocation, Lifetime, and Environment
◼ Aliases, Dangling References, and Garbage:
◼ Dangling Reference:
◼ Is a location that has been de-allocated
from the environment, but is still accessible
within the program. Dangling references are
impossible in a garbage- collected
environment with no direct access to
addresses.

10
3
Allocation, Lifetime, and Environment
◼ Aliases, Dangling References, and Garbage:
◼ Garbage:
◼ Is memory that is still allocated in the
environment but has become inaccessible
to the program. Garbage can be a problem
in a non-garbage collected environment, but
is much less serious than dangling
references.

10
4
Allocation, Lifetime, and Environment
◼ The environment maintains the bindings of
names to locations.

10
5
Thank You

2/28/2025 106

You might also like