Compiler: Definition and Detailed Phases of Compilation

Compiler: Definition and Detailed Phases of Compilation

Verified Sources
Nov 4, 2026

A Compiler is a language-processing system that converts a source program into an equivalent target program (often machine code or an intermediate representation), while preserving meaning and enforcing language rules.2

A compiler is commonly described as having a front end (lexical + syntax + semantic + IR creation) and a back end (optimization + code generation). This separation enables reuse of analysis while retargeting code generation to different machines.2

Key ideas

  • Token streams feed parsing.
  • AST / parse trees represent grammar structure.
  • Symbol table stores meaning-related information used across phases.2
  • Intermediate Representation (IR) simplifies optimization and later code generation.

Academic framing: The classic phase model is often presented in compiler textbooks: lexical → syntax → semantic → IR → optimization → code generation.2

Footnotes

  1. https://en.wikipedia.org/wiki/Compiler - Overview of compilers and phases (lexical, syntax, semantic, IR, optimization, code generation). ↩ ↩2 ↩3 ↩4 ↩5

  2. https://en.wikipedia.org/wiki/Parser - Background on parsing and parse structures used by compiler front ends; complements syntax/AST discussion. ↩ ↩2 ↩3 ↩4 ↩5 ↩6

Compiler Design: Phases of a Compiler (Lexical to Code Generation)

1) Lexical Analysis (Scanning)

Lexical analysis reads the source program as a character stream and produces a stream of tokens such as identifiers, keywords, operators, and literals.2

Typical responsibilities

  • Tokenization: group characters into meaningful tokens (e.g., varName, 123, +, ==).
  • Classification: assign each token a type (identifier/keyword/operator/literal).
  • Lexical error handling: detect invalid characters or malformed literals.
  • Support for later phases: attach token attributes like:
    • identifier lexeme (name),
    • literal value,
    • line/column positions for error messages.2

Visual view

Pro Tip (engineering): Design your lexer so it also records source locations; this dramatically improves diagnostics quality in later phases.

Footnotes

  1. https://en.wikipedia.org/wiki/Compiler - Overview of compilers and phases (lexical, syntax, semantic, IR, optimization, code generation). ↩ ↩2 ↩3 ↩4

  2. https://en.wikipedia.org/wiki/Parser - Background on parsing and parse structures used by compiler front ends; complements syntax/AST discussion. ↩ ↩2 ↩3 ↩4

2) Syntax Analysis (Parsing)

Syntax analysis verifies the token stream conforms to the language grammar and constructs a structured representation such as a parse tree or an AST.2

Typical responsibilities

  • Grammar enforcement: determine whether sequences of tokens form valid grammatical constructs (e.g., declarations, statements, expressions).
  • Parse-tree/AST construction: build hierarchical structure that preserves program syntax needed for semantics and IR generation.
  • Syntax error reporting & recovery: detect where the input stops matching the grammar and attempt recovery to report more errors in one compile.

Visual view

Callout (warning): Naive error handling can cause cascading failures (one syntax mistake leading to many misleading later errors). Good parsers use strategies to recover locally.

Footnotes

  1. https://en.wikipedia.org/wiki/Compiler - Overview of compilers and phases (lexical, syntax, semantic, IR, optimization, code generation). ↩ ↩2

  2. https://en.wikipedia.org/wiki/Parser - Background on parsing and parse structures used by compiler front ends; complements syntax/AST discussion. ↩ ↩2 ↩3 ↩4

3) Semantic Analysis

Semantic analysis goes beyond syntax by checking meaning-related constraints that grammar alone cannot express.2

Typical responsibilities

  • Type checking: verify expression types are consistent with operators and assignments.2
  • Scope & binding rules: determine which identifier declaration each use refers to (name resolution).2
  • Attribute propagation: attach semantic attributes (types, storage info) to AST nodes used later by IR generation.
  • Semantic error handling: report errors like:
    • undeclared variables,
    • incompatible types,
    • invalid operations for a type.

Role of the Symbol Table

The symbol table is built/updated here and used to resolve identifiers and store their attributes (e.g., type, scope level, offsets).2

Footnotes

  1. https://en.wikipedia.org/wiki/Compiler - Overview of compilers and phases (lexical, syntax, semantic, IR, optimization, code generation). ↩ ↩2 ↩3 ↩4 ↩5

  2. https://en.wikipedia.org/wiki/Parser - Background on parsing and parse structures used by compiler front ends; complements syntax/AST discussion. ↩ ↩2 ↩3 ↩4 ↩5

4) Intermediate Code Generation (IR)

Intermediate code generation converts the semantically analyzed structure into an intermediate representation (IR).2

Why IR?

IR provides:

  • Machine independence: analysis and optimization become target-agnostic.
  • Uniform structure: later phases operate on a simpler form than raw AST.

Common IR forms include:

  • Three-address code (instructions with explicit operands),
  • Quadruples,
  • Static Single Assignment (SSA) style IR (in many modern compilers).

Visual view

