弹性错误"错过缓冲区的结束"在我使用yymore时的EOF()

时间:2016-09-23 07:30:17

标签: compiler-construction flex-lexer lexer

我正在编写一个flex程序来处理字符串常量。

当输入文件在字符串中遇到EOF时,我想返回一个ERROR标记。

文件遇到EOF后出现以下错误" ERROR"打印出来:

  

致命的弹性扫描仪内部错误 - 错过缓冲区的结束

这是我的代码:(可以重现此错误的简化版本)

%option noyywrap
    #define ERROR 300
    #define STRING 301
    char *text;
%x str

%%

\"            {BEGIN(str); yymore();}
<str>\"       {BEGIN(INITIAL); text=yytext; return STRING;}
<str>.        {yymore();}
<str><<EOF>>  {BEGIN(INITIAL); return ERROR;}

%%

int main(){
    int token;
    while((token=yylex())!=0){
        if(token==STRING)
            printf("string:%s\n",text);
        else if(token==ERROR)
            printf("ERROR\n");
    }
    return 0;
}

当我删除yymore()函数调用时,错误消失,打印后程序正常退出&#34; ERROR&#34;。

我想知道为什么会这样,我想在不删除yymore()的情况下解决它。

1 个答案:

答案 0 :(得分:1)

收到EOF指示后,您无法继续进行词法扫描,因此>>> import numpy as np >>> isinstance(2.0, np.float) True >>> isinstance(2.0, np.float64) False 规则不正确,这就是错误消息所指示的内容。

与任何未定义的行为一样,在某些情况下,错误可能会导致任意行为,包括错误地认为它可以正常工作。 (使用您的弹性版本,如果您不使用<str><<EOF>>,就会发生这种情况。)

您需要确保在收到EOF后不重新输入扫描仪循环。例如,您可以返回一个错误代码,表示不能再读取令牌(与可重新启动的错误指示相反,如果需要)。或者您可以为词法分析器设置一个标志,使其立即返回0不可恢复的错误。

这是第二个策略的一个例子(只是规则,因为没有别的变化):

yymore

另一种可能的解决方案是使用&#34;推送解析器&#34;,其中%% /* indented code before the first pattern is inserted * at the beginning of yylex, allowing declaration of * variables. The fatal_error flag is declared static, * since this is not a reentrable lexer. If it were * reentrable, we'd put the flag in the lexer context * (as part of the "extra data"), which would be a lot cleaner. */ static int fatal_error = 0; /* If the error we last returned was fatal, we do * not re-enter the scanner loop; we just return EOF */ if (fatal_error) { fatal_error = 0; /* reset the flag for reuse */ return 0; } \" {BEGIN(str); yymore();} <str>\" {BEGIN(INITIAL); text=yytext; return STRING;} <str>. {yymore();} <str><<EOF>> {BEGIN(INITIAL); fatal_error = 1; /* Set the fatal error flag */ return ERROR;} %% 使用每个令牌调用解析器,而不是相反。 yylex支持这种风格,而且它通常更方便;特别是,它允许一个动作向解析器发送多个令牌,在这种情况下,它将不需要静态本地标志。