Lecture 6- Semantic Analysis
Lecture 6- Semantic Analysis
Compiler construction
Introduction to semantic analysis
Languages
• Syntax of a language
• the rules specifying valid constructions of a
language
• e.g. syntax of algebra: x+2 is valid; x2+ is not valid
• Semantic of a language
• the interpretation of symbols and strings
• e.g. semantics of algebra: x+2 is the sum of the
values of x and 2
Compiler construction
Introduction to semantic analysis
token intermediate
stream form
abstract intermediate
syntax tree form
annotated target
AST language
Compiler construction
Introduction to semantic analysis
• Semantic analysis is the process of computing additional
information about a program's meaning after the syntactic
structure is known:
• Purpose: Semantic analysis ensures that a program's
statements and declarations are semantically correct,
meaning their meaning is clear and consistent.
• Process: Semantic analysis involves:
• Adding information to the symbol table
• Performing type checking
• Using attribute grammars to relate the program's
meaning to its syntactic structure
• Computing attribute values using semantic rules
• Evaluating semantic rules on the parse tree
• Output: The output of semantic analysis is the annotated
tree syntax.
• Phase in compilation: Semantic analysis is the third phase
of the compilation process.
Compiler construction
Introduction to semantic analysis
• Semantic analysis checks for various rules that
cannot be enforced by the syntax alone. These
include:
• Type Checking: Verifying that operands and
operators are compatible. E.g: Ensuring you don’t
add a string to an integer (3 + "hello" is invalid).
• Scope Resolution: Determining which variables,
functions, or identifiers are accessible in a given
part of the code (handling variable declarations,
shadowing, etc.).
• Name Resolution: Ensuring that every identifier
(variable, function, class, etc.) is declared before
it is used.
• Type Inference and Conversion: Handling implicit
type conversions or coercion when allowed, and
Compiler construction
Introduction to semantic analysis
• Semantic Rule Enforcement: Enforcing rules specific to
the language, such as:
• Function return type matches the declared type.
• The number and types of function arguments
match the declaration.
• Variables are initialized before use.
• Symbol Table Management: Maintaining a symbol
table where variable/function names are stored along
with their associated attributes (type, scope, etc.).
• Control Flow Checks:
• Ensuring proper use of control flow constructs like
break, continue, return, etc.
• Validating that all execution paths return a value in
non-void functions.
• Array and Pointer Checks: Verifying that array indices
are within bounds (if feasible at Compiler
compile time) and
construction
Introduction to semantic analysis
• Example
Compiler construction
Symbol Tables
• Purpose: To hold information (i.e., attribute
values) about identifiers that get computed
at one point and used later.
• E.g.: type information:
• computed during parsing;
• used during type checking, code
generation.
• Operations:
• create, delete a symbol table;
• insert, lookup an identifier
• Typical implementations: linked list, hash 12
Compiler construction
Type checking
• Dynamic Type Checking: Performed at runtime.
• Examples: Python, JavaScript.
• Benefits:
• Allows more flexible code (e.g., duck typing).
• Drawback:
• Type errors are discovered only during execution.
• Example:
• a = 5 + "hello" # Error: Cannot add integer and string
• Optional Type Checking:
• Some languages support both static and dynamic type
checking (e.g., TypeScript for JavaScript).
14
Compiler construction
Type checking
Type Systems
• A type system defines the set of rules governing type
compatibility in a programming language.
• Characteristics:
• Strongly-Typed: Prohibits mixing types without
explicit conversion (e.g., Java, Python).
• Weakly-Typed: Allows implicit type conversions
(e.g., C).
Compiler construction
Semantic Analysis
• Semantic Analysis computes additional information related to the meaning
of the program once the syntactic structure is known.
• In typed languages as C, semantic analysis involves
• As for Lexical and Syntax analysis, also for Semantic Analysis we need both
a Representation Formalism and an Implementation Mechanism.
Compiler construction
Syntax Directed Translation: Intro
Compiler construction
Syntax Directed Translation: Intro
• It involves associating:
• Attributes with grammar symbols.
• Semantic Actions with grammar productions.
Compiler construction
Syntax Directed Translation: Intro (Cont.)
• Evaluation of Semantic Rules may:
– Generate Code;
– Insert information into the Symbol Table;
– Perform Semantic Check;
– Issue error messages; etc.
Compiler construction
Syntax Directed Definitions
Compiler construction
Syntax Directed Definitions (Cont.)
Compiler construction
Form of Syntax Directed Definitions
• Each production, A → α, is associated with a set of semantic rules:
b : = f (c 1 , c2 , . . . , c k ), where f is a function and either
1. b is a synthesized attribute of A , and c1 , c2 , . . . , c k are attributes of the
grammar symbols of the production, or
2. b is an inherited attribute of a grammar symbol in α, and c1 , c2 , . . . , c k
are attributes of grammar symbols in α or attributes of A .
• Procedure calls (e.g. print in the next slide) define values of Dummy
synthesized attributes of the non terminal on the left-hand side of the
production.
Compiler construction
Syntax Directed Definitions: An
Example
• Example. Let us consider the Grammar for arithmetic expressions.
The Syntax Directed Definition associates to each non terminal a
synthesized attribute called val.
P RODUCTION S EMANTIC R ULE
L → En print(E.val)
E → E1 + E . v a l : = E 1 .val +
T
T.val E . v a l : = T.val
E → T
T.val : = T 1 .val ∗ F.val
T → T1 ∗ T.val : = F.val
F T → F F.val : = E . v a l
F → (E)
F.val :=digit.lexva
Compiler construction
S-Attributed Definitions
Compiler construction
S-Attributed Definitions
Example. The above arithmetic grammar is an example of an S-Attributed Definition. The annotated parse-tree for the
input 3*5+4n is:
L
E.val = n
19
E.val = + T.val =
15 4
F.val = 4
T.val =
T.val =1 5 * F.val = 5 digit.lexval=
3 4
F.val = 3 digit.lexval=
5
digit.lexval=
3
Compiler construction