The new trace output is here and it seems you're right, isKeyword and isType (yes I'd decided to separate it again and keep both in the lexer) take a lot of time:
http://dpaste.1azy.net/0d6aff6b154874 106186 95403 0 pure nothrow bool Puzzle.Lexer.isKeyword(immutable(char)[]) 159688 78020 69289 0 pure nothrow bool Puzzle.Lexer.isType(immutable(char)[])
I never thought that. :)