Skip to content
Part IA Michaelmas, Lent Term

Compiling Regular Expressions to NFA

Overview

We construct an NFA-ε\varepsilon for each regular expression by induction on the structure of the regex.

Each construction maintains the invariant that:

  • The NFA has exactly one start state (no incoming ε\varepsilon-transitions)
  • The NFA has exactly one accepting state (no outgoing ε\varepsilon-transitions)

This modular approach enables clean composition.

Base Cases

Epsilon: ε\varepsilon

NFA with one state that is both start and accepting.

NFA for epsilon

→q◯\xrightarrow{\quad} \textcircled{\scriptstyle q}

L(Mε)={ε}L(M_\varepsilon) = \{\varepsilon\}

Empty: ∅\emptyset

NFA with one state, start but not accepting.

NFA for empty set

→q\xrightarrow{\quad} q

L(M∅)=∅L(M_\emptyset) = \emptyset

Symbol: aa

NFA with two states with a single aa-labelled transition.

NFA for symbol a

→q0→aq1◯\xrightarrow{\quad} q_0 \xrightarrow{a} \textcircled{\scriptstyle q_1}

L(Ma)={a}L(M_a) = \{a\}

Union: R1∣R2R_1 | R_2

Construction

  1. Create new start state qsq_s
  2. Create new accepting state qfq_f
  3. Add ε\varepsilon-transitions:
    • qs→εstart(M1)q_s \xrightarrow{\varepsilon} \text{start}(M_1)
    • qs→εstart(M2)q_s \xrightarrow{\varepsilon} \text{start}(M_2)
    • accept(M1)→εqf\text{accept}(M_1) \xrightarrow{\varepsilon} q_f
    • accept(M2)→εqf\text{accept}(M_2) \xrightarrow{\varepsilon} q_f

NFA construction for union

Properties

  • Number of states: ∣M1∣+∣M2∣+2|M_1| + |M_2| + 2
  • Linear in regex size

Concatenation: R1R2R_1 R_2

Construction

  1. Add ε\varepsilon-transition from accept(M1)\text{accept}(M_1) to start(M2)\text{start}(M_2)
  2. Start state: start(M1)\text{start}(M_1)
  3. Accepting state: accept(M2)\text{accept}(M_2)

NFA construction for concatenation

Properties

  • Number of states: ∣M1∣+∣M2∣|M_1| + |M_2|
  • No new states added

Kleene Star: R∗R^*

Construction

  1. Create new start/accepting state q0q_0
  2. Add ε\varepsilon-transition q0→εstart(M)q_0 \xrightarrow{\varepsilon} \text{start}(M)
  3. Add ε\varepsilon-transition from accept(M)\text{accept}(M) to start(M)\text{start}(M) (loop)
  4. Add ε\varepsilon-transition from accept(M)\text{accept}(M) to q0q_0
  5. q0q_0 is the new accepting state

NFA construction for Kleene star

Alternative Construction

Some presentations use:

  • q0q_0 is start, ε→start(M)\varepsilon \to \text{start}(M)
  • Accepting states include accept(M)\text{accept}(M) and a new state
  • Loop back from accept(M)\text{accept}(M) to start(M)\text{start}(M)

Properties

  • Number of states: ∣M∣+1|M| + 1
  • Accepts ε\varepsilon and any concatenation of strings from L(M)L(M)

Size Analysis

Number of States

For regex RR of size nn (number of symbols and operators):

∣MR∣=O(n)|M_R| = O(n)

The Thompson construction builds NFAs with at most 2n2n states.

Comparison to DFA

The equivalent DFA may have up to 2∣MR∣2^{|M_R|} states.

The exponential blowup is unavoidable in the worst case.

Correctness

Theorem

For any regex RR, the construction produces NFA-ε\varepsilon MRM_R with L(MR)=L(R)L(M_R) = L(R).

Proof

By structural induction on RR.

Base cases: Direct verification for ε\varepsilon, ∅\emptyset, and symbols.

Union: w∈L(MR1∣R2)w \in L(M_{R_1|R_2}) iff there is a path through M1M_1 or M2M_2. This happens iff w∈L(M1)w \in L(M_1) or w∈L(M2)w \in L(M_2), iff w∈L(R1)∪L(R2)=L(R1∣R2)w \in L(R_1) \cup L(R_2) = L(R_1 | R_2).

Concatenation: w∈L(MR1R2)w \in L(M_{R_1 R_2}) iff we can split w=uvw = uv with path through M1M_1 on uu then through M2M_2 on vv. This happens iff u∈L(R1)u \in L(R_1) and v∈L(R2)v \in L(R_2), iff w∈L(R1)⋅L(R2)w \in L(R_1) \cdot L(R_2).

Star: Similar analysis using the fact that the construction accepts ε\varepsilon and any concatenation of strings from L(M)L(M).


Summary

  • Thompson’s construction: linear-size NFA for any regex
  • Union: new start with ε\varepsilon-edges to both branches
  • Concatenation: ε\varepsilon-edge from accept of first to start of second
  • Star: new start/accept with loop back
  • Total states: O(∣R∣)O(|R|) where ∣R∣|R| is regex size