Buscar

plp-aula03-cap3Sebesta

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 42 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 42 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 42 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Paradigmas de 
Linguagem de 
Programação
Descrevendo a sintaxe e a 
semântica – Parte 2
 
Tópicos
 Métodos formais para descrever a 
sintaxe:
EBNF.
Grafos de sintaxe.
Gramáticas de atributos.
 
EBNF 
 EBNF – versão estendida da BNF:
Não aumenta poder descritivo, mas 
aumenta sua legibilidade e 
capacidade de escrita.
 
EBNF – parte opcional
 Parte opcional de um lado direito, 
definida por colchetes:
 Exemplo em C:
EBNF:
• <seleção> → if (<expressão>) <instrução> 
[else <instrução>];
BNF:
• <seleção> → if (<expressão>) <instrução>;
• <seleção> → if (<expressão>) <instrução> 
else <instrução>;
 
EBNF – repetição 
 Indicar que o lado direito pode ser repetido 
indefinidamente ou omitido completamente, definido 
por chaves.
 Permite que listas sejam criadas com uma única 
regra, em vez de usar recursão e duas regras.
 Exemplo:
 EBNF :
• <list_ident> → <identificador> {, <identificador>}
 BNF:
• <list_ident> → <identificador> 
• <list_ident> → <identificador>, <list_ident>
 
EBNF – múltipla escolha
 Opções de múltipla escolha: quando um 
único elemento deve ser escolhido de um 
grupo, as opções são colocadas entre 
parênteses e separadas por OU ‘|’.
Exemplo em Pascal:
• EBNF:
• <inst_for> → for <var> := <expr> (to|downto) <expr> 
do <inst>
• BNF:
• <inst_for> → for <var> := <expr> to <expr> do <inst> 
• <inst_for> → for <var> := <expr> downto <expr> do 
<inst>
 
EBNF
 Colchetes, chaves e parênteses são 
metassímbolos (ferramentas 
notacionais) e não símbolos 
terminais.
Nos casos em que estes 
metassímbolos também são símbolos 
terminais na linguagem sendo 
descrita, as instâncias dos símbolos 
terminais podem ser sublinhadas.
 
BNF x EBNF
 BNF:
<expr> -> <expr> + <termo> |
 <expr> - <termo> |
 <termo>
<termo> -> <termo> * <fator> |
<termo> / <fator> |
<fator>
 
BNF x EBNF
 EBNF:
<expr> -> <termo> {(+|-)<termo>}
<termo> -> <fator> {(*|/) 
<fator>}
 
Exercício 1
 Dadas as regras em BNF, escreva suas 
formas equivalentes em EBNF.
 <inst_atrib> → <ident> = <expr>;
 <signed_number> → <sign> <number> | <number> 
 <inst_while> → while <expr> { <lista_inst> } 
 <lista_inst> → <inst> | <inst> <lista_inst>
 
Solução 1
 BNF = EBNF: 
• <inst_atrib> → <ident> = <expr>;
 BNF:
• <signed_number> → <sign> <number> | <number> 
 EBNF:
• <signed_number> → [ <sign> ] number 
 BNF:
• <inst_while> → while <expr> { <lista_inst> } 
• <lista_inst> → <inst> | <inst> <lista_inst>
 EBNF:
• <inst_while> → while <expr> {{ <inst> }}
 
Exercício 2
 Dada a descrição EBNF para a instrução if em Ada, 
escreva seu correspondente em BNF:
 <inst_if> → if <condição> then <inst> {<else_if>} 
[else <inst>] end if
 <else_if> → elseif <condição> then <inst>
 
Solução 2
 EBNF:
 <inst_if> → if <condição> then <inst> {<else_if>} [else 
<inst>] end if
 <else_if> → elseif <condição> then <inst>
 BFN:
 <inst_if> → if <condição> then <inst> end if | 
if <condição> then <inst> else <inst> end if |
if <condição> then <inst> <elseif> end if |
if <condição> then <inst> <elseif> else <inst> end if
 <else_if> → elseif <condição> then <inst> |
 elseif <condição> then <inst> <else_if> 
 
Grafos de sintaxe
 As informações nas regras BNF e EBNF 
podem ser representadas em grafos 
dirigidos, chamados grafos de sintaxe.
 Um grafo distinto é usado para cada 
unidade sintática.
 Aumentam legibilidade ao permitir-nos 
visualizá-los.
 Símbolos:
Símbolos terminais
Símbolos não terminais
 
Grafos de sintaxe
 <inst_atrib> → <ident> = <expr>;
