You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.2 KiB

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)