C 在lex的定义和规则部分中编写语句的区别

C 在lex的定义和规则部分中编写语句的区别,c,lex,lexical-analysis,C,Lex,Lexical Analysis,我是莱克斯的新手。假设目标是编写一个lex程序来计算字数。我们应该声明一个int变量计数器,并在每次看到单词时递增它。问题是这些代码示例之间的区别是什么: %option main %{ #include<stdio.h> #include<string.h> int i = 0; %} %% ([a-zA-Z0-9])+ {i++;} %% %主选项 %{ #包括 #包括 int i=0; %} %% ([a-zA-Z0-

我是莱克斯的新手。假设目标是编写一个lex程序来计算字数。我们应该声明一个int变量计数器,并在每次看到单词时递增它。问题是这些代码示例之间的区别是什么:

%option main
%{ 
#include<stdio.h> 
#include<string.h> 
             int i = 0;
%} 

%%
([a-zA-Z0-9])+    {i++;}
%%
%主选项
%{ 
#包括
#包括
int i=0;
%} 
%%
([a-zA-Z0-9])+{i++;}
%%

%主选项
%{ 
#包括
#包括
%} 
%%
int i=0;
([a-zA-Z0-9])+{i++;}
%%

%主选项
#包括
#包括
int i=0;
%%
([a-zA-Z0-9])+{i++;}
%%
#include#include
的位置是否影响此处的代码?
程序是否根据我们声明整数变量的位置而改变?

是的,顺序很重要。但是这里的问题不是
#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);
                    return 0; /* Let the caller know we're done */
                  }
%主选项
/*%{和%}分隔符必须位于行的开头。
%{和%}之间的行被逐字复制到生成的
文件,靠近开头。
*/
%{ 
#包括
#包括
%} 
%%
/*这些行必须缩进。%%和%%后面的缩进行
*在第一条规则被逐字插入到生成的
*lexer位于函数定义的开头
*yylex。这允许您声明局部变量,如nword。
*/
int nwords=0;
([a-zA-Z0-9])+{++nWord;}
/*这里还有其他规定。每个可能的输入都应该由
*一些规则。
*/
/*至少可以忽略所有不匹配的字符
*使用以下回退(这应该是最后一条规则)。
*/
.|\n;
{printf(“%d个字。\n”,nwords);
返回0;/*让呼叫者知道我们完成了*/
}
这里需要使用
规则来打印字数,因为
nwords
yylex
之外将不可用。另一种方法是将
nwords
作为全局变量,但全局变量通常被认为是一个坏主意。(无论如何,您使用的是
%option main
,这意味着您不打算编写
main()
函数,因此没有其他逻辑位置来报告字数

如果要使
nwords
全局化,可以在
%{…%}
块中声明
nwords
,以便在任何函数之外声明它


Flex允许您省略
%{
%}
只要要插入的代码是缩进的。但这很脆弱,会让很多人在阅读代码时感到困惑;明确建议您使用分隔符,这样您就不必担心插入的代码是否缩进。

您可能还需要一个
|\n;
规则来忽略其他字符而不是呼应他们。。。
%option main
#include<stdio.h> 
#include<string.h> 
            int i = 0;
%%
([a-zA-Z0-9])+    {i++;}
%%
%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);
                    return 0; /* Let the caller know we're done */
                  }