Compiling Regular Expressions to NFA
Overview
We construct an NFA- 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 -transitions)
- The NFA has exactly one accepting state (no outgoing -transitions)
This modular approach enables clean composition.
Base Cases
Epsilon:
NFA with one state that is both start and accepting.
Empty:
NFA with one state, start but not accepting.
Symbol:
NFA with two states with a single -labelled transition.
Union:
Construction
- Create new start state
- Create new accepting state
- Add -transitions:
Properties
- Number of states:
- Linear in regex size
Concatenation:
Construction
- Add -transition from to
- Start state:
- Accepting state:
Properties
- Number of states:
- No new states added
Kleene Star:
Construction
- Create new start/accepting state
- Add -transition
- Add -transition from to (loop)
- Add -transition from to
- is the new accepting state
Alternative Construction
Some presentations use:
- is start,
- Accepting states include and a new state
- Loop back from to
Properties
- Number of states:
- Accepts and any concatenation of strings from
Size Analysis
Number of States
For regex of size (number of symbols and operators):
The Thompson construction builds NFAs with at most states.
Comparison to DFA
The equivalent DFA may have up to states.
The exponential blowup is unavoidable in the worst case.
Correctness
Theorem
For any regex , the construction produces NFA- with .
Proof
By structural induction on .
Base cases: Direct verification for , , and symbols.
Union: iff there is a path through or . This happens iff or , iff .
Concatenation: iff we can split with path through on then through on . This happens iff and , iff .
Star: Similar analysis using the fact that the construction accepts and any concatenation of strings from .
Summary
- Thompson’s construction: linear-size NFA for any regex
- Union: new start with -edges to both branches
- Concatenation: -edge from accept of first to start of second
- Star: new start/accept with loop back
- Total states: where is regex size