13

如果我忘记在任何文件的末尾放置一个空行,我的程序就会出现语法错误。问题是我的语法需要换行符来结束当前行。由于不存在换行符,因此野牛会生成语法错误,因为它没有完成规则。

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

4

5 回答 5

20

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

<<EOF>> { static int once = 0; return once++ ? 0 : '\n' }
于 2009-11-22T20:45:59.497 回答
6

在您的 lex 文件中

#define yyterminate() return token::END

在你的 yacc 文件中

%token END 0 "end of file"
于 2009-11-19T00:58:20.260 回答
3

实际上,要在 lex|flex 中捕获文件结尾,您可以使用yywrap()词法分析器在到达输入文件结尾时调用的函数。

lex 和 flex 都可以使用此解决方案。 的回调yywrap()指示EOF您可以重新实现此函数并在输入流的末尾注入您需要做的工作。

于 2011-12-20T13:45:10.073 回答
1

以前的作品对我来说很好。

如果您使用 C Bizon(不是 C++),只需在 token::END 和 yacc 文件中使用 END %token END

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

可以这样解决:

bool term = false;
#define yyterminate() return (term = !term)?END : YY_NULL
于 2014-02-07T15:14:23.870 回答
0

另一种方法是重组您的语法,使其末尾不需要换行符。只要您的语言允许空行(通常是这种情况),您就可以使用换行符而不是行终止符来编写语法

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

Now if you do have a newline at the end of the input, this gets treated as a blank line after that newline, which is probably fine.

于 2020-03-22T17:49:25.883 回答