LRM Prof. Mantovani ← Aulas da disciplina
Semana 8 · Aula 8 de 14

Análise semântica I — gramáticas de atributos

Depois da estrutura, o significado: atributos sintetizados e herdados, gramáticas de atributos e a tradução dirigida pela sintaxe (SDT) que executa ações ao longo da árvore.

📚 Compiladores📝 mini-quiz ao final
Objetivos da aula

O que você vai aprender

1

Distinguir atributos sintetizados e herdados e o sentido do fluxo de informação.

2

Anexar ações semânticas às produções de uma gramática (esquema de tradução).

3

Entender a tradução dirigida pela sintaxe (SDT) e os tipos S-atribuído e L-atribuído.

4

Avaliar atributos sobre uma árvore percorrendo-a na ordem correta.

1 · Motivação

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.

💡
Pense na semântica como o controle de qualidade da fábrica: a peça já saiu da linha de montagem (sintaxe), mas alguém precisa conferir se ela encaixa nas outras (tipos, escopos, declarações).
2 · Mapa

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.

Léxica
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.

3 · Conceito

O que é uma gramática de atributos

Gramática de atributos. Uma GLC em que cada símbolo (terminal ou não-terminal) recebe um conjunto de atributos, e cada produção recebe regras semânticas que calculam esses atributos a partir dos atributos vizinhos.

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.

4 · Explicação

Sintetizados × herdados

Atributo sintetizado. Calculado a partir dos atributos dos filhos do nó. A informação flui de baixo para cima. Ex.: o valor numérico de uma subexpressão.
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.

5 · Exemplo

Uma gramática de atributos para valor

A gramática abaixo sintetiza o atributo val (o valor numérico) de cada nó:

// regras semânticas entre chaves E → E1 + T { E.val = E1.val + T.val } E → T { E.val = T.val } T → T1 * F { T.val = T1.val * F.val } T → F { T.val = F.val } F → ( E ) { F.val = E.val } F → num { F.val = num.lexval }

Repare: val de cada nó vem sempre dos filhos. É um atributo sintetizado puro.

6 · Interativo

Avalie atributos passo a passo

Passo 1
As folhas recebem seus valores: num(2).lexval = 2, num(3).lexval = 3, num(4).lexval = 4.
Passo 2
Sobe nos fatores: F.val = 2, F.val = 3, F.val = 4 (regra F → num).
Passo 3
O produto 3 * 4: T.val = T1.val * F.val = 3 * 4 = 12 (regra T → T1 * F).
Passo 4
Os termos sobem: o termo da esquerda é T.val = 2; o da direita é T.val = 12.
Passo 5
A soma final: E.val = E1.val + T.val = 2 + 12 = 14. O atributo subiu até a raiz.
7 · Conceito

Tradução dirigida pela sintaxe (SDT)

SDT (Syntax-Directed Translation). Técnica em que se anexam ações semânticas às produções de uma gramática. À medida que o parser reconhece a estrutura, as ações são executadas — calculando atributos, emitindo código ou atualizando a tabela de símbolos.

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.

8 · Explicação

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.
💡
Em um esquema de tradução, a posição da ação importa: A → B {ação} C executa a ação entre reconhecer B e C, o que é essencial para atributos herdados.
9 · Analogia

A árvore como linha de montagem

🏭 Analogia
A árvore sintática é uma linha de montagem. Cada nó, ao ser processado, executa uma tarefa (a ação semântica) e passa o resultado adiante como atributo. Atributos sintetizados são peças que sobem da base para o produto final; atributos herdados são instruções que descem da gerência para a base. A SDT é o roteiro que diz a cada estação o que fazer e quando.
10 · Comparação

Sintetizado × herdado lado a lado

SintetizadoHerdado
Origem do valorAtributos dos filhosAtributos do pai/irmãos
Sentido do fluxoDe baixo para cimaDe cima para baixo / lateral
Exemplo típicoValor de uma expressãoTipo numa declaração
AvaliaçãoPercurso pós-ordemExige ordem cuidadosa
Casa bem comParsing ascendente (LR)Parsing descendente (LL)
11 · Fluxo

