11

私はparsecでいくつかのテキストを解析しようとしています:

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

choice「leave」と一致させようと思っていますが、失敗した場合は「login」などを試してください。ただし、「leave」と一致させようとするだけで、失敗した場合はエラーになります。

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"

私は何が間違っているのですか?

4

1 に答える 1

16

Parsecは、(効率のために)このように自動的にバックトラックしません。ルールは、ブランチがトークンを受け入れると、代替ブランチがプルーニングされるというものです。try (string "leave")解決策は、 andtry (string "login")などを使用して明示的なバックトラッキングを追加することです。

あなたの例では、「l」文字は、Parsecを最初の「leave」ブランチにコミットし、「login」と「join」の次のブランチを放棄するトークンです。

詳細については、parsecのReal World Haskell(本、オンライン)を参照してください。

于 2012-04-02T12:34:36.323 に答える