一棵树通常表示为一种包含指向其子节点的指针和一个存储其节点类型的
node
成员的结构,或者是某个特定类的实例,因此您可以派生出其实际类型(即如果它包含算术表达式、if语句、循环等)。
一个简单的示例确实是
if
语句,正如您所提到的那样。对于这个,您会做类似于以下的操作(伪代码如下):
enum AST_Node {
Node_if,
Node_and,
Node_or,
Node_not,
Node_equal,
Node_less,
};
struct AST {
struct AST *children[MAX_CHILDREN];
enum AST_Node node;
};
struct AST *parse_if_statement()
{
expect("if");
expect("(");
struct AST *condition = parse_expression();
expect(")");
struct AST *then_branch = parse_statement();
struct AST *else_branch = NULL;
if (accept("else")) {
else_branch = parse_statement();
}
struct AST *if_statement = new_AST_node(Node_if);
if_statement->children[0] = condition;
if_statement->children[1] = then_branch;
if_statement->children[2] = else_branch;
return if_statement;
}
基本上,您只需预期/接受永久的词汇元素(“if”,条件周围的括号等),然后将子树(条件和两个分支)的解析交给适当的解析器函数。这就是如何遍历树:您基本上会进行深度优先遍历,按顺序编译或解释每个子项。然后添加当前正在解释/编译的子树的节点类型所暗示的额外语义。
Value *interpret_if_statement(struct AST *ast)
{
assert(ast->node == Node_if);
struct AST *condition = ast->children[0];
struct AST *then_branch = ast->children[1];
struct AST *else_branch = ast->children[2];
Value *condval = interpret_expression(condition);
if (condval->bool_value == TRUE) {
return interpret_statement(then_branch);
} else if (else_branch != NULL) {
return interpret_statement(else_branch);
} else {
return NULL;
}
}