Recursive parser optimization by rewriting context-free grammars