gpt4 book ai didi

c - 如何为 pycparser 预处理 C 源代码

转载 作者:搜寻专家 更新时间:2023-10-31 00:11:32 24 4
gpt4 key购买 nike

我需要用 pycparser 解析我的 C 和 C++ 代码, 但之前需要去除预处理器指令和注释。

那么,你知道有什么方法可以做到这一点吗?我找到了 CPP预处理器,但我不知道我是否可以像那样使用它而无需“完整”预处理。

我找到了一个工具 unifdef也,这似乎完全符合我的要求,但仅限于预处理器条件(例如 #ifdef)。

我不想自己写这个工具,因为它要用于一个相当大的项目,所以我想使用一些非常复杂的东西。


我的尝试:

我试图找到在这段代码中调用函数 test 的地方:

#include <stdio.h>

// asdfdsa
/* sadfsd
*
*/

void test() {
printf("asd");
}

int main() {

test();

test();

return 0;
}

我使用命令 gcc -E -std=c99 test.c -o testP.c 预处理了这段代码,然后我尝试使用这段 Python 代码查找函数调用:

#-----------------------------------------------------------------
# pycparser: func_defs.py
#
# Using pycparser for printing out all the calls of some function
# in a C file.
#
# Copyright (C) 2008-2015, Eli Bendersky
# License: BSD
#-----------------------------------------------------------------
from __future__ import print_function
import sys

# This is not required if you've installed pycparser into
# your site-packages/ with setup.py
sys.path.extend(['.', '..'])

from pycparser import c_parser, c_ast, parse_file


# A visitor with some state information (the funcname it's
# looking for)
#
class FuncCallVisitor(c_ast.NodeVisitor):
def __init__(self, funcname):
self.funcname = funcname

def visit_FuncCall(self, node):
if node.name.name == self.funcname:
print('%s called at %s' % (self.funcname, node.name.coord))


def show_func_calls(filename, funcname):
ast = parse_file(filename, use_cpp=True)
v = FuncCallVisitor(funcname)
v.visit(ast)

if __name__ == "__main__":
if len(sys.argv) > 2:
filename = sys.argv[1]
func = sys.argv[2]
else:
filename = 'test.c'
func = 'test'

show_func_calls(filename, func)

但是,我仍然收到这个错误:

Traceback (most recent call last):
File "func_calls.py", line 46, in <module>
show_func_calls(filename, func)
File "func_calls.py", line 33, in show_func_calls
ast = parse_file(filename, use_cpp=True)
File "/usr/local/lib/python2.7/dist-packages/pycparser/__init__.py", line 93, in parse_file
return parser.parse(text, filename)
File "/usr/local/lib/python2.7/dist-packages/pycparser/c_parser.py", line 146, in parse
debug=debuglevel)
File "/usr/local/lib/python2.7/dist-packages/pycparser/ply/yacc.py", line 265, in parse
return self.parseopt_notrack(input,lexer,debug,tracking,tokenfunc)
File "/usr/local/lib/python2.7/dist-packages/pycparser/ply/yacc.py", line 1047, in parseopt_notrack
tok = self.errorfunc(errtoken)
File "/usr/local/lib/python2.7/dist-packages/pycparser/c_parser.py", line 1691, in p_error
column=self.clex.find_tok_column(p)))
File "/usr/local/lib/python2.7/dist-packages/pycparser/plyparser.py", line 55, in _parse_error
raise ParseError("%s: %s" % (coord, msg))
pycparser.plyparser.ParseError: /usr/lib/gcc/x86_64-linux-gnu/4.9/include/stdarg.h:40:27: before: __gnuc_va_list

最佳答案

pycparser 文档特别 says您应该使用cppgcc -E 来准备要解析的源代码。因此,“完整”预处理不是 cpp问题,它是您在代码上运行 pycparser 所需的功能。

如果您简单地去除所有预处理器指令的代码,解析将失败,因为未声明的类型(如 int32_tsize_t)和库函数缺少原型(prototype)。

编辑:pycparser 仅支持 C99 语法。如果 gcc 出于某种原因将您的代码用于 C++,请像这样运行预处理器:

gcc -E -std=c99

EDIT2:您似乎遇到了更多与编译器特定符号相关的错误。尝试使用 "fake" headerspycparser 提供:

gcc -E -std=c99 -I/path/to/pycparser/utils/fake_libc_include

关于c - 如何为 pycparser 预处理 C 源代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33763611/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com