返回介绍

子类的事先--Var

发布于 2025-02-24 22:44:39 字数 1677 浏览 0 评论 0 收藏 0

screen() 调用 new() 来创建一个新的变量符号并且返回它到识别器,并插入它到一个表达式树中。因此, Var 必须创建可以项节点行为的符号表项,也就是说,当定义 struct Var 的时候,我们需要扩展一个 struct Name 来继承在符号表中存在的能力并且我们必须支持动态绑定的函数可以适用于表达式节点。我们描述接口在 Var.h 中:

const void * Var;
const void * Assign;

一个变量具有一个名字和一个值。如果我们计算一个算术表达式的值,我们需要返回 .value 成员。如果我们删除一个表达式,我们一定不能删除变量节点,因为它存活在符号表中:

struct Var { struct Name _; double value; };
#define value(tree) (((struct Var *) tree) -> value)

static double doVar (const void * tree) {
  return value(tree);
}

static void freeVar (void * tree) {
}

就如在 4.6 节中讨论的,通过提供一个值的访问函数来简化代码。

创建一个变量需要分配一个 struct Var ,插入一个变量名的动态副本,并且标识值 VAR 被识别器规定:

static void * mkVar (va_list ap) {
  struct Var * node = calloc(1, sizeof(struct Var));
  const char * name = va_arg(ap, const char *);
  size_t len = strlen(name);

  assert(node);
  node-> _.name = malloc(len + 1);
  assert(node -> _.name);
  strcpy((void *) node-> _.name, name);
  node -> _.token = VAR;
  return node;
}

static struct Type _Var = { mkVar, doVar, freeVar };

const void * Var = & _Var;

new() 照料插入 Var 类型描述到节点中,在符号被 screen() 返回之前或者任何的使用。

就技术而言, mkVar()Name 的构建子。然而,只有变量名需要被动态存储。因为饿哦我们决定在我们的计算器中构建子负责分配一个对象,我们不能让 Var 构建子调用一个 Name 构建子来维护 .name.token 成员--一个 Name 构建子将会分配一个 struct Name 而不是一个 struct Var

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文