2016-12-13 20 views
5

Tôi không biết perl 5, nhưng tôi nghĩ rằng tôi muốn chơi với perl 6. Tôi đang thử khả năng ngữ pháp của nó, nhưng cho đến nay tôi không có may mắn. Dưới đây là mã của tôi cho đến nay:Tại sao ngữ pháp này không hoạt động?

grammar CopybookGrammar { 
     token TOP { {say "at TOP" } <aword><num>} 
     token aword { {say "at word" } [a..z]+ } 
     token num { {say "at NUM" } [0..9]+ } 
} 


sub scanit($contents) { 
     my $match1 = CopybookGrammar.parse($contents); 
     say $match1; 
} 

scanit "outline1"; 

Đầu ra là như sau:

at TOP 
at word 
(Any) 

Đối với một số lý do, nó không xuất hiện để phù hợp với các quy tắc <num>. Ý tưởng nào?

Trả lời

8

Bạn quên dấu ngoặc nhọn trong cú pháp character classes:

[a..z]+ nên <[a..z]>+

[0..9]+ nên <[0..9]>+

Bởi bản thân, dấu ngoặc vuông [ ] chỉ đơn giản đóng vai trò như một non-capturing group trong Perl 6 regexes. Vì vậy, [a..z]+ sẽ khớp với chữ "a", tiếp theo là hai ký tự bất kỳ, tiếp theo là chữ cái "z", và sau đó là toàn bộ một lần nữa bất kỳ số lần nào. Vì điều này không khớp với từ "đường viền", mã thông báo <aword> không khớp cho bạn và việc phân tích cú pháp không tiếp tục với mã thông báo <num>.


PS: Khi gỡ lỗi văn phạm, một lựa chọn thuận tiện hơn để thêm {say ...} khối ở khắp mọi nơi, là sử dụng Grammar::Debugger. Sau khi cài đặt mô-đun đó, bạn có thể tạm thời thêm dòng use Grammar::Debugger; vào mã của mình và chạy chương trình - sau đó nó sẽ thực hiện từng bước ngữ pháp của bạn (sử dụng phím ENTER để tiếp tục) và cho bạn biết mã thông báo nào khớp với cách.

+2

Mô-đun chị em cho Ngữ pháp :: Trình gỡ lỗi ** Ngữ pháp :: Tracer ** từ cùng một vị trí như Grammar :: Debugger. 'sử dụng Grammar :: Tracer;' và bạn sẽ nhận được một dấu vết của ngữ pháp chạy với dữ liệu đầu vào. – donaldh

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