Académique Documents
Professionnel Documents
Culture Documents
Anlise Lxica
Felipe Ferraz
Agenda
Definio de Compilador Etapas da Compilao Introduo Anlise Lxica Implementao Manual de um Lexer
Definio de Compilador
Compilador
Definio geral:
um programa que traduz um texto escrito em uma linguagem computacional (fonte) para um texto equivalente em outra linguagem computacional (alvo)
Entrada: cdigo fonte (na ling. fonte) Sada: cdigo alvo (na ling. alvo)
Tipos de Compiladores
Assembler ou Montador
Tipo simples de compilador A linguagem fonte uma linguagem assembly (ou linguagem de montagem)
Tipos de Compiladores
Compilador tradicional
Em muitos casos, o compilador gera cdigo objeto, que um cdigo de mquina incompleto
Etapas da Compilao
Etapas da Compilao
Tradicionalmente, os compiladores se dividem em um conjunto de etapas Mostraremos as cinco etapas bsicas a seguir
Podem existir tambm outras etapas intermedirias de otimizao de cdigo, omitidas na figura
8
Etapas da Compilao
Anlise Lxica
Anlise Sinttica
Fases da Compilao
Fase de Anlise
Fase de Sntese
Etapas da Compilao
Anlise Lxica
Anlise Sinttica
Front-End (Anlise)
Back-End (Sntese)
11
Etapas da Compilao
Modularidade deixa o compilador mais legvel e mais fcil de manter Eficincia permite tratar mais a fundo cada etapa com tcnicas especializadas Portabilidade facilita adaptar um compilador para
Receber outro cdigo fonte (muda o front-end) Gerar cdigo para outra mquina (muda o back-end)
12
Etapas da Compilao
Anlise Lxica
Anlise Sinttica
Front-End (Anlise)
Back-End (Sntese)
13
Anlise Lxica
Objetivo
Ler os caracteres do cdigo fonte agrupando-os de maneira significativa (em lexemas) e classificando esses agrupamentos (em tokens)
Em outras palavras
Relembrando...
Lexema: sequncia de caracteres com significado interligado Token: classificao dada ao lexema
Geralmente retornado junto com o prprio lexema ou outro atributo, como um ponteiro ou um valor numrico associado
16
Relembrando...
ATRIB
ADD MULT DEF ID NUM_INT PT_VG
=
+ * def [_a-z][_a-z0-9]* [0-9][0-9]* ;
17
WHITESPACE [ \t\n\r]+
Anlise Lxica
O mdulo de software responsvel por essa etapa pode ser chamado de:
Remover espaos em branco Contar linhas e colunas, para identificar a localizao de erros Expandir macros
18
Anlise Lxica
Existem vrias tcnicas para construo de um lexer, inclusive tcnicas de construo (semi) automtica
Porm, iniciaremos vendo como fazer um lexer simples manualmente
19
Implementao Manual
Linguagem para especificar expresses Tokens de 1 caractere apenas Sem tratamento de espaos em branco
21
Exemplo de Implementao
Tokens de XPR-0
NUMERO PT_VIRG ADD MULT ABRE_PAR FECHA_PAR [0-9] ; + * ( )
22
Exemplo de Implementao
Exemplo de Implementao
Exemplo no Eclipse...
24
Exemplo de Implementao
Criar classe Token Precisa guardar pelo menos o tipo Pode ter outras informaes
Exemplo no Eclipse...
25
Exemplo de Implementao
Mtodo nextToken()
Exemplo no Eclipse...
26
Implementao Manual
O exemplo anterior foi bem simples, apenas para dar uma noo de construo de um lexer
Complicaes adicionais que podem surgir
Tratamento de espao em branco Tokens de vrios caracteres Tokens com prefixos comuns Diferenciar identificadores de palavras-chave
27
Melhorando o Lexer
Espao em branco
Fazer um lao para ler todo caractere considerado como espao em branco Analisar antes de qualquer outro token
29
Melhorando o Lexer
Espaos em branco
// ignora os espaos em branco e quebras de linha while (nextChar == ' ' || nextChar == '\t' || nextChar == '\r' || nextChar == '\n') { nextChar = this.readByte(); } // testar fim de arquivo ... // testar outros tokens ...
30
Melhorando o Lexer
Dentro, faz um lao do-while (ou while) Cada smbolo vlido deve ser concatenado ao lexema
31
Melhorando o Lexer
... else if (Character.isDigit(nextChar)) { do { lexema.append((char) nextChar); nextChar = this.readByte(); } while (Character.isDigit(nextChar)); tipo = TokenType.NUMERO;
} ...
32
Melhorando o Lexer
Prefixos comuns
Se tokens de mltiplos caracteres tiverem parte em comum Adiar a deciso sobre o tipo e deixa para fazer a deciso num nvel mais interno Continuar lendo os caracteres e armazenando no lexema at poder decidir
33
Melhorando o Lexer
Prefixos comuns
... else if (nextChar == '>') { nextChar = this.readByte(); if (nextChar == '=') { tipo = TokenType.GREATER_EQ; nextChar = this.readByte(); } else { tipo = TokenType.GREATER; //no precisa ler o prximo char } } ...
34
Melhorando o Lexer
Pode usar uma tabela hash (Hashtable, em Java) Adicionar as palavras-chave com seus tipos de token Aps ler o lexema, s consultar a tabela
Hashtable
Estrutura de dados que mapeia chaves (keys) a valores (values) Classe Hashtable (Java)
Mtodo put recebe o par (chave,valor) Mtodo 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)); Integer v = (Integer) numbers.get("one");
36
Melhorando o Lexer
Palavras-chave
Criao da hash
Melhorando o Lexer
Palavras-chave
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; } }
38
Buffers de Leitura
Na leitura de um ID, por exemplo, preciso chegar num caractere invlido para parar Como devolver este ltimo caractere?
Ler um bloco de caracteres do disco mais eficiente do que ler caractere a caractere
40
Buffer nico
Geralmente, usa-se como tamanho do buffer o tamanho do bloco de disco Exemplo: 4096 bytes (4 KB)
41
Buffer nico
t e m p forward = a
lexemeBegin
lexemeBegin: incio do lexema atual forward: prximo caractere a ser analisado pelo
lexer
forward
42
Buffer nico
Vantagens
Leitura mais eficiente do arquivo (em blocos) Permite devolver um caractere, retornando o apontador forward
Buffers Duplos
Evita que um lexema fique incompleto, desde que tokens no possam passar do tamanho de um buffer
e m p = a u x * 1 0
lexemeBegin
forward
44
Buffers Duplos
Sentinelas
No precisa testar o fim do buffer a cada passo, basta testar quando achar esse caractere
cdigo fonte
sentinela
cdigo fonte
sentinela
46
Sentinelas
Basta consultar a posio do caractere Sentinelas ficam em posies fixas no fim do buffer Um fim de arquivo real aparece em qualquer outra posio
p = a eof u x ; eof
eof
sentinela
fim de arquivo
sentinela
47
48
Expresses Regulares
Expresses Regulares
Para especificar quais lexemas so associados a cada token, podem ser usadas expresses regulares
50
Expresses Regulares
ATRIB
ADD MULT DEF ID NUM_INT PT_VG
=
+ * def [_a-z][_a-z0-9]* [0-9][0-9]* ;
51
WHITESPACE [ \t\n\r]+
Lexer Manual
Tratar espaos em branco Tratar tokens de mltiplos caracteres Diferenciar identificadores de palavras reservadas Criao de buffer
Lexer Automtico
Recebe uma sequncia de caracteres de entrada Retorna se ela casa ou no com a expresso
Reconhecedor sim/no
53
palavra
(encontrada no cdigo fonte)
Expresses Regulares
Expresses bsicas
Operadores
54
Autmatos Finitos
Autmatos Finitos
Foram vistos em Teoria da Computao, junto com expresses regulares So equivalentes s expresses regulares, ou seja, representam as mesmas linguagens
56
Autmatos Finitos
Seguiremos a definio do livro texto para AFN, porm usando a sigla em ingls NFA
57
NFA
Pode ler o prximo smbolo da palavra Ou pode acontecer sem leitura de smbolo:
Se existir algum caminho que pare em um estado de aceitao, a palavra dita aceita
58
NFA
Exemplos:
s 3
Exerccio:
59
Como vimos em Teoria da Computao, possvel converter de uma expresso regular para um NFA
Veremos
61
62
63
64
NFA
Autmatos no-determinsticos (NFA) permitem mltiplos caminhos para leitura de uma mesma palavra
Pode ser usado, mas computacionalmente ineficiente, devido necessidade de expandir todos os caminhos
DFA
Sem transies vazias Com apenas uma opo de transio para cada caractere/smbolo Para todo caractere possvel, h uma transio
66
DFA
Exemplo
67
DFA
Exemplo
Diagrama de estados
Tabela
68
NFA DFA
A partir do NFA pode ser feita uma converso para um DFA por um processo genrico
O DFA resultante pode ficar com mais estados, mas existe um processo genrico de minimizao de estados tambm No veremos esses dois procedimentos...
69
Autmatos
Assim, os autmatos so usados para criar reconhecedores a partir de expresses regulares dadas
Mas como usar autmatos para criar um scanner? Como fazer isso automaticamente?
70
Recebe uma especificao (na forma de regras lxicas) Como sada, gera o cdigo do lexer
Regras Lxicas
Scanner
72
Regras Lxicas
Servem para especificar as expresses regulares e os tokens associados a elas Na prtica, associa a expresso regular com algum cdigo definido pelo usurio
{ return new Token(A_PARENT); } { return new Token(F_PARENT); }
"(" ")"
73
Gerando um Lexer...
Converte cada expresso regular (associada a cada token) para um NFA Une todos os NFAs em um s, criando um estado inicial e usando transies vazias
Um s estado inicial, mas vrios estados de aceitao Cada estado de aceitao vai indicar o reconhecimento de um token especfico
74
Gerando um Lexer...
Se dois estados de aceitao do NFA forem combinados em um estado do DFA, apenas o token definido primeiro ser retornado
Exemplo
Exemplo
77
Exemplo
NFA combinado
78
Exemplo
79
Reconhecimento no Lexer...
Vimos como gerar o autmato para reconhecer as expresses regulares associadas aos tokens
Mas como esse autmato usado no lexer gerado automaticamente?
80
Reconhecimento no Lexer...
Reinicia o autmato volta ao estado inicial Retoma a leitura de onde parou na ltima chamada
Reconhecimento no Lexer...
Exemplo
Incio no estado q0 L a q2q4q7 L b q5q8 L b q6q8 L b q8 L a erro, ento volta a q8 e retorna TOKEN_Z
83
Reconhecimento no Lexer...
O gerador l as regras lxicas, cria um autmato e, ento, gera o cdigo fonte do lexer baseado no autmato
O lexer, depois de compilado, que vai operar como descrito na ltima parte da aula
84
Exemplos de Geradores
Para C
Lex e Flex
Para Java
JLex e JFlex
Para C#
C# Lex, C# Flex
85
Bibliografia
AHO, A., LAM, M. S., SETHI, R., ULLMAN, J. D., Compiladores: princpios, tcnicas e ferramentas. Ed. Addison Wesley. 2a Edio, 2008 (Captulo 3)
86