Eliminating Left Recursion without the Epsilon
James Smith
TL;DR
A revised version of the standard algorithm to eliminate immediate left recursion is extended to a recursive algorithm to explicitly eliminate indirect left recursions, ensuring that all of the grammar's original rules are retained, resulting in parse trees that are still useful in practice.
Abstract
The standard algorithm to eliminate indirect left recursion takes a preventative approach, rewriting a grammar's rules so that indirect left recursion is no longer possible, rather than eliminating it only as and when it occurs. This approach results in many of the rules being lost, so that the parse trees that result are often devoid of the detail that the BNF was supposed to capture in the first place. Furthermore, the standard algorithm results in exponential blow-up as the BNF is rewritten, making it wholly unworkable in practice. To avoid these pitfalls, we revise the standard algorithm to eliminate direct left recursion and then take a graph-theoretic approach to eliminating indirect left recursion. We also extend the algorithm to rewrite the resultant parse trees in order to recover the parse trees that would have resulted if left recursion had not had to be eliminated in the first place. Therefore, aside from a couple of caveats, our algorithm works not just in theory but also in practice.
