How to skip subtrees bypassing AST using python bindings for libclang

I just started using libclang through python bindings. I understand that I can traverse the entire syntax tree (AST) with get_children , but I could not find the get_next_sibling() function (or anything else that it can be called) so that I can skip subtrees that are of no interest Is there such a function?

+4
source share
3 answers

As Francesco noted, you can skip the elements. The above code example does not work anymore due to changes in the latest version of cindex.py.

The following is a minimal example of getting specific nodes from AST.

example.cpp file:

 int i; char var[10]; double tmp; int add (int a, int b) { int r; r=a+b; return (r); } 

Python code example:

 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 

if you want the type of each element of the array u to go through:

 result[1].type.element_type.kind #######OUTPUT###### >>> TypeKind.CHAR_S 

since modul cindex.py is well documented, it should not be difficult to find how to get the necessary information.

+3
source

I do not think that the get_next_sibling function exists in the Python API, but I also do not understand why you need it.

In the python API, each node in the AST knows about all its children, so skipping uninteresting subtrees is easy by simply looping them over the parent children. Reusing the example from Eli Bendersky is an excellent blog post about the Python libclang API :

 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) 
+2
source

In terms of clang-c, the CXChildVisitResult enumeration has 3 meanings, and CXChildVisit_Continue skips visiting children, so the visitor comes to the next brother. Something similar should be in python.

-1
source

Source: https://habr.com/ru/post/1482873/


All Articles