如果我忘记在我的任何文件的末尾添加一个空行,我的程序会出现语法错误。问题是我的语法期望换行结束当前行。由于新行不存在,因此bison不会生成语法错误。
我该如何解决这个问题?我尝试让<<EOF>>
返回MY_EOF
但是当我这样做时,lex崩溃了一场可怕的死亡。我猜其默认EOF中的代码我没有打电话。我不知道它们可能是什么功能。使用EOF会创建错误symbol EOF is used, but is not defined as a token and has no rules
答案 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 在输入末尾有换行符,则将其视为该换行符之后的空白行,这可能很好。