123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- import sys
- from pycparser import parse_file
- from pycparser.c_ast import *
- from pycparser.c_parser import CParser, Coord, ParseError
- from pycparser.c_lexer import CLexer
- def expand_decl(decl):
- """ Converts the declaration into a nested list.
- """
- typ = type(decl)
- if typ == TypeDecl:
- return ['TypeDecl', expand_decl(decl.type)]
- elif typ == IdentifierType:
- return ['IdentifierType', decl.names]
- elif typ == ID:
- return ['ID', decl.name]
- elif typ in [Struct, Union]:
- decls = [expand_decl(d) for d in decl.decls or []]
- return [typ.__name__, decl.name, decls]
- else:
- nested = expand_decl(decl.type)
- if typ == Decl:
- if decl.quals:
- return ['Decl', decl.quals, decl.name, nested]
- else:
- return ['Decl', decl.name, nested]
- elif typ == Typename: # for function parameters
- if decl.quals:
- return ['Typename', decl.quals, nested]
- else:
- return ['Typename', nested]
- elif typ == ArrayDecl:
- dimval = decl.dim.value if decl.dim else ''
- return ['ArrayDecl', dimval, nested]
- elif typ == PtrDecl:
- return ['PtrDecl', nested]
- elif typ == Typedef:
- return ['Typedef', decl.name, nested]
- elif typ == FuncDecl:
- if decl.args:
- params = [expand_decl(param) for param in decl.args.params]
- else:
- params = []
- return ['FuncDecl', params, nested]
- #-----------------------------------------------------------------
- class NodeVisitor(object):
- def __init__(self):
- self.current_parent = None
- def visit(self, node):
- """ Visit a node.
- """
- method = 'visit_' + node.__class__.__name__
- visitor = getattr(self, method, self.generic_visit)
- return visitor(node)
- def visit_FuncCall(self, node):
- print("Visiting FuncCall")
- print(node.show())
- print('---- parent ----')
- print(self.current_parent.show())
- def generic_visit(self, node):
- """ Called if no explicit visitor function exists for a
- node. Implements preorder visiting of the node.
- """
- oldparent = self.current_parent
- self.current_parent = node
- for c in node.children():
- self.visit(c)
- self.current_parent = oldparent
- def heapyprofile():
- # pip install guppy
- # [works on python 2.7, AFAIK]
- from guppy import hpy
- import gc
- hp = hpy()
- ast = parse_file('/tmp/197.c')
- gc.collect()
- h = hp.heap()
- print(h)
- def memprofile():
- import resource
- import tracemalloc
- tracemalloc.start()
- ast = parse_file('/tmp/197.c')
- print('Memory usage: %s (kb)' %
- resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)
- snapshot = tracemalloc.take_snapshot()
- print("[ tracemalloc stats ]")
- for stat in snapshot.statistics('lineno')[:20]:
- print(stat)
- if __name__ == "__main__":
- source_code = r'''void foo() {
- L"hi" L"there";
- }
- '''
- memprofile()
- #heapyprofile()
- #parser = CParser()
- #ast = parser.parse(source_code, filename='zz')
- #ast.show(showcoord=True, attrnames=True, nodenames=True)
|