Você está na página 1de 42

Profa. Valria D.

Feltrim
DIN UEM

programa-fonte
analisador lxico
Tabela de smbolos

analisador sinttico
analisador semntico

Tabela de palavras e
smbolos reservados

gerador de cdigo intermedirio


otimizador de cdigo
gerador de cdigo
programa-alvo
dados de
entrada

sada

Manipulao
de erros

Primeira etapa de um compilador


Funes:
Ler o arquivo com o programa-fonte
Identificar os tokens correspondentes
um token se estende at que seja encontrado um
caracter que no faa parte dele
Relatar erros lxicos

Classes de tokens:
Identificadores
Nmeros
Palavras reservadas
Delimitadores e operadores

Seja a cadeia x:=y*2;


Cadeia

Token

t_id

:=

t_atrib

t_id

t_mult

t_num

t_ptvg

Seja a cadeia x:=y*2;


Token

Cdigo

Cadeia

Token

t_id

t_num

:=

t_mult

t_atrib

t_ptvg

program p;
var x: integer;
begin
x:=1;
while (x<3) do
x:=x+1;
end.

Cadeia

Token

program

t_program

t_id

t_ptvg

t_id

var

t_var

<

t_menor

t_id

t_num

t_doispt

t_fechapar

integer

t_tipo

do

t_do

t_ptvg

t_id

begin

t_begin

:=

t_atrib

t_id

t_id

:=

t_atrib

t_mais

t_num

t_num

t_ptvg

t_ptvg

while

t_while

end

t_end

t_abrepar

t_pt

Em geral, subordinado ao analisador sinttico


Sub-rotina do analisador sinttico: a cada chamada, o analisador
lxico retorna para o analisador sinttico uma cadeia lida e o
token correspondente
<lexema, token>

O analisador sinttico combina os tokens e verifica a


boa formao do programa-fonte usando a gramtica da
linguagem
programafonte

Analisador
lxico

obter
prximo token
token

Analisador
sinttico

Consumir comentrios e caracteres no imprimveis


(espao em branco, tabulao, cdigo de nova
linha)
Possvel manipulao da tabela de smbolos
Relacionar as mensagens de erro emitidas pelo
compilador com o programa-fonte
Manter contagem do nmero de linhas

Diagnstico e tratamento de erros lxicos

Exemplos:
O que delimita um token?
Diferenciao de letras maisculas/minsculas?
Qual o conjunto de palavras reservadas?
Qual as regras para a formao de identificadores?
Quais os operadores aceitos?
Quais os delimitadores aceitos? ( . ; : ) [ ] { }
Quais as regras para a formao de nmeros?
Quais as regras para a formao de comentrios?
etc.

Fragmento de gramtica:
cmd if expr then cmd
| if expr then cmd else cmd
expr termo relop termo
| termo
Regras de
termo id
lxicos:
| num
if
then
else
relop
id
num

formao dos itens

if
then
else
< | <= | = | <> | > | >=
letra ( letra | digito )*
digito+(.digito+)?(E(+|-)?digito+)?

