views:

41

answers:

1

Hy guys, i'm developing a scripting engine with flex and bison and now i'm implementing the eval and load functions for this language. Just to give you an example, the syntax is like :

import std.*;

load( "some_script.hy" );

eval( "foo = 123;" );

println( foo );

So, in my lexer i've implemented the function :

void hyb_parse_string( const char *str ){
    extern int yyparse(void);
    YY_BUFFER_STATE prev, next;
    /*
     * Save current buffer.
     */
    prev = YY_CURRENT_BUFFER;
    /*
     * yy_scan_string will call yy_switch_to_buffer.
     */
    next = yy_scan_string( str );
    /*
     * Do actual parsing (yyparse calls yylex).
     */
    yyparse();
    /*
     * Restore previous buffer.
     */
    yy_switch_to_buffer(prev);
}

But it does not seem to work. Well, it does but when the string (loaded from a file or directly evaluated) is finished, i get a sigsegv :

Program received signal SIGSEGV, Segmentation fault.
0xb7f2b801 in yylex () at src/lexer.cpp:1658
1658            if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )

As you may notice, the sigsegv is generated by the flex/bison code, not mine ... any hints, or at least any example on how to implement those kind of functions?

PS: I've succesfully implemented the include directive, but i need eval and load to work not at parsing time but execution time (kind of PHP's include/require directives).

+1  A: 

That error would seem to indicate the YY_CURRENT_BUFFER is invalid, probably null. This will happen if you call yypop_buffer_state to pop off the last input buffer. If you do that in an <<EOF>> rule, (for example, dealing with an include directive as you say you've implemented), you need to check YY_CURRENT_BUFFER and if its null, call yyterminate, otherwise it will crash like you see.

Edit

Simone, I'm not sure if I understand your comment. If you have an <<EOF>> rule, that action needs to either call yyterminate() or establish a new input source somehow, or you'll get a crash similar to what you report. When you see the crash, is it in the hyb_parse_string (in the yyparse call) function you posted? Use gdb's bt command to see a stack trace. What is your <<EOF>> rule action?

Chris Dodd
I'm not doing that in any rule, it's just a stand alone function called AFTER the script is parsed.Include directive is easy to implement 'cause i can deal with <<EOF>> as you said being inside a lexer rule, but what if i have to implement something external to a rule?
Simone Margaritelli