web-dev-qa-db-ja.com

同種vs.異種AST表現

同種か異種かを選択する理由は何ですかAST複雑なドメイン固有のプログラミング言語を実装するための表現?

私が尋ねていることを非常に明確にするために、ここにいくつかの追加の背景があります:

同種とは、単一のジェネリック型であるノードで構成されるツリーを意味します。たとえば、この質問は実際には言語に依存しないと思いますが、C++のような構造体を例として使用すると、これは最小限の同種の抽象構文ツリーノードと見なします。

struct Node {
  int tag;
  void *data;

  Node *first_child;
  Node *next_sibling;
};

異種とは、複数の個々のタイプであるノードで構成されるツリーを意味します(たとえば、文法生成ごとに1つ)。たとえば、特定の言語を想定したくありませんが、ここでもC++のような構造体を使用して説明しますが、これらの型は、異種の抽象構文ツリーツリーを構築するために使用される階層の一部と見なします。

struct Node {};

struct Integer_Node : Node {
  int value;
};

struct Plus_Node : Node {
  Node *right;
  Node *left;
};

struct If_Statement : Node {
  Node *Condition;
  Node *Then_Expression;
  Node *Else_Expression;  
};

// ... more types, depending on the language ...

長年にわたって、通常は非常にアドホックな方法で、いくつかの小さな専用コンパイラを実装してきました。通常、構文直接変換で十分なので、実際の「AST」をあまり使用していません。

現在、私はASTを構築し、検証、セマンティック分析、およびなど。

たとえば、同種のスキームを使用すると、事前にコードの量が減るようですが、私が考慮していない理由により、異種のスキームが長期的に見ればより効果が上がるのではないかと思います。一方、異種方式では、コンパイラーの静的型チェック、仮想メソッドディスパッチなどのメリットが得られるように見えますが、セマンティックパスなどを開発するときに、それらのどれが本当に非常に役立つのでしょうか。

基本的に、私はここで実際に経験を積んだかもしれない人々からいくつかの洞察を得たいと思っています。私は多くのコンパイラーの本を読み、適度な量の基本的なコンパイラー作成経験を持っていますが、私が手に入れることができる文献でこの特定の二分法が扱われるのを見たことはありません。

5
wjl

私にとって、異種混合AST=の大きな利点は、強制された注釈付きのswitchステートメントを形成することです(Cのような言語を想定)。

同種のASTの場合、通常、大きなswitchステートメントを使用して、ある種のルーチンまたはクラスが作成されます。自分がどの子ノードであるかを追跡する必要があります。「最初に子は条件付きで、2番目は真のブロック、3番目は偽のブロックです。」コードを変更するときはいつでも、DSL構文のメンタルな絵を何度も繰り返し作成していることに気づくでしょう。

もちろん、大量に文書化することもできますが、優れたプログラムはできるだけ自己文書化する必要があります。異種のASTはまさにそれを行います。

さらに、異種のASTを同種のものに簡単に変換できますが、その逆はできません。タグ情報を追加してください(言語が安価な_is-a_クエリ)Node(int index)メソッドを追加して名前付きフィールドを返すことができるため、異種混合ASTを使用しても、一般的に何も失うことはありません。

同種のswitchルーチンでStrategyパターンを使用するのと同じくらい簡単なので、異種のASTはVisitorパターンに理想的です。 is異機種混合AST自体に特定の機能を追加する方が簡単です。インタプリタに変換したい場合は、何らかの「評価」を追加するだけです。 "メソッド。

均質なASTもしlimiting状況がある場合。コンパイラをOOPのないシステムに移植する必要がある場合利用可能な言語、または速度を最適化する必要がある場合。同種のASTはFSMと組み合わせる方が簡単です。後者は、汎用の多目的コンパイラが必要な場合にも有利です。構文規則をその場でロードします。ただし、コンパイラーを十分にテストした後は、これらのテーブルを生成する異種のASTから始める方が簡単です。

したがって、全体として、どちらのツリーも「このツリーは「セマンティックパス」に役立つか、それとも妨げるのか」という点で特定の利点を提供しないと言えます。異種のAST=の利点は、私の経験では、コンパイラの面倒なものをコーディングする際に考えなければならないことや集中力を減らすことです。多くの反復性と簿記があります私がモットーとしているのは、できる限りコンピュータに作業を任せることです。

5
Jer