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

时间:2013-08-12 13:45:19

标签: c++ c++11 g++

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

1 个答案:

答案 0 :(得分:15)

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

  • 表达
  • 声明

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

您可能希望为扩展语句基类的语句类型设置一个类。

典型情况如下:

  • 语句块(语句列表)
  • ite(如果是其他的话)
  • for(一个for循环及其初始化语句列表,检查表达式,增量语句和块
  • while(类似,但只检查表达式
  • 变量声明
  • 赋值(包括+ = - = ++ - ,你可以用一个运算符字段,一个lval和一个rval包装所有的一个类)
  • 函数调用(void one)

表达式:

  • Bop(二进制操作,任何有2个操作数和1个操作符的东西,即+ - * /%|&&& || ==<
  • Uop(一元操作,任何有1个操作数和1个操作符的东西,即〜!)
  • 函数调用(not-void ones)
  • 条件表达式(exp?true val:false val)

拥有这2个抽象(表达式和语句)的好处在于,在所有类中,您将拥有抽象类型,并且能够以访问者模式访问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,只有静态类型就足够了,如果你计划实现一些后端,你也需要一些动态类型)。

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

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表单中的代码,您将需要一个内存,它将包含一个包含运行时内存信息的堆栈/堆。此时,您需要将值与其类型信息一起存储。