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)
Back to top