There is a parser running on bison & flex. To build and make the whole project cmake is used.
So, from flex file I create lexer.cpp file and from bison file parser.cpp & parser.hpp. The code looks like this :
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;
}
Before compilation, I manually create cpp files from .flex
and .ypp
files:
flex -o lexer.cpp lexer.flex
bison -d -o parser.cpp parser.ypp
To build all this mess, I use 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
)
So, the problem appears, when linking :
/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
As a solution I tried to add %noyywrap
option, include parser.hpp
into .flex
file after than I include additional classes, put extern "C" int yylex(void);
line into parser.ypp
etc. But right now I have no idea how to fix it. Can you help me with it?
I solved the problem by removing extern "C"
and leaving int yylex(void);
part in parser.ypp
file. You can read more about it here.
It looks to me like you're intending to use the C lexer API. After all, in your parser you say
extern "C" int yylex(void);
So it's a bit puzzling that you use %option c++
in your flex file. If you do that, you will get the C++ interface, which does not include a "C" yylex()
.
I think your easy option would be to delete that %option
and change the declaration of yylex
to just
int yylex();
without the extern "C"
If you really want to use the C++ interfaces, I believe the Bison manual includes an example of using a C++ flex lexer. It's more work but I'm sure it pays off.
Also, I'm not a CMake user but I'm pretty sure CMake does know how to compile flex/bison projects (see, for example, this answer). It might get confused by the C++ interfaces, but it looks like it's easy to do a traditional C build.