問題タブ [boost-proto]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - Boost Phoenix 式を文字列化できますか?
Boost Phoenix 式を C++ の代表的な文字列に変換できますか? ができた:
次に、次のようなものを含む文字列を生成する可能性があります。
この例には荒削りな部分があることは承知していますが、これらの線に沿って何かが試みられたのでしょうか?
c++ - カスタム型を式ツリーに非介入的に置き換える
既存のコード プロジェクトに遅延評価を導入しようとしています。プロジェクトのコアは基本的に、カスタム型を使用した大量の計算で構成されています (これは double のように機能しますが、バックグラウンドで追加の作業を行います)。
私たちの目標は、既存の式を最適化するために、boost proto を使用して遅延評価の概念を導入することです。
制限:
- 既存の計算は変更できません
- 使用される型は typedef によって定義されるため、型自体を置き換えることが可能です
簡単な概念実証を実装しようとしましたが、コードが意図したとおりに動作するように管理できませんでした。これまでに得たものは次のとおりです。
私たちの主な問題は、リテラルと式の両方で同様に機能する型を定義できないことです。この例では、c は proto::terminal 型の Expression であり、式の代入を無視します。auto を使用して式を保存すると、正常に機能します。また、直接初期化することはできません。
問題を正しく理解していれば、式とリテラルに 2 つの異なる型が必要になりますが、既存の型しか変更できないため、これは不可能です。
また、BOOST_PROTO_DEFINE_OPERATORS(...) を使用してカスタム型を非侵入型端末にするなど、他のオプションも調べましたが、遅延代入も不可能です。
それで、私たちの質問は、私たちが望むものを達成できるかどうか、または遅延評価を導入するために既存のコードを変更する必要があるかどうかです.
助けてくれてありがとう、マティアスenter code here
c++ - Boost Phoenix のネストされた let ブロック内の変数の隠蔽
「内部」ローカル変数が「外部」ローカル変数を隠している場合、Boost Phoenix のネストされた let ブロックで問題が発生します。ドキュメントhereの「可視性」の例でも、ここに示されています。
次のようなエラーが表示されます。
フェニックスのインナーレットブロックのスコープ内でそのような変数を「シャドウ」する方法を知っている人はいますか? 現在、GCC バージョン 4.8 スナップショットで Ubuntu 13.04 を使用しています。クラン 3.2; ブースト 1.49; Boost 1.53も。
c++ - Boost Proto 子式のタグ タイプの取得
Boost Proto 式のうち、proto_tag
メンバーを期待できないのはいつですか? たとえば、次のいずれかの方法を使用して、プレースホルダーのタグの種類について問い合わせることができます。
しかし、式の子のタグ タイプについて尋ねると、proto_tag
メンバーが存在しないように見えます。次のコードの 3 行目でエラーが発生します。
Clang および GCC のエラーは、問題の型がクラス、名前空間、またはスコープ付きの列挙型ではないことを報告します。Clang 3.2、GCC 4.7.2、および Boost 1.53 を使用しています。
c++ - Boost Phoenix でローカル変数の型を取得する
スコープ付き Boost Phoenix ステートメント内で使用されるローカル変数の型を取得するにはどうすればよいですか? Phoenix と Proto を使用して、Phoenix 式のさまざまな側面を抽出できます。たとえば、次のコードはアリティ (3) を公開します。タグタイプ (lambda_actor); Phoenix ラムダ式の子 2 タグ タイプ (shift_left):
ローカル変数の型を取得するにはどうすればよいですか。この例では:_a
および_b
?
c++ - DSL 入力を高性能表現テンプレートに解析する方法
(タイトルと本文の両方を編集し、発生したスピンオフの質問を作成しました)
このアプリケーションでは、論理式の単純な DSL を解析するのが理想的です。ただし、これを行う方法は、(実行時に) 入力テキストを解析して、式を遅延評価された構造 (式テンプレート) に変換し、後でパフォーマンスに敏感なコード内で使用できるようにすることです。
理想的には、この手法を使用して可能な限り迅速に評価を行うのが理想的です。この手法は、毎回プレースホルダーに異なる値を代入して何度も使用されるためです。式テンプレートが、指定された入力テキスト文字列と同じ関数をモデル化するハードコードされた関数と同等のパフォーマンスを発揮するとは思っていません。つまり、実際にコンパイルするルートを下る必要はありません。実行中のプログラム(他の質問には動的ライブラリのコンパイル/ロードが含まれると思います)。
ブーストから例を読んだ私自身の考えは、ブースト::精神を使用して入力テキストの解析を行うことができ、必要な文法を開発できると確信しています。ただし、パーサーを boost::proto と組み合わせて、実行可能な式テンプレートを作成する方法がわかりません。私が見た精神のほとんどの例は、単なるインタープリターであるか、ある種の構文ツリーを構築するだけで、それ以上のことはしません。私が見た proto のほとんどの例では、DSL がホスト ソース コードに埋め込まれており、文字列から最初に解釈する必要がないことを前提としています。boost::spirit が実際に boost::proto で実装されていることは承知していますが、これが問題に関連しているかどうか、またはその事実が便利な解決策を示唆しているかどうかはわかりません。
繰り返しますが、次のようなものを実現できる必要があります。
最小限の例、または後でコンテキストで評価される入力テキストから式を作成する上に構築できる小さなカーネルでさえ、本当に感謝しています。
これはここに投稿された質問とまったく同じではないと思います:ブーリアン式をブーストスピリットで解析 することは、非常に巧妙に見えますが、これが必ずしもこれを行う最速の実行方法であると確信していないためです。やがて、投稿されたすべての回答のベンチマークを実行しようとします。
c++ - Boost.Proto を使用した Eigen 式テンプレートの構築
Boost.Proto を使用して、組み込みのドメイン固有言語を Eigen ライブラリで実装された一連の行列演算に変換したいと考えています。効率が重要なので、proto で Eigen 式テンプレートを生成し、時期尚早の評価を回避する必要があります。
行列の乗算式を生成できる簡単な文法を実装しました。以下のコードは警告なしでコンパイルされ (g++ 4.8.0 および Intel C++ 2013.3 で Boost 1.54.0 および Eigen 3.1.3 を使用)、私の式が 1 つの乗算演算しかない限り機能します。チェーンに乗算を追加するとすぐにクラッシュします。Valgrind は、評価が完了する前に Eigen::GeneralProduct 式テンプレートのテンポラリの 1 つが破棄されるためだと教えてくれました。
なぜこれが起こるのか、またはそれを防ぐために何ができるのかわかりません。すべての助けに感謝します!
c++ - Boost.Proto で式ツリーを構築し、段階的に評価/変更することは可能ですか?
Boost.Proto 式ツリーの一部を抽出し、それらを個別に (外部的に) 評価してから、抽出した部分を結果に置き換えて式ツリーを変更することはできますか?
私の特定のケースでは、繰り返し実行されるレガシーコードを書き直すことができるかどうかを評価しようとしています:
- SQLを生成します
- データベースに問い合わせる
- 結果を使用して、新しい SQL クエリを生成します
- データベースに再度クエリを実行します... (など)
1. 1 つの大きな式ツリーを生成する 2. 式ツリーから SQL を取得する。これは次のもので構成されます。ツリーにアクセスし、結果の単一の sql を生成する前に評価する必要があるサブクエリを確認します c. サブクエリがある場合は、SQL を作成して文字列として返し、SQL を外部で評価し、ツリーを変更して、サブクエリを結果に置き換えます
(また、同一のサブクエリを特定し、可能であれば一度だけ評価したいと思います)
これは可能ですか?理解/習得が困難なコードが必要になるか?
Boost.Proto ドキュメントをざっと読んだことがありますが、サブツリーを外部で評価し、ツリー全体が単一のクエリになるまで結果に置き換える必要があるこのシナリオを意図しているかどうかはわかりません。
編集:
次のテーブルがあるとしましょう。
オブジェクト ID | 名前
attribute_link objectid | 属性 ID
属性 ID | 親 ID | 名前 | 価値
私のクエリは、カスタムの「クエリ」オブジェクト、つまり複数の AND、OR 句を持つ (バイナリ) ツリーとして入ってきます。
例: query1 = object.id=10 OR (attribute.name = "name" OR attribute.name = "name2")
これは次のように変換されます: 属性の名前が「name」であるオブジェクト 10 の属性を取得します。parentid フィールドに注目してください。これは、探している attribute.name をネストすることができ、 object に直接リンクできないことを意味します。
私がする必要があるのは: 1.これを十分な情報を含む式ツリーに変換する 2.このツリーをデータベース層に送信する 3.上記で説明したようにツリーを処理する (複数の段階で行う場合もある)
おそらく、式ツリーは次のようになります。
find_attributes( object_id = 10 AND attribute_name = ( "name" OR "name2") )
SQL構文が異なるデータベースが複数あるため、このようにしたいと考えています。したがって、データベースに基づいて処理ステップの一部をオーバーライドできる必要があります。
たとえば PostgreSQL の場合:
処理は最初に find_attributes ノードを認識し、属性を検索していることを認識します。
さらに見てみると、属性を object.id = 10 にリンクする必要があります。すぐにクエリを生成して実行し、object.id = 10 のすべての属性を取得して、式ツリーの object_id = 10 ノードを実際の属性に置き換えます。 ids (object_id = 10) => (attribute_id = (20 または 21))。
次に、attribute_name ノードを見つけます。属性はネストされているため、name = "name" または "name2" を持つすべての属性行を見つける必要があります。
(オプションの) 最適化ステップとして、何百万もの属性があるため、attribute_id ノードと attribute_name ノードを単一のクエリにマージする必要があります。
結果のクエリは次のようになります。
(属性 ID を検索) SELECT id FROM 属性 WHERE objectid = 10)
(最終クエリ) ---
WITH
get_roots AS (SELECT * FROM 属性 WHERE (id=20 OR id=21))、
get_childs AS (SELECT * FROM get_roots、属性 WHERE attributes.parentid = get_roots.id)、
get_grandchilds AS (SELECT * FROM get_childs、属性 WHERE 属性.parentid = get_childs.id)SELECT * FROM get_roots UNION
SELECT * FROM get_childs UNION
SELECT * FROM get_grandchilds
(属性がここで 3 レベルの深さだけであると仮定すると、再帰的な CTE として書き直される可能性があります)
可能性はあると思いますが、やり過ぎでしょうか?クエリのセットは限られていますが、ここで紹介するクエリは最も複雑です。
c++ - Boost.Proto: カスタム ターミナル クラスを使用した EDSL の一般的なクラス レイアウト
Boost.Proto に慣れるために、ユーザー ガイドの TArray の例を適用して、固定されているが任意のサイズの浮動小数点ベクトル用のさらに別の式テンプレート ライブラリを構築しようとしています。最初に行うことは、ベクター クラスを定義することです。
vector_expr_wrapper
また、operator[]
それ自体をオーバーロードして、端末に対して返されるvector_context
派生元で評価します。proto::callable_context
vector[index]
FPVector
コードをコンパイルして非常に単純なステートメント ( ) で呼び出すと、a = b + c;
次のエラー メッセージが表示されます。
そして、g ++は可能な候補のものをリストします...それから私が理解しているのは、定義するvector_expr_wrapper
前にの定義全体を提供する必要があるということですが、他のすべてが(文法、評価コンテキスト...)に依存するFPVector
ため、そうすることができません。vector_expr_wrapper
FPVector
これを解決するにはどうすればよいですか (つまり、クラスをどのようにレイアウトすればよいですか)?
TArray の例は、配列クラスを非常に遅く定義し、その型をint[3]
before で指定することによって、この問題を回避しています。これは、私のコンテキストでは再現できないと思います。
ご助力ありがとうございます!