Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementação de Testes em Oberon #148

Open
wants to merge 76 commits into
base: master
Choose a base branch
from

Conversation

Marcolino5
Copy link

@Marcolino5 Marcolino5 commented Jul 25, 2023

PARSER
Decidimos, junto do professor, utilizar o parser combinator no lugar do parser gerado pelo ANTLR usado até o momento.
Inicialmente focamos na implementação de Asserts, pois eram mais simples e existiam bons exemplos de statements parecidos. Então implementamos inicialmente o AssertTrue, AssertEqual e AssertNotEqual e posteriormente o AssertError. todos no Parser de Statements.
Tendo um melhor entendimento do funcionamento do parser, graças a implementar os asserts, foi implementado o parser de Testes que utiliza de base a estrutura do parser de Procedures mas simplifica certas partes e adiciona informações uteis para o funcionamento dos testes como o modificador utilizado.
Tendo implementado as partes esperadas, tínhamos que fazer com que o resto da ast gerada por esse parser seja equivalente a arvore gerada anteriormente. Para isso, foram implementadas algumas funcionalidades que não haviam sido implementadas e foi preciso concertar ou mudar certas partes que acabavam criando problemas.
Dentre as coisas que foram implementadas, as mais complicadas foram o parser de imports que havia uma base mas que não atendia ao requisito e o parser de expressões lambda que ainda não existia. Além disso, foi adicionado as expressões not, o parser de comentários feito utilizando regular expressions.
Além de features novas, foi preciso mudar implementações existentes para ficar de acordo com a arvore esperada.
Uma das mudanças mais significativas foi resultado de uma necessidade criada ao implementar lambda expressions pois seria preciso a definição de argumentos formais antes do parser de expressões. Isso levou a criação de uma classe de parser chamada Compposite Parsers que contem parsers que são blocos para parsers mais complexos mas diferente dos parsers em Basic Parsers utilizam outros parsers em sua construção. Além disso foi preciso mudar a sequencia do parser de expressões para que a prioridade de expressões logicas fique correta.
Além disso foram feitas varias mudanças menores para garantir a corretude da ast gerada. Como mudar a ordem dos parsers ao utilizar o combinator choice, mudar algumas estruturas para criar equivalência com o parser gerado pelo ANTLR e generalizar algumas estruturas utilizadas em múltiplos parsers.
Os componentes a seguir seriam trabalhados, também, por outros grupos. Dessa forma, decidimos primeiro adicioná-los nos componentes antigos, mais orientados à objetos, para posteriormente utilizar os componentes novos já completos. O molde do que deveria ser feito em diante estava pronto, de tal forma que a implementação deles seria comparativamente mais simples do que o parser.

INTERPRETER
Seguimos o molde da interpretação de statements para implementar a interpretação dos asserts. O AssertTrue foi feito utilizando a função "evalCondition", que identifica se a expressão contida no AssertTrue é verdadeira; Se não for, lança uma exceção. Tivemos dificuldade em fazer com que ela identificasse que estava dentro de um teste e lançasse um erro diferente, que identificasse o teste; Decidimos por mantê-lo dessa forma, apenas lançando um erro de assert. Inicialmente, fizemos uma implementação para cada tipo de assert (Equal, NotEqual e Error), que depois retiramos, uma vez que passamos a utilizar o CoreTransformer.
A implementação dos testes no interpretador seguiu de forma similar às procedures. O interpretador visitado perpassaria a lista de testes declarados e, se tivessem o modifier "TEST", seguiriam um procedimento análogo a um ProcedureCallStmt: usaria a função "callTest", que daria um update no environment com as declarações presentes no teste e checaria o statement presente no teste, posteriormente se livrando do update. Implementamos a possibilidade de escolha entre o interpretador: com um argumento adicional "select", é possível escolher entre interpretar apenas os testes (select = "TEST"), utilizar apenas o interpretador base (select = "BASE" ou sem argumento, pois select é definido como "BASE" por padrão) ou ambos (select = "BOTH").

TYPE CHECKER
Mais uma vez seguimos o molde de outros statements para implementar a checagem de tipos no assert. Se o statement identificado fosse um assert, verificamos se a expressão dentro dele corresponde a um booleano. Novamente, anteriormente havíamos implementado uma checagem para cada tipo de assert; Com o uso do CoreTransformer, isso não se mostrou mais necessário.
Com a mesma estratégia do interpretador, seguimos o formato das procedures. Os erros dos testes são identificados assim que o type checker é visitado; A corretude de tipos dos testes é checado instanciando as variáveis e constantes presentes no teste e verificando seu statement. Por fim, concatenamos eles com os erros das procedures.

Implementamos uma transformação do AssertEqual (AssertTrue(EQExpression(left, right))), AssertNotEqual (AssertTrue(NEQExpression(left, right))) e AssertError (AssertTrue(BoolValue(false))) no CoreTransformer, de forma que o processamento dessas statements no typechecker e interpretador fosse facilitado, sendo necessário apenas implementar o AssertTrue em ambos.
Por último, unimos os projetos dos grupos que tornaram o interpretador e o type checker funcionais, implementando os testes em suas versões funcionais, seguindo o mesmo formato utilizado por eles. Obs: caso seja oportuno, temos a versão sem essas mudanças
O uso do environment implementado pelo grupo do interpretador acarretou em 17 erros dentro do type checker e stdlibrary que não chegamos a solucionar. Todos os 17 parecem ser relacionados com o lookup do Environment. O uso do interpretador funcional acarretou em um erro adicional, de forma que há 18 erros no total dentro dos testes na versão final do nosso projeto.
Nossa maior dificuldade nesse projeto foi, a princípio, entender o que já havia sido escrito, como as coisas funcionavam. Assim que começávamos a entender e tínhamos um norte, o desenvolvimento fluiu continuamente, sem maiores obstáculos.

Componentes do grupo:
Eduardo Marciano de Melo Meneses - 211055227
Felipe Rocha Core - 211055245
Gabriela de Oliveira Henriques - 211055254
Lucas Rocha dos Santos - 211055325
Marcos Alexandre da Silva Neres - 211055334

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants