• Nenhum resultado encontrado

Compiladores-03

N/A
N/A
Protected

Academic year: 2021

Share "Compiladores-03"

Copied!
47
0
0

Texto

(1)

Análise Léxica (parte 1)

“O Senhor olha dos céus para os filhos dos homens, para ver se há alguém que tenha entendimento, alguém que busque a Deus.”

(2)

Sumário da Aula

Definição de Compilador

Etapas da Compilação

Introdução à Análise Léxica

(3)
(4)

“Compilador (geral)”

Definição mais abrangente:

 É um programa que traduz um texto escrito em uma

linguagem computacional (fonte) para um texto

equivalente em outra linguagem computacional (alvo)

Entrada: código fonte (na ling. fonte)Saída: código alvo/objeto (na ling. alvo)

Dependendo do propósito, podem ter nomes

(5)

Tipos de “Compiladores”

Assembler ou Montador

 Tipo simples de “compilador”

A linguagem fonte é uma linguagem assembly (ou

linguagem de montagem)

 Correspondência direta com a linguagem de máquina

 A linguagem alvo é uma linguagem de máquina

(6)

Tipos de “Compiladores”

Compilador (def. tradicional)

Traduz de uma linguagem de alto nível para uma de

baixo nível

 Em muitos casos, o compilador gera um código de

máquina incompleto

Precisa passar por um linker para virar executável  Exemplo: gcc

 Em outros casos, o compilador gerar um código em

(7)

Tipos de “Compiladores”

Tradutor Fonte-para-Fonte (source-to-source)

 Traduz de uma linguagem de alto nível para outra

linguagem de alto nível

(8)

Tipos de “Compiladores”

Decompilador

 Traduz de baixo nível para alto nível

 Faz o inverso de um compilador tradicional

Disassembler

 Traduz de código de máquina para linguagem

assembly

(9)
(10)

Etapas da Compilação

Os livros apresentam uma arquitetura para os

compiladores que os divide em um conjunto de

etapas ou camadas

Mostraremos as cinco etapas básicas a seguir

