State machines are wonderful tools
Some random fun things you can do with DFAs&#x2F;NFAs:<p>1. From two machines you can build a single machine that corresponds to running them in lockstep&#x2F;parallel. Most language classes are closed under unions but regular languages stand out by being closed 
under intersections, and that relies on this construction. You can&#x27;t replicate this construction with pushdown automata to show that context-free languages are closed under intersection because the product automata would require two stacks. But in fact the intersection of a context-free language with a regular language is context-free via this construction.<p>2. You can run them backwards. Usually works best with NFAs since reversing a DFA can seriously inflate the state space. E.g. if you&#x27;re trying to match a regular expression of the form &#x27;&lt;re1&gt; string &lt;re2&gt;&#x27; you can search for &#x27;string&#x27; and then match re1 backward and re2 forward. Running machines backwards can also be used for computing capture groups after a match has been found since the fastest methods for matching don&#x27;t let you compute capture groups on the fly. Decoupling the re1 and re2 machines also means you end up with two independent machines with smaller state spaces, which means smaller, cache-friendlier lookup tables. See the next item for a less conventional example of what you can do with small state spaces.<p>3. While DFA execution seems inherently serial, it can actually be parallelized very effectively if the state space is small enough, through speculative execution. Suppose you want to lex a string in parallel by chopping it in half. You don&#x27;t know what state the DFA will be in when it reaches the halfway point, but you can process the second half for all possible states at that point. Then when both halves are finished you throw away all but one of the speculative answers for the second half based on the final state for the first half. This is extremely fast and practical with PSHUFB&#x2F;TBL-like instructions if your state space is small enough, at most 16 states for PSHUFB. You can mux together multiple PSHUFBs to go beyond that limit but the cost increases substantially. (This is a parallel prefix algorithm when applied recursively. As far as I know the application to parallel lexing goes back to the Hillis-Steele paper on data-parallel algorithms from 1986.)<p>4. There&#x27;s a critical optimization for the last algorithm which is sometimes applicable. A log file processor might have numerous internal states while processing a line, so you&#x27;d rather not speculate on all of them. Instead you can chop the file in half and from the second half seek forward to the next newline and start there. This avoids speculation entirely if there&#x27;s a unique state following a newline character regardless of what state you were in before the newline.