2011-12-28 52 views
14

Tôi đang sử dụng ANTLR để phân tích cú pháp biểu thức logic trong công cụ Java mà tôi đang viết và tôi gặp sự cố vì truyền chuỗi đầu vào không hợp lệ tới trình tạo và phân tích cú pháp ANTLR được tạo bất kỳ ngoại lệ nào. Thay vì ném một RecognitionException, như tôi mong đợi, các tệp được tạo ra chỉ in thông báo lỗi tới bàn điều khiển và trả về như thể không có lỗi xảy ra, khiến chương trình của tôi gặp sự cố khi nó chạy vào dữ liệu trống sau này.ANTLR không ném lỗi trên đầu vào không hợp lệ

Tôi đã sử dụng ANTLRWorks phiên bản 1.4.3 để tạo tệp và có vẻ như có một số tùy chọn để thực sự ném lỗi thay vì in trên bảng điều khiển, nhưng tôi chưa tìm thấy gì. Có ai biết làm thế nào để có được ANTLR để thực sự ném thông báo lỗi? Tôi thấy rằng vấn đề tương tự trong C# đã được giải quyết bằng cách sử dụng một phiên bản cũ hơn của ANTLR, là những gì tôi cần phải làm gì?

EDIT: Sau khi Bart chỉ cho tôi trong sự chỉ đạo của những gì tôi đang tìm kiếm, tôi tìm thấy trang này

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

mà "Lỗi xử lý" phần có mã mà đã làm những gì tôi muốn chính xác hơn. Để thay đổi cách ANTLR bắt được ngoại lệ, bạn có thể nói điều này trong tệp ngữ pháp:

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

Lực lượng này để ném ngoại lệ thay vì xử lý và khôi phục. Ngoài ra còn có một số công cụ trong phần đó về việc ghi đè các hàm không phù hợp và khôi phục để đảm bảo tất cả các ngoại lệ có thể được ném ra.

Trả lời

17

Một sửa chữa dễ dàng sẽ được ghi đè của lexer của bạn và phân tích cú pháp của reportError(...) và ném một ngoại lệ của riêng bạn thay vì để cho ANTLR cố gắng để phục hồi từ cú pháp không chính xác/input:

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 

Thông tin thêm về báo cáo lỗi (và phục hồi): https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Error+reporting+and+recovery

+0

Ồ, cảm ơn bạn rất nhiều, tôi biết có cách đơn giản để chỉnh sửa tệp ngữ pháp để làm những gì tôi muốn, nhưng ANTLR quá lớn, tôi không biết chính xác những gì cần tìm. –

+0

Bạn đang chào đón @BeaMetitiri. –

+0

Liên kết đã lỗi thời – gvlasov

1

bạn nên sử dụng một người biết lắng nghe lỗi như đề xuất in this answer

Tuy nhiên, đối với một di cư nhanh chóng từ antlr3 để antlr4/ANTLR v4, bạn có thể sử dụng thứ là ngữ pháp của bạn:

@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()); 
    } 
} 
Các vấn đề liên quan