-1

我目前正在为玩具语言“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 规则中,我在没有包含 stmt_list 的情况下初始化 WhileNode。这样我就可以准确地存储 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()。任何有关改进这种铸造方法的帮助将不胜感激!

4

1 回答 1

0

好吧,我是个傻瓜。我没有意识到我不小心从 '*$7' 中省略了 '$',在这种情况下,尝试使用 *7 做任何事情只是取消引用一个 int 类型(这显然是无效的)。我为这个错误道歉。

于 2018-10-27T02:49:09.117 回答