-- MateusLudwich - 01 May 2005
Dado o seguinte problema / Dada a seguinte especificação:
Elaborar uma aplicação, com interface gráfica, para:
1 - Ler e validar AFD e AFND (pode ser na forma de tabela de transição)
2 - Ler e validar GR
3 - Reconhecer sentenças aceitas por AFD e AFND e geradas por uma GR
4 - Converter GR para AF
5 - Converter AF para GR
6 - Determinizar AFND
7 - Minimizar AFD
Observações:
1 - Pode-se usar apenas letras maiúsculas para representar Não-Terminais e
Estados
2 - Os terminais podem ser quaisquer caracteres especiais, dígitos ou letras
minúsculas
3 - Os nomes de símbolos e estados não devem ser pré-estabelecidos
4 - Além da corretude, serão observados aspectos como usabilidade e robustez da
aplicação.
Será possível usar TDD neste caso?
Tentando usar TDD, precisamos criar a princípio uma Infra-Estrutura de
testes. Infra-Estrutura de testes para testar o que?
Bem, podemos observar claramente dois elementos deste problema: gramáticas e
autômatos, podemos criar uma infra-estrutura de teste para cada um. Há um outro
elemento que pertence à aplicação em si que é a interface gráfica com o
usuário, para a qual também podemos criar uma infra-estrutura de teste.
Pensando assim podemos ter o seguinte teste para gramática:
TesteGR00
Ao criarmos uma Infra-Estrutura para gramática e adicionarmos este teste nela
(fase amarela o teste falha). Assim passamos para a fase vermelha.
Criando a classe GramaticaRegular e escrevendo um método chamado "ehRegular()"
que retorna sempre "true" passamos para a fase verde.
FaseVerde01
Agora precisamos fatorar:
O código feito aparentemente não pode ser simplificado;
O código não parece ter duplicações;
Entretanto passou-se no teste escrito pois o método sempre retorna true.
Devemos fazer um método que retorne true apenas se a gramática for regular.
Para isto precisamos de uma gramática definida. Mas o teste atual não está
definindo nenhuma gramática!
Caímos então na necessidade de fatorar o código de testes:
Como fazer um teste que explicite/defina uma gramática?
Sabemos que uma gramática é definida da seguinte maneira:
G = (Vn,Vt,P,S)
onde,
Vn - conjunto finito de símbolos não-terminais, que no caso deverão ser
representados por letras maiúsculas;
Vt - conjunto finito de símbolos terminais, que no caso podem ser quaisquer
caracteres especiais, dígitos ou letras minúsculas;
P - conjunto finito de pares (a, b) denominados produções (ou regras
gramaticais ou de sintaxe);
S - É o símbolo inicial da gramática.
Para que o teste explicite uma gramática ele deve conter então uma lista de
Vn´s (letras maiúsculas), uma lista de Vt´s (letras minúsculas, caracteres
especiais ou dígitos), uma lista de pares (a, b), e um S (letra maiúscula que
indica o símbolo inicial da gramática).
A lista de pares (a,b) o que é?
É a lista de produções da gramática. No caso de uma GR num par (a,b), "a"
deve ser um símbolo não-terminal (letra maiúscula) e "b" deve ser um símbolo
terminal seguido ou não de um símbolo não-terminal.
O código feito (classe GramaticaGR) não precisa até então ser modificado, mas
durante a sua fatoração acabamos descobrindo a necessidade de fatorar também o
código de teste, e fatorando o mesmo descobrimos que ele deve ser modificado.
Vamos escrever então um outro teste:
TesteGR01
Ao adicionarmos este teste na Infra-Estrutura de testes (fase amarela), o teste
falha. Assim passamos para a fase vermelha. O teste falhou pois o método
construtor da classe GramaticaRegular ainda não está definido. Escrevendo um
construror que possua os parâmetros desejados, passamos para a fase verde.
FaseVerde02
Agora precisamos fatorar a classe GramaticaGR:
O código feito aparentemente não pode ser simplificado;
O código não parece ter duplicações;
Ok, então vamos para o próximo teste.
TesteGR02?
|