Академический Документы
Профессиональный Документы
Культура Документы
Campus de Quixadá
Análise Léxica
Linguagens de Programação
Roteiro
Introdução
Análise Léxica
Expressões regulares
Autômato finito determinísticos
Autômato finito não determinísticos
flex - fast lexical analyzer generator
Análise Sintática
Introdução
Os sistemas de implementação de linguagens devem
analisar o código fonte, independentemente de qual
abordagem for utilizada:
Compilação, Interpretação ou Híbrido.
A sintaxe de praticamente todas as linguagens é descrita
através da BNF;
Introdução
A análise sintática consiste, na maioria dos casos, de duas
partes:
Análise Léxica: trata as construções de pequena escala (nome e
literais numéricos);
Análise Sintática: trata as construções de larga escala
(expressões, instruções)
Introdução
Vantagens do uso da BNF na descrição da sintaxe:
Fornece uma descrição clara e precisa da sintaxe;
O analisador sintático (parser) pode ser baseado
diretamente da BNF;
Parsers baseados na BNF são de fácil manutenção;
Introdução
Razões para se separar Análise Léxica da Sintática
Simplicidade: pode-se usar soluções menos complexas
para análise léxica (tornando o processo, como um todo,
menos complexo).
Eficiência: a separação permite a otimização da análise
léxica;
Portabilidade: partes do analisador léxico podem não
ser portáveis, mas o parser sempre é.
Análise Léxica
O analisador léxico é um reconhecedor de padrões para
strings;
Ele é um front-end para o parser;
Seu papel é identificar substrings, no programa fonte, que
apareçam juntas (lexemas);
Um lexema é um padrão de caracteres que é associado a
uma categoria léxica (token);
soma é um lexema, e IDENTIFICADOR é o seu token;
Análise Léxica
Funções:
Identificar tokens no texto-fonte
Guardar numeração das linhas
Gerar referência cruzada
Conversão de constantes
Ignorar alguns elementos sintáticos
Inserir identificadores (ids) na tabela de símbolos
Análise Léxica
Def.: Conjunto de strings formados a partir de
elementos de um alfabeto ∑
Exemplos para ∑ = {a,b}
L1 = {ab, ba}
L2 = {a, aa, aaa, aaaa, ...}
L3 = {ε , a, aa, aaa, aaaa, aaaaa, ...}
L4 = {}
L5 = {ε}
Análise Léxica
Operações com Linguagens
União
Concatenação
Fechamento
Fechamento Positivo
Análise Léxica
Definição recursiva de expressão regular
ε é uma e.r.
Se α ∈ ∑, α e (α) são e.r.
Se α e β são e.r., então αβ é uma e.r., denotando a linguagem
L(α)L(β)
Se α e β são e.r., então α|β é uma e.r., denotando a linguagem
L(α) ∪ L(β)
Se α é uma e.r., então α+ é uma e.r., denotando a linguagem
L(α)+
Se α é uma e.r., então α* é uma e.r., denotando a linguagem
L(α)*
Nada mais é e.r.
Análise Léxica
Aplicações de expressões regulares
Definição de constantes inteiras
d=0|1|2|3|4|5|6|7|8|9
n = d+
i = (+|-|ε)n
r = d*.d*
Ids do Cobol
l = a | b | ... | z | A | B | ... | Z
id = l(l|d)*
Análise Léxica
Autômatos
Def.: reconhecedores de linguagens a partir da
transição de estados
Tipos:
determinísticos (DFAs) - o próximo passo é conhecido,
independentemente do estado corrente
não-determinísticos (NFAs) - não se sabe o próximo passo
pois possivelmente existe mais de uma alternativa
Análise Léxica
AFs determinísticos
DFA = <Q, ∑, δ, Qo, F> onde:
Q conjunto de estados
∑ alfabeto
δ função de transição TOTAL
δ:Q x ∑→Q
Qo estado inicial Qo ⊆ Q
F estado final F ⊆ Q
Análise Léxica
AFs não-determinísticos
DFA = <Q, ∑, δ, Q0,F> onde:
Q conjunto de estados
∑ alfabeto
δ função de transição TOTAL
δ : Q x (∑ ∪ ε )→ 2Q
Q0 estado inicial Qo ⊆ Q,
F estado final F ⊆ Q
Análise Léxica
Análise Léxica
Análise Léxica
a..zA..Z0..9
a..zA..Z
q1 q2
q2
Análise Léxica
Análise Léxica
Existem três maneiras de se implementar um analisador
léxico:
Escrever uma descrição formal dos padrões de símbolos da
linguagem, utilizando uma linguagem de descrição relacionada
com expressões regulares e usar uma ferramenta de software
para gerar automaticamente o analisador;
Construir um diagrama de estados que descreve os tokens e
escrever um programa que implementa este diagrama;
Construir um diagrama de estados que descreve os tokens e
construir uma implementação do diagrama dirigida por tabela.
Análise Léxica
Em muitos casos, pode-se combinar transições para
simplificar o diagrama;
Para reconhecer identificadores, maiúsculas e minúsculas são
equivalentes;
Para reconhecer um literal inteiro, todos os dígitos são
equivalentes;
Palavras reservadas e identificadores podem ser reconhecidos
da mesma forma;
Procura-se na tabela se símbolos se um possível identificador não é,
de fato, uma palavra reservada.
Análise Léxica
getChar:
Pega o próximo caractere na entrada;
Coloca seu valor na variável global nextChar;
Determina sua classe e coloca-lá na variável global charClass;
Lookup
Determina se a string em lexema é uma palavra reservada
(retorna um código)
Análise Léxica
Análise Léxica
Análise Léxica
Análise Léxica
Análise Léxica
Matching rule
De cima para baixo
Mais longo possível
Elementos sintáticos das e.r.em flex
[a-zA-Z] conjunto
a* 0 ou +
a+ 1 ou +
b? 0 ou 1
^ início da linha
$ fim da linha
[^abc] qualquer caractere exceto a, b, e c.
a|b=> Reconhece a ocorrência de a ou de b
Análise Léxica
Exemplos de expressões regulares simples:
DIGITO [0-9]
LETRA [a-zA-Z]
INTEIRO [0-9]+
INTSIGNED -?[0-9]+
DECIMAL [0-9]*\.[0-9]+ => aceita .33 / não aceita números
sem casas decimais
INTOUDEC ([0-9]+)|([0-9]*\.[0-9]+)
IOUDSIGNED -?(([0-9]+)|([0-9]*\.[0-9]+))
NOMEVAR [a-z][a-z0-9\_]* => usando opção “case
insensitive”...