Considere-se o ficheiro de texto “Dados

Propaganda
DEP. INFORMÁTICA - UNIVERSIDADE DA BEIRA INTERIOR
Eng. Informática
Linguagens Formais e Compilação
Resolução da Frequência 1
2º Semestre
20/Abril/2010
Pergunta
A.1
A.2
A.3
A.4
B
C.1
C.2
Total
Cotação
0,75
0,50
0,50
0,75
2,00
0,75
0,75
6,00
A. AUTÓMATOS FINITOS DETERMINÍSTICOS (AFD) E PROGRAMAÇÃO EM C
Considere os seguintes conjuntos: letra = { a, …, z, A, …, Z }, digito = { 0, …, 9 }, hifen = { _ } e
ponto = { . }, e o alfabeto S = letra  digito  hifen  ponto.
1.
Desenhe um AFD sobre o alfabeto S que reconheça sequências de digitos que formam
números inteiros (por ex., 543) e números reais (por ex., 52.614) sem sinal.
2. Indique, justificando, que tipo de palavras são reconhecidas pelo autómato finito determinístico
sobre o alfabeto S apresentado na 2ª página. Apresente as características particulares das
palavras reconhecidas pelo autómato. Dê um exemplo de uma palavra reconhecida por ele.
As palavras aceites/reconhecidas pelo autómato da última página têm as seguintes características:
- começam por uma letra
- segue-se, ou não, uma subsequência de letras, digitos e hífen's, em que os hifen's só podem
estar isolados (isto é, não podem estar 2 ou mais hifen seguidos) e não podem terminar esta
subsequência
- após esta subquência, caso exista, segue-se um ponto (que será único em toda a palavra)
- após o ponto, segue-se uma subsequência de exactamente 3 letras.
Resumindo, este autómato reconhece nomes de ficheiros (nome.extensão), em que nome começa
por uma letra, contém letras, digitos e hifen's (não aceita hifen seguidos, nem no final do nome), e
a extensão é formada por exactamente 3 letras.
3. Construa a tabela das d-transições do autómato finito determinístico apresentado na 2ª página.
símbolos terminais
estados
letra
digito
hifen
ponto
q0
q1
q9
q9
q9
q1
q1
q1
q2
q4
q2
q3
q3
q9
q9
q3
q1
q1
q2
q4
q4
q5
q8
q8
q8
q5
q6
q8
q8
q8
q6
q7
q9
q9
q9
q7
q9
q9
q9
q9
q8
q8
q8
q8
q8
q9
q9
q9
q9
q9
4. Implemente em linguagem C o autómato finito determinístico apresentado na 2ª página.
int delta (int q, char ch)
{
int M[10][4] = { 1, 9, 9, 9, 1, 1, 2, 4, 3, 3, 9, 9, 1, 1, 2, 4, 5, 8, 8, 8, 6, 8, 8, 8, 7, 9, 9, 9, 9
9, 9, 9, 8, 8, 8, 8, 9, 9, 9, 9 }
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' )
return (M[q][0]);
else if (ch >= '0' && ch <= '9')
return (M[q][1]);
else if (ch == '_')
return (M[q][2]);
else
return (M[q][3]);
}
int main ()
{
int q_actual, k;
char st[100];
puts (“Introduza uma sequência de letras, digitos, hifen e pontos : “);
gets(st);
for (k = 0; k < strlen(st); k++)
q_actual = delta (q_actual, st[k]);
if (q_actual == 7)
printf (“%s é aceite pelo autómato.\n”, st);
else
printf (“%s não é aceite pelo autómato.\n”, st);
}
B. LEX
Implemente um programa em LEX que, dado um texto :
–
substitua a palavra UBI pela palavra DIUBI em todas as suas ocorrências;
–
determine o número de ocorrências da palavra UBI;
–
determine o número de palavras começadas pelos caracteres a ou A;
–
determine o número de palavras com 5 ou mais letras;
–
determine o número de palavras com 2 ou mais b's;
–
determine o número de reais (em formato de ponto flutuante: 0.65) entre 0 e 2.
(NOTA: palavra = sequência de letras.)
%{
int cont1 = 0, cont2 = 0, cont3 = 0, cont4 = 0, cont5 = 0;
%}
%%
UBI
{ cont1++; printf (“DIUBI”); }
[aA][a-zA-Z]*
{ cont2++; }
[a-zA-Z]{5}[a-zA-Z]*
{ cont3++; }
[ac-zAC-Z]*b[ac-zAC-Z]*b[a-zA-Z]*
{ cont4++; }
[01]”.”[0-9]+ | 2”.”0+
{ cont5++; }
%%
int main()
{
yylex();
printf (“Número de ocorrências da palavra UBI = %d\n”, cont1);
printf (“Número de palavras começadas pelos caracteres a ou A = %d\n”, cont2);
printf (“Número de palavras com 5 ou mais letras = %d\n”, cont3);
printf (“Número de palavras com 2 ou mais b's = %d\n”, cont4);
printf (“Número de reais (em formato de ponto flutuante: 0.65) entre 0 e 2 = %d\n”, cont5);
return 0;
}
C. FIRST e FOLLOW
Considere a seguinte gramática G = (Σ, T, P, S), em que Σ = { S, A, B, C, D }, T = { a, b, c, d, e, f }
e P = { S → DC; A → e | a | Cb; B → e | c | dA; C → e | f; D → AB }
1. Determine o conjunto First dos símbolos terminais e não terminais de G.
First (a) = { a }
First (b) = { b }
First (c) = { c }
First (d) = { d }
First (e) = { e }
First (f) = { f }
First (S) = { a, e, f, c, d }
First (A) = { ε, a, e, f }
First (B) = { ε, c, d }
First (C) = { e, f }
First (D) = { ε, a, e, f, c, d }
Utilizando A → ε, tira-se o seguinte :
ε ∈ First (A)
Utilizando A → a, tira-se o seguinte :
a ∈ First (A)
Utilizando B → ε, tira-se o seguinte :
ε ∈ First (B)
Utilizando B → c, tira-se o seguinte :
c ∈ First (B)
Utilizando C → e, tira-se o seguinte :
e ∈ First (C)
Utilizando C → f, tira-se o seguinte :
f ∈ First (C)
Utilizando B → d A, tira-se o seguinte :
First (d A )  First (B)
First (d A ) = First (d )  First (A ) (se d deriva e)
Como d não deriva e, apenas d ∈ First (B)
Utilizando A → C b , tira-se o seguinte :
First (C b ) ⊂ First (A)
First (C b ) = First (C) - { e }  First (b ) (se C deriva e)
Como C não deriva e, (pois ε ∉ First (C) e First (C) é final), apenas First (C) ⊂ First (A).
Logo, { e, f } ⊂ First (A)
Utilizando D → A B , tira-se o seguinte :
First (A B ) ⊂ First (D)
First (A B ) = First (A) - { e }  First (B) - { e } (se A deriva e)  { e } (se A, B derivam e)
Como A, B derivam e, (ε ∈ First(A) e ε ∈ First(B)), First (A B ) = First (A)  First (B)  { e }
Logo, { a, e, f }  { c, d }  { e } = { a, e, f, c, d, e } ⊂ First (D)
Utilizando S → D C , tira-se o seguinte :
First (D C ) ⊂ First (S)
First (D C ) = First (D) - { e }  First (C) - { e } (se D deriva e)  { e } (se D, C derivam e )
Como D deriva e (ε ∈ First(D)) e C não deriva e (ε  First(D)), First(D C ) = First(D)  First(C)
Logo, { a, e, f, c, d }  { e, f } = { a, e, f, c, d } ⊂ First (S)
2. Determine o conjunto Follow dos símbolos não terminais de G.
Follow (S) = { $ }
Follow (A) = { c, d, e, f }
Follow (B) = { e, f }
Follow (C) = { $, b }
Follow (D) = { e, f }
Utilizando S → D C , tira-se o seguinte :
First (C) - { e } ⊂ Follow (D). Logo, { e, f } ⊂ Follow (D)
Follow (S) ⊂ Follow (D), se C deriva e. Como C não deriva e (ε  First(C)), não se faz nada.
Follow (S) ⊂ Follow (C). Logo, $  Follow(C)
Utilizando D → A B , tira-se o seguinte :
First (B) - { e } ⊂ Follow (A). Logo, { c, d } ⊂ Follow (A)
Follow (D) ⊂ Follow (A), se B deriva e.
Como B deriva e (ε  First(B)), Follow (D) ⊂ Follow (A). Logo, { e, f } ⊂ Follow (A)
Follow (D) ⊂ Follow (B). Logo, { e, f } ⊂ Follow (B)
Utilizando A → ε :
Não se tira qualquer resultado.
Utilizando A → a :
Não se tira qualquer resultado.
Utilizando A → C b , tira-se o seguinte :
First (b)  Follow (C). Logo, b ∈ Follow (C)
Utilizando B → ε :
Não se tira qualquer resultado.
Utilizando B → c :
Não se tira qualquer resultado.
Utilizando B → d A , tira-se o seguinte :
Follow (B) ⊂ Follow (A). Logo, { e, f } ⊂ Follow (A)
Utilizando C → e :
Não se tira qualquer resultado.
Utilizando C → f :
Não se tira qualquer resultado.
ATENÇÃO: Rever todas as relações entre FOLLOW's.
Expressão regular Significado
Expressão regular Significado
x
Caracter “x”
“x” ou \x
Caracter “x”
[xy] ou x|y
Caracter x ou y
[x-y]
Caracteres entre x e y
[^x]
Todos os caracteres excepto x
.
Qualquer caracter excepto “\n”
x?
Caracter x opcional
()
Associação de expr. regulares
x*
x repetido 0 ou mais vezes
x+
x repetido 1 ou mais vezes
x{n}
Repetição de x n vezes
x{n,m}
Repetição de x n a m vezes
^x
O caracter “x” deve aparecer no início da linha
x$
O caracter “x” deve aparecer no fim da linha
Download