Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 1 | import sys |
Eli Bendersky | 00de62c | 2015-04-18 06:55:42 -0700 | [diff] [blame^] | 2 | from pycparser import parse_file |
Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 3 | from pycparser.c_ast import * |
| 4 | from pycparser.c_parser import CParser, Coord, ParseError |
| 5 | from pycparser.c_lexer import CLexer |
| 6 | |
| 7 | |
| 8 | def expand_decl(decl): |
| 9 | """ Converts the declaration into a nested list. |
| 10 | """ |
| 11 | typ = type(decl) |
Eli Bendersky | 685818d | 2013-06-11 18:44:05 -0700 | [diff] [blame] | 12 | |
Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 13 | if typ == TypeDecl: |
| 14 | return ['TypeDecl', expand_decl(decl.type)] |
| 15 | elif typ == IdentifierType: |
| 16 | return ['IdentifierType', decl.names] |
| 17 | elif typ == ID: |
| 18 | return ['ID', decl.name] |
| 19 | elif typ in [Struct, Union]: |
| 20 | decls = [expand_decl(d) for d in decl.decls or []] |
| 21 | return [typ.__name__, decl.name, decls] |
Eli Bendersky | 685818d | 2013-06-11 18:44:05 -0700 | [diff] [blame] | 22 | else: |
Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 23 | nested = expand_decl(decl.type) |
Eli Bendersky | 685818d | 2013-06-11 18:44:05 -0700 | [diff] [blame] | 24 | |
Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 25 | if typ == Decl: |
| 26 | if decl.quals: |
| 27 | return ['Decl', decl.quals, decl.name, nested] |
| 28 | else: |
| 29 | return ['Decl', decl.name, nested] |
| 30 | elif typ == Typename: # for function parameters |
| 31 | if decl.quals: |
| 32 | return ['Typename', decl.quals, nested] |
| 33 | else: |
| 34 | return ['Typename', nested] |
| 35 | elif typ == ArrayDecl: |
| 36 | dimval = decl.dim.value if decl.dim else '' |
| 37 | return ['ArrayDecl', dimval, nested] |
| 38 | elif typ == PtrDecl: |
| 39 | return ['PtrDecl', nested] |
| 40 | elif typ == Typedef: |
| 41 | return ['Typedef', decl.name, nested] |
| 42 | elif typ == FuncDecl: |
| 43 | if decl.args: |
| 44 | params = [expand_decl(param) for param in decl.args.params] |
| 45 | else: |
| 46 | params = [] |
| 47 | return ['FuncDecl', params, nested] |
| 48 | |
| 49 | #----------------------------------------------------------------- |
| 50 | class NodeVisitor(object): |
eli.bendersky | 724b1cc | 2011-03-05 10:45:08 +0200 | [diff] [blame] | 51 | def __init__(self): |
Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 52 | self.current_parent = None |
Eli Bendersky | 685818d | 2013-06-11 18:44:05 -0700 | [diff] [blame] | 53 | |
Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 54 | def visit(self, node): |
Eli Bendersky | 685818d | 2013-06-11 18:44:05 -0700 | [diff] [blame] | 55 | """ Visit a node. |
Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 56 | """ |
| 57 | method = 'visit_' + node.__class__.__name__ |
| 58 | visitor = getattr(self, method, self.generic_visit) |
| 59 | return visitor(node) |
Eli Bendersky | 685818d | 2013-06-11 18:44:05 -0700 | [diff] [blame] | 60 | |
eli.bendersky | 3b52ac0 | 2011-03-18 06:32:23 +0200 | [diff] [blame] | 61 | def visit_FuncCall(self, node): |
Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 62 | print("Visiting FuncCall") |
| 63 | print(node.show()) |
| 64 | print('---- parent ----') |
| 65 | print(self.current_parent.show()) |
Eli Bendersky | 685818d | 2013-06-11 18:44:05 -0700 | [diff] [blame] | 66 | |
Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 67 | def generic_visit(self, node): |
Eli Bendersky | 685818d | 2013-06-11 18:44:05 -0700 | [diff] [blame] | 68 | """ Called if no explicit visitor function exists for a |
Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 69 | node. Implements preorder visiting of the node. |
| 70 | """ |
| 71 | oldparent = self.current_parent |
| 72 | self.current_parent = node |
| 73 | for c in node.children(): |
| 74 | self.visit(c) |
| 75 | self.current_parent = oldparent |
| 76 | |
| 77 | |
Eli Bendersky | 00de62c | 2015-04-18 06:55:42 -0700 | [diff] [blame^] | 78 | def memprofile(): |
| 79 | import resource |
| 80 | import tracemalloc |
| 81 | |
| 82 | tracemalloc.start() |
| 83 | |
| 84 | ast = parse_file('/tmp/197.c') |
| 85 | |
| 86 | print('Memory usage: %s (kb)' % |
| 87 | resource.getrusage(resource.RUSAGE_SELF).ru_maxrss) |
| 88 | |
| 89 | snapshot = tracemalloc.take_snapshot() |
| 90 | print("[ tracemalloc stats ]") |
| 91 | for stat in snapshot.statistics('lineno')[:20]: |
| 92 | print(stat) |
| 93 | |
| 94 | |
Eli Bendersky | 685818d | 2013-06-11 18:44:05 -0700 | [diff] [blame] | 95 | if __name__ == "__main__": |
Eli Bendersky | 8e5d3a9 | 2014-03-15 14:06:00 -0700 | [diff] [blame] | 96 | source_code = r'''void foo() { |
Eli Bendersky | c9f1a38 | 2014-03-15 14:12:00 -0700 | [diff] [blame] | 97 | L"hi" L"there"; |
Eli Bendersky | 8e5d3a9 | 2014-03-15 14:06:00 -0700 | [diff] [blame] | 98 | } |
Even | 13ad219 | 2011-11-06 16:02:43 +0100 | [diff] [blame] | 99 | ''' |
Eli Bendersky | a1da7fd | 2012-07-06 15:48:57 +0300 | [diff] [blame] | 100 | |
Eli Bendersky | 00de62c | 2015-04-18 06:55:42 -0700 | [diff] [blame^] | 101 | memprofile() |
| 102 | |
| 103 | #parser = CParser() |
| 104 | #ast = parser.parse(source_code, filename='zz') |
| 105 | #ast.show(showcoord=True, attrnames=True, nodenames=True) |
| 106 | |
| 107 | |