Você está na página 1de 14

Linguagens e Programao

2 Anlise Lxica
Fontes: 1. Compiladores Princpios e prticas, Keneth C.Louden, Thomson, 2004. Cap. 1 Introduo Cap. 2 Processo de Varrimento, Anlise lxica 2. Compiladores - Princpios , Tcnicas e Ferramentas, Alfred V. Aho, Monica S. Lam e Ravi Sethi, Pearson, 2 edio, 2007. Cap. 3 Anlise Lxica 3. Processadores de Linguagens da concepo implementao, Rui Gustavo Crespo. IST Press.1998. Cap. 2 Definio de Linguagens

Ana Madureira
Engenharia Informtica Ano Lectivo: 2011/2012

Anlise Lxica
Agrupa sequncias de caracteres em tokens - as unidades bsicas da sintaxe A sequncia de caracteres que formam um token chama-se lexema tokens tpicos: constantes (literais), ids, operadores, palavras--chave, etc. Elimina sequncias de caracteres inteis (espaos, tabs, LF, CR, comentrios) Recorre-se de:
Expresses Regulares - representam padres de cadeias de caracteres Autmatos Finitos forma matemtica de descrever tipos particulares de algoritmos , para descrever o processo de reconhecimento de padres em cadeias de caracteres.

Funes da Anlise Lxica

Agrupar os caracteres individuais do programa fonte em palavras, designadas por tokens, que so as unidades bsicas das linguagens de programao, e que sero usados pelo analisador sintctico (parser) ignorar alguns tipos de caracteres (espaos, tabs, LF, CR) e os comentrios produzir mensagens de erro quando algum caracter ou sequncia de caracteres no so reconhecidos localizar os tokens no texto fonte (n de linha, n de coluna) actuar como pr-processador (em certos compiladores)

Tokens e Lexemas
Token representa um conjunto de cadeias de entrada possvel Lexema uma determinada cadeia de entrada associada a um token
Token Alguns lexemas possveis

for if while nmero

for if while 1089, 142857, .0, 3.14159

identificador

i, j, contador, nome_aluno

abr_par

Analisador lxico
O analisador lxico (scanner) actua como uma subrotina do analisador sintctico (parser):
programa fonte Pedido do prximo token

scanner
token

parser

struct TokenRecord { TokenType kind; int linenum; union { char *lexeme; int value; } attribute; }

