A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Teoria e Implementação de Linguagens Computacionais Revisão 1º EE André Ricardo Schäffer Lopes – Rodrigo Diego Melo Amorim–

Apresentações semelhantes


Apresentação em tema: "Teoria e Implementação de Linguagens Computacionais Revisão 1º EE André Ricardo Schäffer Lopes – Rodrigo Diego Melo Amorim–"— Transcrição da apresentação:

1 Teoria e Implementação de Linguagens Computacionais Revisão 1º EE André Ricardo Schäffer Lopes – arsl@cin.ufpe.brarsl@cin.ufpe.br Rodrigo Diego Melo Amorim– rdma@cin.ufpe.brrdma@cin.ufpe.br

2 Níveis de Linguagem Linguagem de máquina 0000 0001 0011 0010 controle explícito dos endereços de memória dificuldade em ler, escrever, editar Linguagem de Montagem Assembly language Uso de um programa montador (assembler) Instruções têm relação direta com Linguagem de Máquina Linguagem de alto nível Mais próxima da linguagem natural Uso de interpretadores ou compiladores Várias instruções de máquina para cada linha de comando

3 Processadores de Linguagens Manipulam programas expressos em alguma linguagem de programação: Tradutores Compiladores Interpretadores

4 Tradutores e Compiladores Tradutor Linguagem fonte -> Linguagem destino Chinês para inglês Java para C Compilador Ling. de alto nível -> Ling. de baixo nível

5 Interpretadores Recebem um programa fonte escrito em uma linguagem fonte, e o executam imediatamente Lê, analisa e executa as instruções, uma de cada vez

6 Compiladores x Interpretadores Compiladores Tempo de espera pela compilação Execução dos programas com máxima performance, em linguagem de máquina Interpretadores Resultados imediatos Sem a tradução do programa para código objeto antes da execução Execução (de linguagem de alto nível) até 100 vezes mais lenta que a versão compilada

7 Uso de interpretadores Programador trabalha em modo interativo Quer ver o resultado de uma instrução antes de entrar na próxima Execução de instruções apenas um vez, ou raramente Programas descartáveis Em que a velocidade de execução não é tão importante

8 Diagramas Tombstone Programas Programa P expresso na linguagem L P L graph Basic sort x86 sort Java

9 Diagramas Tombstone Máquinas Máquina M M SPARCPPCx86

10 Diagramas Tombstone Execução Programa P rodando na máquina M P M Msort PPC sort PPC x86 X

11 Diagramas Tombstone Tradutores Tradutor de S para T expresso na linguagem L S L T  Java C x86  Java x86 

12 Diagramas Tombstone Tradução Um programa fonte P expresso na linguagem S -> um programa objeto expresso na linguagem T, usando um tradutor de S para T executando na máquina M?

13 Diagramas Tombstone Tradução P S P T S M T  M

14 Compilação em dois estágios sort Java sort C Java x86 C  C  sort x86

15 Cross-Compiler Roda em uma máquina hospedeira, mas gera código para outra máquina Usado quando a máquina destino tem pouca memória, não tem compilador ou outras ferramentas

16 Exemplo Cross-Compiler sort Java sort PPC Java x86 PPC  x86 sort PPC

17 Diagramas Tombstone Interpretador Interpretador de S expresso na linguagem L S L SQL x86 shell C Basic x86

18 Diagramas Tombstone Interpretação Um programa P expresso em uma linguagem S, usando um interpretador de S executando na máquina M?

19 Diagramas Tombstone S M P S M

20 Interpretive Compiler Características de interpretadores e compiladores Compila para uma linguagem intermediária, e interpreta esta linguagem Simples e rápido de traduzir para ela, e simples e rápida de interpretar Exemplo: Java, no JDK

21 Java no JDK Java M JVM  M Java M JVM  M M P M P Java P JVM

22 Máquina Real x Abstrata Projeto de uma nova máquina “Ultima” Para testes: usar um interpretador P Ultima M M P 

23 Bootstrapping Compilação de uma linguagem utilizando um compilador dessa mesma linguagem Utilizado para melhorar a eficiência de um compilador Precisa de um compilador escrito em outra linguagem que depois será descartado

24 Bootstrapping versão 1 M C M M  Ada-S C M  C M  M M 

25 Bootstrapping versão 2 M Ada-S M  M M  M  Inicia desenvolvimento do novo compilador Compilador antigo Compilador novo Ada-S M M 

26 Bootstrapping versão 2a M Ada-S M M  M  Compilador novo Compilador +novo Ada-S M M  M  Inicia desenvolvimento do novo compilador

27 Bootstrapping versão 3 M Ada Ada-S M  Ada Ada-S M  Ada M M  M M Ada-S  M Linguagem estendida

