Как я могу разобрать в структуре данных для последующего выполнения? (Флекс - Бизон)

Это для школьного задания. Я просто ищу точку в правильном направлении. Может быть, я просто не узнаю ответ, когда увижу его (поиск в Google).

Вместо синтаксического анализа грамматики и немедленного выполнения {действия}, я хотел бы поместить все в структуру данных для последующего выполнения. Например: IF-cond-stmt-ELSE-stmt, при обычном разборе выполняются оба stmt. Я думаю, если бы я мог положить это куда-нибудь, я бы контролировал то, что происходит.

Я с базы?

1 ответ

Решение

Это совершенно правильно.

Обычный способ создать структуру данных - это построить ее (как своего рода дерево), установив $$ (то есть семантическое значение продукции) для поддерева, укорененного в этом узле.

Например:

%{
typedef
  struct Operation {
    short type;
    short operator;
    union {
      struct {
        struct Operation* left;
        struct Operation* right;
      };
      Identifier* id;
      // ... other possible value types
    };
  } Operation;
  Operation* new_binary_node(int operator, Operation* left, Operation* right) {
    Operation* subtree = malloc(sizeof *subtree);
    subtree->type = BINOP;
    subtree->operator = operator;
    subtree->left = left;
    subtree->right = right;
  }
  Operation* new_identifier_node(Identifier* id) {
    Operation* subtree = malloc(sizeof *subtree);
    subtree->type = IDENTIFIER;
    subtree->id = id;
  }
  void free_node(Operation* subtree) {
    if (subtree) {
      switch (subtree->operator) {
        case BINOP: free_node(subtree->left);
                    free_node(subtree->right);
                    break;
        case IDENTIFIER:
                    free_identifier(subtree->id);
                    break;
        // ...
      }
      free(subtree);
    }
  }
%}

%union {
   Operator*   op;
   Identifier* id;
}

%type <op> expr
%token <id> IDENTIFIER
%left '+' '-'
%left '*' '/'
/* ... */
%%
expr: expr '+' expr { $$ = new_binary_node('+', $1, $3); }
    | expr '-' expr { $$ = new_binary_node('-', $1, $3); }
    | expr '*' expr { $$ = new_binary_node('*', $1, $3); }
    | expr '/' expr { $$ = new_binary_node('/', $1, $3); }
    | IDENTIFIER    { $$ = new_identifier_node($1); }
    | '(' expr ')'  { $$ = $2; }
/* ... */
Другие вопросы по тегам