Erros
Smbolo no pertencente ao conjunto de smbolos terminais da
linguagem: @
Identificador mal formado: j@, 1a
Tamanho do identificador: minha_varivel_para_...
Nmero mal formado: 2.a3
Tamanho excessivo do nmero: 5555555555555555
Fim de arquivo inesperado (comentrio no fechado): {...
Char ou string mal formados: a, hello world

Os erros detectveis nessa etapa so limitados


Viso local do programa-fonte, sem contexto
fi (a>b) then...

desejvel que se usem notaes formais para


especificar e reconhecer a estrutura dos tokens que
sero retornados pelo analisador lxico
Evitam-se erros
Mapeamento mais consistente e direto para o programa de
anlise lxica

Notaes
Gramticas ou expresses regulares: especificao de tokens
Autmatos finitos: reconhecimento de tokens

Determinam conjuntos de cadeias vlidas


Linguagem

Exemplos
Identificador: letra ( letra | dgito )*
Nmero inteiro sem sinal: dgito+
Nmero inteiro com sinal: ( + | - ) dgito+

Modelo matemtico
Conjunto de estados S
Conjunto de smbolos de entrada (alfabeto)
Funes de transio que mapeiam um par estado-smbolo de
entrada em um novo estado ()
Um estado inicial s0
Um conjunto de estados finais F para aceitao de cadeias

Reconhecimento de cadeias vlidas


Uma cadeia reconhecida se existe um percurso do estado
inicial at um estado final

S={0,1,2,3}, ={a,b}, s0=0, F={3}


a
0

Quais cadeias esse autmato aceita?


Escreva como uma expresso regular

S={0,1,2,3}, ={a,b}, s0=0, F={3}


a
0

Quais cadeias esse autmato aceita?


(a | b)*abb

Representao em tabela de transio


Vantagem: acesso rpido
Desvantagem: pode ocupar grande espao quando o alfabeto de
entrada grande
a
0

b
Estado

Smbolo de entrada
a

{0,1}

{0}

---

{2}

---

{3}

Se o autmato determinstico (i.e., para cada estado s e


smbolo de entrada a, existe somente uma transio possvel e
no existem transies vazias), o seguinte algoritmo pode ser
aplicado
s:=s0
c:=prximo_caractere()
enquanto (c<>eof e s for um estado vlido) faa
s:=transio(s,c)
c:=prximo_caractere()
fim
se s for um estado final
ento retornar cadeia aceita
seno retornar falhou

s:=s0
c:=prximo_caractere()
enquanto (c<>eof e s for um estado vlido) faa
s:=transio(s,c)
c:=prximo_caractere()
fim
se s for um estado final
ento retornar cadeia aceita
seno retornar falhou

Estado

Smbolo de entrada
a

{1}

{0}

---

{2}

---

---

S={0,1,2}, ={a,b}, s0=0, F={2}


b

Reconhecer cadeia bab

Algoritmo de Thompson para construo de AFs


ER
AFN
AFN
AFD
Minimizao de estados

Teoria da
Computao

Para a aplicao em compiladores, em geral,


muito simples construir um autmato determinstico
Definies lxicas relativamente simples

Opo: incorporao das transies no cdigo do programa


Tabela de transio no mais necessria
b
s:=s0
enquanto (verdadeiro) faa
c:=prximo_caractere()
0
case (s)
0: se (c=a) ento s:=1
seno se (c=b) ento s:=0
seno retornar falhou
1: se (c=b) ento s:=2
seno retornar falhou
2: se (c=eof) ento retornar cadeia aceita
seno retornar falhou
fim //case
fim //enquanto

! "
Exemplos de tokens possveis
Identificadores: x, y, minha_varivel, meu_procedimento, ...
Palavras reservadas e smbolos especiais: while, for, :=, <>, ...
Nmeros: inteiros, reais, ...

No basta identificar o token, deve-se retorn-lo ao


analisador sinttico junto com a cadeia correspondente
Concatenao da cadeia conforme o autmato percorrido
Associao de aes aos estados finais do autmato

s vezes, para se decidir por um token, tem-se que se


ler um caractere a mais, o qual deve ser devolvido
cadeia de entrada depois
Funo retroceder()

! "
Autmato para os smbolos := e :

q0

q1

q2

retornar(:=, t_atrib)

q3

retornar(:, t_dp)
retroceder()

outro

outro qualquer caracter diferente de =


Precisa ser devolvido entrada pois pode ser o incio de um
novo token
var x :integer

! "
Exerccio: autmato para operadores relacionais >, >=, <, <=, = e <>
q0

<

q1

q2

retornar(<=, t_menor_igual)

q3

retornar(<>, t_dif)

q4

retornar(<, t_menor)
retroceder()

q5

retornar(=, t_igual)

q7

retornar(>=, t_maior_igual)

q8

retornar(>, t_maior)
retroceder()

>

>

q6

outro

=
outro

! "
Autmato para identificadores: letra seguida de qualquer
combinao de letras e dgitos
letra|dgito

q0

letra

q1

outro

q2

retornar(cadeia,t_id)
retroceder()
Opcionalmente:
retornar(ptr, t_id)
retroceder()

! "
Autmato para palavras reservadas: while, if, for, array, etc.
Opes
Fazer um autmato para cada palavra-reservada
Trabalhoso e ineficiente

Deixar que o autmato para identificadores reconhea as


palavras reservadas e, ao final, verificar na tabela de palavras
reservadas se se trata de uma palavra reservada ou no
Simples e elegante
letra|dgito

q0

letra

q1

outro

q2

se busca_tabela(cadeia)=verdadeiro
ento retornar(cadeia,t_cadeia)
seno retornar(cadeia,t_id)
retroceder()

! "
Autmato para consumir caracteres no imprimveis: espaos
em branco, tabulaes e cdigos de nova linha
O analisador lxico no deve produzir tokens para esses
smbolos
letra|dgito

| \t | \n

q0

letra

q1

outro

q2

se busca_tabela(cadeia)=verdadeiro
ento retornar(cadeia,t_cadeia)
seno retornar(cadeia,t_id)
retroceder()

! "
Exerccios
Construir autmatos para se reconhecer
Nmeros inteiros com e sem sinal: 5, -1, 100
Nmeros reais: 3.11, 0.1

Construir autmato para consumir comentrios


{essa funo serve para...}
/*essa funo serve para...*/

Conjunto de procedimentos que reconhecem cadeias vlidas e


lhes associam tokens
Cada vez que chamado, retorna um par lexema-token para o
analisador sinttico
Consome caracteres irrelevantes: espaos em branco,
tabulaes, cdigos de nova linha, comentrios
Produz mensagens de erro apropriadas quando uma cadeia no
reconhecida por algum autmato
Tratamento apropriado na implementao do analisador lxico

!
Smbolo no pertencente ao conjunto de smbolos terminais da
linguagem / identificador mal formado: v@r
No h autmato para reconhecer esses smbolos

Nmero mal formado: 2.a3

Estado final do autmato de nmeros reais no atingido

Tamanho do identificador / tamanho excessivo de nmero:


minha_varivel_para_..., 5555555555555555
Dependncia da especificao da linguagem
Verificvel por ao associada ao estado final dos autmatos

Fim de arquivo inesperado (comentrio no fechado): {...

Dependncia da especificao da linguagem: comentrios de vrias linhas?


Estado final do autmato de comentrios no atingido

Char ou string mal formados: a, hello world

Estado final do autmato de literais no atingido

!
Idealmente, a compilao no pode parar
Opes para recuperao de erro Exemplo: beg#in
Deletar caracteres lidos at o erro e comear a anlise no prximo
caractere no lido
Retorna par <in,t_id>

Deletar o caractere ilegal e continuar a anlise


Retorna pares <beg,t_id> e <in,t_id>

No distinguir erros lxicos, i.e., associa-se um token nada ao erro e


deixa-se a identificao do erro para uma prxima etapa
Retorna pares <beg,t_id>, <#,t_nada> e <in,t_id>

Em qualquer caso, erros devem ser relatados


<#,erro_lxico> ou <#,caractere_invlido> na linha xxx...

#
Palavras reservadas
Carregadas no incio da execuo do compilador
Busca deve ser eficiente
Usar a mesma estrutura da Tabela de Smbolos ou uma
tabela separada (Tabela de Palavras Reservadas)

Reconhecimento de tokens
Criao e manuteno de um buffer
Facilidade de leitura e devoluo de caracteres no caso de
arquivos grandes
Arquivos pequenos podem ser lidos de uma vez para a memria

$
Para cada definio regular da linguagem, ser
construdo um autmato finito determinstico
Com exceo para as palavras reservadas, pois
inicialmente sero tratadas como identificadores

Fragmento de gramtica:
cmd if expr then cmd
| if expr then cmd else cmd
expr termo relop termo
| termo
termo id
| num

Regras de formao dos itens


lxicos:
if
if
then then
else else
relop < | <= | = | <> | > | >=
id
letra ( letra | digito )*
num digito+(.digito+)?(E(+|-)?digito+)?

"
q0

<

q1

q2

retornar(<=, t_menor_igual)

q3

retornar(<>, t_dif)

q4

retornar(<, t_menor)
retroceder()

q5

retornar(=, t_igual)

q7

retornar(>=, t_maior_igual)

q8

retornar(>, t_maior)
retroceder()

>

>

q6

outro

=
outro

"

letra | dgito

letra

10

outro

11

se busca_tabela(cadeia)=verdadeiro
ento retornar(cadeia,t_cadeia)
seno retornar(cadeia,t_id)
retroceder()

"
A definio da forma dgito frao? expoente?
Faremos 3 autmatos:
dgito
dgito frao?
dgito frao? expoente?

O lexema reconhecido para um dado token precisa ser o


mais longo possvel
O analisador lxico no pode parar aps enxergar 12 ou 12.3
quando a entrada for 12.3E4
Portanto, os 3 autmatos precisam ser testados na ordem
reversa
Inicio pelo autmato mais abrangente

"
dgito
12

dgito

13

dgito

dgito
dgito

14

15

16

+|

20

dgito

21

dgito

dgito

E
dgito

17

dgito

outro

19

retornar(cadeia,t_num)
retroceder()

dgito

22

dgito

23

outro

24

retornar(cadeia, t_num)
retroceder()

dgito

25

18

26

outro

27

retornar(cadeia, t_num)
retroceder()

"
Opcionalmente
dgito
12

dgito

13

dgito

dgito

14

dgito

15

16

20

17

dgito

18

dgito

E
outro

+|

outro

retornar(cadeia,t_num)
retroceder()

21

retornar(cadeia,t_num)
retroceder()

outro

19

retornar(cadeia,t_num)
retroceder()

$
Se pusermos todos os autmatos anteriores juntos,
teremos a seqncia de autmatos para o
reconhecimento dos tokens do 1slide
Estados iniciais com numerao mais baixa so testados antes

Sempre que possvel, melhor procurar por tokens de


alta freqncia antes dos tokens menos freqentes
Um autmato atingido somente aps termos falhado nos
autmatos anteriores
Ex.: Espao em branco muito freqente, portanto, seu
autmato deve vir no incio

%
Uma seqncia de autmatos pode ser convertida em
um programa que procure pelos tokens especificados
Enfoque sistemtico:
Cada estado recebe um segmento de cdigo
Se existem transies deixando o estado corrente, ento seu cdigo
l um caracter e determina que transio seguir (se possvel)
Se existe uma transio (caracter lido, estado E), o caracter
reconhecido e o controle transferido para o cdigo do estado E
Seno, o estado corrente no aceita o caracter lido e, nesse caso,
ocorre uma falha (chama-se a rotina falha(), que determina um novo
autmato para ser testado)

token proxToken(){
Consumo de caracteres
while (1) {
no imprimveis
switch (estado) {
case 0: c = proxChar();
if (c == || c ==\t || c ==\n){
estado = 0; inicio_lexema++;
} else if (c ==<) estado = 1;
else if (c ===) estado = 5;
else if (c ==>) estado = 6;
else estado = falha(); break;
...
case 9: c = proxChar();
if (isletter(c)) estado = 10;
else estado = falha(); break;
...
case 25: c = proxChar();
Conforme
if (isdigit(c)) estado = 26;
caracteres vlidos
else estado = falha(); break;
so lidos, devem
case 26: c = proxChar();
ser concatenados
if (isdigit(c)) estado = 26;
else estado = 27; break;
case 27: retrocede(1); instala_num(); return(t_num);
} //switch
Coloca o lexema em uma
} //while
varivel global
} //token

%
Rotina falha()
Retrocede o ponteiro de leitura para o incio do lexema
Decide qual ser o prximo estado de partida (qual autmato vai
ser testado)
int estado = 0, partida = 0; /* variveis globais */
int falha() {
ptr_leitura = inicio_lexema;
switch (partida) {
case 0: partida = 9; break;
case 9: partida = 12; break;
case 12: partida = 20; break;
case 20: partida = 25; break;
case 25: recupera(); break;
default: /* erro do compilador */
}
retornar partida;
estado
estado atual (rotina proxToken())
}
partida

estado de partida do autmato corrente

Você também pode gostar