Refactor blocks into their own regexes

This simplifies a lot of code. On the other hand, this does not change
the prior semantics of terminator detection, which means that if any
whitespace is taken before <.eat_terminator> is called, a final '}'
won't be recognized as terminating a statement.