It would be much nicer if we didn't have to turn either piece of code inside out. Knuth's coroutines In The Art of Computer Programming , Donald Knuth presents a solution to this sort of problem. His answer is to throw away the stack concept completely. Stop thinking of one process as the caller and the other as the callee, and start thinking of them as cooperating equals. So each time the decompressor emits another character, it saves its program counter and jumps to the last known location within the parser - and each time the parser needs another character, it saves its own program counter and jumps to the location saved by the decompressor.
Control shuttles back and forth between the two routines exactly as often as necessary.
This is very nice in theory, but in practice you can only do it in assembly language, because no commonly used high level language supports the coroutine call primitive. Languages like C depend utterly on their stack-based structure, so whenever control passes from any function to any other, one must be the caller and the other must be the callee. So if you want to write portable code, this technique is at least as impractical as the Unix pipe solution. We must accept that in reality, at the C level, one function will be caller and the other will be callee. The callee has all the problems.