5

fslex および fsyacc ツールは現在、2 段階のコンパイルを必要とし、ファイルを生成してから fsc でコンパイルします。ソース ファイルが埋め込みリソースであり、プログラムによって fslex と fsyacc に供給され、生成されたコードが CodeDom を使用してオンザフライでコンパイルされていれば、これらのツールははるかに使いやすいと思います。

これは実現可能ですか?もしそうなら、これを実装するには何が必要ですか?

4

2 に答える 2

4

ジョン、これは素晴らしい質問です。実際、 fsharp-tools (F# 用の新しいレクサーおよびパーサー ジェネレーターの実装)の設計目標の 1 つは、それらを埋め込み可能にすること、特にこのようなシナリオを可能にすることです。

今のところ、 fsharplexでこれを簡単に実行できる機能を (まだ) 実装していませんが、それで思いとどまらないでください。私はfsharplex (およびfsharp-toolsの他のツール) を多かれ少なかれ純粋に機能的なスタイルで作成したので、グローバルな状態などの問題は発生しないはずです。コンパイラ コードをハックするのは比較的簡単なはずなので、いくつかのコンビネータを使用して regex AST を構築し、コンパイラを実行してコンパイル済みの DFA を取得し、ステート マシンの IL を動的アセンブリに出力します (これを「焼き付ける」ことができます)。実行します)。

fsharpyaccは現在、コンパイル ロジックの大部分を純粋に機能的なライブラリであるGrahamに配置するアプローチを使用しています。文法分析/操作およびパーサーの DFA コンパイル アルゴリズムは汎用的で、再利用可能で、テストが容易でなければならないという考えがあります。そのため、F# を使用して言語ツールを構築したい人は誰でも、それらを構築するための共通のフレームワークを利用できます。同様に、 Grahamへの貢献/改善はfsharpyaccに簡単に戻ることができます。最終的には、これと同じアプローチを使用するようにfsharplexを変更します。これにより、NuGet パッケージを参照するだけで正規表現コンパイラを独自のコードに埋め込むことができます (DFA から IL を生成するコードを記述するだけで済みます)。

fsharplexfsharpyaccは MEF を使用して、さまざまなバックエンドをプラグインできるようにします。今のところ、それらはターゲットfslexを絞っているだけでfsyacc、互換性の理由もありますが、将来的にパフォーマンスを向上させるために、(現在のテーブルベースのバックエンドではなく) コードベースのバックエンドを実装したいと考えています.

更新 -- あなたの質問を読み直したところ、*.fslおよび*.fsyファイル自体を埋め込み、実行時にそれぞれのコンパイラを呼び出す必要があることに気付きました。これは、ツールをコンパイルし、独自のプロジェクトからアセンブリを参照することで実現できます。IIRC では、両方のコンパイラでエントリ ポイントを公開して、外部コードから呼び出すことができるようにしました。メイン エントリ ポイント (たとえば、コンソールからツールを呼び出したときに実行されるもの) は、コマンドライン引数を解析して、この「外部」エントリ ポイントに渡すだけです。

*.fslただし、および*.fsyファイルを直接埋め込むには問題が 1 つあります。それらを埋め込み、実行時にfsharplexfsharpyaccを介して実行すると、ユーザー定義のアクション (たとえば、レクサーまたはパーサーのルールが一致したときに実行されるコード) は引き続き F# ソース コードとして指定されます。それらを実行可能コードにコンパイルする方法を決定する必要があります。

于 2013-10-05T11:47:23.710 に答える
2

言語との完全な統合のために、式ツリー (F# の LISP "eval") または類似のものを使用するバックエンドを備えたパーサー コンビネーターのようなインターフェイスを提供することは実行可能であるはずです。または、TypeProvider です。多くのオプションがあります。テーブル生成が高価な計算である場合はCache、ディスク キャッシュなどを提供することでキャッシュできます。

時間、献身、専門知識の不足以外に、(非モナディック) パーサー コンビネーターのようなインターフェイスを備えたツールを持ちながら、効率的なコンパイル済みの実装を妨げるものはないと思います。

時々、このお気に入りのプロジェクトに戻って、コンビネータを使用してソースで指定された正規表現 (およびレクサー) を最適化し、ステート マシンにコンパイルする代数的アプローチで遊んでいます。効率化のためのいくつかの重要な部分がまだ欠けていますが、次のとおりです。

https://github.com/toyvo/ocaml-regex-algebraic

于 2013-10-05T03:16:30.407 に答える