blob: 098081d9516fe9154b76cdf6cad65948214c0b69 [file] [log] [blame]
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001import sys
2from pycparser.c_ast import *
3from pycparser.c_parser import CParser, Coord, ParseError
4from pycparser.c_lexer import CLexer
5
6
7def expand_decl(decl):
8 """ Converts the declaration into a nested list.
9 """
10 typ = type(decl)
Eli Bendersky685818d2013-06-11 18:44:05 -070011
Eli Benderskya1da7fd2012-07-06 15:48:57 +030012 if typ == TypeDecl:
13 return ['TypeDecl', expand_decl(decl.type)]
14 elif typ == IdentifierType:
15 return ['IdentifierType', decl.names]
16 elif typ == ID:
17 return ['ID', decl.name]
18 elif typ in [Struct, Union]:
19 decls = [expand_decl(d) for d in decl.decls or []]
20 return [typ.__name__, decl.name, decls]
Eli Bendersky685818d2013-06-11 18:44:05 -070021 else:
Eli Benderskya1da7fd2012-07-06 15:48:57 +030022 nested = expand_decl(decl.type)
Eli Bendersky685818d2013-06-11 18:44:05 -070023
Eli Benderskya1da7fd2012-07-06 15:48:57 +030024 if typ == Decl:
25 if decl.quals:
26 return ['Decl', decl.quals, decl.name, nested]
27 else:
28 return ['Decl', decl.name, nested]
29 elif typ == Typename: # for function parameters
30 if decl.quals:
31 return ['Typename', decl.quals, nested]
32 else:
33 return ['Typename', nested]
34 elif typ == ArrayDecl:
35 dimval = decl.dim.value if decl.dim else ''
36 return ['ArrayDecl', dimval, nested]
37 elif typ == PtrDecl:
38 return ['PtrDecl', nested]
39 elif typ == Typedef:
40 return ['Typedef', decl.name, nested]
41 elif typ == FuncDecl:
42 if decl.args:
43 params = [expand_decl(param) for param in decl.args.params]
44 else:
45 params = []
46 return ['FuncDecl', params, nested]
47
48#-----------------------------------------------------------------
49class NodeVisitor(object):
eli.bendersky724b1cc2011-03-05 10:45:08 +020050 def __init__(self):
Eli Benderskya1da7fd2012-07-06 15:48:57 +030051 self.current_parent = None
Eli Bendersky685818d2013-06-11 18:44:05 -070052
Eli Benderskya1da7fd2012-07-06 15:48:57 +030053 def visit(self, node):
Eli Bendersky685818d2013-06-11 18:44:05 -070054 """ Visit a node.
Eli Benderskya1da7fd2012-07-06 15:48:57 +030055 """
56 method = 'visit_' + node.__class__.__name__
57 visitor = getattr(self, method, self.generic_visit)
58 return visitor(node)
Eli Bendersky685818d2013-06-11 18:44:05 -070059
eli.bendersky3b52ac02011-03-18 06:32:23 +020060 def visit_FuncCall(self, node):
Eli Benderskya1da7fd2012-07-06 15:48:57 +030061 print("Visiting FuncCall")
62 print(node.show())
63 print('---- parent ----')
64 print(self.current_parent.show())
Eli Bendersky685818d2013-06-11 18:44:05 -070065
Eli Benderskya1da7fd2012-07-06 15:48:57 +030066 def generic_visit(self, node):
Eli Bendersky685818d2013-06-11 18:44:05 -070067 """ Called if no explicit visitor function exists for a
Eli Benderskya1da7fd2012-07-06 15:48:57 +030068 node. Implements preorder visiting of the node.
69 """
70 oldparent = self.current_parent
71 self.current_parent = node
72 for c in node.children():
73 self.visit(c)
74 self.current_parent = oldparent
75
76
Eli Bendersky685818d2013-06-11 18:44:05 -070077if __name__ == "__main__":
Eli Benderskya1da7fd2012-07-06 15:48:57 +030078 source_code = r'''
Eli Bendersky3877c4c2013-07-13 06:54:04 -070079
Eli Benderskye7c55cf2014-01-25 06:15:43 -080080void f(int x[10]);
Even13ad2192011-11-06 16:02:43 +010081 '''
Eli Benderskya1da7fd2012-07-06 15:48:57 +030082
Eli Bendersky685818d2013-06-11 18:44:05 -070083 parser = CParser()
Eli Benderskya1da7fd2012-07-06 15:48:57 +030084 ast = parser.parse(source_code, filename='zz')
85 ast.show(showcoord=False, attrnames=True, nodenames=True)
Eli Benderskya1da7fd2012-07-06 15:48:57 +030086
Eli Benderskya1da7fd2012-07-06 15:48:57 +030087