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/…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
