Centro de Estudos, Desenvolvimento e Inovação em Software — CEDIS | UnB

Integração da análise semântica ao compilador

FGA0003 — Compiladores 1 · Semana 7 · Aula prática

Prof. Sergio Antônio Andrade de Freitas
Curso de Engenharia de Software · Universidade de Brasília · 2026
símbolo CEDIS logo UnB
símbolo CEDISCEDIS
2/35

Produto esperado da aula

01

Construir

Parser constrói a AST sem concentrar toda a semântica nas ações do Bison.

02

Validar

Módulo semântico resolve nomes, verifica tipos e anota nós.

03

Diagnosticar

Erros semânticos aparecem com linha, causa e contexto.

04

Testar

Casos válidos e inválidos são executados de forma reproduzível.

símbolo CEDISCEDIS
3/35

Roteiro de laboratório

  1. 01Reproduzir o estado atual do GitHub
  2. 02Auditar o que o código realmente implementa
  3. 03Separar parsing e análise semântica
  4. 04Adicionar int, float, tipos inferidos e TIPO_ERRO
  5. 05Melhorar diagnósticos e testes
  6. 06Documentar e publicar o incremento
seção

Ponto de partida

O que já existe e o que precisa mudar

símbolo CEDISCEDIS
5/35

O que já existe no GitHub

Arquivos presentes

  • parser.y e lexer.l
  • ast.c e ast.h
  • tabela.c e tabela.h
  • Makefile e run_tests.sh
  • README.md e tests/

Funcionalidades anunciadas

  • declaração de variáveis
  • redeclaração
  • compatibilidade de tipos
  • AST anotada
  • testes automatizados
símbolo CEDISCEDIS
6/35

Arquitetura atual

  • O parser já insere e busca símbolos.
  • A checagem de tipos aparece em ações do Bison.
  • A impressão é feita durante o parsing.
  • A prática irá modularizar esse fluxo.
Arquitetura atual no GitHub
símbolo CEDISCEDIS
7/35

Limitações encontradas

Problemas técnicos

  • float existe na enumeração, mas não é produzido
  • teste com string não chega à semântica
  • compatibilidade de atribuição é incompleta
  • nome de nó pode ser lido sem inicialização

Problemas arquiteturais

  • semântica concentrada no parser
  • tabela sem escopo explícito
  • diagnósticos sem localização suficiente
  • run_tests.sh apenas executa arquivos
símbolo CEDISCEDIS
8/35
Arquitetura desejada com parser, AST, passagens semânticas e diagnósticos

Arquitetura desejada

  • Flex continua produzindo tokens.
  • Bison constrói a AST.
  • Semântica percorre a AST em passagens.
  • Diagnósticos são acumulados e impressos ao final.
símbolo CEDISCEDIS
9/35

Checkpoint 1 — linha de base

git

Atualizar

git pull

cd

Entrar

cd "semana 07/src"

make

Compilar

make clean && make

run

Testar

./run_tests.sh

símbolo CEDISCEDIS
10/35

Auditoria rápida da execução

Observe

  • o que compila
  • quais mensagens aparecem
  • se os testes distinguem sucesso/falha
  • se a AST mostra tipos

Registre

  • erros léxicos versus semânticos
  • casos sem saída esperada
  • diagnósticos sem linha
  • funcionalidades prometidas, mas ausentes
seção

Parte 1

Corrigir a base e preparar os tipos

símbolo CEDISCEDIS
12/35

Correções iniciais obrigatórias

C

CFLAGS

Adicionar -Wall -Wextra -g no Makefile.

L

Linha

Usar %option yylineno no lexer.

AST

Nós

Inicializar todos os campos da AST.

M

Memória

Adicionar funções de liberação.

símbolo CEDISCEDIS
13/35

Linguagem mínima da prática

Tipos

  • int
  • float
  • TIPO_ERRO

Construções

  • declaração: int a; float b;
  • atribuição: a = expr;
  • expressões com + e -
  • identificadores, inteiros e reais
símbolo CEDISCEDIS
14/35

Regras semânticas adotadas

Expressões

  • int + int → int
  • int + float → float
  • float + int → float
  • float + float → float

Atribuições

  • int → float é permitido
  • float → int é erro sem cast
  • uso exige declaração prévia
  • redeclaração no mesmo escopo é erro
símbolo CEDISCEDIS
15/35

Propagação de tipos

  • Analise filhos antes do nó pai.
  • Promova int para float quando permitido.
  • Anote o tipo inferido no nó.
  • Não gere diagnósticos em cascata.
Propagação de tipos na AST
seção

Parte 2

Separar construção da AST e validação

símbolo CEDISCEDIS
17/35

Remover semântica direta do parser

Antes

ID { Simbolo *s = buscarSimbolo($1); if (!s) yyerror("nao declarado"); }

Depois

ID { $$ = ast_criar_identificador($1, yylineno); }

símbolo CEDISCEDIS
18/35

Primeira e segunda passagens

  • Passagem 1: declarações, escopos e tabela.
  • Passagem 2: usos, tipos e atribuições.
  • A tabela alimenta a resolução de nomes.
  • A AST recebe anotações semânticas.
Duas passagens semânticas
símbolo CEDISCEDIS
19/35

Passagem 1 — declarações

Entrada

  • AST_PROGRAMA
  • AST_DECLARACAO
  • nome, tipo e linha

Saída

  • símbolos inseridos
  • redeclarações detectadas
  • tipo declarado registrado
  • escopo inicial global
símbolo CEDISCEDIS
20/35
Resolução de uso de identificador na tabela de símbolos

Resolução de identificadores

  • Buscar o nome na tabela ativa.
  • Anotar o nó com o símbolo resolvido.
  • Copiar o tipo do símbolo para o nó.
  • Gerar erro se o símbolo não existir.
símbolo CEDISCEDIS
21/35

Passagem 2 — expressões e atribuições

Expressões

  • identificador → tipo do símbolo
  • literal inteiro → int
  • literal real → float
  • operação → tipo resultante

Atribuições

  • resolver lado esquerdo
  • analisar expressão
  • comparar tipo declarado e tipo inferido
  • registrar diagnóstico se incompatível
símbolo CEDISCEDIS
22/35

Introduzir TIPO_ERRO

1

Causa única

O primeiro erro explica a origem do problema.

2

Propagação

Nós dependentes recebem TIPO_ERRO.

3

Menos ruído

Evita mensagens derivadas e enganadoras.

4

Mais clareza

O estudante foca no erro que precisa corrigir.

seção

Parte 3

Gerar saídas úteis para depuração

símbolo CEDISCEDIS
24/35

Diagnósticos localizados

Formato

[SEMÂNTICO] Linha 4: identificador 'total' não declarado. [SEMÂNTICO] Linha 7: 'a' já foi declarado na linha 2.

Resumo

Análise semântica concluída com 2 erros. Nenhuma geração posterior deve ocorrer se houver erro semântico.

símbolo CEDISCEDIS
25/35
AST antes e depois da anotação semântica

AST anotada

  • Tipo inferido no nó.
  • Símbolo resolvido em identificadores.
  • Conversões ou erros registrados.
  • Saída facilita depuração do compilador.
símbolo CEDISCEDIS
26/35

Testes atuais × testes reais

Atual

  • percorre tests/*.txt
  • imprime saída
  • não compara esperado
  • não classifica passou/falhou

Desejado

  • separa válidos e inválidos
  • compara saída ou códigos
  • exibe PASSOU/FALHOU
  • interrompe se make falhar
símbolo CEDISCEDIS
27/35

Suíte mínima de testes

Válidos

tests/validos/ 01-declaracao.comp1 02-promocao.comp1 03-expressoes.comp1

Inválidos

tests/invalidos/ 01-nao-declarada.comp1 02-redeclaracao.comp1 03-atribuicao-invalida.comp1

símbolo CEDISCEDIS
28/35

Checkpoint 2 — tipos

T

int e float

Lexer e parser reconhecem os dois tipos.

P

Promoção

int + float resulta em float.

A

Atribuição

float para int gera erro.

E

TIPO_ERRO

Erros são propagados sem cascata.

símbolo CEDISCEDIS
29/35

Checkpoint 3 — evidências

AST

AST anotada

Nós exibem tipos inferidos e símbolos resolvidos.

TAB

Tabela

Declarações aparecem com tipo, escopo e linha.

MSG

Mensagens

Diagnósticos possuem linha e causa.

TST

Testes

Casos positivos e negativos estão versionados.

símbolo CEDISCEDIS
30/35

Níveis de conclusão

Essencial

  • não declarada
  • redeclaração
  • expressões int
  • AST com tipos

Esperado e avançado

  • int e float
  • promoção numérica
  • diagnósticos acumulados
  • testes com PASSOU/FALHOU
símbolo CEDISCEDIS
31/35

Documentação e Git

MD

README

Descrever regras semânticas implementadas.

OK

Testes

Explicar como executar validos e invalidos.

Git

Commit

git commit -m "Integra análise semântica"

Push

git push

seção

Próximo passo

Do programa validado ao código intermediário

símbolo CEDISCEDIS
33/35

Checklist final

1

Parser

Constrói a AST sem concentrar a semântica.

2

Semântica

Resolve nomes, tipos e atribuições.

3

Diagnóstico

Acumula erros com localização.

4

Projeto

README, testes e commit publicados.

símbolo CEDISCEDIS
34/35

Referências e materiais

    símbolo CEDISCEDIS
    35/35

    Encerramento

    → avançar · ← voltar · deslize (touch) · n notas · f tela cheia · p imprimir