2012-02-25 27 views
5

Tôi đang cố triển khai BNF for EPD trong Pharo/PetitParser.Làm thế nào để ngăn chặn sự tham lam với PetitParser?

digit18 := $1 asParser/$2 asParser/$3 asParser/$4 asParser/$5 asParser/$6 asParser/$7 asParser/$8 asParser. 
piecePromotion := $N asParser/$B asParser/$R asParser/$Q asParser. 
promotion := ($= asParser) , piecePromotion. 
fileLetter := ($a asParser/$b asParser/$c asParser/$d asParser/$e asParser/$f asParser/$g asParser/$h asParser). 
targetSquare := fileLetter , digit18. 
disambiguation := fileLetter/digit18. 
pieceCode := ($N asParser/$B asParser/$R asParser/$Q asParser/$K asParser) optional. 
castles := $O asParser, $- asParser, $O asParser, (($- asParser, $O asParser) optional) . 
sanMove := (pieceCode, disambiguation optional, targetSquare, promotion optional, ($+ asParser/$# asParser) optional) "/ castles". "commented out because I'd be getting another error with this enabled" 

sau đó tôi thử và phân tích như thế này:

element := PPUnresolvedParser new. 

element def: (sanMove). 
mse := element end. 
mse parse: 'Re4'. 

Nhưng tôi nhận được lỗi này:

$h expected at 2 // btw these indexes seem to start at 0 

Nếu tôi cố gắng Ree4 như là đầu vào nó phân tích thành công như #($R $e #($e $4) nil nil). Điều này làm cho tôi nghĩ rằng cờ tùy chọn về định hướng không hoạt động đúng cách và trình phân tích cú pháp không thử xem nó có phân tích cú pháp mà không phân tích cú pháp "e" dưới dạng disambiguation hay không, mặc dù nó có thể. Nó dẫn đến việc không thể phân tích cú pháp bắt buộc targetSquare mặc dù, vì vậy tôi không hiểu tại sao PetitParser bỏ cuộc.

Trả lời

4

Parsing Expression Grammars (loại công cụ phân tích cú pháp mà PetitParser đang sử dụng) tham lam. Điều này có nghĩa là họ không bao giờ quay trở lại ngay sau khi một cái gì đó đã được tiêu thụ thành công. Trong trường hợp của bạn, quy tắc "định hướng" được tiêu thụ thành công, do đó trình phân tích cú pháp không bao giờ thử lại bỏ qua ngay cả khi trình phân tích cú pháp sau đó bị kẹt.

Ngữ pháp BNF và PEG trông giống nhau, nhưng chúng có ngữ nghĩa rất khác nhau. Do đó bạn không thể chỉ dịch một quy tắc ngữ pháp BNF theo quy tắc sang PetitParser. Bạn phải cẩn thận sắp xếp các lựa chọn (các vấn đề trật tự trong PEG). Trong ví dụ cụ thể của bạn, bạn có thể thay đổi sanMove tới:

sanMove := pieceCode, ((targetSquare, promotion optional, ($+ asParser/$# asParser) optional)/(disambiguation optional, targetSquare, promotion optional, ($+ asParser/$# asParser) optional)). 

Với quy tắc mà cả hai bài kiểm tra của bạn phân tích:

sanMove end parse: 'Ree4'. 
sanMove end parse: 'Re4'. 
Các vấn đề liên quan