Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 获取指定函数中调用的所有函数_Python_C_Pycparser - Fatal编程技术网

Python 获取指定函数中调用的所有函数

Python 获取指定函数中调用的所有函数,python,c,pycparser,Python,C,Pycparser,我正在使用pycparser解析C代码。我的目标是,给定一个C代码和一个函数名,列出指定函数中调用的所有函数 我查看了pycparser的文档,但找不到任何具体解决此问题的方法 我想要与cscope相同的功能: Functions called by this function: ksw_extd2_sse41 File Function Line 0 ksw2_extd2_sse.c ksw_reset_extz 59 ksw_reset

我正在使用pycparser解析C代码。我的目标是,给定一个C代码和一个函数名,列出指定函数中调用的所有函数

我查看了pycparser的文档,但找不到任何具体解决此问题的方法

我想要与cscope相同的功能:

Functions called by this function: ksw_extd2_sse41

  File             Function          Line
0 ksw2_extd2_sse.c ksw_reset_extz     59 ksw_reset_extz(ez);
1 ksw2_extd2_sse.c _mm_set1_epi8      64 zero_ = _mm_set1_epi8(0);
2 ksw2_extd2_sse.c _mm_set1_epi8      65 q_ = _mm_set1_epi8(q);
3 ksw2_extd2_sse.c _mm_set1_epi8      66 q2_ = _mm_set1_epi8(q2);
4 ksw2_extd2_sse.c _mm_set1_epi8      67 qe_ = _mm_set1_epi8(q + e);
5 ksw2_extd2_sse.c _mm_set1_epi8      68 qe2_ = _mm_set1_epi8(q2 + e2);
6 ksw2_extd2_sse.c _mm_set1_epi8      69 sc_mch_ = _mm_set1_epi8(mat[0]);
7 ksw2_extd2_sse.c _mm_set1_epi8      70 sc_mis_ = _mm_set1_epi8(mat[1]);
8 ksw2_extd2_sse.c _mm_set1_epi8      71 sc_N_ = mat[m*m-1] == 0? _mm_set1_epi8(-e2) : _mm_set1_epi8(mat[m*m-1]);
9 ksw2_extd2_sse.c _mm_set1_epi8      72 m1_ = _mm_set1_epi8(m - 1);
a ksw2_extd2_sse.c kcalloc            92 mem = (uint8_t*)kcalloc(km, tlen_ * 8 + qlen_ + 1, 16);
b ksw2_extd2_sse.c memset             97 memset(u, -q - e, tlen_ * 16);
c ksw2_extd2_sse.c memset             98 memset(v, -q - e, tlen_ * 16);
d ksw2_extd2_sse.c memset             99 memset(x, -q - e, tlen_ * 16);
e ksw2_extd2_sse.c memset            100 memset(y, -q - e, tlen_ * 16);

* Lines 1-16 of 278, 263 more - press the space bar to display more *

我解决了。下面的visitor类打印代码库中所有函数的每个函数调用

class Visitor(c_ast.NodeVisitor):
    def visit_FuncDef(self, node):
        for stmt in node.body.block_items or []:
            if isinstance(stmt, c_ast.FuncCall):
                print (f"Function {node.decl.name} calls {stmt.name.name}")
嵌套访问者就可以了。 访问funccallin FuncDef访问者,如下所示

您的代码将只访问1个深度的函数调用

class FuncCallVisitor(c_ast.NodeVisitor):
    def __init__(self):
        self.callees = []  
    def visit_FuncCall(self, node):
        self.callees.append(node.name.name)

        # nested funccall
        if node.args:
            self.visit(node.args)

class FuncDefVisitor(c_ast.NodeVisitor):
    def visit_FuncDef(self, node):
        fcv = FuncCallVisitor()
        fcv.visit(node.body)

        print(fcv.callees) # calles has all funccall in this funcdef

另一个选项是让cscope为您完成工作并解析cscope数据库。这可能有用。谢谢你的建议。但我不确定如何解析cscope.out文件。如果我要解析,仅仅解析源代码不是更好吗?我认为解析代码会更困难,因为您必须忽略注释和带引号的字符串,以及处理宏和#ifdef。几年前我创建了一个工具,它必须存储函数树。我所做的是使用C编译器为每个函数生成汇编代码,然后解析结果。由于汇编有一个通常很小的指令集和一个固定的格式,所以解析要比C容易得多。pycparser为我处理这些事情。所以我不必担心。转移到组装是我的备用计划,我真的很想避免。这里还有一个例子:谢谢。这个例子和我想要的略有不同。该示例列出了文件中的所有函数调用。我想要函数定义中的所有函数调用。你是指函数定义中的函数定义吗?这在C语言中是允许的吗?不,我的意思是在另一个funccall中funccall,或者在if语句中funccall…或者别的什么。是的,它适用于循环中的函数调用、if语句和其他块。但我不知道它是如何在funccalls中为funccalls工作的。您的意思是main的被调用方应该是将被调用的所有函数吗?
outer\u func(internal\u func(param))
在这种情况下,如果您不调用self.visit(node.args)或self.generic\u visit(),FuncCallVisitor将只访问outer\u func。请参见“是”,但
内部函数是FuncCall,而不是FuncDef。因此,内部函数中调用的函数将不会列出。