我目前正在为玩具语言“ Micro”实现编译器,并创建了一些用于处理AST的类。我使用的解析器工具是Bison。我正在尝试为while循环和if / else语句生成程序集,但是在将父类对象ASTNode转换为其子元素WhileNode时遇到问题。
在解析器中,我已将所有这些节点的返回类型声明为父类ASTNode。
%type <node> if_stmt stmt base_stmt loop_stmt read_stmt write_stmt control_stmt return_stmt assign_stmt else_part while_stmt func_decl
%union{
std::string* s;
std::list<std::string> * str_list;
ASTNode * node;
std::list<ASTNode*> * ast_list;
JumpType * jtype;
Conditional * condition;
}
在while_stmt规则中,我初始化了WhileNode而不包含其中的stmt_list。这样我就可以准确地存储currentBlockID,以生成标签,分支语句等。
while_stmt : _WHILE _OPAREN cond _CPAREN decl
{
currentBlockID = scope_iterator;
SymbolTable* tmp = new SymbolTable("BLOCK " + std::to_string(scope_iterator++), ststack.top());
ststack.top()->children.push_back(tmp);
ststack.push(tmp);
$<node>$ = new WhileNode($3->left_expr, $3->right_expr, currentBlockID, $3->jtype, ASTNodeType::WHILE);
}
stmt_list _ENDWHILE
{
ststack.pop();
dynamic_cast<WhileNode *> $<node>6->copyStmtList(*7);
$$ = $<node>6;
}
;
我在中间规则中定义了WhileNode,以便在其他节点构造中迭代此blockID之前可以捕获currentBlockID(if / else节点也会增加blockID。)我的问题是dynamic_cast在规则的最后。我尝试使用静态和动态强制转换来执行此操作,但是两者都有问题。
这是动态转换当前出现的错误:
src/parser.yy: In function ‘int yyparse()’:
src/parser.yy:388:81: error: invalid type argument of unary ‘*’ (have ‘int’)
dynamic_cast<WhileNode *> $<node>6->copyStmtList(*7);
我已经参考过以这种方式实现此问题,但仍然遇到问题:How do I cast a parent class as the child class。
我使用dynamic_cast的原因是因为由于返回类型是ASTNode,所以它没有孩子的方法copyStmtList()。改进此铸造方法的任何帮助将不胜感激!
答案 0 :(得分:0)
嗯,我是个傻瓜。我没有意识到我不小心从'* $ 7'省略了'$',在这种情况下,尝试用* 7做任何事情只是在引用一个int类型(这显然是无效的)。对此我深表歉意。