haskell - 用 `ParsecT` 进行排列解析?

标签 haskell monads monad-transformers parsec parser-combinators

我有一个使用 permute 的文件解析器来自 parsec 结合各种Parser秒。看起来像 permute只允许 Identity monad,我确信它会降低算法的复杂性。

现在我正在尝试将我所有的解析代码转换为使用 MyErrorClass m => ParsecT String () m , 其中Monad m => MyErrorClass mclass具有特殊的错误处理。具体来说,使用 permute 的代码现在需要组合需要 MyErrorClass m 的解析器这样他们就可以提供结构化错误,而不仅仅是使用 fail . (permute 仅在解析编程语言的模块配置文件时使用。文件格式允许嵌入某些语言结构,重用编译器的解析器。)

我只用permute在 3 个地方,这个数字不太可能增加,所以为这 3 个中的每一个组合一些一次性函数并不是不可能的。或者,我可以删除字段排序的灵 active ,但我宁愿不。


在我做任何重要的事情之前,我是否缺少一个简单的解决方案 parsec ?也许我能以某种方式填充ParsecT String () m进入permute来自 parsers 而不是 parsec ? (这会增加依赖性,但可能是值得的。)


编辑:

以下是关于为什么结构化错误对解析有用的一些背景知识。

在大多数情况下,我分别进行解析和验证。例如,在解析成功后检查重复的符号定义。

我经常遇到类似于 expected //, /* or argument type 的解析错误,并且可能需要一段时间(对我来说,语言创建者)才能理解正在调用的解析器。

MyErrorClass允许构造错误消息,例如

("In parsing of function declaration for " ++ show f) ??> do
  -- parse the components of function f
  -- any error messages here will be nested under the message above

能够像这样添加上下文至少会告诉用户解析器在失败时试图做什么。

最后,使用 MyErrorClass还将允许 try 无法抑制的快速失败错误或 <|> . (在一些地方,我有使用过时语法的明确错误消息。)

最佳答案

正如@danidiaz 所建议的那样, parser-combinators 轻松解决了置换 ParsecT文字问题.

需要注意的是,使用 ParsecTMonad m 转换 错误(甚至它自己的错误)并不是特别有用,除了能够使用不能被 <|> 忽略的快速失败错误之外和 try .

  • 您不能“降级”ParsecT 的错误状态至 m自己的错误类型,因为(AFAIK)无法访问 ParsecT 的当前错误状态.

  • ParsecT缺少与 StateT 相当的东西的 mapStateT .这意味着无法转换存储在 m 中的错误。没有使用 runPT 实际执行解析器(等),这是不可能进行中间解析的。

总而言之,ParsecT不漏mStateT 相同做一些m无法从内部访问的功能 ParsecT .

关于haskell - 用 `ParsecT` 进行排列解析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65160666/

相关文章:

haskell - Applicative 的 ghci 特例?

haskell - 为什么有一个用于 exceptT 的 MonadMask 实例?

haskell - 在 Haskell 中对异构列表进行类型安全查找

python - 将函数映射到元组中的元素

haskell - 什么编程任务为您提供了 monad 的突破?

haskell - 无限输入的非确定性

haskell - 大型 Monad 堆栈的示例

haskell - 尴尬的单子(monad)变压器堆栈

haskell - 如何在 Haskell 98 下编写多态函数

parsing - Haskell 解析为自定义数据类型