使用 flex 时有格式规则要遵循吗?

There are formatting rules to follow when using flex?

我不明白为什么在 2 个功能相同的源文件中,只有 1 个以 flex 通过编译阶段,而另一个生成关于 use of undeclared identifier 的错误。

这个没问题(我在编辑器中通常不使用制表符,那些都是空格)

        int num_lines = 0, num_chars = 0;

%%
\n      ++num_lines; ++num_chars;
.       ++num_chars;

%%
int main()
        {
        yylex();
        printf( "# of lines = %d, # of chars = %d\n",
                num_lines, num_chars );
        }

这个 flex 不接受,除了错误什么都不会产生

int num_lines = 0, num_chars = 0;

%%
\n  ++num_lines; ++num_chars;
.   ++num_chars;

%%

int main()
{
    yylex();
    printf( "# of lines = %d, # of chars = %d\n", num_lines, num_chars );
}

如果我想用 flex 编译我的扫描仪,我是否必须遵循一些特定的约定?

是的,lex/flex 中有格式规则,您违反了它们。

我总结一下。 lex/flex 输入程序分为三个主要部分,它们由第一列(行首)中的 %% 定界符分隔。最后一部分是可选的。第一部分用于词法声明;在本节中,可以命名正则表达式。第二部分指定要对模式执行的操作,第三部分(可选)用于要转录到输出文件的 (C) 代码。它用于定义操作部分中使用的函数。

第一个(lex 声明)部分的标准格式是:

name     pattern

名称必须从第一列(行首)开始并且模式在同一行 由白色 space.

分隔

第二个(操作)部分的格式类似:

pattern   action

模式必须从第一列(行首)开始,并且动作在同一行上被白色space分隔。该模式可以在多行上继续,但必须以白色缩进 space 否则它将被解释为一个新模式。

第三部分没有布局限制,因为只是跳过了代码。

最后一项语法功能很有用。在第一节中,没有指定应复制到输出的词法模式的代码可以由行首的 %{%} 指示。此外,在动作(第二)部分中,任何没有模式且只有一个动作的代码都会被复制到输出中。

C 中的变量声明开始您的文件违反了这些规则。如果它从左边开始,它将被视为词法定义。

如果你想在C中声明一些应该被复制到输出中的变量,你可以按以下方式进行:

%{
int num_lines = 0, num_chars = 0;
%}
%%
\n      ++num_lines; ++num_chars;
.       ++num_chars;

或者像这样:

%%
        int num_lines = 0, num_chars = 0;
\n      ++num_lines; ++num_chars;
.       ++num_chars;