2013-08-21 40 views
5

Tôi có một định nghĩa quy tắc như vậy:ANTLR ưu tiên thẻ

reference: volume':'first_page'-'last_page ; 

volume: INTEGER; 
first_page: INTEGER; 
last_page: INTEGER; 

INTEGER: [0-9]+; 

FREE_TEXT_WORD: NON_SPACE+; 

fragment NON_SPACE : ~[ \r\n\t]; 

Với đầu vào "168: 321-331", tôi nghĩ rằng nó sẽ phù hợp với các tài liệu tham khảo quy tắc. Nhưng trên thực tế, toàn bộ chuỗi được mã hóa là FREE_TEXT_WORD.

Tôi làm cách nào để tạo mã thông báo INTEGER mất tùy chọn hơn FREE_TEXT_WORD trong trường hợp này?

Cảm ơn.

Trả lời

4

ANTLR sẽ luôn luôn sử dụng một mã thông báo còn hơn một dấu hiệu ngắn hơn, do đó, để khắc phục tình trạng này, bạn phải thực hiện một trong những điều sau đây:

  1. Tận dụng tối FREE_TEXT_WORD không phù hợp với hơn 3 ký tự cho đầu vào 168:321-331 , ví dụ bằng cách không cho phép nó chứa một chữ số, hoặc có thể loại bỏ toàn bộ quy tắc.

    • Bạn cũng có thể thay đổi FREE_TEXT_WORD thành FREE_TEXT_CHARACTER. Bằng cách giới hạn quy tắc chỉ phù hợp với một ký tự đơn, nó sẽ không bao giờ dài hơn một mã thông báo khác vì vậy mức độ ưu tiên của nó sẽ được xác định bởi vị trí của nó trong ngữ pháp. Sau đó bạn sẽ cần phải tạo ra một quy tắc phân tích cú pháp cho chữ:

      freeTextWord : FREE_TEXT_CHARACTER+; 
      
  2. Di chuyển FREE_TEXT_WORD thẻ vào một chế độ mà không được kích hoạt tại điểm mà đầu vào của bạn đạt 168:321-331.

0

FREE_TEXT_WORD ở dạng hiện tại của nó đang ghi lại mọi thứ. Bạn cần một số non greedy lexer rule.

Hãy thử thay đổi

FREE_TEXT_WORD: NON_SPACE+;

để

FREE_TEXT_WORD: NON_SPACE+?;.

+1

-1: Điều này không có vẻ như nó đang hoạt động. Những gì bạn đã thực sự thực hiện được chuyển đổi quy tắc thành 'FREE_TEXT_WORD: NON_SPACE;', cho phép quy tắc 'INTEGER' khớp với đầu vào bằng cách buộc quy tắc' FREE_TEXT_WORD' thành * không bao giờ * khớp nhiều hơn một ký tự. –

+0

@ 280Z28 Cảm ơn bạn đã bình luận. Tôi đã thực sự ấn tượng rằng đó là một vấn đề tham lam và thử nghiệm nhanh chóng của tôi đã giải quyết vấn đề của OP vì vậy tôi đã gửi một câu trả lời. Tuy nhiên tôi đã mua cuốn sách ngày hôm qua, vì vậy hãy để tôi tiêu hóa nó một lúc. Tôi sẽ giữ câu trả lời ở đây và cuối cùng sẽ cập nhật hoặc xóa nó. – auselen