Etapa 3: Analisador Sintático LL Manual
Objetivos
- Compreender o funcionamento de um Analisador Sintático Descendente Recursivo (Recursive Descent Parser).
- Implementar a gramática de expressões respeitando precedência de operadores.
- Integrar o Parser com a AST, construindo a árvore durante a análise.
Fundamentação Teórica
O Parser verifica se a sequência de tokens está gramaticalmente correta. Na abordagem descendente recursiva, cada Não-Terminal da gramática vira um método no código Java. Exemplo: Para a regra A -> B C, criamos um método parseA() que chama parseB() e depois parseC().
Atividades Práticas
1. Gramática de Expressões (Precedência)
Para garantir que a multiplicação (*) tenha precedência sobre a soma (+), estruturamos a gramática em níveis:
Expression: Trata soma e subtração.Term: Trata multiplicação e divisão.Factor: Trata números, identificadores e parênteses.
Pseudocódigo do método parseExpression():
public Expression parseExpression() {
Expression left = parseTerm(); // Desce um nível
while (currentToken is '+' or '-') {
Operator op = currentToken;
match(op); // Consome o operador
Expression right = parseTerm();
left = new BinaryExpression(left, right, op); // Monta o nó
}
return left;
}2. O Método match()
Crie um método auxiliar match(TokenType expected): - Se o token atual for do tipo esperado: consome o token (chama scanner.nextToken()) e retorna. - Se não for: Lança uma SyntaxException (“Esperado X, encontrado Y”).
3. Recuperação de Erros (Panic Mode)
Implemente uma estratégia simples: Quando ocorrer um erro sintático dentro de um comando, o compilador não deve parar imediatamente. - Reporte o erro. - Pule tokens (skip) até encontrar um delimitador de sincronização seguro, como um ponto-e-vírgula (;) ou end. - Retome a análise.
4. Implementação dos Comandos
Implemente métodos para: - parseCommand(): Verifica o próximo token para decidir se é if, while, identificador (atribuição) ou block. - parseAssignment(): Espera id, :=, expression, ;. - parseIf(): Espera if, expression, then, command, opcionalmente else, command.
O que entregar
- O código do
Parser. - Um programa principal que lê um arquivo fonte, faz o parsing e imprime a AST resultante (formato textual ou JSON).
Exemplo de Saída da AST para x := 10 + 5;:
Program
CommandList
AssignmentCommand (Target: x)
BinaryExpression (+)
Literal (10)
Literal (5)