Haskell中Parsec的"电池"

jos*_*inb 4 parsing haskell parsec

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

  • 整数(可能已签名)
  • 浮动(可能使用科学记数法,如"3.4e-8")
  • 带有例如转义引号的字符串

我希望找到准备使用解析器作为Parsec的一部分.我得到的最接近的是Parsec.Tokens模块(定义integer和朋友),但是这些解析器需要一个"语言定义",这似乎超出了解析像JSON这样简单的东西 - 它似乎是为编程语言.

所以我的问题是:

  1. Parsec.Token中的函数是正确的方法吗?如果是这样,如何制作合适的语言定义?

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

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

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

相关问题:

如何让Parsec让我调用`read` :: Int?

如何使用parsec解析Integer

dup*_*ode 6

Parsec.Token中的函数是正确的方法吗?

对,他们是.如果您不关心语言定义指定细节(即您不打算使用依赖于它们的解析器,例如identifierreserved),则只需使用emptyDef默认值:

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

lexer = P.makeTokenParser emptyDef

integer = P.integer lexer
Run Code Online (Sandbox Code Playgroud)

正如您所指出的,这对您的用例来说是不必要的笨拙.值得一提的是,megaparsec(参见Alec的建议)提供了一个integer没有仪式的相应解析器.(另一方面,megaparsec不会尝试烘焙支持例如保留字,但在您实际需要的情况下实现并不困难.)