PHPで書かれたまともなPHPパーサーはありますか?[閉まっている]


80

私はPHPコードの操作と分析に多くの作業を行っています。通常、私はこれを行うためにTokenizerを使用します。ほとんどのアプリケーションでは、これで十分です。ただし、レクサーを使用した解析では、信頼性が十分でない場合があります(明らかに)。

したがって、PHPで記述されたPHPパーサーを探しています。hnw / PhpParserkumatch / stagehand-php-parserが見つかりました。どちらも、zend_language_parser.yをCではなくPHPで.yファイルに自動変換することによって作成されます(その後、LALR(1)パーサーにコンパイルされます)。しかし、この自動変換は機能しません。

それで、PHPで書かれたまともなPHPパーサーはありますか?(PHP 5.2用と5.3用に1つずつ必要です。しかし、そのうちの1つだけが出発点としても適しています。)


1
あなたの目標は何ですか?ここで何を達成しようとしていますか?
チャールズ

3
@チャールズ:私がこれを使うことはたくさんあります。AST表現でPHPソースコードを必要とするものすべて;)
NikiC 2011

1
@mario:それはたくさんの情報を落とします。これは実際には、ファイルに関する情報を抽出するタスク専用に設計されています。したがって、クラスステートメント、メソッドステートメント、returnステートメントなどを保持するだけで、実際に最も関心のあるすべてのコードを無視します。
nikiC 2011

2
PHPでコーディングされた大規模で堅牢な言語パーサーは見つからないと思います。それを求める必要はありません。
Ira Baxter

4
先週、私はパーサーの初期バージョンを自分で作成しました:github.com/nikic/PHP-Parserコードベースに対してテストしたところ、うまく機能しました。実際に使えるようにインターフェースの改善に取り組んでいきます。
nikiC 2011

回答:


128

ここで完全で安定したパーサーが見つからなかった後、私は自分でパーサーを作成することにしました。結果は次のとおりです。

PHPパーサー:PHPで記述されたPHPパーサー

このプロジェクトは、PHP5.2とPHP7.1の間のすべてのPHPバージョン用に記述されたコードの解析をサポートしています。

パーサー自体とは別に、ライブラリはいくつかの関連コンポーネントを提供します。

  • ASTをPHPにコンパイルして戻す(「プリティプリント」)
  • ASTをトラバースおよび変更するためのインフラストラクチャ
  • XMLとの間のシリアル化(および人間が読める形式でのダンプ)
  • 名前空間名(エイリアスなど)の解決

使用法の概要については、ドキュメントの「基本コンポーネントの使用法」セクションを参照してください。


2
これはすごい!それを維持する計画はありますか?
MikeSchinkel 2015年

1
@NikiCありがとうございます!それは素晴らしいライブラリです:
BVengerov 2016

1
わあ、2011年12月初旬にPHP 7.1がサポートされました!
dotancohen 2017年

9

これは純粋なPHP制約に違反するため、優れたオプションにはなりませんが、次のようになります。

少し前に、php-internalsの人々は、構文解析テクノロジとしてLemonに切り替えることを決定しました。PHP svnリポジトリには、必要な変更を含むブランチがあります。

彼らは、レモンのソリューションが約10〜15%遅いことがわかったため、これを続行しないことにしました。しかし、ブランチはまだそこにあります。

PHP拡張として書かれた古いレモンパーサーがあります。あなたはそれで働くことができるかもしれません。このPEARパッケージもありますこの他のレモンパッケージもありますPGNに関するこのブログ投稿を介し)。

もちろん、それが機能したとしても、データをどのように処理するのか、あるいはデータがどのように見えるのかはわかりません。

もう1つの奇抜なオプションは、JavaでのPHP実装であるQuercusを覗くことです。彼らはパーサーを書かなければならなかったでしょう、多分それは調査する価値があるかもしれません。


まず第一に:広範な研究のために+1。主な問題は、PHPでパーサーを構築する方法がないということではありません。レモンPHP文法の使用とコンパイルについては、すでに説明しました。さらに簡単なのは、おそらく「実際の」yacc / bison文法を使用することです(そのためのコンパイラーもあります)。問題は、オペコードを生成するためのyaccCコードをASTを生成するためのyaccPHPコードに変換することは本当に本当に大変な作業であるということです。だから私は誰かがすでにその仕事をしたかどうかを探していました。
nikiC 2011

@nikic IMO、まだ誰もこれを行っていない理由の1つは、PHPが実際に何であるか、およびそれを解析する方法についての仕様がないことです。php-internalsは以前、コンセプト全体を完全に拒否していました。その結果、PHPソースコード自体の外に、実際に解析を実行する方法についての信頼できるソースはありません。参照する信頼できる情報源がなければ、正しいパーサーを構築することは本当の冒険になるでしょう。残念ながら、これは、yaccまたはLemonデータから始めることが最良のオプションである可能性があることを意味します。
チャールズ

