372 / 286 / 97
Регистрация: 17.12.2009
Сообщений: 567
|
|
1 | |
BISON, освобождение памяти при синтаксической ошибке.04.05.2011, 16:14. Показов 1406. Ответов 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(); } ![]()
0
|
|
04.05.2011, 16:14 | |
Ответы с готовыми решениями:
2
Освобождение памяти при выходе из программы Освобождение памяти при очистке ContentControl Освобождение памяти при вставке в QMap |
36 / 36 / 8
Регистрация: 13.05.2010
Сообщений: 70
|
|||||||||||
09.12.2011, 16:35 | 2 | ||||||||||
в функцию yyparse можно передать параметр при вызове.
и что если вместо malloc использовать обвертку, в которой будет вызываться память использую контролирующий объект т.е
да и не забыть объявить #define YYPARSE_PARAM dummy, SomeObject *MyObject и собрать с ключом %pure_parser (может и без него) Тогда ваш общий объект будет доступен как доп параметр во все функции.
0
|
04.03.2016, 16:34 | 3 | |||||
Aye Aye, лучше поздно, чем никогда
сделайте в вашей структуре метод delete , который в себе бы вызывал методы delete потомков.
0
|
04.03.2016, 16:34 | |
Помогаю со студенческими работами здесь
3
Освобождение выделенной памяти при закрытии программы Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |