1

嗨,伙计们,我正在开发一个带有 flex 和 bison 的脚本引擎,现在我正在为这种语言实现 eval 和 load 函数。举个例子,语法如下:

import std.*;

load( "some_script.hy" );

eval( "foo = 123;" );

println( foo );

所以,在我的词法分析器中,我实现了这个功能:

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);
}

但这似乎不起作用。好吧,确实如此,但是当字符串(从文件加载或直接评估)完成时,我得到一个 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 )

您可能会注意到,sigsegv 是由 flex/bison 代码生成的,而不是我的……任何提示,或者至少有任何关于如何实现这些功能的示例?

PS:我已经成功实现了 include 指令,但是我需要 eval 和 load 来工作,而不是在解析时而是在执行时(PHP 的 include/require 指令的一种)。

4

1 回答 1

1

该错误似乎表明YY_CURRENT_BUFFER无效,可能为空。如果您调用yypop_buffer_state弹出最后一个输入缓冲区,就会发生这种情况。如果您在<<EOF>>规则中执行此操作(例如,处理您所说的已实现的包含指令),您需要检查YY_CURRENT_BUFFER它是否为空,请调用yyterminate,否则它将像您看到的那样崩溃。

编辑

西蒙娜,我不确定我是否理解你的评论。如果您有<<EOF>>规则,则该操作需要调用 yyterminate() 或以某种方式建立新的输入源,否则您将遇到与您报告的类似的崩溃。当您看到崩溃时,它是否在您发布的hyb_parse_stringyyparse调用中)函数中?使用 gdb 的bt命令查看堆栈跟踪。你的<<EOF>>规则动作是什么?

于 2010-05-19T03:22:16.637 回答