Etapas de otimização de código (após/durante as

(11)

Etapas da Compilação

Análise Léxica Análise Sintática Analise Semântica Geração de Código Intermediário Geração de Código Final

(12)

Duas Fases da Compilação

Fase de Análise

 Subdivide o programa em partes constituintes  Cria uma estrutura abstrata do programa

Feita pelo front-end

Fase de Síntese

 Reconstrói o programa na linguagem-alvo  Gera código final

(13)

Etapas da Compilação

Front-End (Análise) Back-End (Síntese) Análise Léxica Análise Sintática Analise Semântica Geração de Código Intermediário Geração de Código Final

(14)

Etapas da Compilação

Mas por que essa divisão em etapas?

Modularidade – deixa o compilador mais legível e

mais fácil de manter

Eficiência – permite tratar mais a fundo cada etapa

com técnicas especializadas

Portabilidade – facilita adaptar um compilador para

 Receber outro código fonte (muda o front-end)

(15)

Etapas da Compilação

Front-End (Análise) Back-End (Síntese) Análise Léxica Análise Sintática Analise Semântica Geração de Código Intermediário Geração de Código Final

(16)
(17)

Análise Léxica

Objetivo

 Analisar o código fonte, dividindo-o em trechos

indivisíveis e relevantes para a linguagem (os

lexemas) e classificando esses trechos (em tokens)

Entrada: seqüência de caracteres do código

fonte

(18)

Relembrando...

Lexema: seqüência de caracteres que são

considerados indivisíveis na linguagem

Token: classificação dada ao lexema

Geralmente retornado junto com o próprio lexema ou

outro atributo associado ao lexema (como um ponteiro ou um valor numérico)

(19)

Relembrando...

Tokens especificados como expressões

regulares:

ABRE_PAR → ( FECHA_PAR → ) EQ → = ADD → + MULT → * DEF → def IDENTIFIER → [_a-z][_a-z0-9]* NUM_LITERAL → [0-9][0-9]* PT_VG → ;

(20)

Análise Léxica

O módulo de software responsável por essa

etapa pode ser chamado de:

 Analisador Léxico, Lexer ou Scanner

Além de retornar os tokens, ele pode:

 Remover caracteres de “whitespace”  Contar linhas e colunas

(21)

Análise Léxica

Existem várias técnicas para construção de um

lexer, inclusive técnicas de construção (semi)

automática

Porém, iniciaremos vendo como fazer

(22)

Implementação Manual de

um Lexer

(23)

Implementação Manual

Vamos começar implementando tokens em uma

linguagem simples, chamada Xpress-0

 Linguagem para especificar expressões  Lexemas/tokens de 1 caractere apenas  Sem tratamento de espaços em branco

(24)

Exemplo de Implementação

Tokens de Xpress-0

NUM_LITERAL → [0-9] PT_VIRG → ; ADD → + MULT → * ABRE_PAR → ( FECHA_PAR → )

(25)

Exemplo de Implementação

Vamos dar exemplo em Java

Passos para implementar o lexer

 Implementar os tipos dos tokens

 Implementar uma classe para o token  Implementar o lexer

(26)

Exemplo de Implementação

Como implementar os tipos de tokens

Criar um “enum” TokenType

 Criar um valor nele para indicar fim de arquivo

(27)

Exemplo de Implementação

Como implementar os tokens

Criar classe Token

Precisa guardar pelo menos o tipo  Pode ter outras informações

 O lexema

 Uma subclassificação

 O valor inteiro/float/char/etc. ligado ao token  Etc.

(28)

Exemplo de Implementação

Como implementar o lexer

Criar classe Lexer  Método “nextToken()”

 Lê o próximo caractere, classifica-o e retorna o token

(29)

Exemplo de Implementação

O exemplo completo pode ser baixado do site

 http://sites.google.com/site/profpablosampaio

(30)

Implementação Manual

O exemplo anterior foi bem simples, para iniciar

Questões mais avançadas que costumam ser

tratadas por um lexer real:

 Tratamento de espaço em branco  Tokens de vários caracteres

 Tokens com prefixos comuns

(31)
(32)

Melhorando o Lexer

Tratando espaços em branco (whitespaces)

 Fazer um laço para ler todo caractere considerado

como espaço em branco

(33)

Espaços em Branco

// ignora os espaços em branco e quebras de linha while (nextChar == ' ' || nextChar == '\t'

|| nextChar == '\r' || nextChar == '\n') { nextChar = this.readByte();

}

// testar fim-de-arquivo aqui...

(34)

Melhorando o Lexer

Tokens de vários caracteres

 Faz uma decisão externa com base no primeiro

símbolo

Usar switch (mais eficiente) ou if-else’s encadeados

Dentro, faz um laço do-while (ou while)

 Cada símbolo válido deve ser concatenado ao

(35)

Tokens de Vários Caracteres

Considere que “lexema” é um objeto StringBuilder

... else if (Character.isDigit(nextChar)) { do { lexema.append((char) nextChar); nextChar = this.readByte(); } while (Character.isDigit(nextChar)); tipo = TokenType.NUMERO; } ...

(36)

Melhorando o Lexer

Prefixos comuns

 Se tokens de múltiplos caracteres tiverem parte em

comum

 Adiar a decisão sobre o tipo e deixa para fazer a

decisão num nível mais interno

 Continuar lendo os caracteres e armazenando no

(37)

