モジュールでツリーを生成し、他のモジュールに同じツリーを入力する必要がある場合(またはほとんど同じツリー、何らかの形で最適化されている場合)にASDLが使用されます。
これを行うには、構造の機能(理想的にはタイプチェッカー)、ツリーを印刷して、正しく生成したことを視覚化する機能が必要です。
ASDLは、代数的データ型(haskellやmlなど)の構文やBNFの構文とほぼ同じ構文で書かれたツリーを入力として受け取りますが、はるかに単純化され、すべてのコンストラクタを自動生成します。ツリーの簡単な説明から始まる関数です。
たとえば、レクサーがある場合、タイプを持つレクエムを生成する必要があります。また、語彙の出力ストリームを見る必要があります(これは線形なので、非常に単純なツリーです)。代わりに、語彙素を構築する、印刷するための関数を書いて、あなたは彼らにその
lexeme=
ID(STRING)
| INT(num_integer)
| FLOAT(num_float)
attributes(int coord_x, int coord_y)
num_integer:
....
num_float:
....
のようなものを定義し、あなたのレクサーからコンストラクタID、INT、FLOAT、などを呼び出します。 ASDLは、必要なすべての関数でこの単純な構文を変換し、ASTのノードを作成したり、必要なものを印刷したりします。 ASDLは生成されたコードに制限を課しません。
トークンの座標などの型にattributes
を追加すると、そのような属性がその型の各コンストラクタのパラメータに追加されます。パーサによって作成された
Aより複雑なツリーは、パーサによって作られたSUM(_ _)の呼び出しがで作成したノードを合計する合格することを確認します。この場合のASDLはその
expr: SUM(expr, expr)
|PRODUCT(expr, expr)
|number
number: num_integer
ようになります。 exprのコンストラクタの1つ。 num_integer
は外部で定義されています。おそらく、レクサーのasdlツリーによって定義されています。
number: [0-9]+
などの正規表現を含むコンストラクタを定義することはできません。 ASDLはEBNFより簡単です。
これらのコンストラクタは、必要なものをビルドするために、チェックを入力して、lexer/parser/codeジェネレータがasdlで定義された言語に適合するツリーを出力するように定義されます。
ASDLについてよく理解するには、3-4パーサーを作成し、生成するコードに共通するものを確認する必要があります。その共通部分は実際はASDLなので、これは特にパーサーの出力のための抽象です。