"Batteries" Haskell 秒差距

"Batteries" for Parsec in Haskell

我是 Haskell 的新手,我一直在尝试使用 Parsec 编写 JSON 解析器作为练习。这大部分进展顺利,我能够用相对较少的代码解析列表和对象,这些代码也是可读的(太棒了!)。但是,对于 JSON 我还需要解析像

这样的原语

作为 Parsec 的一部分,我希望找到可以使用解析器来处理这些事情的东西。我得到的最接近的是 Parsec.Tokens 模块(定义 integer 和朋友),但是那些解析器需要一个 "language definition" 似乎远远超出了我应该做的解析像 JSON -- 它似乎是为编程语言设计的。

所以我的问题是:

  1. Parsec.Token 中的函数是正确的方法吗?如果可以,如何做出合适的语言定义?

  2. 是否在其他地方定义了 "primitive" 整数解析器等?也许在另一个包裹里?

  3. 我应该自己编写这些低级解析器吗?我可以看到自己经常重复使用它们......(模糊的科学数据格式等)

我注意到这个网站上的一个问题说 Megaparsec 包含这些原语 [1],但我想这些不能与 parsec 一起使用。

相关问题:

How do I get Parsec to let me call `read` :: Int?

How to parse an Integer with parsec

Are the functions in Parsec.Token the right way to go here?

是的,他们是。如果您不关心 minutiae specified by a language definition (i.e. you don't plan to use the parsers which depend on them, such as identifier or reserved), just use emptyDef 作为默认值:

import Text.Parsec
import qualified Text.Parsec.Token as P
import Text.Parsec.Language (emptyDef)

lexer = P.makeTokenParser emptyDef

integer = P.integer lexer

正如您所指出的,这对于您的用例来说显得过于笨拙。值得一提的是megaparsec(cf. ) provides a corresponding integer parser without the ceremony. (The flip side is that megaparsec doesn't try to bake in support for e.g. reserved words, but that isn't difficult to implement在你实际需要的情况下。)