我有一种奇怪的想法。假设我有这样的事情:
data Statement = StatementType Stuff Source
现在我想解析这样一个语句,解析所有的东西,之后我想把我处理过的所有字符(对于这个特定的语句)放到结果数据结构中。出于某种原因。
是否可能,如果可以,如何实现?
答案 0 :(得分:4)
一般情况下,这是不可能的。 parsec
并不期望它的流类型有很多,特别是没有办法有效地分割流。
但是对于具体的流类型(例如String
,或[a]
或ByteString
),这样的黑客会起作用:
parseWithSource :: Parsec [c] u a -> Parsec [c] u ([c], a)
parseWithSource p = do
input <- getInput
a <- p
input' <- getInput
return (take (length input - length input') input, a)
此解决方案依赖于返回当前输入的函数getInput
。所以我们可以得到两次输入:在解析之前和之后,这给出了消耗元素的确切数量,并且知道我们可以take
来自原始输入的这些元素。
在这里你可以看到它的实际效果:
*Main Text.Parsec> parseTest (between (char 'x') (char 'x') (parseWithSource ((read :: String -> Int) `fmap` many1 digit))) "x1234x"
("1234",1234)
但您还应该查看attoparsec
,因为它使用match函数正确支持此功能。