自动生成C结构构造函数?

发布于 2025-01-06 06:04:53 字数 615 浏览 6 评论 0原文

我想实现一种新语言,并且我想用 C 语言来实现,使用著名的 flex+yacc 组合。事实是,编写整个 AST 代码非常耗时。有没有一个工具可以自动生成结构体的构造函数?

我想要具有以下行为的东西:

输入:

enum AgentKind {A_KIND1, A_KIND2};
typedef struct Agent_st
{
    enum AgentKind kind;
    union {
        struct {int a, b, c} k1;
        struct {int a, GList* rest} k2;
    } u;
} Agent;

输出:

Agent*    agent_A_KIND1_new(int a, b, c)
{
    Agent* a = (Agent*)malloc(sizeof(Agent));
    a->kind = A_KIND1;
    a->k1.a = a;
    ...
    ...
    return a;
}

Agent*    agent_A_KIND2_new(int a, GList* rest)
{ ... }

谢谢!

I want to implement a new language, and I would like to do it in C, with the famous flex+yacc combination. Well, the thing is, writing the whole AST code is very time consuming. Is there a tool that automatically generate the constructors for the structs?

I would like something with the following behavior:

input:

enum AgentKind {A_KIND1, A_KIND2};
typedef struct Agent_st
{
    enum AgentKind kind;
    union {
        struct {int a, b, c} k1;
        struct {int a, GList* rest} k2;
    } u;
} Agent;

output:

Agent*    agent_A_KIND1_new(int a, b, c)
{
    Agent* a = (Agent*)malloc(sizeof(Agent));
    a->kind = A_KIND1;
    a->k1.a = a;
    ...
    ...
    return a;
}

Agent*    agent_A_KIND2_new(int a, GList* rest)
{ ... }

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吃不饱 2025-01-13 06:04:53

通过巧妙地使用预处理器宏,您也许能够得到一些东西。

首先是头文件:

#ifndef AST_NODE
# define AST_NODE(token) \
    struct AST_ ## token \
    {                    \
        int kind;        \
    };
#endif

AST_NODE(TokenType1)
AST_NODE(TokenType2)

然后是源文件:

#define AST_NODE(token)                                        \
struct AST_ ## token *AST_ ## token ## _new()                  \
{                                                              \
    struct AST_ ## token *node = malloc(sizeof(AST_ ## token); \
    node->kind = token;                                        \
    return node;                                               \
}

#include "ast.h"

如果您在任何其他文件中包含“ast.h”文件,您将有两个结构:AST_TokenType1AST_TokenType2

上述源文件创建了两个函数:AST_TokenType1_new()AST_TokenType2_new(),它们分配正确的结构并设置结构成员 kind

You might be able to get something working with clever use of pre-processor macros.

First the header file:

#ifndef AST_NODE
# define AST_NODE(token) \
    struct AST_ ## token \
    {                    \
        int kind;        \
    };
#endif

AST_NODE(TokenType1)
AST_NODE(TokenType2)

Then the source file:

#define AST_NODE(token)                                        \
struct AST_ ## token *AST_ ## token ## _new()                  \
{                                                              \
    struct AST_ ## token *node = malloc(sizeof(AST_ ## token); \
    node->kind = token;                                        \
    return node;                                               \
}

#include "ast.h"

If you include the "ast.h" file in any other file, you will have two structures: AST_TokenType1 and AST_TokenType2.

The source file described above creates two functions: AST_TokenType1_new() and AST_TokenType2_new() which allocate the correct structure and sets the structure member kind.

鸵鸟症 2025-01-13 06:04:53

好吧,由于没有工具,我决定今天下午编写一些代码。
我开始了一个看起来不错的项目,我想继续下去。

我在 Haskell 中基于内置的 haskell 类型编写了一个有点简单的代码生成器(只是 IO monad 内的一堆嵌套折叠)。

AST 类型声明:

http://pastebin.com/gF9xF1vf

基于 AST 声明的 C 代码生成器:

http://pastebin.com/83Z4GH38

生成的结果:

http://pastebin.com/jJPgm5PE

怎么会有人不喜欢 Haskell?
:)

ps: 我编写这个代码是因为我当前正在从事的项目将在不久的将来遭受巨大的变化,而这些变化将使 AST 失效,从而迫使我编写另一个 AST 模块......
现在我可以很快做到了!

不过还是谢谢你的回答。

Well, since there was no tool I decided to code something this afternoon.
I started something that looks like a nice project, and I would like to continue it.

I coded a somewhat simple (just a bunch of nested folds inside the IO monad) code generator in Haskell, based in builtin haskell types.

The AST type declaration:

http://pastebin.com/gF9xF1vf

The C code generator, based on the AST declaration:

http://pastebin.com/83Z4GH38

And the generated result:

http://pastebin.com/jJPgm5PE

How can somebody not love Haskell?
:)

ps: I coded this because the project I'm currently working on is going to suffer a huge amount of changes in the near future, and those changes will invalidade the AST, thus forcing me to code another AST module...
Now I can do it quite fast!

Thanks for the answer though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文