Compiler Design
Introduction to Compiler Design
A Compiler is a computer program that translates source code written in a high-level language (like C, C++, Java, or Rust) into a lower-level language, typically machine code, assembly, or bytecode, that can be executed directly by the CPU.
Why Do We Need Compilers?
Computers operate using binary signals (0s and 1s). High-level programming languages are designed for human readability and abstract reasoning. Compilers bridge this semantic gap by translating abstract syntax structures into physical CPU operations, performing optimization and static type checks in the process.
Compiler vs Interpreter
While both compilers and interpreters convert source code into executable instructions, they process the translation at different times and in different ways.
| Aspect | Compiler | Interpreter |
|---|---|---|
| Translation Unit | Translates the entire program at once. | Translates and executes line-by-line. |
| Execution Speed | Fast (compilation cost is paid once upfront). | Slower (translation happens repeatedly during run). |
| Output File | Produces a standalone binary (.exe, .out). | Does not generate a standalone file. |
| Error Reporting | Reports all syntactic and semantic errors after scanning. | Stops execution immediately upon reaching the first error. |
| Examples | C, C++, Rust, Go, Haskell. | Python, Ruby, PHP, Basic. |
Types of Compilers
Compilers are configured differently depending on target hosts and runtime performance requirements.
Single-Pass Compiler
Scans the source code once, emitting target machine instructions directly. Simple but lacks global optimizations.
Multi-Pass Compiler
Traverses the source code representation multiple times, creating intermediate states. Essential for complex languages and optimizations.
Cross Compiler
Runs on one architecture (e.g., x86) but generates code for a different architecture (e.g., ARM).
Just-In-Time (JIT) Compiler
Compiles code dynamically during program execution (e.g., V8 for JavaScript, HotSpot for JVM).