Compiladores e Interpretadores: Estrutura e Funcionamento

Enviado por macbriene e classificado em Computação

Escrito em em português com um tamanho de 6,89 KB

Interpretador: recebe a primeira instrução, confere, converte e ordena sua execução. Repete o processo sucessivamente. Apenas uma instrução fica na memória a cada instante. Se o programa fonte for executado uma segunda vez, haverá uma nova tradução.

Compiladores: recebe a primeira instrução, confere, converte e passa para a próxima instrução sucessivamente. Após converter a última instrução (sem nenhum erro), a CPU volta à primeira instrução e executa (sucessivo). Se o programa fonte for executado uma segunda vez, não haverá uma nova tradução.
Vantagem: execução mais rápida. Desvantagem: modificação exige nova tradução.

Montadores (Assemblers): Traduzem programas escritos em linguagem de montagem em programas escritos em linguagem de máquina (0s e 1s).

Pré-processadores: Traduzem programas escritos em linguagem de alto nível em outros programas escritos também em linguagem de alto nível. Exemplo: pré-processador C (processamento de macros e inclusão de arquivos).

Análise: quebra o código-fonte em suas partes e cria uma representação intermediária do programa.

Síntese: Constrói o programa-destino a partir da representação intermediária.

Análise Léxica: lê uma sequência de caracteres e a organiza como tokens (sequências de caracteres com algum significado).

Análise Sintática: agrupa caracteres ou tokens em uma estrutura hierárquica com algum significado.

Análise Semântica: verifica se os componentes de um programa se encaixam de forma a ter um significado adequado.

Análise Sintática - Parsing:

  • Também chamada de análise gramatical.
  • Envolve o agrupamento dos tokens em frases gramaticais.
  • Baseada na gramática da linguagem, é gerada uma árvore sintática (parse tree) do programa.

Tratamento e Recuperação de Erros:

  • Erros são gerados, mas o compilador deve informar o máximo possível de erros em uma única execução: isso é feito através de recuperação de erros, que avisa sobre o erro, mas tenta continuar o processo de compilação.
  • Tipos de erros: léxicos, sintáticos, semânticos, etc.

Otimização de Código: Realiza transformações no código visando melhorar sua performance em aspectos de tempo de execução, uso de memória, tamanho do código executável, etc.

Organização de um Compilador:

  • As fases são separadas em:
  • Interface Front-end (Vanguarda): até a geração de código intermediário. Depende da linguagem fonte e independe da máquina alvo.
  • Interface Back-end (Retaguarda): inclui as fases de otimização e geração de código. Independe da linguagem fonte e depende da máquina alvo.

É comum manter a interface de vanguarda e refazer a de retaguarda para produzir um compilador da mesma linguagem em uma máquina diferente.

Linguagem = sintaxe + semântica

  • Especificação da sintaxe: gramática livre de contexto, BNF (Backus-Naur Form).
  • Especificação Semântica: informal (textual), operacional, denotacional, de ações.

Gramática Livre de Contexto

  • Um conjunto de tokens (símbolos terminais).
  • Um conjunto de símbolos não-terminais.
  • Um conjunto de produções: cada produção consiste de um não-terminal, uma seta e uma sequência de tokens e/ou não-terminais.
  • Um não-terminal designado como símbolo inicial (de partida).

Parsing: Processo de procurar uma árvore gramatical para uma dada string de tokens (análise gramatical ou análise sintática).

Ambiguidade: Uma parse tree gera uma string de tokens, mas uma string pode possuir várias parse trees se a gramática for ambígua.
Solução: usar sempre gramáticas não ambíguas ou gramáticas ambíguas com informações adicionais sobre como resolver ambiguidades.

Tradução Dirigida pela Sintaxe

  • A definição dirigida pela sintaxe usa uma gramática livre de contexto para especificar a estrutura sintática da entrada.
  • Associa a cada símbolo um conjunto de atributos e a cada produção associa regras semânticas para computar os valores dos atributos.
  • Gramática e regras semânticas constituem a definição dirigida pela sintaxe.

Análise Gramatical

  • Processo de se determinar se uma cadeia de tokens pode ser gerada por uma gramática.
  • Método de análise gramatical para construir tradutores dirigidos pela sintaxe.
  • Na prática, o parsing de linguagens pode ser feito por algoritmos lineares.
  • Travessia linear da esquerda para a direita, olhando um token de cada vez.

Parsers Top-Down e Bottom-Up: Refere-se à ordem em que os nós da parse tree são criados.

  • Top-down: mais fáceis de escrever à mão.
  • Bottom-up: suportam uma classe maior de gramáticas e de esquemas de tradução, sendo usados pelas ferramentas de geração de parsers.

Backtracking: A escolha de uma produção pode exigir tentativa e erro, voltando para tentar novas alternativas possíveis.

  • Parsing Preditivo: parsing em que não ocorre backtracking (retrocesso).

Parsing Descendente Recursivo

Método de análise sintática top-down em que um conjunto de procedimentos recursivos é usado para processar a entrada.

  • Cada procedimento está associado a um símbolo não-terminal da gramática.
  • O Parsing Preditivo é um caso especial de parsing descendente recursivo em que o símbolo lookahead determina sem ambiguidades o procedimento a ser chamado para cada não-terminal.

Análise Léxica

  • Lê e converte a entrada para um fluxo de tokens.
  • Uma sequência de caracteres de entrada compõe um único token (lexema).
  • Um scanner isola o parser do lexema dos tokens.
  • Quando um lexema é examinado, algum mecanismo é necessário para verificação.

Usando um Analisador Léxico:

  • Funções que um analisador léxico realiza:
  • Tratamento de espaços em branco (brancos, tabulações, avanço de linha).
  • Tratamento de números maiores que 9 (constantes).
  • Reconhecimento de identificadores e palavras-chave.

Entradas relacionadas: