python ast 解析enum为C头文件

发布时间:2024年01月23日
from _ast import Assign, ClassDef, FunctionDef, Import
import ast
from typing import Any


str="""import enum

class MsgIdMacro(enum.Enum):
    MSG_ID_1 = (1, "消息1")
    MSG_ID_2 = (2, "消息2")
    MSG_ID_3 = (enum.auto(), "消息3")

    def __new__(cls, value, string_value):
        member = object.__new__(cls)
        member._value_ = value
        member.string_value = string_value
        return member
"""



class OStringStream():
    def __init__(self):
        self._buff=""
        self._len = 0
    
    @property
    def buff(self):
        return self._buff
        
    @property
    def len(self):
        return self._len
    
    def append(self, data):
        self._buff += data
        self._len += len(data)
        
class Visitor(ast.NodeVisitor):
    def __init__(self, file):
        self._file = file
        self._indent = 4
        self._data = OStringStream()
        self._data.append("""#ifndef MSG_ID_H
#define MSG_ID_H
""")
    def entry_indent(self, space=1):
        self._indent += space
        self._data.append(Visitor.backspace(self._indent))
        
    def exit_indent(self, space=1):
        self._indent -= space
        
    def visit(self, node):
        """Visit a node."""
        method = 'visit_' + node.__class__.__name__
        visitor = getattr(self, method, self.generic_visit)
        return visitor(node)
    
    @staticmethod
    def backspace(num=1):
        return " "*num
    
    def line(self):
        self._data.append("\n")
    
    def visit_FunctionDef(self, node: FunctionDef) -> Any:
        return True
    
    def visit_Assign(self, node: Assign) -> Any:
        is_auto_func = False
        msg_id_name = node.targets[0].id
        msg_id_value, doc = node.value.elts
        if isinstance(msg_id_value, ast.Call) and isinstance(msg_id_value.func, ast.Attribute) and msg_id_value.func.attr == 'auto':
            is_auto_func=True
        self.entry_indent(4)
        
        msg_id_value = "," if is_auto_func else f"={msg_id_value.value},"
        self._data.append(f"{msg_id_name}{msg_id_value}             //              {doc.value}")
        self.line()
        self.exit_indent(4)
        return True
    
    def visit_Import(self, node: Import) -> Any:
        return True
    
    def visit_ClassDef(self, node: ClassDef) -> Any:
        if not node.name:
            print(f"Error:expect class name")
            return False
        self._data.append("enum %s%s" %(node.name, Visitor.backspace()))
        self._data.append("{")
        self.line()
        
        for stmt in node.body:
            res = self.visit(stmt)
            if not res:
                print(f"Error: stmt error")
                return False
        self._data.append("}")
    
    def generic_visit(self, node):
        return True
    
    def write_file(self):
        with open(self._file, "w") as f:
            f.write(self._data.buff)


if __name__ == "__main__":
    out = ast.parse(str)
    for stmt in out.body:
        print(stmt)
        vs = Visitor("msg_id.h")
        vs.visit(stmt)
        vs._data.append("#endif")
        vs.write_file()


文章来源:https://blog.csdn.net/CodeHouse/article/details/135761128
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。