2012-03-24 2 views
4

Я работаю с Bison, чтобы построить AST для компилятора, который я пишу. Каков наилучший способ создания узлов в AST? Например, мой вопрос может быть более ясным.Построение АСТ с использованием Bison

Учитывая следующий фрагмент кода:

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. Внесите модификатор, не содержащий термина, введите Field, создайте новое поле здесь, заполните, что я могу, и передайте его в поле, чтобы заполнить остальные.
  2. Модификатор имеет свой собственный тип, который содержит два значения bool и передает это извлечение данных при создании нового поля в полевом правиле.

В таких ситуациях, как это, что является предпочтительным способом?

+3

Я бы лично пошел с альтернативными двумя. В основном потому, что 'модификатор' на самом деле не является« полем », а чем-то отдельным. –

+0

Да, я решил пойти со вторым способом, так как теперь модификатор имеет тип std :: pair . Похоже, это зависит от того, потому что в другом случае было больше смысла идти с первым подходом ... – mcorley

ответ

2

Как и другие, предпочтительным способом было бы иметь модификатор структуры с видимостью и статическими параметрами. Но я, вероятно, сделаю это статическим модификатором в том смысле, что он не будет передан в поле, а вместо этого просто используется для извлечения значений, а затем передается в поле. Вы даже можете выделить его в стек и повторно использовать, чтобы сделать это быстрее.

Что-то по следующим направлениям:

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; } 
    ; 

Кроме того, если вы не очень уверены в будущем языка, вы можете рассмотреть вопрос о внесении Visibility перечисления. Вы никогда не знаете, какого рода видимости вы могли бы мечтать, развивая язык, и, по крайней мере, если у вас есть это в перечислении, проще продлиться позже.

Наслаждайтесь.

Смежные вопросы