Сцепление с EOF в flex

У меня есть следующая строка:

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

и мне нужно игнорировать последний EOL - \n или же \r\n до EOF. Я не могу понять, как соединить его с EOF, чтобы оно было действительным регулярным выражением. Я пробовал:

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

но он говорит, что это "непризнанное правило".

1 ответ

Решение

<<EOF>> на самом деле не является символом шаблона, так как он не может быть частью шаблона. Логически, маркер EOF не является символом; <<EOF>> псевдо-шаблон - это единственный гибкий шаблон, которому может соответствовать пустая строка.

Не существует символа гибкого шаблона, который представляет конец ввода, и, таким образом, невозможно выразить шаблон "с последующим EOF".

Таким образом, вам нужно работать с другой точки зрения: обнаружить шаблон, за которым не следует 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;}

Это гибкое поведение по умолчанию в конце файла, и вам нужно только <<EOF>> Правило, если вам нужно сделать что-то до возврата 0.

Другие вопросы по тегам