Python-C语言语法解析:pycparser模块

0 前言

>>返回Python系列文章目录<<

pycparser是python的一个用于解析C语言的第三方库,用于获取C语言的语法树

1 pycparser模块(三方库)

argparse模块是Python的第三方库,需要安装

pip install pycparser 

pycparser模块导入方式

# 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 *

1.1 方法列表

① 使用以下方法从c文件创建parser类:

ast = parse_file(filename, use_cpp = False)

# fake_libc_include文件夹放在处理的c语言目录下
ast = parse_file(filename, use_cpp = True, cpp_path=r'C:\MinGW\bin\gcc.exe', cpp_args=r'-I./fake_libc_include')
parse_file的参数说明
use_cpp是否使用本地c语言编译器预处理代码,去掉其中的#命令(头文件、宏定义、pragma)
cpp_path本地c语言编译器路径
cpp_argsfake_libc_include文件夹路径,use_cpp=True时使用,需要从官网下载

获取c语言文件的抽象语法树ast,如果要处理#include语句,需要下载fake_libc_include文件夹,让编译器预处理常用的方法(添加其到代码的抽象语法树中)

parser_file() 方法也可以设置use_cpp=False,不用本地的c语言编译器预处理代码,就能输出抽象语法树。

② 使用以下方法从字符串创建parser类:

# 读取的文本序列,需去除#include #define这类语句才能生成AST
with open(filename, encoding='utf-8) as f:
	txt = f.read()
ast = CParser().parse(txt)

1.2 语法树组成

创建语法树后得到根目录类型 FileAST,FileAST类属性如下:

  • self.ext = [Node](下级节点列表)

FileAST下级节点组成的列表,FileAST下级节点只有3种可能:

  • Typedef:typedef数据类型定义
  • Decl:变量声明
  • FuncDef:函数声明

例如:

print(ast.ext[0])

if(type(ast.ext[0]) is Decl):

1.2.1 数据类型定义 Typedef

Typedef 节点以typedef语句的定义对象 uint8为中心

typedef int uint8;

Typedef.name = 'uint8'
Typedef.coord = ':1:13'

数据类型定义 Typedef 属性如下:

  • self.name = str (typedef定义对象)
  • self.quals = [str] (限定符号列表: const, volatile)
  • self.storage = [str] (存储说明符列表: extern, register, etc.)
  • self.type = Node (TypeDecl节点)
  • self.coord= str(定义对象所在行列)
1.2.1.1 类型声明 TypeDecl
typedef int uint8;

TypeDecl = Typedef.type
TypeDecl.name = 'uint8'
TypeDecl.coord = ':1:13'

Typedef 的下一级 类型声明 TypeDecl 是以typedef语句格式为中心

类型声明 TypeDecl 属性如下:

  • self.name = str (typedef定义对象)
  • self.quals = [str] (限定符号列表: const, volatile)
  • self.storage = [str] (存储说明符列表: extern, register, etc.)
  • self.type = Node ( IdentifierType节点)
  • self.coord= str(定义对象所在行列)
1.2.1.1.1 标识符类型 IdentifierType
typedef int uint8;

TypeDecl = Typedef.type
IdentifierType = TypeDecl.type
IdentifierType.names = ['int']
IdentifierType.coord = ':1:9'

TypeDecl 的下一级 标识符类型 IdentifierType 是简单标识符,比如void, char定义之类

标识符类型 IdentifierType 属性如下:
self.name = [str] (标识符字符串列表)

  • self.coord= str(标识符字符串所在行列)

1.2.2 变量声明 Decl

uint8 a = 0;

Decl.name = 'a'
Decl.quals = ['const', 'volatile']
Decl.coord = ':5:22'

变量声明 Decl 属性如下:

  • self.name = str (被声明的变量名)
  • self.quals = [str] (限定符号列表: const, volatile)
  • self.storage = [str] (存储说明符列表: extern, register, etc.)
  • self.funcspec = [str] (函数说明符列表: C99的inline)
  • self.type = Node (TypeDecl节点)
  • self.init = Node (初始化值,Constant节点)
  • self.bitsize = Node (位域bit field大小,或者为None)

1.2.2.1 常量 Constant

常量 Constant 属性如下:

  • self.type= str (基本数据类型,int等)
  • self.value= str (数值)
  • self.coord= str(标识符字符串所在行列)

1.2.3 函数定义 FuncDef

FuncDef 方法定义,不同于 FuncDecl,有具体的函数实现过程

int test(uint8 b)
{
  b = 0;
  return b;
}

函数定义 FuncDef 属性如下:

  • self.decl = Node (一般是包含FuncDecl的Decl节点)
  • self.body = Node (函数实现的代码块)
  • self.coord= str(标识符字符串所在行列)

1.2.4 函数声明 FuncDecl

FuncDecl既可以单独存在,也可以是函数定义的一部分

int test(uint8 b)
{
  b = 0;
  return b;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值