2012-04-11 5 views
12

私はいくつかのC++のコードで次のマクロを使用している場合:パーサーとしてCLANG、スクリプト言語としてPythonを使用して、C++コードでマクロを解析するにはどうすればよいですか?

_Foo(arg1, arg2) 

私は私のすべてのインスタンスとクランを使用して、そのマクロのエクステントとcindex.pyを提供するPythonバインディングを見つけるためにはPythonを使用したいと思います。コードでPythonの正規表現を直接使用したくないのは、それが私には99%の方法しか得られないが100%ではないからです。 100%になるためには、文法的に正しいコンパイルをしているが正規表現には意味をなさないばかげたことをすべて処理するために、Clangのような実際のC++パーサを使用する必要があります。私は100%のケースを処理する必要があり、私たちがコンパイラの1つとしてClangを使用しているので、それをこのタスクのパーサーとしても使用するのは理にかなっています。

私は事前に定義されたクランのPythonバインディングが知っているタイプではなく、マクロのように見えるものを見つけることができる午前次のPythonコードを考える:私は私が探しています何を考えて

def find_typerefs(node): 
    ref_node = clang.cindex.Cursor_ref(node) 
    if ref_node: 
     print 'Found %s Type %s DATA %s Extent %s [line=%s, col=%s]' % (
      ref_node.spelling, ref_node.kind, node.data, node.extent, node.location.line, node.location.column) 

# Recurse for children of this node 
for c in node.get_children(): 
    find_typerefs(c) 

index = clang.cindex.Index.create() 
tu = index.parse(sys.argv[1]) 
find_typerefs(tu.cursor) 

はへの道であります生のASTをマクロ_FOO()の名前で解析しますが、わかりません。誰かがマクロの名前を渡して、Clangからエクステントやデータを取得できるようにするコードを提供することはできますか?

+1

'sの/ CLANG/Clang/g' –

+4

私はClangを使用していませんが、ASTであなたのマクロを見つけることはできません。 C++コンパイルの段階(http://stackoverflow.com/questions/8833524/what-are-the-stages-of-compilation-of-ac-program)を見ると、前処理部分でマクロが「消えて」いるコンパイル前に完了し、ASTが生成されます。この時点では、マクロは完全にマクロの内容に置き換えられて存在しません。私はClangの前処理部分を調べ、そこから得られるものを見ていきます。 – uesp

+4

@uespまあ、Clangは単なるコンパイラではありません。 *偉大な*診断を提供しようと努力する*偉大な*コンパイラです。だからマクロ*はClangで追跡されています(マクロの出現について[クラスリスト](http://clang.llvm.org/doxygen/annotated.html)をチェックしてください)。私は非常に驚くべきことに、たとえそれが構文違反のマクロを犯したとしても、OPのような機能的なマクロでは非常に可能だと思います。 – delnan

答えて

0

私はかつて、libclangから取得したAST全体を事前テストするスクリプトを書いて、どの情報がどこにあるのかを確認しました。

ここでは、次のとおりです。https://gist.github.com/2503232

8

あなたはIndex.parseに適切なoptionsフラグを渡す必要があります:

tu = index.parse(sys.argv[1], options=clang.cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD) 

カーソル訪問者の残りの部分は次のようになります。

def visit(node): 
    if node.kind in (clang.cindex.CursorKind.MACRO_INSTANTIATION, clang.cindex.CursorKind.MACRO_DEFINITION): 
     print 'Found %s Type %s DATA %s Extent %s [line=%s, col=%s]' % (node.displayname, node.kind, node.data, node.extent, node.location.line, node.location.column) 
    for c in node.get_children(): 
     visit(c) 
関連する問題