定义中的书写语句与lex中的规则部分之间的区别

问题描述 投票:0回答:1

我是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的位置而变化?

c windows parsing yacc lex
1个回答
0
投票

是,订单很重要。但这不是#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可让您省略%{%},只要要插入的代码缩进即可。但这非常脆弱,会使许多人混淆您的代码。绝对建议您使用定界符,这样就不必担心插入的代码是否缩进。

© www.soinside.com 2019 - 2024. All rights reserved.