c++ - Flex Lexer 工具中的类 istream

标签 c++ flex-lexer lexer

我在 2.5.4 版本的 flex 中遇到了一些问题,但无法找出问题所在。最近Rhel机器从5升级到6.5。

  1. 我可以替换 class istream 吗?与 #include <isotream> using namespace std;
  2. 如果是,我应该在 lexer.l 文件中写入什么。
  3. 在 flex-2.5.3 中生成 #include<iostream>仅使用命名空间标准
  4. 我无法使用 flex-2.5.3,因为它不支持 RHEL5 机器。

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;
%}

%%

生成的scanner文件(文件比较大所以加入问题部分)

/* 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 编译

我在 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 * ));

最佳答案

问题不太可能是由对 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 成功地编译了一个简单的 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 分发引用中包含的 FlexLexer.h 文件 iostream.h .您可能需要将其更改为 iostream .

完成后,我可以生成 C++ 文件:

flex-2.5.4 -Sflex.skl.new ...

从上面的补丁可以看出,修复包括:

  • 总是包括stdio.h .如果你不这样做,EOF未定义。
  • 删除 istream 的前向声明并将其替换为 #include <iostream> .由于无论如何都会包含该 header ,因此似乎可以更早地包含它。
  • 添加 using namespace std; ,这与 flex 2.5.4 中的用法相匹配。显然,它设计使用的 C++ 标准库没有将标准原型(prototype)放入 std 中。命名空间。

我仍然认为使用古老的 flex 版本不是一个好主意,我鼓励您升级到最新的稳定版本(目前为 2.5.39),或者至少升级到 2.5.35。如果您遇到问题,请尝试创建一个最小可编译示例并提交一个单独的问题。

关于c++ - Flex Lexer 工具中的类 istream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34590605/

相关文章:

android - "<FlexLexer.h> not found",仅在 C++ 模式下发生

C++读取一个字符串后跟两个 double

c++ - 使用纯 C++/Boost 读取/写入具有 unicode 文件名的文件

c++ - GLSL:未呈现制服的变化

c - 使用 Eclipse IDE 作为我的编程语言的文本编辑器

parsing - Antlr3:无法匹配词法分析器规则中使用的解析器规则中的标记

c++ - 将指针用于条件 while/for 循环会在编译时出错

我们可以使用 GCC 来处理 C 项目的翻译阶段 1..5

java - 如何合并两个 AST?

regex - OCaml 中 "not belonging to"的正则表达式