Símbolos 
terminais 
sublinhados
=
inst_atrib
ident expr ;
{while }inst
inst_while
expr
 <inst_while> → while <expr> {{ <inst> }}
 
Exercício 3
 Construa os grafos de sintaxe para a 
descrição EBNF da instrução if em 
Ada:
<inst_if> → if <condição> then 
<inst> {<else_if>} [else <inst>] end if
<else_if> → elseif <condição> then 
<inst>
 
Solução 3
else_if instthencondiçãoelseif
 <inst_if> → if <condição> then <inst> {<else_if>} [else <inst>] 
end if
 <else_if> → elseif <condição> then <inst>
inst_if
end_if
elseelse_ifinstthencondiçãoif inst
 
Gramática de 
atributos
 
Gramática de atributos
 Usada para descrever mais detalhes de uma 
LP do que é possível com uma gramática 
livre de contexto.
 
Semântica estática
 Exemplos de características de LP difíceis ou impossíveis de 
escrever em BNF:
 Regras de compatibilidade de tipos são difíceis de escrever:
• Ex: em Java um valor real não pode ser atribuído a uma variável 
do tipo inteiro, ainda que o oposto seja legal → exige símbolos não 
terminais e regras adicionais para ser especificado.
 Não é possível descrever a regra segundo a qual todas as variáveis 
devem ser declaradas antes de serem referenciadas.
 Esses exemplos fazem parte da categoria das regras de 
linguagem chamada semântica estática.
 Semântica estática se relaciona apenas indiretamente com o 
significado dos programas durante a execução, tem relação com 
as formas legais dos programas (sintaxe).
 
Gramáticas de atributos
 Usadas para descrever mais detalhes de uma LP do que é 
possível com uma gramática livre de contexto.
 São gramáticas com adição de:
 Atributos: associados a símbolos gramaticais (são 
semelhantes a variáveis na medida em que podem 
ter valores atribuídos a eles).
 Funções de computação de atributos (funções 
semânticas): são associadas as regras gramaticais 
para especificar como os valores de atributos são 
computados.
 Funções predicadas: declaram a parte da sintaxe e 
as regras semânticas estáticas da linguagem. 
 
Gramáticas de atributos
 Proposta por Knuth, 1968.
 Definição: uma gramática de atributos é 
uma gramática BNF com as seguintes 
adições:
Para cada símbolo gramatical X há um 
conjunto A(X) de valores de atributos.
Cada regra tem um conjunto de funções que 
define certos atributos dos símbolos não 
terminais na regra. 
Cada regra tem um conjunto de predicados 
(possivelmente vazio) para verificar 
consistência de atributos.
 
Gramáticas de atributos
 Atributos:
Os símbolos terminais têm atributos 
intrínsecos (que descrevem a informação 
léxica a cada um deles associada). 
Os símbolos não-terminais são associados 
com atributos genéricos, através dos quais 
se poderá sintetizar informação semântica 
(subindo na árvore de sintaxe abstrata, das 
folhas para a raiz), ou herdar informação 
semântica (descendo na árvore de sintaxe 
abstrata, do topo para as folhas), 
 
Gramáticas de atributos
 Seja X0 → X1 ... Xn uma regra:
 Funções na forma S(X0) = f(A(X1), ... A(Xn)) definem 
atributos sintetizados. 
 Funções na forma I(Xj) = f(A(X0), ... , A(Xj-1)), para i ≤ j 
 ≤ n, definem atributos herdados.
 Inicialmente, os atributos intrínsecos estão nas 
folhas.
 Função predicada tem a forma de expressão 
booleana no conjunto de atributos {A(X0), ..., A(Xn)}. 
• As únicas derivações permitidas são aquelas em 
que todo predicado associado a cada não 
terminal é verdadeiro. 
• Uma função predicada falsa indica uma violação 
das regras de sintaxe ou semântica estática da 
linguagem.
 
Gramáticas de atributos
 Uma árvore de análise de uma 
gramática de atributos é aquela baseada 
em sua gramática BNF subjacente, com 
um conjunto possivelmente vazio de 
valores de atributos anexados a cada 
vértice.
 Uma árvore de análise é dita totalmente 
atribuída se todos os valores de 
atributos tiverem sido computados.
 
Gramáticas de atributos
 Como os valoresdos atributos são 
computados?
Se todos os atributos forem herdados, 
a árvore pode ser construída de cima 
pra baixo. 
Se todos os atributos forem 
sintetizados, a árvore pode ser 
construída de baixo para cima. 
Em muitos casos, ambos atributos 
são usados, e alguma combinação 
deve ser usada.
 
