Bison Flex 链接问题
Bison Flex linking problems
bison & flex 上有一个解析器 运行。使用 cmake 构建和制作整个项目。
所以,我从 flex 文件创建 lexer.cpp 文件,从 bison 文件创建 parser.cpp & parser.hpp。代码如下所示:
lexer.flex :
%{
#include "structures/RedirectionExpr.h"
// and about 8 includes like the upper one
#include <iostream>
#include <bits/stdc++.h>
#include "parcer.hpp"
using namespace std;
%}
%option noyywrap
%option c++
%%
/* Some staff */
%%
parser.ypp :
%{
#include "structures/RedirectionExpr.h"
// and about 8 includes like the upper one, like in lexer.flex
#include <bits/stdc++.h>
#include <iostream>
extern "C" int yylex(void);
extern "C" int yyparse();
extern "C" int errors;
void yyerror (char const *s);
using namespace std;
%}
%union {
/* Union types. */
}
// %token definitions
// %type definitions for grammar
%%
/* grammar is here */
%%
void yyerror (char const *s) { /* Some code here */ }
int main(int argc, char *argv[])
{
do {
yyparse();
} while (true);
return 0;
}
编译之前,我从 .flex
和 .ypp
文件手动创建 cpp 文件:
flex -o lexer.cpp lexer.flex
bison -d -o parser.cpp parser.ypp
为了构建所有这些混乱,我使用 cmake:
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(parse)
set(CMAKE_CXX_STANDARD 14)
add_executable(parse
src/structures/RedirectionExpr.cpp
# other includes of classes used
src/lexer.cpp
src/parser.cpp src/parser.hpp
)
所以,问题出现了,链接的时候:
/usr/sbin/ld: CMakeFiles/parse.dir/src/parser.cpp.o: in function `yyparse':
parser.cpp:(.text+0x31a): undefined reference to `yylex'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/parse.dir/build.make:294: parse] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/parse.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
作为解决方案,我尝试添加 %noyywrap
选项,将 parser.hpp
包含到 .flex
文件中,然后再包含额外的 类,放入 extern "C" int yylex(void);
行进入 parser.ypp
等。但现在我不知道如何解决它。你能帮我吗?
更新
我通过删除 extern "C"
并将 int yylex(void);
部分留在 parser.ypp
文件中解决了这个问题。您可以阅读更多相关信息 here.
在我看来,您打算使用 C 词法分析器 API。毕竟,在你的解析器中你说
extern "C" int yylex(void);
所以你在 flex 文件中使用 %option c++
有点令人费解。如果这样做,您将获得 C++ 接口,其中不包含 "C" yylex()
。
我认为您的简单选择是删除 %option
并将 yylex
的声明更改为
int yylex();
没有 extern "C"
如果您真的想使用 C++ 接口,我相信 Bison 手册包含一个使用 C++ flex 词法分析器的示例。这是更多的工作,但我相信它会得到回报。
此外,我不是 CMake 用户,但我很确定 CMake 确实知道如何编译 flex/bison 项目(例如,参见 this answer)。它可能会被 C++ 接口弄糊涂,但看起来很容易进行传统的 C 构建。
bison & flex 上有一个解析器 运行。使用 cmake 构建和制作整个项目。
所以,我从 flex 文件创建 lexer.cpp 文件,从 bison 文件创建 parser.cpp & parser.hpp。代码如下所示:
lexer.flex :
%{
#include "structures/RedirectionExpr.h"
// and about 8 includes like the upper one
#include <iostream>
#include <bits/stdc++.h>
#include "parcer.hpp"
using namespace std;
%}
%option noyywrap
%option c++
%%
/* Some staff */
%%
parser.ypp :
%{
#include "structures/RedirectionExpr.h"
// and about 8 includes like the upper one, like in lexer.flex
#include <bits/stdc++.h>
#include <iostream>
extern "C" int yylex(void);
extern "C" int yyparse();
extern "C" int errors;
void yyerror (char const *s);
using namespace std;
%}
%union {
/* Union types. */
}
// %token definitions
// %type definitions for grammar
%%
/* grammar is here */
%%
void yyerror (char const *s) { /* Some code here */ }
int main(int argc, char *argv[])
{
do {
yyparse();
} while (true);
return 0;
}
编译之前,我从 .flex
和 .ypp
文件手动创建 cpp 文件:
flex -o lexer.cpp lexer.flex
bison -d -o parser.cpp parser.ypp
为了构建所有这些混乱,我使用 cmake:
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(parse)
set(CMAKE_CXX_STANDARD 14)
add_executable(parse
src/structures/RedirectionExpr.cpp
# other includes of classes used
src/lexer.cpp
src/parser.cpp src/parser.hpp
)
所以,问题出现了,链接的时候:
/usr/sbin/ld: CMakeFiles/parse.dir/src/parser.cpp.o: in function `yyparse':
parser.cpp:(.text+0x31a): undefined reference to `yylex'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/parse.dir/build.make:294: parse] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/parse.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
作为解决方案,我尝试添加 %noyywrap
选项,将 parser.hpp
包含到 .flex
文件中,然后再包含额外的 类,放入 extern "C" int yylex(void);
行进入 parser.ypp
等。但现在我不知道如何解决它。你能帮我吗?
更新
我通过删除 extern "C"
并将 int yylex(void);
部分留在 parser.ypp
文件中解决了这个问题。您可以阅读更多相关信息 here.
在我看来,您打算使用 C 词法分析器 API。毕竟,在你的解析器中你说
extern "C" int yylex(void);
所以你在 flex 文件中使用 %option c++
有点令人费解。如果这样做,您将获得 C++ 接口,其中不包含 "C" yylex()
。
我认为您的简单选择是删除 %option
并将 yylex
的声明更改为
int yylex();
没有 extern "C"
如果您真的想使用 C++ 接口,我相信 Bison 手册包含一个使用 C++ flex 词法分析器的示例。这是更多的工作,但我相信它会得到回报。
此外,我不是 CMake 用户,但我很确定 CMake 确实知道如何编译 flex/bison 项目(例如,参见 this answer)。它可能会被 C++ 接口弄糊涂,但看起来很容易进行传统的 C 构建。