【问题标题】:Why I get error while I write symbols before <<EOF>>?为什么我在 <<EOF>> 之前写符号时会出错?
【发布时间】:2019-11-21 11:00:31
【问题描述】:
为什么会出现以下错误:
无法识别的规则
当我尝试这样做时:
%x CS
\" {BEGIN(CS);}
<CS>(.*)<<EOF>> {printf("Error"); exit(0);} *** ERROR:unrecognized rule
<CS>\" {BEGIN(INITIAL); return;}
我该如何解决?
【问题讨论】:
标签:
regex
pattern-matching
flex-lexer
lex
【解决方案1】:
<<EOF>> 只能用作完整的模式。它不是模式元素。它是唯一不匹配任何输入的 (f)lex 模式,这意味着它必须返回 0 或以其他方式安排解析终止。
(F)lex 不提供在输入结束时识别模式的机制。这通常不是问题,因为它通常可以通过识别没有出现在输入末尾的标记来处理;一旦这些被识别,任何也匹配模式的标记都必须在末尾。
虽然这确实提供了一个几乎通用的解决方案,但在特定情况下,例如您的 sn-p,还有更简单的解决方案。例如,以下将识别带引号的字符串并为未终止的字符串产生错误。
%x CS
%%
\" { BEGIN(CS); }
<CS>[^"\n]+ { /* string contents */ }
<CS>\" { BEGIN(INITIAL); }
<CS>\n |
<CS><<EOF>> { /* error */ }
在这种情况下,我们不允许在字符串中使用换行符,因此未终止的字符串错误可能意味着字符串未在行内完成或字符串在遇到换行符之前被文件结尾终止时间>。这不太可能,因为非空文本文件应该总是以换行符结尾,但我们总是需要考虑极端情况。 (如果我们想允许多行字符串,我们可以从第一个 <CS> 模式中删除 \n 的排除。通常我们会添加规则来识别转义序列。)