Pythonバインディングを介してlibclangを使い始めたところです。を使用して構文ツリー (AST) 全体をトラバースできることは理解していますが、関心のないサブツリーをスキップできる関数 (またはそれが呼ばれる可能性のある関数)get_children
を見つけることができませんでした。get_next_sibling()
そのような機能は存在しますか?
1597 次
3 に答える
3
関数が Python API に存在するとは思いませんget_next_sibling
が、それが必要な理由もわかりません。
Python API では、AST の各ノードはそのすべての子を認識しているため、興味のないサブツリーをスキップすることは、親の子のループでスキップするだけで簡単に実行できます。libclang Python API に関する Eli Bendersky の優れたブログ投稿の例を再利用します。
def find_typerefs(node, typename):
""" Find all references to the type named 'typename'
"""
if node.kind.is_reference():
ref_node = clang.cindex.Cursor_ref(node)
if ref_node.spelling == typename:
print 'Found %s [line=%s, col=%s]' % (
typename, node.location.line, node.location.column)
# Recurse for children of this node,
# skipping all nodes not beginning with "a"
for c in node.get_children():
if c.spelling.startswith ("a"):
find_typerefs(c, typename)
于 2013-05-27T09:38:53.887 に答える
3
francesco が指摘したように、要素をスキップすることは可能です。ただし、最新の cindex.py リビジョンの変更により、言及されたコード例は機能しなくなりました。
以下は、AST から特定のノードを取得するための最小限の例です。
example.cpp ファイル:
int i;
char var[10];
double tmp;
int add (int a, int b)
{
int r;
r=a+b;
return (r);
}
Python コードの例:
import sys
from clang.cindex import *
index = Index.create()
tu = index.parse('example.cpp')
root_node = tu.cursor
#for further working with children nodes i tend to save them in a seperate list
#wanted nodes in extra list "result"
wanted_nodes = ['var', 'tmp']
result = []
node_list= []
for i in node.get_children():
node_list.append(i)
for i in node_list:
if i.spelling in wanted_nodes:
result.append(i)
#now result contains the two nodes "var" and "add"
#print the name
for i in result:
print i.spelling
#print the type
for i in result:
print i.type.kind
######OUTPUT#######
>>> var
>>> add
>>> TypeKind.CONSTANTARRAY
>>> TypeKind.DOUBLE
さらに配列の各要素のタイプが必要な場合は、次のようにします。
result[1].type.element_type.kind
#######OUTPUT######
>>> TypeKind.CHAR_S
モジュール cindex.pyは十分に文書化されているため、必要な情報を取得する方法を見つけるのは難しくありません。
于 2013-06-19T13:47:44.067 に答える