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

Parsing 如何使用megaparsec报告多个错误?,parsing,haskell,megaparsec,Parsing,Haskell,Megaparsec,根据megaparsec文档,我还没有找到一个这样做的例子。我只找到一个。然而,它只显示了如何解析以换行符分隔的玩具语言,也没有显示如何解析为ParseErrorBundle。这不是决定性的。您希望使用带恢复功能的从Megaparsec生成的错误中恢复,并与registerParseError(或registerFailure或registerFailure)一起“注册”这些错误(或您自己生成的错误)以进行延迟处理 在解析结束时,如果没有注册任何解析错误,则解析成功,而如果注册了一个或多个解析错

根据megaparsec文档,我还没有找到一个这样做的例子。我只找到一个。然而,它只显示了如何解析以换行符分隔的玩具语言,也没有显示如何解析为ParseErrorBundle。这不是决定性的。

您希望使用带恢复功能的
从Megaparsec生成的错误中恢复,并与
registerParseError
(或
registerFailure
registerFailure
)一起“注册”这些错误(或您自己生成的错误)以进行延迟处理

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

下面是一个解析逗号分隔的数字列表的非常简单的示例:

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,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
您必须仔细研究解析器以了解原因。
sebby
以交替顺序成功地应用
number
comma
解析器来解析
“1,2”
。当到达
e
时,它应用
number
解析器,但该解析器失败(因为
某些digitChar
至少需要一个数字字符)。这是一个未恢复的错误,因此解析立即结束,没有注册其他错误,因此只打印一个错误

此外,如果您删除了

> parseTest numbers "1,2,e,4,5x"
1:5:
  |
1 | 1,2,e,4,5x
  |     ^
unexpected 'e'
expecting digit
> 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"