static struct ast_node *ir_visit_ast_node(struct ast_node *node) { // 非法节点 if (nullptr == node) { return nullptr; } bool result = true; switch (node->type) { case AST_OP_NULL: // 叶子节点 result = ir_leaf_node(node); break; case AST_OP_MUL: // 乘法节点 result = ir_mul(node); break; case AST_OP_ADD: // 加法节点 result = ir_add(node); break; case AST_OP_EXPR: // 表达式结点,不显示表达式的值 // 由于不显示值,并且不支持赋值操作,都是右值操作,这里什么都不做 result = ir_show(node, false); break; case AST_OP_EXPR_SHOW: // 表达式结点,显示表达式的值 result = ir_show(node, true); break; case AST_OP_ASSIGN: // 赋值语句 result = ir_assign(node); break; case AST_OP_BLOCK: // 多个语句组成的块 result = ir_block(node); break; // TODO 其它运算符支持追加,同时增加表达式运算函数调用 //add_no2:sub case AST_OP_SUB: //减法节点 result = ir_sub(node); break; default: // 错误,不支持 result = false; break; } // 语义解析错误,则出错返回 if (!result) { node = nullptr; } return node; }这是在干嘛
时间: 2023-12-06 19:42:20 浏览: 83
这段代码是对抽象语法树(AST)进行遍历,根据节点类型调用不同的代码生成函数生成中间代码。具体来说:
- 对于叶子节点,调用 ir_leaf_node() 生成对应的中间代码。
- 对于乘法节点,调用 ir_mul() 生成对应的中间代码。
- 对于加法节点,调用 ir_add() 生成对应的中间代码。
- 对于表达式节点,根据是否需要显示表达式的值,调用 ir_show() 生成对应的中间代码。
- 对于赋值语句节点,调用 ir_assign() 生成对应的中间代码。
- 对于多个语句组成的块节点,调用 ir_block() 生成对应的中间代码。
- 对于不支持的节点类型,返回错误。
最后返回处理后的节点。这段代码的作用是将 AST 转换为中间代码,用于后续的编译和执行。
相关问题
// 赋值操作 static bool ir_assign(struct ast_node *node) { // TODO real number add struct ast_node *son1_node = node->sons[0]; struct ast_node *son2_node = node->sons[1]; // 赋值节点,自右往左运算 // 赋值运算符的左侧操作数 struct ast_node *left = ir_visit_ast_node(son1_node); if (!left) { // 某个变量没有定值 // 这里缺省设置变量不存在则创建,因此这里不会错误 return false; } // 赋值运算符的右侧操作数 struct ast_node *right = ir_visit_ast_node(son2_node); if (!right) { // 某个变量没有定值 return false; } // 这里只处理整型的数据,如需支持实数,则需要针对类型进行处理 // 创建临时变量保存IR的值,以及线性IR指令 node->blockInsts.addInst(right->blockInsts); node->blockInsts.addInst(left->blockInsts); node->blockInsts.addInst( new AssignIRInst(left->val, right->val)); node->val = left->val; return true; }修改代码为可以同时处理整数型和实数型
// 赋值操作
static bool ir_assign(struct ast_node *node) {
struct ast_node *son1_node = node->sons[0];
struct ast_node *son2_node = node->sons[1];
// 赋值节点,自右往左运算
// 赋值运算符的左侧操作数
struct ast_node *left = ir_visit_ast_node(son1_node);
if (!left) {
// 某个变量没有定值
// 这里缺省设置变量不存在则创建,因此这里不会错误
return false;
}
// 赋值运算符的右侧操作数
struct ast_node *right = ir_visit_ast_node(son2_node);
if (!right) {
// 某个变量没有定值
return false;
}
// 根据类型选择不同的指令
if (left->type == AST_TYPE_REAL || right->type == AST_TYPE_REAL) {
// 实数型的处理
node->blockInsts.addInst(right->blockInsts);
node->blockInsts.addInst(left->blockInsts);
node->blockInsts.addInst(
new AssignRealIRInst(left->val, right->val));
} else {
// 整数型的处理
node->blockInsts.addInst(right->blockInsts);
node->blockInsts.addInst(left->blockInsts);
node->blockInsts.addInst(
new AssignIRInst(left->val, right->val));
}
node->val = left->val;
return true;
}
typedef bool (*expr_handler_t)(struct ast_node *); static struct { enum ast_operator_type type; expr_handler_t action; } expr_handlers[] = { {AST_OP_NULL, expr_leaf_node}, {AST_OP_MUL, expr_mul}, {AST_OP_ADD, expr_add}, {AST_OP_EXPR, expr_noaction}, {AST_OP_EXPR_SHOW, expr_show}, {AST_OP_ASSIGN, expr_assign}, {AST_OP_BLOCK, expr_block}, //add_no2:sub {AST_OP_SUB, expr_sub}, };这是在干嘛
这段代码定义了一个表达式处理器类型`expr_handler_t`,它接受一个指向 AST 节点的指针,并返回一个布尔值。接着定义了一个数组`expr_handlers`,其中包含了不同类型的操作符和对应的处理函数,这些操作符包括加减乘除、赋值、块等。在程序中,当需要处理某个类型的操作符时,可以直接使用对应的处理函数。
阅读全文