2

値を変数名にバインドする edsl を C++ で書くことは可能ですか? たとえば、次のように記述できる edsl を Haskell で記述できます(この質問も参照してください)

prog3 :: StackProg Expr
prog3 = do
  push (IntL 3)
  push (IntL 4)
  a <- pop
  b <- pop
  return (Plus a b)

aそして、これにより、とbが変数である AST が生成されます。C ++で同様のことが可能ですか? したい(重要度順)

  • 結果として得られる edsl の受け入れ可能な構文、
  • 賢明なAST
  • オブジェクト (DSL) 言語の型安全性
  • わかりやすいメカニズム。
4

2 に答える 2

2

有効な C++ 式の構文を生成したい場合 (おそらくすべての C++ 式のサブセットとして、do 記法がモナド操作に制限されるように)、それらを静的に検証して消費する場合、最善の策はBoost.Protoです。端的に言えば、EDSL を書いて記述するのは、それ自体が EDSL です。

詳しい使い方は書きません。使い方を習得するのは難しいかもしれませんが、特に C++ メタプログラミングに慣れていない場合は、ドキュメントが優れており、文法を書いたことがある場合は、マークを見つけることができると思います. 私の別の回答では、単純な算術式のみを受け入れ、導関数を計算するためにそれらを消費する文法で EDSL を書く方法について誰かに説明しました。

あなたの正確な質問に関しては、答えは短い「いいえ、それはできません」か、長い「Boost.Phoenixが示すようにある程度はできますが、おそらくそうではありません」のいずれかでなければならないのではないかと思います.不可解なエラーや EDSL ユーザーの余分なコンパイル時間を考慮して、時間をかけて実装する価値があります。」これに対する私の推論は、あなたがやりたいことは 2 つのレベルに当てはまるということです。do 記法は Haskell 固有の機能ですが、構文ツリーを消費し、EDSL 自体のレベルでそれにセマンティクスを与えます。

たまたま、典型的な Proto スタイルの EDSL は有効な C++ 式であり、言語はそのレベルでのスコープを提供しておらず、変数は別のステートメントで宣言されています。たとえば、と は Phoenix が提供する宣言された C++ 変数であるため、_a + _b有効な C++ フラグメントですが、とはバインドされていないため、EDSL では有効なプログラムではありません。はい、エラーはキャッチされますが、自分で実装する必要があります。比較すると、do 記法は Haskell の一部であるため、どの EDSL も無料で継承します。つまり、は単独では決して有効ではありません - someと someが必要です。_a_b_a_breturn (a + b)ab

ただし、留意すべき点がいくつかあります。C++11 はラムダ式を提供するため、実際にはここでスコープを取得できますが、EDSL ではそれらは不透明になり、構文ツリーには変数のみが表示されます。一部の内省により、その変数が一部の型で呼び出し可能であることが明らかになる場合がありますが、それだけです。ラムダが EDSL で値を返すことを要求したとしても、他に何ができるかわかりません。これは常に心配する価値があるとは限りません。一部の EDSL には完全に適していると言えます。

同様に、C++11 では、EDSL 式の一部を「因数分解」することがはるかに簡単になります。a <- fooこれは do 表記の砂糖とはあまり同等ではありませんが、 と同等let a = fooです。したがって、実際にはそれほど困難なく、次のことを「正しいこと」にすることができます。

auto double_pop = make_tuple(pop(), pop());
auto program = (push(3), push(4), consume(double_pop));

これは、一義的で不自然な次のものと同等である可能性があります。

program = do
  let a = pop
  return consume `ap` a `ap` a

(Boost.Proto は C++03 ライブラリとして開始されたため、C++11 を使用する前にドキュメントをauto熟読してください。IIRC には警告があります。)

于 2013-02-22T21:04:14.150 に答える
2

いいえ、C++ で直接モデル化することはできません。ただし、C++ では、Lua などの他のエンジンを埋め込むことができます。Lua は拡張エンジンとしてよく使用され、DSL に適しています。

この回答も StackOVerflow で確認してください

Lua を C++ に埋め込む手順:

  1. これは Lua の Web ページです
  2. ソースはこちらからダウンロードしてください
  3. Lua を C++ アプリケーションに統合します
于 2013-02-21T09:07:17.797 に答える