Parsec - '很多'和错误消息

时间:2010-11-16 21:27:11

标签: haskell parsec

当我尝试解析many p时,我没有收到“期待p”消息:

> parse (many (char '.') >> eof) "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting end of input

比较
> parse (sepBy (char '.') (char ',') >> eof) "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting "." or end of input

报告“。”正如我所料。 many1 p <|> return []也适用。

所有这些功能都接受空输入,那么为什么many没有报告它的期望呢?这是一个错误还是一个功能?

4 个答案:

答案 0 :(得分:7)

使用manyTill

,您将收到更好的错误消息
> parse (manyTill (char '.') eof) "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting end of input or "."

这只是因为你与>>链接的方式。如果第一个解析器成功,那么第二个解析器将运行。 many成功,因此尝试了eofeof失败,因此您只会收到eof的错误消息。

使用manyTill,它会尝试两个解析器(第二个),如果两个都失败,则会合并错误消息(这是因为它在内部使用<|>

但总的来说,使用<?>定义自己的错误更容易:

> parse (many (char '.') >> eof <?> "lots of dots") "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting lots of dots

答案 1 :(得分:3)

在某种程度上肤浅的意义上,行为差异的原因是manyprimitive parsersepBy被构建in a similar manner给你重新实现的many }。在后一种情况下,“期待...”消息是基于导致解析失败的路径上可用的替代方案构建的; many没有这样的选择,只是无条件地成功。

我不知道我将其描述为一个错误一个功能,它只是Parsec如何工作的怪癖。错误处理并不是Parsec的实力,这似乎不是我在这方面首先要担心的事情。如果它充分困扰你,你可以通过查看其他解析库来获得更好的服务。例如,我听说过有关uu-parsinglib的好消息。

答案 2 :(得分:1)

来自haddock

  

许多p应用解析器p 0或   更多次。返回一个列表   返回p。

的值

因此空字符串是many组合子的有效输入。

[补充]

啊,现在我明白了你的观点。使用expecting a or b(选择组合子)时会报告<|>many是在不使用<|>的情况下实施的,但sepBy在内部使用它。

答案 3 :(得分:0)

这是parsec-3.1中引入的错误。如果您使用以前的版本进行测试,则会收到如下错误消息:

> parse (many (char '.') >> eof) "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting "." or end of input

至少,这是修复bug后我得到的: - )