野牛文件结束

时间:2009-11-18 14:14:09

标签: yacc bison lex eof

如果我忘记在我的任何文件的末尾添加一个空行,我的程序会出现语法错误。问题是我的语法期望换行结束当前行。由于新行不存在,因此bison不会生成语法错误。

我该如何解决这个问题?我尝试让<<EOF>>返回MY_EOF但是当我这样做时,lex崩溃了一场可怕的死亡。我猜其默认EOF中的代码我没有打电话。我不知道它们可能是什么功能。使用EOF会创建错误symbol EOF is used, but is not defined as a token and has no rules

5 个答案:

答案 0 :(得分:16)

您可以使用flex EOF规则在输入中附加换行符:

<<EOF>> { static int once = 0; return once++ ? 0 : '\n' }

答案 1 :(得分:4)

在你的lex文件中

#define yyterminate() return token::END

在您的yacc文件中

%token END 0 "end of file"

答案 2 :(得分:2)

事实上,为了捕获lex | flex中的文件结尾,你可以使用词法分析器调用的yywrap()函数,如果到达输入文件的末尾。

这个解决方案可供lex和flex使用。yywrap()的回调表示EOF,因此您可以重新实现此功能并注入输入流末尾需要完成的工作。

答案 3 :(得分:1)

以前对我来说很好。

如果你使用C Bizon(不是C ++),只需使用END作为token :: END和yacc文件 %token END

之后还有另一个问题,如果宏不返回YY_NULL,它永远不会终止(无限循环)

可以这样解决:

bool term = false;
#define yyterminate() return (term = !term)?END : YY_NULL

答案 4 :(得分:0)

另一种方法是重组语法,以使最后不需要换行。只要您的语言允许空白行(通常是这种情况),您就可以使用换行符将其写为分隔符行而不是终止符

input: line | input '\n' line ;
line: /* empty */
    | ... various other rules ...

现在,如果 do 在输入末尾有换行符,则将其视为该换行符之后的空白行,这可能很好。