我正在BISON中构建AST,并创建了用于构建树的类。我利用了一些继承的类来存储不同的信息(AddExprNode存储一个op(即“ +”),LiteralNode存储一个常量“ 1.49”,等等。)这些继承自超类ASTNode。
已为我为(微型)构建解析器的语言提供了一个语法文件。当我可以接收文字,变量或完整表达式作为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);
};
这是我的联合声明和类型定义:
%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手册的能力似乎使我失望。
答案 0 :(得分:3)
ASTNode * node; AddExprNode * add_node; MulExprNode * mul_node; VarRefNode * var_node; LiteralNode * lit_node;
类型为ASTNode *
的变量可以存储指向ASTNode
的任何子类的实例的指针。因此,您可以摆脱上面的所有foo_node
定义,只需保留ASTNode * node;
定义并将所有节点存储在该定义中即可。
这样,您的primary
规则的类型就可以是node
,没有问题。