Gramáticas de atributos
 Exemplo de gramática de atributos que descreve a regra na qual o 
nome end de um procedimento em Ada deve coincidir com o nome 
do procedimento.
Regra de sintaxe: <def_proc> → procedure <nome_do_proc>[1] 
<corpo_do_proc> end <nome_do_proc>[2];
Regra semântica: <nome_do_proc>[1].string = 
<nome_do_proc>[2].string
Observações:
 O atributo de cadeia de <nome_do_proc> é <nome_do_proc>.string 
 Há mais de uma ocorrência do não-terminal <nome_do_proc>, então 
utiliza-se colchetes para distingui-las.
 
Gramáticas de atributos
 Exemplo de gramática de atributos usada para 
verificar as regras de tipo de uma instrução 
simples de atribuição.
 BNF:
<atribuição> → <var> = <expr>
<expr> → <var> + <var>
| <var>
<var> → A | B | C
 
Gramáticas de atributos
 Parte sintática da gramática de atributos:
<atribuição> → <var> = <expr>
<expr> → <var> + <var>
| <var>
<var> → A | B | C
 Atributos para os símbolos não-terminais:
 tipo_efetivo: um atributo sintetizado associado a <var> e <expr>.
• Usado para armazenar o tipo efetivo, int ou real. No caso de uma expressão o 
tipo é determinado a partir dos tipos reais do vértice-filho. No caso de uma 
variável o tipo é intrínseco.
 tipo_esperado: um atributo herdado associado a <expr>.
• Usado para armazenar o tipo int ou real, esperado para expressão, conforme 
determinado pelo tipo da variável no lado esquerdo da atribuição.
 
Gramáticas de atributos
Regra de sintaxe: <atribuição> → <var> = <expr>
Regra semântica: <expr>.tipo_esperado ← <var>.tipo_efetivo
Regra de sintaxe: <expr> → <var>[2] + <var>[3]
Regra de semântica: <expr>.tipo_efetivo ← 
if (<var>[2].tipo_efetivo = int) e (<var>[3].tipo_efetivo = int) then 
int 
else real 
endif
Predicado: <expr>.tipo_efetivo = <expr>.tipo_esperado
Regra de sintaxe: <expr> → <var> 
Regra de semântica: <expr>.tipo_efetivo ← <var>.tipo_efetivo
Predicado: <expr>.tipo_efetivo = <expr>.tipo_esperado
Regra de sintaxe: <var> → A | B | C
Regra de semântica: <var>.tipo_efetivo ← look_up( <var>.string)
A função look-up 
pesquisa 
determinado nome 
de variável na tabela 
de símbolos e 
retorna o tipo desta.
 
Gramáticas de atributos
<atribuição>
<expr>
<var>
<var>[2] <var>[3]
A BA= +
Árvore de análise para A = A + B
 
<atribuição>
<expr>
<var>
<var>[2] <var>[3]
A BA= +
Fluxo dos atributos na árvore de análise para A = A + B
tipo_efetivo
tipo_efetivo tipo_efetivo
tipo_efetivotipo_esperado
Gramáticas de atributos
<var>.tipo_efetivo ← look-up(A)
<expr>.tipo_esperado ← 
<var>.tipo_efetivo
<var>[2].tipo_efetivo ← look-up(A)
<var>[3].tipo_efetivo ← look-up(B)
<expr>.tipo_efetivo ← int ou real 
<expr>.tipo_esperado = 
<expr>.tipo_efeitvo (Verdadeiro ou 
Falso)
 
<atribuição>
<expr>
<var>
<var>[2] <var>[3]
A BA= +
Árvore de análise completamente atribuída para A = A + B
tipo_efetivo = real
tipo_efetivo = real
tipo_efetivo = int
tipo_esperado = real
tipo_efetivo = real
Gramáticas de atributos
Exemplo:
A definido como real
B definido como inteiro
Regra semântica: <expr>.tipo_efetivo ← 
if (<var>[2].tipo_efetivo = int) e (<var>[3].tipo_efetivo = int) then 
int else real endif
 
Gramáticas de atributos
 São usadas para:
 Fornecer descrições completas da sintaxe e 
semântica estática de linguagens de 
programação.
Definição formal de uma linguagem que pode 
ser introduzida em um sistema de geração 
de compiladores.
Processamento de linguagens naturais.
 Grande número de atributos e de regras 
semânticas necessárias dificulta leitura e 
escrita dessas gramáticas.
 
