为什么该规则在使用C++在 Flex 上不起作用?
why is the rule not working on Flex using C++?
我有这段代码,但使用 c++ 无法正常工作。 我试过了,但我没有得到任何错误,你怎么看?有谁知道哪个是错误?
ejem05.l
%x use
%{
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
using namespace std;
#define MAX_USE_NUM 10
YY_BUFFER_STATE use_stack[MAX_USE_NUM];
int use_stack_ptr = 0;
%}
%option c++ noyywrap
%%
<INITIAL,use>[0-9]+ {cout<< "Number found: "<< endl;}
use[[:blank:]]+ {BEGIN(use);}
<use>[[:alpha:][:punct:][:digit:]]+ {
cout << "Nombre de archivo: "<< YYText() << endl;
if ( use_stack_ptr >= MAX_USE_NUM ) {
fprintf( stderr, "Too much files" );
exit(1);
}
use_stack[use_stack_ptr++] = YY_CURRENT_BUFFER;
ifstream in(YYText());
yyin = ∈
if (!yyin) {
cout<< "ERROR file not found" << endl;
exit(1);
}
yy_switch_to_buffer(
yy_create_buffer( yyin, YY_BUF_SIZE ) );
BEGIN(0);
}
<<EOF>> {
if (--use_stack_ptr < 0 ) {
yyterminate();
} else {
yy_delete_buffer( YY_CURRENT_BUFFER );
yy_switch_to_buffer(use_stack[use_stack_ptr] );
}
}
%%
int main(int argc, char** argv) {
++argv, --argc; /* skip over program name */
ifstream in(argv[0]);
yyFlexLexer* lexer = new yyFlexLexer(&in);
while(lexer->yylex()!=0)
;
return 0;
}
我的输入文件是:
恩特拉达.txt
use entrada1.txt
use entrada2.txt
文件内容:
恩特拉达1.txt
45
56
文件内容:
恩特拉达2.txt
34
67
89
我得到这个结果:
Nombre de archivo: entrada1.txtNombre de archivo: entrada2.txt
我使用以下命令编译了此文件:
flex ejem05.l
c++ lex.yy.cc -o ejem05
./ejem05 entrada.txt
不起作用的规则是:
<INITIAL,use>[0-9]+ {cout<< "Number found: "<< endl;}
提前谢谢。对不起,我的英语不好。
我不知道这是否是你所看到的行为的原因,因为它基本上是未定义的行为,但它似乎可能与问题有关。
这些都不是C++ I/O 对象的适当使用:
{
// ...
ifstream in(YYText()); // Point 1
yyin = ∈ // Point 2
if (!yyin) { // Point 3
cout<< "ERROR file not found" << endl;
exit(1);
}
yy_switch_to_buffer( // Point 4
yy_create_buffer( yyin, YY_BUF_SIZE ) );
BEGIN(0);
}
in
具有自动存储持续时间(即它是一个局部变量),因此它将在退出范围时被破坏,这将很快(但不是在传递给yy_create_buffer
之前。见下文。yyin
是一个成员变量,因此其生存期是 FlexLexer 对象的生存期。&in
是本地对象的地址(如上所述)。当块退出时,yyin
变成悬空指针,因为它指向的对象不再存在。任何使用它的尝试都将是未定义的行为。(我怀疑你侥幸逃脱的原因是yyin
实际上并不是每个人都使用,但我不确定。由于
yyin
刚刚设置为实际对象的地址,因此它不能是空指针。所以测试永远不会成功。即使文件未正确打开,也永远不会检测到错误。C 惯用法是检查fopen
的返回值,它返回指向FILE
的指针,因此可能是 NULL。检查文件是否正确打开C++习惯用法是:if (!in) {
它依赖于被覆盖的
operator!
.您也可以调用in.fail()
,它具有相同的语义。最后,您将
yyin
(通过引用)传递给yy_create_buffer
。yy_create_buffer
函数没有很好的文档记录(这是我自己很少使用C++接口的原因之一),但它没有所有权作为参数接收std::istream*
。(yyFlexLexer
对象在某种程度上被记录在案;在其构造函数的描述中,文档指出"yyFlexLexer 不拥有其流参数的所有权。用户有责任确保指向的流至少与 yyFlexLexer 实例一样长地保持活动状态",事实证明,在这种情况下适用大致相同的警告。这并不奇怪,因为yy_create_buffer
成员函数无法复制它传递std::istream
对象 - 这些对象不可复制 - 并且没有复制,就无法获得所有权。yy_create_buffer
所做的是保留一个指向std::istream
rdbuf()
的指针。(这没有记录,但在生成的代码中清晰可见。但是,因为它是std::fstream
,所以当in
被破坏时,它也会处理掉它的rdbuf()
。随后尝试使用指向已销毁rdbuf
的指针当然是更不确定的行为,但是如果您非常非常幸运(或者可能不走运),则内存中仍然有足够的位有效,指向rdbuf
在第一次尝试读取文件时报告文件结束或错误。这肯定会解释您所看到的症状,但这都是高度推测性的。
底线:如果您要使用C++,请按规则玩游戏。不要创建悬空指针,不要让应该保留的对象过早地被破坏,并在创建对象之后和使用对象之前检查对象的有效性std::fstream
。
- 我的神经网络不起作用 [XOR 问题]
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- C++为什么尽管我调用了void函数,它却不起作用
- 为什么在保护模式下继承升级不起作用
- 循环在计数器中不起作用
- 在其他文件中创建类时在 c++ 项目中不起作用
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 为什么二进制搜索在我的测试中不起作用
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 带有指定长度字符* 参数的 std::regex_search 在 VS2017 中不起作用?
- Bjarne Stroustrup Book - std_lib_facilities.h - 不起作用(未知类型名称)
- 为什么简单的算术减法在"if"条件下不起作用?
- 为什么Stroustup书中的has_f不起作用
- 你能检查一下为什么在这个代码中从链接列表中删除项目不起作用吗
- 嵌套While循环不起作用(C++问题)
- C++Matching Brackets 2解决方案不起作用
- 为什么这段代码不起作用,我该如何解决?
- 为什么该规则在使用C++在 Flex 上不起作用?