The fact that I need to mention that yacc is an LALR(1) parser should suggest to the uninitiated how baroque virtually everything to do with parsing actually is. From a users perspective, LALR(1) really means "this thing doesn't parse a lot of things that I quite reasonably would expect it to be able to parse". In other words, yacc will generally refuse to work on most "human friendly" grammars, requiring the user to understand arcane nonsense such as "shift / reduce errors". This is all done in the name of efficiency. However the need for extreme efficiency in these algorithms often dates from the 60's. As we all know, computers were a little bit slower back in the day. What was slow back then often works at the speed of light today. There are parsing algorithms out there - Earley parsing is a particular favourite of mine - which can parse any context-free grammar, which constitutes the vast majority of modern programming languages. They may not be as fast as yacc but for the vast majority of purposes (up to and including full blown compilers) they're absolutely fine, and no user is likely to notice the difference in execution speed. However anyone who uses, say, Earley parsing will most definitely notice the massive ease in which grammars can be expressed and used. Therefore I believe the pain which most people associate with parsing text is the result of a 40 year old obsession with speed that today verges on the masochistic.
My personal favorite replacement for LALR parsers are Packrat parsers. Linear time, but they use more space. Luckily, RAM is a lot cheaper than it used to be and we needn't limit ourselves to 64kb chunks of data any more.