当前位置: 首页 > news >正文

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. 方法1:
ast = parse_file(filename, use_cpp = False)
  1. 方法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_argsfake_libc_include文件夹路径,需要在路径添加 -I 指明所包头文件路径; use_cpp=True 时使用

语法树组成

抽象语法树 ast 类型为 <class 'pycparser.c_ast.FileAST'>

其解析的具体内容通过 print(ast.ext) 查看,ext 数据类型为列表

FileAST 下级节点只有 3 种可能 :

  • Typedeftypedef 数据类型定义
  • 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 = strTypedef 定义对象)
  • Typedef.quals = [str] (限定符号列表: const, volatile
  • Typedef.storage = [str] (存储说明符列表: extern, register, etc.
  • Typedef.type = NodeTypeDecl节点)
  • 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= strtypedef定义对象)
  • TypeDecl.quals = [str] (限定符号列表: const, volatile
  • TypeDecl.align= [str] (暂不清楚)
  • TypeDecl.type = NodeIdentifierType节点)
  • 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文件是否存在&#xff0c;存在就会有。前提是在run configuration配置了打印多个日志...

Java版本+企业电子招投标系统源代码+支持二开+Spring cloud tbms

​ 项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以…...

FinalShell SSH工具安装教程及编辑窗口修改背景颜色,自定义背景图片,修改字体,修改快捷键(详细图文教程)

FinalShell 在 Windows 上提供了一个方便、安全、功能完备的远程管理工具。它的中文支持和自定义功能让其适合国内 Linux 系统管理者使用。与 Xshell 等软件相比&#xff0c;FinalShell 更注重功能实用性。 目录 FinalShellFinalShell的安装教程FinalShell 的一些主要功能和特点…...

uni-app中监听网络状态,并在嵌入webView页面的组件中添加网络监测

uni-app中监听网络状态&#xff0c;并在嵌入webView页面的组件中添加网络监测 uni-app中监听网络状态 下载插件 打开网络异常组件页面&#xff0c;点击"下载插件并导入HBuilderX"按钮&#xff0c;打开HBuilderX软件后&#xff0c;选择需要导入插件的项目&#xff…...

TP5前后端分离RBAC权限管理API

TP5前后端分离RBAC权限管理API 1.创建配置项目2.管理员功能2.1登录验证2.2.返回分页数据2.3增删改功能 3.角色功能3.权限管理4.给管理员分配角色5.给角色分配权限6.导航菜单功能 坑神的博客文章可以参考&#xff0c;还可以和他交流请教&#xff0c;坑神人很nice&#xff01; 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/ 两个重要级数&#xff08;p级数和几何级数&#xff09; ht…...

QT如何打包

目录 1.windeployqt工具 2.工具位置 3.使用方法 4.注意事项 Qt Creator 默认以动态链接的方式生成可执行文件&#xff0c;该文件无法独立运行&#xff0c;必须为其提供所需的动态链接库。也就是说&#xff0c;只分享 Qt Creator 生成的可执行文件是不行的&#xff0c;必须将…...

【c语言】通讯录(动态版+文件+背景音乐)含源码

开饭了&#xff0c;之前写的通讯录&#xff0c;是否会有人觉得申请1000人的空间是不是有点用不上呀&#xff0c;怎么才能做到要多少申请多少个呢&#xff1f;&#xff1f;我们学完动态内存管理&#xff0c;和文件的相关操作&#xff0c;终于可以继续完善我们的通讯录了 船新版本…...

c#后端获实体类多列最大值

如何在一个返回一个实体求某些列的最大值&#xff0c;最小值&#xff0c;平均值&#xff0c;求和呢&#xff1f; 过去一直都是用的循环对比&#xff0c;没有进行归纳&#xff0c;或者就是最笨的办法 var demos new List<Demo>();foreach (var item in demos){var values…...

腾讯云国际轻量应用服务器使用流程是什么呢?

腾讯云国际轻量应用服务器怎么使用呢&#xff1f;下面一起来了解一下&#xff1a; 1. 熟悉轻量应用服务器基础知识 ①什么是轻量应用服务器 TencentCloud Lighthouse&#xff1f; ②轻量应用服务器与云服务器 CVM 的区别是什么&#xff1f; ③为什么选择轻量应用服务器&#xf…...

CentOS 8 非编译方式 yum 安装 FFmpeg

FFmpeg 是一套免费的开源计算机程序&#xff0c;它提供了录制、转换以及流化音视频的完整解决方案。FFmpeg 在 Linux 平台下开发&#xff0c;但它同样也可以在其它操作系统环境中编译运行&#xff0c;包括 Windows、Mac OS X 等。大多数文章都是说的ubuntu上如何安装&#xff0…...

【Linux命令详解 | ssh命令】 ssh命令用于远程登录到其他计算机,实现安全的远程管理

文章标题 简介一&#xff0c;参数列表二&#xff0c;使用介绍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 工具&#xff0c;包括 IP 地址监控工具、流氓检测工具和 MAC 地址解析器&#xff0c;用于日常监控和管理 DNS 名称、IP和 MAC 地址。地址监控工具用于 IP监控&#xff0c;用于管理 DNS 名称、网络的 IP 和 MAC 地址&#xff0c;并跟踪 IP 地址。 IP…...

基于OpenCV的人脸识别和模型训练系统(万字详解)

前言 我们身边的人脸识别有车站检票&#xff0c;监控人脸&#xff0c;无人超市&#xff0c;支付宝人脸支付&#xff0c;上班打卡&#xff0c;人脸解锁手机。 人脸检测是人脸识别系统组成的关键部分之一&#xff0c;其目的是检测出任意给定图片中的包含的一个或多个人脸&#…...

Docker容器与虚拟化技术:Docker镜像创建、Dockerfile实例

目录 一、理论 1.Docker镜像的创建方法 2.Docker镜像结构的分层 3.Dockerfile 案例 4.构建Systemctl镜像&#xff08;基于SSH镜像&#xff09; 5.构建Tomcat 镜像 6.构建Mysql镜像 二、实验 1.Docker镜像的创建 2. Dockerfile 案例 3.构建Systemctl镜像&#xff08;…...

每天一道leetcode:646. 最长数对链(动态规划中等)

今日份题目&#xff1a; 给你一个由 n 个数对组成的数对数组 pairs &#xff0c;其中 pairs[i] [lefti, righti] 且 lefti < righti 。 现在&#xff0c;我们定义一种 跟随 关系&#xff0c;当且仅当 b < c 时&#xff0c;数对 p2 [c, d] 才可以跟在 p1 [a, b] 后面…...

651页23万字智慧教育大数据信息化顶层设计及建设方案WORD

导读&#xff1a;原文《651页23万字智慧教育大数据信息化顶层设计及建设方案WORD》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 目录 一、 方案背景 1.1 以教育…...

Vue3 使用json编辑器

安装 npm install json-editor-vue3 main中引入 main.js 中加入下面代码 import "jsoneditor";不然会有报错&#xff0c;如jsoneditor does not provide an export named ‘default’。 图片信息来源-github 代码示例 <template><json-editor-vue class…...

centos7 docker离线安装教程

centos7 docker离线安装教程 离线安装包下载# docker离线安装时需要两个安装包&#xff1a;selinux包、docker包&#xff0c; 下载地址&#xff1a; https://download.docker.com/linux/centos/7/x86_64/stable/Packages/selinux包下载 https://download.docker.com/linux/…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的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、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

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)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...