Regex to NFA converter: Thompson’s construction step by step
Type a regular expression and this converter builds the equivalent nondeterministic finite automaton (NFA) with Thompson’s construction. Step through it one sub-expression at a time, read off the transition table, then run strings through the finished NFA to see which states are live after every symbol.
On this page
Regex to NFA converterThompson’s construction, one sub-expression at a time.
States are numbered in the order they are created. Orange: the fragment just built. ε-transitions consume no input.
Pseudocode
- for each sub-expression, innermost first:
- symbol c: new s, f; s –c→ f
- ε: new s, f; s –ε→ f
- RS: accept(R) –ε→ start(S)
- R|S: new s, f; s –ε→ start(R), start(S); accept(R), accept(S) –ε→ f
- R*: new s, f; s –ε→ start(R), f; accept(R) –ε→ start(R), f
- R+: as R*, but without the s –ε→ f skip
- R?: new s, f; s –ε→ start(R), f; accept(R) –ε→ f
- the last fragment’s s and f are the start and accepting state
Result
Test many strings
Transition table
How to write the expression
The converter understands the operators of formal language theory, which are a small core of the regular expressions in programming languages.
| Write | Meaning | Example |
|---|---|---|
ab | concatenation: a then b | abb matches only abb |
a|b | union (alternation): a or b | cat|dog |
a* | Kleene star: zero or more a | (ab)* matches ε, ab, abab, … |
a+ | one or more a | 0+ matches 0, 00, 000, … |
a? | optional: zero or one a | colou?r |
( ) | grouping | (a|b)*abb |
ε | the empty string | (a|ε)b is the same as a?b |
\*, \|, … | a literal special character | a\+b matches a+b |
Precedence runs from tightest to loosest: the postfix operators *, + and ?, then concatenation, then |. So ab|c* means . Every other character is a literal symbol of the alphabet, and spaces are ignored. An empty alternative stands for ε, so a| matches a or the empty string. Character classes such as [a-z], anchors and back-references are not part of the theory and are not supported; write (a|b|c) instead of [abc].
Thompson’s construction in five rules
Ken Thompson described this construction in 1968 for a text editor’s search command. It builds the NFA bottom-up, one small fragment per sub-expression. Each fragment has exactly one start state and one accepting state, and nothing ever leaves its accepting state, so fragments can be plugged together like pieces of track.
- A symbol becomes two states joined by one -transition.
- ε becomes two states joined by an ε-transition, which moves without reading input.
- Concatenation links the accepting state of ’s fragment to the start of ’s with an ε-transition.
- Union adds a new start state with ε-transitions into both fragments, and a new accepting state that both fragments lead into.
- Star adds new start and accepting states, a back edge from the end of to its beginning (repeat), and a skip edge from the new start to the new end (zero times). drops the skip edge; drops the back edge.
Because every rule adds at most two states, an expression with symbols and operators gives an NFA with at most states, and every state has at most two outgoing transitions. That linear size is why the construction is still used: the NFA is small, quick to build, and easy to simulate.
Worked example: ab|c
The parser reads this as , so the construction runs innermost first: fragments for a (states 0, 1), b (2, 3), their concatenation (an ε-edge 1 → 2), the fragment for c (4, 5), and finally the union, which adds start state 6 and accepting state 7. That is 8 states and 8 transitions. Load ab|c in the converter and step through it to see exactly this order.
What the diagram shows
- States are numbered in creation order, so the numbers tell you which sub-expression made them, as in most textbooks.
- The layout follows the expression. Alternatives of a union are stacked, back edges of a star loop over the top of their fragment, and skip edges pass underneath.
- In Run a string mode the highlighted states are all the states the NFA could be in after reading the input so far. An NFA accepts if any of them is accepting when the input runs out.
The default expression, (a|b)*abb (strings over a and b that end in abb), gives 14 states and 16 transitions, 11 of them ε-moves. Of the strings abb, aabb, babb, ab, abba, it accepts abb, aabb, babb.
From NFA to DFA
An NFA is easy to build but awkward to run directly, because it can be in many states at once. The next step in a lexer generator or regex compiler is the subset construction, which turns the NFA into a deterministic automaton whose states are sets of NFA states. The NFA to DFA converter takes the same expression and steps through it, and the DFA simulator lets you edit and test the result. The theory behind all three tools is in from regular expressions to automata.
References
- K. Thompson, “Programming techniques: Regular expression search algorithm”, Communications of the ACM 11(6), 1968. doi:10.1145/363347.363387
- A. V. Aho, M. S. Lam, R. Sethi and J. D. Ullman, Compilers: Principles, Techniques, and Tools, 2nd ed., Pearson, 2006. Section 3.7.
- M. Sipser, Introduction to the Theory of Computation, 3rd ed., Cengage, 2012. Section 1.3.