Using exceptions is totally common, but this seems to raise/catch/log 6 errors each time it tries to parse a `for` statement. I'm a noob when it comes to compilers, but maybe a token -> function dictionary would be a better approach?
That does sound a bit extreme. (I freely admit I went by this description and never looked at the parser code myself, though some other portions I did read were pretty normal Python.)
Python implements iterators by raising a GeneratorExit, StopIteration or StopAsyncIteration exception. Exception handling is one of the core means of control flow in python along with function calls and if statements.
Also, because python lacks gotos and switch statements, "exception-oriented" code is a good way to implement efficient finite state machines common in compiler code.