具有自定义标记数据类型的 parsec-3.1.0

发布于 2024-08-25 22:02:50 字数 372 浏览 6 评论 0原文

parsec-3.1.0 ( http://hackage.haskell.org/package/parsec- 3.1.0) 适用于任何令牌类型。但是,有一些组合器(例如 Text.Parsec.Char.satisfy)仅为 Char 数据类型定义。似乎没有更通用的对应物可用。

我应该定义自己的版本还是我错过了什么?

也许 Haskell 中有不同的解析器库允许:

  • 自定义令牌类型
  • 自定义解析器状态(我需要解析有状态格式 - Wavefront OBJ)

parsec-3.1.0 ( http://hackage.haskell.org/package/parsec-3.1.0 )
works with any token type. However there are combinators like Text.Parsec.Char.satisfy that are only defined for Char datatype. There doesn't seem to be any more general counterpart available.

Should I define my own versions or did I miss something?

Perhaps there are different parser libraries in Haskell that allows:

  • custom token types
  • custom parser state (I need to parse stateful format - Wavefront OBJ)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深陷 2024-09-01 22:02:50

oneOfnoneOfanyChar 的通用版本可以根据通用的 satisfy 构建,非常简单

oneOfT :: (Eq t, Show t, Stream s m t) => [t] -> ParsecT s u m t
oneOfT ts = satisfyT (`elem` ts)

noneOfT :: (Eq t, Show t, Stream s m t) => [t] -> ParsecT s u m t
noneOfT ts = satisfyT (not . (`elem` ts))

anyT :: (Show t, Stream s m t) => ParsecT s u m t
anyT = satisfyT (const True)

satisfyT :: (Show t, Stream s m t) => (t -> Bool) -> ParsecT s u m t
satisfyT p = tokenPrim showTok nextPos testTok
    where
      showTok t     = show t
      testTok t     = if p t then Just t else Nothing
      nextPos p t s = -- however you update position for your token stream

:可能看起来这些概括似乎缺失,但您会注意到这里的这些概括对类型 t 做出了某些假设,但对于某人的令牌类型来说可能并不正确。它被假定为 ShowEq 的实例,但我可以想象它们以除 show 之外的其他方式显示的令牌类型,并且令牌类中的成员资格可以通过 ==elem 之外的某些方法来实现。

最后,一旦您的令牌类型不再是 Char,您选择如何表示位置并因此更新它,在很大程度上取决于您对令牌和流的表示。

因此,我可以理解为什么不存在更通用的形式。

Generalized versions of oneOf, noneOf, and anyChar can be built out of a generalized satisfy, easily enough:

oneOfT :: (Eq t, Show t, Stream s m t) => [t] -> ParsecT s u m t
oneOfT ts = satisfyT (`elem` ts)

noneOfT :: (Eq t, Show t, Stream s m t) => [t] -> ParsecT s u m t
noneOfT ts = satisfyT (not . (`elem` ts))

anyT :: (Show t, Stream s m t) => ParsecT s u m t
anyT = satisfyT (const True)

satisfyT :: (Show t, Stream s m t) => (t -> Bool) -> ParsecT s u m t
satisfyT p = tokenPrim showTok nextPos testTok
    where
      showTok t     = show t
      testTok t     = if p t then Just t else Nothing
      nextPos p t s = -- however you update position for your token stream

It might seem that the generalization of these seems missing, but you'll notice that these generalizations here make certain assumptions about the type t that may not be true for someone's token type. It is assumed to be an instance of Show and Eq, yet I can imagine token types for which they are displayed some other way than show, and that membership in a class of tokens might be achieved via some method other than == and elem.

Lastly, once your token type is no longer a Char, how you choose to represent position, and thus updated it, is highly dependent on your representation of tokens and streams.

Hence, I can see why a more generalized form doesn't exist.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文