Many production compilers have hand-written parsers because of error reporting, not because of issues with parser-generator algorithms.
Consider the example of missing parenthesis. I can specify a grammar with the following:
EXPR =
...
| '(' EXPR ')'
The generated parser will not gracefully report a mismatched number of parentheses! Instead, it will report that the user's input is not formatted as expected, which makes it hard for the user to understand what went wrong.It is possible to modify the grammar to look for this case specifically:
EXPR =
...
| '(' EXPR ')'
| '(' EXPR // report this explicitly
But now I've just polluted my once-pristine grammar file. And adding all of the necessary error checks throughout the grammar will really make things complicated.So, many production compilers end-up with custom parsers to report unexpected input in a sane way. It is not that the algorithms are lacking; there is simply no mechanism for a generator to know what a mismatched parenthesis should be reported as.