Генерировать конструкторы структуры C автоматически? - PullRequest
0 голосов
/ 16 февраля 2012

Я хочу реализовать новый язык, и я хотел бы сделать это в 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)
{ ... }

Спасибо!

Ответы [ 2 ]

2 голосов
/ 16 февраля 2012

Возможно, вам удастся заставить что-то работать с умным использованием макросов препроцессора.

Первый файл заголовка:

#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_TokenType1 и AST_TokenType2.

Исходный файл, описанный выше, создает две функции: AST_TokenType1_new() и AST_TokenType2_new(), которые распределяют правильную структуру и устанавливают элемент структуры kind.

1 голос
/ 17 февраля 2012

Ну, поскольку не было никакого инструмента, я решил кое-что написать сегодня днем. Я начал что-то похожее на хороший проект, и я хотел бы продолжить его.

Я написал несколько простой (просто набор вложенных сгибов внутри монады ввода-вывода) генератор кода на Haskell, основанный на встроенных типах haskell.

Объявление типа AST:

http://pastebin.com/gF9xF1vf

Генератор кода C, основанный на объявлении AST:

http://pastebin.com/83Z4GH38

И сгенерированный результат:

http://pastebin.com/jJPgm5PE

Как кто-то может не любить Хаскелл? :)

ps: я кодировал это, потому что проект, над которым я сейчас работаю, в ближайшем будущем претерпит огромное количество изменений, и эти изменения приведут к недействительности AST, что заставит меня кодировать другой модуль AST ... Теперь я могу сделать это довольно быстро!

Спасибо за ответ.

...