c语言元编程与python代码生成
calligra的Python项目详细描述
Author: | Elie ROUDNINSKI |
---|
calligra是一个纯python包,它试图对c语言语法的一个子集进行建模,以便从python脚本中推断c类型。 它的主要目标是进行元编程和代码生成。它根本不解析C代码本身。
calligra最初设计用于(取消)序列化json中的复杂(但不太复杂…)c结构。
内容
安装
1.1要求
calligra需要python 3。它已经在Linux上的Python3.6上进行了测试,但它应该在3.4和3.6上以及Windows上也能工作。 目前,它不需要任何外部python模块/包,但将来可能会有所改变。
由于calligra旨在生成代码,因此可能需要一些外部依赖项来编译生成的代码。
1.2来自Github
您可以克隆此存储库并直接使用setuptools安装它:
$ python3 setup.py install --user
1.3来自PIP
作为每个pip可用包,您可以使用pip包轻松安装它:
$ python3 -m pip install --user calligra
如何
2.1简介
如前所述,calligra旨在解释python级别的c类型。
目前,您可以对以下类型进行建模:
- 主要类型,如char、int、float、double等。
- C字符串(char*)
- 枚举
- 结构,命名和匿名
- 联合,命名和匿名
以及以下声明修饰符:
- 指针
- 数组
不支持指针的嵌套数组或指向数组的指针。
目前,您有两个选择:
- 从python定义所有内容
- 使用cparser导入器模块解析c代码
将来,您将能够从以下位置导入定义:
- json模式
2.2示例
让我们从一个基本的例子开始。 在下面的代码片段中,我们将使用两个成员定义一个名为person的c结构:
- 字符串名称
- 无符号整数age
然后我们将生成相关的C代码。
首先导入主模块:
importcalligraimportcalligra.stdlib
calligra模块是对c类型/声明语法进行建模的地方。 calligra.stdlib是定义标准C类型的地方。
然后定义结构:
namespace=calligra.stdlib.namespaceperson=calligra.struct(namespace,'person')person.add(calligra.declaration(namespace,namespace.get('char'),'name',pointer=True))person.add(calligra.declaration(namespace,namespace.get('uint8_t'),'age'))
最后,生成c代码:
print(person.define())
这将生成类似于:
structperson{char*name;uint8_tage;};
更高级的示例位于^{tt2}$目录中。
3个模块
3.1转换
转换模块位于^{tt3}$目录中,用于(取消)将c类型序列化为另一种格式(如json)。
当前可用的转换模块有:
- calligra.convert.jansson:使用Jansson库将c类型转换为json或从json转换为json。
3.1.1为了使用jansson转换模块,只需导入calligra.convert.jansson模块:
importcalligra.convert.jansson
之后,每种类型都应该有一个to_json和一个from_ json方法。
它们实际上是calligra.functions对象,您可以定义它来生成相应的c代码:
print(person.to_json.define())
它应该产生类似于:
json_t*person_to_json(structpersonconst*person);
对于函数体:
print(person.to_json.code(body=True))
它应该生成类似于(非合同代码):
json_t*person_to_json(structpersonconst*person){json_t*json=json_object(),*child;if(!json){returnNULL;}/*name*/if((person!=NULL)&&((*person).name!=NULL)&&(*(*person).name!=0)){child=json_string((*person).name);if(!child||json_object_set_new_nocheck(json,"name",child)!=0){if(child){json_decref(child);}json_decref(json);returnNULL;}}/*age*/if(person!=NULL){child=json_integer((*person).age);if(!child||json_object_set_new_nocheck(json,"age",child)!=0){if(child){json_decref(child);}json_decref(json);returnNULL;}}returnjson;}
为了使用jansson转换模块,只需导入calligra.convert.jansson模块:
importcalligra.convert.jansson
之后,每种类型都应该有一个to_json和一个from_ json方法。 它们实际上是calligra.functions对象,您可以定义它来生成相应的c代码:
print(person.to_json.define())
它应该产生类似于:
json_t*person_to_json(structpersonconst*person);
对于函数体:
print(person.to_json.code(body=True))
它应该生成类似于(非合同代码):
json_t*person_to_json(structpersonconst*person){json_t*json=json_object(),*child;if(!json){returnNULL;}/*name*/if((person!=NULL)&&((*person).name!=NULL)&&(*(*person).name!=0)){child=json_string((*person).name);if(!child||json_object_set_new_nocheck(json,"name",child)!=0){if(child){json_decref(child);}json_decref(json);returnNULL;}}/*age*/if(person!=NULL){child=json_integer((*person).age);if(!child||json_object_set_new_nocheck(json,"age",child)!=0){if(child){json_decref(child);}json_decref(json);returnNULL;}}returnjson;}