4

Pythonを使用して特定のデータ構造を記述する独自の小さなDSLを作成する必要があるとします。たとえば、私は次のようなものを書くことができるようになりたいです

f(x) = some_stuff(a,b,c)

宣言されていない識別子について文句を言ったり、関数some_stuffを呼び出そうとしたりする代わりに、Pythonを使用して、さらに便利なようにリテラル式に変換します。

__getattr__適切に再定義されたメソッドと__setattr__メソッドを使用してクラスを作成し、それを次のように使用することで、これに合理的な近似値を得ることができます。

e = Expression()
e.f[e.x] = e.some_stuff(e.a, e.b, e.c)

迷惑な「e」を取り除くことができれば、それでもかっこいいでしょう。接頭辞を付け、[]の使用を避けることもできます。だから私は疑問に思っていましたが、グローバル名のルックアップと割り当てを一時的に「再定義」することは可能ですか?関連するメモとして、Python式のこのような「引用」機能を簡単に実現するための優れたパッケージがあるのではないでしょうか。

4

3 に答える 3

3

いいアイデアかどうかはわかりませんが、試してみようと思いました。要約する:

class PermissiveDict(dict):
    default = None

    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            return self.default

def exec_with_default(code, default=None):
    ns = PermissiveDict()
    ns.default = default
    exec code in ns
    return ns
于 2010-04-17T01:37:56.890 に答える
2

入力コードの抽象構文ツリー(またはそれぞれ解析ツリー)を解析、アクセス、および変換するために、Pythonに含まれているastまたはモジュールを確認することをお勧めします。parser私の知る限り、Pythonで書かれたSage数学システムには、同様の種類のプリコンパイラがあります。

于 2010-04-17T00:12:08.437 に答える
-1

Wai のコメントに応えて、私が見つけた楽しい解決策を 1 つ紹介します。まず第一に、それが何をするかをもう一度説明するために、次のコードがあると仮定します:

definitions = Structure()
definitions.add_definition('f[x]', 'x*2')
definitions.add_definition('f[z]', 'some_function(z)')
definitions.add_definition('g.i', 'some_object[i].method(param=value)')

ここで、定義を追加すると、左側と右側を解析し、他の醜いことを行うことを意味します。ここで、(必ずしも良いとは限りませんが、確かに楽しい) アプローチの 1 つを使用すると、上記のコードを次のように記述できます。

@my_dsl
def definitions():
    f[x] = x*2
    f[z] = some_function(z)
    g.i  = some_object[i].method(param=value)

そして、内部でほとんどの解析を Python に行わせます。exec <code> in <environment>このアイデアは、Ian が言及した単純なステートメントに基づいており、ハック的な追加が 1 つあります。つまり、関数のバイトコードを少し調整し、すべてのローカル変数アクセス操作 (LOAD_FAST) を環境からの変数アクセス (LOAD_NAME) に切り替える必要があります。

説明よりも表示の方が簡単です: http://fouryears.eu/wp-content/uploads/pydsl/

実用的にするために実行したいさまざまなトリックがあります。たとえば、上記のリンクに示されているコードでは、@my_dsl 関数内で for ループや if ステートメントなどの組み込み関数や言語構造を使用することはできません。ただし、Env クラスにさらに動作を追加することで、これらを機能させることができます。

更新しますこれは、同じことのもう少し冗長な説明です。

于 2010-05-18T12:36:02.437 に答える