2014-04-11 34 views
3

我在這裏有一些代碼,用於解析URI路徑到一個字符串列表。例如,/user/home將變爲["user", "home"]Haskell Parsec:撤消失敗的許多

pathPiece :: Parser String 
pathPiece = do 
     char '/' 
     path <- many1 urlBaseChar 
     return path 

uriPath :: Parser [String] 
uriPath = do 
    pieces <- many pathPiece 
    try $ char '/' 
    return pieces 

parseUriPath :: String -> [String] 
parseUriPath input = case parse uriPath "(unknown)" input of 
        Left _ -> [] 
        Right xs -> xs 

然而,如果路徑與另一/如,這應該是一個合法的路徑結束時,解析器將失敗。這是因爲pathPiece無法解析最後的/,因爲沒有以下urlBaseChars。我想知道如何解析許多人,直到失敗爲止,如果失敗了,你可以撤銷角色消費。

+0

關於樣式的說明,do {x < - m; return x}'相當於'm'(由monad法則保證!)所以'pathPiece'可以簡化一下。 – cdk

回答

5

試試這個:

pathPiece :: Parser String 
pathPiece = try $ do 
    char '/' 
    many1 urlBaseChar 

uriPath :: Parser [String] 
uriPath = do 
    pieces <- many pathPiece 
    optional (char '/') 
    return pieces 

您需要添加一個trypathPiece。否則,解析最終的/將使Parsec 認爲新的pathPiece已經開始,並且沒有try,則沒有回溯。另外,除非你真的想要需要最後/,你需要使它成爲optional。 函數try不這樣做。

+0

感謝您的幫助kosmikus。這是正確的,我學到了一些關於Parsec的知識;) – MCH

1

我想你可以在這裏使用many1 urlBaseChar `sepEndBy` char '/'。請參閱Parsec中的sepEndBy