当前位置: 首页 > 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/…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...