秒差距 - “许多”和错误消息

发布于 2024-10-03 00:38:56 字数 540 浏览 0 评论 0原文

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

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

Compare to

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

which reports “.”正如我所期望的。 many1 p <|>; return [] 也有效。

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

When I try to parse many p, I don't receive the 'expecting p' message:

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

Compare to

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

which reports "." as I'd expect. many1 p <|> return [] works as well.

All of these functions accept empty input, so why doesn't many report what it's expecting? Is it a bug or a feature?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

琉璃繁缕 2024-10-10 00:38:56

使用 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

You'll get better error messages with manyTill:

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

This is just due to the way you chain with >>. If the first parser succeeds, then the second one will be run. many succeeds, so eof is tried. eof fails so you only get eof's error message.

With manyTill, it tries both parsers (the second first) and, if both fail, the error messages are combined (this is because it uses <|> internally).

On the whole, though, it's easier to define your own errors with <?>:

> parse (many (char '.') >> eof <?> "lots of dots") "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting lots of dots
空心空情空意 2024-10-10 00:38:56

从表面上看,行为差异的原因是 many原始解析器sepBy 则构造为 以类似的方式 重新实现 很多。在后一种情况下,“期望...”消息是基于导致解析失败的路径上可用的替代方案构建的;对于many来说,没有这样的选择,它只是无条件地成功。

我不知道我会将其描述为错误还是功能,这只是秒差距工作方式的一个怪癖。错误处理并不是秒差距的真正强项,这似乎并不是我在这方面首先担心的事情。如果它足够困扰您,那么研究其他解析库可能会更好。例如,我听说过有关 uu-parsinglib 的好消息。

In a somewhat superficial sense, the reason for the difference in behavior is that many is a primitive parser whereas sepBy is constructed in a similar manner to your reimplemented many. In the latter case, the "expecting..." message is constructed based on alternatives that were available along the path that led to the parse failure; with many there were no such choices, it merely succeeded unconditionally.

I don't know that I'd describe this as either a bug or a feature, it's just sort of a quirk of how Parsec works. Error handling is not really Parsec's strength and this really doesn't seem like the first thing I'd worry about in that regard. If it bothers you sufficiently you may be better served by looking into other parsing libraries. I've heard good things about uu-parsinglib, for instance.

温柔一刀 2024-10-10 00:38:56

来自 黑线鳕< /a>

许多 p 将解析器 p 应用于零或
更多次。返回一个列表
p的返回值。

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

[补充]

啊,现在我明白你的意思了。当使用<|>(选择组合器)时,会报告期望 a 或 bmany 的实现不使用 <|>,但 sepBy 在内部使用它。

From haddock

many p applies the parser p zero or
more times. Returns a list of the
returned values of p.

So empty string is a valid input for many combinator.

[Added]

Ah, now I see your point. expecting a or b is reported when <|> (choice combinator) is used. many is implemented without using <|>, but sepBy uses it internally.

通知家属抬走 2024-10-10 00:38:56

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

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

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

This is a bug introduced in parsec-3.1. If you test with prior versions you should get an error message like this:

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

At least, that's what I get after fixing the bug :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文