Да, порядок имеет значение. Но здесь дело не в #include
строках.
Вот один правильный способ написания этой программы:
%option main
/* The %{ and %} delimiters must be at the beginning of the line.
Lines between %{ and %} are copied verbatim into the generated
file, near to the beginning.
*/
%{
#include <stdio.h>
#include <string.h>
%}
%%
/* These lines must be indented. Indented lines after the %% and
* before the first rule are inserted verbatim into the generated
* lexer right at the beginning of the definition of the function
* yylex. This lets you declare local variables, like nwords.
*/
int nwords = 0;
([a-zA-Z0-9])+ { ++nwords; }
/* Other rules go here. Every possible input should be matched by
* some rule.
*/
/* At a minimum, you can ignore all unmatched characters
* using the following fall back (which should be the last rule).
*/
.|\n ;
<<EOF>> { printf("%d words found.\n", nwords); }
Правило <<EOF>>
необходимо здесь, чтобы распечататьколичество слов, потому что nwords
не будет доступно за пределами yylex
. Альтернативой является сделать nwords
глобальной переменной, но глобальные переменные обычно считаются плохой идеей. (И в любом случае вы используете %option main
, что означает, что вы не собираетесь писать функцию main()
, поэтому нет другого логического места, чтобы сообщить количество слов.
Если вы хотите сделать nwords
global, вы должны объявить nwords
в блоке %{...%}
, чтобы он был объявлен вне какой-либо функции.
Flex позволяет исключать %{
и %}
до тех пор, пока кодвставка с отступом. Но это довольно хрупко и может смутить многих людей, читающих ваш код; определенно рекомендуется использовать разделители, и тогда вам не нужно беспокоиться о том, вставлен ли код с отступом или нет.