28 Bootstrapping - melhorando a eficiência Ada Mslow Mfast  Ada Mslow  Ada Mfast  M

29 Bootstrapping - melhorando a eficiência Ada Mslow Mfast  M P Ada P Mfast M P

30 Bootstrapping - melhorando a eficiência Ada Mslow Mfast  M Ada Mfast  Ada Mfast 

31 Especificação de Linguagens Sintaxe A forma do programa Organização das frases Palavras reservadas Semântica estática (Restrições contextuais) Regras de escopo e regras de tipo Semântica Significado do programa

32 O processo de Compilação begin if x = 5 then... 1100111 0011100011 Código Fonte Compilador Programa output + params

33 Fases de Compilação abstração implementação Código fonte Tokens e Lexemas Árvore sintática abstrata Código máquina AST decorada Análise Léxica Análise Sintática Análise Semântica Geração de Código

34 Análise Léxica (Scanning) Código fonte -> sequência de tokens Símbolos como identificadores, literais, operadores, palavras-chave, pontuação etc. if (n == 0) { return 1; } else {... } RPARLCUR RCUR if LPAR return else "n" id "0" intLit assign "1" intLit comm

35 Análise Sintática Agrupa caracteres ou Tokens em uma estrutura hierárquica com algum significado Responsável por determinar se uma dada cadeia de entrada pertence ou não à linguagem definida por uma gramática int y = 0,k = 0; int x = y+++k; A seguinte construção é válida?

36 Gramáticas – descrevendo Linguagens Gramáticas Livres de Contexto são utilizadas para descrever linguagens de programação Produções Símbolos terminais Símbolos não-terminais Símbolo inicial

37 Exemplo S → S ; S S → id := E S → print (L) E → id E → num E → E + E E → (S, E) L → E L → L, E Terminais: id print, + ; := ( ) num Não terminas: S E L Símbolo inicial: S → é utilizado na notação de produções A cadeia seguinte pertence à gramática? a := 7; b := c + (d := 5 + 6, d)

38 Derivações S S ; S S ; id := E id := E ; id := E id := num ; id := E id := num ; id := E + E id := num ; id := E + (S, E) id := num ; id := id + (S, E) id := num ; id := id + (id := E, E) id := num ; id := id + (id := E + E, E) id := num ; id := id + (id := E + E, id) id := num ; id := id + (id := num + E, id) id := num ; id := id + (id := num + num, id)

