Q1Compiler Design
Question
Explain the phases of a compiler.
Answer
A comprehensive architectural breakdown of the six sequential phases of a compiler: Lexical, Syntax, Semantic, Intermediate Code, Optimization, and Target Code generation.
The compilation of high-level source code into low-level machine code is not a singular event, but rather an incredibly complex, multi-stage engineering pipeline. A modern compiler mathematically decomposes the translation process into exactly six strict, sequential phases. These phases are structurally grouped into the "Front-End" (analysis) and the "Back-End" (synthesis), both of which communicate aggressively with the centralized Symbol Table and the Error Handler.
1. Lexical Analysis (Scanner)
This is the absolute first phase. The scanner violently rips through the raw source code text, stripping away all developer comments and whitespace. It mathematically groups the remaining characters into logical atomic units called "Tokens" (e.g., keywords, identifiers, operators). If it encounters illegal characters, it throws a lexical error.
2. Syntax Analysis (Parser)
The parser receives the continuous stream of tokens and aggressively verifies them against the Context-Free Grammar (CFG) of the programming language. It attempts to mathematically build a massive hierarchical structure known as a Parse Tree or Syntax Tree. If the tokens violate the grammatical rules (e.g., missing semicolons), a syntax error is violently triggered.
3. Semantic Analysis
Even if the code is grammatically perfect, it must make logical sense. This phase rigorously checks for semantic consistency. It performs absolute type checking (e.g., ensuring a string is not multiplied by an integer) and validates that variables are declared before they are used, annotating the syntax tree with data types.
4. Intermediate Code Generation
Once the syntax and semantics are proven flawless, the compiler generates an abstract, machine-independent representation of the code. This is usually rendered as Three-Address Code (TAC), which breaks complex mathematical expressions into simple, register-like instructions.
5. Code Optimization
This phase aggressively attacks the intermediate code, mathematically transforming it to consume less RAM and execute faster on the CPU. It violently eliminates "dead code" (code that is never executed) and pre-calculates constant math expressions (Constant Folding).
6. Target Code Generation
The final phase translates the highly optimized intermediate code directly into the absolute physical machine code or assembly instructions required by the specific target CPU architecture (e.g., x86, ARM), mapping virtual variables to physical silicon registers.