Exercício 1
 Escreva uma gramática de atributos cuja base BNF é 
dada abaixo, mas cujas regras de linguagem sejam as 
seguintes: tipos de dados não podem ser misturados 
em expressões, mas as instruções de atribuição não 
precisam ter os mesmos tipos em ambos os lados do 
operador de atribuição.
<atribuição> → <var> = <expr>
<expr> → <var> + <var>
| <var>
<var> → A | B | C
 
Gramáticas de atributos
Regra de sintaxe: <atribuição> → <var> = <expr>
Regra semântica: <expr>.tipo_esperado ← <var>.tipo_efetivo
Regra de sintaxe: <expr> → <var>[2] + <var>[3]
Regra de semântica: <expr>.tipo_efetivo ← 
if (<var>[2].tipo_efetivo = int) e (<var>[3].tipo_efetivo = int) then 
int 
else real 
endif
Predicado: <expr>.tipo_efetivo = <expr>.tipo_esperado
Regra de sintaxe: <expr> → <var> 
Regra de semântica: <expr>.tipo_efetivo ← <var>.tipo_efetivo
Predicado: <expr>.tipo_efetivo = <expr>.tipo_esperado
Regra de sintaxe: <var> → A | B | C
Regra de semântica: <var>.tipo_efetivo ← look_up( <var>.string)
 
Solução 1
 Regra de sintaxe: <atribuição> → <var> = <expr>
Regra de sintaxe: <expr> → <var>[2] + <var>[3]
Regra de semântica: <expr>.tipo_efetivo ← 
if (<var>[2].tipo_efetivo = <var>[3].tipo_efetivo) then 
<var>[2].tipo_efetivo
else ERRO
endif
Regra de sintaxe: <expr> → <var> 
Regra de semântica: <expr>.tipo_efetivo ← 
<var>.tipo_efetivo
Regra de sintaxe: <var> → A | B | C
Regra de semântica: <var>.tipo_efetivo ← 
look_up( <var>.string)
 
<atribuição>
<expr>
<var>
<var>[2] <var>[3]
A CB= +
Árvore de análise completamente atribuída para A = B + C
tipo_efetivo = real
tipo_efetivo = int
tipo_efetivo = int
tipo_efetivo = int
Solução 1
Exemplo:
A definido como real
B definido como inteiro
C definido como inteiro
Regra semântica: <expr>.tipo_efetivo ← if 
(<var>[2].tipo_efetivo = <var>[3].tipo_efetivo) then 
<var>[2].tipo_efetivo else ERRO endif
 
Exercício 2
 Escreva uma gramática de atributos 
cuja base BNF é dada abaixo e que 
seja capaz de realizar verificação de 
tipos.
<atribuição> → <id> = <expr>
<id> → A | B | C
<expr> → <id> + <expr>
| <id> * <expr>
| (<expr>)
| <id>
 
Solução 2
Regra de sintaxe: <atribuição> → <id> = <expr>
Regra de semântica: <expr>.tipo_esperado ← <id>.tipo_efetivo
Regra de sintaxe: <id> → A | B | C
Regra de semântica: <id>.tipo_efetivo ← 
look_up( <id>.string)
Regra de sintaxe: <expr> → (<expr>[2])
Regra de semântica: <expr>.tipo_efetivo ← 
<expr>[2].tipo_efetivo
Predicado: <expr>.tipo_efetivo = <expr>.tipo_esperado
Regra de sintaxe: <expr> → <id>[2]
Regra de semântica: <expr>.tipo_efetivo ← 
<id>[2].tipo_efetivo
Predicado: <expr>.tipo_efetivo = <expr>.tipo_esperado
 
Solução 2
Regra de sintaxe: <expr> → <id>[3] + <expr>[3]
Regra de semântica: <expr>.tipo_efetivo ← 
if (<id>[3].tipo_efetivo = int ) e (<expr>[3].tipo_efetivo = int) then 
int
else real
endif
Predicado: <expr>.tipo_efetivo = <expr>.tipo_esperado
Regra de sintaxe: <expr> → <id>[4] * <expr>[4]
Regra de semântica: <expr>.tipo_efetivo ← 
if (<id>[4].tipo_efetivo = int ) e (<expr>[4].tipo_efetivo = int) then 
int
else real
endif
Predicado: <expr>.tipo_efetivo = <expr>.tipo_esperado
 
Referências Bibliográficas
 Sebesta, R. Conceitos de 
Linguagens de programação. 5ª 
edição. Bookman, 2003. Cap 3.

Outros materiais