3

parsec-3.1.0 ( http://hackage.haskell.org/package/parsec-3.1.0 ) は、どのトークン タイプでも機能します。ただし、Char データ型に対してのみ定義されている Text.Parsec.Char.satisfy のようなコンビネータがあります。これ以上一般的なものはないようです。

独自のバージョンを定義する必要がありますか、それとも何か見逃していましたか?

おそらく、Haskell には次のことを可能にするさまざまなパーサー ライブラリがあります。

  • カスタム トークン タイプ
  • カスタム パーサーの状態 (ステートフル フォーマットを解析する必要があります - Wavefront OBJ)
4

1 に答える 1

4

、 、およびの一般化されたバージョンはoneOf、一般化されたから簡単に構築できます。noneOfanyCharsatisfy

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これらの一般化が欠けているように見えるかもしれませんが、ここでのこれらの一般化は、誰かのトークン型には当てはまらない可能性がある型に関する特定の仮定を行っていることに気付くでしょう。Showこれはandのインスタンスであると想定されていますが、トークンの種類が 以外の方法で表示され、トークンのクラスのメンバーシップが and 以外の方法で達成される可能性があることEqを想像できます。show==elem

最後に、トークン タイプが ではなくなったChar場合、位置を表す方法を選択して更新する方法は、トークンとストリームの表現に大きく依存します。

したがって、より一般化された形式が存在しない理由がわかります。

于 2010-03-19T05:48:34.000 に答える