在 flex 中连接到 EOF

concatenating to EOF in flex

我有以下行:

<INITIAL><<EOF>>        {return 0;}

并且我需要忽略 EOF 之前的最后一个 EOL - \n\r\n。 我不知道如何将它连接到 EOF,以便它成为一个有效的正则表达式。我试过:

<INITIAL>((\n)|(\r\n))*<<EOF>>      {return 0;}

但它说它是 "unrecognized rule"。

<<EOF>> 并不是真正的模式符号,因为它不能成为模式的一部分。从逻辑上讲,EOF 标记不是一个字符; <<EOF>> 伪模式是唯一可以与空字符串匹配的弹性模式。

没有表示输入结束的弹性模式符号,因此无法表达模式 "followed by EOF"。

因此您需要从不同的角度进行工作:检测 而非 后跟 EOF 的模式。

如果一个模式后面没有 EOF,则它后面必须至少有一个字符。我们可以使用尾随上下文运算符来编写。一旦我们匹配了模式的这些实例,由于最长匹配规则:

\r?\n/(.|\n)  { /* A new line NOT followed by EOF */ }
\r?\n         { /* A new line followed by EOF */ }

我们需要在尾随上下文中使用 .|\n,因为 .\n 不匹配。由于尾随上下文运算符的优先级,括号是不必要的。

在换行符后强制检测尾随上下文会使此扫描器的交互式使用变得烦人,因为如果第一个规则返回换行符标记,则在读取另一行之前不会真正返回它。


顺便说一句,不需要

<INITIAL><<EOF>>        {return 0;}

这是文件结束时的 flex 默认行为,如果您需要在返回 0 之前执行某些操作,则只需要一个 <<EOF>> 规则。