C++中的抽象语法树表示

Abstract Syntax Tree representation in C++

本文关键字:语法树 表示 抽象 C++      更新时间:2023-10-16

我已经有了创建令牌列表的令牌化器接口。我有解析器的工作机制。它真的很独特,很有魅力。我唯一怀念的是AST的基本结构。树、节点和语句应该如何在抽象级别上表示。我不需要任何实现,只需要一个快速的想法,它在类层次结构中应该是什么样子?我正在研究一种面向对象的语言。是的,我已经意识到我需要两种类型的陈述。一些返回值的"表达式"类型语句和一个不返回的指令流控制类型语句。非常感谢。

如果您的语言是命令式/c,那么常见的场景从顶部层次结构拆分为两个超类型开始:

  • 表达式
  • 声明

程序是一个语句列表,它本身就是一个语句。

对于扩展语句基类的语句类型,您可能希望有一个类。

一个典型的场景如下:

  • 语句块(语句列表)
  • ite(if then else)
  • for(一个带有初始化语句列表、检查表达式、增量语句和块的for循环
  • while(类似,但仅检查表达式
  • 变量声明
  • 赋值(包括+=-=++--,您可以用一个运算符字段、一个lval和一个rval将所有赋值封装在一个类中)
  • 函数调用(无效一个)

对于表达式:

  • Bop(二进制运算,任何有2个操作数和1个运算符的运算,即+-*/%|&&||=<
  • Uop(一元运算,任何有1个操作数和1个运算符的运算,即~!)
  • 函数调用(不是无效调用)
  • 条件表达式(exp?true val:false val)

拥有这两个抽象(表达式和语句)的好处是,在所有类中,您都将拥有抽象类型,并且能够使用访问者模式访问AST。

例如,有些类看起来像这样(伪代码):

class Ite extends Statement {
   Expression condition;
   Statement ifBranch;
   Statement elseBranch;
}

class Bop extends Expression {
   BOperator operator;  // +, -. * or whatever
   Expression left;     // Left operand
   Expression right;    // Right operand
}

class StatementBlock extends Statement {
   List<Statement> statements;
}

class Assignment extends Statement {
   AOperator assignOp;  // = += -= etc.
   LVal lvalue;         // The lvalue cannot be an arbitrary expression, you will usually have a specific type for it
   Expression rvalue;   // Right value
}

此外,您还需要某种方式来表示类型(对于AST,仅静态类型就足够了,如果您还计划实现一些后端,那么您还需要一些动态类型)。

如果您不打算支持需要大小信息的固定大小数组,则通常可以使用一些枚举来指定静态类型。如果您想要大小为的固定大小数组,可以为类型实现一个类,并使数组类型包含额外的大小信息。

enum Type {
   CHAR,
   SHORT,
   INT,
   LONG,
   FLOAT,
   DOUBLE,
   ARRAY
}
class Float extends StaticType {
    final Type type = Type.FLOAT;
}
class Array extends StaticArray {
    final Type type = Type.ARRAY;
    int size;
}

然后,您将为AST中的每个类型实例化一个StaticType实例,例如,当用户声明变量时。如果将来计划进行静态类型检查,也可以使用相同的层次结构。

至于运行/解释AST形式的代码,您将需要一个Memory,它将保存一个包含运行时内存信息的堆栈/堆。此时,您需要将值及其类型信息一起存储。