2012-03-24 45 views
4

我正在與Bison合作爲我編寫的編譯器構建AST。在AST中建立節點的最佳方法是什麼?舉個例子,我的問題可能會更清楚。使用Bison構建AST

考慮下面的代碼片段:

field 
    : modifier type TOK_IDENT TOK_SEMICOLON 
    { 
     // I want to return a pointer to a node of type Field 
     // i.e. $$ = new Field(name, isVisible, isStatic, type); 
    } 
    ; 

modifier 
    : visibility_opt static_opt 
    { 
     // Should I make the new Field here and pass it up? 
     // Or a new type that contains both vis and static options?  
    } 
    ; 

visibility_opt 
    : /* default */ { $$ = true; } 
    | TOK_PUBLIC { $$ = true; } 
    | TOK_PRIVATE { $$ = false; } 
    ; 

static_opt 
    : /* default */ { $$ = false; } 
    | TOK_STATIC { $$ = true; } 
    ; 

在上面的例子中,我想現場規則返回現場節點,但我需要一些將在分析過程中傳遞了修改規則的屬性(即這些是綜合屬性)。

我可以想到兩種方法可以在不改變語法的情況下做到這一點。

  1. 使非終端修飾符有類型字段,在這裏創建新的字段,填寫我可以,並將其傳遞到字段填寫其餘。
  2. 讓修飾符擁有自己的類型,該類型擁有兩個bool值,並在字段規則中創建新字段時將其傳遞到提取數據。

在這種情況下,首選的方法是什麼?

+3

我會親自去替代兩個。主要是因爲'修飾符'不是一個真正的'字段',而是一些獨立的東西。 – 2012-03-24 20:57:19

+0

是的,我選擇了第二種方式,現在讓修飾符有型std :: pair 。這似乎取決於它,因爲在另一種情況下,採用第一種方法更合理。 – mcorley 2012-03-24 21:20:58

回答

2

與其他人一樣,建議首選的方法是使用帶可見性和靜態選項的結構體修飾符。但是我可能會將它作爲一個靜態修飾符,因爲它不會傳遞到字段中,而只是用於提取值並傳遞到Field中。你甚至可以在堆棧中分配它,並重新使用它來加快速度。

東西大致如下:

static struct { boolean vis_opt; boolean static_opt; } mod; 

field 
    : modifier type TOK_IDENT TOK_SEMICOLON 
    { 
     $$ = new Field(..., mod.vis_opt, mod.static_opt, ...); 
    } 
    ; 

modifier 
    : visibility_opt static_opt 
    { 
     mod.vis_opt = $1; 
     mod.static_opt = $2; 
    } 
    ; 

visibility_opt 
    : /* default */ { $$ = true; } 
    | TOK_PUBLIC { $$ = true; } 
    | TOK_PRIVATE { $$ = false; } 
    ; 

static_opt 
    : /* default */ { $$ = false; } 
    | TOK_STATIC { $$ = true; } 
    ; 

而且,除非你很漂亮某些語言的未來,你可能要考慮作出的知名度枚舉。你永遠不知道在開發語言時你最終會夢到什麼樣的visibilit'ies,至少如果你在枚舉中擁有它,稍後會更容易被擴展。

享受。