haskell - "Unexpected end of input - expecting end of input"(秒差距)

标签 haskell parsec

考虑这个parsec解析器(放入文件parsec-eof-test.hs):

import Text.Parsec
import Text.Parsec.String

main = do
  x <- parse (manyTill anyChar eof >> fail "forced fail") "" <$> readFile "parsec-eof-test.hs"
  print (x :: Either ParseError String)

如果你运行它,你会得到:

Left (line 7, column 1):
unexpected end of input
expecting end of input
forced fail

意外的输入结束 - 期望输入结束 - 这没有任何意义,这是一个矛盾。

这是怎么回事?

这是秒差距的一个错误默认值,还是我正在查看的实际上是秒差距在解析时出现的一些潜在错误?

由于我的解析器 manyTill anyChar eof 消耗输入,我希望发出的唯一错误消息是强制失败。我错过了什么?

最佳答案

按预期与 Megaparsec 配合使用:

module Main (main) where

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

type Parser = Parsec Void String

main :: IO ()
main = do
  parseTest' (manyTill anyChar eof >> fail "forced fail" :: Parser String)
    "somethingsomething"

当我运行它时,我得到:

1:19:
  |
1 | somethingsomething
  |                   ^
forced fail

您收到秒差距错误消息的原因是(如果我没记错的话)秒差距内部使用了很多有问题的“约定”。一种这样的约定是“意外的输入结束”由不存在其他意外的项目来表示。当然,这只会带来麻烦。当我开始将 Parsec 转换为 Megaparsec 时,我很害怕这是 Haskell 的“工业实力”解析库。

为什么你没有得到其他意想不到的组件?因为 fail 实际上会导致您的解析器失败(正如您所期望的),因此不会生成任何它们。它也不会生成预期的组件,但由于此功能,这些组件(在您的情况下是“预期输入结束”部分)会被拾取并合并到您的 fail 错误消息中:

λ> parseTest (many (char 'a') *> many (char 'b') *> empty) ""
parse error at (line 1, column 1):
unexpected end of input
expecting "a" or "b"

秒差距足够聪明,可以发现“a”和“b”在这里仍然是可能的。在这种情况下是有道理的,但会让你失望失败

秒差距中的错误消息是一件疯狂的事情,如果你开始批判性地阅读代码,那绝对是疯狂的。

附注我无意刻薄,但我们就称铲子为铲子吧。

关于haskell - "Unexpected end of input - expecting end of input"(秒差距),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47514596/

相关文章:

Haskell:为什么我的斐波那契数列实现效率低下?

parsing - 使用 Haskell/Parsec 转换\"into "

haskell - 了解 Parsec 中的 SourceName

arrays - 使用数组在 haskell 中解析方案向量

haskell - 如何删除reactive-banana中的重复事件

haskell - 将值列表插入具有持久性的数据库中

list - 如何递归地请求输入并返回列表

haskell - 如何在 Haskell 中计算表达式

haskell - 学习 haskell `parsec` : trying to rewrite `words` function as a basic exercise

c++ - C++ 函数的 parsec 解析器?