What the parser leaves undone
A syntactically valid program can still be garbage:
int foo() {
return bar(x, x); // bar? x? never declared
}
int main() {
foo() + "hello"; // int + char* ?
return; // missing value in int-returning function
}
None of these are syntax errors — the grammar accepts them. They are semantic errors, and catching them is the job of semantic analysis. Semantic analysis walks the AST produced by the parser, builds supporting data structures, and either annotates the AST with type information or rejects the program with meaningful diagnostics.
The output — a typed AST — is what every downstream phase (IR generation, optimization) can trust. Without it, code generation would have to guess sizes, calling conventions, and memory layouts.
