文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
子类的事先--Var
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论