Os dois sentidos na árvore

Sintetizado e herdado coexistem na mesma árvore, movendo-se em direções opostas:

Pai↓ herdaFilho
Filhos↑ sintetizaPai

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.

12 · Aprofundamento

Por que L-atribuído importa

Gramática L-atributada. Cada atributo herdado de um símbolo do lado direito depende apenas dos atributos do pai e dos símbolos à sua esquerda na produção. O "L" vem de left-to-right.

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.

13 · Interativo

Verifique seu entendimento

Em "T → T1 * F { T.val = T1.val * F.val }", o atributo T.val é de que tipo?

T.val depende dos atributos dos filhos (T1.val e F.val), logo flui de baixo para cima: é sintetizado.
14 · Caso prático

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:

// T = tipo; L = lista de identificadores D → T L { L.tipo = T.tipo } // L herda o tipo de T L → L1 , id { L1.tipo = L.tipo; inserir(id, L.tipo) } L → id { inserir(id, L.tipo) }

O atributo tipo desce de T para L e se propaga lateralmente por toda a lista — impossível de fazer só com sintetizados.

15 · Erros comuns

Armadilhas com atributos

⚠️
Confundir o sentido. Tentar calcular um sintetizado a partir do pai (ou um herdado a partir dos filhos) gera dependências circulares ou valores indefinidos.

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.
16 · Dicas

Como projetar boas regras semânticas

Prefira atributos sintetizados sempre que possível: são mais simples e avaliáveis em pós-ordem.

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).
17 · Interativo

Pense antes de revelar

Por que o atributo "tipo" numa declaração "int a, b, c" precisa ser herdado, e não sintetizado?
Porque o tipo nasce no símbolo T (à esquerda) e precisa descer e se espalhar para cada identificador da lista L (à direita). Um atributo sintetizado só sobe dos filhos para o pai; ele jamais conseguiria levar a informação do irmão T para os identificadores dentro de L. O movimento exigido é de cima para baixo e lateral — a definição de atributo herdado.
18 · Flashcards

Revise os termos

Atributo sintetizadovirar
Calculado a partir dos filhos; flui de baixo para cima. Ex.: valor de uma expressão.
Atributo herdadovirar
Calculado a partir do pai/irmãos; flui de cima para baixo. Ex.: tipo numa declaração.
SDTvirar
Tradução dirigida pela sintaxe: ações anexadas às produções, executadas durante o parsing.
L-atributadavirar
Herdados dependem só de atributos à esquerda; permite avaliação em uma passada.
19 · Conexões

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.
20 · Síntese

O essencial da aula

🔑
A análise semântica verifica o significado que a sintaxe não captura. As gramáticas de atributos penduram valores nos nós: sintetizados sobem dos filhos, herdados descem do pai. A SDT torna isso operacional, anexando ações às produções e executando-as durante o parsing. Gramáticas L-atributadas permitem avaliar tudo em uma única passada.
Mão na massa · colaborativo

Atividade em grupo · Calculadora com atributos

Em trios, anotem uma gramática de expressão com ações que calculam o valor.

⏱️ 25 min👥 trios🧩 design semântico

Roteiro

  1. Partam da gramática E→E+T|T, T→T*F|F, F→(E)|num.
  2. Anexem a cada produção uma ação que sintetiza o atributo val.
  3. Tracem o cálculo de val para a entrada 2 + 3 * 4 subindo pela árvore.
  4. Confiram o resultado: 14.
Anotadorescreve as ações
Avaliadorpropaga os atributos
Conferentevalida o resultado
📤 Entrega: Gramática anotada + traço da avaliação de 2 + 3 * 4.
Teste seu conhecimento

Mini-quiz · Aula 8

20 questões sobre esta aula. Escolha e veja a explicação na hora.

0/20

📌 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.