Python pycparser(c文件解析)模块使用教程
文章目录
- 安装 pycparser 模块
- 模块开发者网址
- 获取抽象语法树
-
- 1. 需要导入的模块
- 2. 获取 不关注预处理相关 c语言文件的抽象语法树ast
- 3. 获取 预处理后的c语言文件的抽象语法树ast
- 语法树组成
-
- 1. 数据类型定义 Typedef
- 2. 类型声明 TypeDecl
- 3. 标识符类型 IdentifierType
- 4. 变量声明 Decl
- 5. 常量 Constant
- 6. 函数定义 FuncDef
- 7. 函数声明 FuncDecl
- 8. 函数参数列表 ParamList
- 9. 代码块 Compound
- to do
感谢这两篇文章对于我学习之初的帮助
https://blog.csdn.net/u011079613/article/details/122462729
https://blog.csdn.net/qq_38808667/article/details/118059074
安装 pycparser 模块
pip install pycparser -i https://mirrors.aliyun.com/pypi/simple/
模块开发者网址
https://github.com/eliben/pycparser
获取抽象语法树
1. 需要导入的模块
# parser_file 用于处理c语言文件 from pycparser import parse_file from pycparser import CParser # c语言有错误时,会引出此错误 from pycparser.plyparser import ParseError # c_ast.py 文件下包含了抽象语法树的节点类 from pycparser.c_ast import *
2. 获取 不关注预处理相关 c语言文件的抽象语法树ast
文件中需删除 #开头 预处理代码,不能有注释代码
- 方法1:
ast = parse_file(filename, use_cpp = False)
- 方法2:
with open(filename, encoding='utf-8',) as f: txt = f.read() ast = CParser().parse(txt) # 使用此方法需要 删除头文件
3. 获取 预处理后的c语言文件的抽象语法树ast
获取c语言文件的抽象语法树ast,如果要处理 #include 等语句,需要下载fake_libc_include文件夹,让编译器预处理常用的方法(添加其到代码的抽象语法树中)
点击此处下载 fake_libc_include

cpp_args必须加上 -E , 否则返回的抽象语法树是个空列表
ast = parse_file(filename, use_cpp = True, cpp_path=r'C:\MinGW\bin\gcc.exe', cpp_args=['-E', r'-Iutils/fake_libc_include'])
使用 parse_file 类获取 预处理后的c语言文件的抽象语法树ast
| parse_file 参数 | 说明 |
|---|---|
| filename | 需要解析的 .c 文件名 |
| use_cpp | 是否使用本地c语言编译器预处理代码,去掉其中的#命令(头文件、宏定义、pragma)值:False/True |
| cpp_path | 本地c语言编译器路径 |
| cpp_args | fake_libc_include文件夹路径,需要在路径添加 -I 指明所包头文件路径; use_cpp=True 时使用 |
语法树组成
抽象语法树 ast 类型为
其解析的具体内容通过 print(ast.ext) 查看,ext 数据类型为列表
FileAST 下级节点只有 3 种可能 :
- Typedef :typedef 数据类型定义
- Decl :变量声明
- FuncDef :函数声明
示例:
test.c
typedef int uint32;
int g =0;
int add(int a, int b)
{
int c = 0;
c = a + b;
return c;
}
int main(void)
{
printf("hello world");
return 0;
}
cparser.py
# parser_file 用于处理c语言文件
from pycparser import parse_file
from pycparser import CParser
# c语言有错误时,会引出此错误
from pycparser.plyparser import ParseError
# c_ast.py 文件下包含了抽象语法树的节点类
from pycparser.c_ast import *
filename = 'test.c'
ast = parse_file(filename, use_cpp = False)
print(type(ast))
for eachNode in ast.ext:
print(eachNode.__class__.__name__) # 打印节点类型名
#print(eachNode) # 打印节点内容
输出

1. 数据类型定义 Typedef
Typedef 数据结构类型
数据类型定义 Typedef 属性如下:
- Typedef.name = str (Typedef 定义对象)
- Typedef.quals = [str] (限定符号列表: const, volatile)
- Typedef.storage = [str] (存储说明符列表: extern, register, etc.)
- Typedef.type = Node (TypeDecl节点)
- Typedef.coord= str(定义对象所在行列)
- Typedef.coord.column= str(定义对象所在列)
- Typedef.coord.line= str(定义对象所在行)
- Typedef.coord.file= str(定义对象所在文件)
示例:
test.c
typedef const int cuint32;
cparser.py
# parser_file 用于处理c语言文件
from pycparser import parse_file
from pycparser import CParser
# c语言有错误时,会引出此错误
from pycparser.plyparser import ParseError
# c_ast.py 文件下包含了抽象语法树的节点类
from pycparser.c_ast import *
filename = 'test.c'
ast = parse_file(filename, use_cpp = False)
print(type(ast.ext[0]))
print('name = ', ast.ext[0].name) # Typedef 定义对象
print('quals = ', ast.ext[0].quals)
print('storage = ', ast.ext[0].storage)
print('type = ', ast.ext[0].type)
print('coord = ', ast.ext[0].coord)
输出

