Regular expressions (regex) and Finite State Automata (FSA) are foundational concepts in theoretical computer science, compiler design, lexical analysis, and formal language theory. Understanding the conversion between regular expressions, Non-Deterministic Finite Automata (NFA), and Deterministic Finite Automata (DFA) is essential for writing high-performance parsers and preventing catastrophic exponential backtracking (Regular Expression Denial of Service - ReDoS).
This guide details Thompson's Construction algorithm, the Powerset Subset Construction for DFA determinization, Chomsky hierarchy classifications, and ReDoS mitigation.
+-----------------------------------------------------------------------------------------+
| FINITE AUTOMATA COMPARISON |
+-----------------------------------------------------------------------------------------+
| Dimension | Deterministic Finite Automaton(DFA)| Non-Deterministic Automaton(NFA)|
+------------------------+------------------------------------+---------------------------------+
| Transition Uniqueness | Exactly 1 transition per (state, σ)| Multiple transitions possible |
| $\epsilon$-Transitions | Not permitted | Permitted (free jumps) |
| String Matching Time | Strictly $O(N)$ linear time | $O(M \cdot N)$ or $O(2^N)$ back |
| State Space Size | Potentially $O(2^M)$ states | Exactly $O(M)$ states (Linear) |
| Canonical Engines | Rust `regex`, Google `RE2` | Python `re`, PCRE, JavaScript |
+-----------------------------------------------------------------------------------------+
Ken Thompson's algorithm compiles any regular expression of length M into an equivalent \epsilon-NFA with at most 2M states in O(M) time.
Thompson Construction Primitives:
1. Base Symbol 'a': (State 0) --- 'a' ---> ((State 1))
2. Concatenation 'ab': (S0) -- 'a' --> (S1) -- ε --> (S2) -- 'b' --> ((S3))
3. Alternation 'a|b': (S_in) -- ε --> (Branch A) -- ε --> ((S_out))
\-- ε --> (Branch B) -- ε --/
4. Kleene Star 'a*': (S_in) -- ε --> (Loop A) -- ε --> ((S_out))
\-------- ε -------------->/ (Bypass)
Backtracking engines (such as standard Python and JavaScript regex engines) evaluate ambiguous nested quantifiers like (a+)+$ in O(2^N) exponential time when matching non-matching inputs like "aaaaaaaaaaaaab".