我正在用 BISON 构建 AST,并创建了类来处理树的构建。我使用了一些继承的类来存储不同的信息(AddExprNode 存储一个操作(即“+”),LiteralNode 存储一个文字“1.49”等)这些继承自父类(super class) ASTNode。
我已经为我正在为其构建解析器的语言提供了一个语法文件 (Micro.) 我遇到了一个问题,当我可以接收一个文字、变量或完整表达式作为 a 的返回类型时初级。
primary : _OPAREN expr _CPAREN {
$<node>$ = $2;
};
| id {
$<var_node>$ = new VarRefNode($1, ASTNodeType::VAR_REF);
};
| _INTLITERAL {
$<lit_node>$ = new LiteralNode(LiteralType::isINT, $1, ASTNodeType::LITERAL);
//$$->printNode();
};
| _FLOATLITERAL {
$<lit_node>$ = new LiteralNode(LiteralType::isFLOAT, $1, ASTNodeType::LITERAL);
};
这是我的 union 声明和类型定义:
%type <s> id str var_type any_type
%type <node> expr_prefix factor factor_prefix postfix_expr expr primary expr_list expr_list_tail call_expr
%type <add_node> addop
%type <mul_node> mulop
%type <var_node> primary
%type <lit_node> primary
%type <s_table> decl var_decl param_decl_tail param_decl_list
%type <s_entry> string_decl param_decl
%type <str_list> id_list id_tail
%type <st_list> func_declarations if_stmt stmt stmt_list func_body func_decl else_part loop_stmt while_stmt
%union{
SymbolTableEntry * s_entry;
char * s;
SymbolTable * s_table;
std::vector<SymbolTable *> * st_list;
std::vector<char *> * str_list;
ASTNode * node;
AddExprNode * add_node;
MulExprNode * mul_node;
VarRefNode * var_node;
LiteralNode * lit_node;
}
如上所示,BISON 不允许您根据在规则中遇到的标记使单个规则(如主要规则)的返回类型($$)不同。
有没有办法做到这一点?我的 google-fu 和阅读 BISON 手册的能力似乎让我失望了。
最佳答案
ASTNode * node; AddExprNode * add_node; MulExprNode * mul_node; VarRefNode * var_node; LiteralNode * lit_node;
ASTNode *
类型的变量可以存储指向 ASTNode
的任何子类的实例的指针。因此,您可以摆脱上面所有的 foo_node
定义,只需保留 ASTNode * node;
定义并将所有节点存储在该定义中即可。
这样你的 primary
规则的类型就可以是 node
并且没有问题。
关于c++ - 在 BISON 语义规则中实现多种返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52807994/