为什么在<< EOF >>之前写符号时会出错?

时间:2019-11-21 11:00:31

标签: regex pattern-matching flex-lexer lex

为什么会出现以下错误:

  

无法识别的规则

当我尝试这样做时:

%x CS
\"                      {BEGIN(CS);}
<CS>(.*)<<EOF>>         {printf("Error"); exit(0);}   *** ERROR:unrecognized rule 
<CS>\"                  {BEGIN(INITIAL); return;}

我该如何解决?

1 个答案:

答案 0 :(得分:0)

<<EOF>>只能用作完整模式。它不是模式元素。这是唯一不匹配输入的(f)lex模式,这意味着它必须返回0或以其他方式安排解析终止。

(F)lex不提供在输入末尾识别模式的机制。通常这不是问题,因为通常可以通过识别未出现在输入末尾的标记来处理它。一旦识别出这些令牌,任何与模式匹配的令牌都必须在末尾。

尽管确实提供了几乎通用的解决方案,但在某些情况下(例如您的代码段),甚至还有更简单的解决方案。例如,以下内容将识别带引号的字符串,并为未终止的字符串产生错误。

%x CS
%%
\"              { BEGIN(CS); }
<CS>[^"\n]+     { /* string contents */ }
<CS>\"          { BEGIN(INITIAL); }
<CS>\n          |
<CS><<EOF>>     { /* error */ }

在这种情况下,我们不允许在字符串中使用换行符,因此,未终止的字符串错误可能意味着该行未完成,或者在遇到换行符之前以文件结尾终止的字符串。这不太可能,因为非空文本文件应始终以换行符结尾,但是我们始终需要考虑特殊情况。 (如果要允许多行字符串,我们可以从第一个\n模式中删除<CS>的排除。通常,我们会添加一些规则来识别转义序列。)