用Python做一个适用于 自制操作系统 的 编译器,用于实现Python转C,使用ast抽象语法树的解析转换文件内容(C到Python用pycparser) 需要达到一下要求: 1.不需要支持第三方或自带的模块 2.需要支持全部内部的定义方法,包括关键字,比如if for while break continue等,语句判断需要支持and or not is == != >= <= > < 等。 3.需要支持乘法、除法加法减法和异或计算。 3.True 和 False 通过定义宏1/0实现。 4.class转换比较复杂(支持面向对象),而且不能使用任何库,转换为C的类内常量和类外函数,Python通过映射表映射到函数上。 5.你需要书写c.py和t.py,如果有导入xxx的库名为c或t直接忽略,这是py2c的内部语义库。 其它所有import xxx或from xxx import xxx统一都翻译为#include xxx 注意不能忽略,只有c和t可以忽略,其它的都要翻译为#include xxx,并且注释上原语句,在再次Python化时就可以直接套用原语句了 6.import 只需要 include对应的文件,import的文件应该已经一起被翻译成c或h了, 从别的模块导入的函数需要去掉模块名称,而且要加上namespce处理,注意代码缩进。 7.注意函数调用和结构体实例化的实现,还有value和key不准变成None。 8.请你实现,并且注意C的极端小众的表达,并想好如何在Python中语义化表达,比如asm,range简化,class简化,typedef 和其后缀,指针操作,define,宏。 9.有一些C中的极端语句,Python无法语义化,比如asm,指针操作等指令。 提供一个扩展库c.pyi,py2c在转化时直接忽略import c等相关语句,将c.*比如c.asm("""""", *args, ...)直接转为C asm具体语义, 比如 asm volatile ( "movb $0x0e, %%ah\n" "int $0x10\n" : : "a"(c) );这种语句和类似特殊语句的实现 10.支持双向转换(py->c,c->py),对于不知道含义的函数就当没看见就好了,直接按照通用语义转换。 11.支持内存地址硬编码赋值等(c.py) 12.强制类型转换赋值 13.区分class xxx()和class xxx(c.class_point),普通结构体和结构体指针 14.支持结构体成员嵌套访问 15.支持结构体数组+指针索引访问,实现结构体数组的Python语义映射(l: c.class_list = []) 16.static 关键字支持(i: t.Static | t.CInt) 17.支持栈指针直接操作,ESP,语义映射 18.支持宏常量强制类型转换(依赖c.py) 19.支持高级位运算和多层嵌套逻辑或位运算组合 20.对于#define宏,使用t.CDefine(t.CType)作为类型表示 21.对于仅声明暂不定义的量,用xxx: xxx = c.State 22.对于Python的函数,要求其返回值和参数必须注解,def example(e1: t.CType) -> t.CType: xxx 这样才能正确转换为C函数,比如def xxx(e1: t.CChar) -> t.CInt: xxx转为int xxx(char e1) {xxx}。 若函数无返回值,可以写 def xxx(e1: t.CChar) -> None: xxx或def xxx(e1: t.CChar) -> t.CVoid: xxx 或不进行注解 对于语法,需要写在c.py。 对于类型,需要写在t.py,比如c_int、c_char等,而不是直接写int,不然会出现冲突。 c.py和t.py的定义都需要写元数据以及语法定义,通过元数据和元函数来实现具体的语法定义,以便于扩展,比如 class CInt(t.CType): def __init__(self): self.CName = 'int' super().__init__() def ... 23.对于C->Py和Py->C的翻译,更多地通过c.py和t.py中t.CType和c.CGrammar来实现,也就是在通过ast或pycparser解析后, 如果可以的话把数据类型交给t.CType委托处理,语法给c.CGrammar委托处理,而不是硬编码在Py2C主程序中。 24.禁止使用硬编码来偷懒! 对于需要多个类型的情况,比如 static char *str = "hello"; 在 Python 中仅需定义 str: t.CStatic | t.Char | t.Ptr = "hello"; 无需定义 t.CStaticCharPtr 这种复杂的类型,直接用 t.CStatic | t.Char | t.Ptr 即可。 允许使用元函数修改多种类型的组合方式,比如 class CStatic(t.CType): def __init__(self): self.CName = 'static char *' super().__init__() def __merge__(self, types: list): # 此处 types 为多个父为 t.Ctypes,比如 [t.CStatic, t.Char, t.Ptr] # 在此处我需要返回我修改后的 types,比如假设我与 t.Ptr 冲突(实际上并不冲突,只是作示例),那就返回 [t.CStatic, t.Char] if t.Ptr in types: types.remove(t.Ptr) return types 以此类推,支持更多种类型。 你需要默认支持的类型: char int short long float double void unsigned char unsigned int unsigned short unsigned long signed char struct union enum typedef auto register static extern const volatile size_t int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t intptr_t uintptr_t ptrdiff_t wchar_t char16_t char32_t bool _Complex _Imaginary 注意,转换后的python或c需要符合其语法规范,不能有语法错误。 还有就是,C中的所有函数,都请你当作普通函数(定义在其它h文件),也就是不需要考虑函数的定义和实现。 如果有-wh参数,后面会带着几个h文件,也就是这些函数的定义,你可以进行参考,如果没有就算了,按默认方法处理。 代码格式要求:所有命名都使用帕斯卡命名法,首字母大写,缩写大写,不需要注释,最简代码,但人类可读。 你可以写一个入口程序,再写多个小库在./lib中,来降低复杂度,./lib文件夹已创建,无需检查。 禁止使用硬编码偷懒! 执行方法: python TransPyC.py -f test.py -o test.c python TransPyC.py -f test.c -o test2.py -wh test.h 仅需一个Python文件 然后你需要尝试将test.c转为test.py并验证是否正确,再将test.py转为test2.c并验证是否和test.c语义相同。 test.c已存在,这是一个略微复杂的操作系统C程序,需要你进行完整转换。 我已经给了你example_test.py,作为目标转换结果的参考。 中文输出