It's tedious to write from scratch until it's complete. In my experience, it's more tedious to maintain a parser generator than a recursive descent parser. The reason is, if you write a recursive descent parser the right way, it's gonna be so simple even a freshman can maintain it at the end of the day.
After having written parser dozens of times nowadays I don't bother with anything other than recursive descent. In practice, I don't think anything works better.
Parsing combinator libraries are a good middle ground between a declarative grammar and useful error handling.