Most of the JIT compilers take an intermediate or bytecode language as their input. For that reason, the structure of a JIT compiler is closer to that of a traditional assembler than that of an AOT compiler.
Lexical analysis and parsing are much simpler, because the input language is much simpler that your typical high level programming language.
Semantic analysis is probably completely absent, trusting that the bytecode doesn't try to do the impossible (like mixing integer and floating point operations without the required conversions).
What a AOT and JIT compiler have in common are the optimisations and code generation, although a JIT compiler can't perform lengthy optimisations but can generate more specific instructions foreasily do optimisations that require information about how the target processorcode is actually being used.