具体的な構文木の文法規則は、構文で言うマッチ。抽象構文ツリーの目的は、「構文ツリー」に不可欠なものを「単純に」表現することです。
AST IMHOの真の価値は、CSTよりも小さいため、処理にかかる時間が短いことです。(誰が気にするのかと言うかもしれませんが、私は一度に数千万のノードが存在するツールを使用しています!)。
構文ツリーの構築をサポートするほとんどのパーサージェネレーターは、ツリーノードがCSTよりも「単純」であるという前提の下で、構築方法を個人的に正確に指定することを要求します(そして、プログラマーはかなり良いので、一般的に正しいです)怠惰な)。おそらくそれは、より少ないツリービジター関数をコーディングする必要があることを意味し、エンジニアリングエネルギーを最小限に抑えるという点でも価値があります。3500のルールがある場合(たとえば、COBOLの場合)、これは重要です。そして、この「シンプルさ」は「小ささ」の良い性質につながります。
しかし、そのようなASTがあると、そこにはなかった問題が発生します。文法と一致しないため、両方を精神的に追跡する必要があります。そして、3500ルール文法に対して1500のASTノードがある場合、これは非常に重要です。そして、文法が進化した場合(常に進化します!)、同期を保つための2つの巨大なセットがあります。
もう1つの解決策は、パーサーにCSTノードを作成させ、それらを使用させることです。これは、文法を構築する際の大きな利点です。3500の文法ルールをモデル化するために1500の特別なASTノードを発明する必要はありません。木が文法と同型であると考えてください。文法エンジニアの観点からは、これは完全に頭脳がないため、文法を正しく理解し、心ゆくまでハッキングすることに集中できます。おそらく、ノードビジタールールをさらに作成する必要がありますが、それは管理できます。これについては後で詳しく説明します。
私たちがやるとDMSソフトウェアリエンジニアリングツールキットは、自動的に(GLR)の解析プロセスの結果に基づいて、CSTを構築することです。次に、DMSは、スペース効率の理由から、値を持たない端末(キーワード、句読点)、意味的に役に立たない単項生成を排除し、次のようなリストである文法ルールペアのリストを形成することにより、「圧縮」CSTを自動的に構築します。
L = e ;
L = L e ;
L2 = e2 ;
L2 = L2 ',' e2 ;
そしてそのような形の多種多様なバリエーション。あなたは文法規則と仮想CSTの観点から考えます。ツールは圧縮された表現で動作します。あなたの脳にやさしく、実行時に速く/小さくなります。
驚くべきことに、この方法で構築された圧縮CSTは、手作業で設計した可能性のあるASTのように見えます(例の最後にあるリンクを参照)。特に、圧縮されたCSTは、具体的な構文であるノードを伝送しません。少し厄介な点があります。たとえば、式のサブグラマーに古典的に見られる「(」および「)」の具象ノードはツリーにありませんが、「括弧ノード」は圧縮されたCSTに表示されるため、処理する必要があります。真のASTにはこれがありません。これは、AST構造を指定する必要がないという利便性のために、かなり小さな価格のように思えます。また、ツリーのドキュメントはいつでも利用でき、正しいものです。文法はドキュメントです。
「余分な訪問者」を避けるにはどうすればよいですか?完全ではありませんが、DMSは、ASTをウォークし、CSTとASTの違いを透過的に処理するASTライブラリを提供します。DMSは、「属性文法」エバリュエーター(AGE)も提供します。これは、ノードで計算された値をツリーの上下に渡すための方法です。AGEはすべてのツリー表現の問題を処理するため、ツールエンジニアは、文法ルール自体に直接計算を効果的に書き込むことだけを心配します。最後に、DMSは「表面構文」パターンも提供します。これにより、関連するノードタイプのほとんどを知らなくても、文法からのコードフラグメントを使用して特定のタイプのサブツリーを見つけることができます。
他の回答の1つは、ソースを再生成できるツールを構築する場合、ASTがCSTと一致する必要があることを示しています。これは実際には正しくありませんが、CSTノードがある場合はソースを再生成する方がはるかに簡単です。 DMSは、両方にアクセスできるため、ほとんどのプリティプリンターを自動的に生成します:-}
結論:ASTは、物理的および概念的な小さなものに適しています。CSTからの自動AST構築は両方を提供し、2つの異なるセットを追跡する問題を回避できます。
2015年3月の編集: この方法で作成されたCSTと「AST」の例へのリンク