gpt4 book ai didi

parsing - 如何使用megaparsec报告多个错误?

转载 作者:行者123 更新时间:2023-12-04 11:27:18 26 4
gpt4 key购买 nike

每个 megaparsec 文档,"Since version 8, reporting multiple parse errors at once has become much easier."我一直无法找到一个这样做的例子。我找到的唯一一个是 this .然而,它只显示了如何解析换行符分隔的玩具语言,也没有显示如何 combine multiple errors进入 ParseErrorBundle。此 SO discussion不是决定性的。

最佳答案

您要使用 withRecoveryregisterParseError 一起从 Megaparsec 生成的错误中恢复(或 registerFailureregisterFancyFailure )“注册”这些错误(或您自己生成的错误)以进行延迟处理。

解析结束时,如果没有注册解析错误,则解析成功,如果注册了一个或多个解析错误,则将它们全部打印出来。如果您注册解析错误,然后还触发了未恢复的错误,解析将立即终止,并且将打印所有已注册的错误和最终未恢复的错误。

这是一个非常简单的示例,用于解析以逗号分隔的数字列表:

import Data.Void
import Text.Megaparsec
import Text.Megaparsec.Char

type Parser = Parsec Void String

numbers :: Parser [Int]
numbers = sepBy number comma <* eof
where number = read <$> some digitChar
comma = recover $ char ','
-- recover to next comma
recover = withRecovery $ \e -> do
registerParseError e
some (anySingleBut ',')
char ','

在良好的输入:
> parseTest numbers "1,2,3,4,5"
[1,2,3,4,5]

并在输入时出现多个错误:
> parseTest numbers "1.2,3e5,4,5x"
1:2:
|
1 | 1.2,3e5,4,5x
| ^
unexpected '.'
expecting ','

1:6:
|
1 | 1.2,3e5,4,5x
| ^
unexpected 'e'
expecting ','

1:12:
|
1 | 1.2,3e5,4,5x
| ^
unexpected 'x'
expecting ',', digit, or end of input

这里有一些微妙之处。对于以下情况,仅处理第一个解析错误:
> parseTest numbers "1,2,e,4,5x"
1:5:
|
1 | 1,2,e,4,5x
| ^
unexpected 'e'
expecting digit

并且您必须仔细研究解析器以了解原因。 sepBy成功申请 numbercomma解析器以交替顺序解析 "1,2," .当它到达 e ,它适用于 number失败的解析器(因为 some digitChar 需要至少一位字符)。这是一个无法恢复的错误,所以解析立即结束,没有记录其他错误,所以只打印一个错误。

另外,如果您删除了 <* eof来自 numbers的定义(例如,使其成为更大解析器的一部分),您会发现:
> parseTest numbers "1,2,3.4,5"

在该期间给出解析错误,但是:
> parseTest numbers "1,2,3.4"

解析很好。另一方面:
> parseTest numbers "1,2,3.4\n hundreds of lines without commas\nfinal line, with comma"

在文件末尾给出句点和逗号的解析错误。

问题在于 comma解析器由 sepBy 使用以确定逗号分隔的数字列表何时结束。如果解析器成功(它可以通过恢复来完成,吞噬数百行到下一个逗号), sepBy会尝试继续运行;如果解析器失败(最初是因为恢复代码在扫描整个文件后找不到逗号), sepBy将完成。

最终,编写可恢复的解析器有点棘手。

关于parsing - 如何使用megaparsec报告多个错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59640023/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com