typedef enun {ID, NUM, IF, THEN, TokenType;

Especificao do analisador lxico


Definio do conjunto de tokens Descrio genrica (atravs das suas propriedades) das entidades constituintes da linguagem fonte Dependente da gramtica da linguagem fonte Exemplos de algumas dessas entidades: Palavras-chave da linguagem (p. ex: if then while do, etc.) identificadores (de variveis, procedimentos, tipos, campos de registos, etc.) operadores (aritmticos, lgicos, booleanos, etc.) constantes (tambm chamadas literais - inteiros, reais, caracteres, strings, etc.) sinais de pontuao (; , : [ ( .. etc. ) Definio das regras de formao dos tokens Exemplo: identificador - sequncia de letras ou dgitos, iniciada por letra

Especificao dos tokens


Os tokens so geralmente especificados utilizando expresses regulares As expresses regulares so regras bem definidas que geram um conjunto de sequncias de caracteres (strings) O conjunto de strings gerado por uma expresso regular chama-se uma linguagem regular As strings geradas por uma expresso regular so construdas com caracteres de um conjunto de smbolos chamado alfabeto ()
A linguagem regular gerada por uma expresso regular 'r' denota-se como L(r) (conjunto de strings que so sequncias de smbolos de ) A linguagem regular vazia (sem qualquer string) nota-se por . A linguagem vazia () diferente da linguagem que s contm a string vazia (que se nota por ) L() = { }

Operaes sobre Expresses Regulares


So trs as operaes sobre expresses regulares que fazem parte da sua definio formal (em ordem crescente de prioridade): Alternativa: Uma expresso regular da forma s | t, onde s e t so expresses regulares; se r = s | t ento L(r) = L(s) L(t) Concatenao: Uma expresso regular da forma st, onde s e t so expresses regulares; se r = st ento L(r) = L(s)L(t) = {st | s L(s) et L(t)} Fecho de Kleene: Uma expresso regular da forma s*, onde s uma expresso regular; se r = s* ento L(r) = L(s)*

Uso de parntesis: Uma expresso regular da forma (s), onde s uma expresso regular; se r = (s) ento L(r) = L(s); os parntesis servem apenas para modificar a precedncia das operaes Notar o uso dos caracteres | * ( e ) para designar as operaes entre expresses regulares: estes caracteres com significado especial designam-se por metacaracteres. Se estes caracteres tambm pertencerem ao alfabeto ento o seu uso como caracteres deve ser distinguido de alguma forma ( p. ex. colocando-os entre plicas - (

Exemplos
Concatenao Se S = {aa, b} e T = {a, bb} ento R = ST = {aaa, aabb, ba, bbb}

Fecho de Kleene Se S = {a} ento S* = S0 S1 S2 S3 onde S0 = {}, S1 = S, S2 = SS, S3 = SSS, logo S* = {, a, aa, aaa, aaaa, }
No alfabeto = {a, b, c} a) escrever uma expresso regular que represente todos as strings que contm um s b: (a | c)* b (a | c)* A expresso gera uma linguagem que contm por exemplo: b, abc, abaca, ccbaca, cccccb, etc. b) escrever uma expresso regular que represente todos as strings que contm no mximo um b: (a | c)* | (a | c)* b (a | c)* ou (a | c)* (b | ) (a | c)* Ambas as expresso de cima geram a mesma linguagem que a que foi especificada por palavras

Exemplos
No alfabeto = {a, b, c} escrever uma expresso regular que represente todos as strings que no contm bs consecutivos.
Strings que no contm bs: (a | c)* Strings que tm qualquer coisa a seguir a um b: (b (a | c) )* Combinando os 2 anteriores temos realmente strings sem bs consecutivos: ( (a | c) * | (b (a | c) )* )* = ((a | c) | b (a | c) )* uma vez que (r* | s*)* = (r | s)* No entanto esta ainda no a soluo para o problema inicial, uma vez que no contempla os strings que terminam em b. Para chegar soluo geral basta agora dar essa possibilidade: ((a | c) | b (a | c))* (b | )

Abreviaturas em expresses regulares


Uma ou mais repeties: r r* pode abreviar-se para r+ Zero ou uma instncias (opcional): (r | ) pode abreviar-se para r? Qualquer carcter do alfabeto: (c1 | c2 | | cn) para todo o alfabeto, pode abreviar-se por . Alternativas entre alguns caracteres ou numa gama de caracteres considerando o alfabeto um conjunto ordenado:
(a | b | c ) pode abreviar-se por [abc] letra = [a-zA-Z] char_identificador = [a-zA-Z_]

Qualquer carcter do alfabeto excepto alguns:


alfabeto - todas as letras minsculas (qualquer smbolo excepto a|b|c) = [d-z] pode abreviar-se por ~(a | b | c) ou mais simplesmente por ~[abc] ou ainda [^abc]

Subexpresses:
natural = [0-9]+ natural_com_sinal = (+ | -)? natural

Expresses regulares na definio dos tokens


Para a construo de um analisador lxico deve-se comear por escrever uma expresso regular que compreenda a definio de todos os tokens da linguagem. Processo:
1. Escrever uma expresso regular para cada classe de token da linguagem r1 = palavra_chave = if | then | while | do | r2 = identificador = letra (letra | digito)* r3 = inteiro = digito+ r4 = espao_em_branco = (\n | \t | ' ' | comentario)+
(esta ltima definio no token, mas tambm tem de ser reconhecida)

2. Escrever uma expresso regular global (R)agrupando todas as definies anteriores: R = palavra_chave | identificador | inteiro | espao_em_branco | ...

Limitaes das Expresses Regulares


Certos tokens so difceis de especificar numa expresso regular, como os comentrios delimitados por 2 caracteres, em ordem inversa
Ex: comentrios em C - delimitados por /* e */ : Uma soluo: /* /* (** [^/ *] /*)* *+/

H certos tokens que no so especificveis com expresses regulares


Ex: Os comentrios em Modula-2 podem ser imbricados: (* isto um comentrio em (* Modula - 2 *) *)

Certas linguagens exigem que se conheam vrios caracteres para alm do fim do token que se est a reconhecer (lookahead) Ex: No FORTRAN as palavras chave no so reservadas nem o espao em branco significativo:
IF ( I F .EQ. 0) THENTHEN=1.0 (instrues vlidas em FORTRAN) DO99I=1,10 DO99I=1.10

Nestes casos necessrio usar um scanner no totalmente baseado em expresses regulares

Propriedades das Expresses Regulares


Sejam u e v expresses regulares. Tem-se que:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. u+v=v+u u+u=u (u+v)+x=u+(v+x) u= u=u (uv)x=u(vx) u(v+x)=uv+ux (u+v)x=ux+vx *= u*=u*u*=(u*)*=u*+u* u*= +u*=( +u)*=( +u)u*= +uu* 11. u*=(u++uk)*, k1 12. u*= +u++u k-1+uku*, k>1 13. u*u=uu* 14. (u+v)*=(u*+v*)*=(u*v*)*=(u *v)*u*=u*(vu*)* 15. u(vu)*=(uv)*u 16. (u*v)*= +(u+v)*v 17. (uv*)*=+u(u+v)*

As propriedades das expresses regulares mencionadas acima servem para simplificar expresses regulares e provar a equivalncia entre duas expresses regulares.

Autmato Finito (AF)


As expresses regulares so convenientes para especificar os tokens de uma linguagem.

Que formalismo usar para que possa ser facilmente implementado num programa? Modelo matemtico conhecido por autmato finito (AFD), definido por um vector (S, , s0, F, ): o alfabeto de entrada um conjunto finito de estados S um conjunto de transies entre estados para um carcter de (ou ) do tipo do estado x transita-se para o estado y com a entrada 'c' : S x S (funo parcial) um conjunto de estados de aceitao ou finais F (F S) um estado inicial s0 S

Um autmato finito pode ser representado por uma tabela ou, mais frequentemente por um grafo, em que os ns so estados e os ramos transies, etiquetados com os caracteres que determinam essa transio; os estados inicial e finais devero estar marcados

Representao Grfica

Representao de Autmatos finitos


Podem ser representados por tabelas ou grafos: AFD = (S, , s0, F, )
Esboo de um programa para implementao de um AFD: CASE estado of A: CASE entrada of 0: estado A; END; 1: estado B; END; B: CASE entrada of 0: estado B; END; 1: estado A; END; END;

Autmatos finitos (exemplos)

Reconhecimento de uma string com n caracteres por um AFD:


Comeando no estado inicial, para cada caracter da string, o autmato executa exactamente uma transio de estado para um prximo estado, seguindo o ramo etiquetado com esse caracter. Se aps as n transies o autmato estiver num estado final, ento aceita a string. Se no estiver num estado final ou se em qualquer altura no existir um ramo etiquetado com o caracter actual da string da entrada, ento essa string rejeitada.

Autmatos finitos (exemplos)


<nmero real> = (+|-)?<dgito>*.<dgito>+(e(+|-)?<dgito>+)? function realnum: boolean; var entrada: char; estado: integer; begin estado:=1; read(entrada); while (entrada>=0 and entrada<=9) or (entrada=+) or (entrada=-) or (entrada=e) or (entrada=.) do begin case estado of 1: case entrada of 0,1,9: estado=2; -,+: estado=2; .: estado=3; otherwise: estado=8; end; 2: end; read(entrada); end; realnum:=(estado=4) or (estado=7) end

estado 8: erro

3
. . dgito|+|- digto
+ e|-|

digto

1
dgito

2
|+ |- e

|.

4
+ |- |.

outro caracter

|. |+ |- e|-|+|. e

8
qualquer +|-

dgito

7
dgito

6
dgito

Autmatos finitos (exemplos)


Autmato finito que reconhece os tokens: if id ( < <=
Para reconhecer uma entrada como: if ( a <= seguem-se as transies de estado comeando no estado inicial at no se conseguir ir mais alm (mxima substring);
0-9 a-z

a-e g-z 0-9 ID ID

f IF i

0-9 a-z a-h j-z (

nessa altura se estivermos num estado final reconhece-se o token respectivo; se no estivermos num estado final recuamos, carcter a carcter, at passarmos por um estado final.

PAREN ESQ

<

6
MENOR

7
MENOR|IGUAL

10

Tipos de autmatos
Seja A=(S, , i, F, ) um autmato finito.
A diz-se autmato finito determinstico (AFD) se, perante um smbolo x de , puder transitar, no mximo, para um nico estado, isto : ( (s, x, s) (s, x, s) ) s = s Caso contrrio, A diz-se no determinstico A diz-se autmato finito se possvel transitar de estado sem usar nenhum smbolo de , isto :

S x ({}) x S
Para o alfabeto = {a, b, c, d}, qualquer palavra com um nmero par de smbolos b.

uma string em a,b em que todas as strings acabam em b e comeam em a;

Autmatos finitos no-determinsticos (AFN)


Os autmatos anteriores so determinsticos (as transies entre estados fazem-se apenas com caracteres do alfabeto, e todas as transies que saem de um estado esto etiquetadas com caracteres diferentes) Certas strings so mais fceis de especificar com um autmato no determinstico Exemplo: Todas as strings no alfabeto {0, 1} terminadas por 0 1 1

Exemplo: Strings constitudas por um mltiplo de 2 ou 3 as

Os autmatos finitos no determinsticos podem ter transies de estado sem consumirem qualquer entrada - as chamadas transies

11

Aceitao de AFNs
Uma string x1xn aceite por um AFN se existir um caminho comeando no estado inicial e terminando num estado final, cujas etiquetas dos ramos percorridos coincidam, por ordem, com os caracteres x1 a xn, com a possvel incluso, em qualquer local, de qualquer nmero de transies Os autmatos finitos (determinsticos e no determinsticos) definem linguagens, que so exactamente o conjunto de strings aceites pelo autmato Existe equivalncia entre expresses regulares (ER), autmatos finitos determinsticos (AFD) e autmatos finitos no determinsticos (AFN) Dada uma expresso regular sempre possvel construir um AFN que aceita exactamente a mesma linguagem Dado um AFN sempre possvel construir um AFD que aceita exactamente a mesma linguagem algoritmo da construo dos subconjuntos Dado um AFD sempre possvel construir uma ER que aceita exactamente a mesma linguagem

Equivalncia entre AFN e AFD (exemplo)


Exemplo: Todas as strings no alfabeto {0, 1} terminadas por 0 1 1 Exemplo

AFN
0|1 0 1 1

4
0

AFD
1

1 0 1

2
0 0 1

12

Equivalncia entre AFN e AFD (exemplo)


Exemplo: Exemplo Strings constitudas por um mltiplo de 2 ou 3 as

AFN

AFD
a a a a a a

4
a

Caminho e rtulo
Seja A=(S, , i, F, ) um autmato finito. Um caminho no trivial uma sequncia (s0, a1, s1), (s1, a2, s2), ..., (sn-1, an, sn) onde (si-1, ai, si) Um caminho trivial uma tripla da forma (s, , s), com s S O rtulo do caminho a1 a2 ... an

13

Linguagem reconhecida por um AF


Seja A=(S, , i, F, ) um autmato finito. Um caminho diz-se bem sucedido se comea num estado inicial e termina num estado final Linguagem reconhecida por A: L(A) = {u * : u o rtulo de um caminho bem sucedido em A}

14

Você também pode gostar