Реализация множественных типов возврата в семантических правилах BISON - PullRequest
0 голосов
/ 15 октября 2018

Я строю AST в BISON и создал классы для обработки дерева.Я использовал некоторые унаследованные классы для хранения различной информации (AddExprNode хранит опцию (то есть «+»), LiteralNode хранит литерал «1.49» и т. Д.) Они наследуются от суперкласса ASTNode.

I 'мне предоставили файл грамматики для языка, для которого я создаю свой синтаксический анализатор (Micro). Я столкнулся с проблемой, когда я мог получить литеральное, переменное или полное выражение в качестве возвращаемого типа для основного.

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 не позволяет вам сделать тип возврата ($$) для одного правила (как основной) отличается в зависимости от того, с какими токенами вы сталкиваетесь в правиле.

Есть ли способ сделать это?Мне кажется, что мой гугл-фу и способность читать руководство по BISON подводят меня.

1 Ответ

0 голосов
/ 15 октября 2018
ASTNode * node;
AddExprNode * add_node;
MulExprNode * mul_node;
VarRefNode * var_node;
LiteralNode * lit_node;

Переменная типа ASTNode * может хранить указатель на экземпляр любого подкласса ASTNode.Таким образом, вы можете избавиться от всех приведенных выше определений foo_node, просто сохраните определение ASTNode * node; и сохраните все свои узлы в этом.

Таким образом, тип вашего правила primary может быть простоnode и проблем нет.

...