我是lex的新手。假设目的是编写一个lex程序来计算单词数。我们应该声明一个int变量计数器,并在每次看到一个字时将其递增。问题是这些代码之间有什么区别
%option main
%{
#include<stdio.h>
#include<string.h>
int i = 0;
%}
%%
([a-zA-Z0-9])+ {i++;}
%%
和
%option main
%{
#include<stdio.h>
#include<string.h>
%}
%%
int i = 0;
([a-zA-Z0-9])+ {i++;}
%%
和
%option main
#include<stdio.h>
#include<string.h>
int i = 0;
%%
([a-zA-Z0-9])+ {i++;}
%%
#include<stdio.h> #include<string.h>
的位置会影响此处的代码吗?程序是否会根据我们声明整数i
的位置而变化?
是,订单很重要。但这不是#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
全局,则可以在nwords
块中声明%{...%}
,以便在任何函数之外声明它。
Flex可让您省略%{
和%}
,只要要插入的代码缩进即可。但这非常脆弱,会使许多人混淆您的代码。绝对建议您使用定界符,这样就不必担心插入的代码是否缩进。