Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building an AST using Bison

I am working with Bison to build an AST for a compiler I am writing. What is the best way to build up the nodes in the AST? My question might be more clear with an example.

Given the following snippet:

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

In the above example I want the field rule to return a Field node, but I need some of the attributes of the modifier rule that will be passed up during parsing (i.e. these are synthesized attributes).

I can think of two ways to do this without changing the grammar.

  1. Make the non-terminal modifier have type Field, create the new Field here, fill in what I can, and pass it up to field to fill in the rest.
  2. Let modifier have its own type that holds two bool values and pass this up extracting the data when creating the new Field in the field rule.

In situations like this what is the preferred way to go?

like image 694
mcorley Avatar asked Oct 23 '22 04:10

mcorley


1 Answers

Like others have suggested the preferred way would be to have a struct Modifier with visibility and static options. But I would probably make this a static modifier in that it won't be passed into field, but instead simply used to extract the values and then passed into Field. You can even allocate it in the stack, and reuse it to make this faster.

Something along the following lines:

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

Also, unless you're pretty certain of the future of the language, you might want to consider making visibility an enum. You never know what kind of visibilit'ies' you might end up dreaming while developing the language, and at least if you have it in an enum is easier to be extended later.

Enjoy.

like image 155
Paulo Matos Avatar answered Nov 12 '22 19:11

Paulo Matos