I don’t know why they’re writing the parser using globals though instead of passing a pointer to a parser state struct.
Because there's only one. Why obfuscate that fact? Don't be tempted by the cargo-cult to make things more complex than they need to be just to appease some dogmatic "best" practices that actually aren't.
I think this is a really good example to point to in discussions of ‘cargo-cult’-ing. GP is merely reciting the standard ‘best’ practice for development in C, and on a more complex project or in another use case, they may be correct to do so. However, as you pointed out, in this case the globals are true single instance ‘objects’ and the use is semantically sensible and justified. It dovetails nicely with some of the DoD vs ECS discussion from the front page earlier today. Do what makes the most sense for your use case for reasons that apply to your project, everything else is abstraction.
Because there's only one. Why obfuscate that fact? Don't be tempted by the cargo-cult to make things more complex than they need to be just to appease some dogmatic "best" practices that actually aren't.