PyMacroParser 宏解析工具

PyMacroParser是一个基于Python 2.7的宏解析工具,能够读取.CPP文件中的宏定义,结合预定义宏,解析出可用宏并转化为Python字典。该工具遵循C/C++宏定义标准,处理宏定义、预定义宏、聚合类型等,并考虑了类型转换和兼容性问题。同时,它提供了load、preDefine、dumpDict和dump四个核心方法,支持宏定义的读取、预定义、字典输出和源文件导出。
摘要由CSDN通过智能技术生成


PyMarcoParser宏解析工具

题目要求

题目描述

假定有CPP 源码文件(.cpp) 仅有如下内容

  1. 包含C/C++ 风格的注释: // 及 /**/
  2. 包含空白字符
  3. 只包含 #ifdef/#ifndef/#else/#endif/#define/#undef 这几个宏指令的应用
  4. #define 定义仅有如下定义情况:
    #define identifier token-stringopt
  5. 其中 token-stringopt 只有兼容如下几种C/C++指定基本类型常量表示内容:整型,浮点,布尔(true, false),字符(忽略宽字符),字符串,及各上述基本类型组成的聚合。
  6. 聚合:结构体 或者 数组初始化,均可用聚合初始化形式{}表示,聚合类型可以多维(嵌套).
  7. 除如上指定内容及适当的空格制表符换行等等等,不再有其他内容。不考虑字符映射及三元组序列, 不考虑行拼接

    注释,空白字符,常量,和字符串的类型定义请参考如下相关描述文档
    聚合初始化参考如下网址中关于聚合初始化的表述
    预处理器相关参考如下文档,特别注意 “转换阶段” 与 “预处理器指令”

有如上特点的CPP源码文件,为了实现与Python脚本兼容对接,
请基于Python 2.7.X 封装实现一个可重用的类,要求如下:

  1. 该类能读取 .cpp文件中的宏定义,并接收可变化的预定义宏串, 并根据两者,解析出当前所有的可用的宏定义。全部字符串都是ANSI编码。
  2. 可用宏定义可转为Python字典模式输出。 其中宏名转为字符串作为字典key, 若有与宏对应的常量定义转为对应python数据类型后作为字典的value。 类型对应关系见附表。若无任何常量则value为None
  3. 可用宏定义可再次导出成为只含有当前宏定义的CPP源文件。
  4. 请遵循CPP宏及常量类型的定义标准,确保相同常量变换后数值上保持一致,类型上与Python保持兼容(由于python转换过程中可能会损失掉C的具体类型信息,比如char 可能最终变为 int,具体表示方法也会有所变化,比如16进制最终表示为10进制, 故多次转换后能保持最终常量的值相等即可。 类型转换标准见“注意”)
  5. 只允许使用Python内置模块(如sys、math)和string模块,不允许使用其他标准模块及任何第三方开发库(包括但不限于re),不要使用 evel/exec 懒人解析, 不要使用copy;deepcopy等懒人复制。
  6. 独立完成作业,并代码中给予必要的注释。
  7. 代码采用UTF-8编码

该类的类名要求为PyMacroParser,所提供的方法约定如下:

  1. load(self, f) 从指定文件中读取CPP宏定义,存为python内部数据,以备进一步解析使用。 f为文件路径,文件操作失败抛出异常;
    无返回值。若在初步解析中遇到宏定义格式错误 或 常量类型数据定义错误应该抛出异常。
  2. preDefine(self, s) 输入一堆预定义宏名串,宏名与宏名之间以”;” 分割。
    比如串"mcname1;mcname2"相当于把
    #define mcname1
    #define mcname2
    加在了CPP宏数据的最前面。
    而空串"" 表示没有任何预定义宏。 显然,预定义宏会影响对CPP文件数据内的可用宏解析。
    preDefine函数可被反复调用,每次调用自动清理掉之前的预定义宏序列。 preDefine 与 load的CPP宏定义数据,一起决定最终可用的宏。
  3. dumpDict(self) 返回一个dict, 结合类中存储的CPP宏定义与预定义的宏序列,解析输出所有的可用宏到一个字典,其中宏名转为字符串后作为字典的key, 若有与宏名对应的常量转为python数据对象,无常量则存为None, 注意不要返回类中内置的对象的引用。 解析过程若遇到宏定义格式错误 或 常量类型数据定义错误应该抛出异常;
  4. dump(self, f) 结合类中的CPP宏定义数据与预定义宏序列,解析输出所有可用宏存储到新的CPP源文件,f为CPP文件路径,文件若存在则覆盖,文件操作失败抛出异常。 若遇到宏定义格式错误 或 常量类型数据定义错误应该抛出异常。 注意,转换后的常量数据表示应与Python对应类型兼容, 所以常量类型的长度存储信息可能丢失(例如 short 转为 int; float 转为 double 等), 允许特别表示方法信息丢失(例如原本16进制 统一变成10进制表示等)。 导出宏的顺序不做特别要求。

示例

Input
假设源文件 a.cpp 中有如下内容

#ifndef MCTEST
#define MCTEST

#ifdef MC1

#define data1 0x20
/*cmment start*/#define /*this is comment*/ data2 2.5f
#define data3 L"this is a data"
#define data4 true


#ifdef MC2

#define data5 'a'
#define data6 { {2.0, "abc"}, {1.5, "def"}, {5.6f, "7.2"}} // 浮点与字符串组成的结构体初始化聚合, 再进一步聚合组成了数组

#else

#define data5 {5.0, 7.5, 3.8}
#define data6 'c'

#endif //end MC2


#else

#define data1 1.0f /* this is float
may be changed
*/
#define data2 2
#define data3 false
#define data4 "this is a data"


#ifdef MC2

#define
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值