抽象構文木は木でなければなりませんか?


13

パーサーの出力はツリーにする必要がありますか、それとも一般的なグラフにすることもできますか?

さらに、構文に木ではなく一般的なグラフ表現を使用している既存の言語や妥当な言語はありますか?


論理 -calculusには、周期的な抽象的な構文表現があります。μ
PAL GD

回答:


14

パーサーの出力はツリーである必要はありません。実際、変数の使用から抽象構文ツリーにオーバーレイされたDEFinitionへの参照などを検討すると、すぐにグラフが得られます。

大事なことは、解析は一般にシングルパスで行われるように設計されていることです。これは、スペースやプロセッサ速度の不足などの歴史的な理由だけでなく、理由がより簡単だからです。次に、後続のフェーズで解析ツリーに追加情報を飾ります。

プログラミング言語の解析に使用されるかどうかはわかりませんが、グラフ文法などがあります。


1
定義使用リンクで装飾された構文ツリーなどのグラフ構造を単一パスで出力することは完全に可能です。60年代に多くのコンパイラがそれを行いました。
babou

4

OPの質問は少し後向きです。もちろん、解析アルゴリズムは必要に応じて出力できます。問題は、解析の目的と、パーサーがこの目標を満たす結果を出力するかどうかを理解することです。次に、そのための適切な表現、たとえばツリーやグラフが何であるかを考えることができます。

パーサーは、言語の構文の正式な定義に従って、入力として与えられた文の構文構造を提供するアルゴリズムです。

言語の構文を構成するものについて人々が同意しない場合があることに注意してください。それを純粋な形式言語バックボーンに制限するものもあれば、タイプ、ジャンル、数、またはその他のより複雑なものなど、わずかに意味論的な考慮事項を導入するものもあります(NLPまたはプログラミング言語を区別していません)。ほとんどの言語には、グラフの表現を必要とする機能がありますが、構文にそれを含めるかどうかを決定するのは「実装者」(より良い言葉がないため)です。

したがって、構文の定義内容によっては、異なる種類の形式構造を出力する必要があります。

純粋なContext-Free解析の単純な場合、解析ツリーは、以下で説明するあいまいさの問題、またはASTを取得するために少し変更する必要がある場合を除きます(以下を参照)。

ただし、より複雑なケースでは、ツリー内のリンクで表されることが多いさまざまな構造が必要になる場合があり、したがってグラフ構造になります。これは、言語構文の定義に大きく依存します。

また、どのツリーを出力すべきかは明らかではありません。ツリー隣接文法(TAG)の場合、構文ツリーが派生ツリーと同じではないように機能しますが、前者は後者から派生できます。出力したいのは関連する質問かもしれません。

あいまいさに関する別の問題もあります。与えられた文は、あなたの言語に属している間、多くの異なる方法でそうするかもしれませんが、多くの異なる方法で構文構造を割り当てられるかもしれません。

次に、これらの構造のうちの1つだけをランダムに選択するか、明確に定義された基準(たとえば、尤度)に従って選択することができます。また、それらのいくつかまたはすべてを出力することもできます。複数を出力したい場合は、通常、それらを共有している独自の構造にパックしておくと便利です。これにより、スペースと計算時間が節約され、複雑さが実際の問題になる可能性があります。

それらをすべて出力することを選択した場合、可能な解析の数は無限になる可能性があるため、共有する以外に選択肢はありません。そして、グラフ内に何らかの形で循環を持たせることによってのみ、無限に有限に表現することができます。したがって、一般的にグラフ構造を作成する必要があります。ただし、このグラフ構造のプロパティは、選択した形式的な構文の種類に関連しています。

抽象構文ツリーについて

さて、質問は抽象構文木に関するものでもありました。私は混乱を招くので、「抽象的な」部分をスキップしました。確かに、この質問はそのさまざまな再記述ですでに混乱しています。

歴史的観点からのASTについては、1960-1970年の言語Lispとプログラム操作システムに由来します。アイデアは、プログラムを操作の目的と、数学者が公式で行う方法を知っている形式的な方法でプロパティを分析または定義するために、数式としての大きな表現と見なすことでした。式として、それらは自然にツリー構造化されましたが、これらのツリーをグラフに変えるさまざまな情報で装飾することができました。これは形式的にも実用的にも便利であり、コンパイラやプログラミングシステムでさらに使用されました。

