winepretzel
winepretzel

Reputation: 227

Bison stack values ($n) being overwritten (using C)

I've written a parser in Bison that acts like this on expressions:

expr: 
   integer{
     exprPass pass;
     sprintf(s, load instructions, $1); //s is a global char buffer
     pass.s= s;
     pass.type = int;
     $$ = pass;
   }
   |
   double{
     exprPass pass;
     sprintf(s, load instructions, $1); //s is a global char buffer
     pass.s= s;
     pass.type = int;
     $$ = pass;
   }
   (etc)

This works fine until I run it through something like

comparison: expression LESSTHAN expression

When I print $1.s, it's the same as #3.s!

$2 has the correct operator, no issues there

I know expression is working ok; testing it with 2<0 using printfs shows me that pass.s gets 2, then 0. I don't know how $1 is somehow set to $3... I have to think the problem is in my C code?

My struct for expressions is

typedef exprPass{
   char* s;
   variable_type type;
   //some other data
}

Upvotes: 1

Views: 135

Answers (1)

Eric Postpischil
Eric Postpischil

Reputation: 224310

When exprPass is assigned in the lexical analyzer (or whatever else prepares it for Bison), is s set to point to a buffer in the lexical analyzer that contains the recognized string? If so, then what is happening is:

  • The first expression is recognized, and an exprPass is set to point to it.
  • The lexical analyzer reuses the buffer to continuing recognizing strings.
  • Now the first exprPass is pointing to a buffer that no longer contains the original string.
  • When the parser has both expressions, they are pointing to the same buffer, so they contain the same string.

To fix this, you must make a copy of each string (or otherwise preserve its value) when it is first recognized, and you must release the memory of that copy when the string is no longer needed. Depending on your needs, it may be easier to convert the string to a number when the lexical analyzer recognizes that and to store the number in exprPass. Then you have only a copy of the value and do not have to deal with copying strings and managing memory allocations.

Upvotes: 1

Related Questions