如何为散布元素列表编写parsec解析器?

时间:2014-06-07 12:27:07

标签: parsing haskell parsec

假设输入看起来像foo#1 bar baz-3.qux [...]。我想编写一个解析器,它只消耗输入直到[之前的第一个空格,这意味着foo#1 bar baz-3.qux(没有尾随空格)。

我应该如何使用parsec来解决这个问题?

我可以想象像

这样的东西
foo = many1 $ letter <|> digit <|> oneOf " #-."

但这会消耗最后的空间,我想避免。什么是解析散布在另一件事物中的事物列表的一般方法? (想象一下,它不仅仅是一个空间,还需要解析的东西)。

P.S:我正在寻找最通用的解决方案,而不是解决这个特定例子的聪明黑客。

1 个答案:

答案 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 '[')