A resposta curta é que você usa pilhas. This é um bom exemplo, mas vou aplicá-lo a uma AST.
FYI, este é o Algoritmo do Shunting-Yard de Edsger Dijkstra.
Nesse caso, usarei uma pilha de operadores e uma pilha de expressões. Como os números são considerados expressões na maioria das linguagens, utilizarei a pilha de expressões para armazená-las.
class ExprNode:
char c
ExprNode operand1
ExprNode operand2
ExprNode(char num):
c = num
operand1 = operand2 = nil
Expr(char op, ExprNode e1, ExprNode e2):
c = op
operand1 = e1
operand2 = e2
# Parser
ExprNode parse(string input):
char c
while (c = input.getNextChar()):
if (c == '('):
operatorStack.push(c)
else if (c.isDigit()):
exprStack.push(ExprNode(c))
else if (c.isOperator()):
while(operatorStack.top().precedence >= c.precedence):
operator = operatorStack.pop()
# Careful! The second operand was pushed last.
e2 = exprStack.pop()
e1 = exprStack.pop()
exprStack.push(ExprNode(operator, e1, e2))
operatorStack.push(c)
else if (c == ')'):
while (operatorStack.top() != '('):
operator = operatorStack.pop()
# Careful! The second operand was pushed last.
e2 = exprStack.pop()
e1 = exprStack.pop()
exprStack.push(ExprNode(operator, e1, e2))
# Pop the '(' off the operator stack.
operatorStack.pop()
else:
error()
return nil
# There should only be one item on exprStack.
# It's the root node, so we return it.
return exprStack.pop()
(Por favor, seja gentil com meu código. Eu sei que não é robusto; é apenas para ser pseudocódigo.)
De qualquer forma, como você pode ver no código, expressões arbitrárias podem ser operandos para outras expressões. Se você tiver a seguinte entrada:
5 * 3 + (4 + 2 % 2 * 8)
o código que eu escrevi produziria este AST:
+
/ \
/ \
* +
/ \ / \
5 3 4 *
/ \
% 8
/ \
2 2
E quando você quiser produzir o código para essa AST, faça uma Traversal da Árvore de Pedidos de Postagens . Quando você visita um nó folha (com um número), você gera uma constante porque o compilador precisa conhecer os valores do operando. Quando você visita um nó com um operador, gera a instrução apropriada do operador. Por exemplo, o operador '+' fornece uma instrução "add".