Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Compiler construction “弹性误差”;“缓冲区末端缺失”;在EOF时,当我使用yymore()时_Compiler Construction_Flex Lexer_Lexer - Fatal编程技术网

Compiler construction “弹性误差”;“缓冲区末端缺失”;在EOF时,当我使用yymore()时

Compiler construction “弹性误差”;“缓冲区末端缺失”;在EOF时,当我使用yymore()时,compiler-construction,flex-lexer,lexer,Compiler Construction,Flex Lexer,Lexer,我正在编写一个flex程序来处理字符串常量 当输入文件在字符串中遇到EOF时,我想返回一个错误标记 在文件满足EOF并打印“错误”后,我出现以下错误: 致命的flex扫描仪内部错误--缺少缓冲区结束 这是我的代码:(一个可以重现这个错误的简化版本) %选项noyywrap #定义错误300 #定义字符串301 字符*文本; %x染色体 %% \“{BEGIN(str);yymore();} \{开始(初始);text=yytext;返回字符串;} . {yymore();} {开始

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

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

在文件满足EOF并打印“错误”后,我出现以下错误:

致命的flex扫描仪内部错误--缺少缓冲区结束

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

%选项noyywrap
#定义错误300
#定义字符串301
字符*文本;
%x染色体
%%
\“{BEGIN(str);yymore();}
\{开始(初始);text=yytext;返回字符串;}
.        {yymore();}
{开始(初始);返回错误;}
%%
int main(){
int标记;
而((token=yylex())!=0){
如果(标记==字符串)
printf(“字符串:%s\n”,文本);
else if(令牌==错误)
printf(“错误\n”);
}
返回0;
}
当我删除
yymore()
函数调用时,错误消失,程序在打印“error”后正常退出


我想知道为什么会发生这种情况,我想在不删除
yymore()
的情况下解决它。在收到EOF指示后,您无法继续词法扫描,因此您的
规则不正确,这就是错误消息所指示的

与任何未定义的行为一样,在某些情况下,错误可能会导致任意行为,包括错误地假设它会工作的工作。(例如,对于flex版本,如果不使用
yymore
,就会发生这种情况。)

您需要确保在收到EOF后不会重新进入扫描仪循环。例如,您可以返回一个错误代码,指示无法读取更多令牌(与可重启的错误指示相反,如果需要的话)。或者您可以为lexer设置一个标志,使其在发生不可恢复的错误后立即返回0

下面是第二种策略的一个示例(只是规则,因为没有其他变化):

%%
/*插入第一个图案之前的缩进代码
*在yylex开始时,允许声明
*变量。致命错误标志声明为静态,
*因为这不是一个可重入的lexer。如果是
*可重入性,我们将标志放在lexer上下文中
*(作为“额外数据”的一部分),这将更加干净。
*/
静态整数致命错误=0;
/*如果我们上次返回的错误是致命的,我们会这样做
*不重新进入扫描仪循环;我们只是返回EOF
*/
如果(致命错误){
致命错误=0;/*重置标志以重新使用*/
返回0;
}
\“{BEGIN(str);yymore();}
\{开始(初始);text=yytext;返回字符串;}
.        {yymore();}
{开始(初始);
致命错误=1;/*设置致命错误标志*/
返回错误;}
%%
另一种可能的解决方案是使用“push解析器”,其中
yylex
使用每个令牌调用解析器,而不是相反
bison
支持这种风格,而且通常更方便;特别是,它允许一个操作向解析器发送多个令牌,这样就不需要使用静态本地标志

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