"Batteries" Haskell 秒差距
"Batteries" for Parsec in Haskell
我是 Haskell 的新手,我一直在尝试使用 Parsec 编写 JSON 解析器作为练习。这大部分进展顺利,我能够用相对较少的代码解析列表和对象,这些代码也是可读的(太棒了!)。但是,对于 JSON 我还需要解析像
这样的原语
- 整数(可能有符号)
- 浮点数(可能使用科学记数法,例如“3.4e-8”)
- 字符串,例如转义引号
作为 Parsec 的一部分,我希望找到可以使用解析器来处理这些事情的东西。我得到的最接近的是 Parsec.Tokens 模块(定义 integer
和朋友),但是那些解析器需要一个 "language definition" 似乎远远超出了我应该做的解析像 JSON -- 它似乎是为编程语言设计的。
所以我的问题是:
Parsec.Token 中的函数是正确的方法吗?如果可以,如何做出合适的语言定义?
是否在其他地方定义了 "primitive" 整数解析器等?也许在另一个包裹里?
我应该自己编写这些低级解析器吗?我可以看到自己经常重复使用它们......(模糊的科学数据格式等)
我注意到这个网站上的一个问题说 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在你实际需要的情况下。)
我是 Haskell 的新手,我一直在尝试使用 Parsec 编写 JSON 解析器作为练习。这大部分进展顺利,我能够用相对较少的代码解析列表和对象,这些代码也是可读的(太棒了!)。但是,对于 JSON 我还需要解析像
这样的原语- 整数(可能有符号)
- 浮点数(可能使用科学记数法,例如“3.4e-8”)
- 字符串,例如转义引号
作为 Parsec 的一部分,我希望找到可以使用解析器来处理这些事情的东西。我得到的最接近的是 Parsec.Tokens 模块(定义 integer
和朋友),但是那些解析器需要一个 "language definition" 似乎远远超出了我应该做的解析像 JSON -- 它似乎是为编程语言设计的。
所以我的问题是:
Parsec.Token 中的函数是正确的方法吗?如果可以,如何做出合适的语言定义?
是否在其他地方定义了 "primitive" 整数解析器等?也许在另一个包裹里?
我应该自己编写这些低级解析器吗?我可以看到自己经常重复使用它们......(模糊的科学数据格式等)
我注意到这个网站上的一个问题说 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. 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在你实际需要的情况下。)