假设输入看起来像foo#1 bar baz-3.qux [...]
。我想编写一个解析器,它只消耗输入直到[
之前的第一个空格,这意味着foo#1 bar baz-3.qux
(没有尾随空格)。
我应该如何使用parsec来解决这个问题?
我可以想象像
这样的东西foo = many1 $ letter <|> digit <|> oneOf " #-."
但这会消耗最后的空间,我想避免。什么是解析散布在另一件事物中的事物列表的一般方法? (想象一下,它不仅仅是一个空间,还需要解析的东西)。
P.S:我正在寻找最通用的解决方案,而不是解决这个特定例子的聪明黑客。
答案 0 :(得分:4)
我认为您正在寻找的是notFollowedBy
。像
foo = many1 $ letter
<|> digit
<|> oneOf "#-."
<|> (try $ char ' ' >> notFollowedBy (char '[') >> return ' ')
你可以抽象出模式来获得当然的一般功能:
endedBy :: (Show y) => Parser x -> Parser x -> Parser y -> Parser [x]
endedBy p final terminal = many1 $ p <|> t where
t = try $ do
x <- final
notFollowedBy terminal
return x
foo' = endedBy (letter <|> digit <|> oneOf "#-.") (char ' ') (char '[')