2011-12-28 14 views
14

Sto usando ANTLR per analizzare le espressioni logiche in uno strumento Java sto scrivendo, e sto avendo problemi perché passare le stringhe di input non valide al lexer e al parser ANTLR generati non causa eventuali eccezioni. Invece di lanciare una RecognitionException, come mi aspetterei, i file generati stampano semplicemente il messaggio di errore sulla console e restituiscono come se non si fossero verificati errori, causando il crash del mio programma quando viene eseguito successivamente nei dati vuoti.ANTLR non genera errori sull'input non valido

Ho usato ANTLRWorks versione 1.4.3 per generare i file, e sembra che ci dovrebbe essere una sorta di opzione per far sì che si generino errori piuttosto che stampare sulla console, ma non ho trovato nulla. Qualcuno sa come ottenere ANTLR per lanciare effettivamente i messaggi di errore? Ho visto che questo stesso problema in C# è stato risolto utilizzando una versione precedente di ANTLR, è quello che devo fare?

EDIT: Dopo Bart mi ha segnalato in direzione di quello che stavo cercando, ho trovato questa pagina

https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Migrating+from+ANTLR+2+to+ANTLR+3

sezione "Gestione degli errori", il cui codice che aveva fatto quello che voglio di più esattamente. Per cambiare il modo in cui ANTLR cattura eccezioni, si può dire questo nel file di grammatica:

@rulecatch { 
    catch (RecognitionException e) { 
    throw e; 
    } 
} 

Questa forze ANTLR per generare l'eccezione invece di gestirlo e di recupero. Ci sono anche alcune cose in quella sezione sull'override delle funzioni di mismatch e recovery per assicurarsi che vengano lanciate tutte le eccezioni possibili.

risposta

17

una soluzione semplice sarebbe quella di ignorare del vostro lexer e parser di reportError(...) e un'eccezione della propria invece di lasciare ANTLR cercando di riprendersi dalla non corretta sintassi/Ingresso:

grammar YourGrammar; 

// options/header/tokens 

@parser::members { 
    @Override 
    public void reportError(RecognitionException e) { 
    throw new RuntimeException("I quit!\n" + e.getMessage()); 
    } 
} 

@lexer::members { 
    @Override 
    public void reportError(RecognitionException e) { 
    throw new RuntimeException("I quit!\n" + e.getMessage()); 
    } 
} 

// lexer & parser rules 

Altro su segnalazione degli errori (e recupero): https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Error+reporting+and+recovery

+0

Oh, grazie sooo molto, sapevo che ci doveva essere un modo semplice per modificare solo il file di grammatica per fare quello che voglio, ma ANTLR è così grande, non l'ho fatto sapere esattamente cosa cercare. –

+0

Siete i benvenuti @BeaMetitiri. –

+0

Il collegamento è obsoleto – gvlasov

1

si consiglia di utilizzare un listener di errore come suggerito in this answer

Tuttavia, per una migrazione rapida da antlr3 antlr4/ANTLR v4, si potrebbe usare per th è come il vostro Grammer:

@parser::members 
{ 
    private final Logger log = LogManager.getLogger(this.getClass().getName()); 
    public java.util.HashMap<String, Double> memory = new java.util.HashMap<String, Double>(); 

    @Override 
    public void notifyErrorListeners(Token offendingToken, String msg, RecognitionException ex) 
    { 
    throw new RuntimeException(msg); 
    } 
} 

@lexer::members 
{ 
    @Override 
    public void recover(RecognitionException ex) 
    { 
    throw new RuntimeException(ex.getMessage()); 
    } 
} 
Problemi correlati