2

My bison / flex parser start by reading input from a file:

FILE *myfile = fopen(file.c_str(), "r");
yyin = myfile;
yyparse();

At some point after that, it reads and parse input from a string in memory:

yy_scan_string(str.c_str());
yyparse();
yy_delete_buffer(YY_CURRENT_BUFFER);

It seems to work well up to this point. However, when the program needs to read and parse input from the file again using the first code it doesn't work (terminates with segmentation fault). Is there a fix to this issue?

Timofei Davydik
  • 7,244
  • 7
  • 33
  • 59
mhmhsh
  • 161
  • 1
  • 13

2 Answers2

4

The problem is that after your second block of code above, flex's input buffer (YY_CURRENT_BUFFER) points at the buffer you created in yy_scan_string and deleted with yy_delete_buffer. So the next call to yylex (from yyparse) will likely crash from derferencing a dangling pointer. So what you need to do is set the buffer state to a valid buffer with yy_switch_to_buffer after calling yy_delete_buffer and before calling yyparse again. You can do that with push/pop as you note (though that code does leak the two created buffers and never frees them). Or you can more directly save and restore the old buffer around the parse from the string:

YY_BUFFER_STATE temp = YY_CURRENT_BUFFER;
yy_scan_string(str.c_str());
yyparse();
yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer(temp);
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
0

I think I figured it out, simply by pushing and poping buffers. Instead of the above, I used:

yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));

yypush_buffer_state(yy_scan_string(str));

yypop_buffer_state();

source: http://westes.github.io/flex/manual/Multiple-Input-Buffers.html

rici
  • 234,347
  • 28
  • 237
  • 341
mhmhsh
  • 161
  • 1
  • 13