構文解析ツリーと抽象構文ツリーの違いを説明する最も簡単な例は何ですか?


14

私の理解では、パーサーは解析ツリーを作成し、その後それを破棄します。ただし、抽象構文ツリーをポップアウトすることもできます。これは、コンパイラが使用すると思われます。

私は、解析ツリーと抽象構文ツリーの両方が解析段階で作成されているという印象を受けています。次に、これらが異なる理由を誰かが説明できますか?


3
なぜ彼らは異なっていなければならないのですか?わずかに異なる2つの視点からは、同じものになれないでしょうか?
S.Lott

1
これら2つの「わずかに異なる視点」を理解しているかどうかわからない:
コンビネーターロジック

それがポイントです。それらは同じものなので、混乱を招きます。視点に応じて、構文解析とコード生成(またはインタープリターの場合は実行)という言葉があります。
-S.Lott

違いはありません。少し想像すると、考えられる抽象的な構文ツリーの構文表現を発明できます。想像力に欠けると、LispのS式はすべてに適したデフォルトの構文になります。
SKロジック

1
コメントする前に答えをすべて読んでおく必要があります。違いはありますが、それらを別々にしたり組み合わせたりすることは実装上の問題です。
ポール

回答:


20

解析ツリーは、具象構文ツリーとも呼ばれます。

基本的に、抽象ツリーの情報はコンクリートツリーの情報よりも少なくなります。具象ツリーには言語の各要素が含まれていますが、抽象ツリーには関心のない部分が捨てられています。

たとえば、次の式: (2 + 5) * 8

コンクリートはこんな感じ

  ( 2  + 5 )  * 8
  |  \ | / |  | |
  |   \|/  |  | |
   \___|__/   | |
       \______|/

一方、抽象ツリーには次のものがあります。

2  5 
 \/   
  +  8
   \/
   *

具体的なケースでは、括弧と言語のすべての部分がツリーに組み込まれています。抽象の場合、括弧はなくなりました。これは、その情報がツリー構造に組み込まれているためです。


この方法でどの言語のどのコンパイラに実装されているかを忘れていました。なぜなら、パーサーはすぐに括弧を捨てることもできるからです。
インゴ14

1
@Ingo、私の答えには、コンパイラが括弧を捨てるときについて何も言うことがありません。具体的な解析ツリーと抽象解析ツリーの違いは何かを尋ねます。
ウィンストンユワート14

だから、確かに、あなたはあなたの主張のソースに名前を付けることができますか?または、これはあなたのプライベートな定義ですか?
インゴ14



0

最初に理解する必要があるのは、特定の方法でパーサーやコンパイラを書くことを強制する人はいないということです。具体的には、パーサーの結果がツリーである必要は必ずしもありません。入力を表すのに適した任意のデータ構造を使用できます。

たとえば、次の言語:

prog:
      definition 
    | definition ';' prog
    ;

definition: .....

定義のリストとして表すことができます。(Nitpickersはリスト縮退ツリーであることを指摘します、とにかく。)

次に、解析ツリー(またはパーサーが返したデータ構造)を保持する必要はありません。それどころか、コンパイラは通常、一連のパスとして構築され、前のパスの結果を変換します。したがって、コンパイラの全体的なレイアウトは次のようになります。

parser :: String             -> Maybe [Definitions]      -- parser
pass1  :: [Definitions]      -> Maybe DesugaredProg      -- desugarer
pass2  :: DesugaredProg      -> Maybe TypedProg          -- type checker
pass3  :: TypedProg          -> Maybe AbstractTargetLang -- code generation
pass4  :: AbstractTargetLang -> Maybe String             -- pretty printer

compiler :: String           -> Maybe String    -- transform source code to target code
compiler source = do
   defs  <- parser source
   desug <- pass1 defs
   typed <- pass2 desug
   targt <- pass3 typed
   pass4 targt

結論構文解析ツリー抽象構文ツリー具体的な構文ツリーなどについて人々が話すのを聞いた場合、常に特定の目的に適しデータ構造に置き換えてください。


2
これは質問への答えですか?
ウィンストンユワート14

@WinstonEwert私は、「解析ツリー」と「抽象構文ツリー」は抽象化であり、「適切なデータ構造」にすぎないと主張しています。だから、答えはその普遍性に質問が、意味がないということでない限り、あなたはパーサの戻り値の型と言語L.のコンパイラXYで他のいくつかのパスの戻り値の型の違いを尋ねる
インゴ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.