Reputation: 359
I'm having a problem in logical operators
In my .y file i have:
expr: expr oper1 expr { $$=insert_expression($2, $1, $3); }
| expr oper2 expr { $$=insert_expression($2, $1, $3); }
;
In my .l file i determined that oper1 and oper2 are:
"<" | ">" | "=" | "<>" | "<=" | ">=" { return oper1; }
"AND" | "OR" { return oper2; }
Then i have a structure to put the values in:
typedef struct _Expression
{
char *oper;
struct _Expression *ex1;
struct _Expression *ex2;
} is_expression;
and put the values in:
is_expression* insert_expression(char* oper, is_expression *expr1, is_expression *expr2)
{
is_expression* e = (is_expression*)malloc(sizeof(is_expression));
e->ex1 = expr1;
e->ex2 = expr2;
e->oper = oper;
return e;
}
and finally show them:
void show_expression(is_expression *e)
{
show_expression(e->ex1);
printf("%s", e->oper);
show_expression(e->ex2);
}
but then i get a segmentation fault everytime i use a expr oper expr:
Program received signal SIGSEGV, Segmentation Fault
Any ideas about what i'm doing wrong?
Thanks
Upvotes: 1
Views: 1735
Reputation: 126536
In order to have sane values for $n
, you need a %union
directive to specify all the possible types, and then you need to use those types in %token
/%type
directives:
%union {
is_expression *exp;
char *str;
}
%token<str> oper1 oper2
%type<exp> expr
Then you ALSO need to make sure you set the values properly in your .l file:
"<" | ">" | "=" | "<>" | "<=" | ">=" { yylval.str = strdup(yytext); return oper1; }
"AND" | "OR" { yylval.str = strdup(yytext); return oper2; }
Otherwise, you'll be passing random garbage as the first operand to insert_expression
, and then crashing when you try to do anything with oper
(as it points at random garbage)
Upvotes: 0
Reputation: 14910
The default type for all tokens is int
. If you don't have
%union {
char *oper1
char *oper2
}
There will be problems. As it is, you are mixing pointers and ints. This causes you're program to attempt to access arbitrary memory, causing the segfault.
Edit:
Alright, then fire that thing up in gdb or my preferred cgdb.
cgdb yourCompiledParser
> r (add necessary command line switches)
when it segfaults
> backtrace
That will get you the approximate location it's failing at, and show you where you need break points. For gdb/cgdb debugging tips, check out this article.
Upvotes: 0
Reputation: 58667
Let's see:
void show_expression(is_expression *e)
{
show_expression(e->ex1);
printf("%s", e->oper);
show_expression(e->ex2);
}
Recursion must have a way to terminate!
A big clue is that you have just one printf
which prints the operator. But the tree has stuff in it other than just operators: namely, operands!
In your expression tree, these operands are leaf nodes. How are they represented? They probably have null pointers for ex1
and ex2
, right? (Hopefully not garbage: all your parser rules do $$
to some value, right?)
Also, there must be much more to your yacc file than that. The rule for expr
you have shown cannot exist by itself because it is not reducible to a sequence of terminal symbols.
Upvotes: 1