Yeah, I guess it comes down to the later compiler layers, when doing data structure manipulation for the actual code generation.
Pattern matching and FP/LP based algorithms are quite convenient, versus doing it in an imperative approach.
Hand coded parsers win on the error reporting front.
Interestingly, most mature industrial languages (e.g. Java, GCC, clang) use hand-coded recursive descent parsers. And of course such parsers can be implemented very easily from first principles using parser combinators in FP.
I've used both JavaCC and Antlr in the past for small DSLs, both are very good tools, when working with Java.