There is a tension between the language (grammar) used to describe a language and the algorithm that is used to parse the language. In practice, a Pratt Parser (https://en.wikipedia.org/wiki/Pratt_parser) is often a good choice since it has the simplicity of a recursive descent parser but avoids the recursive plunge for objects like expressions.