使用Attoparsec时输入不完整的问题 [英] Problem with incomplete input when using Attoparsec

查看:142
本文介绍了使用Attoparsec时输入不完整的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将使用Parsec的一些正常运行的Haskell代码转换为使用Attoparsec,希望获得更好的性能。我已经做了更改,所有的东西都编译完了,但我的解析器无法正常工作。

I am converting some functioning Haskell code that uses Parsec to instead use Attoparsec in the hope of getting better performance. I have made the changes and everything compiles but my parser does not work correctly.

我解析一个由不同记录类型组成的文件,每行一个。我的每个解析记录或注释的函数都能正常工作,但是当我尝试编写函数来编译一系列记录时,解析器总是返回一个部分结果,因为它需要更多输入。

I am parsing a file that consists of various record types, one per line. Each of my individual functions for parsing a record or comment works correctly but when I try to write a function to compile a sequence of records the parser always returns a partial result because it is expecting more input.

这是我尝试过的两个主要变体。

These are the two main variations that I've tried. Both have the same problem.

items :: Parser [Item]
items = sepBy (comment <|> recordType1 <|> recordType2) endOfLine

对于第二个,我更改了记录/注释解析器消费行尾字符。

For this second one I changed the record/comment parsers to consume the end-of-line characters.

items :: Parser [Item]
items = manyTill (comment <|> recordType1 <|> recordType2) endOfInput

?有没有其他的方法来实现我所尝试的?

Is there anything wrong with my approach? Is there some other way to achieve what I am attempting?

推荐答案

我之前遇到过这个问题,我的理解是它是由< |> sepBy 定义中的工作方式造成的:

I've run into this problem before and my understanding is that it's caused by the way that <|> works in the definition of sepBy:

sepBy1 :: Alternative f => f a -> f s -> f [a]
sepBy1 p s = scan
    where scan = liftA2 (:) p ((s *> scan) <|> pure [])

一旦(s),它将只移动到 pure [] *> scan)失败,这不会发生,因为您处于输入结束。

This will only move to pure [] once (s *> scan) has failed, which won't happen just because you're at the end of the input.

我的解决方案有只需在结果空 ByteString调用 feed >由 parse 返回。这可能是一种破解,但它似乎也是如何 attoparsec-iteratee 处理问题:

My solution has been just to call feed with an empty ByteString on the Result returned by parse. This might be kind of a hack, but it also seems to be how attoparsec-iteratee deals with the issue:

f k (EOF Nothing)  = finalChunk $ feed (k S.empty) S.empty

据我所知,这是 attoparsec-iteratee 在这里工作的唯一原因,而普通的旧的解析不会。

As far as I can tell this is the only reason that attoparsec-iteratee works here and plain old parse doesn't.

这篇关于使用Attoparsec时输入不完整的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