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.

AspectCompilerInterpreter
Translation UnitTranslates the entire program at once.Translates and executes line-by-line.
Execution SpeedFast (compilation cost is paid once upfront).Slower (translation happens repeatedly during run).
Output FileProduces a standalone binary (.exe, .out).Does not generate a standalone file.
Error ReportingReports all syntactic and semantic errors after scanning.Stops execution immediately upon reaching the first error.
ExamplesC, 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).