我在使用2.5.4版本的flex中面临一些问题而无法找出问题。最近,Rhel机器从5升级到6.5。
class istream
替换为#include <isotream> using namespace std;
#include<iostream>
lexer.l(修改以创建简单的测试用例)
{
/* need this for the call to atof() below */
#include <math.h>
#include <string>
#include <iostream>
#undef yyFlexLexer
#define yyFlexLexer hSpiceConverterFlexer
#include "kernel.h"
using namespace std;
static bool a = true;
%}
%option c++ debug
%%
%{
string copyText;
%}
%%
生成的扫描程序文件(文件很大,因此添加问题部分)
/* A lexical scanner generated by flex */
/* Scanner skeleton version:
* $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
*/
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
#ifdef c_plusplus
#ifndef __cplusplus
#define __cplusplus
#endif
#endif
#ifdef __cplusplus
#include <stdlib.h>
class istream;
#include <unistd.h>
如果class istream
替换为<iostream> using namespace std;
,我可以使用gcc编译
我用class istream得到的错误
ex.yy.cc: In member function ¡virtual int hSpiceConverterFlexer::yylex()¢:
lex.yy.cc:987:37: error: cannot convert ¡std::istream* {aka std::basic_istream<char>*}¢ to ¡istream*¢ in assignment
lex.yy.cc: At global scope:
lex.yy.cc:1095:25: error: expected constructor, destructor, or type conversion before ¡(¢ token
lex.yy.cc:1130:35: error: variable or field ¡switch_streams¢ declared void
lex.yy.cc:1130:35: error: reference to ¡istream¢ is ambiguous
lexer.cpp:24:7: note: candidates are: class istream
class istream;
^
In file included from /depotbld/RHEL6.0/gcc-4.8.2/include/c++/4.8.2/ios:38:0,
from /depotbld/RHEL6.0/gcc-4.8.2/include/c++/4.8.2/ostream:38,
from /depotbld/RHEL6.0/gcc-4.8.2/include/c++/4.8.2/iostream:39,
from ../include/FlexLexer.h:47,
from lexer.cpp:239:
/depotbld/RHEL6.0/gcc-4.8.2/include/c++/4.8.2/iosfwd:133:33: note: typedef class std::basic_istream<char> std::istream
typedef basic_istream<char> istream;
^
lex.yy.cc:1130:44: error: ¡new_in¢ was not declared in this scope
lex.yy.cc:1130:59: error: expected primary-expression before ¡*¢ token
lex.yy.cc:1130:61: error: ¡new_out¢ was not declared in this scope
lexer.cpp:209:14: warning: ¡void* yy_flex_alloc(yy_size_t)¢ declared ¡static¢ but never defined [-Wunused-function]
static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
^
lexer.cpp:210:14: warning: ¡void* yy_flex_realloc(void*, yy_size_t)¢ declared ¡static¢ but never defined [-Wunused-function]
static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
^
lexer.cpp:211:13: warning: ¡void yy_flex_free(void*)¢ declared ¡static¢ but never defined [-Wunused-function]
static void yy_flex_free YY_PROTO(( void * ));
答案 0 :(得分:1)
这个问题不太可能是由flex 2.5.4的变化引起的。 2.5.3和2.5.4之间的差异很小。更有可能的是,flex 2.5.3和2.5.4都不兼容RHEL 6.5中包含的标准C ++库版本
据我了解,RHEL 6.5的flex版本为2.5.35,虽然距离最新版本很远,但与现代版本相近。升级到该版本应该可以解决问题,因为它使用了一组更正常的C ++包含。
经过一些实验,我使用gcc-4.8和flex 2.5.4成功编译了一个带有C ++ API的简单flex文件。为此,我使用以下补丁文件创建了一个稍微修改过的flex.skl
文件:
--- flex.skl 1996-09-10 18:58:54.000000000 -0500
+++ flex.skl.new 2016-01-05 23:16:36.435900415 -0500
@@ -8,9 +8,7 @@
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
-%-
#include <stdio.h>
-%*
/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
@@ -25,7 +23,8 @@
#include <stdlib.h>
%+
-class istream;
+#include <iostream>
+using namespace std;
%*
#include <unistd.h>
另外,2.5.4分发引用iostream.h
中包含的FlexLexer.h文件。您可能需要将其更改为iostream
。
完成后,我可以用:
生成C ++文件flex-2.5.4 -Sflex.skl.new ...
从上面的补丁中可以看出,修复包括:
stdio.h
。如果您不这样做,则EOF
未定义。istream
的转发声明并将其替换为#include <iostream>
。由于无论如何都会包含该标题,因此似乎可以更早地包含它。using namespace std;
,与flex 2.5.4中的用法相匹配。显然,它设计使用的C ++标准库没有将标准原型放入std
命名空间。我仍然认为使用古老的flex版本不是一个好主意,我鼓励你升级到最新的稳定版本(目前是2.5.39),或者至少升级到2.5.35。如果您遇到一些问题,请尝试创建一个Minimal Compilable示例并提交一个单独的问题。