Flex/C++:'yypanic'未在范围内声明,错误:重新定义'class yFlexLexer','yyFlexLexer'未在此范围内声明

问题描述 投票:0回答:1

您好,我正在尝试将 Flex 与 C++ 结合使用。阅读 Flex 手册后,我开始编写一个小示例来构建我的项目。

我最初想出了这个小例子。

#include <string.h>

#include <iostream>  
#include <sstream>  
#include <string>    
#include <streambuf>
#include <fstream> 

int main() {
    std::string stringvalues = "TOKEN TEST 123";
    std::istringstream inputStringStream(stringvalues);

    std::istream& inputStream = inputStringStream;
    std::ofstream outputStream("test.txt");

    yyFlexLexer myTest(inputStream, outputStream);
}

在构建文件夹内,当我执行

cmake ..
然后点击
make
时,我收到以下错误:

alfredo@alfredo-ThinkPad-T440p:~/repos/FlexCpp/build$ make
[ 20%] Linking CXX static library libkeywords.a
[ 20%] Built target keywords
[ 40%] Building CXX object src/back-end/CMakeFiles/Foo.dir/main.cpp.o
/home/alfredo/repos/FlexCpp/src/back-end/main.cpp: In function ‘int main()’:
/home/alfredo/repos/FlexCpp/src/back-end/main.cpp:17:5: error: ‘yyFlexLexer’ was not declared in this scope
   17 |     yyFlexLexer myTest(inputStream, outputStream);
      |     ^~~~~~~~~~~
