Parsec:解析后抓取原始源

时间:2014-10-15 04:43:26

标签: haskell parsec

我有一种奇怪的想法。假设我有这样的事情:

data Statement = StatementType Stuff Source

现在我想解析这样一个语句,解析所有的东西,之后我想把我处理过的所有字符(对于这个特定的语句)放到结果数据结构中。出于某种原因。

是否可能,如果可以,如何实现?

1 个答案:

答案 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函数正确支持此功能。