基本的に、ASTは名前からもわかるようにツリーですが、さらに情報を伝えることができます。残りは、実装者の選択と見る人の目にあります。それはグラフですか、それとも装飾された木ですか?ただし、基本的なASツリーは重要です。これは、理論とプログラミングの両方で構築する足場だからです。

ASTは、正式な言語理論で研究されている解析アルゴリズムによって生成された解析ツリー(構文はコンテキストフリーベース)とは異なることに注意してください。その理由は、構文の設計が当時の解析技術によって制約され、それ自体が利用可能な低計算能力によって制約されていたためです。その結果、構文ツリーは、プログラムの構造を自然に考慮するものの拷問されたバリアントに過ぎず、ASTと呼ばれるより簡潔で単純なバージョンを得るために、基本的な形式解析プロセスの一部ではなく、さらなる処理を実行する必要がありました。

ただし、あいまいな文のすべての構造を表現する場合、コンピューター上のツリーの表現は、抽象的であるかどうかにかかわらず、ある程度制約されます。特に、これは複雑さの問題を隠します。解析ツリーからASツリーへの変換中に、グラフ構造のあいまいさを保持することも問題になる場合があります。ただし、そのことに懸念がある場合は、構文解析ツリーがASTとして機能できるように、具体的な構文を定義することができます。これは、あいまいさを処理する非常に一般的なアルゴリズムと、現在のコンピューターの能力によって許可されています。


1

GLR解析(一般化LR)を使用して解析し、入力の解析があいまいな場合(入力を解析する方法は複数あります)、解析の結果は、解析されたDAGではなく、DAGと考えることができます解析ツリー。パースDAGは、多くの可能性のあるパースをコンパクトにエンコードします:複数の可能性のあるパースツリー。

ただし、コンテキストなしの文法があり、入力文字列が明確に解析できる場合(この入力文字列を生成する文法に1つの派生しかない場合)、および解析の仕事が生成する場合、その派生...そしてこれらの条件下では、構文解析の出力は常に解析ツリーになります。なぜなら、文脈自由文法の生成は本質的にツリー構造を持っているからです。


元のGLRパーサー(その方法と呼ばれる)は、バグがあったために解析DAGを生成した可能性があります。可能な解析の数は一般に無限である可能性があるため、cyleを含まない有限構造でこの無限大を表現する方法はありません。実際の構造は、2部グラフの一種であり、and-orグラフに少し似ています。また、別の名前で知られています。この無限のあいまいさを表現できないことは、さまざまなNLPの状況で問題になる可能性があります。
babou

0

NLPでは、抽象構文表現は有向非巡回グラフ(DAG)です。2つのエッジが同じノードを指す状況を「構造共有」と呼びます。


0

+ =演算子の「AST」が(たとえば)ツリーではないCのインタプリタを書いたことがあります。考えてみましょうa[i++] += dどこa[i++]intdありますdouble。暗黙的な変換およびフェッチ操作はツリー内で明示的であったため、問題はフェッチの場所a[i++]とダブルへの変換をどこに置くかです。私たちの解決策は、木を放棄することでした。結果の「ASG」は次のようになりました

         +=
       / | \
      /  |  \
     /   |   \
    / convert \
    |     |    \
    |   fetch  fetch
    |   /       |
    index       d
    /  \
   a   postinc
       |
       i

0

私は、それが抽象的なツリーではなく、抽象的な「構文ツリー」でもないこと、そして構文が抽象的であることに気付くまで、これに戸惑っていました。

ですから、あなたの質問に答えるために、具体的な構文ツリー、決定ツリー、または他のツリーと同様に、抽象的な構文ツリーがツリーであるほうがよいと結論付けます。

一方、抽象構文グラフ、抽象構文図、抽象構文キューブ、または抽象構文仕様の使用を妨げるものは何もありません。

「抽象構文木」の抽象構文木は、混乱を避けるのに役立つと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.