树通常表示为包含指向其子节点的指针的结构,并且它具有node
存储其节点类型的成员或者它属于某个类,以便您可以派生它的实际类型(即,如果它包含算术表达式,则if 语句、循环等)。
if
正如你提到的,一个简单的例子确实是声明。为此,你会做这样的事情(伪C如下):
enum AST_Node {
Node_if,
Node_and,
Node_or,
Node_not,
Node_equal,
Node_less,
// etc., other node types follow
};
struct AST {
struct AST *children[MAX_CHILDREN]; // don't do this
enum AST_Node node;
};
struct AST *parse_if_statement()
{
// expect tokens in order
expect("if");
// parse condition
expect("(");
struct AST *condition = parse_expression();
expect(")");
// parse two child statements
struct AST *then_branch = parse_statement();
struct AST *else_branch = NULL;
if (accept("else")) {
else_branch = parse_statement();
}
// create AST, fill in children
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];
// evaluate condition
Value *condval = interpret_expression(condition);
if (condval->bool_value == TRUE) {
// if condition is true, interpret "then" branch
return interpret_statement(then_branch);
} else if (else_branch != NULL) {
// otherwise interpret "else" branch, if any
return interpret_statement(else_branch);
} else {
return NULL;
}
}