2016-05-30 1 views
14

言語でファイルを解析したいとします。X。本当に、私はその中の情報のほんの一部にしか関心がありません。その目的のためにHaskellの多くのeDSL(例えばMegaparsec)にパーサを書くのは簡単です。容易に機能getFoo :: Text -> Maybe Fooを生じさせる正確な入力を再構築できるパーサーを作成する方法は確立されていますか?

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

parseFoo :: Parsec Text Foo 
parseFoo = ... 

しかし、今、私も同じように変更しますFoo情報のソースは、つまりは基本的に私はそれをすることによってそれを行うことが可能です

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

性質を持つ

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

を実装したいですパーサーの結果をレンズのようなものに変更する

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

しかし、定義がもっと煩雑になる–私はただ無関係の情報を光沢させることはできませんが、すべてのstringサブパルスのマッチを保存し、手動で再構成する必要があります。

これは、文字列再構成をパーサーモナドの周囲にあるStateTレイヤーに保つことによっていくらか自動化できますが、既存のプリミティブパーサーを使用することはできません。

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

+0

は、一般的に「抽象構文木」を構築し、すべての書式設定が省略されます。あなたが探しているのは "具体的な構文木"です。私はこれを構築するライブラリを知らない。 – sapanoia

答えて

1

ソリューションはHaskellで実装されていますか?私は1つを知らない。彼らは存在するかもしれない。

一般に、収集されたトークンに「書式」情報を格納することによって、元のプログラムに合った正当なバージョンを再生するのに十分な情報を格納できます。制限内で、フォーマット情報トークンの元の文字列です。それを近似すると、正確に答えが少なくなります。

パーズツリー内に明示的なトークンとして空白を残しておけば、それを再生成することもできます。それが役に立つかどうかは、アプリケーションによって異なります。一般に、私はこれが過度のものだと思う。キャプチャする方法と、再生成する方法を何/上

詳細は私のSOの回答で見つけることができます:Compiling an AST back to source code

1

これは、「双方向変換」の場合ですか?例えば、特定の、「可逆構文の説明:統一解析とプリティプリントする」のhttp://ceur-ws.org/Vol-1571/

Rendelとオスターマンによって http://dblp.org/rec/conf/haskell/RendelO10、Haskellのシンポジウム2010ライブラリの解析(参照http://lambda-the-ultimate.org/node/4191

+1

はい、それは素晴らしい仕事です。それは本当に私の問題に対処していますか?私はこれらの可逆パーサーが主に '解析する 'ことを保証しているという印象を受けました。 ≡id'を印刷する。彼らはまた 'printについて何か保証することができますか?解析? – leftaroundabout

+0

かなり印刷しているなら、 'print(parse s)=== s'モジュロ空白?正確な印刷のために、基本的なプリンタ/パーサを構築することはさらに簡単になります。 – d8d0d65b3f7cf42

+2

私のアプリケーションでは、ファイルのほとんどが空白(または「コメント」)です。なぜなら、実際にほとんどのコンテンツを細かく解析するのではなく、いくつかの変数しか解析しないからです。 – leftaroundabout

関連する問題