我正在尝试用parsec解析一些Text:
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
尝试匹配“离开”,如果失败,则尝试“登录”等。但它只会尝试匹配“离开”,如果失败,则给出一个错误。
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"
我做错了什么?
答案 0 :(得分:14)
Parsec不会像这样自动回溯(为了提高效率)。规则是,一旦分支接受令牌,则修剪备用分支。解决方案是使用try (string "leave")
和try (string "login")
等添加显式回溯。
在您的示例中,'l'字符是将Parsec提交到第一个“leave”分支并放弃“login”和“join”的下一个分支的标记。
Real World Haskell的更多细节(在线书籍)on parsec。