Представление AST в C с различными структурами для типов узлов - PullRequest
0 голосов
/ 31 марта 2019

У меня есть много структур, которые выглядят примерно так:

typedef struct ast_function_node
{        
    int node_type;
    ast_node* arguments;
    symbol* sym;
} ast_function_node;

typedef struct ast_while_node
{
    int node_type;
    ast_node* condition;
    ast_node* while_branch;
} ast_while_node;

typedef struct ast_assignment_node
{
    int node_type;
    symbol* sym;
    ast_node* value;
} ast_assignment_node;

typedef struct ast_number_node
{
    int node_type;
    double value;
} ast_number_node;

typedef struct ast_string_node 
{
    int node_type;
    char* value;
} ast_string_node;

etc...

И базовая структура:

typedef struct // Basic AST node
{
  int node_type;
  struct ast_node* left;
  struct ast_node* right;
} ast_node;

Я могу довольно легко заполнить этот AST, но когда дело доходит до его обхода, я застреваю в аду приведения типов. Если я хотел посетить каждый узел, посмотреть на его тип и затем сделать что-то соответственно, каков наилучший способ сделать это? Простое приведение к базовому узлу ast_node, конечно, не сделает этого.

1 Ответ

2 голосов
/ 01 апреля 2019

Я бы сделал это в C, используя struct с union членом:

typedef struct ast_function
{        
    ast_node* arguments;
    symbol* sym;
} ast_function;

typedef struct ast_while
{
    ast_node* condition;
    ast_node* while_branch;
} ast_while;

typedef struct ast_assignment
{
    symbol* sym;
    ast_node* value;
} ast_assignment;

/* Etc. */

typedef struct ast_node {
  int node_type;
  /* See anonymous unions in any C reference */
  union {
    ast_function   function_data;
    ast_while      while_data;
    ast_assignment assignment_data;
    /* Etc. */
  };
}

Тогда вам вообще не нужны приведения:

switch (node->node_type) {
  case AST_FUNCTION:
    handle_function(&node->function_data); 
    break;
  /* Etc. */
}

Если вы сделаете node_type enum вместо int, компилятор сможет предупредить вас, если вы пропустите возможность в вашем switch утверждении.

...