2012-04-02 9 views
8

Tôi đang cố gắng để phân tích một số văn bản với parsec:Haskell Text.Parsec.Combinator lựa chọn không backtrack

data Cmd = LoginCmd String 
     | JoinCmd String 
     | LeaveCmd String 
    deriving (Show) 

singleparam :: Parser Cmd 
singleparam = do 
    cmd <- choice [string "leave", string "login", string "join"] 
    spaces 
    nick <- many1 anyChar 
    eof 
    return $ LoginCmd nick 

Tôi đang mong đợi choice để cố gắng kết hợp "để lại", và nếu nó không thành công, sau đó thử "đăng nhập" vv Nhưng nó chỉ cố gắng để phù hợp với "để lại", và nếu nó không thành công, sau đó đưa ra một lỗi.

ghci> parseTest singleparam (pack "login asdf") 
parse error at (line 1, column 1): 
unexpected "o" 
expecting "leave" 
ghci> parseTest singleparam (pack "leave asdf") 
LoginCmd "asdf" 

Tôi đang làm gì sai?

Trả lời

14

Parsec không tự động quay lại như thế này (để có hiệu quả). Quy tắc là khi một chi nhánh chấp nhận một mã thông báo thì các nhánh thay thế sẽ được cắt bớt. Giải pháp là để thêm một tùy ý rõ ràng sử dụng try (string "leave")try (string "login"), vv

Trong ví dụ của bạn nhân vật 'l' là token cam Parsec để là người đầu tiên "rời" chi nhánh và từ bỏ các chi nhánh tiếp theo của "đăng nhập" và " tham gia".

Thêm chi tiết trong thế giới thực Haskell (sách, trực tuyến) on parsec.