Após a Análise Léxica nos dar os Tokens e a Análise Sintática construir a Árvore Sintática Abstrata (AST), a fase de Análise Semântica atua como um inspetor de lógica e significado.
Se a Sintaxe verifica se o código está bem formado, a Semântica verifica se ele está significativo e válido para a linguagem.
O Analisador Semântico percorre a AST e usa a Tabela de Símbolos (criada na fase léxica e atualizada nas fases seguintes) para responder a perguntas críticas sobre o código:
Entrada (AST e Tabela de Símbolos) | Analisador Semântico | Saída (AST Anotada/Verificada) | ||
Estrutura do programa | Estrutura verificada e pronta para otimização |
O principal foco nesta fase é o Check de Tipos (Type Checking).
Este é o trabalho mais crucial da análise semântica. Ele garante que as operações estejam sendo feitas com os tipos de dados compatíveis.
Exemplo de Erros Semânticos (de Tipo):
Incompatibilidade de Tipos: Tentar somar um número a uma string ou atribuir um valor booleano a uma variável inteira.
Código: int idade = "vinte e cinco";
Erro Semântico: Você não pode colocar um texto (string) em uma caixa (variável) feita para guardar números inteiros (int).
Uso de Variáveis Não Declaradas: Tentar usar um nome que o compilador não reconhece.
Código: total = subtotal + imposto;
(Onde imposto
não foi declarado).
Erro Semântico: O compilador não encontra a variável imposto
na Tabela de Símbolos. Ele avisa: “Uso de identificador não declarado.”
Argumentos Incorretos em Funções: Chamar uma função passando o número ou o tipo errado de parâmetros.
Código: imprimirNome(10, true);
(Se a função imprimirNome
espera apenas um argumento do tipo string).
Erro Semântico: A função foi chamada com tipos errados ou número incorreto de argumentos.
Além da checagem de tipos, o analisador semântico lida com:
Verificação de Escopo: Garantir que uma variável só está sendo usada dentro da região do código (bloco ou função) onde ela foi declarada.
Controle de Fluxo: Em algumas linguagens, verificar se todos os caminhos em um if
/else
retornam um valor, se necessário.
Anotação da AST: Depois que um nó da AST é verificado e considerado válido, o analisador anota informações importantes (como o tipo de retorno da expressão ou o escopo da variável) diretamente na árvore. Isso facilita as fases seguintes.
É importante notar que a Análise Semântica não pega todos os erros. Ela não consegue detectar erros de Lógica.
Erro Semântico (Detectável): int resultado = "olá" * 5;
(String e Multiplicação são incompatíveis).
Erro de Lógica (Não Detectável pelo Compilador): salarioLiquido = salarioBruto + deducoes;
(A sintaxe e os tipos estão corretos, mas o programador errou a lógica, pois deveria ser subtração).
O compilador não pode saber a sua intenção, apenas se as regras da linguagem foram seguidas.
Com a AST semanticamente verificada e anotada, o compilador passa para a fase de Geração de Código Intermediário ou Otimização, pois ele agora tem certeza de que o programa é estruturalmente válido e faz sentido lógico em termos de tipos de dados.
A Análise Semântica é a última checagem de “qualidade” antes do código começar a ser preparado para execução.