Essa gramática é deixada recursiva:
Expression ::= AdditionExpression
AdditionExpression ::=
MultiplicationExpression
| AdditionExpression '+' MultiplicationExpression
| AdditionExpression '-' MultiplicationExpression
MultiplicationExpression ::=
Term
| MultiplicationExpression '*' Term
| MultiplicationExpression '/' Term
Term ::=
Number
| '(' AdditionExpression ')'
Number ::=
[+-]?[0-9]+(\.[0-9]+)?
Portanto, em teoria, a descida recursiva não funcionará. Mas, explorando as propriedades da gramática em que cada regra recursiva à esquerda corresponde a um nível de precedência específico, e que a aparência de um único token é suficiente para escolher a produção correta, as regras recursivas à esquerda podem ser analisadas individualmente com loops while.
Por exemplo, para analisar o AdditionExpression não terminal, esse pseudocódigo é suficiente:
function parse_addition_expression() {
num = parse_multiplication_expression()
while (has_token()) {
get_token()
if (current_token == PLUS)
num += parse_multiplication_expression()
else if (current_token == MINUS)
num -= parse_multiplication_expression()
else {
unget_token()
return num
}
}
return num
}
Qual é o nome correto para esse tipo de analisador? Este artigo informativo refere-se apenas a ele como "Solução clássica": https://www.engr.mun.ca/~theo/Misc/exp_parsing.htm
Deve haver um nome adequado para esse tipo de analisador.
Respostas:
É apenas um analisador LL (1) implementado com descida recursiva.
Começa com:
aplique a remoção de recursão esquerda para obter uma gramática LL (1):
escreva as funções correspondentes:
remova a recursão da cauda:
na linha:
e você só precisa adicionar o processamento semântico para obter sua função.
fonte
Você deseja analisar o LL (k ) análise . O artigo da Wikipedia é praticamente inútil, mas é basicamente descendente recursivo comk lookahead de símbolos.
Há também LL (∗ ), que permite olhar atento sem limites.
Veja aqui uma visão abrangente de quão poderosa é essa classe de analisadores.
fonte