2011-12-28 13 views
14

Używam ANTLR do parsowania wyrażeń logicznych w narzędziu Java, które piszę, i mam problemy, ponieważ przekazywanie nieprawidłowych ciągów wejściowych do generowanego lexera ANTLR i analizatora składni nie powoduje wszelkie wyjątki. Zamiast generowania wyjątku RecognitionException, tak jak oczekiwałbym, wygenerowane pliki po prostu wypisują komunikat o błędzie na konsolę i zwracają, jak gdyby nie wystąpiły żadne błędy, powodując awarię mojego programu, gdy później zostanie on uruchomiony w pustych danych.ANTLR nie generuje błędów na błędnych danych wejściowych

Do wygenerowania plików użyłem ANTLRWorks w wersji 1.4.3. Wygląda na to, że powinna istnieć jakaś opcja, aby rzeczywiście wyświetlać błędy, zamiast drukować na konsoli, ale nic nie znalazłem. Czy ktoś wie, jak zmusić ANTLR do wysyłania komunikatów o błędach? Widziałem, że ten sam problem w języku C# został rozwiązany przy użyciu starszej wersji ANTLR, czy to jest to, co muszę zrobić?

EDIT: Po Bart wskazał mnie w kierunku tego, co szukałem, znalazłem tę stronę

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

którego sekcja „Obsługa błędów” miał kod, który robił, co chcę bardziej dokładnie. Aby zmienić sposób ANTLR łapie wyjątki, można powiedzieć, że w pliku gramatyki:

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

Zmusza ANTLR rzucić wyjątek zamiast obsługiwać go i odzyskanie. W tej sekcji jest także trochę informacji o przesłonięciu funkcji niezgodności i odzyskiwania, aby upewnić się, że wszystkie możliwe wyjątki są zgłaszane.

Odpowiedz

17

łatwo naprawić byłoby zastąpić swoją lexer i parser na reportError(...) a wyjątek własnego zamiast pozwolić ANTLR próbuje odzyskać od niewłaściwej składni/wejścia:

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 

Więcej na temat raportowania błędów (i odzysku): https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Error+reporting+and+recovery

+0

Och, dziękuję taaak dużo, wiedziałem, że musi być prosty sposób wystarczy edytować plik gramatyki, aby robić to, co chcę, ale ANTLR jest tak duży, że nie zrobił dokładnie wiedzieć, czego szukać. –

+0

Nie ma za co. @BeaMetitiri. –

+0

Link jest przestarzały – gvlasov

1

należy użyć detektor błędu jak sugeruje in this answer

jednak na szybką migrację z antlr3 do antlr4/antlr v4, można użyć th jest jako 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()); 
    } 
} 
Powiązane problemy