make[2]: *** [src/back-end/CMakeFiles/Foo.dir/build.make:80: src/back-end/CMakeFiles/Foo.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:126: src/back-end/CMakeFiles/Foo.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

奇怪的是,如果我注释掉main.cpp中的最后一行

    //yyFlexLexer myTest(inputStream, outputStream);

我收到以下错误:

lexer.l: In member function ‘virtual int yyFlexLexer::yylex()’:
lexer.l:172:1: error: ‘yypanic’ was not declared in this scope
/usr/local/flex/include/FlexLexer.h: At global scope:
/home/alfredo/repos/FlexCpp/src/back-end/lexer.yy.cc:49:25: error: redefinition of ‘class yyFlexLexer’
   49 |     #define yyFlexLexer yyFlexLexer
      |                         ^~~~~~~~~~~
/home/alfredo/repos/FlexCpp/src/back-end/lexer.yy.cc:49:25: note: previous definition of ‘class yyFlexLexer’
   49 |     #define yyFlexLexer yyFlexLexer
      |                         ^~~~~~~~~~~
make[2]: *** [src/back-end/CMakeFiles/Foo.dir/build.make:94: src/back-end/CMakeFiles/Foo.dir/lexer.yy.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:126: src/back-end/CMakeFiles/Foo.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

我的项目目录如下所示。

backend/
  |- main.cpp (what you saw ealier)
  |- CMakeLists.txt
  |- keywords.hxx (contains enum tokens and struct)
  |- lexer.l 
  |- lexer.yy.cc (this will be generated by lexer.l when we compile with c++
                  we set %option c++ in our lexer.l file )

这是我的 lexer.l 的样子

    /* we dont have an interactive session. */ 
%option never-interactive


    /* we will handle the nodefault rule. */
%option nodefault

    /* we dont want yyinput() and yyunput(). */
%option noinput nounput


    /* don't include <unistd.h> we dont need it. */
%option nounistd


    /* 
        not needed for now, in the future when users can work 
        with multiple files we can start using it.
    */
%option noyywrap


    /* 
        these two options are doubled to get more detailed reports.
        write performance report to stderr.
    */
%option perf-report perf-report

    /* write statistics summary to stderr. */
%option verbose verbose

    /* generate warning messages for mistakes. */
%option warn

    /* maintain current line number in yylineno. */
%option yylineno

%option c++



    /* c items that can be used in the rules section */
%{
#include <stdio.h> 
#include <keywords.hxx>



int iskeyword(char * keyword);



%}

digit      [0-9]
exponent   [ee][-+]?{digit}+


id_start   [_a-za-z]
id_after   {id_start}|{digit}



    /*===================rules===================*/
%% 

    /* a bunch of rules */

%% 
    /*=================user-code=================*/
#include <keywords.hxx>

    /*As mentioned by Flex manual we include this if our main() is not in this file */
#include <FlexLexer.h>

int iskeyword(char * keyword){
    for(int index = 0; index < NUM_KEYWORDS; index++){
        if(strcmp(keywords[index].keyWord, keyword)){
            return keywords[index].token;
        }
    }
    return 0;
}

CMakeLists.cmake

cmake_minimum_required(VERSION 3.5)

project(
    TestingProj
)


set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/local/flex/include")

find_package(FLEX REQUIRED)


add_library(keywords keywords.hxx)
set_target_properties(keywords PROPERTIES LINKER_LANGUAGE CXX)
target_include_directories(keywords PUBLIC ./)


FLEX_TARGET(
    gen_lexer
    lexer.l
    lexer.yy.cc
)

add_executable(
    Foo
    main.cpp
    ${FLEX_gen_lexer_OUTPUTS}
)

target_link_libraries(Foo PUBLIC keywords)
target_link_libraries(Foo PUBLIC ${FLEX_LIBRARIES})

如果我记录以下内容

message("FLEX_FOUND ${FLEX_FOUND}")
message("FLEX_EXECUTABLE ${FLEX_EXECUTABLE}")
message("FLEX_VERSION ${FLEX_VERSION}")
message("FLEX_LIBRARIES ${FLEX_LIBRARIES}")
message("FLEX_INCLUDE_DIRS ${FLEX_INCLUDE_DIRS}")

我明白了

FLEX_FOUND TRUE
FLEX_EXECUTABLE /usr/local/flex/bin/flex
FLEX_VERSION 2.6.4
FLEX_LIBRARIES /usr/local/flex/lib/libfl.so
FLEX_INCLUDE_DIRS /usr/local/flex/include

我也厌倦了遵循 Flex 手册。没有帮助。

如果您想创建多个(不同的)词法分析器类,您可以使用“-P”标志(或 prefix= option) 将每个 yyFlexLexer 重命名为其他“xxFlexLexer”。然后是你 每个词法分析器类可以在其他源中包含 一次,首先重命名 yyFlexLexer如下: #undef yyFlexLexer #define yyFlexLexer xxFlexLexer #包括 #undef yyFlexLexer #define yyFlexLexer zzFlexLexer #包括

我不确定我做错了什么。我花了很多时间试图让 Flex 和 C++ 工作。我能够让 Flex 和纯 C 工作,但只是 C++ 我遇到了麻烦。截至发布时,我的最佳猜测是

FlexLexer.h
文件存在问题。出于某种原因,我从源代码构建的其他项目在其
FlexLexer.h
文件夹中构建了
/include
文件。据我所知,它现在指向
FlexLexer.h
的正确位置,我的情况是在
/usr/local/flex/include/FlexLexer.h:
或者我的
.cmake
文件可能有问题。

任何帮助将不胜感激。

c++ cmake flex-lexer
1个回答
0
投票

我首先按照 Tysvarev 留下的评论解决了这个问题,我引用了他们。

“不需要显式包含 lexer.l 中的该文件。但是在 main.cpp 中,你需要包含 FlexLexer.h,否则编译器没有有关 yyFlexLexer 类的信息”

然后在

%{ ... %}
块内,我像这样定义了yypanic

void yypanic( char* errorMessage);

最后在我写的用户代码中

void yypanic(char * errorMessage) {
    std::cout << errorMessage << std::endl;
}
© www.soinside.com 2019 - 2024. All rights reserved.