2012-04-30 17 views
5

Mamy następujące podgrupy część gramatyki ANTLR:Obsługa błędów antlr składni lub jak dać lepszą wiadomość na nieoczekiwany znak

signed_int 
     : SIGN? INT 
    ; 

INT : '0'..'9'+ 
     ; 

Kiedy ktoś wchodzi wartość liczbową wszystko jest w porządku, ale jeśli błędnie wpisać coś takiego 1O (jeden i kapitału o) możemy uzyskać tajemniczą wiadomość błąd jak:

error 1 : Missing token at offset 14 
near [Index: 0 (Start: 0-Stop: 0) ='<missing COLON>'  type<24> Line: 26 LinePos:14] 
: syntax error... 

Co to dobry sposób, aby obsługiwać ten rodzaj błędu? Pomyślałem o zdefiniowaniu typu znacznika SYMBOL typu catch-all, ale prowadzi to do zbyt wielu błędów budowania parsera . Będę dalej badał obsługę błędów Antlr, ale ja myślałem, że zamieściłbym to tutaj, by poszukać pewnych spostrzeżeń.

Odpowiedz

4

Powinieneś Nadpisać metody reportError w lexer i parser. Można to zrobić poprzez dodanie tego kodu do pliku Lexer:

@Override 
public void reportError(RecognitionException e) { 
    throw new RuntimeException(e); 
} 

i stworzyć metodę mecze w parsera, który sprawdza, jeśli ciąg wejściowy odpowiada podanej gramatyki:

public static boolean matches(String input) { 
    try { 
     regExLexer lexer = new regExLexer(new ANTLRStringStream(input)); 
     regExParser parser = new regExParser(new CommonTokenStream(lexer)); 
     parser.goal(); 
     return true; 
    } catch (RuntimeException e) { 
     return false; 
    } 
    catch (Exception e) { 
     return false; 
    } 
    catch (OutOfMemoryError e) { 
     return false; 
    } 

} 

@Override 
public void reportError(RecognitionException e) { 
    throw new RuntimeException(e); 
} 

Następnie w użyciu pliku Parser.matches (dane wejściowe); sprawdzić, czy dane wejście pasuje do gramar. Jeśli pasuje do metody, zwraca true, w przeciwnym wypadku zwraca false, więc gdy zwróci false, możesz przekazać użytkownikom dowolny dostosowany komunikat o błędzie.