2. 类型声明 TypeDecl
Typedef 的下一级 类型声明 TypeDecl 是以typedef语句格式为中心
类型声明 TypeDecl 属性如下:
- TypeDecl.declname= str (typedef定义对象)
- TypeDecl.quals = [str] (限定符号列表: const, volatile)
- TypeDecl.align= [str] (暂不清楚)
- TypeDecl.type = Node ( IdentifierType节点)
- TypeDecl.coord= str(定义对象所在行列)
- TypeDecl.coord.column= str(定义对象所在列)
- TypeDecl.coord.line= str(定义对象所在行)
- TypeDecl.coord.file= str(定义对象所在文件)
示例:
test.c
typedef const int cuint32;
cparser.py
# parser_file 用于处理c语言文件
from pycparser import parse_file
from pycparser import CParser
# c语言有错误时,会引出此错误
from pycparser.plyparser import ParseError
# c_ast.py 文件下包含了抽象语法树的节点类
from pycparser.c_ast import *
filename = 'test.c'
ast = parse_file(filename, use_cpp = False)
print(type(ast.ext[0].type))
my_typeDecl = ast.ext[0].type
print('name = ', my_typeDecl.declname) # Typedef 定义对象
print('quals = ', my_typeDecl.quals)
print('type = ', my_typeDecl.type)
print('storage = ', my_typeDecl.align)
print('coord = ', my_typeDecl.coord)
print('coord.column = ', my_typeDecl.coord.column) # (定义对象所在列)
print('coord.line = ', my_typeDecl.coord.line) # (定义对象所在行)
print('coord.file = ', my_typeDecl.coord.file) # (定义对象所在文件)
输出

3. 标识符类型 IdentifierType
TypeDecl 的下一级 标识符类型 IdentifierType 是简单标识符,比如 void, char 定义之类
原数据类型 :
标识符类型 IdentifierType 属性如下:
- IdentifierType.name = [str] (标识符字符串列表)
- IdentifierType.coord= str(定义对象所在行列)
- IdentifierType.coord.column= str(定义对象所在列)
- IdentifierType.coord.line= str(定义对象所在行)
- IdentifierType.coord.file= str(定义对象所在文件)
4. 变量声明 Decl
Decl 数据结构类型
变量声明 Decl 属性如下:
- Decl.name = str (被声明的变量名)
- Decl.quals = [str] (限定符号列表: const, volatile)
- Decl.align= [str] (暂不清楚)
- Decl.storage = [str] (存储说明符列表: extern, register, static等)
- Decl.funcspec = [str] (函数说明符列表: C99的inline)
- Decl.type = Node (TypeDecl 节点)
- Decl.init = Node (初始化值,Constant节点)
- Decl.bitsize = Node (位域bit field大小,或者为None)
- Decl.coord= str(定义对象所在行列)
- Decl.coord.column= str(定义对象所在列)
- Decl.coord.line= str(定义对象所在行)
- Decl.coord.file= str(定义对象所在文件)
示例:
test.c
typedef const int cuint32; static const int g =0;
cparser.py
# parser_file 用于处理c语言文件
from pycparser import parse_file
from pycparser import CParser
# c语言有错误时,会引出此错误
from pycparser.plyparser import ParseError
# c_ast.py 文件下包含了抽象语法树的节点类
from pycparser.c_ast import *
filename = 'test.c'
ast = parse_file(filename, use_cpp = False)
print(type(ast.ext[1]))
my_ext = ast.ext[1]
print('name = ', ast.ext[1].name) # Typedef 定义对象
print('quals = ', ast.ext[1].quals)
print('align = ', ast.ext[1].align)
print('storage = ', ast.ext[1].storage)
print('funcspec = ', ast.ext[1].funcspec)
print('type = ', ast.ext[1].type)
print('init = ', ast.ext[1].init)
print('bitsize = ', ast.ext[1].bitsize)
print('coord = ', ast.ext[1].coord)
输出

5. 常量 Constant
常量 Constant 属性如下:
- Constant.type= str (基本数据类型,int等)
- Constant.value= str (数值)
- Constant.coord= str(定义对象所在行列)
- Constant.coord.column= str(定义对象所在列)
- Constant.coord.line= str(定义对象所在行)
- Constant.coord.file= str(定义对象所在文件)
6. 函数定义 FuncDef
FuncDef 方法定义,不同于 FuncDecl,有具体的函数实现过程
函数定义 FuncDef 属性如下:
- FuncDef.decl = Node (一般是包含Decl的节点)
- param_decls=None (暂不清楚)
- FuncDef.body = Node (函数实现的代码块 一般是包含Compound 的节点)
- FuncDef.coord= str(标识符字符串所在行列)
- FuncDef.coord.column= str(定义对象所在列)
- FuncDef.coord.line= str(定义对象所在行)
- FuncDef.coord.file= str(定义对象所在文件)
7. 函数声明 FuncDecl
FuncDecl 既可以单独存在,也可以是函数定义的一部分
函数定义 FuncDecl 属性如下:
- FuncDecl.args= Node (一般是包含ParamList的节点)
- FuncDecl.type= [str] (一般是包含TypeDecl的节点)
8. 函数参数列表 ParamList
以 list 形式,可遍历 参数
函数定义 ParamList 属性如下:
- ParamList.params= [str](有哪些参数 ,一般是包含Decl的节点)
9. 代码块 Compound
以 list 形式,可遍历 代码块内容
函数定义 Compound 属性如下:
- Compound .block_items= [str](有哪些参数 ,一般是包含 Decl Assignment 和 Return的节点)
to do
解析任意编程语言 tree-sitter
本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/d9bc8b7692.html
