Escolar Documentos
Profissional Documentos
Cultura Documentos
Notas de Aula
(atualizado em 21/06/2013)
Este material apenas um roteiro contento os tpicos na ordem que so estudados em sala de aula com uma breve explicao dos pontos mais importantes. Portanto, necessrio que voc complete seus estudos lendo a bibliografia indicada. Mais importante ainda a resoluo dos exerccios propostos que esto em outro documento. H um foco para estudos de casos aplicados s linguagens de programao visando uma construo slida de pr-requisitos para a disciplina de Compiladores. Sobre a ementa, critrios avaliativos, lista de exerccios propostos, materiais de apoio, ferramentas para interao etc, consulte o site da disciplina: http://www.ceunes.ufes.br/prof/henriquecristovao Tpicos: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. Bibliografia recomendada: ................................................................................................................. 3 Hierarquia de Chomsky, seus elementos, aplicaes e exemplos: ..................................................... 3 Exemplo de gramtica. ....................................................................................................................... 4 Estudo de caso 1: nmero inteiros ...................................................................................................... 6 Conceitos importantes ........................................................................................................................ 7 Linguagens Regulares ........................................................................................................................ 7 Gramtica Regular (GR)..................................................................................................................... 7 Estudo de caso 1: nmero inteiros (resolvido com gramtica regular) ............................................. 8 Expresso Regular .............................................................................................................................. 8 Estudo de caso 1: nmero inteiros ...................................................................................................... 9 Estudo de caso 2: nmeros reais ......................................................................................................... 9 Autmato Finito Determinstico (AFD) ........................................................................................... 10 Exemplos de AFD, AFND e AF..................................................................................................... 11 Estudo de caso 1: nmero inteiros .................................................................................................... 14 Estudo de caso 2: nmeros reais ....................................................................................................... 15 GR x AFD x ER ............................................................................................................................... 15 Algoritmo para converter AFD em GR (sem conflitos esquerda): ................................................ 15 Estudo de caso 2: nmeros reais (gramtica regular sem conflitos) ................................................ 16 Estudo de caso 3: nomes de variveis .............................................................................................. 17 Estudo de caso 4: nmeros binrios sem sinal e com 3 dgitos ........................................................ 17 Estudo de caso 5: nmeros reais com possibilidade de notao cientfica....................................... 18 Estudo de caso 6: nmeros hexadecimais em Java, de 1 a 4 dgitos ................................................ 19 Estudo de caso 7: nmeros octais em Java ....................................................................................... 19 Converso de AFND e AF em AFD ............................................................................................... 19
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 1 / 66
25. Minimizao de um Autmato Finito............................................................................................... 19 26. Busca de texto: aplicao para um AFND ....................................................................................... 20 27. Uso do simulador JFLAP para Linguagens Regulares ..................................................................... 21 28. Lema do Bombeamento para Linguagens Regulares ....................................................................... 24 29. Aplicao do Lema do Bombeamento para a Prova de No Regularidade de Linguagens ............. 25 30. Mquina de Mealy ............................................................................................................................ 27 31. Mquina de Moore ........................................................................................................................... 27 32. Exemplo de Mquina de Moore para classificar nmeros inteiros sem sinal .................................. 28 33. Exemplo de Mquina de Moore para classificar os operadores relacionais do C/Java .................... 29 34. Mquina de Moore para construo de Analisador Lxico .............................................................. 30 35. Gramtica Livre de Contexto (GLC) ................................................................................................ 30 36. Exemplos de linguagens livres de contexto...................................................................................... 30 37. Uso do simulador JFLAP para Linguagens Livres de Contexto ...................................................... 31 38. Aplicaes de Linguagens Livres de Contexto ................................................................................ 32 39. Gramticas ambguas e o problema do else flutuante ...................................................................... 37 40. Fatorao de gramticas ................................................................................................................... 37 41. Algoritmo para fatorar gramticas.................................................................................................... 38 42. Recursividade esquerda em gramticas ......................................................................................... 39 43. Algoritmo para eliminao da recursividade esquerda .................................................................. 39 44. Anlise Preditiva .............................................................................................................................. 40 45. Anlise Preditiva na construo de Analisadores Sintticos ............................................................ 42 46. Forma Normal de Chomsky ............................................................................................................. 42 47. Aplicao da Forma Normal de Chomsky: Algoritmo de Cocke-Younger-Kasami ........................ 42 48. Forma Normal de Greibach .............................................................................................................. 43 49. Formato BNF para gramticas livres de contexto ............................................................................ 43 50. Formato EBNF para gramticas livres de contexto .......................................................................... 44 51. Autmato com Pilha ......................................................................................................................... 45 52. Aplicao da Forma Normal de Greibach: construo de Autmato com Pilha .............................. 47 53. Lema do Bombeamento para Linguagens Livres de Contexto ........................................................ 47 54. Aplicao do Lema do Bombeamento para Linguagens Livres e Contexto .................................... 47 55. Linguagens Sensveis ao Contexto ................................................................................................... 48 56. Mquina de Turing ........................................................................................................................... 48 57. Gramtica Sensvel ao Contexto ...................................................................................................... 50 58. Linguagens Enumerveis Recursivamente ....................................................................................... 52 APNDICE A: Exemplo de uso do Graphviz (Graph Visualization Software) ........................................ 53 APNDICE B: Exemplo de um Analisador Lxico construdo atravs da Anlise Preditiva .................. 56 APNDICE C: Exemplo de um Analisador Sinttico construdo atravs da Anlise Preditiva ............... 63
1. Bibliografia recomendada:
MENEZES, Paulo Fernando Blauth. Linguagens Formais e Autmatos. 5 ed. Porto Alegre: Sagra Luzzatto, 2008. HOPCROFT, John E.; ULLMAN, Jeffrey D.; MOTWANI, Rajeev. Introduo teoria de autmatos, linguagens e computao. 2. ed. Rio de Janeiro: Elsevier, 2002. ROSA, Joo luis Garcia. Linguagens formais e autmatos. Rio de Janeiro: LTC, 2010. SUDKAMP, Thomas A. Languages and machines: an introduction to the theory of computer science. 2. ed. Massachusets: Addison-Wesley Publishing Company, Inc., 1997. GERSTING, Judith L. Fundamentos matemticos para a cincia da computao. 4. ed. Porto Alegre: Sagra Luzzatto, 2001. LEWIS, Harry R.; PAPADIMITRIOU, Christos H. Elementos de teoria da computao. 2. ed. Porto Alegre: Artmed, 2000.
Linguagem Regular (tipo 3) Formalismo denotacional: expresso regular. Formalismo gerador (ou axiomtico): gramtica regular. Formalismo reconhecedor: autmato finito determinstico. Aplicaes: representao e gerao de tokens; construo de analisadores lxicos (scanner). Exemplos de linguagens: nomes de variveis de uma linguagem, nmeros inteiros sem sinal, nmeros reais, palavras reservadas de uma linguagem, ponto-e-vrgula, operadores relacionais.
Linguagem Livre de Contexto (tipo 2) Formalismo gerador: gramtica livre de contexto. Formalismo reconhecedor: autmato com pilha. Aplicaes: representao e gerao de programas da maioria das linguagens de programao conhecidas (C++, Pascal, Java, etc.); construo de analisadores sintticos (parser). Exemplos de linguagens: Linguagem C, Linguagem SQL. Linguagem Sensvel ao Contexto (tipo 1) Formalismo gerador: gramtica sensvel ao contexto. Formalismo reconhecedor: Mquina de Turing com memria limitada. Aplicaes: auxlio na representao de linguagens naturais. Linguagem Enumervel Recursivamente (tipo 0) Formalismo gerador: gramtica irrestrita, tambm conhecida como gramtica com estrutura de frase. Formalismo reconhecedor: Mquina de Turing. Aplicaes: auxlio na representao de linguagens naturais.
3. Exemplo de gramtica. Para ilustrar o conceito de gramtica que ser dado logo adiante, segue uma gramtica divertida e geradora de frases em ingls. Disponvel em SUDKAMP, 1997.
<sentence> -> <noun-phrase><verb-phrase> | <noun-phrase><verb><direct-object-phrase> <noun-phrase> -> <adjective-list><proper-noun> | <determiner><adjective-list><common-noun> <proper-noun> -> John | Jill <common-noun> -> car | hamburger <determiner> -> a | the <verb-phrase> -> <verb><adverb> | <verb> <verb> -> drives | eats <adverb> -> slowly | frequently <adjective-list> -> <adjective><adjective-list> | <adjective> -> big | juicy | brown <direct-object-phrase> -> <determiner><adjective-list><common-noun>
ou ainda:
<sentence> =>* big John drives slowly
rvore de derivao:
<sentence>
<noun-phrase>
<verb-phrase>
<adjective-list>
<proper-noun>
<verb>
<adverb>
John
drives
slowly
<adjective>
<adjective-list>
big
Obs.: como a gramtica livre de contexto e est no nvel 2 da Hierarquia de Chomsky, ela no tem poder de representar de forma completa uma linguagem natural que do nvel zero, portanto ela tambm gera frases semanticamente incorretas, como por exemplo:
the big big car eats a brown car
Parte dos problemas semnticos podem ser resolvidos computacionalmente, tal como ser visto na disciplina de Compiladores no prximo semestre. A representao formal de uma gramtia dada por uma qudrupla de elementos G = (V, T, P, S) Onde: V = conjunto de smbolos variveis (ou no terminais) T = conjunto de smbolos terminais P = conjunto de regras de produo S = smbolo que deve iniciar todas as derivaes Sendo assim a gramtica anterior definida: G = (V, T, P, <sentence>) V = { <sentence>, <noun-phrase>, <verb-phrase>, <verb>, <direct-object-phrase>, <proper-noun>, <determiner>, <common-noun>, <adverb>, <adjective-list>, <adjective>, <direct-object-phrase>}
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 5 / 66
T = { a, the, John, Jill, hamburger, car, drives, eats, slowly, frequently, big, juicy, brown } P = { <sentence> -> <noun-phrase><verb-phrase> | <noun-phrase><verb><direct-object-phrase>
<noun-phrase> -> <adjective-list><proper-noun> | <determiner><adjective-list><common-noun> <proper-noun> -> John | Jill <common-noun> -> car | hamburger <determiner> -> a | the <verb-phrase> -> <verb><adverb> | <verb> <verb> -> drives | eats <adverb> -> slowly | frequently <adjective-list> -> <adjective><adjective-list> | <adjective> -> big | juicy | brown <direct-object-phrase> -> <determiner><adjective-list><common-noun>
Observe a modularizao feita, passando a responsabilidade do sinal para A e a responsabilidade do nmero inteiro sem sinal para B. Desta forma a expresso resultante ficou sendo a concatenao de A com B.
5. Conceitos importantes
Alfabeto: um conjunto finito de smbolos. Normalmente representado por String, palavra ou cadeia de caracteres: uma sequencia finita de smbolos do alfabeto justapostos. Palavra vazia: a ausncia de smbolos. Normalmente representada por ou Tamanho de uma string: a qtde de smbolos que compe a string. |w| representa o tamanho de w. Prefixo, sufixo e subpalavra (ou substring). Concatenao. Concatenao sucessiva: suponha w uma palavra de uma alfabeto e n a quantidade de concatenaes sucessivas, ento: wn = wn-1 w. Quando n=0: w0 = Estrela de Kleene: seja V um conjunto, ento V* o conjunto de todos elementos que podem ser formados atravs da concatenao de zero ou mais elementos de V. Linguagem formal: um conjunto de palavras sobre um alfabeto.
Duas gramticas so equivalentes se a linguagem gerada de uma igual a outra.
6. Linguagens Regulares
Tem como aplicao o reconhecimento de tokens num projeto de compiladores. Possui os seguintes formalismos (sero estudados com detalhes nas prximas sees): Gerador: gramtica regular (GR) Denotacional: expresso regular (ER) Reconhecedor: autmato finito determinstico (AFD)
Propriedades: Se L uma linguagem gerada por uma gramtica regular, ou representada por uma expresso regular, ou reconhecida por um autmato finito determinstico, ento L uma linguagem regular . Se L uma linguagem regular ento existe uma gramtica regular que gega L, existe tambm uma expresso regular que representa L, e existe um autmato finito determinstico que reconhece L.
9. Expresso Regular
um formalismo denotacional para linguagens regulares que facilita a comunicao homem x homem, e principalmente entre homem x mquina. Definio: uma expresso regular (ER) sobre um alfabeto indutivamente definida como: a) {} uma ER e representa a linguagem vazia; b) uma ER e representa a linguagem contendo a string vazia;
c) x uma ER e representa a linguagem {x} d) se r e s so ER e representam as linguagens R e S respectivamente, ento: d.1) ( r | s ) ER e representa a linguagem R U S Obs.: algumas literaturas usam: r + s, outras usam: r U s d.2) ( rs ) ER e representa a linguagem RS = {uv | u R e v S} d.3) ( r* ) ER e representa a linguagem R*
Precedncia: por conveno assume-se a seguinte ordem de execuo: 1) parnteses: ( ) 2) concatenao sucessiva: * 3) concatenao 4) unio: |
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 8 / 66
Conjunto de meta-smbolos extendidos usados nas ER e normalmente encontrados na literatura: Suponha o alfabeto = {a,b} a+
a|b
a*
a?
Descrio da linguagem, ou exemplos de strings { , a, aa, aaa, aaaa, } { a, aa, aaa, aaaa, } { , a } { a, b } { ab} { , ab, abab, ababab, ...}
Obs.: ba, aab, aabb no pertencem linguagem { , b, bb, bbb, a, aa, aaa, ...} Obs.: ba, bba, ab no pertencem linguagem todas as strings, inclusive todas as strings, exceto
todas as strings iniciadas por a todas as strings terminadas por ba todas as strings com tamanho par strings iniciadas por a e terminadas por b strings iniciadas por bb e terminadas por aaa
10.
ER: (+|-|)(0|...|9)+
11.
Exemplos de strings da linguagem: L= { 2.5, +2.5, -2.5, +2, -2, +0, 0, .5, -.5, ...} ER: (+|-|)(0|...|9)*(.)?(0|...|9)+
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 9 / 66
12.
um formalismo reconhecedor que tem como objetivo aceitar ou rejeitar strings dadas como entrada de uma determinada linguagem regular. Ou seja uma mquina abstrata capaz de reconhecer a pertinncia de strings para uma dada linguagem representada pelo autmato atravs de um grafo orientado. Definio: Um autmato finito determinstico (AFD) uma 5-upla M = (, Q, , q0, F) onde: o alfabeto dos smbolos de entrada Q o conjunto dos estados possveis a funo transio, :Qx Q q0 o estado inicial F o conjunto de estados finais. Deve possuir ao menos um elemento.
Representao do AFD por intermdio de um grafo: O estado inicial indicado por uma seta sem origem, e os estados finais so representados por dois crculos concntricos, cada um. Exemplo 1: AFD para aceitar a linguagem regular formada apenas por a.
M = (, Q, , q0, F) = {a,b}
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 10 / 66
Q = {q0, q1} - funo transio: a q0 q1 q1 F = {q0} Algumas observaes importantes sobre autmatos finitos: em cada estado pode ter no mximo uma transio de sada por smbolo terminal, seno ele classificado como Autmato Finito No Determinstico (AFND) havendo uma transio com o autmato classificado como Autmato com Movimentos Vazios (AF) todo AFND e AF pode ser convertido em AFD.
b q0
13.
Observe os exemplos (j usados em ER) a a distino entre AFD, AFND, AF. AFD, AFND, AF
ER
a*
a+
a?
a|b
ab
(ab)*
b*|a*
(a|b)*
(a|b)+
a(a|b)*
AFND:
AFD:
(a|b)*ba
((a|b)(a|b))+
AFND:
AFD:
a(a|b)*b
AFND:
AFD:
bb(a|b)+aaa
AF:
a?b+
AFD:
14.
AF :
AFD:
15.
Exemplos de strings da linguagem: L= { 2.5, +2.5, -2.5, +2, -2, +0, 0, .5, -.5, ...} ER: (+|-|)(0|...|9)*(.)?(0|...|9)+ AF:
AFD:
GR:
G = (V,T,P,S) V = {S,A,B} T = {+,-,.,0,1,2,3,4,5,6,7,8,9} P = { S -> +A | -A | A A -> 0A |...| 9A | .B | B B -> 0B |...| 9B | 0 |...| 9 }
16.
GR x AFD x ER
Se uma dada linguagem formal pode ser representada por um dos elementos GR, AFD ou ER, ento ela regular e pode-se encontrar os outros dois elementos.
17.
Cada estado do AFD se transforma numa varivel da gramtica, e cada transio numa regra. Os estados finais simbolizam a varivel que vai para .
Exemplo:
Quando usamos um AFD, ao invs de um AF ou AFND, temos a garantia de obter uma gramtica sem conflitos esquerda. considerado conflito em terminais esquerda para uma mesma varivel.
18.
V = {S,A,B,C,D} T = {+,-,.,0,1,2,3,4,5,6,7,8,9} P = { S -> +A | -A | .C | 0B |...| 9B A -> 0B |...| 9B | .C B -> .C | 0B |...| 9B | C -> 0D |...| 9D D -> 0D |...| 9D | }
19.
Suponha que estas variveis s podem ser formadas por uma letra obrigatria e, opcionalmente, seguidas de letras e nmeros. Exemplos de strings da linguagem: L= { x, Valor, Salario13, a2b3, ....} ER: (a|...|Z)(0|...|9|a|...|Z)*
AFD:
GR:
G = (V,T,P,<S>) V = {<S>,<A>} T = {0,...,9,a,...,z,A,...,Z} P = { } <S> -> a<A> |...| Z<A> <A> -> a<A> |...| Z<A> | 0<A> |...| 9<A> |
20.
L= { 000, 001, 010, 011, 100, 101, 110, 111 } ER: (0|1)(0|1)(0|1) AFD:
GR:
G = (V,T,P,S)
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 17 / 66
ou, simplesmente:
G = (V,T,P,S) V = {S} T = {0,1} P = { S -> 000, 001, 010, 011, 100, 101, 110, 111 }
21.
Exemplos de strings da linguagem: L= { 2.5E34, +2.5E-45, -2.5e+5, +2e7, .5E100, -.555e555, ...} ER: (+|-)?(0|...|9)*(.)?(0|...|9)+ ((E|e)(+|-)?(0|...|9)+)?
AFD:
GR:
G = (V,T,P,<S>) V = {<S>,<A>,<B>,<C>,<D>,<E>,<F>} T = {+,-,.,0,1,2,3,4,5,6,7,8,9,e,E} P = { <S> -> +<A> | -<A> | .<C> | 0<B> |...| 9<B> <A> -> 0<B> |...| 9<B> | .<C> <B> -> .<C> | e<E> | E<E> | 0<B> |...| 9<B> | <C> -> 0<D> |...| 9<D> <D> -> 0<D> |...| 9<D> | | e<E> | E<E> <E> -> 0<F> |...| 9<F> <F> -> 0<F> |...| 9<F> | }
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 18 / 66
22.
Exemplos de strings da linguagem: L= { 0xABCD, 0x0000, 0XA, 0X3a3f, 0x25, ...} ER: 0(X|x)(0|...|F)(0|...|F)?(0|...|F)?(0|...|F)? AFD:
23.
So sempre iniciados por zero e formados por dgitos de 0 a 7. Convencionaremos que apenas um zero no octal, mas decimal. Supomos tambm a inexistncia de sinal. L= { 05, 01234567, 00, 01010, ...} ER: 0(0|...|7)+ AFD:
24.
25.
26.
Fonte: HOPCROFT, ULLMAN, MOTWANI, 2002. O AFND transformado para seu equivalente AFD:
27.
Pgina principal do JFLAP: http://www.jflap.org/ Download: http://www.jflap.org/jflaptmp/ Tutorial: http://www.jflap.org/tutorial/ Execute diretamente o arquivo JFLAP.jar
Dicas para construo: para criar uma transio arraste o mouse do estado inicial at o estado final.
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 21 / 66
o software no aceita a notao a,b como transies para os smbolos a ou b, mas devem ser feitas uma transio separada para cada smbolo. use o boto direito para selecionar estado inicial e final (selecione o boto ). ).
uma transio para o prprio estado feita com um clique sobre ele (selecione o boto
3- Teste do autmato: Selecione Input - Multiple Run Digite as strings de teste e selecione Run Inputs:
28.
Se L linguagem regular, ento m 1; w L, |w| m onde w = xyz com |y| 1 e |xy| m e i 0, xyiz L
Obs.: m pode ser considerado como a qtde de estados de um AFD que reconhece a linguagem regular (SUDKAMP, 1997, p. 212) sobre o limite m 1, entre as bibliografias consultadas, somente Lewis e Papadimitriou (2000, p. 91) estabelecem esta condio. Tal limite til em provas da no regularidade de linguagens. Veja exemplo 3 no prximo tpico onde, na prova por absurdo, considerar m 1 permite que w = a2m bm bm am continue no pertencendo a L, por outro lado se fizssemos m=0, w pertenceria a L, invalidando a prova.
Exemplo 1: Linguagem: L = ab Tal com o lema afirma, se L regular ento dever atender as condies do Lema: m = 3 ; w L, |w| 3 onde w = xyz com |y| 1, |xy| 2 Como no existe nenhum w com tamanho maior ou igual a 3, ento i 0, xyiz L
Exemplo 2: Linguagem: L = ab* L regular, logo deve atender as condies do Lema: m = 2 ; w L, |w| 2 onde w = xyz com |y| 1, |xy| 2 Testando para cada um w: w = ab; x=a, y=b, z=. i 0, xyiz L w = abb; x=a, y=b, z=b. i 0, xyiz L w = abbb; x=a, y=b, z=bb. i 0, xyiz L e assim por diante.
Ateno: os exemplos 1 e 2 so apenas ilustrativos, mas o Lema do Bombeamento no serve para provar que uma linguagem regular!! Ele apenas afirma que se ela for regular ento atende a determinadas condies. No prximo tpico veremos uma aplicao til do Lema.
Exemplos de provas de no regularidade de linguagens: Exemplo 1: L = { an bn | n 0 } Suponha por absurdo que L seja regular, ento existe um w escolhido como am-1 a bm , m, pertence a L onde w = xyz com x= am-1 e y=a e z=bm satisfazendo |w| m, |y| 1 e |xy| m Assim fazendo i=0 em w = xyiz teremos w = am-1 bm no pertencente a L, o que uma contradio! Logo, L no regular.
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 25 / 66
Exemplo 2: L = { aj bk | j k 0 } Suponha por absurdo que L seja regular, ento existe um w escolhido como am+1 b bm-1 , m, pertence a L onde w = xyz com x= am+1 e y= b e z=bm-1 satisfazendo |w| m, |y| 1 e |xy| m Assim fazendo i=3 em w = xyiz teremos w = am+1 bm+2 no pertencente a L, o que uma contradio! Logo, L no regular. Exemplo 3: L = { x xR | x {a,b}* } Suponha por absurdo que L seja regular, ento existe um w escolhido como am bm bm am , m, pertence a L onde w = xyz com x= e y= am e z= bm bm am satisfazendo |w| m, |y| 1 e |xy| m Assim fazendo i=2 em w = xyiz teremos w = a2m bm bm am no pertencente a L, o que uma contradio! Logo, L no regular. Exemplo 4: L = { aj bk | j k } Suponha por absurdo que L seja regular, ento existe um w escolhido como am bm+m , m, pertence a L onde w = xyz com x= e y= am e z= bm+m satisfazendo |w| m, |y| 1 e |xy| m Assim fazendo i=2 em w = xyiz teremos w = a2m bm+m = a2m b2m no pertencente a L, o que uma contradio! Logo, L no regular. Exemplo 5: L = { ap | p primo } Suponha por absurdo que L seja regular, ento existe um w escolhido como am-1 a, m primo 3, pertence a L onde w = xyz com x= am-1 e y= a e z= satisfazendo |w| m, |y| 1 e |xy| m Assim fazendo i=2 em w = xyiz teremos w = am+1 no pertencente a L, pois m+1 no primo, o que uma contradio! Logo, L no regular.
30.
Mquina de Mealy
Pode ser considerado como um Autmato Finito Determinstico (AFD) com sadas associadas s transies. Definio: Uma Mquina de Mealy uma 6-upla M = (, Q, , q0, F, ) onde: o alfabeto dos smbolos de entrada Q o conjunto dos estados possveis a funo transio, :Qx Qx* q0 o estado inicial F o conjunto de estados finais. Deve possuir ao menos um elemento. o alfabeto de smbolos de sada Exemplo: uma Mquina de Mealy que l uma cadeia de 0s e 1s e produz uma sada trocando os caracteres da entrada (0s por 1s e 1s por 0s).
31.
Mquina de Moore
um AFD com sadas associadas aos estados. Aplicao tpica de Mquinas de Moore no desenvolvimento de Analisadores Lxicos em Compiladores, onde so classificados os caracteres de entrada de um programa em tokens, ou seja, em unidades lxicas que representam uma categoria de elementos. Exemplos de tokens: numeros reais, variveis, operadores relacionais, palavras reservadas, etc. Definio: Uma Mquina de Moore uma 7-upla M = (, Q, , q0, F, , G) onde: o alfabeto dos smbolos de entrada Q o conjunto dos estados possveis a funo transio, :Qx Q q0 o estado inicial F o conjunto de estados finais. Deve possuir ao menos um elemento. o alfabeto de smbolos de sada G a funo de sada, G:Q *
Exemplo: observe uma Mquina de Moore para solucionar o mesmo problema resolvido pela Mquna de Mealy anterior, ou seja, l e troca os caracteres da entrada para a sada.
32.
Esta mquina de Moore classifica nmeros inteiros sem sinal de acordo com a sua base: decimal, octal e hexadecimal. ER para cada sada da mquina: ER para nmeros hexadecimais <HEX>: ER para nmeros decimais <DEC>: ER para nmeros octais <OCT>: Sero considerados 0, 08 e 058 como decimais. Obs.: as sadas so representadas pelas descries entre < e > e em letras maisculas.
34.
Uma aplicao bastante interessante para a Mquina de Moore na construo de analisadores lxicos em compiladores. No apndice B, encontra-se um exemplo, desenvolvido em Java, de um analisador para uma linguagem simples. Sugere-se como trabalho da disciplina a implementao de um analisador lxico para um subconjunto de uma linguagem de programao conhecida.
35.
um formalismo gerador para linguagens do tipo 2, na Hierarquia de Chomsky. Numa GLC, as regras no tem limitao do lado direito. Isto , elas tem o formato: A -> Onde: A V (conjunto de variveis) (TUV)* (concatenaes de smbolos entre T e V)
36.
Como elas no so regulares, no existe expresso regular que as represente. Observe a outra notao usada para a sua representao: an = as concatenados n vezes { a i bi ; i0 }
i)
S -> aSb |
ii)
{ a2i b2i
; i1 }
iii)
; i 0, k 0 }
iv)
{ ai bk ak bi
; i 1, k 1 }
v)
37.
Pgina principal do JFLAP: http://www.jflap.org/, e download: http://www.jflap.org/jflaptmp/ Gramtica livre de contexto 1- Selecione Grammar 2- Digite a gramtica no espao indicado:
3- Para testar uma string, selecione Input Brute Force Parse Digite a string desejada na caixa Input e clique em Start Se houver indicao que ela foi aceita, pressione Step vrias vezes para visualizar a rvore de derivao.
38.
Os elementos classificados numa mquina de Moore pertencem s linguagens regulares, so representados por expresses regulares, gerados por gramticas regulares e reconhecidos por autmatos finitos determinsticos fincando limitados em representaes simples como nmeros, variveis, palavras reservadas, operadores etc. Problemas mais complexos, como trechos de um programa, expresses com parnteses balanceados no podem ser representados por gramticas regulares, precisando subir um nvel na Hierarquia de Chomsky para serem representados, neste caso, as linguagens livres de contexto. Estudo de caso: GLC para gerar trechos de uma linguagem de programao parecida com o Pascal Suponha os seguintes tokens j classificados por um analisador lxico atravs de uma mquina de Moore. Token
<NUM> <IDENT> <ATRIB> <OPER-ADIT> <OPER-MULT> <VIRG> <PT-VIRG> <ABRE-PAR> <FECHA-PAR> <FOR> <FUNCTION> <BEGIN> <END> <DO> <TO> <DOWNTO>
Expresso regular
(0|...|9)*(.)?(0|...|9)+ (a|...|Z)(0|...|9|a|...|Z)* := +|*|/ , ; ( ) (f|F)(o|O)(r|R) (f|F)(u|U)(n|N)(c|C)(t|T)(i|I)(o|O)(n|N) (b|B)(e|E)(g|G)(i|I)(n|N) (e|E)(n|N)(d|D) (d|D)(o|O) (t|T)(o|O) (d|D)(o|O)(w|W)(n|N)(t|T)(o|O)
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 32 / 66
Exemplos de GLCs para gerar as linguagens descritas: i) Expresso aritmtica com parnteses balanceados, nmeros, variveis e operadores de soma, subtrao, multiplicao e diviso. Exemplos de 5 strings: 2 ; (+3) ; 3-+6 ; 2*(Valor+4) ; 3-(Cont1+Cont2)*(4-(9-8)+1) GLC:
exp
->
termo ->
Esta GLC tambm poderia ser reescrita usando-se um nico smbolo no terminal (exp):
exp -> exp <OPER-ADIT> exp | exp <OPER-MULT> exp | <ABRE-PAR> exp <FECHA-PAR> | <OPER-ADIT> <NUM> | <NUM> | <IDENT>
ii)
iii)
Bloco de comandos de atribuio. Cada comando deve ser terminado por ponto-e-vrgula. Exemplo de 1 string:
begin x := 3; Valor := Valor + 2 * (x+1); end
GLC:
blocoAtrib -> <BEGIN> listaAtrib <END> listaAtrib -> atrib <PT-VIRG> listaAtrib |
iv)
Comando de repetio for estilo Pascal. Considere que o corpo pode ser composto apenas por atribuies e/ou outros comandos for, e o incio e fim podem ser expresses aritmticas quaisquer. Dois exemplos: 1 string:
for x := 0 to 50 do begin x := 3; Valor := Valor + 1; end for x := 10 downto 5 do for y := 1 to 10 do w := w + x + y;
2 string:
GLC:
comandoFor -> <FOR> <IDENT> <DOIS-PT> <ATRIB> exp sentido exp <DO> corpoFor sentido -> <TO> | <DOWNTO> corpoFor -> comandonico | blocoComandos comandonico -> atrib <PT-VIRG> | comandoFor blocoComandos -> <BEGIN> listaComandos <END> listaComandos -> comandonico listaComandos |
v)
Definio de funes no estilo Pascal. O corpo e formado por comandos de atribuio e/ou for. Exemplo 1:
function Media(Nota1,Nota2:Real; var Peso:Integer):Real; var Soma, Resultado : Real; Status : Integer; begin Soma := Nota1 + Nota2; Resultado := Soma/2; Status := 1; Media := Resultado; end
Exemplo 2:
function Constante:Real; begin Constante := 100; end
GLC:
declaraFuno -> <FUNCTION> <IDENT> parmetro <DOIS-PT> <PT-VIRG> declaraVar corpoFuno parmetro -> <ABRE-PAR> listaArgumentos <FECHA-PAR> | listaArgumentos -> argumento <PT-VIRG> listaArgumentos | argumento argumento -> referncia defVar referncia -> <VAR> | defVar -> listaIdent <DOIS-PT> tipo tipo -> <IDENT> listaIdent -> <IDENT> <VIRG> listaIdent | <IDENT> declaraVar -> | <VAR> listaDeclara listaDeclara -> defVar <PT-VIRG> listaDeclara | defVar corpoFunao -> blocoComandos
39.
Uma gramtica ambgua quando gera a mesma string por mais de uma derivao. Um situao tpica onde isto acontece na gramtica que gera a estrutura condicional sem os tokens de marcao de bloco, como por exemplo nas Linguagens C e Java:
if(x>5) if(y>8) comando1; else comando2;
Para resolver tal conflito, o else sempre pertence ao if mais prximo, como mostra a identao:
if(x>5) if(y>8) comando1; else comando2;
<IF> <ABRE-PAR> expresso <FECHA-PAR> comando | <IF> <ABRE-PAR> expresso <FECHA-PAR> comando <ELSE> comando
Esta gramtica ambgua pois gera o cdigo anterior atravs de duas rvores de derivao distintas. Sugere-se como exerccio a construo de uma gramtica no ambgua para resolver o problema.
40.
Fatorao de gramticas
Quando se implementa uma gramtica atravs da aplicao da anlise preditiva, espera-se que esta no possua conflitos a esquerda, pois seno h uma impossibilidade de escrever as condicionais que representam cada opo da regra. Exemplo:
S -> aS | aA A -> bA |
H um conflito esquerda no terminal a, e isto impossibilita o funcionamento do algoritmo: Veja uma tentativa de implementao:
S() { se(prox = a) reconhece(a); S(); seno se(prox = a) reconhece(a); A(); } A() { se(prox = b) reconhece(b); A(); }
41.
Caso geral da eliminao de conflitos esquerda: Gramtica com conflito esquerda: A -> 1 | 2 | ... | n | Onde: A V ,n, (TuV)* Gramtica sem conflito esquerda (fatorada): A -> R | R -> 1 | 2 | ... | n Onde: A,R V ,n, (TuV)*
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 38 / 66
42.
Outro pr-requisito para aplicao da anlise preditiva que no haja recursividade esquerda na gramtica. Exemplo:
S -> Sa | b
Linguagem gerada: ba* A varivel S possui recursividade esquerda. No h como implementar uma gramtica desta forma. Veja uma tentativa:
S() { se(prox = b) S(); reconhece(a); seno se(prox = b) reconhece(b); }
Implementao:
S() { reconhece(b); R(); } R() { se(prox = a) reconhece(a); R(); }
43.
Caso geral: Gramtica com recursividade esquerda: A -> A1 | A2 | ... | An | 1 | 2 |...| n Onde: A V n,n (TuV)* Gramtica sem recursividade esquerda: A -> 1R | 2R |...| nR R -> 1R | 2R| ... | nR | Onde: A,R V n,n (TuV)*
44.
Anlise Preditiva
uma tcnica algoritmica que transforma uma gramtica em um algoritmo reconhecedor. Pr-requisitos para a gramtica: fatorada (sem conflitos esquerda sem recursividade esquerda sem ambigidade
Procedimentos bsicos: - cada varivel da gramtica se transforma num procedimento. - cada ou encontrado numa regra deve ser escrito como uma estrutura condicional onde cada seleo deve verificar a ocorrncia de todos os possveis primeiros terminais.
Uma possvel gramtica para esta linguagem (neste caso, a gramtica no regular):
G = (V,T,P,S) V = {S,A,B,C,D,E} T = {a,b,c,d,e,f,g,<EOF>} P = {S -> A <EOF> | <EOF> A -> aA | bA | Bg B -> cC C -> B | DE D -> dD | E -> e | f }
Como esta gramtica no tem conflito, ambigidade e recursividade esquerda, aplicaremos a tcnica da anlise preditiva para gerao do algoritmo:
funo S() { se(prxCaracter==a ou prxCaracter==b ou prxCaracter==c) A(); reconhece(<EOF>); seno se(prxCaracter==<EOF>) reconhece(<EOF>); seno imprime(erro); // era esperado um dos seguintes caracteres: a,b,c,<EOF> )
funo A() { se(prxCaracter==a) reconhece(a); A(); seno se(prxCaracter==b) reconhece(b); A(); seno se(prxCaracter==c) B(); reconhece(g); seno imprime(erro); // era esperado um dos seguintes caracteres: a,b,c ) funo B() { reconhece(c); C(); ) funo C() { se(prxCaracter==c) B(); seno se(prxCaracter==d ou prxCaracter==e ou prxCaracter==f) D(); E(); seno imprime(erro); // era esperado um dos seguintes caracteres: c,d,e,f } funo D() { se(prxCaracter==d) reconhece(d); D(); seno ; } funo E() { se(prxCaracter==e) reconhece(e); seno se(prxCaracter==f) reconhece(f); seno imprime(erro); // era esperado um dos seguintes caracteres: e,f } Obs.: A funo reconhece tem o objetivo de verificar se o prximo caractere de fato o que foi passado como argumento. Se sim ento l o prximo caractere pe em prxCaracter, seno dispara uma mensagem de erro. funo reconhece(caracter c) { se(prxCaracter == c) prxCaracter = lPrximoCaracterDoArquivo(); seno imprime(erro); // era esperado o caractere representado por c sai_do_programa; }
45.
Desde que a gramtica de uma determinada linguagem esteja fatorada, sem recursividade esquerda e sem ambiguidade, constri-se facilmente um analisador sinttico por meio da tcnica da anlise preditiva explicada no tpico anterior. Neste caso, ele se comporta como um reconhecedor top-down. No apndice C encontra-se um exemplo, desenvolvido em Java, de um analisador sinttico construdo por meio da tcnica da anlise preditiva. Este exemplo a continuidade do analisador lxico apresentado no apndice B. Sugere-se como trabalho da disciplina a implementao de um analisador sinttico para um subconjunto de uma linguagem de programao conhecida.
46.
Uma gramtica livre de contexto est na Forma Normal de Chomsky (FNC) se cada produo segue uma das seguintes formas: i) ii) A -> BC A -> a
onde: A, B, C V a Exemplo: A gramtica formada pelas regras: S -> aSb | c Pode ser reescrita na FNC como: S A B C -> -> -> -> AB | c a SC b
47.
O algoritmo de Cocke-Younger-Kasami foi desenvolvido por J. Cocke, D. H. Younger e T. Kasami, em 1965. Ele usa uma gramtica livre de contexto na FNC e classificado como bottom-up, ou seja, faz o processamento a partir das folhas da rvore de derivao. Desta forma, ele aceita gramticas com conflitos esquerda e recursividade esquerda. Sugere-se como trabalho da disciplina o estudo e a implementao deste algoritmo para a construo de um analisador sinttico aplicado a um subconjunto de uma linguagem de programao.
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 42 / 66
48.
Uma gramtica livre de contexto est na Forma Normal de Greibach (FNG) se toda produo possui a seguinte forma: A -> a onde: AV a U {} V*
Exemplo: A gramtica formada pelas regras: S -> aSb | c Pode ser reescrita na FNG como: S -> aSB | c B -> b
Uma aplicao interessante da FNG a construo de autmatos com pilha, que sero estudados mais adiante.
49.
um formato de gramtica usado para simplificar escritas de gramticas livres de contexto. BNF: Backus Naur Form foi escrito pela primeira vez por John Backus and Peter Naur para a sintaxe da linguagem de programao Algol 60. O formato BNF consiste em, simplesmente, reescrever regra do tipo: A -> uA | em: A -> {u}
Exemplo: Suponha uma gramtica para gerar declaraes de variveis em Java, como: int a,b; double c; suponha tambm os tokens: <TIPO>, <IDENT>, <VIRG>, <PT-VIRG>
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 43 / 66
Uma gramtica convencional seria escrita desta forma: listaDeclara -> declara <PT-VIRG> listaDeclara | declara -> <TIPO> listaIdent declara | listaIdent -> <IDENT> <VIRG> listaIdent | <IDENT>
No formato BNF ela ficaria: listaDeclara -> { declara <PT-VIRG> } declara -> { <TIPO> listaIdent } listaIdent -> <IDENT> { <VIRG> <IDENT> }
50.
uma Extenso do BNF. usado tambm na simplificao da escrita de gramticas livres de contexto, sendo bem mais poderoso do que o formato BNF. Usa os mesmos meta-smbolos da expresso regular: *, +, ?, |, alm de permitir a associao de subexpresses com parnteses. Exemplo: Suponha uma gramtica para gerar declaraes de variveis em Java, como: int a,b; double c; suponha tambm os tokens: <TIPO>, <IDENT>, <VIRG>, <PT-VIRG> Uma gramtica convencional seria escrita desta forma: listaDeclara -> declara <PT-VIRG> listaDeclara | declara -> <TIPO> listaIdent declara | listaIdent -> <IDENT> <VIRG> listaIdent | <IDENT>
No formato EBNF ela ficaria: listaDeclara -> ( <TIPO> <IDENT> ( <VIRG> <IDENT> )* <PT-VIRG> )*
51.
uma mquina abstrata para reconhecimento de linguagens livres de contexto. um AFND com o poder de uma pilha associada. Definio: Um autmato com pilha (AP) uma 6-upla M = (, Q, , , q0, F) onde: o alfabeto dos smbolos de entrada Q o conjunto finito dos estados possveis o conjunto de smbolos de pilha a funo transio : Q x ( U {}) x ( U {}) (Q x U {}) q0 o estado inicial F o conjunto de estados finais. Deve possuir ao menos um elemento. Representao do AP por intermdio de um grafo: Tal como no AFND, o estado inicial indicado por uma seta sem origem, e os estados finais so representados por dois crculos concntricos, cada um. No precisa de ser determinstico. Para que ocorra a aceitao da palavra de entrada necessrio que, alm de terminar a leitura da palavra e o autmato estar num estado final, a pilha deve estar vazia. Cada transio formada pelo smbolo de leitura seguido do smbolo que desempilhado e o smbolo que empilhado. Exemplos: Obs.: devido a limitao do software que fez o desenho, ser considerado @ como i) L = { a n bn ; i0 }
S -> aSb |
M = (, Q, , , q0, F) onde: = { a, b } Q = { q0, q1 } ={X} (q0, a, ) = (q1, X) (q0, , ) = (q1, ) (q1, a, ) = (q1, X) F = { q1 }
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 45 / 66
ii)
L = { a2n b2n
; i0 }
S -> aaSbb |
iii)
L = { an bk ci
; i=n+k }
iv)
L = { an bk ci
; k=n+i }
v)
52.
A partir de uma gramtica livre de contexto na FNG, que gera a linhagem L, constri-se com relativa facilidade um autmato com pilha que reconhece a linguagem L. O autmato com pilha gerado pode depois ser usado, por exemplo, para a construo de analisadores sintticos. Sugere-se como trabalho da disciplina o estudo e a implementao deste algoritmo, capaz de receber uma gramtica na FNG e fornecer como sada o autmato com pilha equivalente.
53.
Motivao: Como descobrir que uma determinada linguagem livre de contexto ou no? Sabemos que se for apresentado um autmato com pilha que a reconhea ou uma gramtica livre de contexto que a gere ento esta linguagem livre de contexto. Por outro lado, para provar que ela no livre de contexto, usaremos o Lema do Bombeamento como explicado a seguir. Se uma linguagem livre de contexto (LLC) ento atende ao lema do bombeamento (LB): LLC LB Pela lgica proposicional podemos representar: LLC LB ok LB LLC no podemos afirmar ~LLC ~LB no podemos afirmar ~LB ~LLC ok, pela equivalncia lgica da contraposio Assim, devido a contraposio, conseguimos transformar o lema numa ferramenta valiosa para provar que uma linguagem no livre de contexto, bastando para isto, mostrar que ela no atende ao lema do bombeamento. Lema: Se L linguagem livre de contexto, ento m 1 ; w L, |w| m onde w = uxvyz com |xy| 1 e |xvy| m e i 0, uxivyiz L
54.
Como j foi dito, o Lema do Bombeamento bom para provar que uma determinada linguagem L no livre de contexto. Isto nem sempre possvel, mas, de uma maneira geral, usamos o seguinte modelo de prova, pela tcnica do absurdo: 4) supomos L livre de contexto 5) procuramos uma palavra w L dependente de m de tal forma que m, |w| m e satisfazendo w = uxvyz com |xy| 1 e |xvy| m 6) finalmente, exibimos um valor de i 0 tal que uxivyiz no pertence a L, desta forma fica provado por absurdo que L no regular. Observe que, pela lgica de 1 ordem, a negao do quantificador , e vice-versa.
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 47 / 66
55.
Na Hierarquia de Chomsky essas linguagens so de tipo 1. Elas conseguem representar problemas mais complexos do que as de tipo 3 e 2.
As abstraes usadas neste nvel so: gramtica sensvel ao contexto como geradora e mquina de Turing como reconhcedora.
56.
Mquina de Turing
um dispositivo terico, conhecido como mquina universal, que foi concebido pelo matemtico britnico Alan Turing (1912-1954), muitos anos antes de existirem os modernos computadores digitais (o artigo de referncia foi publicado em 1936). Num sentido preciso, um modelo abstrato de um computador, que se restringe apenas aos aspectos lgicos do seu funcionamento (memria, estados e transies) e no sua implementao fsica. Numa mquina de Turing pode-se modelar qualquer computador digital. (Wikipedia). Na Hierarquia de Chomsk ela usada para reconhecer linguagens sensveis ao contexto (nvel 1). A Tese de Church, de acordo com as palavras do prprio Turing, pode ser enunciada como: Toda 'funo que seria naturalmente considerada computvel' pode ser computada por uma Mquina de Turing. Devido impreciso do conceito de uma "funo que seria naturalmente considerada computvel", a tese no pode ser nem provada nem refutada formalmente. Qualquer programa de computador pode ser traduzido em uma mquina de Turing, e qualquer mquina de Turing pode ser traduzida para uma linguagem de programao de propsito geral; assim, a tese
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 48 / 66
equivalente a dizer que qualquer linguagem de programao de propsito geral suficiente para expressar qualquer algoritmo. A mquina de Turing composta de um cabeote gravador/leitor que opera sobre uma fita de entrada dividida em clulas sucessivas. Cada clula contm um nico smbolo e elas so preenchidas a priori com espao em branco. Cada computao sobre a mquina (transio no grafo) faz sempre: 1. l um smbolo na posio do cabeote 2. grava um smbolo na posio do cabeote 3. move o cabeote para esquerda (L) ou direito (R).
Exemplos: L = { an bn cn ; i0 }
i)
ii)
L={wcw
; w pertence a {a,b}* }
57.
Na Hierarquia de Chomsky, as linguagens sensveis ao contexto so geradas por uma gramtica sensvel ao contexto. A sensibilidade ao contexto devido ao fato de que, normalmente, o lado esquerdo de suas regras de produo formado por mais de um smbolo, gerando, assim, um contexto obrigatrio para a substituio. Ela representada por produes do tipo: A -> onde: A , ou: S -> desde que S no aparea no lado direito de nenhuma produo. V (T U V)* (T U V)+
Exemplos apresentados em aula: i) L = { an bn cn Regra S S cB bB -> -> -> -> aSBc abc Bc bb ; i1 } Exemplo de gerao pela aplicao da regra aaSBcBc aaabcBcBc aaabBBccc aaabbbccc
ii)
; w pertence a {a,b}* }
aAS | bBS | c aA bA aB bB ca cb
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 50 / 66
Outro teste:
58.
Uma linguagem que aceita por uma Mquina de Turing dita como uma Linguagem Enumervel Recursivamente, que do tipo 0. Se existe uma Mquina de Turing que aceita todas as strings da linguagem, e que no aceita as strings que no pertencem a linguagem, essa linguagem Enumervel Recursivamente. importante observar que no aceita no mesmo que rejeita, pois a Mquina de Turing poderia entrar num loop infinito e nunca parar para aceitar ou rejeitar a string. Alm da Mquina de Turing, que trabalha como reconhecedora deste tipo de linguagem, existem as gramticas irrestritas que gera a linguagem. A gramtica irrestrita representada por produes do tipo: -> onde: (TUV)+ (TUV)*
Ou seja, as suas regras no possuem restrio, exceto pela exigncia de pelo menos um smbolo (terminal ou no terminal) no lado esquerdo da regra de produo. Exemplo: L = { an bn cn S cB aB bB -> -> -> -> ; i0 }
aSBc | Bc ab bb
Obs.: vrios outros elementos que do continuidade a esse assunto sero estudados na disciplina Teoria da Computao, tais como outros tipos de Mquinas de Turing e seus formalismos, decidibilidade, o problema da parada e da indecidibilidade, etc.
Exemplo de sada:
Cdigo fonte para gerao do desenho anterior: /* Mquina de Moore para classificar nmeros decimais, octais e haxadecimais (inteiros sem sinal) ER de nmeros hexadecimais: ER de nmeros decimais: ER de nmeros octais: So decimais: 0, 08, 058 */ /* Obs.: aceita nomes dos estados grandes: basta coloc-lo entre aspas */ digraph AFD { rankdir=LR; size="6" node [shape = circle]; /* determinao dos estados de classificao (estados finais) da mquina de Moore */ subgraph cluster1 { /* numere sequencialmente... */ node [shape = doublecircle]; q1 /* mude esta linha: nome do estado */ label = "<DEC>"; /* mude esta linha: descrio do token*/ color=white } subgraph cluster2 { node [shape = doublecircle]; q3 /* mude esta linha: nome do estado */ label = "<HEX>"; /* mude esta linha: descrio do token*/ color=white } subgraph cluster3 { node [shape = doublecircle]; q4 /* mude esta linha: nome do estado */ label = "<DEC>"; /* mude esta linha: descrio do token*/ color=white } subgraph cluster4 { node [shape = doublecircle]; q5 /* mude esta linha: nome do estado */ label = "<OCT>"; /* mude esta linha: descrio do token*/ color=white } 0(X|x)(0|...|F)+ (0|...|9)+ 0(0|...|7)+
/* q0 q1 q2 q0 q1 q1 q5
seo escreva todas as transies... */ [ label = "0" ]; [ label = "x,X" ]; -> q3 [ label = "0...9,a...f,A...F" ]; -> q4 [ label = "0...9" ]; -> q5 [ label = "0...7" ]; [ label = "8,9" ]; [ label = "8,9" ];
APNDICE B:
Suponha uma linguagem de programao composta somente de comandos de atribuio cujo lado direito formado por um nmero inteiro sem sinal ou uma varivel (composta por letras minsculas e hfens, sendo que se o hfen for o primeiro caractere ento deve ser acompanhado por uma letra na segunda posio) Expresses regulares para os tokens: Token
<NUM> <ATRIB> <IDENT> <PTOVIRG> <EOF>
ER
(0|...|9)+ -: (-|)(a|...|z)(a|...|z|-)* ; caracter que representa o fim de arquivo
Exemplos de lexemas
0, 25, 999, 0005 -: x, x-, -a, -a---, def-cod, x-a ;
Mquina de Moore:
<NUM> 0,...,9
0,...,9 \t,\n,\r,espao
s1
: s2
<ATRIB>
s0
s3
s6
<EOF>
s4 s5
<PTOVIRG> <IDENT>
a,...,z,-
Testes do analisador lxico implementao da mquina de Moore: (execute o arquivo TesteAnalisadorLexico.java do exemplo) Teste 1:
x -: 5; valor -: valor-total ; -soma -: total ;
Console de sada:
IDENT ATRIB NUM PTOVIRG IDENT ATRIB IDENT PTOVIRG IDENT ATRIB IDENT PTOVIRG EOF Anlise lxica realizada com sucesso no arquivo entrada.txt
Teste 2:
x-:5; valor -: total;
Console de sada:
IDENT Erro lxico: caractere encontrado: : era(m) esperado(s): 0123456789abcdefghijklmnopqrstuvwxyz;-
Obs.: aps a classificao de x-, como no existe previso para : em S4, a mquina de Moore iniciada novamente em S0 para classificar o prximo token.
Teste 3:
x -: 5; valor - total;
Console de sada:
IDENT ATRIB NUM PTOVIRG IDENT Erro lxico: caractere encontrado: era(m) esperado(s): abcdefghijklmnopqrstuvwxyz:
Teste 4:
x -; 5;
Console de sada:
IDENT Erro lxico: caractere encontrado: ; era(m) esperado(s): abcdefghijklmnopqrstuvwxyz:
Teste 5:
valor@2 -: 5;
Console de sada:
IDENT Erro lxico: caractere encontrado: @ era(m) esperado(s): abcdefghijklmnopqrstuvwxyz-0123456789;<EOF>
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 57 / 66
1 <<interface>> Constantes +String DIGITOS +String LETRAS +String VAZIOS +char EOF +char ATRIB +char PTOVIRG +enum Token +String NOME_DEFAULT_ARQUIVO_ENTRADA
AnalisadorLexico -char proxCaractere -int linha -StringBuffer entrada -int posicao -Token tokenReconhecido +AnalisadorLexico() +leProxCaractere() +proxCaractereIs()
+MyAnalisadorSintatico parser
Implementao do analisador lxico por intermdio da anlise preditiva: Obs.: para rodar este exemplo, separe cada classe num arquivo, pois elas so public. //-------------------------------------------------------------------------------------------------------------------public interface Constantes { enum Token { NUM, ATRIB, IDENT, EOF, PTOVIRG, VAZIO }; String DIGITOS = "0123456789", LETRAS = "abcdefghijklmnopqrstuvwxyz", ATRIB = "-:", VAZIOS = " \r\n\t"; EOF HIFEN PTOVIRG DOISPONTOS = = = = 0, '-', ';', ':';
char
String }
NOME_DEFAULT_ARQUIVO_ENTRADA = "entrada.txt";
//-------------------------------------------------------------------------------------------------------------------public class ErroLexico extends RuntimeException { private char caractereEncontrado; private String caracteresEsperados; public ErroLexico(char _caracterEncontrado, String _caracteresEsperados) { this.caractereEncontrado = _caracterEncontrado; this.caracteresEsperados = _caracteresEsperados; } public String toString() { return "caractere encontrado: "+((char)this.caractereEncontrado)+ "\nera(m) esperado(s): "+this.caracteresEsperados; } }
//-------------------------------------------------------------------------------------------------------------------public abstract class Analisador implements Constantes { protected String nomeArquivoEntrada; public Analisador(String _nomeArquivoEntrada) { this.nomeArquivoEntrada = _nomeArquivoEntrada; } public Analisador() { this.nomeArquivoEntrada = NOME_DEFAULT_ARQUIVO_ENTRADA; } }
//-------------------------------------------------------------------------------------------------------------------import java.io.FileReader; import java.io.IOException; public class AnalisadorLexico extends Analisador { protected char proxCaractere; // caractere disponvel no cabeote de leitura protected int linha = 1; // linha atual do arquivo fonte protected StringBuffer entrada = new StringBuffer(); // armazena o contedo do arquivo protected int posicao = 0; // posio do caractere a ser lido na entrada protected Token tokenReconhecido; // ltimo token lido // transfere o arquivo para o buffer entrada public AnalisadorLexico(String _nomeArquivoEntrada) { super(_nomeArquivoEntrada); try { FileReader file = new FileReader(_nomeArquivoEntrada); int c; while((c = file.read()) != -1) { this.entrada.append((char)c); } file.close(); leProxCaractere(); } catch (IOException e) { throw new RuntimeException("Erro de leitura no arquivo "+_nomeArquivoEntrada); } } // l o prximo caractere do buffer. Se fim, retorna EOF // avana o ponteiro de leitura 1 posio public void leProxCaractere() { try { this.proxCaractere = this.entrada.charAt(this.posicao++); } catch(IndexOutOfBoundsException e) { this.proxCaractere = EOF; } } // verifica se o prximo caractere um dos que esto em s // NO avana o ponteiro de leitura public boolean proxCaractereIs(String s) { if (s.indexOf(this.proxCaractere) != -1) return true; else return false; } }
//-------------------------------------------------------------------------------------------------------------------import java.io.IOException; public class MyAnalisadorLexico extends AnalisadorLexico { public MyAnalisadorLexico(String _nomeArquivoEntrada) { super(_nomeArquivoEntrada); } public void s0() { if(this.proxCaractereIs(DIGITOS)) { leProxCaractere(); s1(); } else if(this.proxCaractere == HIFEN) { leProxCaractere(); s2(); } else if(this.proxCaractereIs(LETRAS)) { leProxCaractere(); s4(); } else if(this.proxCaractere == PTOVIRG) { leProxCaractere(); s5(); } else if(this.proxCaractere == EOF) { leProxCaractere(); s6(); } else if(this.proxCaractereIs(VAZIOS)) { leProxCaractere(); s0(); } else { throw new ErroLexico(this.proxCaractere,DIGITOS+LETRAS+VAZIOS+PTOVIRG+HIFEN); } } public void s1() { this.tokenReconhecido = Token.NUM; if(this.proxCaractereIs(DIGITOS)) { leProxCaractere(); s1(); } } public void s2() { if(this.proxCaractere == DOISPONTOS) { leProxCaractere(); s3(); } else if(this.proxCaractereIs(LETRAS)) { leProxCaractere(); s4(); } else throw new ErroLexico(this.proxCaractere,LETRAS+DOISPONTOS); } public void s3() { this.tokenReconhecido = Token.ATRIB; } public void s4() { this.tokenReconhecido = Token.IDENT; if(this.proxCaractereIs(LETRAS+HIFEN)) { leProxCaractere(); s4();
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 61 / 66
} } public void s5() { this.tokenReconhecido = Token.PTOVIRG; } public void s6() { this.tokenReconhecido = Token.EOF; } }
//-------------------------------------------------------------------------------------------------------------------public class TesteAnalisadorLexico { static public MyAnalisadorLexico scanner; public static void main(String[] args) { try { if(args.length != 1) throw new RuntimeException("esqueceu de escrever o nome do arquivo de entrada! \n" + "No Eclipse insira em: Run - Open Run Dialog - Arguments"); scanner = new MyAnalisadorLexico(args[0]); // chama a mquina de Moore vrias vezes at encontrar o fim de arquivo do { scanner.s0(); System.out.println(scanner.tokenReconhecido); } while(scanner.tokenReconhecido != Constantes.Token.EOF); System.out.println("Anlise lexica realizada com sucesso no arquivo "+scanner.nomeArquivoEntrada); } catch(ErroLexico e) { System.out.println("Erro lxico: "+e.toString()); } catch(RuntimeException e) { System.out.println("Erro: "+e.getMessage()); } } }
APNDICE C:
O analisador iniciado no apndice B, atravs da construo da anlise lxica, ser agora complementado com o analisador sinttico, por meio da anlise preditiva classificada como uma tcnica de reconhecimento top-down. Relembrando, o exemplo uma linguagem composta somente de comandos de atribuio cujo lado direito formado por um nmero inteiro sem sinal ou uma varivel (composta por letras minsculas e hfens, sendo que se o hfen for o primeiro caractere ento deve ser acompanhado por uma letra na segunda posio)
Obs.: esta gramtica j est fatorada (sem conflitos esquerda) e tambm no possui recursividade esquerda. Testes dos analisadores lxico e sinttico integrados: (execute o arquivo Uso.java do exemplo) Teste 1:
x -: 5; valor-mensal -: 123; s -: -total ;
Console de sada:
Anlise realizada com sucesso no arquivo entrada.txt
Teste 2:
x -: valor -: 123; soma -: total ;
Console de sada:
Erro sinttico: token encontrado: IDENT era(m) esperado(s): PTOVIRG
Teste 3:
X 5; valor -: 123; soma -: total ;
Console de sada:
Erro sinttico: token encontrado: NUM era(m) esperado(s): ATRIB
Teste 4:
x -: 5; valor -: 123;;soma -: total ;
Console de sada:
Erro sinttico: token encontrado: PTOVIRG era(m) esperado(s): IDENT EOF
Teste 5:
x -: 5; valor -: 123; soma -: ;
Console de sada:
Erro sinttico: token encontrado: PTOVIRG era(m) esperado(s): NUM IDENT
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 63 / 66
Teste 6:
x -: 5#; valor -: 123; soma -: total ;
Console de sada:
Erro lxico: caractere encontrado: # era(m) esperado(s): 0123456789;
Teste 7:
x -: 5; valor -: @ ; soma -: total ;
Console de sada:
Erro lxico: caractere encontrado: @ era(m) esperado(s): 0123456789abcdefghijklmnopqrstuvwxyz-
Implementao por intermdio da anlise preditiva: Obs.: basta inserir estes arquivos no cdigo do exemplo do analisador lxico. //-------------------------------------------------------------------------------------------------------------------public class ErroSintatico extends RuntimeException implements Constantes { private Token tokenEncontrado; private Token[] tokensEsperados; public ErroSintatico(Token _tokenEncontrado, Token[] _tokensEsperados) { this.tokenEncontrado = _tokenEncontrado; this.tokensEsperados = _tokensEsperados; } public ErroSintatico(Token _tokenEncontrado, Token _tokenEsperado) { this.tokenEncontrado = _tokenEncontrado; this.tokensEsperados = new Token[1]; tokensEsperados[0] = _tokenEsperado; } public String toString() { String listaDeTokensEsperados = ""; for(int i=0; i<this.tokensEsperados.length; i++) listaDeTokensEsperados += this.tokensEsperados[i] + " "; return "token encontrado: "+this.tokenEncontrado+ "\nera(m) esperado(s): "+listaDeTokensEsperados; } }
//-------------------------------------------------------------------------------------------------------------------public class AnalisadorSintatico extends Analisador implements Constantes { protected MyAnalisadorLexico scanner; public AnalisadorSintatico(String _nomeArquivoEntrada) { this.scanner = new MyAnalisadorLexico(_nomeArquivoEntrada); // l o primeiro token e o coloca no campo tokenReconhecido this.leProxToken(); } public AnalisadorSintatico() { super(); }
// executa 1 vez a mquina de Moore public void leProxToken() { this.scanner.s0(); } // verifica se o prximo token t // avana o ponteiro para o prximo token public void reconhece(Token t) { if(t == this.scanner.tokenReconhecido) this.leProxToken(); else throw new ErroSintatico(this.scanner.tokenReconhecido, t); } // verifica se o prximo token t // NO avana o ponteiro de leitura public boolean proxTokenIs(Token t) { if(t == this.scanner.tokenReconhecido) return true; else return false; } }
//-------------------------------------------------------------------------------------------------------------------public class MyAnalisadorSintatico extends AnalisadorSintatico { public MyAnalisadorSintatico(String _nomeArquivoEntrada) { super(_nomeArquivoEntrada); } public void inicio() { corpo(); reconhece(Token.EOF); } public void corpo() { if(proxTokenIs(Token.IDENT)) { comandoAtribuicao(); reconhece(Token.PTOVIRG); corpo(); } else if(proxTokenIs(Token.EOF)) ; else { Token[] tokensEsperados = {Token.IDENT,Token.EOF}; throw new ErroSintatico(this.scanner.tokenReconhecido,tokensEsperados); } } public void comandoAtribuicao() { reconhece(Token.IDENT); reconhece(Token.ATRIB); exp(); } public void exp() { if(proxTokenIs(Token.NUM)) leProxToken(); else if(proxTokenIs(Token.IDENT)) leProxToken(); else { Token[] tokensEsperados = {Token.NUM,Token.IDENT}; throw new ErroSintatico(this.scanner.tokenReconhecido,tokensEsperados); } } }
Notas de aula de Ling Formais e Autmatos prof. Henrique 2013-1 pgina 65 / 66
//-------------------------------------------------------------------------------------------------------------------public class Uso { static public MyAnalisadorSintatico parser; public static void main(String[] args) { try { if(args.length != 1) throw new RuntimeException("esqueceu de escrever o nome do arquivo de entrada! \n" + "No Eclipse insira em: Run - Open Run Dialog - Arguments"); parser = new MyAnalisadorSintatico(args[0]); parser.inicio(); System.out.println("Anlise realizada com sucesso no arquivo "+parser.nomeArquivoEntrada); } catch(ErroLexico e) { System.out.println("Erro lxico: "+e.toString()); } catch(ErroSintatico e) { System.out.println("Erro sinttico: "+e.toString()); } catch(RuntimeException e) { System.out.println("Erro: "+e.getMessage()); } } }