AST (Abstract Syntax Tree)

AST (Abstract Syntax Tree) は、主にコンパイラがコードを読み取り、ターゲットバイナリを生成するために使用する、ソースコードのグラフ表現です。

たとえば、このコード サンプルの AST は次のようになります:

ソース コードから AST への変換は、あらゆる種類の構造化データを処理するときに非常によく行われるパターンです。 典型的なワークフローは、「生のデータをグラフ ベースのフォーマットに変換するパーサーを作成し、それをレンダリング エンジンで消費できるようにする」ことに基づいています。net:

上の画像で、DOT 言語の生のテキストがオブジェクト ツリーに変換されたことに注目してください (json ファイルとして消費/保存も可能です)。

開発者として、「コードまたは生データをグラフとして見る」ことができれば、驚くべきパラダイム シフトを遂げたことになり、介護者全体に多大な貢献をすることになるでしょう。

たとえば、私は AST とカスタム パーサーを使用して、次のようなことを行っています。

  • コードで実際に何が起こっているかをチェックするテストを書く (コードのオブジェクト モデルにアクセスできれば簡単)
  • 通常の「正規表現」ベースのパーサーが理解に苦しんだログ データを使用する
  • カスタム言語で書かれたコードで静的分析を行う
  • データ ダンプを
  • 複数のソース コード ファイルのスライスで変換されたファイルを作成する (私はこれを MethodStreams および CodeStreams と呼んでいます)-これが実際にどのようなものかは、以下の例を参照してください
  • perform custom code refactoring ( たとえば、コード内のセキュリティ問題を自動修正する) – これが実際にどのようなものかは以下の例を参照してください

When building parser for a specific data source, ASTから元のテキストに戻ることができる(データを失うことなく)ラウンドトリップ機能が重要なマイルストーンです。

これは、IDE におけるコード リファクタリングがどのように機能するか (たとえば、変数の名前を変更すると、その変数のすべてのインスタンスが名前変更される) とまったく同じです。

  • ファイル A の AST を作成する
  • ファイル B を AST からの変換として作成する
  • ファイル A はファイル B と等しい (byte byte)
  • これが可能になると、コードをプログラム的に簡単に変更できます。なぜなら構文を正しく作成するソース コード (AST からの変換となる) を気にせずに強く型付けされたオブジェクトを操作することができるようになるためです。)

    AST オブジェクトを使用してテストを書く

    一度、ソース コード (または消費するデータ) を「操作可能なオブジェクトから AST パーサーだけ離れたところ」とみなすようになると、チャンスと能力の全単語が開放されます。 「特定の認証 (またはデータ検証) メソッドが、公開されたすべての Web サービス メソッドで呼び出されることを確認する」のでしょうか。

    この呼び出しについてチェックするテストをプログラム的に書くことができない限り、唯一の選択肢は以下のとおりです。

    1. その要件を定義する「標準文書/Wiki ページ」を作成し、すべての開発者がそれを読み、理解し、さらに重要なことに、それに従うようにする
    2. その標準/要件が正しく実装されたかどうかを手動で確認する (Pull Requests コード レビューで)
    3. 「正規表現」ベースのツールを使用して自動化を試みる (商用またはオープンソース)。
    4. QA テスト (およびセキュリティ レビュー) を手動で行い、盲点を発見する

    しかし、この要件をチェックするテストを書く能力がある場合、以下のことが起こります。

    1. コードの AST を消費して、標準/要件が正しく実装/コーディングされたかどうかを非常に明確にチェックできるテストを書く
    2. テスト ファイル内のコメントにより、ドキュメントはテスト コードから生成できる (すなわち、テスト コードから)……
    3. テスト ファイル内のコメントにより、ドキュメントはテスト コードから生成できる。つまり、この標準/要件のドキュメントを作成するための余分なステップは必要ありません)
    4. これらのテストをローカル ビルドおよびメイン CI パイプラインの一部として実行する
    5. 失敗したテストを持つことにより、開発者は問題が発見されるとすぐにそれを知ることができ、非常に迅速に修正できる

    これはソフトウェア開発ライフサイクルに組み込まれた方法で、アーキテクチャとセキュリティ要件を拡張する方法の好例と言えます。

    We need ASTs for legacy and cloud environments

    AST を深く掘り下げると、それが異なる層または次元間の抽象化層であることに気付きます。 しかし、現在のレガシーおよびクラウド環境 (私たちが「コードとしてのインフラストラクチャ」と呼ぶ部分) を見ると、そのエコシステムの大部分は、現実をプログラム可能なオブジェクトに変換する AST パーサーを今日持っていないことに気付きます。

    これは素晴らしい研究領域で、レガシー システムまたはクラウド アプリケーションの DSL (Domain Specific Languages) を作成することに集中できます (それぞれが完全に異なるソース セットを持っているので、1つを選択します)。 私たちが必要とする DSL の一例は、ラムダ関数の動作 (すなわち、実行に必要なリソース、およびラムダ関数に期待される動作) を記述およびコード化するための言語です。 このファイルには、そのオリジナルのメソッドに関連するすべてのソース コード (複数のファイルから生成) が含まれており、コード レビューを行う際に大きな違いをもたらしました。

    なぜこれを行ったかを理解するために、私が抱えていた問題から始めましょう。 しかし、私は WebServices メソッドしか見ておらず、そのコードベースのほんの一部しかカバーしていませんでした (これらはインターネットに公開されるメソッドであるため、これは理にかなっています)。 インターネットに公開されているメソッドを見つける方法は知っていましたが、それらがどのように動作するかを理解するためには、それらのメソッドの実行パスにあるコードを含むファイルである、何百ものファイルを見なければなりませんでした。

    O2 プラットフォームには、非常に強力な C# パーサーとコード リファクタリング サポート (REPL 機能のために実装) がすでにあったので、次のような新しいモジュールをすばやく書くことができました:

    1. web サービス メソッド X
    2. から始まるすべてのメソッドを計算し、2 によって呼ばれるすべてのメソッドを計算し、そのメソッドが X2.1.2.1 から呼ばれるメソッドを計算した。 (再帰的に)

    3. 前の手順で特定したすべてのメソッドから AST オブジェクトを取得
    4. 4.のすべてのオブジェクトで新しいファイルを作成

    この新しいファイルは、セキュリティ レビューで読む必要のあるコードだけを含んでいたので、驚くべきことでした。

    しかし、この状況では、ファイルの先頭に検証 RegEx (すべての Web サービス メソッドに適用) を追加し、ファイルの下部に関連するストアド プロシージャのソース コードを追加することができたので、さらに良くなったのです。

    これは、幅広い能力とテクニック (この場合はソース コードをプログラムで操作する能力) にアクセスすることにより、より良い仕事ができるようになった良い例です。 もしあなたがこの道を進むなら、MethodStreamsの技術を発展させたO2 PlatformのCodeStreamsもチェックしてみてください。 CodeStreams は、特定のソース変数によってタッチされるすべての変数のストリームを提供します (静的解析では Taint フロー解析および Taint チェックと呼ばれるものです)。

    以下は、左側のコードがプログラムによって右側のコードに変換されたときの UI の様子です (追加の AntiXSS.HtmlEncode ラッパー メソッドを追加することによって)

    変換とコードの修正を行うソースコードです (コードのラウンドトリップに注目してください)。

    2018 年、このワークフローを開発者に優しい方法で実装する方法は、それらの余分の変更で Pull Request を自動的に作成することです。

    コメントを残す

    メールアドレスが公開されることはありません。