Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
372 / 286 / 97
Регистрация: 17.12.2009
Сообщений: 567
1

BISON, освобождение памяти при синтаксической ошибке.

04.05.2011, 16:14. Просмотров 1284. Ответов 2


Здравствуйте. При работе с BISON, как освободить память выделенную под возвращаемые продукциями "объекты" в случае синтаксической ошибки? Все мануалы облазил (штук 5-6) не нашел ничего кроме описания зачем нужен токен error и yyerrok и все такое.
Вот составил пример, чтобы вопрос был ясен и было на чем показать. В нем надо как-то, в продукции line строка 36, освободить память, занятую деревом, если произошла ошибка разбора.
Код
/* Синтаксический анализатор для простых арифметических выражений.  */
%{
#include <stdio.h>
#include <stdlib.h>
#define YYDEBUG 1
static int yylex(void);
static int yyerror(char*);

float variable;

typedef struct tree {
  struct tree *left;
  struct tree *right;
  float val;
  int op;
} tree;
#define YYSTYPE tree*
tree *make_tree(tree *l, tree *r, float v, int o);
void print_tree(tree *t);
void free_tree(tree *t);
%}

%token NUM
%left '+' '-'
%left '/' '*'
%left UNARY
%left '('

%%
input:
    line                 { print_tree($1); free_tree($1); }
  | input line           { print_tree($2); free_tree($2); }
  ;
line:
    exp '\n'             { $$ = $1; }
  | error '\n'           { /* Тут надо освободить память. */ }
  ;
exp:
    prim
  | exp '+' exp          { $$ = make_tree($1, $3, 0, '+'); }
  | exp '-' exp          { $$ = make_tree($1, $3, 0, '-'); }
  | exp '*' exp          { $$ = make_tree($1, $3, 0, '*'); }
  | exp '/' exp          { $$ = make_tree($1, $3, 0, '/'); }
  ;
prim:
    '(' exp ')'          { $$ = $2; }
  | '-' prim %prec UNARY { $$ = make_tree($2, NULL, 0, 'u'); }
  | NUM                  { $$ = make_tree(NULL, NULL, variable, 'v'); }
  ;
%%
tree *make_tree(tree *l, tree *r, float v, int o)
{
  tree* t = (tree*)malloc(sizeof(tree));
  t->left = l;
  t->right = r;
  t->val = v;
  t->op = o;
  return t;
}
void print_tree(tree *t)
{
  static n = 0;
  if (t != NULL) {
    int i;
    for (i = 0; i < n; i++)
      printf(" ");
    switch(t->op) {
    case 'u': printf("- unary\n"); break;
    case 'v': printf("%f\n", t->val); break;
    default:
      printf("%c\n", t->op);
    }
    n++;
    print_tree(t->left);
    print_tree(t->right);
    n--;
  }
}
void free_tree(tree *t)
{
  if (t != NULL) {
    free_tree(t->left);
    free_tree(t->right);
    free(t);
  }
}
int yylex()
{
  int c;
  while (!feof(stdin) && (c = getc(stdin)) == ' ');
  if (feof(stdin)) return 0;
  switch (c) {
  case '+':
  case '-':
  case '*':
  case '/':
  case '(':
  case ')':
  case '\n':
        return c;
  default:
    break;
  }
  if (isdigit(c)) {
    ungetc(c, stdin);
    fscanf(stdin, "%f", &variable);
    return NUM;
  }
}

int yyerror(char *s)
{
  fprintf(stderr, "%s.\n", s);
  return 1;
}
int main()
{
  /* yydebug = 1; */
  return yyparse();
}
Единственная моя идея: сделать стек с указателями на узлы дерева, и при появлении токена error все эти указатели освобождать. Но это плохой вариант, слишком много лишнего кода. Пример выше - всего лишь пример, есть "реальная программа" для построения синтаксического дерева для исходника на C, и там время работы критично, мне кажется... Нет ли у BISON какого-нибудь "родного" способа освободить память? Собственным стеком бизона yyvs пользоваться не получается ошибка сегментирования или ноль реакции на print_tree и free_tree.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.05.2011, 16:14
Ответы с готовыми решениями:

Apache2 не выдает предупреждение о синтаксической ошибке
Установил Апач на операционную систему Линукс ( Убунту) по этому руководству...

Освобождение памяти при выходе из программы
Просматривая исходные тексты программ, заметил, что часто на событие FormDestroy вешают удаление...

Освобождение памяти при очистке ContentControl
Добрый день! Ситуация следующая, динамически создаю некотрый userControl, помещаю его в...

Освобождение памяти при вставке в QMap
Есть Qmap&lt;int,int*&gt; data; делаю инсерт int * d = new int; *d = 5; data.insert(0,d); d =...

2
36 / 36 / 8
Регистрация: 13.05.2010
Сообщений: 70
09.12.2011, 16:35 2
в функцию yyparse можно передать параметр при вызове.
и что если вместо malloc использовать обвертку, в которой будет вызываться память использую контролирующий объект

т.е

C
1
yyparse( NULL, MyObject );
и
C
1
2
3
4
5
6
7
8
9
tree *make_tree(SomeObject *MyObject, tree *l, tree *r, float v, int o)
{
  tree* t = (tree*)tree_alloc(MyObject->tree_heap, sizeof(tree));
  t->left = l;
  t->right = r;
  t->val = v;
  t->op = o;
  return t;
}

да и не забыть объявить #define YYPARSE_PARAM dummy, SomeObject *MyObject
и собрать с ключом %pure_parser (может и без него)

Тогда ваш общий объект будет доступен как доп параметр во все функции.
0
215 / 63 / 25
Регистрация: 30.04.2013
Сообщений: 866
Записей в блоге: 10
04.03.2016, 16:34 3
Aye Aye, лучше поздно, чем никогда

сделайте в вашей структуре метод delete , который в себе бы вызывал методы delete потомков.
C
1
2
3
4
5
6
7
8
9
10
11
struct A {
  A* left;
  A *right;
 
  void delete {
     left->delete();
     right->delete();
     free(left);
     free(right);
  }
};
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.03.2016, 16:34

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Освобождение памяти при удалении структуры
Есть структура с указателем на блок памяти, если удалить структуру,память внутри структуры...

Освобождение памяти при работе скрипта
Добрый день! Столкнулся с проблемой постепенного пожирания памяти работающим скриптом. Скрипт...

Освобождение памяти при работе с DataTable
Работаю с большими таблицами (DataTable) локально. Есть ли какие-нибудь средства принудительного...

Освобождение выделенной памяти при закрытии программы
Добрый вечер. Подскажите, при закрытии программы, вся память что была выделена внутри программы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.