0

我想實現一種新的語言,我想用C語言來完成它,着名的flex + yacc組合。嗯,事情是,編寫整個AST代碼非常耗時。有沒有一種工具可以自動生成結構的構造函數?自動生成C結構體構造函數嗎?

我想有以下行爲的東西:

輸入:

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) 
{ ... } 

謝謝!

+0

很多很多很多年以前,我嘗試過一種使用類似於lex/yacc的文件格式的工具,並且應該與那些幫助創建和遍歷AST的工具一起使用。不幸的是我不記得這個名字,我懷疑它會很容易找到。但至少存在(或已經存在)這樣的工具。 – 2012-02-16 15:59:07

+0

如果您使用emacs或visual studio,您可以依靠片段來幫助您獲得大量時間 – Eregrith 2012-02-16 16:02:45

回答

1

那麼,由於沒有工具,我決定今天下午編寫代碼。 我開始看起來像一個不錯的項目,我想繼續它。

我在Haskell中編寫了一個基於內置haskell類型的稍微簡單的(只是一堆嵌套在IO monad中的嵌套摺疊)代碼生成器。

的AST類型聲明:

http://pastebin.com/gF9xF1vf

C代碼發生器,基於所述AST聲明:

http://pastebin.com/83Z4GH38

並將所產生的結果是:

http://pastebin.com/jJPgm5PE

有人不愛Haskell? :)

ps:我編碼,因爲我目前正在研究的項目將在不久的將來承受巨大的變化,而這些變化將無效AST,因此迫使我編碼另一個AST模塊... 現在我可以做得非常快!

感謝您的答案。

+0

我真的沒有時間學習Haskell(或類似的語言),但在我看來,函數式語言對於編譯器來說是非常好的。 – 2012-02-17 06:19:27

+0

@JoachimPileborg,不完全正確。一些非常簡單的任務,例如全局累加器,可能會在函數式編程中出現令人頭痛的問題,但對於簡單或任何通過複雜數據結構遍歷的任何事情來說,這都非常好! – Victor 2012-02-17 10:52:14

2

您可能可以通過巧妙使用預處理器宏來獲得某些東西。

第一頭文件:

#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

+0

感謝您的代碼,我試圖使用宏,但他們不會給我所需的所有「電源」。我剛剛用我今天編碼的東西回答了我的問題。 – Victor 2012-02-17 02:30:31