3

当我尝试解析 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

4 回答 4

8

您将获得更好的错误消息manyTill

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

这只是由于您与>>. 如果第一个解析器成功,则将运行第二个解析器。many成功,所以eof尝试。eof失败,因此您只会收到eof' 的错误消息。

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

不过,总体而言,使用以下命令定义自己的错误更容易<?>

> parse (many (char '.') >> eof <?> "lots of dots") "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting lots of dots
于 2010-11-17T03:20:37.003 回答
3

在某种肤浅的意义上,行为差异的原因是它many是一个原始解析器,而sepBy其构造方式与您重新实现的many. 在后一种情况下,“expecting...”消息是基于导致解析失败的路径上可用的替代方案构建的;没有many这样的选择,它只是无条件地成功了。

我不知道我会将其描述为错误还是功能,这只是 Parsec 工作原理的一种怪癖。错误处理并不是 Parsec 的真正优势,这似乎并不是我在这方面首先担心的事情。如果它足够困扰您,您可能会通过查看其他解析库来获得更好的服务。例如,我听说过关于uu-parsinglib的好消息。

于 2010-11-16T22:08:39.980 回答
1

来自黑线鳕

many p 应用解析器 p 零次或多次。返回 p 的返回值的列表。

所以空字符串是many组合器的有效输入。

[添加]

啊,现在我明白你的意思了。在使用(选择组合器)expecting a or b时报告。在没有使用的情况下实现,但在内部使用它。<|>many<|>sepBy

于 2010-11-16T21:47:41.543 回答
0

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

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

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

于 2010-11-17T05:27:51.680 回答