540 likes | 741 Vues
Compiladores. Faculdade Pernambucana - FAPE Setembro/2007. Tradução Dirigida pela Sintaxe.
E N D
Compiladores Faculdade Pernambucana - FAPE Setembro/2007
Tradução Dirigida pela Sintaxe • Para realizar uma tradução um compilador pode precisas manter muitos atributos para a construção sendo traduzida. Ex: tipo, o número de instruções geradas, uma cadeia de caracteres, uma localização de memória, etc. • Para especificarmos traduções para construções de linguagem de programação, iremos utilizar um formalismo chamado de Definição Dirigida pela Sintaxe.
Tradução Dirigida pela Sintaxe • Uma Definição dirigida pela sintaxe especifica a tradução de uma construção em termos dos atributos associados aos seus componentes sintáticos.
Tradução Dirigida pela Sintaxe Definições Dirigidas pela Sintaxe • Uma definição dirigida pela sintaxe usa uma gramática livre de contexto para especificar a estrutura sintática da entrada. • A cada símbolo da gramática associa um conjunto de atributos, e a cada produção associa um conjunto de regras semânticas para computar os valores dos atributos associados aos símbolos que figuram naquela produção.
Tradução Dirigida pela Sintaxe Definições Dirigidas pela Sintaxe • A gramática e o conjunto de regras semânticas constituem a definição dirigida pela sintaxe.
Tradução Dirigida pela Sintaxe PRODUÇÃO | REGRA SEMÂNTICA lista -> lista digito | lista.v := lista1.v|| digito.v lista -> digito | lista.v : = digito.v digito -> 0 | digito.v := ‘x’ digito -> 1 | digito.v := ‘y’ Digito -> 2 | digito.v := ‘z’ Definição Dirigida pela Sintaxe.
Tradução Dirigida pela Sintaxe Definições Dirigidas pela Sintaxe • A tradução é um mapeamento de entrada e saída. • A saída para cada entrada x é especificada da seguinte maneira: • Construa uma árvore gramatical para x. • Suponha que um nó n seja rotulado pelo símbolo X da gramática. • X.a – Valor do atributo a do símbolo X no nó n.
Tradução Dirigida pela Sintaxe Definições Dirigidas pela Sintaxe • Valor de X.a no nó n é computado usando-se a regra semântica para o atributo a associado com a produção de X usada no nó n. • Uma árvore gramatical mostrando os valores dos atributos a cada nó é denominada uma árvore gramatical anotada.
Tradução Dirigida pela Sintaxe lista.v = xzy lista.v = xz digito.v = y lista.v = x digito.v = z digito.v = x 0 2 1 Valores de atributos nos nós de uma árvore gramatical (árvore gramatical anotada).
Tradução Dirigida pela Sintaxe Atributos Sintetizados • Um atributo é dito sintetizado se seu valor num nó da árvore gramatical é determinado a partir dos atributos dos filhos daquele nó. • Os atributos sintetizados possuem a desejável propriedade de que podem ser avaliados durante um único caminhamento bottom-up (do fundo para cima) da árvore gramatical.
Tradução Dirigida pela Sintaxe • Exemplo 1 – Construa uma definição dirigida pela sintaxe para traduzir expressões, que consistem em dígitos separados por sinais de mais ou de menos na notação posfixa. • Associado a cada não-terminal está um atributo t, cujo valor é uma cadeia de caracteres que representa a notação posfixa para a expressão gerada por aquele não-terminal numa árvore gramatical.
Tradução Dirigida pela Sintaxe PRODUÇÃO | REGRA SEMÂNTICA expr -> expr1 + termo | expr.t := expr1.t || termo.t || ‘+’ Expr -> expr1 – termo | expr.t : = expr1.t || termo.t || ‘-’ Expr -> termo | expr.t := termo.t termo -> 0 | termo.t := ‘0’ termo -> 1 | termo.t := ‘1’ ... | ... termo -> 9 | termo.t := ‘9’ Definição Dirigida pela Sintaxe para a tradução da notação infixa para a posfixa.
Tradução Dirigida pela Sintaxe expr.t = 95 - 2 + expr.t = 95 - termo.t = 2 expr.t = 9 termo.t = 5 termo.t = 9 9 - 5 + 2 Valores de atributos nos nós de uma árvore gramatical (árvore gramatical anotada).
Tradução Dirigida pela Sintaxe • O valor do atributo t a cada nó foi computado utilizando-se a regra semântica associada à produção usada naquele nó. • O valor do atributo t na raiz é a notação posfixa para a cadeia gerada pela árvore gramatical.
Tradução Dirigida pela Sintaxe Caminhamento em Profundidade • Uma Definição Dirigida pela Sintaxe não impõe qualquer ordem específica para a avaliação dos atributos de uma árvore gramatical. • Um caminhamento de uma árvore se inicia à raiz e visita cada nó da mesma em alguma ordem.
Tradução Dirigida pela Sintaxe Caminhamento em Profundidade • O caminhamento em profundidade é aquele que começa da raiz e visita recursivamente os filhos de cada nó numa ordem da esquerda para a direita.
Tradução Dirigida pela Sintaxe Esquema de Tradução • Para especificar traduções, além da definição dirigida pela sintaxe podemos utilizar uma notação mais procedimental chamada de esquema de tradução. • Um esquema de tradução é uma gramática livre de contexto na qual fragmentos de programas, chamados de ações semânticas, são inseridos nos lados direitos das produções.
Tradução Dirigida pela Sintaxe Esquema de Tradução Exemplos: Usando Definição Dirigida pela Sintaxe para traduzir expressões infixas em posfixas. Produção Regra Semântica expr -> expr + termoexpr.t := expr1.t || term.t || ‘+’
Tradução Dirigida pela Sintaxe Esquema de Tradução Exemplos: Usando Esquema de Tradução para traduzir expressões infixas em posfixas. Produção expr -> expr + termo {imprimir(‘+’)} Ação Semântica
Tradução Dirigida pela Sintaxe Esquema de Tradução • No esquema de tradução a posição à qual uma ação deve ser executada é mostrada envolvendo-a entre chaves e escrevendo-a no lado direito da produção: resto -> + termo {imprimir(‘+’)} resto1 • Ao desenharmos uma árvore gramatical para um esquema de tradução, indicamos uma ação construindo para a mesma um filho extra, conectado por uma linha pontilhada ao nó de sua produção.
Tradução Dirigida pela Sintaxe Esquema de Tradução • Produção: resto -> + termo {imprimir(‘+’)} resto1 • Árvore: resto + termo {imprimir(‘+’)} resto Uma folha extra é construída para uma ação semântica
Tradução Dirigida pela Sintaxe Esquema de Tradução Exemplo: Esquema de tradução para transformar expressões na notação infixa para a posfixa. expr -> expr + termo { imprimir(‘+’)} expr -> expr - termo { imprimir(‘-’)} expr -> termo termo -> 0 { imprimir(‘0’)} termo -> 1 { imprimir(‘1’)} ... termo -> 9 { imprimir(‘9’)} Ações traduzindo expressões na notação posfixa
Tradução Dirigida pela Sintaxe Esquema de Tradução Exemplo: Traduzindo 9 – 5 + 2 em 95-2+ usando um esquema de tradução.
Tradução Dirigida pela Sintaxe Atributos Sintetizados e Herdados • Os atributos associados aos símbolos gramaticais que representam uma construção de uma Linguagem de Programação podem ser de dois tipos: atributos sintetizados (já vistos) e atributos herdados. • Uma Definição Dirigida pela Sintaxe que usa exclusivamente atributos sintetizados é dita uma definição S-atribuída.
Tradução Dirigida pela Sintaxe Atributos Sintetizados e Herdados • Uma árvore gramatical para uma definição s-atribuída pode ser sempre anotada através da avaliação das regras semânticas para os atributos a cada nó, de baixo para cima, das folhas para a raiz.
Tradução Dirigida pela Sintaxe Atributos Sintetizados e Herdados • Um atributo herdado é aquele cujo valor a um nó de uma árvore gramatical é definido em termos do pai e/ou irmãos daquele nó. Exemplo: Gramática | Regras Semânticas D -> TL | L.in = T.tipo T -> int | T.tipo = inteiro T -> real | T.tipo = real L -> L1, id | L1.in = L. in | incluir_tipo(id, entrada, L.in) L -> id | incluir_tipo(id, entrada, L.in) Definição Dirigida pela Sintaxe tendo L.in como atributo herdado
Tradução Dirigida pela Sintaxe Atributos herdados Exemplo: Árvore gramatical anotada para a sentença real id1, id2, id3. D T.tipo = real L.in = real real L.in = real id3 L.in = real id2 id1
Tradução Dirigida pela Sintaxe Atributos Sintetizados e Herdados • Na árvore gramatical anotada para a sentença real id1, id2, id3 mostrada anteriormente, os valores de L.in nos três nós fornecem o tipo dos identificadores id1, id2 e id3. • Esses valores são determinados pelo cômputo do valor do atributo T.tipo no filho à esquerda da raiz e, em seguida, pela avaliação de L.in de cima para baixo nos três nós da sub-árvore direita da raiz.
Tradução Dirigida pela Sintaxe Grafos de Dependências • Se um atributo b a um nó da árvore gramatical depender de um atributo c, a regra semântica de c deve ser avaliada antes da regra semântica de b. Ou seja, o atributo b para ser computado depende do valor do atributo c. • As dependências entre os atributos (herdados e sintetizados) podem ser delineadas através de um grafo chamado de grafo de dependências.
Tradução Dirigida pela Sintaxe Grafos de Dependências • Exemplo: Produção Regra Semântica E -> E1 + E2 E.val = E1.val + E2.val val val val E.Val é sintetizado a partir de E1.val e E2.val
Tradução Dirigida pela Sintaxe Grafos de Dependências tipo in entrada in entrada in entrada Grafo de dependências de uma árvore gramatical
Tradução Dirigida pela Sintaxe Ordem de Avaliação • Uma classificação topológica de um grafo acíclico dirigido é qualquer ordenamento m1, m2, ..., mk dos nós do grafo, de tal forma que os lados vão dos primeiros nós do ordenamento para os últimos. • Qualquer classificação topológica de um grafo de dependências fornece uma ordem válida na qual as regras semânticas associadas aos nós na árvore gramatical podem ser avaliadas.
Tradução Dirigida pela Sintaxe Grafos de Dependências 5 6 4 tipo in 7 3 entrada 8 in entrada in 2 9 10 1 entrada Grafo de dependências de uma árvore gramatical
Tradução Dirigida pela Sintaxe Ordem de Avaliação • A tradução especificada por uma definição dirigida pela sintaxe pode ser tornada precisa como segue: • A gramática subjacente é usada para construir uma árvore gramatical para a entrada. • O grafo de dependências é construído como discutido acima. • A partir de uma classificação topológica do grafo de dependências, obtemos uma ordem de avaliação para as regras semânticas. • A avaliação das regras semânticas nessa ordem produz a tradução da cadeia de entrada.
Tradução Dirigida pela Sintaxe Exemplo: • A partir da classificação topológica obtemos o seguinte programa: a4 := read; a5 := a4; incluir_tipo(id3, entrada, a5); a7 := a5; incluir_tipo(id2, entrada, a7); A9 := a7; incluir_tipo(id1, entrada, a9); • A avaliação dessas regras semânticas armazena o tipo real na entrada da tabela de símbolos para cada identificador.
Tradução Dirigida pela Sintaxe Construção de Árvores Sintáticas • As definições dirigidas pela sintaxe podem ser usadas para especificar a construção de árvores sintáticas e outras representações gráficas das construções de linguagem. • A tradução dirigida pela sintaxe pode ser usada em árvores sintáticas ou em árvores gramaticais.
Tradução Dirigida pela Sintaxe Construção de Árvores Sintáticas • Uma árvore sintática é uma forma condensada de árvore gramatical, útil para a representação das construções de linguagem. + * 4 • 5 • Numa árvore sintática, os operadores e palavras-chave não figuram como folhas, mas, em lugar, são associados ao nó inteiro que seria o pai daquelas folhas na árvore gramatical.
Tradução Dirigida pela Sintaxe Construção de Árvores Sintáticas • As definições dirigidas pela sintaxe podem ser usadas para especificar a construção de árvores sintáticas e outras representações gráficas das construções de linguagem. • A tradução dirigida pela sintaxe pode ser usada em árvores sintáticas ou em árvores gramaticais.
Tradução Dirigida pela Sintaxe Construção de Árvores Sintáticas para expressões Exemplo: Seja a Definição Dirigida pela Sintaxe abaixo: ProduçãoRegras Semânticas E -> E1 + T E.nptr := criar-no(‘+’, E1.nptr, T.nptr) E -> E1 – T E.nptr := criar_no(‘-’, E1.nptr, T.nptr) E -> T E.nptr = T.nptr T -> (E) T.nptr : = E.nptr T -> id T.nptr := criar_folha(id, id.entrada) T -> num T.nptr := criar_folha(num, num.valor) Definição dirigida pela sintaxe para a construção da árvore sintática de uma expressão
Tradução Dirigida pela Sintaxe Construção de Árvores Sintáticas para expressões • Exemplo: criar a árvore sintática para a expressão a – 4 + c. + - c a 4
Tradução Dirigida pela Sintaxe Construção de Árvores Sintáticas para expressões • Para criar a árvore sintática para a expressão a – 4 + c usando a Definição Dirigida pela Sintaxe vista anteriormente, foi usado o seguinte programa: P1 := criar_folha(id, entrada_a); P2 := criar_folha(num, 4); P3 := criar_no(´-´, p1, p2); P4 := criar_folha(id, entrada_c); P5 := criar_no(‘+’, p3, p4); • P1, p2 , ..., p5 são os apontadores para nós e entrada_a e entrada_c são apontadores para as entradas na tabela de símbolos dos identificadores a e c, respectivamente.
Tradução Dirigida pela Sintaxe Construção de Árvores Sintáticas para expressões E.nptr E.nptr T.nptr E.nptr T.nptr id T.nptr num id + - + id - num id para a entrada de a na tabela de símbolo
Verificação de Tipos • Um compilador precisa verificar se o programa segue as convenções sintáticas e semânticas da linguagem fonte. Essa checagem, chamada de verificação sintática, assegura que certos tipos de erro de programa serão detectados e reportados. • A verificação de tipos é um exemplo de verificação sintática. Outros exemplos: verificação do fluxo de controle, verificações de unicidade e verificações relacionadas aos nomes.
Verificação de Tipos • A verificação de tipos relata um erro se um operador for aplicado a um operando incompatível. Ex: Soma de um array com uma letra. • Essa verificação checa se o tipo da construção corresponde exatamente àquele esperado no contexto. Árvore sintática Árvore sintática Fluxo de tokens Analisador sintático Analisador sintático Analisador sintático Representação Intermediária Posição do verificador de tipos em alguns compiladores
Verificação de Tipos • Tanto em Pascal quanto em C, os tipos são básicos ou construídos. Ex.: • Pascal - Básico (booleano, caracteres, inteiros, etc.) • Pascal – Construído (array, registros etc.) – Construídos a partir dos tipos básicos.
Verificação de Tipos Expressões de Tipos • O tipo de uma construção de linguagem será denotado por uma “expressão de tipo”. Exemplo de uma expressão de tipo: • Um tipo básico (boolean, caracteres, reais etc) é uma expressão de tipo. Temos também o tipo erro e o tipo vazio. • Uma vez que expressões podem receber nomes, um nome de tipo é uma expressão de tipo. • Um construtor de tipos aplicado a uma expressão de tipo é uma expressão de tipo. • Expressões de tipo podem conter variáveis cujos valores sejam expressões de tipo.
Verificação de Tipos Expressões de Tipos • Os construtores abrangem: • Arrays, Produtos, Registros, Apontadores e Funções. • Arrays: • Se T pe uma expressão de tipo, então array(I,T) é uma expressão de tipo denotando o tipo array de elementos com tipo T e conjunto de índices I. var A: array[1 .. 10] of integer;