Sei sulla pagina 1di 29

Compiladores - Autmatos

Fabio Mascarenhas - 2013.2


http://www.dcc.ufrj.br/~fabiom/comp
Especificao x Implementao
Usamos expresses regulares para dar a especificao lxica da linguagem
Mas como podemos fazer a implementao do analisador lxico a partir dessa
especificao?
Especificao x Implementao
Usamos expresses regulares para dar a especificao lxica da linguagem
Mas como podemos fazer a implementao do analisador lxico a partir dessa
especificao?
Autmatos finitos!
Algoritmos para converter expresses regulares so conhecidos e podem
ser reaproveitados, e autmatos levam a um analisador lxico bastante
eficiente
Autmatos Finitos
Um autmato finito formado por:
Um alfabeto de entrada
Um conjunto de estados
Um estado inicial
Um conjunto de estados finais rotulados
Um conjunto de transies entre estados
Transies
Uma transio s1 -
a
-> s2 quer dizer que se autmato est no estado s1 e o
prximo smbolo da entrada a ento ele vai para o estado s2
Se no h mais caracteres na entrada e estamos em um estado final ento o
autmato aceitou a entrada
Se em algum ponto no foi possvel tomar nenhuma transio, ou a entrada
acabou e no estamos em um estado final, o autmato rejeitou a entrada
Graficamente
Graficamente
estado
Graficamente
estado
estado inicial
Graficamente
estado
estado inicial
estado final
Graficamente
estado
estado inicial
estado final
transio
Graficamente
estado
estado inicial
estado final
transio
a b c
Graficamente
(0|1)*00
Transies
Uma transio uma transio que pode ser tomada espontaneamente pelo
autmato, sem ler nenhum smbolo da entrada
Podemos tambm construir um autmato que pode tomar mais de uma
transio dado um estado e um smbolo
Autmatos com transies e mltiplas transies saindo de um mesmo
estado para um mesmo caractere so no-determinsticos
DFA vs NFA
Um DFA um autmato determinstico, um NFA no-determinstico
Um DFA, dada uma entrada, toma apenas um caminho atravs dos seus
estados
Um NFA toma todos os caminhos possveis para aquela entrada, e aceita
entrada se pelo menos um caminho termina em um estado final
Funcionamento de um NFA
Entrada:
Estados:
Funcionamento de um NFA
Entrada: 1
Estados: { 0 }
Funcionamento de um NFA
Entrada: 1 0
Estados: { 0 } { 0, 1 }
Funcionamento de um NFA
Entrada: 1 0 0
Estados: { 0 } { 0, 1 } { 0, 1, 2 }
Funcionamento de um NFA
Entrada: 1 0 0
Estados: { 0 } { 0, 1 } { 0, 1, 2 }
Aceita!
Funcionamento de um NFA
Entrada: 0
Estados: { 0, 1 }
Funcionamento de um NFA
Entrada: 0 1
Estados: { 0, 1 } { 0 }
No aceita!
Autmatos e linguagens
DFAs, NFAs e expresses regulares todos expressam a mesma classe de
conjunto de smbolos
Linguagens regulares
Isso quer dizer que podemos converter de um para outro
DFAs so mais rpidos para executar
NFAs tm representao mais compacta
Expresses regulares so mais fceis de entender qual conjunto est sendo
expresso
Autmatos e linguagens
DFAs, NFAs e expresses regulares todos expressam a mesma classe de
conjunto de smbolos
Linguagens regulares
Isso quer dizer que podemos converter de um para outro
DFAs so mais rpidos para executar
NFAs tm representao mais compacta
Expresses regulares so mais fceis de entender qual conjunto est sendo
expresso
Por isso usamos
expresses regulares
para a especificao,
e DFAs (ou NFAs) para
implementao!
DFA de anlise lxica
Um DFA de anlise lxica tem os estados finais rotulados com tipos de token
A ideia executar o autmato at chegar no final da entrada, ou dar erro por
no conseguir fazer uma transio, mantendo uma pilha de estados visitados e
o token que est sendo lido
Ento voltamos atrs, botando smbolos de volta na entrada, at chegar em um
estado final, que vai dar o tipo do token
Analisador lxico de tabela
// reconhecer palavras
estado = s
0
token =
pilha.limpa()
while (!eof && estado erro) do
char = leChar()
token = token + char
push (estado)
estado = trans(estado,char)
end;
// limpar estado final
while (estado S
A
and !pilha.vazia()) do
estado pilha.pop()
token = token.truncaUltimo()
voltaChar()
end;
if (estado S
A
)
// rtulo do estado tipo do token
then return <estado, token>
else return erro
Uma otimizao
Se visitamos um estado final ento podemos limpar a pilha, j que vamos parar
nele na volta
// reconhecer palavras
estado = s
0
token =
pilha.limpa()
pilha.push(erro)
while (estado erro) do
char = leChar()
token = token + char
if estado S
A
then pilha.limpa()
push (estado)
estado = trans(estado,char)
end;
// limpar estado final
while (estado S
A
and estado erro) do
estado pilha.pop()
token = token.truncaUltimo()
voltaChar()
end;
if (estado S
A
)
// rtulo do estado tipo do token
then return <estado, token>
else return erro
Construindo o DFA de anlise lxica
Passo 1: construir um NFA para cada regra, o estado final desse NFA
rotulado com o tipo do token
Construo de Thompson
Passo 2: combinar os NFAs em um NFA com um estado inicial que leva aos
estados iniciais do NFA de cada regra via uma transio
Passo 3: transformar esse NFA em um DFA, estados finais ficam com o rtulo
da regra que aparece primeiro
Algoritmo de construo de subconjuntos
DFA da linguagem de comandos simples