【问题标题】:How to generate C code automatically [closed]如何自动生成C代码[关闭]
【发布时间】:2012-09-17 11:47:00
【问题描述】:

我正在做一个 C 项目。我观察到很多代码可以根据某些规则自动生成。 IE。如果我只指定 C 结构,则可以在此基础上自动生成代码。我知道它可以做到,但我以前没有做过。如果有经验的 C 程序员可以提供某些指导或分享他们如何以最少的工程工作量做这些事情的经验,那就太好了。

编辑:具体来说,我需要用 C 编写一个自定义解析器来完成所有这些工作,还是有一些更简单的方法来处理这个问题?

【问题讨论】:

  • 您正在寻找支持模板的 IDE。
  • 这个问题不清楚。您究竟要生成什么代码?为什么你不能写一个输出文本的程序呢?毕竟,这就是所有的 C 代码。
  • 聘请实习生...
  • "如果我只指定 C 结构,基于此,代码可以自动生成。"问题是,代码做什么什么?只是为了定义struct 类型?您是否还想生成为这些类型分配/取消分配内存的代码?操纵和访问成员?显示格式?

标签: c code-generation


【解决方案1】:

简单的部分与 1:1 语法替换有关。

除了 1:1 语法替换之外,困难的部分是做任何非常有意义的事情。

如果您过分依赖宏,您会遇到(编造名称)认知漂移问题,您现在正在设计自己的语言(宏语言),但编译器和运行程序正在使用另一种语言。简单的映射不会使新语言变得更繁琐,但由于宏在纯文本替换级别上运行,即使是简单的映射也会很快变得复杂。

如果您使用的是 C++,那么更好 的解决方案是使用 模板。模板提供了许多与宏相同的功能,只是它们不会受到太多认知漂移的影响,因为模板会替换为对类型系统的认识。

随着类 C 语言结构的语法和含义的发展,您会发现较新的语言经常尝试通过纯 C 解决方案需要“修复”重复代码量的问题。尝试学习一些“接近”C 的新语言,您将体会到可以减少这种代码重复的方法,从而在 C 的“生成”工作中做出更好的选择。

【讨论】:

    【解决方案2】:

    在 C 中进行元编程的一种相对传统的方法是使用像 X macros 这样的技术。

    本质上,与其使用普通的 C 结构声明,不如完全使用宏来定义结构,就像这样

    BEGIN_STRUCT(pointf)
    FIELD(float, x)
    FIELD(float, y)
    END_STRUCT(pointf)
    

    并将这些定义放在一个头文件中,不防止多重包含。

    然后,对于您需要生成的每一段代码(包括基本结构),#define 每个元语言宏,#include 定义头,#undef 再次元语言宏:

    #define BEGIN_STRUCT(N) struct N {
    #define FIELD(T,N) T N;
    #define END_STRUCT(N) }
    #include "definitions.h"
    #undef BEGIN_STRUCT
    #undef FIELD
    #undef END_STRUCT
    

    【讨论】:

      【解决方案3】:

      我见过的一种有效方法是使用宏(一种经常被讨厌的工具)。宏有两个功能可以让生活变得更轻松,单个哈希“#”可以将参数转换为字符串,即#_name 将被转换为"fieldName1",双哈希“##”将参数与其他可以扩展新事物的东西,即STRUCT_##_type##_str将被翻译成STRUCT_int_str,这将被翻译成"%d"

      首先将结构或“描述”包装在宏中,即放入自己的文件(the-struct.def)

      STRUCT_BEGIN(s_my_struct)
        STRUCT_FIELD(int, fieldName1)
        STRUCT_FIELD(int, fieldName2)
        STRUCT_FIELD(int, fieldName3)
      STRUCT_END(s_my_struct)
      
      // Note that you can add more structs here and all will automatically get defined and get the print function implemented 
      

      然后可以在想要声明或实现应该处理结构的事物的地方以不同的方式定义宏。即

      #define STRUCT_BEGIN(_name) struct _name {
      #define STRUCT_END(_name) };
      #define STRUCT_FIELD(_type, _name) _type _name;
      
      #include "the-struct.def"
      
      // then undef them
      #undef STRUCT_BEGIN
      #undef STRUCT_END
      #undef STRUCT_FIELD
      

      并制作一个打印结构的函数

      #define STRUCT_BEGIN(_name) void print_ ## _name(struct _name *s) {
      #define STRUCT_END(_name) }
      #define STRUCT_FIELD(_type, _name) printf("%s = " STRUCT_##_type##_str "\n", #_name, s->_name); 
      #define STRUCT_int_str "%d" /* this is to output an int */
      // add more types...
      
      #include "the-struct.def"
      
      // then undef them
      #undef STRUCT_BEGIN
      #undef STRUCT_END
      #undef STRUCT_FIELD
      #undef STRUCT_int_str
      

      其他用途可以是自动生成函数以交换字节等。

      在这里做了一个小例子作为要点https://gist.github.com/3786323

      【讨论】:

        猜你喜欢
        • 2018-02-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-03
        • 2012-01-07
        • 2012-03-27
        • 1970-01-01
        • 2010-11-21
        相关资源
        最近更新 更多