pycparser解析C代码构建AST

文章目录

构建AST语法树

  • pycparser解析C代码构建AST语法树;
  • pycparser是纯python实现的基于C99的解析器;
  • 不使用C标准的头文件,而是自己构建一套虚拟的头文件,在pycparser/utils/fake_libc_include 目录下;
  • 在分析C代码时,必须先预处理,比如注释掉标准头文件、size_t不支持的语法等;
  • python环境中安装pycparser, pip install pycparser;

编写C代码

如下C代码已经将标准头文件注释;

c 复制代码
//#include <stdio.h>
//#include <malloc.h> // 内存管理
//#include <string.h> // 字符串的头文件
//#include <math.h>
//#include <ctype.h>  // 处理字符的判断


typedef struct {
    int size;
    union {
        int age;
        int size;
        struct {
            int id;
        }mem1;
    }data;
}Variable;


// 声明一个结构体数组,并初始化
Variable arr[] = {{3, {{100}}}};

int idx = 0;

// 函数定义
void testLauf(){
    if(arr[idx].data.mem1.id < 200){
    printf("running...");
	}
}

分析C代码

基于pycparser 分析该样例C代码,并解析testLauf函数中的if条件内容;

python 复制代码
from pycparser import c_ast, parse_file

# 构建语法树
ast = parse_file(r"E:\jack.c", use_cpp=True, cpp_path="cpp", cpp_args=["-Ipycparser/utils/fake_libc_include"])


def process_func_def(node):
    # 处理函数体
    process_compound_or_single(node.body)


def process_compound_or_single(node):
    # 遍历{}中的每个语句
    for item in node.block_items:
        if isinstance(item, c_ast.If):
            r = get_expression_text(item.cond)
            print("r:", r)


stack = []
#
def get_expression_text(node):
    # *****************************
    if isinstance(node, c_ast.StructRef):
        if node.type == "." and get_expression_text(node.field):
            return get_expression_text(node.name) + f".{get_expression_text(node.field)}"
        else:
            return get_expression_text(node.name)
    # *****************************
    elif isinstance(node, c_ast.ArrayRef):
        return f"{get_expression_text(node.name)}[{get_expression_text(node.subscript)}]"

    if hasattr(node, "name"): # isinstance(node, c_ast.ID) and
        return node.name
    elif hasattr(node, "value"):  # isinstance(node, c_ast.Constant) and
        return node.value

    elif hasattr(node, "op"):
        if isinstance(node, c_ast.BinaryOp):
            left = get_expression_text(node.left)
            right = get_expression_text(node.right)
            return f"{left} {node.op} {right}"


# 遍历FileAst 节点的所有的子节点
for node in ast.ext:
    if isinstance(node, c_ast.FuncDef):
        process_func_def(node)

python代码运行输出r: arr[idx].data.mem1.id < 200

CLang方案

windows系统:

bash 复制代码
# 安装 MSYS2:https://www.msys2.org/
# 在 MSYS2 终端中:
pacman -Syu
pacman -S --needed base-devel mingw-w64-x86_64-toolchain

# 或单独安装 clang
pacman -S mingw-w64-x86_64-clang mingw-w64-x86_64-clang-analyzer
相关推荐
java1234_小锋1 小时前
[免费]基于Python的车辆车牌识别系统(PyTorch2卷积神经网络CNN+OpenCV实现)【论文+源码+SQL脚本】
python·opencv·cnn·车牌识别
Q_Q19632884751 小时前
python+django/flask+vue的基于协同过滤算法的体育商品推荐系统
spring boot·python·django·flask·node.js·php
u0119608231 小时前
apscheduler
开发语言·python
CV爱数码1 小时前
【宝藏数据集】LUMOS:腰椎多模态骨质疏松症筛查专用
人工智能·python·深度学习·机器学习·计算机视觉·数据集
杰瑞不懂代码1 小时前
【公式推导】AMP算法比BP算法强在哪(一)
python·算法·机器学习·概率论
deephub1 小时前
LlamaIndex检索调优实战:七个能落地的技术细节
人工智能·python·大语言模型·rag·llamaindex
..过云雨1 小时前
14.【Linux系统编程】进程间通信详解(管道通信、System V共享内存、消息队列、信号量)
linux·c语言·c++·后端
南极星10051 小时前
OPENCV(python)--初学之路(十)
人工智能·python·opencv
Wise玩转AI1 小时前
AI智能体开发实战AutoGen篇(四)——会干活的导诊 Agent(Planner + Tools 实战)
人工智能·python·microsoft·ai智能体·autogen