Hi Bence,
Flink's CEP implementation is mainly based on this paper [1]. It mainly describes how the shared buffer is used to store efficiently the internal state of the NFA.
The translation of the Pattern API into the NFA happens in the NFACompiler.compileFactory method. For every pattern entry, we create a NFA state and insert transition between these states with the corresponding constraints. In case of a followedBy relation, we additionally add a reflexive transition where we ignore the current input symbol.
I hope this helps you a bit to better understand the implementation.
Cheers,
Till