用 C 表示抽象语法树

问题描述 投票:0回答:1

我正在用 C 实现一个简单玩具语言的编译器。我有一个可用的扫描器和解析器,以及 AST 的概念函数/构造的合理背景。 我的问题与用 C 表示 AST 的具体方式有关。我在不同的在线文本/资源中经常遇到三种样式:

每种类型的节点一个结构。

它有一个基节点“class”(结构),它是所有子结构中的第一个字段。 基本节点包含一个存储节点类型(常量、二元运算符、赋值等)的枚举。 使用一组宏来访问结构体的成员,每个结构体一组。 它看起来像这样:

struct ast_node_base {
    enum {CONSTANT, ADD, SUB, ASSIGNMENT} class;
};

struct ast_node_constant {
    struct ast_node_base *base;
    int value;
};

struct ast_node_add {
    struct ast_node_base *base;
    struct ast_node_base *left;
    struct ast_node_base *right;
};

struct ast_node_assign {
    struct ast_node_base *base;
    struct ast_node_base *left;
    struct ast_node_base *right;
};

#define CLASS(node) ((ast_node_base*)node)->class;

#define ADD_LEFT(node) ((ast_node_add*)node)->left;
#define ADD_RIGHT(node) ((ast_node_add*)node)->right;

#define ASSIGN_LEFT(node) ((ast_node_assign*)node)->left;
#define ASSIGN_RIGHT(node) ((ast_node_assign*)node)->right;

每个节点布局一个结构。

这看起来与上面的布局基本相同,除了使用 ast_node_add 和 ast_node_assign 代替,而是使用 ast_node_binary 来表示两者,因为这两个结构的布局是相同的,它们仅在 base-> 的内容上有所不同班级。 这样做的优点似乎是一组更统一的宏(LEFT(node) 对于具有左右的所有节点,而不是每个宏一对),但缺点似乎是 C 类型检查不会那么有用(例如,无法检测到应该只有 ast_node_add 的 ast_node_assign )。

一个结构体total,带有一个联合来保存不同类型的节点数据。

可以在这里找到比我能给出的更好的解释。 使用上一个示例中的类型,它看起来像:

struct ast_node {
  enum { CONSTANT, ADD, SUB, ASSIGNMENT } class;
  union {
    int value;
    struct {
      struct ast_node* left;
      struct ast_node* right;
    } op;
  };
};

我最喜欢第三个选项,因为它使递归遍历更加容易(因为避免了大量指针转换,有利于联合),但它也没有利用 C 类型检查。 第一个选项似乎是最危险的,因为它依赖于被强制转换的结构指针来访问任何节点的成员(甚至同一节点的不同成员需要不同的情况来访问(基本与左侧)),但这些强制转换是类型检查过,所以这可能没有实际意义。 对我来说,第二个选择似乎是两个世界中最糟糕的,尽管也许我错过了一些东西。

这三种方案哪一种最好,为什么? 我还没有遇到更好的第四个选项吗?我假设它们都不是“一刀切”的解决方案,所以如果重要的话,我正在实现的语言是静态类型的命令式语言,几乎C 的一个小子集。

我对第三种(联合)布局有一个具体问题。 如果我只使用值字段,值后面是否会有空白空间以适应写入操作的可能性?

c compiler-construction struct tree abstract-syntax-tree
1个回答
19
投票

您可以使其中任何一个工作。

我更喜欢联合布局,因为这样所有节点都有“相同”的布局。

[您可能会发现使用“子子列表”选项(例如,任意大的动态子列表)很有用,而不是使用左倾或右倾列表。]

您会发现这个问题并不是让编译器构建变得困难的问题。 相反,它具有符号表、执行各种分析、选择机器级 IR、构建代码生成器并进行代码优化。 然后你会遇到真正的用户,你会发现你真正做错了什么:-}

我会选择一个并运行它,以便您有机会解决其他问题。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.