Построение AST с использованием Bison - PullRequest
5 голосов
/ 24 марта 2012

Я работаю с Bison для создания AST для компилятора, который я пишу. Каков наилучший способ построения узлов в 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; }
  ;

В приведенном выше примере я хочу, чтобы правило поля возвращало узел Field, но мне нужны некоторые атрибуты правила-модификатора, которые будут переданы во время синтаксического анализа (т. Е. Это синтезированные атрибуты).

Я могу придумать два способа сделать это без изменения грамматики.

  1. Сделайте так, чтобы нетерминальный модификатор имел тип Field, создайте здесь новое поле, заполните все, что я могу, и передайте его в поле, чтобы заполнить остальные.
  2. Пусть модификатор имеет свой собственный тип, который содержит два значения bool, и передаст его, извлекая данные при создании нового поля в правиле поля.

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

1 Ответ

3 голосов
/ 30 марта 2012

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

Что-то вроде следующего:

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 вы можете мечтать при разработке языка, и, по крайней мере, если у вас это есть в перечислении, его будет легче расширить позже.

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

...