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 类型为 <class 'pycparser.c_ast.FileAST'>
其解析的具体内容通过 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 数据结构类型 <class 'pycparser.c_ast.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].typeprint('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 定义之类
原数据类型 : <class 'pycparser.c_ast.IdentifierType'>
标识符类型 IdentifierType 属性如下:
IdentifierType.name = [str](标识符字符串列表)IdentifierType.coord= str(定义对象所在行列)IdentifierType.coord.column= str(定义对象所在列)IdentifierType.coord.line= str(定义对象所在行)IdentifierType.coord.file= str(定义对象所在文件)
4. 变量声明 Decl
Decl 数据结构类型 <class 'pycparser.c_ast.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
相关文章:
Python pycparser(c文件解析)模块使用教程
文章目录 安装 pycparser 模块模块开发者网址获取抽象语法树1. 需要导入的模块2. 获取 不关注预处理相关 c语言文件的抽象语法树ast3. 获取 预处理后的c语言文件的抽象语法树ast 语法树组成1. 数据类型定义 Typedef2. 类型声明 TypeDecl3. 标识符类型 IdentifierType4. 变量声明…...
解决IDEA tomcat控制台只有server日志
解决IDEA tomcat控制台只有server日志 确认tomcatxxx/conf/logging.properties文件是否存在,存在就会有。前提是在run configuration配置了打印多个日志...
Java版本+企业电子招投标系统源代码+支持二开+Spring cloud tbms
项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以…...
FinalShell SSH工具安装教程及编辑窗口修改背景颜色,自定义背景图片,修改字体,修改快捷键(详细图文教程)
FinalShell 在 Windows 上提供了一个方便、安全、功能完备的远程管理工具。它的中文支持和自定义功能让其适合国内 Linux 系统管理者使用。与 Xshell 等软件相比,FinalShell 更注重功能实用性。 目录 FinalShellFinalShell的安装教程FinalShell 的一些主要功能和特点…...
uni-app中监听网络状态,并在嵌入webView页面的组件中添加网络监测
uni-app中监听网络状态,并在嵌入webView页面的组件中添加网络监测 uni-app中监听网络状态 下载插件 打开网络异常组件页面,点击"下载插件并导入HBuilderX"按钮,打开HBuilderX软件后,选择需要导入插件的项目ÿ…...
TP5前后端分离RBAC权限管理API
TP5前后端分离RBAC权限管理API 1.创建配置项目2.管理员功能2.1登录验证2.2.返回分页数据2.3增删改功能 3.角色功能3.权限管理4.给管理员分配角色5.给角色分配权限6.导航菜单功能 坑神的博客文章可以参考,还可以和他交流请教,坑神人很nice! 1.…...
p-级数的上界(Upper bound of p-series)
积分判别法-The Integral Test https://math.stackexchange.com/questions/2858067/upper-bound-of-p-series https://courses.lumenlearning.com/calculus2/chapter/the-p-series-and-estimating-series-value/ 两个重要级数(p级数和几何级数) ht…...
QT如何打包
目录 1.windeployqt工具 2.工具位置 3.使用方法 4.注意事项 Qt Creator 默认以动态链接的方式生成可执行文件,该文件无法独立运行,必须为其提供所需的动态链接库。也就是说,只分享 Qt Creator 生成的可执行文件是不行的,必须将…...
【c语言】通讯录(动态版+文件+背景音乐)含源码
开饭了,之前写的通讯录,是否会有人觉得申请1000人的空间是不是有点用不上呀,怎么才能做到要多少申请多少个呢??我们学完动态内存管理,和文件的相关操作,终于可以继续完善我们的通讯录了 船新版本…...
c#后端获实体类多列最大值
如何在一个返回一个实体求某些列的最大值,最小值,平均值,求和呢? 过去一直都是用的循环对比,没有进行归纳,或者就是最笨的办法 var demos new List<Demo>();foreach (var item in demos){var values…...
腾讯云国际轻量应用服务器使用流程是什么呢?
腾讯云国际轻量应用服务器怎么使用呢?下面一起来了解一下: 1. 熟悉轻量应用服务器基础知识 ①什么是轻量应用服务器 TencentCloud Lighthouse? ②轻量应用服务器与云服务器 CVM 的区别是什么? ③为什么选择轻量应用服务器…...
CentOS 8 非编译方式 yum 安装 FFmpeg
FFmpeg 是一套免费的开源计算机程序,它提供了录制、转换以及流化音视频的完整解决方案。FFmpeg 在 Linux 平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括 Windows、Mac OS X 等。大多数文章都是说的ubuntu上如何安装࿰…...
【Linux命令详解 | ssh命令】 ssh命令用于远程登录到其他计算机,实现安全的远程管理
文章标题 简介一,参数列表二,使用介绍1. 连接远程服务器2. 使用SSH密钥登录2.1 生成密钥对2.2 将公钥复制到远程服务器 3. 端口转发3.1 本地端口转发3.2 远程端口转发 4. X11转发5. 文件传输与远程命令执行5.1 文件传输5.1.1 从本地向远程传输文件5.1.2 …...
IP 地址监控工具
地址监控实用程序是一套 IP 工具,包括 IP 地址监控工具、流氓检测工具和 MAC 地址解析器,用于日常监控和管理 DNS 名称、IP和 MAC 地址。地址监控工具用于 IP监控,用于管理 DNS 名称、网络的 IP 和 MAC 地址,并跟踪 IP 地址。 IP…...
基于OpenCV的人脸识别和模型训练系统(万字详解)
前言 我们身边的人脸识别有车站检票,监控人脸,无人超市,支付宝人脸支付,上班打卡,人脸解锁手机。 人脸检测是人脸识别系统组成的关键部分之一,其目的是检测出任意给定图片中的包含的一个或多个人脸&#…...
Docker容器与虚拟化技术:Docker镜像创建、Dockerfile实例
目录 一、理论 1.Docker镜像的创建方法 2.Docker镜像结构的分层 3.Dockerfile 案例 4.构建Systemctl镜像(基于SSH镜像) 5.构建Tomcat 镜像 6.构建Mysql镜像 二、实验 1.Docker镜像的创建 2. Dockerfile 案例 3.构建Systemctl镜像(…...
每天一道leetcode:646. 最长数对链(动态规划中等)
今日份题目: 给你一个由 n 个数对组成的数对数组 pairs ,其中 pairs[i] [lefti, righti] 且 lefti < righti 。 现在,我们定义一种 跟随 关系,当且仅当 b < c 时,数对 p2 [c, d] 才可以跟在 p1 [a, b] 后面…...
651页23万字智慧教育大数据信息化顶层设计及建设方案WORD
导读:原文《651页23万字智慧教育大数据信息化顶层设计及建设方案WORD》(获取来源见文尾),本文精选其中精华及架构部分,逻辑清晰、内容完整,为快速形成售前方案提供参考。 目录 一、 方案背景 1.1 以教育…...
Vue3 使用json编辑器
安装 npm install json-editor-vue3 main中引入 main.js 中加入下面代码 import "jsoneditor";不然会有报错,如jsoneditor does not provide an export named ‘default’。 图片信息来源-github 代码示例 <template><json-editor-vue class…...
centos7 docker离线安装教程
centos7 docker离线安装教程 离线安装包下载# docker离线安装时需要两个安装包:selinux包、docker包, 下载地址: https://download.docker.com/linux/centos/7/x86_64/stable/Packages/selinux包下载 https://download.docker.com/linux/…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