Prefixos Comuns

 Exemplo: operadores “>=“ e “>” ... else if (nextChar == '>') { nextChar = this.readByte(); if (nextChar == '=') { tipo = TokenType.GREATER_EQ; nextChar = this.readByte(); } else { tipo = TokenType.GREATER;

//não precisa ler o próximo char }

} ...

(38)

Melhorando o Lexer

Tratando palavras-chaves

 Ler todo o lexema, como se fosse um identificador  Depois, compara o lexema inteiro com a lista de

palavras-chave

Pode usar uma tabela hash (Hashtable, em Java)  Adicionar as palavras-chave com seus tipos de token  Após ler o lexema, é só consultar a tabela

 Se não existir palavra-chave para aquele lexema,

(39)

Hash Table

Estrutura de dados que mapeia chaves (keys) a

valores (values)

Classe Hashtable (Java)

 Método “put” recebe o par (chave,valor)

 Método “get” recebe a chave e retorna o valor  Exemplo: associar “String” com “Integer”

Hashtable numbers = new Hashtable(); numbers.put("one", new Integer(1)); numbers.put("two", new Integer(2));

(40)

Tratando Palavras-Chaves

 Criação da hash

class Lexer {

...

private Hashtable keywords;

Lexer() { keywords.put(“if” , TokenType.IF); keywords.put(“else”, TokenType.ELSE); keywords.put(“int” , TokenType.INT); ... }

(41)

Tratando Palavras-Chaves

 Reconhecimento dos tokens, em nextToken()

if (Character.isLetter(nextChar)) { do { lexema.append((char)nextChar); nextChar = this.readByte(); } while (Character.isLetter(nextChar)); if (keywords.containsKey(lexema.toString())) { tipo = keywords.get(lexema.toString()); } else { tipo = TokenType.IDENTIFICADOR; } }

(42)

Alternativa

Ao invés de uma tabela Hash, pode ser usada

qualquer outra estrutura que funcione como um

dicionário

 Pares chave-valor  A chave é uma string

(43)

Sugestão

Como exercício, sugiro que tentem melhorar o

projeto do site (Xpress-0)

Faça o lexer da linguagem que chamo de

Xpress-1

 Tem caracteres brancos

(44)

Xpress-1

Especificação dos tokens

ABRE_PAR → ( FECHA_PAR → ) ADD → + MULT → * NUM_LITERAL → [0-9]+ PT_VG → ; WHITESPACE → [ \t\n\r]+

(45)

Passadas

É desejável que o lexer rode estritamente em

uma passada

 Cada caractere do código fonte é lido uma única vez  A menos, talvez, do tratamento das palavras

reservadas

Exemplo ruim:

(46)

Buffers

O livro ensina uma técnica para carregar o

arquivo, por partes, em buffers

Hoje em dia, não é necessário

 As bibliotecas de arquivos provavelmente já fazem

t e m p = a eof u x * 1 0 eof

código fonte código fonte

(47)

Conclusão

Fazer o lexer de forma manual é trabalhoso

Na próxima aula veremos uma forma

Referências

Documentos relacionados

A pesquisa será realizada na turma de primeiro ano do Ensino Médio, turma 103 e primeiramente será realizada uma pesquisa teórica sobre o que é Síndrome de Down e quais

Desta forma direcionamos nosso estudo aos problemas relacionados à população de trabalhadores da saúde que podem ser afetados pelo estresse, em consonância

ativamente durante a crise a prospecção de um inquilino, celebrando contrato de locação pelo prazo de 20 anos com uma das mais tradicionais redes de supermercado do estado de

Meus estudos recentes comprovam que as vacinas recombinantes contra a cinomose canina são capazes de proteger completamente filhotes de cães contra a cinomose canina após apenas

alternativas: [A], porque a seca no Brasil meridional é consequência da La Niña; [C], porque a alternativa cita os efeitos da La Niña; [D], porque o aumento das chuvas no nordeste

4 Cf. o prefácio do romance Moçambique com z de zarolho, escrito por Oz Iazdi... Esta forma de escrever o romance encontra analogia no intertexto das lite- raturas de fratura

Realizar um planejamento de capacidade de longo prazo para es- timar a quantidade de recursos necessários para execução de uma carga de trabalho e, assim, estabelecer bons contratos

Após o escoamento do pré-polímero e catalisador, é necessário que o material seja transferido para o processo posterior de mistura, assim foi aplicado um conjunto com