5

コードジェネレーター(この場合は手続き型画像合成-clisk )を駆動するために使用されるClojureでDSLを設計していますが、中間値の最適な表現を見つけるのに問題があります。

もともとDSLは、1つ以上のフォームを返す関数で構成されていました。

(v+ 1.0 [1.0 'y])
=> ['(+ 1.0 1.0) '(+ 1.0 y)]

次に、これらの関数を構成して、より大きなコードブロックを構築できます。

これは単純で、結果のフォームをコードジェネレーターに直接入力できます。ただし、このアプローチの弱点と思われるものを特定しました。たとえば、補助データ(BufferedImagesなどの形式でエンコードできないオブジェクト、最適化に役立つメタデータなど)を渡す必要がある場合などです。

これはLispの世界で解決された問題だと確信しています-この種のDSLの最良の中間表現は通常何でしょうか?

4

3 に答える 3

9

コードの生成に使用される中間表現が必要な場合はいつでも、私の頭に浮かぶ最も明白なものは抽象構文木 (AST) です。あなたの表現例はリストであり、私の経験ではフォームの柔軟性がありません。些細なコード生成以上のことについては、私はブッシュの周りを打ち負かさず、本格的な AST 表現を使用します。リストを使用することで、タイプや最初の項目の意味などの情報を解析するための作業を生成側に任せることができます。AST 表現に移行すると、柔軟性が向上し、システムをより分離できますが、解析側の作業が増えます (または、フォームを生成する関数の作業が増えます)。生成側もより多くの作業を行うことになりますが、

AST がどのように見えるかという点では、Christophe Grand の enlive のどちらかをコピーします。{:tag <tag name> :attrs <map of attrs> :content <some collection>}

または clojure スクリプトが使用するもの、{:op <some operator> :children <some collection>}.

:childrenこれにより、 や が何であるかを正確に知らなくても、任意の構造を覗いて横断できる:op任意のウォーカーを定義できるため、非常に一般的になります:tag

次に、アトミック コンポーネントの場合は、それをマップにラップして、オブジェクトの実際の型とは無関係な型情報 (DSL のセマンティクスに関して) を与えることができます。{:atom <the object> :type :background-image}.

コード生成側では、atom に遭遇すると、コードを にディスパッチし、:type必要に応じてオブジェクトの実際の型にさらにディスパッチできます。コレクション フォームからの生成も簡単で、:op/:tag でディスパッチし、子で再実行します。子供にどのコレクションを使用するかについては、Google グループでの議論をもっと読みたいと思います。彼らの結論は私にとって啓発的でした。

https://groups.google.com/forum/#!topic/clojure-dev/vZLVKmKX0oc/discussion

要約すると、子供の場合、 if ステートメントなどの意味的な順序付けが重要な場合は、 map を使用します{:conditional z :then y :else x}。単なる引数リストの場合は、ベクトルを使用できます。

于 2012-05-26T13:48:47.097 に答える
1

私は理解していないと思います。リストまたは構造体を自分で使用するだけです。

Lisp では、リストには何でも含めることができます。CONS セルはあらゆるものを指すことができるため、リストにはあらゆるものを含めることができます。他のほとんどすべてのデータ構造 (構造、配列、マップなど) も同様です。

現在、これらの構造は、PRINT によってレンダリング可能にすることも、(READ によって) 読み取り可能なものにレンダリングすることもできませんが、格納および操作できないという意味ではありません。

この表現を外部化する必要がある理由はありますか?

于 2012-05-26T05:07:05.980 に答える
1

この点に関してClojureがどのように機能するかはわかりませんが、CLにはこのケース用に特別に設計されたリーダーマクロがあります。つまり、印刷できないオブジェクトを印刷する関数とそれらを読み取るリーダーマクロを定義しますあなたがそれらを印刷した方法。オブジェクトが印刷される方法を定義するには、print-object必要なオブジェクトのタイプに特化した新しいメソッドを定義set-macro-characterし、デザインのオブジェクトを読み取る方法を知っている readtable に関数を追加します。

注意すべき点はたくさんありますが、オブジェクトが再帰的に自分自身を参照できる場合、タイマー爆弾のように通常動作するものもあります。この場合、印刷は以前に印刷されたオブジェクトを考慮する必要があります。

于 2012-05-26T07:03:02.173 に答える