class ast_iterator¶
Iterator over the Abstract Syntax Trees (ASTs, ast ) in the tree rooted at a particular ast .
Initialize with ast.traverse().
At any point during traversal with an ast_iterator , ast_traverse_directives can be applied by invoking ast_iterator.apply_directives(). See the ast_iterator.apply_directives() documentation for an example.
Use as you would any other Python iterator. For example:
# set up ast myast, then...
for e in myast.traverse():
print('ast: ', e)
ast_iterator Members¶
| Constructors | none |
| Methods | __eq__(), __iter__(), __ne__(), __next__(), __repr__(), __str__(), apply_directives(), at_end() |
ast_iterator Details¶
-
class
cs.ast_iterator¶ Iterator over the Abstract Syntax Trees (ASTs,
ast) in the tree rooted at a particularast.-
__eq__(other)¶ Iterator equality.
Parameters: other ( ast_iterator) –Return type: bool Returns: Trueif and only ifselfandotherare at the same position. Behavior is undefined ifselfandotherare not iterating over the same collection.>>> foo = next(p for p in project.current().procedures() if p.name()=='foo') >>> call = next(p for p in foo.points() if p.get_kind()==point_kind.CALL_SITE) >>> myastitr = call.get_ast().traverse() >>> otherastitr = call.get_ast().traverse() >>> myastitr == otherastitr True >>> for a in myastitr: ... if a.get_class() == ast_class.NC_ADDREXPR: ... break ... >>> myastitr == otherastitr False
-
__iter__()¶ Get the iterator object.
Return type: ast_iteratorReturns: self.>>> v0 = project.current() >>> v1 = v0.lookup_symbol('foo') >>> v2 = v1.get_ast() >>> for it in v2.traverse(): # '__iter__' and '__next__' underlyingly manage iteration ... if it.get_class()==ast_class.NC_ROUTINE: ... break ... >>> it <cs.ast [c:routine] foo>
-
__ne__(other)¶ Iterator inequality.
Parameters: other ( ast_iterator) – The iterator to compare against.Return type: bool Returns: Falseif and only ifselfandotherare at the same position. Behavior is undefined ifselfandotherare not iterating over the same collection.>>> foo = next(p for p in project.current().procedures() if p.name()=='foo') >>> call = next(p for p in foo.points() if p.get_kind()==point_kind.CALL_SITE) >>> myastitr = call.get_ast().traverse() >>> otherastitr = call.get_ast().traverse() >>> myastitr != otherastitr False >>> for a in myastitr: ... if a.get_class() == ast_class.NC_ADDREXPR: ... break ... >>> myastitr != otherastitr True
-
__next__()¶ Iterator dereference operator.
Return type: astReturns: The element at the current iterator position. Raises: StopIteration- Side effects: Modifies
self.
The typical use is implicit:
>>> for item in myiter: ... (do something to item)
>>> v0 = project.current() >>> v1 = v0.lookup_symbol('foo') >>> v2 = v1.get_ast() >>> for it in v2.traverse(): # '__iter__' and '__next__' underlyingly manage iteration ... if it.get_class()==ast_class.NC_ROUTINE: ... break ... >>> it <cs.ast [c:routine] foo>
- Side effects: Modifies
-
__repr__()¶ Get a representation of the iterator that includes information useful for debugging.
Return type: str Returns: The string representation. >>> v0 = project.current() >>> v1 = v0.lookup_symbol('foo') >>> v2 = v1.get_type() >>> v3 = v2.traverse() >>> repr(v3) '<cs.ast_iterator begin>'
-
__str__()¶ Get a simple string representation of the iterator.
Return type: str Returns: The string representation. >>> v0 = project.current() >>> v1 = v0.lookup_symbol('foo') >>> v2 = v1.get_type() >>> v3 = v2.traverse() >>> str(v3) '<cs.ast_iterator begin>'
-
apply_directives(directives)¶ Apply
ast_traverse_directivesto anast_iterator.Parameters: directives ( ast_traverse_directives) – theast_traverse_directivesto apply.Return type: NoneType - Side effects: Modifies
self.
Invoke at any point during traversal to specify how traversal should proceed from/within the AST (
ast) at the current iterator position.>>> cu = next(c for c in project.current().compunits() ... if c.name().endswith('apitest.cpp')) >>> proc = next(p for p in cu.procedures() if p.name()=='bar') >>> # get first call site to bar() in function bar() >>> csite = next (pt for pt in proc.points() ... if pt.get_kind()==point_kind.CALL_SITE and pt.callee().name()=='bar') >>> csite <cs.point [call-site] bar(int, void *, int)> >>> # get the actual-in point of rank 2 at csite (because it has a moderately interesting AST) >>> second_actualin = csite.actual_in(2) >>> second_actualin <cs.point [actual-in] $param_2 = (void*)0> >>> second_actualin_ast = second_actualin.get_ast() >>> # traverse with no directives >>> for a in second_actualin_ast.traverse(): ... print(a, '|', a.get_class(), '|', a.children()) ... $param_2 = (void*)0 | c:= | (<cs.ast_field 1:[c:variable] $param_2>, <cs.ast_field 2:[c:cast] (void*)0>) $param_2 | c:variable | (<cs.ast_field name:$param_2>,) (void*)0 | c:cast | (<cs.ast_field 1:[c:pointer] void*>, <cs.ast_field 2:[c:integer-value-32] 0>) void* | c:pointer | () 0 | c:integer-value-32 | (<cs.ast_field value:0>,) >>> # traverse, skipping over children of c:cast ASTs >>> astiter = second_actualin_ast.traverse() >>> for a in astiter: ... if a.get_class() == ast_class.NC_CASTEXPR: ... astiter.apply_directives(ast_traverse_directives.SKIP_CHILDREN) ... print(a, '|', a.get_class(), '|', a.children()) ... $param_2 = (void*)0 | c:= | (<cs.ast_field 1:[c:variable] $param_2>, <cs.ast_field 2:[c:cast] (void*)0>) $param_2 | c:variable | (<cs.ast_field name:$param_2>,) (void*)0 | c:cast | (<cs.ast_field 1:[c:pointer] void*>, <cs.ast_field 2:[c:integer-value-32] 0>
- Side effects: Modifies
-
at_end()¶ Check: is the iterator at the end of the structure?
Return type: bool Returns: Trueif the iterator is at the end of the structure (there are no more elements to iterate over),Falseotherwise.>>> v0 = project.current() >>> v1 = v0.lookup_symbol('foo') >>> v2 = v1.get_ast() >>> v3 = v2.traverse() >>> v3.at_end() False
-