These notes are from the Week 5 of the Compilers course by Stanford.
The semantic analysis phase is the last line of defense for the compiler, meaning the next phase will always have a valid program to compile. This is done in a separate phase because during the parsing phase, it is harder to catch some errors.
Scopes are the way to match the declared variables to their uses. Some scopes can be enclosed in others, and the identifiers which are declared in the innermost scopes have precedence over the outer ones.
Identifiers bindings might be introduced in many ways, such as class declarations, method declarations, let expressions, formal parameters, attribute definitions, and case expressions. Also, another rule for identifiers might be that that the same identifier cannot be declared more than once in the same scope.
Symbol Tables are the way we keep track of the identifiers that are in the current scope. The scope can be defined in some sort of a stack, so when we have multiple occurrences of the same identifier, the last one always wins. Also, when we leave the scope the variables declared can be popped out of the stack.
Types are a set of values that allow a given set of operations. Integers, for example, might are the set of integer numbers and allow arithmetic operators and comparison operators.
Type checking systems work with hypotheses to ensure derived expressions have the expected type. For example, a variable is declared to be an integer and is initialized with the result of a sum
let x: Integer = a + b, the inference system needs to check whether
b are integers and later the result of