I know of lex/yacc/menhir, but I’m a bit sceptic using them, it looks like almost no production compilers are using them? For some reason almost all of them uses a hand-written top-down recursive decent parser, usually in a single huge file called “parser”. Some people say it’s because it’s easier to produce nice error messages this way, and for performance reasons. Still feels odd. It would be much nicer if both humans and compilers could both use a formal grammar as the primary source of information to understand source code written in a language, instead of having to try to understand huge parser files.
Here is a list of some modern compilers and the corresponding parser for each one: