2012-01-26 32 views
5

Vui lòng xem mã nguồn có sẵn tại: https://gist.github.com/1684022.Cách thích hợp để giải quyết sự không rõ ràng về quy tắc lexer ANTLR?

tôi đã có hai thẻ định nghĩa:

ID : ('a'..'z' | 'A'..'Z') ('0'..'9' | 'a'..'z' | 'A'..'Z' | ' ')*; 

PITCH 
    : (('A'|'a') '#'?) 
    | (('B'|'b') '#'?) 
    | (('C'|'c') '#'?); 

Rõ ràng, chữ "A" sẽ là một sự mơ hồ.

Tôi cũng xác định:

note : PITCH; 
name : ID; 
main : name ':' note '\n'? 

Bây giờ, nếu tôi nhập "A: A" làm đầu vào cho phân tích cú pháp, tôi luôn nhận được một lỗi. Trình phân tích cú pháp mong đợi PITCH hoặc ID tùy thuộc vào việc ID hoặc PITCH được xác định trước hay không:

mismatched input 'A' expecting ID 

Cách thích hợp để giải quyết vấn đề này là gì?


Như được mô tả, mặc dù nó có ý nghĩa trực quan về cách phân tích cú pháp hoạt động, ANTLR không thực hiện "điều đúng". Đó là, mặc dù quy tắc main cho biết trước tiên, một lenner name/ID sẽ bị bỏ qua và xác định "A" là PITCH vì nó tuân thủ quy tắc "dài nhất"/"đến trước" thay vì quy tắc "quy tắc cho biết quy tắc" hợp lý hơn.

Giải pháp duy nhất để giả mạo/hack nó bằng cách kết hợp cả ID và PITCH, sau đó kết hợp lại chúng sau khi dasblinkenlight nói?

+0

Có. Không gian phải làm gì với câu hỏi? – Ana

+1

Nhìn kìa, Bart. Có hay không tôi hiểu ANTLR, điểm mà bạn tiếp tục rèn luyện, không liên quan. Tôi đang tìm kiếm một giải pháp có ý nghĩa và mặc dù bạn đã cung cấp một câu trả lời và bốn bình luận, không có giải pháp nào trong số đó là giải pháp, chỉ là bình luận về bài viết của tôi hoặc sự hiểu biết của tôi. Nếu bạn hiểu ANTLR và bạn hiểu vấn đề của tôi tốt hơn tôi, thì hãy đăng một giải pháp thực sự. – Ana

Trả lời

4

Sau đây là cách tôi sẽ tái yếu tố ngữ pháp này để làm cho nó hoạt động:

ID : (('a'..'z' | 'A'..'Z') ('0'..'9' | 'a'..'z' | 'A'..'Z' | ' ')+) 
    | ('d'..'z' | 'D'..'Z'); 

PITCH : 'a'..'c' | 'A'..'C'; 

SHARP : '#'; 

note : PITCH SHARP?; 

name : ID | PITCH; 

main : name ':' note '\n'? EOF 

này tách tên dài từ tên sân một ký tự, mà có được "đoàn tụ" trong phân tích cú pháp. Mã thông báo "sắc nét" cũng có tên riêng và được nhận dạng trong trình phân tích cú pháp dưới dạng mã thông báo tùy chọn.

+0

Cảm ơn, dasblinkenlight. Cảm kích điều đó. Đã hy vọng có một cách sạch hơn nhưng điều này sẽ làm. – Ana

+0

@Ana Đây là phương pháp chuẩn của ANTLR cho phép sử dụng từ khóa làm mã định danh. Trong trường hợp của bạn, 'PITCH' đóng vai trò của một" từ khóa ", trong khi số nhận dạng vẫn là số nhận dạng. – dasblinkenlight

Các vấn đề liên quan