39 Parse tree S S S E Eid:= ; E id + E ) (, ES E := id E E+ num Construída conectando cada derivação à sua origem. Obs. Na prática não é implementada pelos compiladores.

40 Gramática Ambígua A partir dela uma sentença pode dar origem a mais de uma árvore de parsing diferente Indeterminismo é problemático para a compilação Eliminação de ambigüidade Refatoração da gramática

41 Exemplo x := 1 + 2 + 3; S E id:= E +E E +E num S E id:= E +E E +E num

42 Refatoração S → S ; S S → id := E S → print (L) E → id E → num E → E + E E → (S, E) L → E L → L, E S → S ; S S → id := E S → print (L) E → id E → num E → E + T E → T E → (S, E) L → E L → L, E

43 Parsers Avaliam uma entrada quanto à sintaxe Podem ser Top-down Recursive-descent / LL(k) Bottom-up LR(k)

44 Recursive descent parser Algoritmo baseado em previsões Funções mutuamente recursivas Simples implementação Uma função para cada não-terminal Uma cláusula para cada produção Verifica o primeiro símbolo terminal para decidir qual função usar

45 Exemplo A ::= aBcC B ::= CB | cC C ::= da parseA() { accept(‘a’); parseB(); accept(‘c’); parseC(); } parseB() { case (d): parseC(); parseB(); case (c): accept(‘c’); parseC(); } parseC() { accept(‘d’); accept(‘a’); }

46 Recursive descent parser Na prática, constrói uma tabela de produções indexadas por não-terminais e terminais A ::= aBcC B ::= CB | CA C ::= da acd AA::= aBcC BB::= CB B::= CA CC::= da

47 Recursive descent parser Vantagens Fácil de implementar Fácil de entender Desvantagens Performance deficiente Gramática reconhecida possui restrições Sem recursão à esquerda Deve estar fatorada

48 Recursive descent parser A ::= aBcC B ::= CB | CA C ::= da A ::= aBcC B ::= CX X ::= B | A C ::= da acd AA::= aBcC BB::= CX CC::= da XX::=AX::=B Gramática LL(k)

49 Parsers LL(k) Gramáticas SEM entradas duplicadas na tabela são conhecidas como LL(k) LL(1) -> Left-to-right, leftmost-derivation, 1-symbol lookahead Left-to-right – direção na qual os símbolos serão examinados Leftmost-derivation – ordem pela qual os símbolos não- terminais serão expandidos 1-symbol lookahead – não mais que um símbolo será avaliado por vez Também existem LL(2), LL(3),... Toda LL(1) é LL(2), toda LL(2) é LL(3),... LL(k)

50 Recursão à esquerda Gramáticas LL(1) são vulneráveis a entradas duplicadas. Por exemplo, o fragmento a seguir: E → E + T E → T O fato de E aparecer no início do lado direito da produção é a causa do problema. Isso é conhecido como Recursão à Esquerda. Para corrigir, precisamos refatorar a gramática com Recursão à Direita: E → T E´ E´ → +T E´ E´ →

51 Parsers LR(k) Supera as fraquezas de LL(k) LR(1) -> Left-to-right, rightmost-derivation, 1- symbol lookahead Uso de uma pilha para armazenar símbolos de forma temporária Possui duas operações, shift e reduce shift - move o primeiro símbolo para o topo da pilha reduce - escolhe uma regra da gramática do tipo X → A B C. pop C B A da pilha e push X.

52 Parsing LR - de Gramáticas Ambíguas Gramáticas ambíguas ocasionam conflitos em parsers LR Shift-reduce conflict O parser não consegue decidir se empilha o próximo símbolo da entrada, ou se reduz para uma regra já disponível Reduce-reduce conflict O parser pode realizar uma redução para duas regras distintas

53 Parsing LR - de Gramáticas Ambíguas Dangling-else if a then if b then s1 else s2 if a then { if b then s1 else s2 } if a then { if b then s1 } else s2 ?

54 Parsing LR - de Gramáticas Ambíguas Solução: Transformar a gramática Introdução dos conceitos de matched e unmatched S ::= 'if' E 'then' S 'else' S S ::= 'if' E 'then' S S ::=... S ::= M | U M ::= 'if' E 'then' M 'else' M |... U ::= 'if' E 'then' S | 'if' E 'then' M 'else' U

55 Análise Semântica (Contextual) Verifica se o programa está de acordo com as restrições contextuais da linguagem fonte Em uma linguagem com tipos estáticos e ligação estática ela: Verifica regras de escopo Verifica regras de tipos Duas fases: Identificação: ocorrências de nomes x definições Verificação de tipos: aplica regras de tipos para cada expressão, inferindo os tipos, e depois compara com os tipos esperados

56 Identificação Faz a ligação entre uso de nomes e sua definição Tabela de identificação (tabela de símbolos), com nome e atributos de cada identificador Cada definição tem o seu escopo – parte do programa sobre a qual ela tem efeito Delimitado por um bloco

57 Estrutura de blocos de um programa Monolítica: O único bloco é o programa inteiro Declarações estão em um escopo global Regras de escopo: Nenhum identificador pode ser declarado mais de uma vez Nenhum identificador pode ser usado sem ter sido definido

58 Estrutura de blocos de um programa Plana O programa pode ser particionado em vários blocos disjuntos Dois níveis de escopo: Escopo local: ocorrências de identificadores declarados localmente são restritos a um bloco em particular Outras declarações têm escopo global

59 Estrutura de blocos de um programa Aninhada Blocos podem ser aninhados um dentro do outro Vários níveis de escopo: Declarações no nível mais externo têm escopo global (nível 1) Declarações dentro de um bloco interno são locais ao bloco Cada bloco está dentro de outro bloco, com um nível a mais

60 Passos Travessia do programa fonte Um compilador de um passo atravessa o programa uma única vez Um compilador de múltiplos passos faz várias travessias O projeto de um compilador é diretamente relacionado ao número de passos

61 Compilação em múltiplos passos Módulo principal (driver) Chama cada um dos passos Driver do Compilador Analisador SintáticoAnalisador ContextualGerador de Código

62 Compilação em passo único Analisador sintático Realiza/chama as atividades à medida que lê e reconhece o programa Analisador Sintático Analisador ContextualGerador de Código Driver do Compilador

63 Pontos relevantes no Projeto de um Compilador Velocidade – possível vantagem para um passo Espaço – possível vantagem para um passo (dados x programa) Modularidade – vantagem de múltiplos passos Flexibilidade – vantagem de múltiplos passos Transformações/otimizações de programas – vantagem de múltiplos passos


Carregar ppt "Teoria e Implementação de Linguagens Computacionais Revisão 1º EE André Ricardo Schäffer Lopes – Rodrigo Diego Melo Amorim–"

Apresentações semelhantes


Anúncios Google