Как я могу разобрать в структуре данных для последующего выполнения? (Флекс - Бизон)
Это для школьного задания. Я просто ищу точку в правильном направлении. Может быть, я просто не узнаю ответ, когда увижу его (поиск в 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; }
/* ... */