2

重複の可能性:
C++ コード ランタイムをコンパイルして実行する

ユーザーからの式を文字列として入力し、それを呼び出し可能な C++ 関数にコンパイルしたいと考えています。これを簡単に行えるツールはありますか?

基本的に、式ツリーを呼び出し可能なメソッド C# にコンパイルするにはどうすればよいですか? これをC#ではなくC++で行う必要があることを除いて、私がやりたいことと似ているようです。

確かに、lex と yacc を使用して一種の一般的なエバリュエーターを作成できますが、毎回文字列を解析する必要はありません。基本的に、この式は重要な内部ループで実行されるため、実行時に「コンパイル」する方法を探しています。

4

4 に答える 4

1

式を抽象構文ツリーに解析してウォークするか、インプレースで評価する必要があります。このようなものは、単純な数式のニーズを満たす必要があります。

于 2012-08-30T19:32:21.780 に答える
1

簡単ではありません... 私の 2 セントが必要な場合は、次の手順に従います。

  1. 実行時に作成する必要があるコードのインターフェイスを作成します。最初に、できることのインターフェイスを作成します。たとえば、クラスは、インターフェイスを表す純粋な仮想基本クラスから継承する必要があります。プログラムが任意のコードではなく、特定の方法で作成されたコードを使用するように注意してください。
  2. プログラム内からコンパイラを呼び出します。コンパイラは、ソース コードからライブラリを作成する必要があります。どこかに保存した定義済みのプロジェクトを使用して、そのソース ファイルを独自のものに置き換えることができます。そのため、適切なライブラリを簡単に入手できます。
  3. ライブラリを見つけることができる指定されたソースに置きます。
  4. 実行時にライブラリをロードします。検索すると、リンク時だけでなく、実行時に動的ライブラリをロードできることがわかります (この方法で、たとえば、プログラムのプラグインを作成できます)。したがって、プログラムはライブラリをロードして使用できます。たとえば、ここでいくつかの情報を見つけることができます。

しかし、他の人が言ったように、それは簡単な仕事ではありません。

編集: 別の解決策は、boost::spirit::qi のようなパーサーをチェックすることです。これはよく使用されており、非常に役立つ結果が得られます。

于 2012-08-30T19:53:34.457 に答える
1

ミニインタプリタを書くことができます。コマンドは c++ と同じです (すべてではありません)。もちろん、コンパイラはそれを最適化しますが、どれだけ最適化するかはわかりません。私はqbasic(mov、add、sub ...)でのアセンブリのためにそれを行いましたが、インタープリターのインタープリターであるため、かなり遅かったです:D

進化計算とフィットネス関数について考えましたか? 一見の価値あり。

于 2012-08-30T19:26:31.133 に答える
0

解析された式ツリーを表すデータ構造を作成できます。実行時にそれを評価するオーバーヘッドは、毎回文字列を解析する場合に比べて小さくなります。

実際にC++で呼び出し可能なメソッドを取得することは、オブジェクトコードを生成し、それをプログラムに動的にロードする必要があるという点で、非常に困難です。これは、コンパイラツールチェーン全体が行うことの多くを複製します。

于 2012-08-30T19:30:20.050 に答える