Footnotes

  1. https://en.wikipedia.org/wiki/Compiler - Overview of compilers and phases (lexical, syntax, semantic, IR, optimization, code generation). ↩ ↩2

  2. https://en.wikipedia.org/wiki/Parser - Background on parsing and parse structures used by compiler front ends; complements syntax/AST discussion. ↩ ↩2 ↩3

5) Optimization

Optimization transforms IR to improve performance or reduce resource usage while keeping program behavior equivalent.2

Typical responsibilities

  • Local optimizations: remove redundant computations, simplify expressions (e.g., constant folding).
  • Global optimizations: across basic blocks (e.g., common subexpression elimination).
  • Control-flow improvements: reduce unnecessary branches and improve instruction scheduling (implementation-dependent).
  • Dead code elimination: remove code whose results are never used.

Two key terms

  • Basic block: optimization often operates by analyzing blocks and control-flow graphs.
  • Control-flow graph (CFG): a common representation for optimizations.

Footnotes

  1. https://en.wikipedia.org/wiki/Compiler - Overview of compilers and phases (lexical, syntax, semantic, IR, optimization, code generation). ↩

  2. https://en.wikipedia.org/wiki/Parser - Background on parsing and parse structures used by compiler front ends; complements syntax/AST discussion. ↩ ↩2 ↩3 ↩4 ↩5 ↩6

6) Code Generation

Code generation converts optimized IR into target instructions (e.g., assembly or machine code).

Typical responsibilities

  • Instruction selection: map IR operations to target instructions.
  • Register allocation: decide where values live (registers vs stack).
  • Addressing & memory layout: handle variables, temporaries, and calling conventions.2
  • Peephole optimization (often): small pattern-based improvements in emitted code.

Visual view

Footnotes

  1. https://en.wikipedia.org/wiki/Parser - Background on parsing and parse structures used by compiler front ends; complements syntax/AST discussion. ↩ ↩2 ↩3 ↩4 ↩5

  2. https://en.wikipedia.org/wiki/Compiler - Overview of compilers and phases (lexical, syntax, semantic, IR, optimization, code generation). ↩

Compiler Phase Workflow

Lexical Analysis

1

Characters → tokens; lexical errors detected."

Syntax Analysis

2

Tokens → parse tree/AST using grammar; syntax errors reported."

Semantic Analysis

3

Types, scopes, constraints verified; symbol table populated."

IR Generation

4

AST + attributes → intermediate representation."

Optimization

5

IR transformed to reduce time/space while preserving meaning."

Code Generation

6

Optimized IR → target assembly/machine code."

End-to-End Compilation Walkthrough

  1. 1
    Step 1

    Convert the character stream into a token stream; attach attributes like lexeme/value and source positions; report lexical errors.

  2. 2
    Step 2

    Use grammar rules to build a parse tree/AST; validate structure; apply error recovery when grammar mismatches occur.

  3. 3
    Step 3

    Build/update the symbol table; resolve identifiers; type-check expressions; propagate semantic attributes to the AST.

  4. 4
    Step 4

    Translate the AST into intermediate code (IR) that is easier to analyze and optimize than the source structure.

  5. 5
    Step 5

    Apply analysis and transformations (e.g., constant folding, dead code elimination) to produce a faster/smaller IR.

  6. 6
    Step 6

    Lower IR into target instructions, perform register allocation, and emit final assembly/machine code.

Where Errors Are Usually Detected

Typical categories of issues identified in each compiler phase.

Common Questions & Edge Cases

Compiler Phases Quick Recall

1 / 5
Question · Term

What does a lexer produce?

Click to reveal
Answer · Definition

A stream of tokens with attributes like lexemes/values and source positions (token).

Knowledge Check

Question 1 of 4
Q1Single choice

In the standard compiler model, which phase converts a character stream into tokens?

Explore Related Topics

1

Compiler Phase That Converts Source Code into Tokens

Lexical analysis, also called scanning or tokenization, is the compiler front‑end phase that reads raw source characters and groups them into tokens such as keywords, identifiers, literals, operators, and punctuation.

  • It converts each lexeme (e.g., int, x, =) into a token class, producing a token stream for the parser.
  • This phase runs before syntax analysis, which checks token order against the language grammar.
  • Whitespace and comments are typically ignored, and lexical errors (invalid characters) are reported here.
  • Lexical analysis is distinct from later phases like parsing, optimization, and code generation, which operate on already‑tokenized structures.
2

Passes in a Compiler: Definition and How Single- vs Multi-Pass Compilers Work

3

Introduction to Compiler Design and Architecture

The course introduces the fundamental structure and operation of modern compilers, describing how source code is transformed through front‑end analysis, intermediate representation, and back‑end generation.

  • Front‑end performs lexical, syntax, and semantic analysis, building a symbol table and an AST independent of the target.
  • An intermediate representation (IR) like three‑address code lets language‑independent optimizations run before back‑end register and instruction selection.
  • Optimization passes (e.g., dead‑code elimination, loop unrolling) on the IR consume about 50 % of compilation CPU time.
  • Top‑down parsers fail on left‑recursive grammars; they are fixed by rewriting A → Aα | β as A → β A' and A' → α A' | ε.