Compiler
1. Definition
A compiler is system software that translates a program written in a high-level language (source code) into an equivalent machine language program (object code) for a specific target computer. It works on the whole program at once, produces a separate output file, and only then is that file executed. The input language is the source language, the output the target language.
source.c ──► ┌──────────┐ ──► source.obj ──► ┌────────┐ ──► a.exe
(whole file) │ COMPILER │ (object code) │ LINKER │ (executable)
└──────────┘ └────────┘
+ library code
2. Phases of a Compiler
SOURCE PROGRAM
│
┌──────┴───────┐
│ 1 LEXICAL │ characters → tokens (int, x, =, 10, ;)
│ ANALYSIS │
├──────────────┤
│ 2 SYNTAX │ tokens → parse tree (checks grammar of the language)
│ ANALYSIS │
├──────────────┤
│ 3 SEMANTIC │ type checking, scope, declaration-before-use
│ ANALYSIS │ (uses the SYMBOL TABLE)
├──────────────┤
│ 4 INTERMEDIATE CODE GEN │ 3-address code / quadruples
├──────────────┤
│ 5 CODE │ removing redundancy, loop optimisation,
│ OPTIMISER │ constant folding, strength reduction
├──────────────┤
│ 6 CODE │ target machine instructions + register allocation
│ GENERATOR │
└──────────────┘
│
OBJECT CODE + ERROR HANDLER + SYMBOL TABLE (used throughout)
The front end (phases 1-3 + intermediate code) is machine independent; the back end (optimiser + code generator) depends on the target machine.
3. Phase-by-Phase Example
For the statement x = a + b * 5;
| Phase | Output |
|---|---|
| Lexical | <id,x> <=> <id,a> <+> <id,b> <*> <num,5> <;> |
| Syntax | parse tree: = at root, left x, right + with children a and *(b, 5) |
| Semantic | both operands of + are numbers; x, a, b declared; symbol table entries created |
| Intermediate | t1 = b * 5 · t2 = a + t1 · x = t2 |
| Optimised | t1 = b * 5 · x = a + t1 (t2 removed by copy propagation) |
| Code gen | MOV R0, b · MUL R0, 5 · ADD R0, a · MOV x, R0 |
4. Types of Compilers
| Type | Feature |
|---|---|
| Single-pass | Reads source once; fast, less optimisation (old Pascal compilers) |
| Multi-pass | Several passes over the source/intermediate form; better optimisation |
| Native compiler | Runs on and generates code for the same machine |
| Cross compiler | Runs on one machine, generates code for another (embedded/ARM development) |
| AOT (ahead-of-time) | Whole program compiled before execution — C, C++, Go, Rust |
| JIT (just-in-time) | Compiles bytecode to machine code at run time, optimizing hot spots — JVM HotSpot, V8 |
| Transpiler / source-to-source | Output is another high-level language — TypeScript → JavaScript |
| Incremental / bootstrapping | Compiles only changed parts; a compiler written in its own language compiles itself |
5. Compiler vs Interpreter
| Aspect | Compiler | Interpreter |
|---|---|---|
| Translation of | Whole program at once | One statement at a time |
| Output | Object/executable file | No file — result produced while interpreting |
| Execution | After translation, repeatedly (fast run) | Translation and execution interleaved (slow run) |
| Error reporting | All errors after the compilation (a listing) | Stops at the first error, with line number |
| Memory | Needs more memory for object code | Less; no object code |
| Speed of program | Fast (no translation overhead) | Slower (translation overhead per statement) |
| Distribution | Executable is enough — source can be kept secret | Source (or bytecode) must reach the user |
| Examples | C, C++, Go, Rust, Java (javac) | Python, JavaScript, Ruby, classic BASIC, shell |
A program that is already compiled runs faster because translation happened once; an interpreted program is easier to debug and test line by line. Many modern systems blend both (JIT: Java, .NET, JavaScript engines — first interpreted, hot code compiled).
6. Advantages and Limitations of Compilers
Advantages: fastest execution; the executable can be distributed without source; all syntax and most type errors reported before running; heavy optimisation possible.
Limitations: the whole program must be compiled before any output appears, so debugging is slower; the executable is machine specific (must recompile to port); a missing object file/linker error can be confusing; not suited to quick, interactive scripting.
7. Exam Points
- Define a compiler and explain its phases with a block diagram — 7 marks, very frequent.
- Explain lexical, syntax and semantic analysis with a small example — 5 marks.
- Difference between compiler and interpreter — 5 marks, almost certain.
- What are the front end and back end of a compiler? — 3-5 marks.
- Explain any four types of compilers (cross, JIT, AOT, single-pass) — 5 marks.
- Role of the linker and loader in producing an executable — 3-5 marks.