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

🐛 corrigindo Parser ignora tokens indesejados (fix #834 fix #759 fix #867 fix #810 fix #759 fix #190) #871

Merged
merged 7 commits into from
Nov 14, 2020

Conversation

AdsonEsteves
Copy link
Member

@AdsonEsteves AdsonEsteves commented Oct 27, 2020

Disclaimer:
Esse Pull Request ajuda a resolver varias issues (#834 #759 #867 #810 #761 #759 #308), invalida o pull request #851 e resolve a #190.
Atenção no ajuda. O que esse pull request faz principalmente é encontrar erros que não eram encontrados antes ou geravam erros que as soluções não eram práticas.
Portanto, as issues ainda precisam ser resolvidas, tratando os erros gerados e futuros erros desconhecidos que essas mudanças podem pegar.

O que era:
O PortugolParser possui um ErrorHandler que joga exceções quando encontra erros no código

PortugolParser portugolParser = new PortugolParser(new CommonTokenStream(portugolLexer));
portugolParser.setErrorHandler(new DefaultErrorStrategy() {
@Override
public void recover(Parser recognizer, RecognitionException e) {
throw e;
}
@Override
public void reportInputMismatch(Parser recognizer, InputMismatchException e) throws RecognitionException {
String msg = "mismatched input " + getTokenErrorDisplay(e.getOffendingToken());
msg += " expecting one of " + e.getExpectedTokens().toString(recognizer.getVocabulary());
RecognitionException ex = new RecognitionException(msg, recognizer, recognizer.getInputStream(), recognizer.getContext());
ex.initCause(e);
throw ex;
}
@Override
public void reportMissingToken(Parser recognizer) {
beginErrorCondition(recognizer);
Token t = recognizer.getCurrentToken();
IntervalSet expecting = getExpectedTokens(recognizer);
String msg = "missing " + expecting.toString(recognizer.getVocabulary()) + " at " + getTokenErrorDisplay(t);
throw new RecognitionException(msg, recognizer, recognizer.getInputStream(), recognizer.getContext());
}
});

Entretanto esse Handler não possui todas as funções implementadas, sendo uma delas a necessária para identificar "Tokens Indesejados".
Ao se implementar as funções restantes, o Portugol conseguiu encontrar esses problemas e gerar as exceções pelo Parser.
PortugolParser portugolParser = new PortugolParser(new CommonTokenStream(portugolLexer));
portugolParser.setErrorHandler(new DefaultErrorStrategy() {
@Override
public void recover(Parser recognizer, RecognitionException e) {
throw e;
}
@Override
public void reportInputMismatch(Parser recognizer, InputMismatchException e) throws RecognitionException {
String msg = "mismatched input " + getTokenErrorDisplay(e.getOffendingToken());
msg += " expecting one of " + e.getExpectedTokens().toString(recognizer.getVocabulary());
RecognitionException ex = new RecognitionException(msg, recognizer, recognizer.getInputStream(), recognizer.getContext());
ex.initCause(e);
throw ex;
}
@Override
public void reportMissingToken(Parser recognizer) {
beginErrorCondition(recognizer);
Token t = recognizer.getCurrentToken();
IntervalSet expecting = getExpectedTokens(recognizer);
String msg = "missing " + expecting.toString(recognizer.getVocabulary()) + " at " + getTokenErrorDisplay(t);
throw new RecognitionException(msg, recognizer, recognizer.getInputStream(), recognizer.getContext());
}
@Override
protected void reportUnwantedToken(Parser recognizer) {
beginErrorCondition(recognizer);
Token t = recognizer.getCurrentToken();
IntervalSet expecting = getExpectedTokens(recognizer);
String msg = "Expressão " +getTokenErrorDisplay(t)+ " não faz sentido, era esperado o token "+expecting.toString(recognizer.getVocabulary())+". Remova-a para solucionar o problema";
throw new RecognitionException(msg, recognizer, recognizer.getInputStream(), recognizer.getContext());
}
@Override
protected void reportFailedPredicate(Parser recognizer, FailedPredicateException e) {
beginErrorCondition(recognizer);
Token t = recognizer.getCurrentToken();
IntervalSet expecting = getExpectedTokens(recognizer);
String msg = "Expressão " +getTokenErrorDisplay(t)+ " não faz sentido, era esperado o token "+expecting.toString(recognizer.getVocabulary())+".";
throw new RecognitionException(msg, recognizer, recognizer.getInputStream(), recognizer.getContext());
}
@Override
protected void reportNoViableAlternative(Parser recognizer, NoViableAltException e) {
beginErrorCondition(recognizer);
Token t = recognizer.getCurrentToken();
IntervalSet expecting = getExpectedTokens(recognizer);
String msg = "Expressão " +getTokenErrorDisplay(t)+ " não faz sentido, era esperado o token "+expecting.toString(recognizer.getVocabulary())+".";
throw new RecognitionException(msg, recognizer, recognizer.getInputStream(), recognizer.getContext());
}
});

Para frente:
Essas modificações vão começar a identificar diversos erros que eram ignorados. Para alguns usuários vai parecer que "do Nada", o programa dele não funciona e agora gera um erro que não faz sentido. É importante que mais testes sejam feitos antes de um novo release para encontrar e tratar mais mensagens sem sentido.
Muitas das mensagens de erro se tornaram "o nome da funcao não foi retornado". Isso acontece pois o tradutor de erros utiliza o contexto dos tokens para identificar o problema, porém alguns tokens não possuem "contexto" no sintatico (como o senao) e portanto o Parser retorna como contexto, o contexto "Pai", muitas vezes uma funcao.
Dependendo do problema, pode ser necessário alterar o g4 para criar um contexto para esses tokens. idk.

@noschang
Copy link

@AdsonEsteves, na gramática antiga eu incluía o nome dos contextos manualmente em cada parte da gramática. Deixava difícil de ler e manter, mas permitia um maior controle sobre os erros

Depois que o @elieserdejesus mudou a implementação para ANTLR4 eu não sei como ficou essa parte. Acredito que ele removeu as informações de contexto da gramática pois a própria árvore gerada pelo ANTLR já contém algumas informações contextuais

Talvez seja o caso de incluirmos essas informações na gramática somente em pontos específicos, como o caso do senao que você citou. Seria interessante ter a opinião do @elieserdejesus

@AdsonEsteves
Copy link
Member Author

AdsonEsteves commented Nov 12, 2020

@noschang
@elieserdejesus
@AlissonSteffens
@Rafaelfcosta

Aproveitando o embalo, tratei os erros do senao e dos parametros de funcao. Agora ele deve resolver as issues: #834 #759 #867 #810 #759 #190
E uma da #308 , a dos pontos.
Alterei o antlr e coloquei contextos para os parametros de funcao e para o senao. Assim pude capturar os erros sem ambiguidade.

Se puderem testar por favor os problemas com o senao e com os parametros de função e verificar as mensagens de erro.
No caso de palavras "aleatorias" no codigo, ele também deve capturar.


Adicional:
Capturei tbm o #677, pra entrar no combo.
Destaque que talvez futuramente podemos adicionar a possibilidade do usuario retornar vetores.

@AdsonEsteves AdsonEsteves changed the title 🐛 Corrigindo Parser ignora tokens indesejados 🐛 Corrigindo Parser ignora tokens indesejados ( Fix #834 Fix #759 Fix #867 Fix #810 Fix #759) Nov 12, 2020
@AdsonEsteves AdsonEsteves changed the title 🐛 Corrigindo Parser ignora tokens indesejados ( Fix #834 Fix #759 Fix #867 Fix #810 Fix #759) 🐛 Corrigindo Parser ignora tokens indesejados (fix #834 fix #759 fix #867 fix #810 fix #759) Nov 12, 2020
@AdsonEsteves AdsonEsteves changed the title 🐛 Corrigindo Parser ignora tokens indesejados (fix #834 fix #759 fix #867 fix #810 fix #759) 🐛 corrigindo Parser ignora tokens indesejados (fix #834 fix #759 fix #867 fix #810 fix #759) Nov 12, 2020
@AdsonEsteves AdsonEsteves changed the title 🐛 corrigindo Parser ignora tokens indesejados (fix #834 fix #759 fix #867 fix #810 fix #759) 🐛 corrigindo Parser ignora tokens indesejados (fix #834 fix #759 fix #867 fix #810 fix #759 fix #190) Nov 12, 2020
Copy link
Member

@AlissonSteffens AlissonSteffens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Não achei no código onde está esta frase, mas ao testar a #190, a mensagem está errada.
Mensagem atual: Você pulou uma linha ao escrever uma cadeia. Cadeias apenas podem ser escritas em na mesma linha.

Testei todos os outros fix, e estão certos 👍

Copy link
Member

@AlissonSteffens AlissonSteffens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@AdsonEsteves AdsonEsteves merged commit 49103fb into master Nov 14, 2020
@AdsonEsteves AdsonEsteves deleted the corrigindo_tokens_errados_ignorados branch November 14, 2020 20:36
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.

3 participants