O que você vai aprender
Distinguir atributos sintetizados e herdados e o sentido do fluxo de informação.
Anexar ações semânticas às produções de uma gramática (esquema de tradução).
Entender a tradução dirigida pela sintaxe (SDT) e os tipos S-atribuído e L-atribuído.
Avaliar atributos sobre uma árvore percorrendo-a na ordem correta.
A sintaxe está certa, e o significado?
A análise sintática garante que o programa tem forma válida — mas não que ele faz sentido. A frase x = y + 1 é uma árvore impecável; só a análise semântica pergunta: x existe? y existe? os tipos combinam?
Esta aula apresenta o instrumento formal para responder essas perguntas durante (ou logo após) o parsing: as gramáticas de atributos, que penduram informação nos nós da árvore, e a tradução dirigida pela sintaxe, que executa código conforme a estrutura é reconhecida.
Onde estamos no compilador
A análise semântica é a terceira fase do front-end e a ponte para a geração de código intermediário.
tokens→Sintática
árvore→Semântica
árvore anotada→Geração de RI
A saída desta fase é uma árvore sintática anotada (com atributos calculados) e uma tabela de símbolos preenchida — insumos diretos para gerar a representação intermediária.
O que é uma gramática de atributos
Um atributo é simplesmente um valor associado a um nó: o valor de uma expressão, o tipo de uma variável, o código gerado, a posição na memória. As regras dizem como calcular cada um.
Sintetizados × herdados
Atributo herdado. Calculado a partir dos atributos do pai ou dos irmãos. A informação flui de cima para baixo (ou lateralmente). Ex.: o tipo propagado numa declaração de lista de variáveis.
A distinção é o coração da aula: o sentido em que cada atributo se move pela árvore determina como avaliá-lo e em que ordem.
Uma gramática de atributos para valor
A gramática abaixo sintetiza o atributo val (o valor numérico) de cada nó:
Repare: val de cada nó vem sempre dos filhos. É um atributo sintetizado puro.
Avalie atributos passo a passo
Tradução dirigida pela sintaxe (SDT)
A SDT é a forma operacional de aplicar uma gramática de atributos: em vez de só declarar como os atributos se relacionam, descrevemos quando cada cálculo acontece.
Definição dirigida × esquema de tradução
Há duas variantes formais, e a diferença é sutil mas importante:
- SDD (Syntax-Directed Definition): só associa regras aos símbolos, sem dizer a ordem de execução — declarativa.
- Esquema de tradução (translation scheme): coloca as ações entre chaves em posições específicas do lado direito da produção, fixando o momento da execução — operacional.
A → B {ação} C executa a ação entre reconhecer B e C, o que é essencial para atributos herdados.A árvore como linha de montagem
Sintetizado × herdado lado a lado
| Sintetizado | Herdado | |
|---|---|---|
| Origem do valor | Atributos dos filhos | Atributos do pai/irmãos |
| Sentido do fluxo | De baixo para cima | De cima para baixo / lateral |
| Exemplo típico | Valor de uma expressão | Tipo numa declaração |
| Avaliação | Percurso pós-ordem | Exige ordem cuidadosa |
| Casa bem com | Parsing ascendente (LR) | Parsing descendente (LL) |
Os dois sentidos na árvore
Sintetizado e herdado coexistem na mesma árvore, movendo-se em direções opostas:
Uma gramática S-atribuída usa só sintetizados. Uma L-atribuída permite herdados, desde que cada herdado dependa apenas de atributos já calculados à esquerda — o que viabiliza avaliação em uma única passada.
Por que L-atribuído importa
Essa restrição é o que permite avaliar os atributos durante um único percurso da esquerda para a direita — exatamente como um parser descendente percorre a entrada. Por isso L-atribuído combina naturalmente com parsing LL e com a geração de código em uma passada.
Verifique seu entendimento
Em "T → T1 * F { T.val = T1.val * F.val }", o atributo T.val é de que tipo?
Propagando tipo numa declaração
Considere int a, b, c;. O tipo int aparece uma vez, mas precisa chegar a a, b e c. É um caso clássico de atributo herdado:
O atributo tipo desce de T para L e se propaga lateralmente por toda a lista — impossível de fazer só com sintetizados.
Armadilhas com atributos
Ordem de avaliação errada. Usar um atributo antes de ele ter sido calculado. Em gramáticas não-L-atributadas, pode não existir ordem de uma passada que funcione.
Misturar fases. Colocar ações pesadas (geração de código) onde deveriam estar só verificações — dificulta a separação semântica/geração.
Como projetar boas regras semânticas
Quando precisar de herdados, mantenha a gramática L-atributada para garantir avaliação em uma passada.
Nomeie atributos pelo que significam (
val, tipo, cod, lugar), não por como são calculados.Separe responsabilidades: uma ação por finalidade (calcular tipo, emitir código, registrar símbolo).
Pense antes de revelar
Por que o atributo "tipo" numa declaração "int a, b, c" precisa ser herdado, e não sintetizado?
Revise os termos
Como esta aula se liga ao curso
- Vem da aula 5 (GLC): as ações se penduram nas mesmas produções que descrevem a sintaxe.
- Usa a aula 9 (tabela de símbolos): a ação
inserir(id, tipo)escreve diretamente nela. - Prepara a aula 10 (RI): gerar código de três endereços é uma SDT cujos atributos são trechos de código.
- Sustenta a aula 13 (projeto): o mini-compilador é, em essência, uma SDT do começo ao fim.
O essencial da aula
Atividade em grupo · Calculadora com atributos
Em trios, anotem uma gramática de expressão com ações que calculam o valor.
Roteiro
- Partam da gramática E→E+T|T, T→T*F|F, F→(E)|num.
- Anexem a cada produção uma ação que sintetiza o atributo val.
- Tracem o cálculo de val para a entrada 2 + 3 * 4 subindo pela árvore.
- Confiram o resultado: 14.
Mini-quiz · Aula 8
20 questões sobre esta aula. Escolha e veja a explicação na hora.
📌 Resumo — leve isto para a prova
- A semântica verifica o significado: declarações, tipos e escopos, além da forma.
- Atributos sintetizados sobem dos filhos; herdados descem do pai/irmãos.
- A SDT anexa ações às produções, executadas durante o parsing.
- Gramáticas S-atribuídas usam só sintetizados; L-atribuídas permitem avaliação em uma passada.
- Regras sensíveis ao contexto vivem na semântica, não na GLC pura.