This is going to be language-specific: parser combinators are much more pleasant in Haskell than in C++ for example.
Handwritten recursive descent has a lot going for it, error messages in particular.
Handwritten recursive descent has a lot going for it, error messages in particular.