1
votes

I'm building an AST in BISON, and have created classes to handle building the tree. I've utilized some inherited classes to store different information (an AddExprNode stores an op (i.e "+"), LiteralNode stores a literal "1.49", etc.) These inherit from the superclass ASTNode.

I've been provided a grammar file for the language that I'm building my parser for (Micro.) I run into an issue when I could receive either a literal, variable, or full expression as the return type for a primary.

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);
                                };

Here's my union declaration, and the type definitions:

%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;
}

As can be seen above, BISON does not allow you to make the return type ($$) for a single rule (like primary) different based on what tokens you encounter in the rule.

Is there a way to accomplish this? My google-fu and ability to read the BISON manual seem to be failing me.

1

1 Answers

3
votes
ASTNode * node;
AddExprNode * add_node;
MulExprNode * mul_node;
VarRefNode * var_node;
LiteralNode * lit_node;

A variable of type ASTNode * can store a pointer to an instance of any subclass of ASTNode. So you can get rid of all the foo_node definitions above, just keep the ASTNode * node; definition and store all of your nodes in that one.

That way the type of your primary rule can just be node and there's no problem.