2016-11-19 31 views
0

我不明白为什么在2个功能相同的源文件中,只有1个编译阶段通过flex,另一个生成关于use of undeclared identifier的错误。使用flex时,有一些格式规则需要遵循?

这一个是OK(我通常不会在我的编辑器中使用的标签,这些都是空格)

 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编译我的扫描仪,是否必须遵循一些特定的约定?

+0

我尝试了flex的最新github版本,并得到相同的行为,这可能意味着我错过了一些东西... – user31223

+0

我真的需要一个反馈,因为没有暗示我做错了什么或如果这甚至是一个错误 – user31223

回答

0

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

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

用于第一(法声明)部分的标准格式是:

name  pattern 

凡名称必须从第一列开始(线的开始),并且图案通过白色分离在同一行空间。

用于第二(动作)部分中的格式是类似的:

pattern action 

凡模式必须从第一列开始(线的开始),并且操作由空格分隔在同一行 。该模式可以在多行上继续,但必须由空格缩进,否则将被解释为新模式。

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

有一个最终的句法特征很有用。在第一节中,没有指定应该复制到输出的词汇模式的代码可以在行的开始处由%{%}来指示。此外,在动作(第二)部分,任何没有模式和只有一个动作的代码都会被复制到输出中。

用变量声明开始文件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; 
+0

谢谢,使用'%{'和'%}'解决了这个问题,事实上,来自'flex'源doc文件夹的手册中的官方示例的格式与我的文章一样,甚至可以在线阅读https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_node/flex_5.html并且他们不使用您提到的最后2种解决方案中的任何一种;这只是让我更加困惑,因为我假设这些示例写得很好,并且在手册的前几节中没有提及格式规则*。至少现在我知道了,再次感谢。 – user31223

+0

这不完全正确。定义部分中的缩进行和规则部分中的缩进行都被复制到输出中,但在不同的地方。规则部分中的缩进行进入输出文件的开头,因此声明是文件范围。规则部分开始处的缩进行位于'yylex'的开头,因此声明是局部的(并且每次输入'yylex'时都会执行赋值操作(规则部分中的第一个规则之后的缩进行将转到未指定的位置,所以他们真的应该是评论。) – rici

+0

@rici感谢您的澄清。 –

相关问题