Ho implementato un parser LL1 in un approccio non ricorsivo con uno stack esplicito.
Il seguente algoritmo è tratto dal Libro del Drago:
set zp to point to the first symbol of w;
set X to the top stack symbol;
while ( X != $ ) { /* stack is not empty */
if ( X is a )
pop the stack and advance zp;
else if ( X is a terminal )
error();
else if ( M[X, a] is an error entry )
error();
else if ( M[X,a] = X -+ Y1Y2 Yk ) {
output the production X -+ YlY2 - . Yk;
pop the stack;
push Yk, Yk-1,. . . , Yl onto the stack, with Yl on top;
set X to the top stack symbol;
}
Il libro dice:
The parser is controlled by a program that considers X, the symbol on top of the stack, and a, the current input symbol. If X is a nonterminal, the parser chooses an X-production by consulting entry M[X, a] of the parsing table IM. (Additional code could be executed here, for example, code to construct a node in a parse tree.) Otherwise, it checks for a match between the terminal X and current input symbol a.
Tuttavia ho bisogno di maggiori informazioni su come costruire i nodi dell'albero dell'espressione con questo approccio. Ho una gerarchia di nodi di UnaryOperator, BinaryOperator, ecc ma non so dove installarlo.
Tuttavia non ho trovato alcun esempio semplice di questo (con ad esempio il linguaggio aritmetico).