And you wind up overloading a small number of syntax constructions for an endlessly expanding number of uses and soon you're in a twisty maze of parenthesis that all look alike. Look at how HP calculators got trashed by TI.
I'd grant that parser generators still suck, people still act like you're crazy when you say you want to be able to write one grammar and automatically generate not just a parser but an unparser. (I could do amazing stuff with Sphinx if only it supported RST output as well as schemaless RST.)
CASE tools in the 1990 could parse code, let you edit it in a GUI, and make a clean edit to the code (not mess up comments, whitespace, and the ordering of things which is only significant to your version control tools) like a professional programmer would. That's still like something that fell off a UFO.
You should totally be able to compose two grammars. I ought to be able to stick a SQL query right into the middle of program in Java or any other language and have it parsed to an AST. If parser generators were sane I could add
unless(X) { Y }
to a language like Java and add a method that rewrites it to
if(!X) { Y }
and it shouldn't be more than 50 lines of code including imports and ceremony, just a patch to the grammar (AST objects ought to be code generated from the grammar) a simple rewriting function and telling the system where to find the grammar patch and the new function.
Parsing Expression Grammars are a step in the right direction but for a PEG parser to be really revolutionary it needs a few features I've yet to see in one, in particular there has to be some easy way to specify operator precedence either numerically or with a set of statements like
Closer(*,+)
I am mostly disappointed w/ the PEG parser in Python because it falls short of revolutionary promises but you always get "fooled again" with parsing because people care about how fast their compilers are to the exclusion of almost everything else.