使用Bison构建AST

Building an AST using Bison

本文关键字:AST 构建 Bison 使用      更新时间:2023-10-16

我正在与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,在此处创建新的Field,尽我所能填充,并将其传递给Field以填充其余部分
  2. 让修饰符拥有自己的类型,该类型包含两个布尔值,并在字段规则中创建新字段时向上传递提取数据

在这种情况下,首选的方法是什么?

像其他人建议的那样,首选的方法是使用具有可见性和静态选项的structModifier。但我可能会将其作为一个静态修饰符,因为它不会传递到字段中,而是简单地用于提取值,然后传递到字段。您甚至可以在堆栈中分配它,并重用它以使其更快。

大致如下:

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

此外,除非您对该语言的未来非常确定,否则您可能需要考虑将可见性作为枚举。你永远不知道在开发语言时,你最终可能会梦想什么样的可见性,至少如果你把它放在枚举中,以后更容易扩展。

享受吧。