While the Parser ensures the code "looks" right, the Semantic Analyzer ensures the code "is" right. It performs a recursive walk over the Abstract Syntax Tree (AST) to verify that identifiers are used within their proper context. It acts as the final gatekeeper before the compiler commits to generating machine instructions.
add_symbol(). Variables are tracked by their current_scope level. There is only one static entry per variable in the table.exit_scope() loops backward to delete any variable belonging to that scope, keeping memory clean.return_stack array) of expected return types.
SYMBOL_INT) is pushed via push_return_type().get_current_return_type().pop_return_type().In our binarySearch example, the semantic analyzer ensures correct scoping using the Symbol Table. However, during execution, each recursive call creates a separate Activation Record on the call stack.
mid at runtime.Watch how the compiler analyzes the AST strictly top-to-bottom. It evaluates binarySearch once, verifies its internal logic against the LIFO stack, calls exit_scope() to drop local variables, and then moves on to analyze main().
int binarySearch(int arr[], int l, int r, int key) {
int mid;
if (l > r) { return 0-1; }
mid = (l + r) / 2;
if (arr[mid] == key) { return mid; }
else {
if (key < arr[mid]) { return binarySearch(arr, l, mid - 1, key); }
else { return binarySearch(arr, mid + 1, r, key); }
}
}
int main() {
int arr[5] = {1, 3, 5, 7, 9};
int n = 5;
result = binarySearch(arr, 0, n-1, 12);
return 0;
}
| Name | Type | Scope | Offset |
|---|