使用Bison构建AST

5
我正在使用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 rule返回一个Field节点,但我需要在解析期间传递的某些modifier rule属性(即这些是合成属性)。
我能想到两种方法来实现这一点而不改变语法。
  1. 让非终结符modifier具有类型Field,在此处创建新的Field,填充它可以的部分,并将其传递给field规则以填写其余部分。
  2. 让modifier具有自己的类型,其中包含两个bool值,并将其传递给field规则,在创建新的Field时提取数据。
在这种情况下,哪种方式更受欢迎?

4
我个人会选择第二个替代方案。主要是因为“modifier”不是一个“field”,而是一个单独的东西。 - Some programmer dude
我选择了第二种方式,让修改器的类型为std::pair<bool,bool>。不过这似乎取决于情况,因为在另一种情况下,采用第一种方法更有意义... - mcorley
1个回答

3

正如其他人建议的那样,最好的方式是创建一个具有可见性和静态选项的结构 Modifier。但我可能会将其作为静态修饰符,因为它不会被传递到字段中,而是仅用于提取值,然后传递到 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; }
  ;

此外,除非您对语言的未来非常确定,否则可能需要考虑将可见性作为枚举类型。在开发语言时,您永远不知道会梦想到什么样的可见性,并且至少如果您将其放入枚举中,则更容易扩展。祝愉快。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接