15

言語Xでファイルを解析したいとします。本当に、私はその中の情報のほんの一部にしか興味がありません. その目的のために、Haskell の多くの eDSL の 1 つ (Megaparsec など) でパーサーを書くのは簡単です。

data Foo = Foo Int  -- the information I'm after.

parseFoo :: Parsec Text Foo
parseFoo = ...

それはすぐに関数を生じさせますgetFoo :: Text -> Maybe Foo

しかし、今は情報のソースも変更Fooしたいと思います。つまり、基本的に実装したいです

changeFoo :: (Foo -> Foo) -> Text -> Text

プロパティで

changeFoo id ≡ id
getFoo . changeFoo f ≡ fmap f . getFoo

パーサーの結果をレンズのようなものに変更することでそれを行うことができます

parseFoo :: Parsec Text (Foo, Foo -> Text)
parseFoo = ...

しかし、それは定義を非常に面倒なものにします。関連性のない情報をただ単に見過ごすことはできず、すべてのstringサブパースの一致を保存し、手動で再構築する必要があります。

これは、文字列の再構築をStateTパーサー モナドの周りのレイヤーに保持することである程度自動化できますが、既存のプリミティブ パーサーをそのまま使用することはできませんでした。

この問題に対する既存の解​​決策はありますか?

4

2 に答える 2

1

Haskell で実装されたソリューション? 私はそれを知りません。それらは存在する可能性があります。

ただし、一般的には、収集したトークンを使用して「フォーマット」情報を保存することにより、オリジナルにある程度似たプログラムの正当なバージョンを再生成するのに十分な情報を保存できます。制限では、フォーマット情報トークンの元の文字列です。それを近似すると、結果の精度が低下します。

解析ツリーで空白を明示的なトークンとして保持すると、制限内でそれを再生成することさえできます。それが役立つかどうかは、アプリケーションに依存する可能性があります。一般的に、これはやり過ぎだと思います。

何を/どのようにキャプチャし、どのように再生成するかについての詳細は、私の SO の回答: Compiling an AST back to source code にあります。

于 2016-05-30T16:06:36.093 に答える