22

既存のlibclangAPIを使用してclangで宣言が不完全なC++を解析することは可能ですか?つまり、すべてのヘッダーを含めずに.cppファイルを解析し、その場で宣言を推測します。したがって、たとえば次のテキスト:

A B::Foo(){return stuff();}

未知のシンボルAを検出し、Aを差し引くコールバックを呼び出します。これは私の魔法のヒューリスティックを使用したクラスです。次に、このコールバックをBやFooなどで同じように呼び出します。結局、クラスBのメンバーFooがAを返すのを見たと推測できるようにしたいと思います。そして、ものは関数です。コンテキスト:すべてのヘッダーを非常に迅速に解析せずに、適切な構文の強調表示とオンザフライのコード分析を実行できるかどうかを確認したいと思います。

[編集]明確にするために、私は非常に厳しく制限されたC ++解析を探しています。おそらく、いくつかの制限を解除するためのヒューリスティックがあります。

C ++の文法は、コンテキストの依存関係でいっぱいです。Foo()は関数呼び出しですか、それともクラスFooの一時的な構造ですか?Foo<Bar>のものです。テンプレートFoo<Bar>のインスタンス化と変数の宣言、またはオーバーロードされた演算子<と演算子>への奇妙な2つの呼び出しですか?コンテキストでのみ伝えることが可能であり、コンテキストは多くの場合、ヘッダーの解析から発生します。

私が探しているのは、カスタムの慣習規則をプラグインする方法です。たとえば、Win32シンボルをオーバーロードしないことを知っているので、CreateFileは常に関数であり、その署名さえ知っていると安全に想定できます。また、すべてのクラスが大文字で始まり、名詞であり、関数は通常動詞であるため、FooとBarはクラス名であると合理的に推測できます。より複雑なシナリオでは、a<b>cのような副作用のない式を記述しないことを私は知っています。したがって、aは常にテンプレートのインスタンス化であると想定できます。等々。

したがって、問題は、Clang APIを使用して、不明なシンボルに遭遇するたびにコールバックし、私自身の非C++ヒューリスティックを使用して回答を与えることができるかどうかです。私のヒューリスティックが失敗した場合、明らかに解析は失敗します。そして私はBoostライブラリの解析について話していません:)私は非常に単純なC++について話していて、おそらくテンプレートがなく、この場合clangが処理できる最小限に制限されています。

4

4 に答える 4

6

質問がかなり古いことは知っていますが、ここを見てください:

LibFuzzy は、Clang の Lexer に基づいて C++ をヒューリスティックに解析するためのライブラリです。ファジー パーサーはフォールト トレラントであり、ビルド システムの知識がなくても、不完全なソース ファイルでも動作します。パーサーは必然的に推測を行うため、結果の構文ツリーは部分的に間違っている可能性があります。

これは、もはや開発されていないように見える (実験的な?) ツールである clang-highlight のサブプロジェクトです。

私はあいまいな解析部分にのみ興味があり、いくつかの小さな問題を修正し、ツールを自律的にしました (clang のソース ツリーの外でコンパイルできます) と競合するため、C++14 (G++ 6 のデフォルト モード) でコンパイルしようとしないでくださいmake_unique

このページによると、clang-format には独自のファジー パーサーがありますが (積極的に開発されています)、パーサーはツールにより緊密に結合されていました (?)。

于 2016-05-13T11:33:39.967 に答える
5

人々が書くことを許可されているコードを厳しく制限しない限り、すべてのヘッダーを解析せずに C++ を解析する (したがって、キーワード/正規表現を超えた構文の強調表示を行う) ことは基本的に不可能です。プリプロセッサは、物事を台無しにするのに特に優れています。

ファジー解析の難しさ (Visual Studio のコンテキストで) については、興味深いかもしれないいくつかの考えがあります。

于 2012-06-21T07:48:12.500 に答える
1

OPは「ファジー解析」を望んでいません。彼が望んでいるのは、名前と型の解決を必要とせずに、C++ ソース コードを完全にコンテキストフリーで解析することです。彼は、解析の結果に基づいて、型について知識に基づいた推測を行う予定です。

Clang は適切なもつれの解析と名前/型の解決を行います。つまり、解析時にバックグラウンドの型情報をすべて利用できる必要があります。他の回答は、間違った解析ツリーを生成するLibFuzzyと、私が何も知らないclang-formatのファジーパーサーを示唆しています。従来の AST を生成することに固執する場合、これらのソリューションのいずれも、あいまいな解析に直面して「正しい」ツリーを生成しません。

C++ フロント エンドを備えた DMS ソフトウェア リエンジニアリング ツールキットは、型情報なしでC++ ソースを解析でき、正確な「AST」を生成します。これらは実際には抽象的な構文のダグであり、ツリーのフォークは、言語の正確な文法 (あいまいな (サブ) パース)に従って、ソース コードのさまざまな解釈を表します。

Clang が試みているのは、解析時に型情報を使用して、これらの複数のサブ解析を生成しないようにすることです。DMS が行うことは、あいまいな解析を生成し、(オプションの) 解析後 (属性文法評価) パスで、シンボル テーブル情報を収集し、型と矛盾するサブ解析を排除することです。整形式のプログラムの場合、あいまいさのない単純な AST が生成されます。

OP が型情報についてヒューリスティックな推測をしたい場合は、これらの可能な解釈を知る必要があります。それらが事前に排除されている場合、彼はどのタイプが必要になるかを簡単に推測できません。興味深い可能性は、属性文法 (DMS の C++ フロント エンドの一部としてソース形式で提供される) を変更して、部分的な情報でこれを行うために、C++ の型規則をすべて知っているという考えです。標準から約 600 ページの難解な名前と型の解決規則を知る必要があることを考えると、ヒューリスティック アナライザーをゼロから構築するよりも、非常に有利なスタートとなります。

DMS のパーサーによって生成された (dag) の例を見ることができます。

于 2016-05-13T13:51:11.643 に答える