@ nikic、Charles:それは私たちのPHPパーサーにとって本当の冒険でした。アプローチ:字句解析/文法を提案し、何千ものファイルを試して、間違えて、調整して、再試行してください。文書化が不十分な言語用の堅牢なパーサーを取得するには、このようなドキドキの約1年かかります。少なくともそれは私たちのためにした。YMMVですが、それほど多くはないでしょう。
Ira Baxter

7

メトリックツールPHPDependには、完全にPHPで記述されたPHPソースからASTを生成するコードが含まれています。ただし、トークン化にはPHP独自のtoken_get_allを使用します。

ソースコードはgithubで入手できます:https//github.com/manuelpichler/pdepend/tree/master/src/main/php/PHP/Depend

数式のようないくつかの部分のASTの実装は、私が最後にチェックしたときにまだ完了していませんでしたが、その作者によると、それが目標です。


ASTはありますが、「数学演算」にはありません(「式」を意味していると思いますか?これは、特に、二重引用符で囲まれた「文字列リテラル」(式が埋め込まれている)が本当に複雑であると考えると、言語の重要な部分です。文字列式
Ira Baxter

2
これが質問への最も近い答えであるため、あなたは賞金を得ました。しかし、PHPの文法の半分が欠けているため、明らかに実際には使用できません...
NikiC 2011

この投稿の内容は古くなっています。それ以来活発な開発が行われていますが、PHPの文法をどれだけうまくサポートしているかはわかりません。
nhahtdh 2015

4

申し訳ありませんが、これはPHPにはありませんが、この種の機械を構築することは困難であり、PHPは言語処理のタスクには特に適していません。

私たちのPHPフロントエンド、それは完全なPHP 4.xおよび5.xの(EDIT 2016分の9:今PHP 7を扱う)提供の解析を、自動的に、完全なPHPの文法のすべての詳細とのASTを構築するのASTからコンパイルソーステキストを生成することができます。これは、奇妙な文字列リテラル、キャプチャされたコメント、基数付きの数値など、すべての厄介な詳細を考慮すると、思ったよりも難しいです。

しかし、ASTはほとんど十分ではありません(トークンがかろうじて十分でさえないことをすでに観察しました)。

それが構築されている基盤であるDMSSoftware Reengineering Toolkitは、ASTの分析と任意の変換をサポートします。また、一度に大量のファイルを読み取り、PHPファイル全体の分析と変換可能にします。


1
最初の文への応答と同じように:yacc文法(例:kmyacc)からパーサーを生成できるパーサージェネレーターがすでにあります。つまり、PHPでビルドすることと他の言語でビルドすることの間に大きな違いはありません。あなたがしなければならないのは、zend_language_parser.yのCコードをノードツリーを構築するいくつかのPHPコードに「ただ」(皮肉なことに)置き換えることです。
nikiC 2011

そして残りについて:私は本当にPHPソリューションが欲しいです。しかし(そしてこれはおそらくそう思われる)そのようなものがなければ、私はおそらく他のものを使うでしょう。ここSOでDMSについて何度か聞いたことがあるので、調べてみます。
nikiC 2011

@ninkic:すべてのチューリングマシン(PHPを含む)は他のすべてのチューリングマシンをシミュレートできます。もちろん、PHPでビルドすることも可能です。しかし、a)パーサーだけを構築ています。私はPHPパーサが木を構築するために設計されていないではなく、PHP用Pコードジェネレータを養うためにと思うし、私はあなたがニーズが異なっている見つけることだと思うと、b)の人々が繰り返し仮定のミスを犯す彼らが持っている場合にAST、他のすべては簡単です。彼らは主に、ASTで複雑なことをした経験がないためにこの間違いを犯します。この仮定が間違っているので、私はDMSを構築しました。
Ira Baxter

1
a)はい、PHPパーサーは解析ツリーを構築するようには設計されていません。オペコードストリームを構築するように設計されています。そのため、zend言語パーサーをPHPに自動的に変換することはほとんど不可能です。b)私はおそらくこの間違いを犯している人の1人です;)複雑な操作のロードは純粋なトークンストリームですでに実行できるという事実から、私は(あなたの目に誤って?)ASTを使用するとこれがより簡単であると結論付けましたより安定した。
nikiC 2011

@nikic:50年間のコンパイラ技術からの教訓は、各プログラム表現が特定のことを簡単にするということです。テキストだけでプログラム操作を行うことができます。トークンについてさらに多くのことができます。ASTでさらに多くのことができます。シンボルテーブル、制御およびデータフロー情報(グラフ)、変数エイリアシングデータ(ポイントツー分析)があれば、本当に興味深いことを行うことができます。洗練されたコード生成を行おうとすると、これは本当に本当に便利なものであることがわかります。
Ira Baxter

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.