これは、最初から IDE の使用シナリオ向けに設計された初期段階の PHP パーサーです (詳細については、「設計目標」を参照してください)。やるべきことはまだたくさんあるので、現時点では、このリポジトリは主に実験と会話の始まりとして機能します。
これは v0.1 ブランチで、最初の 0.0.x リリース ラインの後に追加された構文をサポートするようにデータ構造を変更します。
マシンを構成したら、パーサーを使用して、使いやすい API 経由で抽象構文ツリー (AST) を生成し、操作することができます。
<?php// 自動ロードに必要なクラスには __DIR__ が必要です。 "/vendor/autoload.php";use MicrosoftPhpParser{DiagnosticsProvider, Node, Parser, PositionUtilities};// 新しいパーサーをインスタンス化します。instance$parser = new Parser();// 文字列内容から AST を返し、出力します$astNode = $parser ->parseSourceFile('<?php /* コメント */ echo "hi!"');var_dump($astNode);// AST ノードからエラーを取得して出力します。パーサーはエラーを適切に処理します。// そのため、IDE 使用シナリオ (コードが不完全な場合が多い) で使用できます。$errors = DiagnosticsProvider::getDiagnostics($astNode);var_dump($errors);// のすべてのノードの子孫を走査します。 $astNodeforeach ($astNode->getDescendantNodes() as $descendant) {if ($descendant instanceof NodeStringLiteral) {// ノードのテキストを出力します (空白やコメントは含まれません)var_dump($descendant->getText());// すべてのノードはその親にリンクされているため、ツリー内を簡単に移動できます。$grandParent = $descendant- >getParent()->getParent();var_dump($grandParent->getNodeKindName());// AST は完全に代表的で、元のソースとのラウンドトリップが可能です。// これにより、消費者は信頼できる書式設定およびリファクタリング ツールを構築できます。var_dump($grandParent->getLeadingCommentAndWhitespaceText()); }// ノードのすべての子または子孫を取得することに加えて、// ノードはノード タイプに固有のプロパティを公開します。if ($descendant instanceof NodeExpressionEchoExpression) {$echoKeywordStartPosition = $descendant->echoKeyword->getStartPosition();//メモリ消費を削減するために、位置はドキュメント内の単一の整数// インデックスとして表されますが、その行と文字の位置は簡単に変更できます。取得.$lineCharacterPosition = PositionUtilities::getLineCharacterPositionFromPosition($echoKeywordStartPosition,$descendant->getFileContents() );echo "行: $lineCharacterPosition->行、文字: $lineCharacterPosition->character"; } }
注: API はまだ完成していないため、公開したい機能をお知らせください。問題を報告してください。何ができるかを検討します。また、予期せぬ動作を伴うバグを解析ツリーにファイルしてください。私たちはまだ初期段階にありますが、フィードバックをいただければ幸いです。
エラー耐性のある設計 - IDE シナリオでは、コードは定義上、不完全です。無効なコードが入力された場合でも、パーサーは有効な完全なツリーと関連する診断を回復して生成できるはずです。
高速かつ軽量 (他の機能のための余地を残すために、1 秒あたり数 MB のソース コードを解析できる必要があります)。
メモリ効率の高いデータ構造
将来の増分解析を可能にする
PHP 言語仕様に準拠し、PHP5 と PHP7 の両方の文法をサポート
生成された AST は、セマンティックおよび変換操作に必要なプロパティ (完全に代表的なものなど) を提供しますが、パフォーマンスも必要です。
完全に代表的で、解析元のテキストに戻ることができます (すべての空白とコメント「トリビア」は解析ツリーに含まれます)。
親/子ノードを介してツリーを簡単に横断することが可能
UI 応答時間は 100 ミリ秒未満であるため、他のすべての処理を並行して実行できる余地を残すために、各言語サーバーの操作は 50 ミリ秒未満である必要があります。
シンプルで長期にわたって保守可能 - パーサーは非常に複雑になる傾向があり、非常に高速であるため、読みやすさとデバッグ能力が最優先されます。
テスト可能 - パーサーは証明可能な有効な解析ツリーを生成する必要があります。これは、ツリーに関する一連の不変条件を定義し、継続的にテストすることによって実現されます。
他の人が簡単に構築できるようにする、フレンドリーで説明的な API。
PHP で書かれています - PHP コミュニティが可能な限り簡単に利用し、貢献できるようにします。
あらゆる段階で十分な正確性を確保するために、パーサーは次の増分アプローチを使用して開発されています。
フェーズ 1: PHP 文法をサポートしないが、EOF および不明なトークンをサポートするレクサーを作成します。すべての不変式に対するテストを作成します。
フェーズ 2: PHP 語彙文法のサポート、多くのテスト
フェーズ 3: PHP 文法をサポートしないが、エラー ノードのツリーを生成するパーサーを作成します。すべての不変式に対するテストを作成します。
フェーズ 4: PHP 構文文法のサポート、多くのテスト
フェーズ 5 (進行中):現実世界の検証と最適化
正確性:サンプル コードベースでエラーが発生していないことを検証し、他のパーサーと比較してベンチマークを行い (不一致があれば調査します)、ファズ テストを行います。
パフォーマンス:大規模な PHP アプリケーションに対するプロファイル、ベンチマーク
フェーズ 6: API を完成させて、人々ができるだけ簡単に利用できるようにします。
PHP の文法構成要素のいくつか (つまり、yield-expression およびテンプレート文字列) はまだサポートされておらず、その他のさまざまなバグもあります。ただし、パーサーはエラー耐性があるため、これらのエラーは適切に処理され、結果として得られるツリーは完全なものになります。現在の状況をより全体的に把握するには、「検証」テスト スイートを実行できます (テストの実行に関する詳細については、「貢献ガイドライン」を参照してください)。または、単純に現在の検証テストの結果を見てみましょう。
パフォーマンスの最適化段階はまだ始まっていませんが、これまでのところ有望な結果が得られており、改善の余地はまだたくさんあります。現在のアプローチの詳細については「仕組み」を参照し、自分のマシンでパフォーマンス テストを実行して自分の目で確認してください。
設計目標- プロジェクトの設計目標 (機能、パフォーマンス指標など) について学びます。
ドキュメント- プロジェクトからパーサーを参照する方法、およびコードに関する質問に答えるために AST 上で操作を実行する方法を学びます。
構文ビジュアライザー ツール- AST をより具体的に感じます。創造力を発揮して、それを打ち破ることができるか試してみましょう。
現状とアプローチ- 文法はどの程度サポートされていますか?パフォーマンス?メモリ? APIの安定性は?
仕組み- アーキテクチャ、設計上の決定、トレードオフについて学びます。
レクサーとパーサー
エラー許容戦略
インクリメンタル解析
未解決の質問
検証戦略
貢献する! - 参加方法を学び、(これまでにパーサーで作業したことがない場合でも) コードベースを強化するのに役立つ教育用コミットへのヒントと、反復を容易にする推奨ワークフローを確認します。
このプロジェクトはマイクロソフトのオープンソース行動規範を採用しています。詳細については、「行動規範に関するよくある質問」を参照するか、追加の質問やコメントがあれば [email protected] までお問い合わせください。