この種の最近の例として、私は Cohesion C# コードベースに従事しており、コードに関する質問がありました。 具体的には、「インターフェイス X から伸びる非 public フィールドを持つすべてのクラス」を検索したいと考えました。 ほとんどの場合、私は Resharper の
構造検索 に手を伸ばしていましたが、倫理的には Jetbrains Rider に移行し、悲しいことに… 構造検索はバックログ内。
ツリーシッターについて最高のことを聞いた とはいえ、今日は私の被害日だったので、CLI ツールを書くクラックを購入しようと思いました。 非常に多くの時間と 130 ~ のコードのトレースを経て、2 秒未満で 6000 個のファイルからレコードデータを検索できる非常に小さなスクリプトができました!たまたま、Microsoft の Roslyn ライブラリを使用して C# で同じツールを作成し、レコードデータからの同じ検索に約 30 秒かかりました。 サビが早い! 驚くことに、Roslyn バージョンはマルチスレッドではなくなりました。 ただし、Rust でのマルチスレッド化の利点は、Rust バージョンがスレッド化され、C# バージョンがスレッド化されなくなった最も大きな原因です。
では、それがどのようにまとめられたのかを見てみましょう。 学習するか、直接コードにスキップしてください
面倒くさがりで産みましょう。 Tree-sitter は、言語の大幅な変更を支援する総合的な AST 解析ライブラリです。 解析するすべての言語に対して C ライブラリを生成することで機能します。 簡単にするために、事前に生成された C# パーサー
をサブモジュールとしてプルして、私たちの使命とそれを構成に追加します。 この C ライブラリを Rust 実行可能ファイルの一部として構築することを確信して、 にトレースについて追加することをお勧めします。 construct.rs
ファイル:
construct.rs は、少し実行するファイルです。 Cargo コンストラクト デバイスのビット。 C コードをまとめて持ち込んだり、ライブラリの構築方法に対するその他のより複雑な調整を定義したりするために費やす可能性があります。
spend std::path::PathBuf; fn most foremost() { let dir: PathBuf=.iter().glean(); cc::Contain::unique() .consist of(&dir) .file(dir.join("parser.c")) .file(dir.join("scanner.c")) .bring collectively("tree- sitter-c-挑発的"); }
これはヘッダーを取得し、
tree-sitter-c-挑発的
を作成し、構築前のステップとしてコンパイルします。
ピース 1: ツリーシッターと錆止め
Tree-sitter は Rust バインディングを提供し、これを使用してこのパーサー ライブラリを FFI としてロードできます。 C は Rust の要件により安全ではないため、安全でないとマークすることをお勧めします
extern "C" { fn tree_sitter_c_sharp() -> 言語; } fn most foremost() { // Tree-sitter C# ライブラリから仕上げレベルの C 特性を呼び出します。 // 安全ではありません。C FFI のヤーンでは安全ではありません。 let language=unsafe { tree_sitter_c_sharp() }; // ツリー シッター パーサーを配置します。 let mut パーサー=tree_sitter::Parser::unique(); parser.set_language(language).unwrap(); // ファイルを解析します。 let source_code=fs::read_to_string("my_csharp_file.cs")?; let tree=parser.parse(&source_code, None).unwrap(); // ... }
こんにちは! C# ファイルを解析しました! 簡単です。
検索レコードデータを定義する方法が必要です。 ツリーシッターは間違いなく 言語
からレコードデータを検索できます 内蔵! 主に S-Expressions
に完全に基づいています。 、そしてこれを少し崇拝しているように見えます:
(binary_expression (number_literal) (number_literal))
。 その検索 recordsdata from は、おそらく非常に効果的に2つの数値に対するバイナリ演算子になる可能性のあるすべてのコードを表します。 すなわち。2 + 2
,7 <<2
、およびいつもの質問
𝚆𝚊𝚝𝚌𝚑 𝙽𝙾𝚆 📺