0

I am tring to parse a C code with pycparser with visitor for every IF statements. From my observation it only visits top nodes without nested IFs. Is it intentional, or something is wrong in my code?

Knight of Ni
  • 1,780
  • 3
  • 20
  • 47

2 Answers2

4

See the comment for the class: https://github.com/eliben/pycparser/blob/master/pycparser/c_ast.py#L107

The children of nodes for which a visit_XXX was defined will not be visited - if you need this, call generic_visit() on the node.

You can use:

NodeVisitor.generic_visit(self, node)

I tried this and it worked for me:

if_conditions.py

from __future__ import print_function
import sys

# This is not required if you've installed pycparser into
# your site-packages/ with setup.py
sys.path.extend(['.', '..'])

from pycparser import c_parser, c_ast, parse_file

class IfVisitor(c_ast.NodeVisitor):
    def __init__(self):
        pass

    def visit_If(self, node):
        node.show()
        self.generic_visit(node);



def start(filename):
    ast = parse_file(filename, use_cpp=True)
    v = IfVisitor()
    v.visit(ast)


if __name__ == "__main__":
    if len(sys.argv) > 2:
        filename = sys.argv[1]
    else:
        filename = 'examples/c_files/test.c'

    start(filename)

test.c

main ( int arc, char **argv ) {

    int i = 1;

    if (i > 1) {
        if (i > 2) {
            printf("Yay!");
        }
    }

    // code
    return 0; // Indicates that everything vent well.     
}
MartyIX
  • 27,828
  • 29
  • 136
  • 207
0

generic_visit() will do. Or, just re-visit child node.

https://github.com/eliben/pycparser/blob/master/examples/func_calls.py#L29

# A visitor with some state information (the funcname it's looking for)
class FuncCallVisitor(c_ast.NodeVisitor):
    def __init__(self, funcname):
        self.funcname = funcname

    def visit_FuncCall(self, node):
        if node.name.name == self.funcname:
            print('%s called at %s' % (self.funcname, node.name.coord))
        # Visit args in case they contain more func calls.
        if node.args:
            self.visit(node.args)

in this case(IF statement),

if node.iftrue:
    self.visit(node.iftrue)

if node.iffalse:
    self.visit(node.iffalse)
Kakarun
  • 11
  • 3